@dxos/react-ui-form 0.8.4-main.d05673bc65 → 0.8.4-main.dfabb4ec29
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 +1004 -612
- 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 +1004 -612
- 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 +12 -6
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
- package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
- package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +26 -4
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +28 -33
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
- package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
- package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +2 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +2 -2
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +65 -63
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +4 -4
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useKeyHandler.d.ts +2 -1
- package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +63 -61
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field-type.d.ts +19 -0
- package/dist/types/src/util/field-type.d.ts.map +1 -0
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/properties.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +1 -0
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -40
- package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
- package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
- package/src/components/FieldEditor/FieldEditor.tsx +4 -3
- package/src/components/Form/AUDIT.md +17 -0
- package/src/components/Form/Form.stories.tsx +23 -36
- package/src/components/Form/Form.tsx +77 -48
- package/src/components/Form/FormField.tsx +27 -15
- package/src/components/Form/FormFieldComponent.tsx +5 -3
- 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 +70 -35
- package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -6
- package/src/components/Form/fields/SelectOptionField.tsx +10 -10
- package/src/components/Form/fields/TextField.tsx +2 -2
- package/src/components/Form/fields/TupleField.tsx +1 -1
- package/src/components/ObjectForm/ObjectForm.tsx +114 -0
- package/src/components/ObjectForm/index.ts +5 -0
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +9 -7
- package/src/components/ObjectPicker/ObjectPicker.tsx +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 +10 -10
- package/src/components/ViewEditor/ViewEditor.test.tsx +0 -1
- package/src/components/ViewEditor/ViewEditor.tsx +15 -15
- package/src/components/index.ts +2 -0
- package/src/components/testing.tsx +19 -11
- package/src/hooks/useKeyHandler.tsx +7 -7
- package/src/index.ts +0 -4
- package/src/translations.ts +66 -63
- package/src/util/field-type.ts +60 -0
- package/src/util/index.ts +1 -0
- package/src/util/refs.ts +7 -3
|
@@ -1,87 +1,11 @@
|
|
|
1
|
-
// src/translations.ts
|
|
2
|
-
var translationKey = "@dxos/react-ui-form";
|
|
3
|
-
var translations = [
|
|
4
|
-
{
|
|
5
|
-
"en-US": {
|
|
6
|
-
[translationKey]: {
|
|
7
|
-
"fields label": "Fields",
|
|
8
|
-
"hidden fields label": "Hidden Fields",
|
|
9
|
-
"empty readonly ref field label": "(none)",
|
|
10
|
-
// TODO(burdon): Standardize field/property.
|
|
11
|
-
"add property button label": "Add property",
|
|
12
|
-
"field property label": "Property",
|
|
13
|
-
"field property placeholder": "Property name",
|
|
14
|
-
"field format label": "Type",
|
|
15
|
-
"field path label": "Field path",
|
|
16
|
-
"add field": "Add field",
|
|
17
|
-
"delete field": "Delete field",
|
|
18
|
-
"field limit reached": "Maximum number of fields reached",
|
|
19
|
-
"boolean input true value": "Yes",
|
|
20
|
-
"boolean input false value": "No",
|
|
21
|
-
"show field label": "Show field",
|
|
22
|
-
"hide field label": "Hide field",
|
|
23
|
-
"delete field label": "Delete field",
|
|
24
|
-
"ref field combobox input placeholder": "Search\u2026",
|
|
25
|
-
"ref field placeholder_one": "Select\u2026",
|
|
26
|
-
"ref field placeholder_other": "Select items\u2026",
|
|
27
|
-
"example placeholder": "Example",
|
|
28
|
-
"latitude placeholder": "Latitude (e.g., 40.7128)",
|
|
29
|
-
"longitude placeholder": "Longitude (e.g., -74.0060)",
|
|
30
|
-
"cancel button label": "Cancel",
|
|
31
|
-
"save button label": "Save",
|
|
32
|
-
// FormatEnum
|
|
33
|
-
"format boolean": "Boolean",
|
|
34
|
-
"format currency": "Currency",
|
|
35
|
-
"format date": "Date",
|
|
36
|
-
"format date-time": "DateTime",
|
|
37
|
-
"format did": "DID",
|
|
38
|
-
"format duration": "Duration",
|
|
39
|
-
"format dxn": "DXN",
|
|
40
|
-
"format email": "Email",
|
|
41
|
-
"format formula": "Formula",
|
|
42
|
-
"format hostname": "Hostname",
|
|
43
|
-
"format integer": "Integer",
|
|
44
|
-
"format json": "JSON",
|
|
45
|
-
"format lnglat": "Geopoint",
|
|
46
|
-
"format markdown": "Markdown",
|
|
47
|
-
"format percent": "Percent",
|
|
48
|
-
"format ref": "Reference",
|
|
49
|
-
"format regex": "RegExp",
|
|
50
|
-
"format string": "String",
|
|
51
|
-
"format single-select": "Select",
|
|
52
|
-
"format multi-select": "Multi-select",
|
|
53
|
-
"format text": "Long text",
|
|
54
|
-
"format time": "Time",
|
|
55
|
-
"format timestamp": "Timestamp",
|
|
56
|
-
"format user": "User",
|
|
57
|
-
"format number": "Number",
|
|
58
|
-
"format uri": "URI",
|
|
59
|
-
"format url": "URL",
|
|
60
|
-
"format uuid": "UUID",
|
|
61
|
-
// GeoPointField.
|
|
62
|
-
"latitude label": "Latitude",
|
|
63
|
-
"longitude label": "Longitude",
|
|
64
|
-
// SelectOptionsField.
|
|
65
|
-
"select option label": "Label",
|
|
66
|
-
"select option label placeholder": "Option label",
|
|
67
|
-
"select option color": "Color",
|
|
68
|
-
"select option delete": "Delete",
|
|
69
|
-
"select option add": "Add option",
|
|
70
|
-
// System schema message.
|
|
71
|
-
"system schema title": "System type",
|
|
72
|
-
"system schema description": "System type: cannot add or remove fields."
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
];
|
|
77
|
-
|
|
78
1
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
79
|
-
import React17, { useCallback as useCallback14, useEffect as
|
|
80
|
-
import { Obj as
|
|
2
|
+
import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
|
|
3
|
+
import { Obj as Obj3 } from "@dxos/echo";
|
|
81
4
|
import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
|
|
82
5
|
import { log as log2 } from "@dxos/log";
|
|
83
|
-
import { useAsyncEffect, useTranslation as
|
|
6
|
+
import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
|
|
84
7
|
import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
|
|
8
|
+
import { translationKey as translationKey9 } from "#translations";
|
|
85
9
|
|
|
86
10
|
// src/util/field.ts
|
|
87
11
|
import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
|
|
@@ -204,6 +128,46 @@ var pathNotUniqueError = (path) => ({
|
|
|
204
128
|
message: `'${path}' is already present`
|
|
205
129
|
});
|
|
206
130
|
|
|
131
|
+
// src/util/field-type.ts
|
|
132
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
133
|
+
import { getAnnotation, isLiteralUnion } from "@dxos/effect";
|
|
134
|
+
var detectFieldType = (ast) => {
|
|
135
|
+
if (isLiteralUnion(ast)) {
|
|
136
|
+
return "select";
|
|
137
|
+
}
|
|
138
|
+
if (SchemaAST.isTypeLiteral(ast)) {
|
|
139
|
+
return "struct";
|
|
140
|
+
}
|
|
141
|
+
switch (ast._tag) {
|
|
142
|
+
case "BooleanKeyword":
|
|
143
|
+
return "boolean";
|
|
144
|
+
case "StringKeyword":
|
|
145
|
+
return "string";
|
|
146
|
+
case "NumberKeyword":
|
|
147
|
+
return "number";
|
|
148
|
+
}
|
|
149
|
+
return void 0;
|
|
150
|
+
};
|
|
151
|
+
var getSelectOptionsFromAst = (ast) => {
|
|
152
|
+
if (!isLiteralUnion(ast)) {
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
return ast.types.flatMap((literalNode) => {
|
|
156
|
+
const value3 = literalNode.literal;
|
|
157
|
+
if (typeof value3 !== "string" && typeof value3 !== "number") {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
|
|
161
|
+
const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
|
|
162
|
+
return [
|
|
163
|
+
{
|
|
164
|
+
value: value3,
|
|
165
|
+
label
|
|
166
|
+
}
|
|
167
|
+
];
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
207
171
|
// src/util/formatting.ts
|
|
208
172
|
import { format as formatDate } from "date-fns/format";
|
|
209
173
|
import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
|
|
@@ -352,43 +316,52 @@ var getFormProperties = (ast) => {
|
|
|
352
316
|
|
|
353
317
|
// src/util/refs.ts
|
|
354
318
|
import { Ref } from "@dxos/echo";
|
|
355
|
-
import {
|
|
319
|
+
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
320
|
+
import { findAnnotation, getArrayElementType, isArrayType } from "@dxos/effect";
|
|
356
321
|
var getRefProps = (ast) => {
|
|
357
322
|
if (isArrayType(ast)) {
|
|
358
323
|
const elementType = getArrayElementType(ast);
|
|
359
324
|
if (elementType) {
|
|
360
325
|
if (Ref.isRefType(elementType)) {
|
|
326
|
+
const typename = findAnnotation(elementType, ReferenceAnnotationId)?.typename;
|
|
361
327
|
return {
|
|
362
328
|
ast: elementType,
|
|
363
|
-
isArray: true
|
|
329
|
+
isArray: true,
|
|
330
|
+
typename
|
|
364
331
|
};
|
|
365
332
|
}
|
|
366
333
|
}
|
|
367
334
|
}
|
|
368
335
|
if (Ref.isRefType(ast)) {
|
|
336
|
+
const typename = findAnnotation(ast, ReferenceAnnotationId)?.typename;
|
|
369
337
|
return {
|
|
370
338
|
ast,
|
|
371
|
-
isArray: false
|
|
339
|
+
isArray: false,
|
|
340
|
+
typename
|
|
372
341
|
};
|
|
373
342
|
}
|
|
374
343
|
return void 0;
|
|
375
344
|
};
|
|
376
345
|
|
|
377
346
|
// src/components/Form/fields/ArrayField.tsx
|
|
378
|
-
import * as
|
|
379
|
-
import * as
|
|
347
|
+
import * as Option4 from "effect/Option";
|
|
348
|
+
import * as SchemaAST4 from "effect/SchemaAST";
|
|
380
349
|
import React5, { useCallback as useCallback3 } from "react";
|
|
381
350
|
import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
|
|
382
351
|
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
352
|
+
import { translationKey as translationKey3 } from "#translations";
|
|
383
353
|
|
|
384
354
|
// src/components/Form/Form.tsx
|
|
385
355
|
import { createContext } from "@radix-ui/react-context";
|
|
356
|
+
import * as Option3 from "effect/Option";
|
|
386
357
|
import * as Schema2 from "effect/Schema";
|
|
387
|
-
import * as
|
|
388
|
-
import React4, { useEffect as
|
|
358
|
+
import * as SchemaAST3 from "effect/SchemaAST";
|
|
359
|
+
import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
|
|
360
|
+
import { Annotation as EchoAnnotation } from "@dxos/echo";
|
|
389
361
|
import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
|
|
390
|
-
import { IconButton, ScrollArea, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
391
|
-
import { mx
|
|
362
|
+
import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
363
|
+
import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
|
|
364
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
392
365
|
|
|
393
366
|
// src/hooks/useFormHandler.ts
|
|
394
367
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
@@ -426,12 +399,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
426
399
|
log("validate", {
|
|
427
400
|
values: values2,
|
|
428
401
|
errors: errors2
|
|
429
|
-
}, {
|
|
430
|
-
F: __dxlog_file,
|
|
431
|
-
L: 155,
|
|
432
|
-
S: void 0,
|
|
433
|
-
C: (f, a) => f(...a)
|
|
434
|
-
});
|
|
402
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
|
|
435
403
|
if (errors2.length === 0 && onValidate) {
|
|
436
404
|
const validatedValues = values2;
|
|
437
405
|
errors2 = onValidate(validatedValues) ?? [];
|
|
@@ -519,12 +487,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
519
487
|
log("onValueChange", {
|
|
520
488
|
path,
|
|
521
489
|
value: value3
|
|
522
|
-
}, {
|
|
523
|
-
F: __dxlog_file,
|
|
524
|
-
L: 254,
|
|
525
|
-
S: void 0,
|
|
526
|
-
C: (f, a) => f(...a)
|
|
527
|
-
});
|
|
490
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
|
|
528
491
|
const jsonPath = createJsonPath(path);
|
|
529
492
|
const pathArray = path;
|
|
530
493
|
let parsedValue = value3;
|
|
@@ -533,12 +496,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
533
496
|
parsedValue = parseFloat(value3) || 0;
|
|
534
497
|
}
|
|
535
498
|
} catch (err) {
|
|
536
|
-
log.catch(err, void 0, {
|
|
537
|
-
F: __dxlog_file,
|
|
538
|
-
L: 264,
|
|
539
|
-
S: void 0,
|
|
540
|
-
C: (f, a) => f(...a)
|
|
541
|
-
});
|
|
499
|
+
log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
|
|
542
500
|
parsedValue = void 0;
|
|
543
501
|
}
|
|
544
502
|
const newValues = mergeAtPath(values, pathArray, parsedValue);
|
|
@@ -647,9 +605,9 @@ var flatMap = (errors) => {
|
|
|
647
605
|
};
|
|
648
606
|
|
|
649
607
|
// src/hooks/useKeyHandler.tsx
|
|
650
|
-
import { useCallback as useCallback2,
|
|
608
|
+
import { useCallback as useCallback2, useLayoutEffect } from "react";
|
|
651
609
|
import { addEventListener } from "@dxos/async";
|
|
652
|
-
var useKeyHandler = (
|
|
610
|
+
var useKeyHandler = (elRef, form) => {
|
|
653
611
|
const handleKeyDown = useCallback2((event) => {
|
|
654
612
|
switch (event.key) {
|
|
655
613
|
case "Enter": {
|
|
@@ -665,13 +623,14 @@ var useKeyHandler = (formElement, form) => {
|
|
|
665
623
|
form.onSave,
|
|
666
624
|
form.autoSave
|
|
667
625
|
]);
|
|
668
|
-
|
|
669
|
-
|
|
626
|
+
useLayoutEffect(() => {
|
|
627
|
+
const el = elRef.current;
|
|
628
|
+
if (!el) {
|
|
670
629
|
return;
|
|
671
630
|
}
|
|
672
|
-
return addEventListener(
|
|
631
|
+
return addEventListener(el, "keydown", handleKeyDown);
|
|
673
632
|
}, [
|
|
674
|
-
|
|
633
|
+
elRef,
|
|
675
634
|
handleKeyDown
|
|
676
635
|
]);
|
|
677
636
|
};
|
|
@@ -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
|
|
@@ -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,48 +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
|
|
1515
|
+
import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1443
1516
|
import { ParentLabelAnnotationId } from "@dxos/schema";
|
|
1444
|
-
import {
|
|
1517
|
+
import { translationKey as translationKey7 } from "#translations";
|
|
1445
1518
|
|
|
1446
1519
|
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1447
|
-
import React10, { forwardRef
|
|
1448
|
-
import { Popover, useTranslation as
|
|
1449
|
-
import { Combobox
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
value: "__create__",
|
|
1455
|
-
label: t(createOptionLabel[0], {
|
|
1456
|
-
ns: createOptionLabel[1].ns,
|
|
1457
|
-
text: query
|
|
1458
|
-
}),
|
|
1459
|
-
icon: createOptionIcon,
|
|
1460
|
-
classNames: "flex items-center gap-2",
|
|
1461
|
-
closeOnSelect: false,
|
|
1462
|
-
onSelect: () => {
|
|
1463
|
-
onCreateItemSelect(query);
|
|
1464
|
-
}
|
|
1465
|
-
});
|
|
1466
|
-
};
|
|
1467
|
-
var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
|
|
1468
|
-
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);
|
|
1469
1527
|
const [showForm, setShowForm] = useState3(false);
|
|
1470
1528
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1471
|
-
const { results, handleSearch } = useSearchListResults({
|
|
1529
|
+
const { results, query, handleSearch } = useSearchListResults({
|
|
1472
1530
|
items: options
|
|
1473
1531
|
});
|
|
1474
|
-
const handleFormSave = useCallback8((values) => {
|
|
1475
|
-
onCreate?.(values);
|
|
1532
|
+
const handleFormSave = useCallback8(async (values) => {
|
|
1533
|
+
await onCreate?.(values);
|
|
1476
1534
|
setShowForm(false);
|
|
1477
1535
|
setFormInitialValue("");
|
|
1478
1536
|
}, [
|
|
@@ -1494,22 +1552,31 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1494
1552
|
}, [
|
|
1495
1553
|
createSchema
|
|
1496
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
|
+
}
|
|
1497
1571
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1498
1572
|
...props,
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
[createInitialValuePath]: formInitialValue
|
|
1507
|
-
} : {},
|
|
1508
|
-
onSave: handleFormSave,
|
|
1509
|
-
onCancel: handleFormCancel
|
|
1510
|
-
}, /* @__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, {
|
|
1511
|
-
placeholder: t("ref field combobox input placeholder"),
|
|
1512
|
-
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
|
|
1513
1580
|
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1514
1581
|
key: option.id,
|
|
1515
1582
|
value: option.id,
|
|
@@ -1517,16 +1584,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1517
1584
|
checked: selectedIds?.includes(option.id),
|
|
1518
1585
|
onSelect: () => onSelect(option.id),
|
|
1519
1586
|
classNames: "flex items-center gap-2"
|
|
1520
|
-
})),
|
|
1587
|
+
})), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
|
|
1588
|
+
query,
|
|
1521
1589
|
createOptionLabel,
|
|
1522
|
-
createOptionIcon,
|
|
1523
|
-
onCreateItemSelect: (
|
|
1524
|
-
setFormInitialValue(
|
|
1590
|
+
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
1591
|
+
onCreateItemSelect: (currentQuery) => {
|
|
1592
|
+
setFormInitialValue(currentQuery);
|
|
1525
1593
|
setShowForm(true);
|
|
1526
1594
|
}
|
|
1527
|
-
}))
|
|
1595
|
+
})), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1528
1596
|
});
|
|
1529
|
-
|
|
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";
|
|
1530
1615
|
var ObjectPicker = {
|
|
1531
1616
|
Root: Combobox.Root,
|
|
1532
1617
|
Portal: Combobox.Portal,
|
|
@@ -1541,39 +1626,41 @@ var isRefSnapshot = (val) => {
|
|
|
1541
1626
|
};
|
|
1542
1627
|
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1543
1628
|
const id = Entity.getDXN(result).toString();
|
|
1544
|
-
const parent = parentLabel ?
|
|
1629
|
+
const parent = parentLabel ? Obj2.getParent(result) : void 0;
|
|
1545
1630
|
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1546
1631
|
return {
|
|
1547
1632
|
id,
|
|
1548
1633
|
label: label ?? id
|
|
1549
1634
|
};
|
|
1550
1635
|
});
|
|
1551
|
-
var
|
|
1636
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1552
1637
|
var RefField = (props) => {
|
|
1553
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db,
|
|
1554
|
-
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);
|
|
1555
1640
|
const { status, error } = getStatus();
|
|
1556
|
-
const typename =
|
|
1641
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1557
1642
|
type
|
|
1558
1643
|
]);
|
|
1559
1644
|
const results = useResults(db, typename);
|
|
1560
|
-
const options =
|
|
1561
|
-
const parentLabel = type ?
|
|
1562
|
-
return
|
|
1645
|
+
const options = useMemo7(() => {
|
|
1646
|
+
const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
|
|
1647
|
+
return getOptions(results, {
|
|
1563
1648
|
parentLabel
|
|
1564
1649
|
});
|
|
1565
1650
|
}, [
|
|
1566
1651
|
results,
|
|
1567
|
-
|
|
1652
|
+
getOptions,
|
|
1568
1653
|
type
|
|
1569
1654
|
]);
|
|
1570
1655
|
const handleGetValue = useCallback9(() => {
|
|
1571
1656
|
const formValue = getValue();
|
|
1657
|
+
const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
|
|
1572
1658
|
const unknownToRefOption = (value3) => {
|
|
1573
|
-
const isRef =
|
|
1659
|
+
const isRef = Ref3.isRef(value3);
|
|
1574
1660
|
if (isRef || isRefSnapshot(value3)) {
|
|
1575
1661
|
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1576
|
-
const
|
|
1662
|
+
const objectId = dxnToObjectId(dxnString);
|
|
1663
|
+
const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
|
|
1577
1664
|
if (matchingOption) {
|
|
1578
1665
|
return matchingOption;
|
|
1579
1666
|
}
|
|
@@ -1585,29 +1672,37 @@ var RefField = (props) => {
|
|
|
1585
1672
|
options,
|
|
1586
1673
|
getValue
|
|
1587
1674
|
]);
|
|
1588
|
-
const handleUpdate = useCallback9((id) => {
|
|
1589
|
-
const item2 = options.find((option) => option.id === id);
|
|
1590
|
-
const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1591
|
-
onValueChange(type, ref);
|
|
1592
|
-
}, [
|
|
1593
|
-
options,
|
|
1594
|
-
type,
|
|
1595
|
-
onValueChange
|
|
1596
|
-
]);
|
|
1597
1675
|
const item = handleGetValue();
|
|
1598
|
-
const selectedIds =
|
|
1676
|
+
const selectedIds = useMemo7(() => item ? [
|
|
1599
1677
|
item.id
|
|
1600
1678
|
] : [], [
|
|
1601
1679
|
item
|
|
1602
1680
|
]);
|
|
1603
1681
|
const createSchema = useSchema(db, typename);
|
|
1604
|
-
const
|
|
1605
|
-
|
|
1606
|
-
|
|
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));
|
|
1607
1690
|
}
|
|
1691
|
+
setOpen(false);
|
|
1608
1692
|
}, [
|
|
1609
1693
|
createSchema,
|
|
1610
|
-
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
|
|
1611
1706
|
]);
|
|
1612
1707
|
const handleSelect = useCallback9((id) => {
|
|
1613
1708
|
if (item?.id === id) {
|
|
@@ -1629,40 +1724,46 @@ var RefField = (props) => {
|
|
|
1629
1724
|
readonly,
|
|
1630
1725
|
label
|
|
1631
1726
|
}), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
|
|
1632
|
-
className:
|
|
1633
|
-
}, t("empty
|
|
1727
|
+
className: "text-description mb-2"
|
|
1728
|
+
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
|
|
1634
1729
|
key: item.id,
|
|
1635
1730
|
dxn: item.id,
|
|
1636
1731
|
rootclassname: "me-1"
|
|
1637
|
-
}, 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, {
|
|
1638
1736
|
asChild: true,
|
|
1639
1737
|
classNames: "p-0"
|
|
1640
1738
|
}, item ? /* @__PURE__ */ React11.createElement("div", {
|
|
1641
|
-
className: "flex gap-
|
|
1739
|
+
className: "flex gap-form-gap w-full"
|
|
1642
1740
|
}, /* @__PURE__ */ React11.createElement(Input6.Root, {
|
|
1643
1741
|
key: item.id
|
|
1644
1742
|
}, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
|
|
1645
1743
|
value: item.label,
|
|
1646
1744
|
readOnly: true,
|
|
1647
1745
|
classNames: "w-full"
|
|
1648
|
-
}))) : /* @__PURE__ */ React11.createElement(
|
|
1649
|
-
classNames: "w-full text-start gap-
|
|
1746
|
+
}))) : /* @__PURE__ */ React11.createElement(Button2, {
|
|
1747
|
+
classNames: "w-full text-start gap-form-gap"
|
|
1650
1748
|
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1651
|
-
role: "none",
|
|
1652
1749
|
className: "grow overflow-hidden"
|
|
1653
1750
|
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1654
|
-
className: "
|
|
1655
|
-
}, placeholder ?? t("ref
|
|
1751
|
+
className: "truncate text-description"
|
|
1752
|
+
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
|
|
1656
1753
|
size: 3,
|
|
1657
1754
|
icon: "ph--caret-down--bold"
|
|
1658
1755
|
}))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
|
|
1659
1756
|
classNames: "dx-card-popover-width",
|
|
1660
1757
|
options,
|
|
1661
1758
|
selectedIds,
|
|
1662
|
-
|
|
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)),
|
|
1663
1763
|
createOptionLabel,
|
|
1664
1764
|
createOptionIcon,
|
|
1665
1765
|
createInitialValuePath,
|
|
1766
|
+
createFieldMap: createFieldMap3,
|
|
1666
1767
|
onCreate: handleCreate,
|
|
1667
1768
|
onSelect: handleSelect
|
|
1668
1769
|
})))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
|
|
@@ -1704,20 +1805,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1704
1805
|
};
|
|
1705
1806
|
|
|
1706
1807
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1707
|
-
import React13, { useCallback as useCallback11, useEffect as
|
|
1808
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1708
1809
|
import { PublicKey } from "@dxos/keys";
|
|
1709
|
-
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";
|
|
1710
1811
|
import { List } from "@dxos/react-ui-list";
|
|
1711
1812
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1712
1813
|
import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
|
|
1814
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1713
1815
|
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
1714
|
-
const { t } =
|
|
1816
|
+
const { t } = useTranslation8(translationKey8);
|
|
1715
1817
|
const { status, error } = getStatus();
|
|
1716
|
-
const [selected, setSelectedId] =
|
|
1717
|
-
const [isNewOption, setIsNewOption] =
|
|
1718
|
-
const inputRef =
|
|
1818
|
+
const [selected, setSelectedId] = useState5(null);
|
|
1819
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
1820
|
+
const inputRef = useRef2(null);
|
|
1719
1821
|
const options = getValue();
|
|
1720
|
-
|
|
1822
|
+
useEffect4(() => {
|
|
1721
1823
|
if (options === void 0) {
|
|
1722
1824
|
onValueChange(type, []);
|
|
1723
1825
|
}
|
|
@@ -1808,7 +1910,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1808
1910
|
type,
|
|
1809
1911
|
onValueChange
|
|
1810
1912
|
]);
|
|
1811
|
-
|
|
1913
|
+
useEffect4(() => {
|
|
1812
1914
|
if (selected && isNewOption && inputRef.current) {
|
|
1813
1915
|
inputRef.current.focus();
|
|
1814
1916
|
setIsNewOption(false);
|
|
@@ -1823,9 +1925,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1823
1925
|
error,
|
|
1824
1926
|
readonly,
|
|
1825
1927
|
label
|
|
1826
|
-
}), /* @__PURE__ */ React13.createElement("div", {
|
|
1827
|
-
role: "none"
|
|
1828
|
-
}, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1928
|
+
}), /* @__PURE__ */ React13.createElement("div", null, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1829
1929
|
items: options,
|
|
1830
1930
|
isItem: (_item) => true,
|
|
1831
1931
|
onMove: readonly ? void 0 : handleMove,
|
|
@@ -1855,20 +1955,20 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1855
1955
|
}, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1856
1956
|
iconOnly: true,
|
|
1857
1957
|
variant: "ghost",
|
|
1858
|
-
label: t(selected === item.id ? "collapse
|
|
1958
|
+
label: t(selected === item.id ? "collapse.label" : "expand.label", {
|
|
1859
1959
|
ns: osTranslations
|
|
1860
1960
|
}),
|
|
1861
1961
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
1862
1962
|
onClick: () => handleClick(item.id)
|
|
1863
1963
|
})), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
|
|
1864
|
-
className: "flex flex-col p-form-padding gap-
|
|
1964
|
+
className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
|
|
1865
1965
|
}, /* @__PURE__ */ React13.createElement(Input8.Label, {
|
|
1866
1966
|
classNames: "text-xs"
|
|
1867
|
-
}, t("select
|
|
1868
|
-
className: "grid grid-cols-[1fr_min-content_min-content] gap-
|
|
1967
|
+
}, t("select-option.label")), /* @__PURE__ */ React13.createElement("div", {
|
|
1968
|
+
className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
|
|
1869
1969
|
}, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
|
|
1870
1970
|
disabled: !!readonly,
|
|
1871
|
-
placeholder: t("select
|
|
1971
|
+
placeholder: t("select-option-label.placeholder"),
|
|
1872
1972
|
ref: selected === item.id ? inputRef : void 0,
|
|
1873
1973
|
value: item.title,
|
|
1874
1974
|
onChange: handleTitleChange(item.id),
|
|
@@ -1882,12 +1982,12 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1882
1982
|
disabled: !!readonly,
|
|
1883
1983
|
icon: "ph--trash--fill",
|
|
1884
1984
|
iconOnly: true,
|
|
1885
|
-
label: t("select
|
|
1985
|
+
label: t("select-option-delete.button"),
|
|
1886
1986
|
onClick: () => handleDelete(item.id)
|
|
1887
1987
|
})))))), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1888
1988
|
variant: "ghost",
|
|
1889
1989
|
icon: "ph--plus--regular",
|
|
1890
|
-
label: t("select
|
|
1990
|
+
label: t("select-option-add.button"),
|
|
1891
1991
|
onClick: handleAdd,
|
|
1892
1992
|
disabled: !!readonly,
|
|
1893
1993
|
classNames: "w-full"
|
|
@@ -1897,7 +1997,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1897
1997
|
// src/components/Form/fields/TextField.tsx
|
|
1898
1998
|
import React14, { useCallback as useCallback12 } from "react";
|
|
1899
1999
|
import { Input as Input9 } from "@dxos/react-ui";
|
|
1900
|
-
var TextField = ({ type, readonly, placeholder,
|
|
2000
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
1901
2001
|
const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
|
|
1902
2002
|
type,
|
|
1903
2003
|
onValueChange
|
|
@@ -1910,8 +2010,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
|
|
|
1910
2010
|
disabled: !!readonly,
|
|
1911
2011
|
placeholder,
|
|
1912
2012
|
value: value3,
|
|
1913
|
-
|
|
1914
|
-
|
|
2013
|
+
onBlur,
|
|
2014
|
+
onChange: handleChange
|
|
1915
2015
|
}));
|
|
1916
2016
|
};
|
|
1917
2017
|
|
|
@@ -1939,7 +2039,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1939
2039
|
// src/components/Form/fields/TupleField.tsx
|
|
1940
2040
|
import React16 from "react";
|
|
1941
2041
|
import { Input as Input11 } from "@dxos/react-ui";
|
|
1942
|
-
import { mx as
|
|
2042
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1943
2043
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1944
2044
|
var gridCols = [
|
|
1945
2045
|
"grid-cols-1",
|
|
@@ -1957,7 +2057,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1957
2057
|
readonly,
|
|
1958
2058
|
label
|
|
1959
2059
|
}), /* @__PURE__ */ React16.createElement("div", {
|
|
1960
|
-
className:
|
|
2060
|
+
className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
|
|
1961
2061
|
}, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
|
|
1962
2062
|
key: prop,
|
|
1963
2063
|
type: "number",
|
|
@@ -1976,13 +2076,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1976
2076
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1977
2077
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1978
2078
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
1979
|
-
const { t } =
|
|
1980
|
-
const [props, setProps] =
|
|
1981
|
-
|
|
2079
|
+
const { t } = useTranslation9(translationKey9);
|
|
2080
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2081
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1982
2082
|
field,
|
|
1983
2083
|
projection
|
|
1984
2084
|
]);
|
|
1985
|
-
const [schemas, setSchemas] =
|
|
2085
|
+
const [schemas, setSchemas] = useState6([]);
|
|
1986
2086
|
useAsyncEffect(async () => {
|
|
1987
2087
|
if (!registry) {
|
|
1988
2088
|
return;
|
|
@@ -1996,22 +2096,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
1996
2096
|
}, [
|
|
1997
2097
|
registry
|
|
1998
2098
|
]);
|
|
1999
|
-
const [referenceSchema, setReferenceSchema] =
|
|
2000
|
-
|
|
2099
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2100
|
+
useEffect5(() => {
|
|
2001
2101
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
2002
2102
|
}, [
|
|
2003
2103
|
schemas,
|
|
2004
2104
|
props?.referenceSchema
|
|
2005
2105
|
]);
|
|
2006
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2106
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
2007
2107
|
fieldSchema: getFormatSchema(props?.format)
|
|
2008
2108
|
});
|
|
2009
|
-
const fieldMap =
|
|
2109
|
+
const fieldMap = useMemo8(() => ({
|
|
2010
2110
|
["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
2011
2111
|
...props2,
|
|
2012
2112
|
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
2013
2113
|
value: value3,
|
|
2014
|
-
label: t(`format
|
|
2114
|
+
label: t(`format.${value3}.label`)
|
|
2015
2115
|
}))
|
|
2016
2116
|
}),
|
|
2017
2117
|
["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
@@ -2085,7 +2185,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2085
2185
|
]);
|
|
2086
2186
|
const handleSave = useCallback14((props2) => {
|
|
2087
2187
|
if (view) {
|
|
2088
|
-
|
|
2188
|
+
Obj3.update(view, () => {
|
|
2089
2189
|
projection.setFieldProjection({
|
|
2090
2190
|
field,
|
|
2091
2191
|
props: props2
|
|
@@ -2113,12 +2213,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2113
2213
|
if (!fieldSchema) {
|
|
2114
2214
|
log2.warn("invalid format", {
|
|
2115
2215
|
props
|
|
2116
|
-
}, {
|
|
2117
|
-
F: __dxlog_file2,
|
|
2118
|
-
L: 172,
|
|
2119
|
-
S: void 0,
|
|
2120
|
-
C: (f, a) => f(...a)
|
|
2121
|
-
});
|
|
2216
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2122
2217
|
return null;
|
|
2123
2218
|
}
|
|
2124
2219
|
return /* @__PURE__ */ React17.createElement(Form.Root, {
|
|
@@ -2140,160 +2235,488 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2140
2235
|
}, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
|
|
2141
2236
|
};
|
|
2142
2237
|
|
|
2143
|
-
// src/components/
|
|
2144
|
-
import
|
|
2145
|
-
import
|
|
2146
|
-
import {
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
var
|
|
2153
|
-
var
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
};
|
|
2170
|
-
|
|
2171
|
-
var SettingsSection = ({ title, description, children }) => {
|
|
2172
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SettingsSectionHeading, {
|
|
2173
|
-
title,
|
|
2174
|
-
description
|
|
2175
|
-
}), /* @__PURE__ */ React18.createElement("div", {
|
|
2176
|
-
className: "w-full pt-trim-md space-y-trim-md"
|
|
2177
|
-
}, children));
|
|
2178
|
-
};
|
|
2179
|
-
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2180
|
-
var SettingsSectionHeading = ({ title, description }) => {
|
|
2181
|
-
const { t } = useTranslation9(translationKey);
|
|
2182
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
|
|
2183
|
-
className: "px-trim-md mt-trim-md mb-trim-md text-xl"
|
|
2184
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
|
|
2185
|
-
className: "px-trim-md my-trim-md text-description"
|
|
2186
|
-
}, toLocalizedString(description, t)));
|
|
2238
|
+
// src/components/ObjectForm/ObjectForm.tsx
|
|
2239
|
+
import * as Schema3 from "effect/Schema";
|
|
2240
|
+
import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
|
|
2241
|
+
import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
|
|
2242
|
+
import { splitJsonPath } from "@dxos/echo/internal";
|
|
2243
|
+
import { invariant } from "@dxos/invariant";
|
|
2244
|
+
import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
|
|
2245
|
+
import { isNonNullable } from "@dxos/util";
|
|
2246
|
+
import { translationKey as translationKey10 } from "#translations";
|
|
2247
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
|
|
2248
|
+
var createFieldMap = {
|
|
2249
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2250
|
+
const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
|
|
2251
|
+
onValueChange,
|
|
2252
|
+
type
|
|
2253
|
+
]);
|
|
2254
|
+
const handleReset = useCallback15(() => onValueChange(type, void 0), [
|
|
2255
|
+
onValueChange,
|
|
2256
|
+
type
|
|
2257
|
+
]);
|
|
2258
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
|
|
2259
|
+
label
|
|
2260
|
+
}), /* @__PURE__ */ React18.createElement(HuePicker2, {
|
|
2261
|
+
value: getValue(),
|
|
2262
|
+
onChange: handleChange,
|
|
2263
|
+
onReset: handleReset
|
|
2264
|
+
}));
|
|
2265
|
+
}
|
|
2187
2266
|
};
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2267
|
+
var ObjectForm = ({ object, schema }) => {
|
|
2268
|
+
const db = Obj4.getDatabase(object);
|
|
2269
|
+
const meta = Obj4.getMeta(object);
|
|
2270
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
|
|
2271
|
+
const values = useMemo9(() => ({
|
|
2272
|
+
tags,
|
|
2273
|
+
...object
|
|
2274
|
+
}), [
|
|
2275
|
+
object,
|
|
2276
|
+
tags
|
|
2277
|
+
]);
|
|
2278
|
+
const formSchema = useMemo9(() => omitId(Schema3.Struct({
|
|
2279
|
+
tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
|
|
2280
|
+
}).pipe(Schema3.extend(schema))), [
|
|
2281
|
+
schema
|
|
2282
|
+
]);
|
|
2283
|
+
const handleCreate = useCallback15((schema2, values2) => {
|
|
2284
|
+
invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
|
|
2285
|
+
invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2286
|
+
const newObject = db.add(Obj4.make(schema2, values2));
|
|
2287
|
+
if (Obj4.instanceOf(Tag2.Tag, newObject)) {
|
|
2288
|
+
Obj4.update(object, (object2) => {
|
|
2289
|
+
Obj4.getMeta(object2).tags = [
|
|
2290
|
+
...Obj4.getMeta(object2).tags ?? [],
|
|
2291
|
+
Obj4.getDXN(newObject).toString()
|
|
2292
|
+
];
|
|
2293
|
+
});
|
|
2294
|
+
}
|
|
2295
|
+
}, []);
|
|
2296
|
+
const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2297
|
+
if (!isValid) {
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2301
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
|
|
2302
|
+
if (hasTagsChange) {
|
|
2303
|
+
Obj4.update(object, (object2) => {
|
|
2304
|
+
Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2307
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
|
|
2308
|
+
if (nonTagPaths.length > 0) {
|
|
2309
|
+
Obj4.update(object, () => {
|
|
2310
|
+
for (const path of nonTagPaths) {
|
|
2311
|
+
const parts = splitJsonPath(path);
|
|
2312
|
+
const value3 = Obj4.getValue(values2, parts);
|
|
2313
|
+
Obj4.setValue(object, parts, value3);
|
|
2314
|
+
}
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
}, [
|
|
2318
|
+
object
|
|
2319
|
+
]);
|
|
2320
|
+
return /* @__PURE__ */ React18.createElement(Form.Root, {
|
|
2321
|
+
schema: formSchema,
|
|
2322
|
+
defaultValues: values,
|
|
2323
|
+
createTypename: Type2.getTypename(Tag2.Tag),
|
|
2324
|
+
createOptionIcon: "ph--plus--regular",
|
|
2325
|
+
createOptionLabel: [
|
|
2326
|
+
"add-tag.label",
|
|
2327
|
+
{
|
|
2328
|
+
ns: translationKey10
|
|
2329
|
+
}
|
|
2330
|
+
],
|
|
2331
|
+
createInitialValuePath: "label",
|
|
2332
|
+
createFieldMap,
|
|
2333
|
+
db,
|
|
2334
|
+
onValuesChanged: handleChange,
|
|
2335
|
+
onCreate: handleCreate
|
|
2336
|
+
}, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
|
|
2197
2337
|
};
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
}
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2338
|
+
|
|
2339
|
+
// src/components/ObjectProperties/ObjectProperties.tsx
|
|
2340
|
+
import * as Function from "effect/Function";
|
|
2341
|
+
import * as Option5 from "effect/Option";
|
|
2342
|
+
import * as Schema4 from "effect/Schema";
|
|
2343
|
+
import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
|
|
2344
|
+
import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
|
|
2345
|
+
import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
|
|
2346
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2347
|
+
import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
|
|
2348
|
+
import { FactoryAnnotation } from "@dxos/schema";
|
|
2349
|
+
import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
|
|
2350
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
2351
|
+
import { translationKey as translationKey11 } from "#translations";
|
|
2352
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
|
|
2353
|
+
var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
|
|
2354
|
+
const db = Obj5.getDatabase(object);
|
|
2355
|
+
const meta = Obj5.getMeta(object);
|
|
2356
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
|
|
2357
|
+
const values = useMemo10(() => ({
|
|
2358
|
+
tags,
|
|
2359
|
+
...object
|
|
2360
|
+
}), [
|
|
2361
|
+
object,
|
|
2362
|
+
tags
|
|
2363
|
+
]);
|
|
2364
|
+
const formSchema = useMemo10(() => {
|
|
2365
|
+
return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
|
|
2366
|
+
}, [
|
|
2367
|
+
object
|
|
2368
|
+
]);
|
|
2369
|
+
const handleCreate = useCallback16((schema, values2) => {
|
|
2370
|
+
invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
|
|
2371
|
+
invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2372
|
+
const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
|
|
2373
|
+
const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
|
|
2374
|
+
return db.add(newObject);
|
|
2375
|
+
}, [
|
|
2376
|
+
db
|
|
2377
|
+
]);
|
|
2378
|
+
const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2379
|
+
if (!isValid) {
|
|
2380
|
+
return;
|
|
2381
|
+
}
|
|
2382
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2383
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
|
|
2384
|
+
if (hasTagsChange) {
|
|
2385
|
+
Obj5.update(object, (object2) => {
|
|
2386
|
+
Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2387
|
+
});
|
|
2388
|
+
}
|
|
2389
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
|
|
2390
|
+
if (nonTagPaths.length > 0) {
|
|
2391
|
+
Obj5.update(object, () => {
|
|
2392
|
+
for (const path of nonTagPaths) {
|
|
2393
|
+
const parts = splitJsonPath2(path);
|
|
2394
|
+
const value3 = Obj5.getValue(values2, parts);
|
|
2395
|
+
Obj5.setValue(object, parts, value3);
|
|
2396
|
+
}
|
|
2397
|
+
});
|
|
2398
|
+
}
|
|
2399
|
+
}, [
|
|
2400
|
+
object
|
|
2401
|
+
]);
|
|
2402
|
+
if (!formSchema) {
|
|
2403
|
+
return null;
|
|
2404
|
+
}
|
|
2405
|
+
return /* @__PURE__ */ React19.createElement(Form.Root, {
|
|
2406
|
+
schema: formSchema,
|
|
2407
|
+
defaultValues: values,
|
|
2408
|
+
createTypename: Type3.getTypename(Tag3.Tag),
|
|
2409
|
+
createOptionIcon: "ph--plus--regular",
|
|
2410
|
+
createOptionLabel: [
|
|
2411
|
+
"add-tag.label",
|
|
2412
|
+
{
|
|
2413
|
+
ns: translationKey11
|
|
2414
|
+
}
|
|
2415
|
+
],
|
|
2416
|
+
createInitialValuePath: "label",
|
|
2417
|
+
createFieldMap: createFieldMap2,
|
|
2418
|
+
db,
|
|
2419
|
+
onValuesChanged: handleChange,
|
|
2420
|
+
onCreate: handleCreate
|
|
2421
|
+
}, /* @__PURE__ */ React19.createElement(Form.Viewport, {
|
|
2422
|
+
...composableProps2(props),
|
|
2423
|
+
ref: forwardedRef
|
|
2424
|
+
}, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
|
|
2425
|
+
});
|
|
2426
|
+
var createFieldMap2 = {
|
|
2427
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2428
|
+
const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
|
|
2429
|
+
onValueChange,
|
|
2430
|
+
type
|
|
2431
|
+
]);
|
|
2432
|
+
const handleReset = useCallback16(() => onValueChange(type, void 0), [
|
|
2433
|
+
onValueChange,
|
|
2434
|
+
type
|
|
2435
|
+
]);
|
|
2436
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
|
|
2437
|
+
label
|
|
2438
|
+
}), /* @__PURE__ */ React19.createElement(HuePicker3, {
|
|
2439
|
+
value: getValue(),
|
|
2440
|
+
onChange: handleChange,
|
|
2441
|
+
onReset: handleReset
|
|
2442
|
+
}));
|
|
2443
|
+
}
|
|
2219
2444
|
};
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2445
|
+
var BaseSchema = Schema4.Struct({
|
|
2446
|
+
tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
|
|
2447
|
+
});
|
|
2448
|
+
|
|
2449
|
+
// src/components/Settings/Settings.tsx
|
|
2450
|
+
import React22 from "react";
|
|
2451
|
+
import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
|
|
2452
|
+
import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
|
|
2453
|
+
import { translationKey as translationKey13 } from "#translations";
|
|
2454
|
+
|
|
2455
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2456
|
+
import * as SchemaAST5 from "effect/SchemaAST";
|
|
2457
|
+
import * as String3 from "effect/String";
|
|
2458
|
+
import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
|
|
2459
|
+
import { getAnnotation as getAnnotation3 } from "@dxos/effect";
|
|
2460
|
+
import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
|
|
2461
|
+
|
|
2462
|
+
// src/components/Settings/SettingsItem.tsx
|
|
2463
|
+
import React20 from "react";
|
|
2464
|
+
import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
2465
|
+
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2466
|
+
import { translationKey as translationKey12 } from "#translations";
|
|
2467
|
+
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
2468
|
+
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
2469
|
+
var SettingsPanel = ({ classNames, children }) => {
|
|
2470
|
+
return /* @__PURE__ */ React20.createElement("div", {
|
|
2471
|
+
className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2230
2472
|
}, children);
|
|
2231
2473
|
};
|
|
2232
|
-
|
|
2474
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2233
2475
|
var SettingsItem = ({ title, description = "", children }) => {
|
|
2234
|
-
const { t } =
|
|
2235
|
-
return /* @__PURE__ */
|
|
2236
|
-
classNames:
|
|
2237
|
-
}, /* @__PURE__ */
|
|
2238
|
-
|
|
2239
|
-
}, toLocalizedString(title, t)), /* @__PURE__ */
|
|
2240
|
-
|
|
2241
|
-
}, toLocalizedString(description, t)), /* @__PURE__ */
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
}, children));
|
|
2476
|
+
const { t } = useTranslation10(translationKey12);
|
|
2477
|
+
return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
|
|
2478
|
+
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
2479
|
+
}, /* @__PURE__ */ React20.createElement(Input12.Label, {
|
|
2480
|
+
classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
|
|
2481
|
+
}, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
|
|
2482
|
+
classNames: "text-base text-description"
|
|
2483
|
+
}, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
|
|
2484
|
+
className: "text-end py-1"
|
|
2485
|
+
}, children)));
|
|
2245
2486
|
};
|
|
2246
2487
|
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2488
|
+
|
|
2489
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2490
|
+
var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
|
|
2491
|
+
const properties = useMemo11(() => {
|
|
2492
|
+
const props = getFormProperties(schema.ast);
|
|
2493
|
+
if (!sort) {
|
|
2494
|
+
return props;
|
|
2495
|
+
}
|
|
2496
|
+
const rank = (name) => {
|
|
2497
|
+
const idx = sort.indexOf(name);
|
|
2498
|
+
return idx === -1 ? Number.POSITIVE_INFINITY : idx;
|
|
2499
|
+
};
|
|
2500
|
+
return [
|
|
2501
|
+
...props
|
|
2502
|
+
].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
|
|
2503
|
+
}, [
|
|
2504
|
+
schema,
|
|
2505
|
+
sort
|
|
2506
|
+
]);
|
|
2507
|
+
const handleChange = useCallback17((name, value3) => {
|
|
2508
|
+
onValuesChanged?.({
|
|
2509
|
+
...values,
|
|
2510
|
+
[name]: value3
|
|
2511
|
+
});
|
|
2512
|
+
}, [
|
|
2513
|
+
values,
|
|
2514
|
+
onValuesChanged
|
|
2515
|
+
]);
|
|
2516
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
|
|
2517
|
+
const name = property.name.toString();
|
|
2518
|
+
const path = pathPrefix ? `${pathPrefix}.${name}` : name;
|
|
2519
|
+
if (visible && !visible(path, values)) {
|
|
2520
|
+
return null;
|
|
2521
|
+
}
|
|
2522
|
+
const entry = fieldMap?.[name];
|
|
2523
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
|
|
2524
|
+
key: name,
|
|
2525
|
+
path,
|
|
2526
|
+
property,
|
|
2527
|
+
value: values[name],
|
|
2528
|
+
onChange: (value3) => handleChange(name, value3),
|
|
2529
|
+
readonly,
|
|
2530
|
+
customField: typeof entry === "function" ? entry : void 0,
|
|
2531
|
+
nestedFieldMap: typeof entry === "object" ? entry : void 0,
|
|
2532
|
+
visible,
|
|
2533
|
+
sort
|
|
2534
|
+
});
|
|
2535
|
+
}));
|
|
2536
|
+
};
|
|
2537
|
+
SettingsFieldSet.displayName = "Settings.FieldSet";
|
|
2538
|
+
var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
|
|
2539
|
+
const { type } = property;
|
|
2540
|
+
const name = property.name.toString();
|
|
2541
|
+
const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
|
|
2542
|
+
const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
|
|
2543
|
+
if (customField) {
|
|
2544
|
+
const CustomField = customField;
|
|
2545
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2546
|
+
title,
|
|
2547
|
+
description
|
|
2548
|
+
}, /* @__PURE__ */ React21.createElement(CustomField, {
|
|
2549
|
+
value: value3,
|
|
2550
|
+
onChange,
|
|
2551
|
+
readonly
|
|
2552
|
+
}));
|
|
2553
|
+
}
|
|
2554
|
+
const fieldType = detectFieldType(type);
|
|
2555
|
+
switch (fieldType) {
|
|
2556
|
+
case "struct":
|
|
2557
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
|
|
2558
|
+
schema: {
|
|
2559
|
+
ast: type
|
|
2560
|
+
},
|
|
2561
|
+
values: value3 ?? {},
|
|
2562
|
+
onValuesChanged: onChange,
|
|
2563
|
+
readonly,
|
|
2564
|
+
fieldMap: nestedFieldMap,
|
|
2565
|
+
visible,
|
|
2566
|
+
sort,
|
|
2567
|
+
pathPrefix: path
|
|
2568
|
+
});
|
|
2569
|
+
case "boolean":
|
|
2570
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2571
|
+
title,
|
|
2572
|
+
description
|
|
2573
|
+
}, /* @__PURE__ */ React21.createElement(Input13.Switch, {
|
|
2574
|
+
disabled: readonly,
|
|
2575
|
+
checked: !!value3,
|
|
2576
|
+
onCheckedChange: (checked) => onChange(!!checked)
|
|
2577
|
+
}));
|
|
2578
|
+
case "select": {
|
|
2579
|
+
const options = getSelectOptionsFromAst(type) ?? [];
|
|
2580
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2581
|
+
title,
|
|
2582
|
+
description
|
|
2583
|
+
}, /* @__PURE__ */ React21.createElement(Select2.Root, {
|
|
2584
|
+
disabled: readonly,
|
|
2585
|
+
value: value3 == null ? "" : globalThis.String(value3),
|
|
2586
|
+
onValueChange: (selected) => {
|
|
2587
|
+
const matched = options.find((option) => globalThis.String(option.value) === selected);
|
|
2588
|
+
onChange(matched?.value ?? selected);
|
|
2589
|
+
}
|
|
2590
|
+
}, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
|
|
2591
|
+
disabled: readonly
|
|
2592
|
+
}), /* @__PURE__ */ React21.createElement(Select2.Portal, null, /* @__PURE__ */ React21.createElement(Select2.Content, null, /* @__PURE__ */ React21.createElement(Select2.Viewport, null, options.map((option) => /* @__PURE__ */ React21.createElement(Select2.Option, {
|
|
2593
|
+
key: globalThis.String(option.value),
|
|
2594
|
+
value: globalThis.String(option.value)
|
|
2595
|
+
}, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
|
|
2596
|
+
}
|
|
2597
|
+
case "string":
|
|
2598
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2599
|
+
title,
|
|
2600
|
+
description
|
|
2601
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2602
|
+
disabled: readonly,
|
|
2603
|
+
value: value3 ?? "",
|
|
2604
|
+
onChange: (event) => onChange(event.target.value)
|
|
2605
|
+
}));
|
|
2606
|
+
case "number":
|
|
2607
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2608
|
+
title,
|
|
2609
|
+
description
|
|
2610
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2611
|
+
disabled: readonly,
|
|
2612
|
+
type: "number",
|
|
2613
|
+
value: value3 ?? "",
|
|
2614
|
+
onChange: (event) => {
|
|
2615
|
+
if (event.target.value === "") {
|
|
2616
|
+
onChange(void 0);
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
const parsed = Number(event.target.value);
|
|
2620
|
+
onChange(Number.isNaN(parsed) ? void 0 : parsed);
|
|
2621
|
+
}
|
|
2622
|
+
}));
|
|
2623
|
+
default:
|
|
2624
|
+
return null;
|
|
2625
|
+
}
|
|
2626
|
+
};
|
|
2627
|
+
|
|
2628
|
+
// src/components/Settings/Settings.tsx
|
|
2629
|
+
var SETTINGS_ROOT_NAME = "Settings.Root";
|
|
2630
|
+
var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
|
|
2631
|
+
var SETTINGS_SECTION_NAME = "Settings.Section";
|
|
2632
|
+
var SettingsRoot = ({ children, classNames }) => {
|
|
2633
|
+
return /* @__PURE__ */ React22.createElement("div", {
|
|
2634
|
+
className: mx4("flex flex-col gap-2", classNames)
|
|
2635
|
+
}, children);
|
|
2636
|
+
};
|
|
2637
|
+
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
2638
|
+
var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
|
|
2639
|
+
return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
|
|
2640
|
+
...composableProps3(props),
|
|
2641
|
+
orientation: "vertical",
|
|
2642
|
+
centered: true,
|
|
2643
|
+
thin: true,
|
|
2644
|
+
ref: forwardedRef
|
|
2645
|
+
}, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
|
|
2646
|
+
classNames: "px-4 pointer-coarse:px-2"
|
|
2647
|
+
}, /* @__PURE__ */ React22.createElement("div", {
|
|
2648
|
+
className: "dx-document flex flex-col gap-2 py-4"
|
|
2258
2649
|
}, children)));
|
|
2650
|
+
});
|
|
2651
|
+
SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
|
|
2652
|
+
var SettingsSection = ({ title, description, children }) => {
|
|
2653
|
+
const { t } = useTranslation11(translationKey13);
|
|
2654
|
+
return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
|
|
2655
|
+
className: "px-trim-md mt-trim-md text-xl"
|
|
2656
|
+
}, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
|
|
2657
|
+
className: "px-trim-md text-description"
|
|
2658
|
+
}, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
|
|
2659
|
+
className: "w-full pt-trim-md space-y-trim-md"
|
|
2660
|
+
}, children));
|
|
2259
2661
|
};
|
|
2260
|
-
|
|
2662
|
+
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2261
2663
|
var Settings = {
|
|
2262
2664
|
Root: SettingsRoot,
|
|
2665
|
+
Viewport: SettingsViewport,
|
|
2263
2666
|
Section: SettingsSection,
|
|
2264
|
-
|
|
2265
|
-
Group: SettingsGroup,
|
|
2266
|
-
GroupButton: SettingsGroupButton,
|
|
2267
|
-
Container: SettingsContainer,
|
|
2268
|
-
Frame: SettingsFrame,
|
|
2269
|
-
FrameItem: SettingsFrameItem,
|
|
2667
|
+
Panel: SettingsPanel,
|
|
2270
2668
|
Item: SettingsItem,
|
|
2271
|
-
|
|
2669
|
+
FieldSet: SettingsFieldSet
|
|
2670
|
+
};
|
|
2671
|
+
|
|
2672
|
+
// src/components/Settings/SettingsSelectField.tsx
|
|
2673
|
+
import React23 from "react";
|
|
2674
|
+
import { Select as Select3 } from "@dxos/react-ui";
|
|
2675
|
+
var createSelectField = ({ options, defaultLabel = "Default" }) => {
|
|
2676
|
+
const normalized = options.map((option) => typeof option === "string" ? {
|
|
2677
|
+
value: option,
|
|
2678
|
+
label: option
|
|
2679
|
+
} : option);
|
|
2680
|
+
const hasDefault = defaultLabel !== null;
|
|
2681
|
+
const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
|
|
2682
|
+
return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
|
|
2683
|
+
disabled: readonly,
|
|
2684
|
+
value: value3 ?? sentinel,
|
|
2685
|
+
onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
|
|
2686
|
+
}, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
|
|
2687
|
+
disabled: readonly
|
|
2688
|
+
}), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2689
|
+
value: sentinel
|
|
2690
|
+
}, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2691
|
+
key: option.value,
|
|
2692
|
+
value: option.value
|
|
2693
|
+
}, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
|
|
2272
2694
|
};
|
|
2273
2695
|
|
|
2274
2696
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2275
2697
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2276
|
-
import * as
|
|
2698
|
+
import * as Array4 from "effect/Array";
|
|
2277
2699
|
import * as Match2 from "effect/Match";
|
|
2278
|
-
import * as
|
|
2279
|
-
import * as
|
|
2280
|
-
import
|
|
2281
|
-
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as
|
|
2700
|
+
import * as Option6 from "effect/Option";
|
|
2701
|
+
import * as Schema5 from "effect/Schema";
|
|
2702
|
+
import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
|
|
2703
|
+
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6 } from "@dxos/echo";
|
|
2282
2704
|
import { View } from "@dxos/echo";
|
|
2283
2705
|
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2284
|
-
import { invariant } from "@dxos/invariant";
|
|
2706
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2285
2707
|
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2286
|
-
import { IconButton as IconButton4, Input as
|
|
2708
|
+
import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
2287
2709
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2288
2710
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2289
2711
|
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2290
|
-
import { mx as
|
|
2291
|
-
|
|
2292
|
-
var
|
|
2712
|
+
import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
|
|
2713
|
+
import { translationKey as translationKey14 } from "#translations";
|
|
2714
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
2715
|
+
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2293
2716
|
const atomRegistry = useContext(RegistryContext);
|
|
2294
2717
|
const schemaReadonly = !isMutable(schema);
|
|
2295
|
-
const { t } =
|
|
2296
|
-
const projectionModel =
|
|
2718
|
+
const { t } = useTranslation12(translationKey14);
|
|
2719
|
+
const projectionModel = useMemo12(() => {
|
|
2297
2720
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2298
2721
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2299
2722
|
const model = new ProjectionModel({
|
|
@@ -2317,21 +2740,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2317
2740
|
if (from._tag !== "scope") {
|
|
2318
2741
|
return void 0;
|
|
2319
2742
|
}
|
|
2320
|
-
return
|
|
2743
|
+
return Option6.fromNullable(from.scope.queues).pipe(Option6.flatMap((queues) => Array4.head(queues)), Option6.map(String), Option6.getOrUndefined);
|
|
2321
2744
|
}), Match2.orElse(() => void 0));
|
|
2322
2745
|
const feeds = useQuery2(db, Filter2.type(Feed.Feed));
|
|
2323
|
-
const targetRef =
|
|
2746
|
+
const targetRef = useMemo12(() => {
|
|
2324
2747
|
if (!queueTarget) {
|
|
2325
2748
|
return void 0;
|
|
2326
2749
|
}
|
|
2327
2750
|
const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
|
|
2328
|
-
return feed ?
|
|
2751
|
+
return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
|
|
2329
2752
|
}, [
|
|
2330
2753
|
queueTarget,
|
|
2331
2754
|
feeds
|
|
2332
2755
|
]);
|
|
2333
|
-
const viewSchema =
|
|
2334
|
-
const base =
|
|
2756
|
+
const viewSchema = useMemo12(() => {
|
|
2757
|
+
const base = Schema5.Struct({
|
|
2335
2758
|
query: mode === "schema" ? Format5.URL.annotations({
|
|
2336
2759
|
title: "Record type"
|
|
2337
2760
|
}) : QueryAST.Query.annotations({
|
|
@@ -2339,19 +2762,19 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2339
2762
|
})
|
|
2340
2763
|
});
|
|
2341
2764
|
if (mode === "tag") {
|
|
2342
|
-
return
|
|
2765
|
+
return Schema5.Struct({
|
|
2343
2766
|
...base.fields,
|
|
2344
2767
|
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2345
|
-
target:
|
|
2768
|
+
target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2346
2769
|
title: "Target Feed"
|
|
2347
|
-
}), ParentLabelAnnotation.set(true),
|
|
2348
|
-
}).pipe(
|
|
2770
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
2771
|
+
}).pipe(Schema5.mutable);
|
|
2349
2772
|
}
|
|
2350
|
-
return base.pipe(
|
|
2773
|
+
return base.pipe(Schema5.mutable);
|
|
2351
2774
|
}, [
|
|
2352
2775
|
mode
|
|
2353
2776
|
]);
|
|
2354
|
-
const viewValues =
|
|
2777
|
+
const viewValues = useMemo12(() => ({
|
|
2355
2778
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2356
2779
|
target: targetRef
|
|
2357
2780
|
}), [
|
|
@@ -2359,7 +2782,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2359
2782
|
view.query.ast,
|
|
2360
2783
|
targetRef
|
|
2361
2784
|
]);
|
|
2362
|
-
const fieldMap =
|
|
2785
|
+
const fieldMap = useMemo12(() => mode === "tag" ? customFields({
|
|
2363
2786
|
types,
|
|
2364
2787
|
tags
|
|
2365
2788
|
}) : void 0, [
|
|
@@ -2367,12 +2790,12 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2367
2790
|
types,
|
|
2368
2791
|
tags
|
|
2369
2792
|
]);
|
|
2370
|
-
const handleUpdate =
|
|
2793
|
+
const handleUpdate = useCallback18((values) => {
|
|
2371
2794
|
const targetValue = values.target;
|
|
2372
2795
|
let queueDxn;
|
|
2373
|
-
if (
|
|
2796
|
+
if (Ref6.isRef(targetValue)) {
|
|
2374
2797
|
const feedDxn = targetValue.dxn.toString();
|
|
2375
|
-
const feed = feeds.find((feed2) =>
|
|
2798
|
+
const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === feedDxn);
|
|
2376
2799
|
if (feed) {
|
|
2377
2800
|
queueDxn = Feed.getQueueDxn(feed)?.toString();
|
|
2378
2801
|
}
|
|
@@ -2384,37 +2807,28 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2384
2807
|
mode,
|
|
2385
2808
|
feeds
|
|
2386
2809
|
]);
|
|
2387
|
-
const handleDelete =
|
|
2388
|
-
|
|
2389
|
-
F: __dxlog_file3,
|
|
2390
|
-
L: 185,
|
|
2391
|
-
S: void 0,
|
|
2392
|
-
A: [
|
|
2393
|
-
"!readonly",
|
|
2394
|
-
""
|
|
2395
|
-
]
|
|
2396
|
-
});
|
|
2810
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2811
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: void 0, A: ["!readonly", ""] });
|
|
2397
2812
|
onDelete?.(fieldId);
|
|
2398
2813
|
}, [
|
|
2399
2814
|
onDelete,
|
|
2400
2815
|
readonly
|
|
2401
2816
|
]);
|
|
2402
|
-
return /* @__PURE__ */
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Message.Root, {
|
|
2817
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
2818
|
+
className: mx5(classNames)
|
|
2819
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
|
|
2406
2820
|
valence: "info",
|
|
2407
2821
|
classNames: "my-form-padding"
|
|
2408
|
-
}, /* @__PURE__ */
|
|
2822
|
+
}, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
|
|
2409
2823
|
schema: viewSchema,
|
|
2410
2824
|
values: viewValues,
|
|
2411
2825
|
fieldMap,
|
|
2412
2826
|
db,
|
|
2413
2827
|
onValuesChanged: handleUpdate
|
|
2414
|
-
}, /* @__PURE__ */
|
|
2415
|
-
label: t("fields
|
|
2828
|
+
}, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2829
|
+
label: t("fields.label"),
|
|
2416
2830
|
asChild: true
|
|
2417
|
-
}), /* @__PURE__ */
|
|
2831
|
+
}), /* @__PURE__ */ React24.createElement(FieldList, {
|
|
2418
2832
|
schema,
|
|
2419
2833
|
view,
|
|
2420
2834
|
registry,
|
|
@@ -2426,9 +2840,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2426
2840
|
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2427
2841
|
const atomRegistry = useContext(RegistryContext);
|
|
2428
2842
|
const schemaReadonly = !isMutable(schema);
|
|
2429
|
-
const { t } =
|
|
2843
|
+
const { t } = useTranslation12(translationKey14);
|
|
2430
2844
|
const [viewSnapshot] = useObject(view);
|
|
2431
|
-
const projectionModel =
|
|
2845
|
+
const projectionModel = useMemo12(() => {
|
|
2432
2846
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2433
2847
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2434
2848
|
const model = new ProjectionModel({
|
|
@@ -2443,38 +2857,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2443
2857
|
schema,
|
|
2444
2858
|
view
|
|
2445
2859
|
]);
|
|
2446
|
-
const [expandedField, setExpandedField] =
|
|
2447
|
-
const handleAdd =
|
|
2448
|
-
|
|
2449
|
-
F: __dxlog_file3,
|
|
2450
|
-
L: 250,
|
|
2451
|
-
S: void 0,
|
|
2452
|
-
A: [
|
|
2453
|
-
"!readonly",
|
|
2454
|
-
""
|
|
2455
|
-
]
|
|
2456
|
-
});
|
|
2860
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2861
|
+
const handleAdd = useCallback18(() => {
|
|
2862
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 182, S: void 0, A: ["!readonly", ""] });
|
|
2457
2863
|
const field = projectionModel.createFieldProjection();
|
|
2458
2864
|
setExpandedField(field.id);
|
|
2459
2865
|
}, [
|
|
2460
2866
|
projectionModel,
|
|
2461
2867
|
readonly
|
|
2462
2868
|
]);
|
|
2463
|
-
const handleToggleField =
|
|
2869
|
+
const handleToggleField = useCallback18((field) => {
|
|
2464
2870
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2465
2871
|
}, [
|
|
2466
2872
|
readonly
|
|
2467
2873
|
]);
|
|
2468
|
-
const handleDelete =
|
|
2469
|
-
|
|
2470
|
-
F: __dxlog_file3,
|
|
2471
|
-
L: 264,
|
|
2472
|
-
S: void 0,
|
|
2473
|
-
A: [
|
|
2474
|
-
"!readonly",
|
|
2475
|
-
""
|
|
2476
|
-
]
|
|
2477
|
-
});
|
|
2874
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2875
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 195, S: void 0, A: ["!readonly", ""] });
|
|
2478
2876
|
if (fieldId === expandedField) {
|
|
2479
2877
|
setExpandedField(void 0);
|
|
2480
2878
|
}
|
|
@@ -2484,36 +2882,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2484
2882
|
onDelete,
|
|
2485
2883
|
readonly
|
|
2486
2884
|
]);
|
|
2487
|
-
const handleMove =
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
L: 276,
|
|
2491
|
-
S: void 0,
|
|
2492
|
-
A: [
|
|
2493
|
-
"!readonly",
|
|
2494
|
-
""
|
|
2495
|
-
]
|
|
2496
|
-
});
|
|
2497
|
-
Obj3.change(view, (v) => {
|
|
2885
|
+
const handleMove = useCallback18((fromIndex, toIndex) => {
|
|
2886
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 206, S: void 0, A: ["!readonly", ""] });
|
|
2887
|
+
Obj6.update(view, (view2) => {
|
|
2498
2888
|
const fields = [
|
|
2499
|
-
...
|
|
2889
|
+
...view2.projection.fields
|
|
2500
2890
|
];
|
|
2501
2891
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2502
2892
|
fields.splice(toIndex, 0, moved);
|
|
2503
|
-
|
|
2893
|
+
view2.projection.fields = fields;
|
|
2504
2894
|
});
|
|
2505
2895
|
}, [
|
|
2506
2896
|
view,
|
|
2507
2897
|
readonly
|
|
2508
2898
|
]);
|
|
2509
|
-
const handleClose =
|
|
2510
|
-
const handleHide =
|
|
2899
|
+
const handleClose = useCallback18(() => setExpandedField(void 0), []);
|
|
2900
|
+
const handleHide = useCallback18((fieldId) => {
|
|
2511
2901
|
setExpandedField(void 0);
|
|
2512
2902
|
projectionModel.hideFieldProjection(fieldId);
|
|
2513
2903
|
}, [
|
|
2514
2904
|
projectionModel
|
|
2515
2905
|
]);
|
|
2516
|
-
const handleShow =
|
|
2906
|
+
const handleShow = useCallback18((property) => {
|
|
2517
2907
|
setExpandedField(void 0);
|
|
2518
2908
|
projectionModel.showFieldProjection(property);
|
|
2519
2909
|
}, [
|
|
@@ -2522,70 +2912,67 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2522
2912
|
if (!viewSnapshot) {
|
|
2523
2913
|
return null;
|
|
2524
2914
|
}
|
|
2525
|
-
return /* @__PURE__ */
|
|
2915
|
+
return /* @__PURE__ */ React24.createElement(List2.Root, {
|
|
2526
2916
|
items: viewSnapshot.projection.fields,
|
|
2527
|
-
isItem:
|
|
2917
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2528
2918
|
getId: (field) => field.id,
|
|
2529
2919
|
onMove: readonly ? void 0 : handleMove,
|
|
2530
2920
|
readonly
|
|
2531
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2921
|
+
}, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
|
|
2532
2922
|
className: "text-sm"
|
|
2533
|
-
}, t("field
|
|
2923
|
+
}, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
|
|
2534
2924
|
role: "list",
|
|
2535
2925
|
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2536
2926
|
}, fields?.map((field) => {
|
|
2537
2927
|
const hidden = field.visible === false;
|
|
2538
|
-
return /* @__PURE__ */
|
|
2928
|
+
return /* @__PURE__ */ React24.createElement(List2.Item, {
|
|
2539
2929
|
key: field.id,
|
|
2540
2930
|
item: field,
|
|
2541
2931
|
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2542
2932
|
"aria-expanded": expandedField === field.id
|
|
2543
|
-
}, /* @__PURE__ */
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
}, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
|
|
2933
|
+
}, /* @__PURE__ */ React24.createElement("div", {
|
|
2934
|
+
className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
|
|
2935
|
+
}, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
|
|
2547
2936
|
disabled: readonly || schemaReadonly
|
|
2548
|
-
}), /* @__PURE__ */
|
|
2937
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
|
|
2549
2938
|
classNames: hidden && "text-subdued",
|
|
2550
2939
|
onClick: () => handleToggleField(field)
|
|
2551
|
-
}, field.path), /* @__PURE__ */
|
|
2552
|
-
label: t(hidden ? "show
|
|
2940
|
+
}, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2941
|
+
label: t(hidden ? "show-field.label" : "hide-field.label"),
|
|
2553
2942
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2554
2943
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2555
2944
|
autoHide: false,
|
|
2556
2945
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2557
2946
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2558
|
-
}), !readonly && /* @__PURE__ */
|
|
2559
|
-
label: t("delete
|
|
2947
|
+
}), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
|
|
2948
|
+
label: t("delete-field.label"),
|
|
2560
2949
|
autoHide: false,
|
|
2561
2950
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2562
2951
|
onClick: () => handleDelete(field.id),
|
|
2563
2952
|
"data-testid": "field.delete"
|
|
2564
|
-
}), /* @__PURE__ */
|
|
2953
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2565
2954
|
iconOnly: true,
|
|
2566
2955
|
variant: "ghost",
|
|
2567
|
-
label: t("toggle
|
|
2956
|
+
label: t("toggle-expand.label", {
|
|
2568
2957
|
ns: osTranslations2
|
|
2569
2958
|
}),
|
|
2570
2959
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2571
2960
|
onClick: () => handleToggleField(field),
|
|
2572
2961
|
"data-testid": "field.toggle"
|
|
2573
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
}, /* @__PURE__ */ React19.createElement(FieldEditor, {
|
|
2962
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
|
|
2963
|
+
className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
|
|
2964
|
+
}, /* @__PURE__ */ React24.createElement(FieldEditor, {
|
|
2577
2965
|
readonly: readonly || schemaReadonly,
|
|
2578
2966
|
registry,
|
|
2579
2967
|
projection: projectionModel,
|
|
2580
2968
|
field,
|
|
2581
2969
|
onSave: handleClose
|
|
2582
2970
|
})));
|
|
2583
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2584
|
-
role: "none",
|
|
2971
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
|
|
2585
2972
|
className: "my-form-padding"
|
|
2586
|
-
}, /* @__PURE__ */
|
|
2973
|
+
}, /* @__PURE__ */ React24.createElement(IconButton4, {
|
|
2587
2974
|
icon: "ph--plus--regular",
|
|
2588
|
-
label: t("add
|
|
2975
|
+
label: t("add-property-button.label"),
|
|
2589
2976
|
onClick: handleAdd,
|
|
2590
2977
|
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2591
2978
|
classNames: "w-full"
|
|
@@ -2593,13 +2980,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2593
2980
|
};
|
|
2594
2981
|
var customFields = ({ types, tags }) => ({
|
|
2595
2982
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2596
|
-
const handleChange =
|
|
2983
|
+
const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
|
|
2597
2984
|
onValueChange
|
|
2598
2985
|
]);
|
|
2599
|
-
return /* @__PURE__ */
|
|
2986
|
+
return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2600
2987
|
readonly,
|
|
2601
2988
|
label
|
|
2602
|
-
}), /* @__PURE__ */
|
|
2989
|
+
}), /* @__PURE__ */ React24.createElement(QueryForm, {
|
|
2603
2990
|
initialQuery: getValue(),
|
|
2604
2991
|
types,
|
|
2605
2992
|
tags,
|
|
@@ -2618,7 +3005,9 @@ export {
|
|
|
2618
3005
|
GeoPointField,
|
|
2619
3006
|
MarkdownField,
|
|
2620
3007
|
NumberField,
|
|
3008
|
+
ObjectForm,
|
|
2621
3009
|
ObjectPicker,
|
|
3010
|
+
ObjectProperties,
|
|
2622
3011
|
RefField,
|
|
2623
3012
|
SelectField,
|
|
2624
3013
|
SelectOptionField,
|
|
@@ -2628,15 +3017,18 @@ export {
|
|
|
2628
3017
|
TupleField,
|
|
2629
3018
|
ViewEditor,
|
|
2630
3019
|
cellClassesForFieldType,
|
|
3020
|
+
createSelectField,
|
|
3021
|
+
detectFieldType,
|
|
2631
3022
|
formatForDisplay,
|
|
2632
3023
|
formatForEditing,
|
|
2633
3024
|
getDefaultValue,
|
|
2634
3025
|
getFormProperties,
|
|
2635
3026
|
getRefProps,
|
|
3027
|
+
getSelectOptionsFromAst,
|
|
3028
|
+
omitHiddenFormFields,
|
|
2636
3029
|
omitId,
|
|
2637
3030
|
parseValue,
|
|
2638
3031
|
pathNotUniqueError,
|
|
2639
|
-
translations,
|
|
2640
3032
|
useFormContext,
|
|
2641
3033
|
useFormFieldState,
|
|
2642
3034
|
useFormHandler,
|