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