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