@dxos/react-ui-form 0.8.4-main.4a85c3132b → 0.8.4-main.51f1e5ca51
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/dist/lib/browser/index.mjs +1005 -585
- 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 +1005 -585
- 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.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 +40 -12
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +76 -74
- 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.map +1 -1
- package/dist/types/src/components/Form/FormFieldSet.d.ts +5 -9
- 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 +83 -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 +2 -2
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +65 -63
- 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 -0
- 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 -40
- package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
- package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
- package/src/components/FieldEditor/FieldEditor.tsx +4 -3
- package/src/components/Form/AUDIT.md +17 -0
- package/src/components/Form/Form.stories.tsx +25 -38
- package/src/components/Form/Form.tsx +77 -47
- package/src/components/Form/FormField.tsx +27 -15
- package/src/components/Form/FormFieldComponent.tsx +3 -1
- package/src/components/Form/FormFieldSet.tsx +98 -77
- package/src/components/Form/fields/ArrayField.tsx +16 -6
- package/src/components/Form/fields/GeoPointField.tsx +8 -7
- package/src/components/Form/fields/MarkdownField.stories.tsx +152 -0
- package/src/components/Form/fields/MarkdownField.tsx +135 -45
- package/src/components/Form/fields/RefField.tsx +78 -38
- package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -6
- package/src/components/Form/fields/SelectOptionField.tsx +8 -8
- 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 +9 -7
- package/src/components/ObjectPicker/ObjectPicker.tsx +83 -64
- 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 -183
- 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 +12 -12
- package/src/components/ViewEditor/ViewEditor.test.tsx +0 -1
- package/src/components/ViewEditor/ViewEditor.tsx +27 -15
- package/src/components/index.ts +2 -0
- package/src/components/testing.tsx +19 -11
- package/src/hooks/useKeyHandler.tsx +7 -7
- package/src/index.ts +0 -4
- package/src/translations.ts +66 -63
- package/src/util/field-type.ts +60 -0
- package/src/util/index.ts +1 -0
- package/src/util/refs.ts +7 -3
|
@@ -1,87 +1,11 @@
|
|
|
1
|
-
// src/translations.ts
|
|
2
|
-
var translationKey = "@dxos/react-ui-form";
|
|
3
|
-
var translations = [
|
|
4
|
-
{
|
|
5
|
-
"en-US": {
|
|
6
|
-
[translationKey]: {
|
|
7
|
-
"fields label": "Fields",
|
|
8
|
-
"hidden fields label": "Hidden Fields",
|
|
9
|
-
"empty readonly ref field label": "(none)",
|
|
10
|
-
// TODO(burdon): Standardize field/property.
|
|
11
|
-
"add property button label": "Add property",
|
|
12
|
-
"field property label": "Property",
|
|
13
|
-
"field property placeholder": "Property name",
|
|
14
|
-
"field format label": "Type",
|
|
15
|
-
"field path label": "Field path",
|
|
16
|
-
"add field": "Add field",
|
|
17
|
-
"delete field": "Delete field",
|
|
18
|
-
"field limit reached": "Maximum number of fields reached",
|
|
19
|
-
"boolean input true value": "Yes",
|
|
20
|
-
"boolean input false value": "No",
|
|
21
|
-
"show field label": "Show field",
|
|
22
|
-
"hide field label": "Hide field",
|
|
23
|
-
"delete field label": "Delete field",
|
|
24
|
-
"ref field combobox input placeholder": "Search\u2026",
|
|
25
|
-
"ref field placeholder_one": "Select\u2026",
|
|
26
|
-
"ref field placeholder_other": "Select items\u2026",
|
|
27
|
-
"example placeholder": "Example",
|
|
28
|
-
"latitude placeholder": "Latitude (e.g., 40.7128)",
|
|
29
|
-
"longitude placeholder": "Longitude (e.g., -74.0060)",
|
|
30
|
-
"cancel button label": "Cancel",
|
|
31
|
-
"save button label": "Save",
|
|
32
|
-
// FormatEnum
|
|
33
|
-
"format boolean": "Boolean",
|
|
34
|
-
"format currency": "Currency",
|
|
35
|
-
"format date": "Date",
|
|
36
|
-
"format date-time": "DateTime",
|
|
37
|
-
"format did": "DID",
|
|
38
|
-
"format duration": "Duration",
|
|
39
|
-
"format dxn": "DXN",
|
|
40
|
-
"format email": "Email",
|
|
41
|
-
"format formula": "Formula",
|
|
42
|
-
"format hostname": "Hostname",
|
|
43
|
-
"format integer": "Integer",
|
|
44
|
-
"format json": "JSON",
|
|
45
|
-
"format lnglat": "Geopoint",
|
|
46
|
-
"format markdown": "Markdown",
|
|
47
|
-
"format percent": "Percent",
|
|
48
|
-
"format ref": "Reference",
|
|
49
|
-
"format regex": "RegExp",
|
|
50
|
-
"format string": "String",
|
|
51
|
-
"format single-select": "Select",
|
|
52
|
-
"format multi-select": "Multi-select",
|
|
53
|
-
"format text": "Long text",
|
|
54
|
-
"format time": "Time",
|
|
55
|
-
"format timestamp": "Timestamp",
|
|
56
|
-
"format user": "User",
|
|
57
|
-
"format number": "Number",
|
|
58
|
-
"format uri": "URI",
|
|
59
|
-
"format url": "URL",
|
|
60
|
-
"format uuid": "UUID",
|
|
61
|
-
// GeoPointField.
|
|
62
|
-
"latitude label": "Latitude",
|
|
63
|
-
"longitude label": "Longitude",
|
|
64
|
-
// SelectOptionsField.
|
|
65
|
-
"select option label": "Label",
|
|
66
|
-
"select option label placeholder": "Option label",
|
|
67
|
-
"select option color": "Color",
|
|
68
|
-
"select option delete": "Delete",
|
|
69
|
-
"select option add": "Add option",
|
|
70
|
-
// System schema message.
|
|
71
|
-
"system schema title": "System type",
|
|
72
|
-
"system schema description": "System type: cannot add or remove fields."
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
];
|
|
77
|
-
|
|
78
1
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
79
|
-
import React17, { useCallback as useCallback14, useEffect as
|
|
80
|
-
import { Obj as
|
|
2
|
+
import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
|
|
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";
|
|
8
|
+
import { translationKey as translationKey9 } from "#translations";
|
|
85
9
|
|
|
86
10
|
// src/util/field.ts
|
|
87
11
|
import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
|
|
@@ -204,6 +128,46 @@ var pathNotUniqueError = (path) => ({
|
|
|
204
128
|
message: `'${path}' is already present`
|
|
205
129
|
});
|
|
206
130
|
|
|
131
|
+
// src/util/field-type.ts
|
|
132
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
133
|
+
import { getAnnotation, isLiteralUnion } from "@dxos/effect";
|
|
134
|
+
var detectFieldType = (ast) => {
|
|
135
|
+
if (isLiteralUnion(ast)) {
|
|
136
|
+
return "select";
|
|
137
|
+
}
|
|
138
|
+
if (SchemaAST.isTypeLiteral(ast)) {
|
|
139
|
+
return "struct";
|
|
140
|
+
}
|
|
141
|
+
switch (ast._tag) {
|
|
142
|
+
case "BooleanKeyword":
|
|
143
|
+
return "boolean";
|
|
144
|
+
case "StringKeyword":
|
|
145
|
+
return "string";
|
|
146
|
+
case "NumberKeyword":
|
|
147
|
+
return "number";
|
|
148
|
+
}
|
|
149
|
+
return void 0;
|
|
150
|
+
};
|
|
151
|
+
var getSelectOptionsFromAst = (ast) => {
|
|
152
|
+
if (!isLiteralUnion(ast)) {
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
return ast.types.flatMap((literalNode) => {
|
|
156
|
+
const value3 = literalNode.literal;
|
|
157
|
+
if (typeof value3 !== "string" && typeof value3 !== "number") {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
|
|
161
|
+
const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
|
|
162
|
+
return [
|
|
163
|
+
{
|
|
164
|
+
value: value3,
|
|
165
|
+
label
|
|
166
|
+
}
|
|
167
|
+
];
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
207
171
|
// src/util/formatting.ts
|
|
208
172
|
import { format as formatDate } from "date-fns/format";
|
|
209
173
|
import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
|
|
@@ -352,43 +316,52 @@ var getFormProperties = (ast) => {
|
|
|
352
316
|
|
|
353
317
|
// src/util/refs.ts
|
|
354
318
|
import { Ref } from "@dxos/echo";
|
|
355
|
-
import {
|
|
319
|
+
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
320
|
+
import { findAnnotation, getArrayElementType, isArrayType } from "@dxos/effect";
|
|
356
321
|
var getRefProps = (ast) => {
|
|
357
322
|
if (isArrayType(ast)) {
|
|
358
323
|
const elementType = getArrayElementType(ast);
|
|
359
324
|
if (elementType) {
|
|
360
325
|
if (Ref.isRefType(elementType)) {
|
|
326
|
+
const typename = findAnnotation(elementType, ReferenceAnnotationId)?.typename;
|
|
361
327
|
return {
|
|
362
328
|
ast: elementType,
|
|
363
|
-
isArray: true
|
|
329
|
+
isArray: true,
|
|
330
|
+
typename
|
|
364
331
|
};
|
|
365
332
|
}
|
|
366
333
|
}
|
|
367
334
|
}
|
|
368
335
|
if (Ref.isRefType(ast)) {
|
|
336
|
+
const typename = findAnnotation(ast, ReferenceAnnotationId)?.typename;
|
|
369
337
|
return {
|
|
370
338
|
ast,
|
|
371
|
-
isArray: false
|
|
339
|
+
isArray: false,
|
|
340
|
+
typename
|
|
372
341
|
};
|
|
373
342
|
}
|
|
374
343
|
return void 0;
|
|
375
344
|
};
|
|
376
345
|
|
|
377
346
|
// src/components/Form/fields/ArrayField.tsx
|
|
378
|
-
import * as
|
|
379
|
-
import * as
|
|
347
|
+
import * as Option4 from "effect/Option";
|
|
348
|
+
import * as SchemaAST4 from "effect/SchemaAST";
|
|
380
349
|
import React5, { useCallback as useCallback3 } from "react";
|
|
381
350
|
import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
|
|
382
351
|
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
352
|
+
import { translationKey as translationKey3 } from "#translations";
|
|
383
353
|
|
|
384
354
|
// src/components/Form/Form.tsx
|
|
385
355
|
import { createContext } from "@radix-ui/react-context";
|
|
356
|
+
import * as Option3 from "effect/Option";
|
|
386
357
|
import * as Schema2 from "effect/Schema";
|
|
387
|
-
import * as
|
|
388
|
-
import React4, { useEffect as
|
|
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";
|
|
389
361
|
import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
|
|
390
|
-
import { IconButton, ScrollArea, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
391
|
-
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";
|
|
392
365
|
|
|
393
366
|
// src/hooks/useFormHandler.ts
|
|
394
367
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
@@ -426,12 +399,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
426
399
|
log("validate", {
|
|
427
400
|
values: values2,
|
|
428
401
|
errors: errors2
|
|
429
|
-
}, {
|
|
430
|
-
F: __dxlog_file,
|
|
431
|
-
L: 155,
|
|
432
|
-
S: void 0,
|
|
433
|
-
C: (f, a) => f(...a)
|
|
434
|
-
});
|
|
402
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
|
|
435
403
|
if (errors2.length === 0 && onValidate) {
|
|
436
404
|
const validatedValues = values2;
|
|
437
405
|
errors2 = onValidate(validatedValues) ?? [];
|
|
@@ -519,12 +487,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
519
487
|
log("onValueChange", {
|
|
520
488
|
path,
|
|
521
489
|
value: value3
|
|
522
|
-
}, {
|
|
523
|
-
F: __dxlog_file,
|
|
524
|
-
L: 254,
|
|
525
|
-
S: void 0,
|
|
526
|
-
C: (f, a) => f(...a)
|
|
527
|
-
});
|
|
490
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
|
|
528
491
|
const jsonPath = createJsonPath(path);
|
|
529
492
|
const pathArray = path;
|
|
530
493
|
let parsedValue = value3;
|
|
@@ -533,12 +496,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
533
496
|
parsedValue = parseFloat(value3) || 0;
|
|
534
497
|
}
|
|
535
498
|
} catch (err) {
|
|
536
|
-
log.catch(err, void 0, {
|
|
537
|
-
F: __dxlog_file,
|
|
538
|
-
L: 264,
|
|
539
|
-
S: void 0,
|
|
540
|
-
C: (f, a) => f(...a)
|
|
541
|
-
});
|
|
499
|
+
log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
|
|
542
500
|
parsedValue = void 0;
|
|
543
501
|
}
|
|
544
502
|
const newValues = mergeAtPath(values, pathArray, parsedValue);
|
|
@@ -647,9 +605,9 @@ var flatMap = (errors) => {
|
|
|
647
605
|
};
|
|
648
606
|
|
|
649
607
|
// src/hooks/useKeyHandler.tsx
|
|
650
|
-
import { useCallback as useCallback2,
|
|
608
|
+
import { useCallback as useCallback2, useLayoutEffect } from "react";
|
|
651
609
|
import { addEventListener } from "@dxos/async";
|
|
652
|
-
var useKeyHandler = (
|
|
610
|
+
var useKeyHandler = (elRef, form) => {
|
|
653
611
|
const handleKeyDown = useCallback2((event) => {
|
|
654
612
|
switch (event.key) {
|
|
655
613
|
case "Enter": {
|
|
@@ -665,13 +623,14 @@ var useKeyHandler = (formElement, form) => {
|
|
|
665
623
|
form.onSave,
|
|
666
624
|
form.autoSave
|
|
667
625
|
]);
|
|
668
|
-
|
|
669
|
-
|
|
626
|
+
useLayoutEffect(() => {
|
|
627
|
+
const el = elRef.current;
|
|
628
|
+
if (!el) {
|
|
670
629
|
return;
|
|
671
630
|
}
|
|
672
|
-
return addEventListener(
|
|
631
|
+
return addEventListener(el, "keydown", handleKeyDown);
|
|
673
632
|
}, [
|
|
674
|
-
|
|
633
|
+
elRef,
|
|
675
634
|
handleKeyDown
|
|
676
635
|
]);
|
|
677
636
|
};
|
|
@@ -751,20 +710,19 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
751
710
|
};
|
|
752
711
|
|
|
753
712
|
// src/components/Form/FormFieldSet.tsx
|
|
754
|
-
import React3, {
|
|
755
|
-
import { mx } from "@dxos/ui-theme";
|
|
756
|
-
import { isTruthy } from "@dxos/util";
|
|
713
|
+
import React3, { useMemo as useMemo3 } from "react";
|
|
757
714
|
|
|
758
715
|
// src/components/Form/FormField.tsx
|
|
759
716
|
import * as Match from "effect/Match";
|
|
760
717
|
import * as Option2 from "effect/Option";
|
|
761
718
|
import * as Schema from "effect/Schema";
|
|
762
|
-
import * as
|
|
719
|
+
import * as SchemaAST2 from "effect/SchemaAST";
|
|
763
720
|
import * as String2 from "effect/String";
|
|
764
721
|
import React2, { useMemo as useMemo2 } from "react";
|
|
765
722
|
import { Format as Format3 } from "@dxos/echo";
|
|
766
|
-
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";
|
|
767
724
|
import { useTranslation } from "@dxos/react-ui";
|
|
725
|
+
import { translationKey } from "#translations";
|
|
768
726
|
var FormField = (props) => {
|
|
769
727
|
const {
|
|
770
728
|
type,
|
|
@@ -776,23 +734,25 @@ var FormField = (props) => {
|
|
|
776
734
|
readonly,
|
|
777
735
|
layout,
|
|
778
736
|
// RefFieldProps
|
|
737
|
+
createTypename,
|
|
779
738
|
createOptionLabel,
|
|
780
739
|
createOptionIcon,
|
|
781
740
|
createInitialValuePath,
|
|
741
|
+
createFieldMap: createFieldMap3,
|
|
782
742
|
db,
|
|
783
|
-
schemaHook,
|
|
784
|
-
getOptions
|
|
743
|
+
useSchema: schemaHook,
|
|
744
|
+
getOptions,
|
|
785
745
|
onCreate
|
|
786
746
|
} = props;
|
|
787
747
|
const { t } = useTranslation(translationKey);
|
|
788
|
-
const title =
|
|
789
|
-
const description =
|
|
790
|
-
const examples =
|
|
748
|
+
const title = getAnnotation2(SchemaAST2.TitleAnnotationId)(type);
|
|
749
|
+
const description = getAnnotation2(SchemaAST2.DescriptionAnnotationId)(type);
|
|
750
|
+
const examples = getAnnotation2(SchemaAST2.ExamplesAnnotationId)(type);
|
|
791
751
|
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
792
752
|
title,
|
|
793
753
|
name
|
|
794
754
|
]);
|
|
795
|
-
const placeholder = useMemo2(() => examples?.length ? `${t("example
|
|
755
|
+
const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
|
|
796
756
|
examples,
|
|
797
757
|
description,
|
|
798
758
|
label
|
|
@@ -805,6 +765,7 @@ var FormField = (props) => {
|
|
|
805
765
|
label,
|
|
806
766
|
placeholder,
|
|
807
767
|
layout,
|
|
768
|
+
db,
|
|
808
769
|
...fieldState
|
|
809
770
|
};
|
|
810
771
|
const jsonPath = createJsonPath2(path ?? []);
|
|
@@ -831,7 +792,7 @@ var FormField = (props) => {
|
|
|
831
792
|
if (Field) {
|
|
832
793
|
return /* @__PURE__ */ React2.createElement(Field, fieldProps);
|
|
833
794
|
}
|
|
834
|
-
const options =
|
|
795
|
+
const options = getSelectOptions(type);
|
|
835
796
|
if (options) {
|
|
836
797
|
const fieldProjections = projection?.getFieldProjections();
|
|
837
798
|
const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
|
|
@@ -849,21 +810,23 @@ var FormField = (props) => {
|
|
|
849
810
|
}
|
|
850
811
|
const refProps = getRefProps(type);
|
|
851
812
|
if (refProps) {
|
|
813
|
+
const isCreateTarget = !createTypename || refProps.typename === createTypename;
|
|
852
814
|
return /* @__PURE__ */ React2.createElement(RefField, {
|
|
853
815
|
...fieldProps,
|
|
854
816
|
...refProps,
|
|
855
|
-
createOptionLabel,
|
|
856
|
-
createOptionIcon,
|
|
857
|
-
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,
|
|
858
821
|
db,
|
|
859
|
-
schemaHook,
|
|
860
|
-
getOptions
|
|
822
|
+
useSchema: schemaHook,
|
|
823
|
+
getOptions,
|
|
861
824
|
onCreate
|
|
862
825
|
});
|
|
863
826
|
}
|
|
864
827
|
if (isNestedType(type)) {
|
|
865
828
|
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
866
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type,
|
|
829
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
|
|
867
830
|
if (typeLiteral) {
|
|
868
831
|
const schema = Schema.make(typeLiteral);
|
|
869
832
|
return /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
@@ -879,8 +842,8 @@ var FormField = (props) => {
|
|
|
879
842
|
createOptionIcon,
|
|
880
843
|
createInitialValuePath,
|
|
881
844
|
db,
|
|
882
|
-
schemaHook,
|
|
883
|
-
getOptions
|
|
845
|
+
useSchema: schemaHook,
|
|
846
|
+
getOptions,
|
|
884
847
|
onCreate
|
|
885
848
|
});
|
|
886
849
|
}
|
|
@@ -904,8 +867,8 @@ var getFormField = ({ type, format }) => {
|
|
|
904
867
|
return BooleanField;
|
|
905
868
|
}
|
|
906
869
|
};
|
|
907
|
-
var
|
|
908
|
-
if (
|
|
870
|
+
var getSelectOptions = (ast) => {
|
|
871
|
+
if (isLiteralUnion2(ast)) {
|
|
909
872
|
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
910
873
|
}
|
|
911
874
|
return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
@@ -913,47 +876,19 @@ var getOptions = (ast) => {
|
|
|
913
876
|
|
|
914
877
|
// src/components/Form/FormFieldSet.tsx
|
|
915
878
|
var FORM_FIELDSET_NAME = "Form.FieldSet";
|
|
916
|
-
var FormFieldSet =
|
|
879
|
+
var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
|
|
917
880
|
const values = useFormValues(FORM_FIELDSET_NAME, path);
|
|
918
|
-
const properties =
|
|
919
|
-
if (!schema) {
|
|
920
|
-
return [];
|
|
921
|
-
}
|
|
922
|
-
const props2 = getFormProperties(schema.ast);
|
|
923
|
-
if (projection) {
|
|
924
|
-
const fieldProjections = projection.getFieldProjections();
|
|
925
|
-
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
926
|
-
const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
927
|
-
const orderedProps = [];
|
|
928
|
-
for (const fieldProjection of fieldProjections) {
|
|
929
|
-
const fieldPath = String(fieldProjection.field.path);
|
|
930
|
-
const prop = visibleProps.find((p) => p.name === fieldPath);
|
|
931
|
-
if (prop) {
|
|
932
|
-
orderedProps.push(prop);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
936
|
-
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
937
|
-
orderedProps.push(...remainingProps);
|
|
938
|
-
return orderedProps;
|
|
939
|
-
}
|
|
940
|
-
const filtered = exclude ? exclude(props2) : props2;
|
|
941
|
-
return sort ? filtered.sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filtered;
|
|
942
|
-
}, [
|
|
881
|
+
const properties = useFormFieldSetProperties({
|
|
943
882
|
schema,
|
|
944
883
|
values,
|
|
945
884
|
exclude,
|
|
946
885
|
sort,
|
|
947
|
-
projection
|
|
948
|
-
|
|
886
|
+
projection
|
|
887
|
+
});
|
|
949
888
|
if ((readonly || layout === "static") && values == null) {
|
|
950
889
|
return null;
|
|
951
890
|
}
|
|
952
|
-
return /* @__PURE__ */ React3.createElement("
|
|
953
|
-
role: "form",
|
|
954
|
-
className: mx("w-full", layout === "inline" && "flex flex-col gap-2"),
|
|
955
|
-
ref: forwardRef4
|
|
956
|
-
}, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
|
|
891
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
|
|
957
892
|
label,
|
|
958
893
|
asChild: true
|
|
959
894
|
}), properties.map((property) => {
|
|
@@ -976,12 +911,52 @@ var FormFieldSet = /* @__PURE__ */ forwardRef(({ label, schema, readonly, path,
|
|
|
976
911
|
projection,
|
|
977
912
|
...props
|
|
978
913
|
}));
|
|
979
|
-
})
|
|
980
|
-
}
|
|
914
|
+
}));
|
|
915
|
+
};
|
|
981
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
|
+
};
|
|
982
952
|
|
|
983
953
|
// src/components/Form/Form.tsx
|
|
984
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
|
+
};
|
|
985
960
|
var [FormContextProvider, useFormContext] = createContext("Form");
|
|
986
961
|
var useFormValues = (componentName, path, defaultValue) => {
|
|
987
962
|
const stablePath = useMemo4(() => path ?? [], [
|
|
@@ -991,10 +966,10 @@ var useFormValues = (componentName, path, defaultValue) => {
|
|
|
991
966
|
const { form: { values, onValueChange } } = useFormContext(componentName);
|
|
992
967
|
const value3 = getValue$2(values, jsonPath);
|
|
993
968
|
const lastAppliedPathRef = useRef(null);
|
|
994
|
-
|
|
969
|
+
useEffect2(() => {
|
|
995
970
|
if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
996
971
|
lastAppliedPathRef.current = jsonPath;
|
|
997
|
-
onValueChange(stablePath,
|
|
972
|
+
onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
|
|
998
973
|
}
|
|
999
974
|
}, [
|
|
1000
975
|
value3,
|
|
@@ -1038,29 +1013,35 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
|
|
|
1038
1013
|
};
|
|
1039
1014
|
FormRoot.displayName = "Form.Root";
|
|
1040
1015
|
var FORM_VIEWPORT_NAME = "Form.Viewport";
|
|
1041
|
-
var FormViewport = ({ children,
|
|
1016
|
+
var FormViewport = composable(({ children, ...props }, forwardedRef) => {
|
|
1042
1017
|
return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
|
|
1018
|
+
...composableProps(props),
|
|
1043
1019
|
orientation: "vertical",
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
...props
|
|
1020
|
+
centered: true,
|
|
1021
|
+
padding: true,
|
|
1022
|
+
thin: true,
|
|
1023
|
+
ref: forwardedRef
|
|
1049
1024
|
}, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
|
|
1050
|
-
};
|
|
1025
|
+
});
|
|
1051
1026
|
FormViewport.displayName = FORM_VIEWPORT_NAME;
|
|
1052
1027
|
var FORM_CONTENT_NAME = "Form.Content";
|
|
1053
|
-
var FormContent = ({
|
|
1028
|
+
var FormContent = composable(({ children, ...props }, forwardedRef) => {
|
|
1054
1029
|
const { form, testId } = useFormContext(FORM_CONTENT_NAME);
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1030
|
+
const localRef = useRef(null);
|
|
1031
|
+
const mergedRef = useMergeRefs([
|
|
1032
|
+
forwardedRef,
|
|
1033
|
+
localRef
|
|
1034
|
+
]);
|
|
1035
|
+
useKeyHandler(localRef, form);
|
|
1057
1036
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
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
|
|
1062
1043
|
}, children);
|
|
1063
|
-
};
|
|
1044
|
+
});
|
|
1064
1045
|
FormContent.displayName = FORM_CONTENT_NAME;
|
|
1065
1046
|
var FORM_FIELDSET_NAME2 = "Form.FieldSet";
|
|
1066
1047
|
var FormFieldSet2 = (props) => {
|
|
@@ -1074,18 +1055,18 @@ var FormFieldSet2 = (props) => {
|
|
|
1074
1055
|
FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
|
|
1075
1056
|
var FORM_ACTIONS_NAME = "Form.Actions";
|
|
1076
1057
|
var FormActions = ({ classNames }) => {
|
|
1077
|
-
const { t } = useTranslation2(
|
|
1058
|
+
const { t } = useTranslation2(translationKey2);
|
|
1078
1059
|
const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
|
|
1079
1060
|
if (readonly || layout === "static") {
|
|
1080
1061
|
return null;
|
|
1081
1062
|
}
|
|
1082
1063
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1083
1064
|
role: "none",
|
|
1084
|
-
className:
|
|
1065
|
+
className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
|
|
1085
1066
|
}, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1086
1067
|
icon: "ph--x--regular",
|
|
1087
1068
|
iconEnd: true,
|
|
1088
|
-
label: t("cancel
|
|
1069
|
+
label: t("cancel-button.label"),
|
|
1089
1070
|
onClick: onCancel,
|
|
1090
1071
|
"data-testid": "cancel-button"
|
|
1091
1072
|
}), onSave && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
@@ -1094,29 +1075,43 @@ var FormActions = ({ classNames }) => {
|
|
|
1094
1075
|
disabled: !canSave,
|
|
1095
1076
|
icon: "ph--check--regular",
|
|
1096
1077
|
iconEnd: true,
|
|
1097
|
-
label: t("save
|
|
1078
|
+
label: t("save-button.label"),
|
|
1098
1079
|
onClick: onSave,
|
|
1099
1080
|
"data-testid": "save-button"
|
|
1100
1081
|
}));
|
|
1101
1082
|
};
|
|
1102
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;
|
|
1103
1098
|
var FORM_SUBMIT_NAME = "Form.Submit";
|
|
1104
1099
|
var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
1105
|
-
const { t } = useTranslation2(
|
|
1100
|
+
const { t } = useTranslation2(translationKey2);
|
|
1106
1101
|
const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
|
|
1107
1102
|
if (readonly || layout === "static") {
|
|
1108
1103
|
return null;
|
|
1109
1104
|
}
|
|
1110
1105
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1111
1106
|
role: "none",
|
|
1112
|
-
className:
|
|
1107
|
+
className: mx("flex w-full pt-form-padding", classNames)
|
|
1113
1108
|
}, /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1114
1109
|
classNames: "w-full",
|
|
1115
1110
|
type: "submit",
|
|
1116
1111
|
variant: "primary",
|
|
1117
1112
|
disabled: disabled ?? !canSave,
|
|
1118
1113
|
icon: icon ?? "ph--check--regular",
|
|
1119
|
-
label: label ?? t("save
|
|
1114
|
+
label: label ?? t("save-button.label"),
|
|
1120
1115
|
onClick: onSave,
|
|
1121
1116
|
"data-testid": "save-button"
|
|
1122
1117
|
}));
|
|
@@ -1126,6 +1121,7 @@ var Form = {
|
|
|
1126
1121
|
Root: FormRoot,
|
|
1127
1122
|
Viewport: FormViewport,
|
|
1128
1123
|
Content: FormContent,
|
|
1124
|
+
Section: FormSection,
|
|
1129
1125
|
FieldSet: FormFieldSet2,
|
|
1130
1126
|
Label: FormFieldLabel,
|
|
1131
1127
|
Actions: FormActions,
|
|
@@ -1134,18 +1130,18 @@ var Form = {
|
|
|
1134
1130
|
|
|
1135
1131
|
// src/components/Form/fields/ArrayField.tsx
|
|
1136
1132
|
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1137
|
-
const { t } = useTranslation3(
|
|
1133
|
+
const { t } = useTranslation3(translationKey3);
|
|
1138
1134
|
const elementType = getArrayElementType2(type);
|
|
1139
1135
|
const { onValueChange } = inputProps;
|
|
1140
1136
|
const values = useFormValues(ArrayField.displayName, path, () => []);
|
|
1141
1137
|
const getDefaultObjectValue = (typeNode) => {
|
|
1142
1138
|
const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
|
|
1143
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode,
|
|
1139
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
|
|
1144
1140
|
if (!typeLiteral) {
|
|
1145
1141
|
return {};
|
|
1146
1142
|
}
|
|
1147
1143
|
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1148
|
-
const defaultValue =
|
|
1144
|
+
const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
|
|
1149
1145
|
return [
|
|
1150
1146
|
prop.name,
|
|
1151
1147
|
defaultValue
|
|
@@ -1180,12 +1176,12 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1180
1176
|
asChild: true
|
|
1181
1177
|
}), /* @__PURE__ */ React5.createElement("div", {
|
|
1182
1178
|
role: "none",
|
|
1183
|
-
className: "flex flex-col gap-
|
|
1179
|
+
className: "flex flex-col gap-form-gap"
|
|
1184
1180
|
}, values?.map((_, index) => {
|
|
1185
1181
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
1186
1182
|
role: "none",
|
|
1187
1183
|
key: index,
|
|
1188
|
-
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"
|
|
1189
1185
|
}, /* @__PURE__ */ React5.createElement(FormField, {
|
|
1190
1186
|
autoFocus: index === values.length - 1,
|
|
1191
1187
|
type: elementType,
|
|
@@ -1205,14 +1201,14 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1205
1201
|
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1206
1202
|
icon: "ph--x--regular",
|
|
1207
1203
|
iconOnly: true,
|
|
1208
|
-
label: t("button
|
|
1204
|
+
label: t("remove.button"),
|
|
1209
1205
|
onClick: () => handleDelete(index),
|
|
1210
1206
|
classNames: "self-center"
|
|
1211
1207
|
}))));
|
|
1212
1208
|
})), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1213
1209
|
classNames: "flex w-full",
|
|
1214
1210
|
icon: "ph--plus--regular",
|
|
1215
|
-
label: t("add
|
|
1211
|
+
label: t("add-item.button"),
|
|
1216
1212
|
onClick: handleAdd
|
|
1217
1213
|
}));
|
|
1218
1214
|
};
|
|
@@ -1260,12 +1256,13 @@ var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
|
|
|
1260
1256
|
};
|
|
1261
1257
|
|
|
1262
1258
|
// src/components/Form/fields/GeoPointField.tsx
|
|
1263
|
-
import React7, { useCallback as useCallback5, useEffect as
|
|
1259
|
+
import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState2 } from "react";
|
|
1264
1260
|
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1265
1261
|
import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1266
1262
|
import { safeParseFloat } from "@dxos/util";
|
|
1263
|
+
import { translationKey as translationKey4 } from "#translations";
|
|
1267
1264
|
var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1268
|
-
const { t } = useTranslation4(
|
|
1265
|
+
const { t } = useTranslation4(translationKey4);
|
|
1269
1266
|
const { status, error } = getStatus();
|
|
1270
1267
|
const geoPoint = useMemo5(() => getValue() ?? [
|
|
1271
1268
|
0,
|
|
@@ -1278,7 +1275,7 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1278
1275
|
]);
|
|
1279
1276
|
const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
|
|
1280
1277
|
const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
|
|
1281
|
-
|
|
1278
|
+
useEffect3(() => {
|
|
1282
1279
|
const location = GeoLocation3.fromGeoPoint(geoPoint);
|
|
1283
1280
|
setLongitudeText(location.longitude?.toString());
|
|
1284
1281
|
setLatitudeText(location.latitude?.toString());
|
|
@@ -1320,24 +1317,24 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1320
1317
|
asChild: true
|
|
1321
1318
|
}), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
|
|
1322
1319
|
role: "none",
|
|
1323
|
-
className: "grid grid-cols-2 gap-
|
|
1324
|
-
}, /* @__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, {
|
|
1325
1322
|
type: "number",
|
|
1326
1323
|
step: "0.00001",
|
|
1327
1324
|
min: "-90",
|
|
1328
1325
|
max: "90",
|
|
1329
1326
|
disabled: !!readonly,
|
|
1330
|
-
placeholder: t("latitude
|
|
1327
|
+
placeholder: t("latitude.placeholder"),
|
|
1331
1328
|
value: latitudeText ?? "",
|
|
1332
1329
|
onChange: handleChange("latitude", setLatitudeText),
|
|
1333
1330
|
onBlur
|
|
1334
|
-
}))), /* @__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, {
|
|
1335
1332
|
type: "number",
|
|
1336
1333
|
step: "0.00001",
|
|
1337
1334
|
min: "-180",
|
|
1338
1335
|
max: "180",
|
|
1339
1336
|
disabled: !!readonly,
|
|
1340
|
-
placeholder: t("longitude
|
|
1337
|
+
placeholder: t("longitude.placeholder"),
|
|
1341
1338
|
value: longitudeText ?? "",
|
|
1342
1339
|
onChange: handleChange("longitude", setLongitudeText),
|
|
1343
1340
|
onBlur
|
|
@@ -1347,7 +1344,7 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1347
1344
|
const latHem = latitude >= 0 ? "N" : "S";
|
|
1348
1345
|
const lngHem = longitude >= 0 ? "E" : "W";
|
|
1349
1346
|
return /* @__PURE__ */ React7.createElement("span", {
|
|
1350
|
-
className: "inline-flex items-center gap-
|
|
1347
|
+
className: "inline-flex items-center gap-form-gap"
|
|
1351
1348
|
}, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
1352
1349
|
className: "text-subdued"
|
|
1353
1350
|
}, "\xB0", latHem)), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
@@ -1356,56 +1353,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1356
1353
|
};
|
|
1357
1354
|
|
|
1358
1355
|
// src/components/Form/fields/MarkdownField.tsx
|
|
1359
|
-
import
|
|
1360
|
-
import {
|
|
1361
|
-
|
|
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 }) => {
|
|
1362
1368
|
const { status, error } = getStatus();
|
|
1363
|
-
const
|
|
1364
|
-
const adjustHeight = useCallback6(() => {
|
|
1365
|
-
const textarea = textareaRef.current;
|
|
1366
|
-
if (textarea) {
|
|
1367
|
-
textarea.style.blockSize = "auto";
|
|
1368
|
-
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
1369
|
-
}
|
|
1370
|
-
}, []);
|
|
1371
|
-
useEffect5(() => {
|
|
1372
|
-
adjustHeight();
|
|
1373
|
-
}, [
|
|
1374
|
-
adjustHeight
|
|
1375
|
-
]);
|
|
1376
|
-
useEffect5(() => {
|
|
1377
|
-
adjustHeight();
|
|
1378
|
-
}, [
|
|
1379
|
-
getValue(),
|
|
1380
|
-
adjustHeight
|
|
1381
|
-
]);
|
|
1382
|
-
const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
|
|
1383
|
-
type,
|
|
1384
|
-
onValueChange
|
|
1385
|
-
]);
|
|
1369
|
+
const isRef = Ref2.isRefType(type);
|
|
1386
1370
|
const value3 = getValue();
|
|
1387
|
-
if ((readonly || layout === "static") &&
|
|
1371
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1388
1372
|
return null;
|
|
1389
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
|
+
};
|
|
1390
1410
|
return /* @__PURE__ */ React8.createElement(Input4.Root, {
|
|
1391
1411
|
validationValence: status
|
|
1392
1412
|
}, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
|
|
1393
1413
|
error,
|
|
1394
1414
|
readonly,
|
|
1395
1415
|
label
|
|
1396
|
-
}), layout === "static" ?
|
|
1397
|
-
|
|
1398
|
-
|
|
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({
|
|
1399
1445
|
placeholder,
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
})
|
|
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")));
|
|
1409
1491
|
};
|
|
1410
1492
|
|
|
1411
1493
|
// src/components/Form/fields/NumberField.tsx
|
|
@@ -1431,47 +1513,32 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
|
|
|
1431
1513
|
};
|
|
1432
1514
|
|
|
1433
1515
|
// src/components/Form/fields/RefField.tsx
|
|
1516
|
+
import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
|
|
1434
1517
|
import "@dxos/lit-ui/dx-tag-picker.pcss";
|
|
1435
|
-
import
|
|
1436
|
-
import {
|
|
1437
|
-
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
1438
|
-
import {
|
|
1439
|
-
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";
|
|
1440
1522
|
import { DXN } from "@dxos/keys";
|
|
1441
1523
|
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1442
|
-
import { Button, Icon as
|
|
1443
|
-
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";
|
|
1444
1527
|
|
|
1445
1528
|
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1446
|
-
import React10, { forwardRef
|
|
1447
|
-
import { Popover, useTranslation as
|
|
1448
|
-
import { Combobox, useSearchListInput, useSearchListResults } from "@dxos/react-ui-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
const {
|
|
1452
|
-
return /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1453
|
-
value: "__create__",
|
|
1454
|
-
label: t(createOptionLabel[0], {
|
|
1455
|
-
ns: createOptionLabel[1].ns,
|
|
1456
|
-
text: query
|
|
1457
|
-
}),
|
|
1458
|
-
icon: createOptionIcon,
|
|
1459
|
-
classNames: "flex items-center gap-2",
|
|
1460
|
-
closeOnSelect: false,
|
|
1461
|
-
onSelect: () => {
|
|
1462
|
-
onCreateItemSelect(query);
|
|
1463
|
-
}
|
|
1464
|
-
});
|
|
1465
|
-
};
|
|
1466
|
-
var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
|
|
1467
|
-
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, useSearchListInput, useSearchListResults } from "@dxos/react-ui-search";
|
|
1532
|
+
import { translationKey as translationKey6 } from "#translations";
|
|
1533
|
+
var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
|
|
1534
|
+
const { t } = useTranslation6(translationKey6);
|
|
1468
1535
|
const [showForm, setShowForm] = useState3(false);
|
|
1469
1536
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1470
1537
|
const { results, handleSearch } = useSearchListResults({
|
|
1471
1538
|
items: options
|
|
1472
1539
|
});
|
|
1473
|
-
const handleFormSave = useCallback8((values) => {
|
|
1474
|
-
onCreate?.(values);
|
|
1540
|
+
const handleFormSave = useCallback8(async (values) => {
|
|
1541
|
+
await onCreate?.(values);
|
|
1475
1542
|
setShowForm(false);
|
|
1476
1543
|
setFormInitialValue("");
|
|
1477
1544
|
}, [
|
|
@@ -1493,21 +1560,30 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1493
1560
|
}, [
|
|
1494
1561
|
createSchema
|
|
1495
1562
|
]);
|
|
1563
|
+
if (showForm && createSchema) {
|
|
1564
|
+
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1565
|
+
...props,
|
|
1566
|
+
onSearch: handleSearch,
|
|
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
|
+
}
|
|
1496
1580
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1497
1581
|
...props,
|
|
1498
|
-
ref,
|
|
1499
1582
|
onSearch: handleSearch,
|
|
1500
|
-
onKeyDownCapture: handleKeyDown
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
values: createInitialValuePath ? {
|
|
1505
|
-
[createInitialValuePath]: formInitialValue
|
|
1506
|
-
} : {},
|
|
1507
|
-
onSave: handleFormSave,
|
|
1508
|
-
onCancel: handleFormCancel
|
|
1509
|
-
}, /* @__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, {
|
|
1510
|
-
placeholder: t("ref field combobox input placeholder"),
|
|
1583
|
+
onKeyDownCapture: handleKeyDown,
|
|
1584
|
+
ref: forwardedRef
|
|
1585
|
+
}, /* @__PURE__ */ React10.createElement(Combobox.Input, {
|
|
1586
|
+
placeholder: t("ref-field-combobox-input.placeholder"),
|
|
1511
1587
|
autoFocus: true
|
|
1512
1588
|
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1513
1589
|
key: option.id,
|
|
@@ -1516,16 +1592,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1516
1592
|
checked: selectedIds?.includes(option.id),
|
|
1517
1593
|
onSelect: () => onSelect(option.id),
|
|
1518
1594
|
classNames: "flex items-center gap-2"
|
|
1519
|
-
})),
|
|
1595
|
+
})), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
|
|
1520
1596
|
createOptionLabel,
|
|
1521
|
-
createOptionIcon,
|
|
1597
|
+
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
1522
1598
|
onCreateItemSelect: (query) => {
|
|
1523
1599
|
setFormInitialValue(query);
|
|
1524
1600
|
setShowForm(true);
|
|
1525
1601
|
}
|
|
1526
|
-
}))
|
|
1602
|
+
})), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1527
1603
|
});
|
|
1528
|
-
|
|
1604
|
+
var CreateItem = ({ createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
|
|
1605
|
+
const { t } = useTranslation6(translationKey6);
|
|
1606
|
+
const { query } = useSearchListInput();
|
|
1607
|
+
const label = createOptionLabel ? t(createOptionLabel[0], {
|
|
1608
|
+
ns: createOptionLabel[1].ns,
|
|
1609
|
+
text: query
|
|
1610
|
+
}) : t("create-option.label");
|
|
1611
|
+
return /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1612
|
+
value: "__create__",
|
|
1613
|
+
label,
|
|
1614
|
+
icon: createOptionIcon,
|
|
1615
|
+
classNames: "flex items-center gap-2",
|
|
1616
|
+
closeOnSelect: false,
|
|
1617
|
+
onSelect: () => {
|
|
1618
|
+
onCreateItemSelect(query);
|
|
1619
|
+
}
|
|
1620
|
+
});
|
|
1621
|
+
};
|
|
1622
|
+
ObjectPickerContent.displayName = "ObjectPicker.Content";
|
|
1529
1623
|
var ObjectPicker = {
|
|
1530
1624
|
Root: Combobox.Root,
|
|
1531
1625
|
Portal: Combobox.Portal,
|
|
@@ -1538,34 +1632,43 @@ var ObjectPicker = {
|
|
|
1538
1632
|
var isRefSnapshot = (val) => {
|
|
1539
1633
|
return typeof val === "object" && typeof val?.["/"] === "string";
|
|
1540
1634
|
};
|
|
1541
|
-
var defaultGetOptions = (results) => results.map((result) => {
|
|
1635
|
+
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1542
1636
|
const id = Entity.getDXN(result).toString();
|
|
1543
|
-
const
|
|
1637
|
+
const parent = parentLabel ? Obj2.getParent(result) : void 0;
|
|
1638
|
+
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1544
1639
|
return {
|
|
1545
1640
|
id,
|
|
1546
1641
|
label: label ?? id
|
|
1547
1642
|
};
|
|
1548
1643
|
});
|
|
1549
|
-
var
|
|
1644
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1550
1645
|
var RefField = (props) => {
|
|
1551
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db,
|
|
1552
|
-
const { t } =
|
|
1646
|
+
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
|
|
1647
|
+
const { t } = useTranslation7(translationKey7);
|
|
1553
1648
|
const { status, error } = getStatus();
|
|
1554
|
-
const typename =
|
|
1649
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1555
1650
|
type
|
|
1556
1651
|
]);
|
|
1557
1652
|
const results = useResults(db, typename);
|
|
1558
|
-
const options =
|
|
1653
|
+
const options = useMemo7(() => {
|
|
1654
|
+
const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
|
|
1655
|
+
return getOptions(results, {
|
|
1656
|
+
parentLabel
|
|
1657
|
+
});
|
|
1658
|
+
}, [
|
|
1559
1659
|
results,
|
|
1560
|
-
|
|
1660
|
+
getOptions,
|
|
1661
|
+
type
|
|
1561
1662
|
]);
|
|
1562
1663
|
const handleGetValue = useCallback9(() => {
|
|
1563
1664
|
const formValue = getValue();
|
|
1665
|
+
const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
|
|
1564
1666
|
const unknownToRefOption = (value3) => {
|
|
1565
|
-
const isRef =
|
|
1667
|
+
const isRef = Ref3.isRef(value3);
|
|
1566
1668
|
if (isRef || isRefSnapshot(value3)) {
|
|
1567
1669
|
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1568
|
-
const
|
|
1670
|
+
const objectId = dxnToObjectId(dxnString);
|
|
1671
|
+
const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
|
|
1569
1672
|
if (matchingOption) {
|
|
1570
1673
|
return matchingOption;
|
|
1571
1674
|
}
|
|
@@ -1577,29 +1680,37 @@ var RefField = (props) => {
|
|
|
1577
1680
|
options,
|
|
1578
1681
|
getValue
|
|
1579
1682
|
]);
|
|
1580
|
-
const handleUpdate = useCallback9((id) => {
|
|
1581
|
-
const item2 = options.find((option) => option.id === id);
|
|
1582
|
-
const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1583
|
-
onValueChange(type, ref);
|
|
1584
|
-
}, [
|
|
1585
|
-
options,
|
|
1586
|
-
type,
|
|
1587
|
-
onValueChange
|
|
1588
|
-
]);
|
|
1589
1683
|
const item = handleGetValue();
|
|
1590
|
-
const selectedIds =
|
|
1684
|
+
const selectedIds = useMemo7(() => item ? [
|
|
1591
1685
|
item.id
|
|
1592
1686
|
] : [], [
|
|
1593
1687
|
item
|
|
1594
1688
|
]);
|
|
1595
1689
|
const createSchema = useSchema(db, typename);
|
|
1596
|
-
const
|
|
1597
|
-
|
|
1598
|
-
|
|
1690
|
+
const [open, setOpen] = useState4(false);
|
|
1691
|
+
const handleCreate = useCallback9(async (values) => {
|
|
1692
|
+
if (!createSchema || !onCreate) {
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1695
|
+
const newObject = await onCreate(createSchema, values);
|
|
1696
|
+
if (newObject) {
|
|
1697
|
+
onValueChange(type, Ref3.make(newObject));
|
|
1599
1698
|
}
|
|
1699
|
+
setOpen(false);
|
|
1600
1700
|
}, [
|
|
1601
1701
|
createSchema,
|
|
1602
|
-
onCreate
|
|
1702
|
+
onCreate,
|
|
1703
|
+
type,
|
|
1704
|
+
onValueChange
|
|
1705
|
+
]);
|
|
1706
|
+
const handleUpdate = useCallback9((id) => {
|
|
1707
|
+
const item2 = options.find((option) => option.id === id);
|
|
1708
|
+
const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1709
|
+
onValueChange(type, ref);
|
|
1710
|
+
}, [
|
|
1711
|
+
options,
|
|
1712
|
+
type,
|
|
1713
|
+
onValueChange
|
|
1603
1714
|
]);
|
|
1604
1715
|
const handleSelect = useCallback9((id) => {
|
|
1605
1716
|
if (item?.id === id) {
|
|
@@ -1621,40 +1732,48 @@ var RefField = (props) => {
|
|
|
1621
1732
|
readonly,
|
|
1622
1733
|
label
|
|
1623
1734
|
}), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
|
|
1624
|
-
className:
|
|
1625
|
-
}, t("empty
|
|
1735
|
+
className: "text-description mb-2"
|
|
1736
|
+
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
|
|
1626
1737
|
key: item.id,
|
|
1627
1738
|
dxn: item.id,
|
|
1628
1739
|
rootclassname: "me-1"
|
|
1629
|
-
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root,
|
|
1740
|
+
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
|
|
1741
|
+
open,
|
|
1742
|
+
onOpenChange: setOpen
|
|
1743
|
+
}, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
|
|
1630
1744
|
asChild: true,
|
|
1631
1745
|
classNames: "p-0"
|
|
1632
1746
|
}, item ? /* @__PURE__ */ React11.createElement("div", {
|
|
1633
|
-
|
|
1747
|
+
role: "none",
|
|
1748
|
+
className: "flex gap-form-gap w-full"
|
|
1634
1749
|
}, /* @__PURE__ */ React11.createElement(Input6.Root, {
|
|
1635
1750
|
key: item.id
|
|
1636
1751
|
}, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
|
|
1637
1752
|
value: item.label,
|
|
1638
1753
|
readOnly: true,
|
|
1639
1754
|
classNames: "w-full"
|
|
1640
|
-
}))) : /* @__PURE__ */ React11.createElement(
|
|
1641
|
-
classNames: "w-full text-start gap-
|
|
1755
|
+
}))) : /* @__PURE__ */ React11.createElement(Button2, {
|
|
1756
|
+
classNames: "w-full text-start gap-form-gap"
|
|
1642
1757
|
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1643
1758
|
role: "none",
|
|
1644
1759
|
className: "grow overflow-hidden"
|
|
1645
1760
|
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1646
|
-
className: "
|
|
1647
|
-
}, placeholder ?? t("ref
|
|
1761
|
+
className: "truncate text-description"
|
|
1762
|
+
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
|
|
1648
1763
|
size: 3,
|
|
1649
1764
|
icon: "ph--caret-down--bold"
|
|
1650
1765
|
}))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
|
|
1651
1766
|
classNames: "dx-card-popover-width",
|
|
1652
1767
|
options,
|
|
1653
1768
|
selectedIds,
|
|
1654
|
-
|
|
1769
|
+
// Strip hidden (`FormInputAnnotation.set(false)`) fields so the
|
|
1770
|
+
// form's validator doesn't reject required-but-hidden fields
|
|
1771
|
+
// such as backing-object refs supplied by a `FactoryAnnotation`.
|
|
1772
|
+
createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
|
|
1655
1773
|
createOptionLabel,
|
|
1656
1774
|
createOptionIcon,
|
|
1657
1775
|
createInitialValuePath,
|
|
1776
|
+
createFieldMap: createFieldMap3,
|
|
1658
1777
|
onCreate: handleCreate,
|
|
1659
1778
|
onSelect: handleSelect
|
|
1660
1779
|
})))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
|
|
@@ -1696,20 +1815,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1696
1815
|
};
|
|
1697
1816
|
|
|
1698
1817
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1699
|
-
import React13, { useCallback as useCallback11, useEffect as
|
|
1818
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1700
1819
|
import { PublicKey } from "@dxos/keys";
|
|
1701
|
-
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as
|
|
1820
|
+
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
|
|
1702
1821
|
import { List } from "@dxos/react-ui-list";
|
|
1703
1822
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1704
1823
|
import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
|
|
1824
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1705
1825
|
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
1706
|
-
const { t } =
|
|
1826
|
+
const { t } = useTranslation8(translationKey8);
|
|
1707
1827
|
const { status, error } = getStatus();
|
|
1708
|
-
const [selected, setSelectedId] =
|
|
1709
|
-
const [isNewOption, setIsNewOption] =
|
|
1710
|
-
const inputRef =
|
|
1828
|
+
const [selected, setSelectedId] = useState5(null);
|
|
1829
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
1830
|
+
const inputRef = useRef2(null);
|
|
1711
1831
|
const options = getValue();
|
|
1712
|
-
|
|
1832
|
+
useEffect4(() => {
|
|
1713
1833
|
if (options === void 0) {
|
|
1714
1834
|
onValueChange(type, []);
|
|
1715
1835
|
}
|
|
@@ -1800,7 +1920,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1800
1920
|
type,
|
|
1801
1921
|
onValueChange
|
|
1802
1922
|
]);
|
|
1803
|
-
|
|
1923
|
+
useEffect4(() => {
|
|
1804
1924
|
if (selected && isNewOption && inputRef.current) {
|
|
1805
1925
|
inputRef.current.focus();
|
|
1806
1926
|
setIsNewOption(false);
|
|
@@ -1853,14 +1973,14 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1853
1973
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
1854
1974
|
onClick: () => handleClick(item.id)
|
|
1855
1975
|
})), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
|
|
1856
|
-
className: "flex flex-col p-form-padding gap-
|
|
1976
|
+
className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
|
|
1857
1977
|
}, /* @__PURE__ */ React13.createElement(Input8.Label, {
|
|
1858
1978
|
classNames: "text-xs"
|
|
1859
|
-
}, t("select
|
|
1860
|
-
className: "grid grid-cols-[1fr_min-content_min-content] gap-
|
|
1979
|
+
}, t("select-option.label")), /* @__PURE__ */ React13.createElement("div", {
|
|
1980
|
+
className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
|
|
1861
1981
|
}, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
|
|
1862
1982
|
disabled: !!readonly,
|
|
1863
|
-
placeholder: t("select
|
|
1983
|
+
placeholder: t("select-option-label.placeholder"),
|
|
1864
1984
|
ref: selected === item.id ? inputRef : void 0,
|
|
1865
1985
|
value: item.title,
|
|
1866
1986
|
onChange: handleTitleChange(item.id),
|
|
@@ -1874,12 +1994,12 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1874
1994
|
disabled: !!readonly,
|
|
1875
1995
|
icon: "ph--trash--fill",
|
|
1876
1996
|
iconOnly: true,
|
|
1877
|
-
label: t("select
|
|
1997
|
+
label: t("select-option-delete.button"),
|
|
1878
1998
|
onClick: () => handleDelete(item.id)
|
|
1879
1999
|
})))))), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1880
2000
|
variant: "ghost",
|
|
1881
2001
|
icon: "ph--plus--regular",
|
|
1882
|
-
label: t("select
|
|
2002
|
+
label: t("select-option-add.button"),
|
|
1883
2003
|
onClick: handleAdd,
|
|
1884
2004
|
disabled: !!readonly,
|
|
1885
2005
|
classNames: "w-full"
|
|
@@ -1889,7 +2009,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1889
2009
|
// src/components/Form/fields/TextField.tsx
|
|
1890
2010
|
import React14, { useCallback as useCallback12 } from "react";
|
|
1891
2011
|
import { Input as Input9 } from "@dxos/react-ui";
|
|
1892
|
-
var TextField = ({ type, readonly, placeholder,
|
|
2012
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
1893
2013
|
const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
|
|
1894
2014
|
type,
|
|
1895
2015
|
onValueChange
|
|
@@ -1902,8 +2022,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
|
|
|
1902
2022
|
disabled: !!readonly,
|
|
1903
2023
|
placeholder,
|
|
1904
2024
|
value: value3,
|
|
1905
|
-
|
|
1906
|
-
|
|
2025
|
+
onBlur,
|
|
2026
|
+
onChange: handleChange
|
|
1907
2027
|
}));
|
|
1908
2028
|
};
|
|
1909
2029
|
|
|
@@ -1931,7 +2051,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1931
2051
|
// src/components/Form/fields/TupleField.tsx
|
|
1932
2052
|
import React16 from "react";
|
|
1933
2053
|
import { Input as Input11 } from "@dxos/react-ui";
|
|
1934
|
-
import { mx as
|
|
2054
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1935
2055
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1936
2056
|
var gridCols = [
|
|
1937
2057
|
"grid-cols-1",
|
|
@@ -1949,7 +2069,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1949
2069
|
readonly,
|
|
1950
2070
|
label
|
|
1951
2071
|
}), /* @__PURE__ */ React16.createElement("div", {
|
|
1952
|
-
className:
|
|
2072
|
+
className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
|
|
1953
2073
|
}, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
|
|
1954
2074
|
key: prop,
|
|
1955
2075
|
type: "number",
|
|
@@ -1968,13 +2088,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1968
2088
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1969
2089
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1970
2090
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
1971
|
-
const { t } =
|
|
1972
|
-
const [props, setProps] =
|
|
1973
|
-
|
|
2091
|
+
const { t } = useTranslation9(translationKey9);
|
|
2092
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2093
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1974
2094
|
field,
|
|
1975
2095
|
projection
|
|
1976
2096
|
]);
|
|
1977
|
-
const [schemas, setSchemas] =
|
|
2097
|
+
const [schemas, setSchemas] = useState6([]);
|
|
1978
2098
|
useAsyncEffect(async () => {
|
|
1979
2099
|
if (!registry) {
|
|
1980
2100
|
return;
|
|
@@ -1988,22 +2108,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
1988
2108
|
}, [
|
|
1989
2109
|
registry
|
|
1990
2110
|
]);
|
|
1991
|
-
const [referenceSchema, setReferenceSchema] =
|
|
1992
|
-
|
|
2111
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2112
|
+
useEffect5(() => {
|
|
1993
2113
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
1994
2114
|
}, [
|
|
1995
2115
|
schemas,
|
|
1996
2116
|
props?.referenceSchema
|
|
1997
2117
|
]);
|
|
1998
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2118
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
1999
2119
|
fieldSchema: getFormatSchema(props?.format)
|
|
2000
2120
|
});
|
|
2001
|
-
const fieldMap =
|
|
2121
|
+
const fieldMap = useMemo8(() => ({
|
|
2002
2122
|
["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
2003
2123
|
...props2,
|
|
2004
2124
|
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
2005
2125
|
value: value3,
|
|
2006
|
-
label: t(`format
|
|
2126
|
+
label: t(`format.${value3}.label`)
|
|
2007
2127
|
}))
|
|
2008
2128
|
}),
|
|
2009
2129
|
["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
@@ -2077,7 +2197,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2077
2197
|
]);
|
|
2078
2198
|
const handleSave = useCallback14((props2) => {
|
|
2079
2199
|
if (view) {
|
|
2080
|
-
|
|
2200
|
+
Obj3.update(view, () => {
|
|
2081
2201
|
projection.setFieldProjection({
|
|
2082
2202
|
field,
|
|
2083
2203
|
props: props2
|
|
@@ -2105,12 +2225,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2105
2225
|
if (!fieldSchema) {
|
|
2106
2226
|
log2.warn("invalid format", {
|
|
2107
2227
|
props
|
|
2108
|
-
}, {
|
|
2109
|
-
F: __dxlog_file2,
|
|
2110
|
-
L: 172,
|
|
2111
|
-
S: void 0,
|
|
2112
|
-
C: (f, a) => f(...a)
|
|
2113
|
-
});
|
|
2228
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2114
2229
|
return null;
|
|
2115
2230
|
}
|
|
2116
2231
|
return /* @__PURE__ */ React17.createElement(Form.Root, {
|
|
@@ -2132,160 +2247,491 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2132
2247
|
}, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
|
|
2133
2248
|
};
|
|
2134
2249
|
|
|
2135
|
-
// src/components/
|
|
2136
|
-
import
|
|
2137
|
-
import
|
|
2138
|
-
import {
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
var
|
|
2145
|
-
var
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
};
|
|
2162
|
-
|
|
2163
|
-
var SettingsSection = ({ title, description, children }) => {
|
|
2164
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SettingsSectionHeading, {
|
|
2165
|
-
title,
|
|
2166
|
-
description
|
|
2167
|
-
}), /* @__PURE__ */ React18.createElement("div", {
|
|
2168
|
-
className: "w-full pt-trim-md space-y-trim-md"
|
|
2169
|
-
}, children));
|
|
2170
|
-
};
|
|
2171
|
-
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2172
|
-
var SettingsSectionHeading = ({ title, description }) => {
|
|
2173
|
-
const { t } = useTranslation9(translationKey);
|
|
2174
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
|
|
2175
|
-
className: "px-trim-md mt-trim-md mb-trim-md text-xl"
|
|
2176
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
|
|
2177
|
-
className: "px-trim-md my-trim-md text-description"
|
|
2178
|
-
}, toLocalizedString(description, t)));
|
|
2250
|
+
// src/components/ObjectForm/ObjectForm.tsx
|
|
2251
|
+
import * as Schema3 from "effect/Schema";
|
|
2252
|
+
import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
|
|
2253
|
+
import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
|
|
2254
|
+
import { splitJsonPath } from "@dxos/echo/internal";
|
|
2255
|
+
import { invariant } from "@dxos/invariant";
|
|
2256
|
+
import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
|
|
2257
|
+
import { isNonNullable } from "@dxos/util";
|
|
2258
|
+
import { translationKey as translationKey10 } from "#translations";
|
|
2259
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
|
|
2260
|
+
var createFieldMap = {
|
|
2261
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2262
|
+
const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
|
|
2263
|
+
onValueChange,
|
|
2264
|
+
type
|
|
2265
|
+
]);
|
|
2266
|
+
const handleReset = useCallback15(() => onValueChange(type, void 0), [
|
|
2267
|
+
onValueChange,
|
|
2268
|
+
type
|
|
2269
|
+
]);
|
|
2270
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
|
|
2271
|
+
label
|
|
2272
|
+
}), /* @__PURE__ */ React18.createElement(HuePicker2, {
|
|
2273
|
+
value: getValue(),
|
|
2274
|
+
onChange: handleChange,
|
|
2275
|
+
onReset: handleReset
|
|
2276
|
+
}));
|
|
2277
|
+
}
|
|
2179
2278
|
};
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2279
|
+
var ObjectForm = ({ object, schema }) => {
|
|
2280
|
+
const db = Obj4.getDatabase(object);
|
|
2281
|
+
const meta = Obj4.getMeta(object);
|
|
2282
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
|
|
2283
|
+
const values = useMemo9(() => ({
|
|
2284
|
+
tags,
|
|
2285
|
+
...object
|
|
2286
|
+
}), [
|
|
2287
|
+
object,
|
|
2288
|
+
tags
|
|
2289
|
+
]);
|
|
2290
|
+
const formSchema = useMemo9(() => omitId(Schema3.Struct({
|
|
2291
|
+
tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
|
|
2292
|
+
}).pipe(Schema3.extend(schema))), [
|
|
2293
|
+
schema
|
|
2294
|
+
]);
|
|
2295
|
+
const handleCreate = useCallback15((schema2, values2) => {
|
|
2296
|
+
invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
|
|
2297
|
+
invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2298
|
+
const newObject = db.add(Obj4.make(schema2, values2));
|
|
2299
|
+
if (Obj4.instanceOf(Tag2.Tag, newObject)) {
|
|
2300
|
+
Obj4.update(object, (object2) => {
|
|
2301
|
+
Obj4.getMeta(object2).tags = [
|
|
2302
|
+
...Obj4.getMeta(object2).tags ?? [],
|
|
2303
|
+
Obj4.getDXN(newObject).toString()
|
|
2304
|
+
];
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2307
|
+
}, []);
|
|
2308
|
+
const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2309
|
+
if (!isValid) {
|
|
2310
|
+
return;
|
|
2311
|
+
}
|
|
2312
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2313
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
|
|
2314
|
+
if (hasTagsChange) {
|
|
2315
|
+
Obj4.update(object, (object2) => {
|
|
2316
|
+
Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2319
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
|
|
2320
|
+
if (nonTagPaths.length > 0) {
|
|
2321
|
+
Obj4.update(object, () => {
|
|
2322
|
+
for (const path of nonTagPaths) {
|
|
2323
|
+
const parts = splitJsonPath(path);
|
|
2324
|
+
const value3 = Obj4.getValue(values2, parts);
|
|
2325
|
+
Obj4.setValue(object, parts, value3);
|
|
2326
|
+
}
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
2329
|
+
}, [
|
|
2330
|
+
object
|
|
2331
|
+
]);
|
|
2332
|
+
return /* @__PURE__ */ React18.createElement(Form.Root, {
|
|
2333
|
+
schema: formSchema,
|
|
2334
|
+
defaultValues: values,
|
|
2335
|
+
createTypename: Type2.getTypename(Tag2.Tag),
|
|
2336
|
+
createOptionIcon: "ph--plus--regular",
|
|
2337
|
+
createOptionLabel: [
|
|
2338
|
+
"add-tag.label",
|
|
2339
|
+
{
|
|
2340
|
+
ns: translationKey10
|
|
2341
|
+
}
|
|
2342
|
+
],
|
|
2343
|
+
createInitialValuePath: "label",
|
|
2344
|
+
createFieldMap,
|
|
2345
|
+
db,
|
|
2346
|
+
onValuesChanged: handleChange,
|
|
2347
|
+
onCreate: handleCreate
|
|
2348
|
+
}, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
|
|
2189
2349
|
};
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2350
|
+
|
|
2351
|
+
// src/components/ObjectProperties/ObjectProperties.tsx
|
|
2352
|
+
import * as Function from "effect/Function";
|
|
2353
|
+
import * as Option5 from "effect/Option";
|
|
2354
|
+
import * as Schema4 from "effect/Schema";
|
|
2355
|
+
import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
|
|
2356
|
+
import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
|
|
2357
|
+
import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
|
|
2358
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2359
|
+
import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
|
|
2360
|
+
import { FactoryAnnotation } from "@dxos/schema";
|
|
2361
|
+
import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
|
|
2362
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
2363
|
+
import { translationKey as translationKey11 } from "#translations";
|
|
2364
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
|
|
2365
|
+
var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
|
|
2366
|
+
const db = Obj5.getDatabase(object);
|
|
2367
|
+
const meta = Obj5.getMeta(object);
|
|
2368
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
|
|
2369
|
+
const values = useMemo10(() => ({
|
|
2370
|
+
tags,
|
|
2371
|
+
...object
|
|
2372
|
+
}), [
|
|
2373
|
+
object,
|
|
2374
|
+
tags
|
|
2375
|
+
]);
|
|
2376
|
+
const formSchema = useMemo10(() => {
|
|
2377
|
+
return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
|
|
2378
|
+
}, [
|
|
2379
|
+
object
|
|
2380
|
+
]);
|
|
2381
|
+
const handleCreate = useCallback16((schema, values2) => {
|
|
2382
|
+
invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
|
|
2383
|
+
invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2384
|
+
const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
|
|
2385
|
+
const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
|
|
2386
|
+
return db.add(newObject);
|
|
2387
|
+
}, [
|
|
2388
|
+
db
|
|
2389
|
+
]);
|
|
2390
|
+
const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2391
|
+
if (!isValid) {
|
|
2392
|
+
return;
|
|
2393
|
+
}
|
|
2394
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2395
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
|
|
2396
|
+
if (hasTagsChange) {
|
|
2397
|
+
Obj5.update(object, (object2) => {
|
|
2398
|
+
Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
|
|
2402
|
+
if (nonTagPaths.length > 0) {
|
|
2403
|
+
Obj5.update(object, () => {
|
|
2404
|
+
for (const path of nonTagPaths) {
|
|
2405
|
+
const parts = splitJsonPath2(path);
|
|
2406
|
+
const value3 = Obj5.getValue(values2, parts);
|
|
2407
|
+
Obj5.setValue(object, parts, value3);
|
|
2408
|
+
}
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
}, [
|
|
2412
|
+
object
|
|
2413
|
+
]);
|
|
2414
|
+
if (!formSchema) {
|
|
2415
|
+
return null;
|
|
2416
|
+
}
|
|
2417
|
+
return /* @__PURE__ */ React19.createElement(Form.Root, {
|
|
2418
|
+
schema: formSchema,
|
|
2419
|
+
defaultValues: values,
|
|
2420
|
+
createTypename: Type3.getTypename(Tag3.Tag),
|
|
2421
|
+
createOptionIcon: "ph--plus--regular",
|
|
2422
|
+
createOptionLabel: [
|
|
2423
|
+
"add-tag.label",
|
|
2424
|
+
{
|
|
2425
|
+
ns: translationKey11
|
|
2426
|
+
}
|
|
2427
|
+
],
|
|
2428
|
+
createInitialValuePath: "label",
|
|
2429
|
+
createFieldMap: createFieldMap2,
|
|
2430
|
+
db,
|
|
2431
|
+
onValuesChanged: handleChange,
|
|
2432
|
+
onCreate: handleCreate
|
|
2433
|
+
}, /* @__PURE__ */ React19.createElement(Form.Viewport, {
|
|
2434
|
+
...composableProps2(props),
|
|
2435
|
+
ref: forwardedRef
|
|
2436
|
+
}, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
|
|
2437
|
+
});
|
|
2438
|
+
var createFieldMap2 = {
|
|
2439
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2440
|
+
const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
|
|
2441
|
+
onValueChange,
|
|
2442
|
+
type
|
|
2443
|
+
]);
|
|
2444
|
+
const handleReset = useCallback16(() => onValueChange(type, void 0), [
|
|
2445
|
+
onValueChange,
|
|
2446
|
+
type
|
|
2447
|
+
]);
|
|
2448
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
|
|
2449
|
+
label
|
|
2450
|
+
}), /* @__PURE__ */ React19.createElement(HuePicker3, {
|
|
2451
|
+
value: getValue(),
|
|
2452
|
+
onChange: handleChange,
|
|
2453
|
+
onReset: handleReset
|
|
2454
|
+
}));
|
|
2455
|
+
}
|
|
2211
2456
|
};
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2457
|
+
var BaseSchema = Schema4.Struct({
|
|
2458
|
+
tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
|
|
2459
|
+
});
|
|
2460
|
+
|
|
2461
|
+
// src/components/Settings/Settings.tsx
|
|
2462
|
+
import React22 from "react";
|
|
2463
|
+
import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
|
|
2464
|
+
import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
|
|
2465
|
+
import { translationKey as translationKey13 } from "#translations";
|
|
2466
|
+
|
|
2467
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2468
|
+
import * as SchemaAST5 from "effect/SchemaAST";
|
|
2469
|
+
import * as String3 from "effect/String";
|
|
2470
|
+
import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
|
|
2471
|
+
import { getAnnotation as getAnnotation3 } from "@dxos/effect";
|
|
2472
|
+
import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
|
|
2473
|
+
|
|
2474
|
+
// src/components/Settings/SettingsItem.tsx
|
|
2475
|
+
import React20 from "react";
|
|
2476
|
+
import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
2477
|
+
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2478
|
+
import { translationKey as translationKey12 } from "#translations";
|
|
2479
|
+
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
2480
|
+
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
2481
|
+
var SettingsPanel = ({ classNames, children }) => {
|
|
2482
|
+
return /* @__PURE__ */ React20.createElement("div", {
|
|
2215
2483
|
role: "none",
|
|
2216
|
-
className:
|
|
2217
|
-
"dx-article",
|
|
2218
|
-
"*:first:mt-0! *:last:mb-0! px-trim-md py-trim-md",
|
|
2219
|
-
"border border-separator rounded-md",
|
|
2220
|
-
classNames
|
|
2221
|
-
])
|
|
2484
|
+
className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2222
2485
|
}, children);
|
|
2223
2486
|
};
|
|
2224
|
-
|
|
2487
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2225
2488
|
var SettingsItem = ({ title, description = "", children }) => {
|
|
2226
|
-
const { t } =
|
|
2227
|
-
return /* @__PURE__ */
|
|
2228
|
-
classNames:
|
|
2229
|
-
}, /* @__PURE__ */
|
|
2230
|
-
|
|
2231
|
-
}, toLocalizedString(title, t)), /* @__PURE__ */
|
|
2232
|
-
|
|
2233
|
-
}, toLocalizedString(description, t)), /* @__PURE__ */
|
|
2489
|
+
const { t } = useTranslation10(translationKey12);
|
|
2490
|
+
return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
|
|
2491
|
+
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
2492
|
+
}, /* @__PURE__ */ React20.createElement(Input12.Label, {
|
|
2493
|
+
classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
|
|
2494
|
+
}, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
|
|
2495
|
+
classNames: "text-base text-description"
|
|
2496
|
+
}, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
|
|
2234
2497
|
role: "none",
|
|
2235
|
-
className: "
|
|
2236
|
-
}, children));
|
|
2498
|
+
className: "text-end py-1"
|
|
2499
|
+
}, children)));
|
|
2237
2500
|
};
|
|
2238
2501
|
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2502
|
+
|
|
2503
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2504
|
+
var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
|
|
2505
|
+
const properties = useMemo11(() => {
|
|
2506
|
+
const props = getFormProperties(schema.ast);
|
|
2507
|
+
if (!sort) {
|
|
2508
|
+
return props;
|
|
2509
|
+
}
|
|
2510
|
+
const rank = (name) => {
|
|
2511
|
+
const idx = sort.indexOf(name);
|
|
2512
|
+
return idx === -1 ? Number.POSITIVE_INFINITY : idx;
|
|
2513
|
+
};
|
|
2514
|
+
return [
|
|
2515
|
+
...props
|
|
2516
|
+
].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
|
|
2517
|
+
}, [
|
|
2518
|
+
schema,
|
|
2519
|
+
sort
|
|
2520
|
+
]);
|
|
2521
|
+
const handleChange = useCallback17((name, value3) => {
|
|
2522
|
+
onValuesChanged?.({
|
|
2523
|
+
...values,
|
|
2524
|
+
[name]: value3
|
|
2525
|
+
});
|
|
2526
|
+
}, [
|
|
2527
|
+
values,
|
|
2528
|
+
onValuesChanged
|
|
2529
|
+
]);
|
|
2530
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
|
|
2531
|
+
const name = property.name.toString();
|
|
2532
|
+
const path = pathPrefix ? `${pathPrefix}.${name}` : name;
|
|
2533
|
+
if (visible && !visible(path, values)) {
|
|
2534
|
+
return null;
|
|
2535
|
+
}
|
|
2536
|
+
const entry = fieldMap?.[name];
|
|
2537
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
|
|
2538
|
+
key: name,
|
|
2539
|
+
path,
|
|
2540
|
+
property,
|
|
2541
|
+
value: values[name],
|
|
2542
|
+
onChange: (value3) => handleChange(name, value3),
|
|
2543
|
+
readonly,
|
|
2544
|
+
customField: typeof entry === "function" ? entry : void 0,
|
|
2545
|
+
nestedFieldMap: typeof entry === "object" ? entry : void 0,
|
|
2546
|
+
visible,
|
|
2547
|
+
sort
|
|
2548
|
+
});
|
|
2549
|
+
}));
|
|
2550
|
+
};
|
|
2551
|
+
SettingsFieldSet.displayName = "Settings.FieldSet";
|
|
2552
|
+
var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
|
|
2553
|
+
const { type } = property;
|
|
2554
|
+
const name = property.name.toString();
|
|
2555
|
+
const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
|
|
2556
|
+
const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
|
|
2557
|
+
if (customField) {
|
|
2558
|
+
const CustomField = customField;
|
|
2559
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2560
|
+
title,
|
|
2561
|
+
description
|
|
2562
|
+
}, /* @__PURE__ */ React21.createElement(CustomField, {
|
|
2563
|
+
value: value3,
|
|
2564
|
+
onChange,
|
|
2565
|
+
readonly
|
|
2566
|
+
}));
|
|
2567
|
+
}
|
|
2568
|
+
const fieldType = detectFieldType(type);
|
|
2569
|
+
switch (fieldType) {
|
|
2570
|
+
case "struct":
|
|
2571
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
|
|
2572
|
+
schema: {
|
|
2573
|
+
ast: type
|
|
2574
|
+
},
|
|
2575
|
+
values: value3 ?? {},
|
|
2576
|
+
onValuesChanged: onChange,
|
|
2577
|
+
readonly,
|
|
2578
|
+
fieldMap: nestedFieldMap,
|
|
2579
|
+
visible,
|
|
2580
|
+
sort,
|
|
2581
|
+
pathPrefix: path
|
|
2582
|
+
});
|
|
2583
|
+
case "boolean":
|
|
2584
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2585
|
+
title,
|
|
2586
|
+
description
|
|
2587
|
+
}, /* @__PURE__ */ React21.createElement(Input13.Switch, {
|
|
2588
|
+
disabled: readonly,
|
|
2589
|
+
checked: !!value3,
|
|
2590
|
+
onCheckedChange: (checked) => onChange(!!checked)
|
|
2591
|
+
}));
|
|
2592
|
+
case "select": {
|
|
2593
|
+
const options = getSelectOptionsFromAst(type) ?? [];
|
|
2594
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2595
|
+
title,
|
|
2596
|
+
description
|
|
2597
|
+
}, /* @__PURE__ */ React21.createElement(Select2.Root, {
|
|
2598
|
+
disabled: readonly,
|
|
2599
|
+
value: value3 == null ? "" : globalThis.String(value3),
|
|
2600
|
+
onValueChange: (selected) => {
|
|
2601
|
+
const matched = options.find((option) => globalThis.String(option.value) === selected);
|
|
2602
|
+
onChange(matched?.value ?? selected);
|
|
2603
|
+
}
|
|
2604
|
+
}, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
|
|
2605
|
+
disabled: readonly
|
|
2606
|
+
}), /* @__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, {
|
|
2607
|
+
key: globalThis.String(option.value),
|
|
2608
|
+
value: globalThis.String(option.value)
|
|
2609
|
+
}, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
|
|
2610
|
+
}
|
|
2611
|
+
case "string":
|
|
2612
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2613
|
+
title,
|
|
2614
|
+
description
|
|
2615
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2616
|
+
disabled: readonly,
|
|
2617
|
+
value: value3 ?? "",
|
|
2618
|
+
onChange: (event) => onChange(event.target.value)
|
|
2619
|
+
}));
|
|
2620
|
+
case "number":
|
|
2621
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2622
|
+
title,
|
|
2623
|
+
description
|
|
2624
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2625
|
+
disabled: readonly,
|
|
2626
|
+
type: "number",
|
|
2627
|
+
value: value3 ?? "",
|
|
2628
|
+
onChange: (event) => {
|
|
2629
|
+
if (event.target.value === "") {
|
|
2630
|
+
onChange(void 0);
|
|
2631
|
+
return;
|
|
2632
|
+
}
|
|
2633
|
+
const parsed = Number(event.target.value);
|
|
2634
|
+
onChange(Number.isNaN(parsed) ? void 0 : parsed);
|
|
2635
|
+
}
|
|
2636
|
+
}));
|
|
2637
|
+
default:
|
|
2638
|
+
return null;
|
|
2639
|
+
}
|
|
2640
|
+
};
|
|
2641
|
+
|
|
2642
|
+
// src/components/Settings/Settings.tsx
|
|
2643
|
+
var SETTINGS_ROOT_NAME = "Settings.Root";
|
|
2644
|
+
var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
|
|
2645
|
+
var SETTINGS_SECTION_NAME = "Settings.Section";
|
|
2646
|
+
var SettingsRoot = ({ children, classNames }) => {
|
|
2647
|
+
return /* @__PURE__ */ React22.createElement("div", {
|
|
2648
|
+
className: mx4("flex flex-col gap-2", classNames)
|
|
2649
|
+
}, children);
|
|
2650
|
+
};
|
|
2651
|
+
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
2652
|
+
var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
|
|
2653
|
+
return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
|
|
2654
|
+
...composableProps3(props),
|
|
2655
|
+
orientation: "vertical",
|
|
2656
|
+
centered: true,
|
|
2657
|
+
thin: true,
|
|
2658
|
+
ref: forwardedRef
|
|
2659
|
+
}, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
|
|
2660
|
+
classNames: "px-4 pointer-coarse:px-2"
|
|
2661
|
+
}, /* @__PURE__ */ React22.createElement("div", {
|
|
2248
2662
|
role: "none",
|
|
2249
|
-
className: "
|
|
2663
|
+
className: "dx-document flex flex-col gap-2 py-4"
|
|
2250
2664
|
}, children)));
|
|
2665
|
+
});
|
|
2666
|
+
SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
|
|
2667
|
+
var SettingsSection = ({ title, description, children }) => {
|
|
2668
|
+
const { t } = useTranslation11(translationKey13);
|
|
2669
|
+
return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
|
|
2670
|
+
className: "px-trim-md mt-trim-md text-xl"
|
|
2671
|
+
}, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
|
|
2672
|
+
className: "px-trim-md text-description"
|
|
2673
|
+
}, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
|
|
2674
|
+
className: "w-full pt-trim-md space-y-trim-md"
|
|
2675
|
+
}, children));
|
|
2251
2676
|
};
|
|
2252
|
-
|
|
2677
|
+
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2253
2678
|
var Settings = {
|
|
2254
2679
|
Root: SettingsRoot,
|
|
2680
|
+
Viewport: SettingsViewport,
|
|
2255
2681
|
Section: SettingsSection,
|
|
2256
|
-
|
|
2257
|
-
Group: SettingsGroup,
|
|
2258
|
-
GroupButton: SettingsGroupButton,
|
|
2259
|
-
Container: SettingsContainer,
|
|
2260
|
-
Frame: SettingsFrame,
|
|
2261
|
-
FrameItem: SettingsFrameItem,
|
|
2682
|
+
Panel: SettingsPanel,
|
|
2262
2683
|
Item: SettingsItem,
|
|
2263
|
-
|
|
2684
|
+
FieldSet: SettingsFieldSet
|
|
2685
|
+
};
|
|
2686
|
+
|
|
2687
|
+
// src/components/Settings/SettingsSelectField.tsx
|
|
2688
|
+
import React23 from "react";
|
|
2689
|
+
import { Select as Select3 } from "@dxos/react-ui";
|
|
2690
|
+
var createSelectField = ({ options, defaultLabel = "Default" }) => {
|
|
2691
|
+
const normalized = options.map((option) => typeof option === "string" ? {
|
|
2692
|
+
value: option,
|
|
2693
|
+
label: option
|
|
2694
|
+
} : option);
|
|
2695
|
+
const hasDefault = defaultLabel !== null;
|
|
2696
|
+
const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
|
|
2697
|
+
return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
|
|
2698
|
+
disabled: readonly,
|
|
2699
|
+
value: value3 ?? sentinel,
|
|
2700
|
+
onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
|
|
2701
|
+
}, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
|
|
2702
|
+
disabled: readonly
|
|
2703
|
+
}), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2704
|
+
value: sentinel
|
|
2705
|
+
}, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2706
|
+
key: option.value,
|
|
2707
|
+
value: option.value
|
|
2708
|
+
}, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
|
|
2264
2709
|
};
|
|
2265
2710
|
|
|
2266
2711
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2267
2712
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2268
|
-
import * as
|
|
2713
|
+
import * as Array4 from "effect/Array";
|
|
2269
2714
|
import * as Match2 from "effect/Match";
|
|
2270
|
-
import * as
|
|
2271
|
-
import * as
|
|
2272
|
-
import
|
|
2273
|
-
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as
|
|
2715
|
+
import * as Option6 from "effect/Option";
|
|
2716
|
+
import * as Schema5 from "effect/Schema";
|
|
2717
|
+
import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
|
|
2718
|
+
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6 } from "@dxos/echo";
|
|
2274
2719
|
import { View } from "@dxos/echo";
|
|
2275
2720
|
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2276
|
-
import { invariant } from "@dxos/invariant";
|
|
2721
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2277
2722
|
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2278
|
-
import { IconButton as IconButton4, Input as
|
|
2723
|
+
import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
2279
2724
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2280
2725
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2281
|
-
import { ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2282
|
-
import { mx as
|
|
2283
|
-
|
|
2284
|
-
var
|
|
2726
|
+
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2727
|
+
import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
|
|
2728
|
+
import { translationKey as translationKey14 } from "#translations";
|
|
2729
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
2730
|
+
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2285
2731
|
const atomRegistry = useContext(RegistryContext);
|
|
2286
2732
|
const schemaReadonly = !isMutable(schema);
|
|
2287
|
-
const { t } =
|
|
2288
|
-
const projectionModel =
|
|
2733
|
+
const { t } = useTranslation12(translationKey14);
|
|
2734
|
+
const projectionModel = useMemo12(() => {
|
|
2289
2735
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2290
2736
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2291
2737
|
const model = new ProjectionModel({
|
|
@@ -2309,21 +2755,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2309
2755
|
if (from._tag !== "scope") {
|
|
2310
2756
|
return void 0;
|
|
2311
2757
|
}
|
|
2312
|
-
return
|
|
2758
|
+
return Option6.fromNullable(from.scope.queues).pipe(Option6.flatMap((queues) => Array4.head(queues)), Option6.map(String), Option6.getOrUndefined);
|
|
2313
2759
|
}), Match2.orElse(() => void 0));
|
|
2314
2760
|
const feeds = useQuery2(db, Filter2.type(Feed.Feed));
|
|
2315
|
-
const targetRef =
|
|
2761
|
+
const targetRef = useMemo12(() => {
|
|
2316
2762
|
if (!queueTarget) {
|
|
2317
2763
|
return void 0;
|
|
2318
2764
|
}
|
|
2319
2765
|
const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
|
|
2320
|
-
return feed ?
|
|
2766
|
+
return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
|
|
2321
2767
|
}, [
|
|
2322
2768
|
queueTarget,
|
|
2323
2769
|
feeds
|
|
2324
2770
|
]);
|
|
2325
|
-
const viewSchema =
|
|
2326
|
-
const base =
|
|
2771
|
+
const viewSchema = useMemo12(() => {
|
|
2772
|
+
const base = Schema5.Struct({
|
|
2327
2773
|
query: mode === "schema" ? Format5.URL.annotations({
|
|
2328
2774
|
title: "Record type"
|
|
2329
2775
|
}) : QueryAST.Query.annotations({
|
|
@@ -2331,18 +2777,19 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2331
2777
|
})
|
|
2332
2778
|
});
|
|
2333
2779
|
if (mode === "tag") {
|
|
2334
|
-
return
|
|
2780
|
+
return Schema5.Struct({
|
|
2335
2781
|
...base.fields,
|
|
2336
|
-
|
|
2782
|
+
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2783
|
+
target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2337
2784
|
title: "Target Feed"
|
|
2338
|
-
}))
|
|
2339
|
-
}).pipe(
|
|
2785
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
2786
|
+
}).pipe(Schema5.mutable);
|
|
2340
2787
|
}
|
|
2341
|
-
return base.pipe(
|
|
2788
|
+
return base.pipe(Schema5.mutable);
|
|
2342
2789
|
}, [
|
|
2343
2790
|
mode
|
|
2344
2791
|
]);
|
|
2345
|
-
const viewValues =
|
|
2792
|
+
const viewValues = useMemo12(() => ({
|
|
2346
2793
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2347
2794
|
target: targetRef
|
|
2348
2795
|
}), [
|
|
@@ -2350,7 +2797,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2350
2797
|
view.query.ast,
|
|
2351
2798
|
targetRef
|
|
2352
2799
|
]);
|
|
2353
|
-
const fieldMap =
|
|
2800
|
+
const fieldMap = useMemo12(() => mode === "tag" ? customFields({
|
|
2354
2801
|
types,
|
|
2355
2802
|
tags
|
|
2356
2803
|
}) : void 0, [
|
|
@@ -2358,12 +2805,12 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2358
2805
|
types,
|
|
2359
2806
|
tags
|
|
2360
2807
|
]);
|
|
2361
|
-
const handleUpdate =
|
|
2808
|
+
const handleUpdate = useCallback18((values) => {
|
|
2362
2809
|
const targetValue = values.target;
|
|
2363
2810
|
let queueDxn;
|
|
2364
|
-
if (
|
|
2811
|
+
if (Ref6.isRef(targetValue)) {
|
|
2365
2812
|
const feedDxn = targetValue.dxn.toString();
|
|
2366
|
-
const feed = feeds.find((feed2) =>
|
|
2813
|
+
const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === feedDxn);
|
|
2367
2814
|
if (feed) {
|
|
2368
2815
|
queueDxn = Feed.getQueueDxn(feed)?.toString();
|
|
2369
2816
|
}
|
|
@@ -2375,37 +2822,29 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2375
2822
|
mode,
|
|
2376
2823
|
feeds
|
|
2377
2824
|
]);
|
|
2378
|
-
const handleDelete =
|
|
2379
|
-
|
|
2380
|
-
F: __dxlog_file3,
|
|
2381
|
-
L: 174,
|
|
2382
|
-
S: void 0,
|
|
2383
|
-
A: [
|
|
2384
|
-
"!readonly",
|
|
2385
|
-
""
|
|
2386
|
-
]
|
|
2387
|
-
});
|
|
2825
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2826
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: void 0, A: ["!readonly", ""] });
|
|
2388
2827
|
onDelete?.(fieldId);
|
|
2389
2828
|
}, [
|
|
2390
2829
|
onDelete,
|
|
2391
2830
|
readonly
|
|
2392
2831
|
]);
|
|
2393
|
-
return /* @__PURE__ */
|
|
2832
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
2394
2833
|
role: "none",
|
|
2395
|
-
className:
|
|
2396
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */
|
|
2834
|
+
className: mx5(classNames)
|
|
2835
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
|
|
2397
2836
|
valence: "info",
|
|
2398
2837
|
classNames: "my-form-padding"
|
|
2399
|
-
}, /* @__PURE__ */
|
|
2838
|
+
}, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
|
|
2400
2839
|
schema: viewSchema,
|
|
2401
2840
|
values: viewValues,
|
|
2402
2841
|
fieldMap,
|
|
2403
2842
|
db,
|
|
2404
2843
|
onValuesChanged: handleUpdate
|
|
2405
|
-
}, /* @__PURE__ */
|
|
2406
|
-
label: t("fields
|
|
2844
|
+
}, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2845
|
+
label: t("fields.label"),
|
|
2407
2846
|
asChild: true
|
|
2408
|
-
}), /* @__PURE__ */
|
|
2847
|
+
}), /* @__PURE__ */ React24.createElement(FieldList, {
|
|
2409
2848
|
schema,
|
|
2410
2849
|
view,
|
|
2411
2850
|
registry,
|
|
@@ -2417,9 +2856,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2417
2856
|
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2418
2857
|
const atomRegistry = useContext(RegistryContext);
|
|
2419
2858
|
const schemaReadonly = !isMutable(schema);
|
|
2420
|
-
const { t } =
|
|
2859
|
+
const { t } = useTranslation12(translationKey14);
|
|
2421
2860
|
const [viewSnapshot] = useObject(view);
|
|
2422
|
-
const projectionModel =
|
|
2861
|
+
const projectionModel = useMemo12(() => {
|
|
2423
2862
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2424
2863
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2425
2864
|
const model = new ProjectionModel({
|
|
@@ -2434,38 +2873,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2434
2873
|
schema,
|
|
2435
2874
|
view
|
|
2436
2875
|
]);
|
|
2437
|
-
const [expandedField, setExpandedField] =
|
|
2438
|
-
const handleAdd =
|
|
2439
|
-
|
|
2440
|
-
F: __dxlog_file3,
|
|
2441
|
-
L: 239,
|
|
2442
|
-
S: void 0,
|
|
2443
|
-
A: [
|
|
2444
|
-
"!readonly",
|
|
2445
|
-
""
|
|
2446
|
-
]
|
|
2447
|
-
});
|
|
2876
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2877
|
+
const handleAdd = useCallback18(() => {
|
|
2878
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 183, S: void 0, A: ["!readonly", ""] });
|
|
2448
2879
|
const field = projectionModel.createFieldProjection();
|
|
2449
2880
|
setExpandedField(field.id);
|
|
2450
2881
|
}, [
|
|
2451
2882
|
projectionModel,
|
|
2452
2883
|
readonly
|
|
2453
2884
|
]);
|
|
2454
|
-
const handleToggleField =
|
|
2885
|
+
const handleToggleField = useCallback18((field) => {
|
|
2455
2886
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2456
2887
|
}, [
|
|
2457
2888
|
readonly
|
|
2458
2889
|
]);
|
|
2459
|
-
const handleDelete =
|
|
2460
|
-
|
|
2461
|
-
F: __dxlog_file3,
|
|
2462
|
-
L: 253,
|
|
2463
|
-
S: void 0,
|
|
2464
|
-
A: [
|
|
2465
|
-
"!readonly",
|
|
2466
|
-
""
|
|
2467
|
-
]
|
|
2468
|
-
});
|
|
2890
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2891
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 196, S: void 0, A: ["!readonly", ""] });
|
|
2469
2892
|
if (fieldId === expandedField) {
|
|
2470
2893
|
setExpandedField(void 0);
|
|
2471
2894
|
}
|
|
@@ -2475,36 +2898,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2475
2898
|
onDelete,
|
|
2476
2899
|
readonly
|
|
2477
2900
|
]);
|
|
2478
|
-
const handleMove =
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
L: 265,
|
|
2482
|
-
S: void 0,
|
|
2483
|
-
A: [
|
|
2484
|
-
"!readonly",
|
|
2485
|
-
""
|
|
2486
|
-
]
|
|
2487
|
-
});
|
|
2488
|
-
Obj3.change(view, (v) => {
|
|
2901
|
+
const handleMove = useCallback18((fromIndex, toIndex) => {
|
|
2902
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 207, S: void 0, A: ["!readonly", ""] });
|
|
2903
|
+
Obj6.update(view, (view2) => {
|
|
2489
2904
|
const fields = [
|
|
2490
|
-
...
|
|
2905
|
+
...view2.projection.fields
|
|
2491
2906
|
];
|
|
2492
2907
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2493
2908
|
fields.splice(toIndex, 0, moved);
|
|
2494
|
-
|
|
2909
|
+
view2.projection.fields = fields;
|
|
2495
2910
|
});
|
|
2496
2911
|
}, [
|
|
2497
2912
|
view,
|
|
2498
2913
|
readonly
|
|
2499
2914
|
]);
|
|
2500
|
-
const handleClose =
|
|
2501
|
-
const handleHide =
|
|
2915
|
+
const handleClose = useCallback18(() => setExpandedField(void 0), []);
|
|
2916
|
+
const handleHide = useCallback18((fieldId) => {
|
|
2502
2917
|
setExpandedField(void 0);
|
|
2503
2918
|
projectionModel.hideFieldProjection(fieldId);
|
|
2504
2919
|
}, [
|
|
2505
2920
|
projectionModel
|
|
2506
2921
|
]);
|
|
2507
|
-
const handleShow =
|
|
2922
|
+
const handleShow = useCallback18((property) => {
|
|
2508
2923
|
setExpandedField(void 0);
|
|
2509
2924
|
projectionModel.showFieldProjection(property);
|
|
2510
2925
|
}, [
|
|
@@ -2513,70 +2928,70 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2513
2928
|
if (!viewSnapshot) {
|
|
2514
2929
|
return null;
|
|
2515
2930
|
}
|
|
2516
|
-
return /* @__PURE__ */
|
|
2931
|
+
return /* @__PURE__ */ React24.createElement(List2.Root, {
|
|
2517
2932
|
items: viewSnapshot.projection.fields,
|
|
2518
|
-
isItem:
|
|
2933
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2519
2934
|
getId: (field) => field.id,
|
|
2520
2935
|
onMove: readonly ? void 0 : handleMove,
|
|
2521
2936
|
readonly
|
|
2522
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2937
|
+
}, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
|
|
2523
2938
|
className: "text-sm"
|
|
2524
|
-
}, t("field
|
|
2939
|
+
}, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
|
|
2525
2940
|
role: "list",
|
|
2526
2941
|
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2527
2942
|
}, fields?.map((field) => {
|
|
2528
2943
|
const hidden = field.visible === false;
|
|
2529
|
-
return /* @__PURE__ */
|
|
2944
|
+
return /* @__PURE__ */ React24.createElement(List2.Item, {
|
|
2530
2945
|
key: field.id,
|
|
2531
2946
|
item: field,
|
|
2532
2947
|
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2533
2948
|
"aria-expanded": expandedField === field.id
|
|
2534
|
-
}, /* @__PURE__ */
|
|
2949
|
+
}, /* @__PURE__ */ React24.createElement("div", {
|
|
2535
2950
|
role: "none",
|
|
2536
|
-
className:
|
|
2537
|
-
}, /* @__PURE__ */
|
|
2951
|
+
className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
|
|
2952
|
+
}, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
|
|
2538
2953
|
disabled: readonly || schemaReadonly
|
|
2539
|
-
}), /* @__PURE__ */
|
|
2954
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
|
|
2540
2955
|
classNames: hidden && "text-subdued",
|
|
2541
2956
|
onClick: () => handleToggleField(field)
|
|
2542
|
-
}, field.path), /* @__PURE__ */
|
|
2957
|
+
}, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2543
2958
|
label: t(hidden ? "show field label" : "hide field label"),
|
|
2544
2959
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2545
2960
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2546
2961
|
autoHide: false,
|
|
2547
2962
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2548
2963
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2549
|
-
}), !readonly && /* @__PURE__ */
|
|
2550
|
-
label: t("delete
|
|
2964
|
+
}), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
|
|
2965
|
+
label: t("delete-field.label"),
|
|
2551
2966
|
autoHide: false,
|
|
2552
2967
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2553
2968
|
onClick: () => handleDelete(field.id),
|
|
2554
2969
|
"data-testid": "field.delete"
|
|
2555
|
-
}), /* @__PURE__ */
|
|
2970
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2556
2971
|
iconOnly: true,
|
|
2557
2972
|
variant: "ghost",
|
|
2558
|
-
label: t("toggle
|
|
2973
|
+
label: t("toggle-expand.label", {
|
|
2559
2974
|
ns: osTranslations2
|
|
2560
2975
|
}),
|
|
2561
2976
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2562
2977
|
onClick: () => handleToggleField(field),
|
|
2563
2978
|
"data-testid": "field.toggle"
|
|
2564
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2979
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
|
|
2565
2980
|
role: "none",
|
|
2566
|
-
className: "col-span-
|
|
2567
|
-
}, /* @__PURE__ */
|
|
2981
|
+
className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
|
|
2982
|
+
}, /* @__PURE__ */ React24.createElement(FieldEditor, {
|
|
2568
2983
|
readonly: readonly || schemaReadonly,
|
|
2569
2984
|
registry,
|
|
2570
2985
|
projection: projectionModel,
|
|
2571
2986
|
field,
|
|
2572
2987
|
onSave: handleClose
|
|
2573
2988
|
})));
|
|
2574
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2989
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
|
|
2575
2990
|
role: "none",
|
|
2576
2991
|
className: "my-form-padding"
|
|
2577
|
-
}, /* @__PURE__ */
|
|
2992
|
+
}, /* @__PURE__ */ React24.createElement(IconButton4, {
|
|
2578
2993
|
icon: "ph--plus--regular",
|
|
2579
|
-
label: t("add
|
|
2994
|
+
label: t("add-property-button.label"),
|
|
2580
2995
|
onClick: handleAdd,
|
|
2581
2996
|
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2582
2997
|
classNames: "w-full"
|
|
@@ -2584,13 +2999,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2584
2999
|
};
|
|
2585
3000
|
var customFields = ({ types, tags }) => ({
|
|
2586
3001
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2587
|
-
const handleChange =
|
|
3002
|
+
const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
|
|
2588
3003
|
onValueChange
|
|
2589
3004
|
]);
|
|
2590
|
-
return /* @__PURE__ */
|
|
3005
|
+
return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2591
3006
|
readonly,
|
|
2592
3007
|
label
|
|
2593
|
-
}), /* @__PURE__ */
|
|
3008
|
+
}), /* @__PURE__ */ React24.createElement(QueryForm, {
|
|
2594
3009
|
initialQuery: getValue(),
|
|
2595
3010
|
types,
|
|
2596
3011
|
tags,
|
|
@@ -2609,7 +3024,9 @@ export {
|
|
|
2609
3024
|
GeoPointField,
|
|
2610
3025
|
MarkdownField,
|
|
2611
3026
|
NumberField,
|
|
3027
|
+
ObjectForm,
|
|
2612
3028
|
ObjectPicker,
|
|
3029
|
+
ObjectProperties,
|
|
2613
3030
|
RefField,
|
|
2614
3031
|
SelectField,
|
|
2615
3032
|
SelectOptionField,
|
|
@@ -2619,15 +3036,18 @@ export {
|
|
|
2619
3036
|
TupleField,
|
|
2620
3037
|
ViewEditor,
|
|
2621
3038
|
cellClassesForFieldType,
|
|
3039
|
+
createSelectField,
|
|
3040
|
+
detectFieldType,
|
|
2622
3041
|
formatForDisplay,
|
|
2623
3042
|
formatForEditing,
|
|
2624
3043
|
getDefaultValue,
|
|
2625
3044
|
getFormProperties,
|
|
2626
3045
|
getRefProps,
|
|
3046
|
+
getSelectOptionsFromAst,
|
|
3047
|
+
omitHiddenFormFields,
|
|
2627
3048
|
omitId,
|
|
2628
3049
|
parseValue,
|
|
2629
3050
|
pathNotUniqueError,
|
|
2630
|
-
translations,
|
|
2631
3051
|
useFormContext,
|
|
2632
3052
|
useFormFieldState,
|
|
2633
3053
|
useFormHandler,
|