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