@dxos/react-ui-form 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced
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 +1009 -612
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +82 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1009 -612
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +84 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +40 -12
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +76 -74
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +11 -5
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -6
- 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 -8
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/RefField.d.ts +12 -6
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
- package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
- package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +26 -4
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +28 -33
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
- package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
- package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +2 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +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 +23 -36
- package/src/components/Form/Form.tsx +77 -48
- package/src/components/Form/FormField.tsx +27 -15
- package/src/components/Form/FormFieldComponent.tsx +6 -3
- package/src/components/Form/FormFieldSet.tsx +49 -32
- package/src/components/Form/fields/ArrayField.tsx +14 -8
- package/src/components/Form/fields/GeoPointField.tsx +8 -7
- package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
- package/src/components/Form/fields/MarkdownField.tsx +135 -45
- package/src/components/Form/fields/RefField.tsx +70 -35
- package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -6
- package/src/components/Form/fields/SelectOptionField.tsx +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 +12 -13
- package/src/components/ViewEditor/ViewEditor.test.tsx +0 -1
- package/src/components/ViewEditor/ViewEditor.tsx +25 -32
- 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 } from "@dxos/ui-theme";
|
|
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;
|
|
@@ -759,12 +718,13 @@ import React3, { useMemo as useMemo3 } from "react";
|
|
|
759
718
|
import * as Match from "effect/Match";
|
|
760
719
|
import * as Option2 from "effect/Option";
|
|
761
720
|
import * as Schema from "effect/Schema";
|
|
762
|
-
import * as
|
|
721
|
+
import * as SchemaAST3 from "effect/SchemaAST";
|
|
763
722
|
import * as String2 from "effect/String";
|
|
764
723
|
import React2, { useMemo as useMemo2 } from "react";
|
|
765
724
|
import { Format as Format3 } from "@dxos/echo";
|
|
766
|
-
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";
|
|
767
726
|
import { useTranslation } from "@dxos/react-ui";
|
|
727
|
+
import { translationKey } from "#translations";
|
|
768
728
|
var FormField = (props) => {
|
|
769
729
|
const {
|
|
770
730
|
type,
|
|
@@ -776,23 +736,25 @@ var FormField = (props) => {
|
|
|
776
736
|
readonly,
|
|
777
737
|
layout,
|
|
778
738
|
// RefFieldProps
|
|
739
|
+
createTypename,
|
|
779
740
|
createOptionLabel,
|
|
780
741
|
createOptionIcon,
|
|
781
742
|
createInitialValuePath,
|
|
743
|
+
createFieldMap: createFieldMap3,
|
|
782
744
|
db,
|
|
783
|
-
schemaHook,
|
|
784
|
-
getOptions
|
|
745
|
+
useSchema: schemaHook,
|
|
746
|
+
getOptions,
|
|
785
747
|
onCreate
|
|
786
748
|
} = props;
|
|
787
749
|
const { t } = useTranslation(translationKey);
|
|
788
|
-
const title =
|
|
789
|
-
const description =
|
|
790
|
-
const examples =
|
|
750
|
+
const title = getAnnotation2(SchemaAST3.TitleAnnotationId)(type);
|
|
751
|
+
const description = getAnnotation2(SchemaAST3.DescriptionAnnotationId)(type);
|
|
752
|
+
const examples = getAnnotation2(SchemaAST3.ExamplesAnnotationId)(type);
|
|
791
753
|
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
792
754
|
title,
|
|
793
755
|
name
|
|
794
756
|
]);
|
|
795
|
-
const placeholder = useMemo2(() => examples?.length ? `${t("example
|
|
757
|
+
const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
|
|
796
758
|
examples,
|
|
797
759
|
description,
|
|
798
760
|
label
|
|
@@ -805,6 +767,7 @@ var FormField = (props) => {
|
|
|
805
767
|
label,
|
|
806
768
|
placeholder,
|
|
807
769
|
layout,
|
|
770
|
+
db,
|
|
808
771
|
...fieldState
|
|
809
772
|
};
|
|
810
773
|
const jsonPath = createJsonPath2(path ?? []);
|
|
@@ -831,7 +794,7 @@ var FormField = (props) => {
|
|
|
831
794
|
if (Field) {
|
|
832
795
|
return /* @__PURE__ */ React2.createElement(Field, fieldProps);
|
|
833
796
|
}
|
|
834
|
-
const options =
|
|
797
|
+
const options = getSelectOptions(type);
|
|
835
798
|
if (options) {
|
|
836
799
|
const fieldProjections = projection?.getFieldProjections();
|
|
837
800
|
const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
|
|
@@ -849,21 +812,23 @@ var FormField = (props) => {
|
|
|
849
812
|
}
|
|
850
813
|
const refProps = getRefProps(type);
|
|
851
814
|
if (refProps) {
|
|
815
|
+
const isCreateTarget = !createTypename || refProps.typename === createTypename;
|
|
852
816
|
return /* @__PURE__ */ React2.createElement(RefField, {
|
|
853
817
|
...fieldProps,
|
|
854
818
|
...refProps,
|
|
855
|
-
createOptionLabel,
|
|
856
|
-
createOptionIcon,
|
|
857
|
-
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,
|
|
858
823
|
db,
|
|
859
|
-
schemaHook,
|
|
860
|
-
getOptions
|
|
824
|
+
useSchema: schemaHook,
|
|
825
|
+
getOptions,
|
|
861
826
|
onCreate
|
|
862
827
|
});
|
|
863
828
|
}
|
|
864
829
|
if (isNestedType(type)) {
|
|
865
830
|
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
866
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type,
|
|
831
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST3.isTypeLiteral);
|
|
867
832
|
if (typeLiteral) {
|
|
868
833
|
const schema = Schema.make(typeLiteral);
|
|
869
834
|
return /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
@@ -879,8 +844,8 @@ var FormField = (props) => {
|
|
|
879
844
|
createOptionIcon,
|
|
880
845
|
createInitialValuePath,
|
|
881
846
|
db,
|
|
882
|
-
schemaHook,
|
|
883
|
-
getOptions
|
|
847
|
+
useSchema: schemaHook,
|
|
848
|
+
getOptions,
|
|
884
849
|
onCreate
|
|
885
850
|
});
|
|
886
851
|
}
|
|
@@ -904,8 +869,8 @@ var getFormField = ({ type, format }) => {
|
|
|
904
869
|
return BooleanField;
|
|
905
870
|
}
|
|
906
871
|
};
|
|
907
|
-
var
|
|
908
|
-
if (
|
|
872
|
+
var getSelectOptions = (ast) => {
|
|
873
|
+
if (isLiteralUnion2(ast)) {
|
|
909
874
|
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
910
875
|
}
|
|
911
876
|
return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
@@ -915,39 +880,13 @@ var getOptions = (ast) => {
|
|
|
915
880
|
var FORM_FIELDSET_NAME = "Form.FieldSet";
|
|
916
881
|
var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
|
|
917
882
|
const values = useFormValues(FORM_FIELDSET_NAME, path);
|
|
918
|
-
const properties =
|
|
919
|
-
if (!schema) {
|
|
920
|
-
return [];
|
|
921
|
-
}
|
|
922
|
-
const schemaProps = getFormProperties(schema.ast);
|
|
923
|
-
const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
|
|
924
|
-
if (projection) {
|
|
925
|
-
const fieldProjections = projection.getFieldProjections();
|
|
926
|
-
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
927
|
-
const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
928
|
-
const orderedProps = [];
|
|
929
|
-
for (const fieldProjection of fieldProjections) {
|
|
930
|
-
const fieldPath = String(fieldProjection.field.path);
|
|
931
|
-
const prop = visibleProps.find((p) => p.name === fieldPath);
|
|
932
|
-
if (prop) {
|
|
933
|
-
orderedProps.push(prop);
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
937
|
-
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
938
|
-
orderedProps.push(...remainingProps);
|
|
939
|
-
return orderedProps;
|
|
940
|
-
}
|
|
941
|
-
return sort ? [
|
|
942
|
-
...filteredProps
|
|
943
|
-
].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
|
|
944
|
-
}, [
|
|
883
|
+
const properties = useFormFieldSetProperties({
|
|
945
884
|
schema,
|
|
946
885
|
values,
|
|
947
886
|
exclude,
|
|
948
887
|
sort,
|
|
949
888
|
projection
|
|
950
|
-
|
|
889
|
+
});
|
|
951
890
|
if ((readonly || layout === "static") && values == null) {
|
|
952
891
|
return null;
|
|
953
892
|
}
|
|
@@ -977,9 +916,49 @@ var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection,
|
|
|
977
916
|
}));
|
|
978
917
|
};
|
|
979
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
|
+
};
|
|
980
954
|
|
|
981
955
|
// src/components/Form/Form.tsx
|
|
982
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
|
+
};
|
|
983
962
|
var [FormContextProvider, useFormContext] = createContext("Form");
|
|
984
963
|
var useFormValues = (componentName, path, defaultValue) => {
|
|
985
964
|
const stablePath = useMemo4(() => path ?? [], [
|
|
@@ -989,10 +968,10 @@ var useFormValues = (componentName, path, defaultValue) => {
|
|
|
989
968
|
const { form: { values, onValueChange } } = useFormContext(componentName);
|
|
990
969
|
const value3 = getValue$2(values, jsonPath);
|
|
991
970
|
const lastAppliedPathRef = useRef(null);
|
|
992
|
-
|
|
971
|
+
useEffect2(() => {
|
|
993
972
|
if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
994
973
|
lastAppliedPathRef.current = jsonPath;
|
|
995
|
-
onValueChange(stablePath,
|
|
974
|
+
onValueChange(stablePath, SchemaAST4.stringKeyword, defaultValue());
|
|
996
975
|
}
|
|
997
976
|
}, [
|
|
998
977
|
value3,
|
|
@@ -1036,29 +1015,35 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
|
|
|
1036
1015
|
};
|
|
1037
1016
|
FormRoot.displayName = "Form.Root";
|
|
1038
1017
|
var FORM_VIEWPORT_NAME = "Form.Viewport";
|
|
1039
|
-
var FormViewport = ({ children,
|
|
1018
|
+
var FormViewport = composable(({ children, ...props }, forwardedRef) => {
|
|
1040
1019
|
return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
|
|
1020
|
+
...composableProps(props),
|
|
1041
1021
|
orientation: "vertical",
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
...props
|
|
1022
|
+
centered: true,
|
|
1023
|
+
padding: true,
|
|
1024
|
+
thin: true,
|
|
1025
|
+
ref: forwardedRef
|
|
1047
1026
|
}, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
|
|
1048
|
-
};
|
|
1027
|
+
});
|
|
1049
1028
|
FormViewport.displayName = FORM_VIEWPORT_NAME;
|
|
1050
1029
|
var FORM_CONTENT_NAME = "Form.Content";
|
|
1051
|
-
var FormContent = ({
|
|
1030
|
+
var FormContent = composable(({ children, ...props }, forwardedRef) => {
|
|
1052
1031
|
const { form, testId } = useFormContext(FORM_CONTENT_NAME);
|
|
1053
|
-
const
|
|
1054
|
-
|
|
1032
|
+
const localRef = useRef(null);
|
|
1033
|
+
const mergedRef = useMergeRefs([
|
|
1034
|
+
forwardedRef,
|
|
1035
|
+
localRef
|
|
1036
|
+
]);
|
|
1037
|
+
useKeyHandler(localRef, form);
|
|
1055
1038
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
|
1060
1045
|
}, children);
|
|
1061
|
-
};
|
|
1046
|
+
});
|
|
1062
1047
|
FormContent.displayName = FORM_CONTENT_NAME;
|
|
1063
1048
|
var FORM_FIELDSET_NAME2 = "Form.FieldSet";
|
|
1064
1049
|
var FormFieldSet2 = (props) => {
|
|
@@ -1072,18 +1057,17 @@ var FormFieldSet2 = (props) => {
|
|
|
1072
1057
|
FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
|
|
1073
1058
|
var FORM_ACTIONS_NAME = "Form.Actions";
|
|
1074
1059
|
var FormActions = ({ classNames }) => {
|
|
1075
|
-
const { t } = useTranslation2(
|
|
1060
|
+
const { t } = useTranslation2(translationKey2);
|
|
1076
1061
|
const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
|
|
1077
1062
|
if (readonly || layout === "static") {
|
|
1078
1063
|
return null;
|
|
1079
1064
|
}
|
|
1080
1065
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1081
|
-
|
|
1082
|
-
className: mx("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)
|
|
1083
1067
|
}, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1084
1068
|
icon: "ph--x--regular",
|
|
1085
1069
|
iconEnd: true,
|
|
1086
|
-
label: t("cancel
|
|
1070
|
+
label: t("cancel-button.label"),
|
|
1087
1071
|
onClick: onCancel,
|
|
1088
1072
|
"data-testid": "cancel-button"
|
|
1089
1073
|
}), onSave && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
@@ -1092,21 +1076,34 @@ var FormActions = ({ classNames }) => {
|
|
|
1092
1076
|
disabled: !canSave,
|
|
1093
1077
|
icon: "ph--check--regular",
|
|
1094
1078
|
iconEnd: true,
|
|
1095
|
-
label: t("save
|
|
1079
|
+
label: t("save-button.label"),
|
|
1096
1080
|
onClick: onSave,
|
|
1097
1081
|
"data-testid": "save-button"
|
|
1098
1082
|
}));
|
|
1099
1083
|
};
|
|
1100
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;
|
|
1101
1099
|
var FORM_SUBMIT_NAME = "Form.Submit";
|
|
1102
1100
|
var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
1103
|
-
const { t } = useTranslation2(
|
|
1101
|
+
const { t } = useTranslation2(translationKey2);
|
|
1104
1102
|
const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
|
|
1105
1103
|
if (readonly || layout === "static") {
|
|
1106
1104
|
return null;
|
|
1107
1105
|
}
|
|
1108
1106
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1109
|
-
role: "none",
|
|
1110
1107
|
className: mx("flex w-full pt-form-padding", classNames)
|
|
1111
1108
|
}, /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1112
1109
|
classNames: "w-full",
|
|
@@ -1114,7 +1111,7 @@ var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
|
1114
1111
|
variant: "primary",
|
|
1115
1112
|
disabled: disabled ?? !canSave,
|
|
1116
1113
|
icon: icon ?? "ph--check--regular",
|
|
1117
|
-
label: label ?? t("save
|
|
1114
|
+
label: label ?? t("save-button.label"),
|
|
1118
1115
|
onClick: onSave,
|
|
1119
1116
|
"data-testid": "save-button"
|
|
1120
1117
|
}));
|
|
@@ -1124,6 +1121,7 @@ var Form = {
|
|
|
1124
1121
|
Root: FormRoot,
|
|
1125
1122
|
Viewport: FormViewport,
|
|
1126
1123
|
Content: FormContent,
|
|
1124
|
+
Section: FormSection,
|
|
1127
1125
|
FieldSet: FormFieldSet2,
|
|
1128
1126
|
Label: FormFieldLabel,
|
|
1129
1127
|
Actions: FormActions,
|
|
@@ -1132,18 +1130,18 @@ var Form = {
|
|
|
1132
1130
|
|
|
1133
1131
|
// src/components/Form/fields/ArrayField.tsx
|
|
1134
1132
|
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1135
|
-
const { t } = useTranslation3(
|
|
1133
|
+
const { t } = useTranslation3(translationKey3);
|
|
1136
1134
|
const elementType = getArrayElementType2(type);
|
|
1137
1135
|
const { onValueChange } = inputProps;
|
|
1138
1136
|
const values = useFormValues(ArrayField.displayName, path, () => []);
|
|
1139
1137
|
const getDefaultObjectValue = (typeNode) => {
|
|
1140
1138
|
const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
|
|
1141
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode,
|
|
1139
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST5.isTypeLiteral);
|
|
1142
1140
|
if (!typeLiteral) {
|
|
1143
1141
|
return {};
|
|
1144
1142
|
}
|
|
1145
1143
|
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1146
|
-
const defaultValue =
|
|
1144
|
+
const defaultValue = SchemaAST5.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
|
|
1147
1145
|
return [
|
|
1148
1146
|
prop.name,
|
|
1149
1147
|
defaultValue
|
|
@@ -1177,13 +1175,11 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1177
1175
|
label,
|
|
1178
1176
|
asChild: true
|
|
1179
1177
|
}), /* @__PURE__ */ React5.createElement("div", {
|
|
1180
|
-
|
|
1181
|
-
className: "flex flex-col gap-2"
|
|
1178
|
+
className: "flex flex-col gap-form-gap"
|
|
1182
1179
|
}, values?.map((_, index) => {
|
|
1183
1180
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
1184
|
-
role: "none",
|
|
1185
1181
|
key: index,
|
|
1186
|
-
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"
|
|
1187
1183
|
}, /* @__PURE__ */ React5.createElement(FormField, {
|
|
1188
1184
|
autoFocus: index === values.length - 1,
|
|
1189
1185
|
type: elementType,
|
|
@@ -1195,22 +1191,20 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1195
1191
|
layout: "inline",
|
|
1196
1192
|
...props
|
|
1197
1193
|
}), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
|
|
1198
|
-
role: "none",
|
|
1199
1194
|
className: "flex flex-col h-full justify-end"
|
|
1200
1195
|
}, /* @__PURE__ */ React5.createElement("div", {
|
|
1201
|
-
role: "none",
|
|
1202
1196
|
className: "flex items-center h-[2rem]"
|
|
1203
1197
|
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1204
1198
|
icon: "ph--x--regular",
|
|
1205
1199
|
iconOnly: true,
|
|
1206
|
-
label: t("button
|
|
1200
|
+
label: t("remove.button"),
|
|
1207
1201
|
onClick: () => handleDelete(index),
|
|
1208
1202
|
classNames: "self-center"
|
|
1209
1203
|
}))));
|
|
1210
1204
|
})), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1211
1205
|
classNames: "flex w-full",
|
|
1212
1206
|
icon: "ph--plus--regular",
|
|
1213
|
-
label: t("add
|
|
1207
|
+
label: t("add-item.button"),
|
|
1214
1208
|
onClick: handleAdd
|
|
1215
1209
|
}));
|
|
1216
1210
|
};
|
|
@@ -1258,12 +1252,13 @@ var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
|
|
|
1258
1252
|
};
|
|
1259
1253
|
|
|
1260
1254
|
// src/components/Form/fields/GeoPointField.tsx
|
|
1261
|
-
import React7, { useCallback as useCallback5, useEffect as
|
|
1255
|
+
import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState2 } from "react";
|
|
1262
1256
|
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1263
1257
|
import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1264
1258
|
import { safeParseFloat } from "@dxos/util";
|
|
1259
|
+
import { translationKey as translationKey4 } from "#translations";
|
|
1265
1260
|
var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1266
|
-
const { t } = useTranslation4(
|
|
1261
|
+
const { t } = useTranslation4(translationKey4);
|
|
1267
1262
|
const { status, error } = getStatus();
|
|
1268
1263
|
const geoPoint = useMemo5(() => getValue() ?? [
|
|
1269
1264
|
0,
|
|
@@ -1276,7 +1271,7 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1276
1271
|
]);
|
|
1277
1272
|
const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
|
|
1278
1273
|
const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
|
|
1279
|
-
|
|
1274
|
+
useEffect3(() => {
|
|
1280
1275
|
const location = GeoLocation3.fromGeoPoint(geoPoint);
|
|
1281
1276
|
setLongitudeText(location.longitude?.toString());
|
|
1282
1277
|
setLatitudeText(location.latitude?.toString());
|
|
@@ -1317,25 +1312,24 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1317
1312
|
label,
|
|
1318
1313
|
asChild: true
|
|
1319
1314
|
}), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
}, /* @__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, {
|
|
1323
1317
|
type: "number",
|
|
1324
1318
|
step: "0.00001",
|
|
1325
1319
|
min: "-90",
|
|
1326
1320
|
max: "90",
|
|
1327
1321
|
disabled: !!readonly,
|
|
1328
|
-
placeholder: t("latitude
|
|
1322
|
+
placeholder: t("latitude.placeholder"),
|
|
1329
1323
|
value: latitudeText ?? "",
|
|
1330
1324
|
onChange: handleChange("latitude", setLatitudeText),
|
|
1331
1325
|
onBlur
|
|
1332
|
-
}))), /* @__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, {
|
|
1333
1327
|
type: "number",
|
|
1334
1328
|
step: "0.00001",
|
|
1335
1329
|
min: "-180",
|
|
1336
1330
|
max: "180",
|
|
1337
1331
|
disabled: !!readonly,
|
|
1338
|
-
placeholder: t("longitude
|
|
1332
|
+
placeholder: t("longitude.placeholder"),
|
|
1339
1333
|
value: longitudeText ?? "",
|
|
1340
1334
|
onChange: handleChange("longitude", setLongitudeText),
|
|
1341
1335
|
onBlur
|
|
@@ -1345,7 +1339,7 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1345
1339
|
const latHem = latitude >= 0 ? "N" : "S";
|
|
1346
1340
|
const lngHem = longitude >= 0 ? "E" : "W";
|
|
1347
1341
|
return /* @__PURE__ */ React7.createElement("span", {
|
|
1348
|
-
className: "inline-flex items-center gap-
|
|
1342
|
+
className: "inline-flex items-center gap-form-gap"
|
|
1349
1343
|
}, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
1350
1344
|
className: "text-subdued"
|
|
1351
1345
|
}, "\xB0", latHem)), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
@@ -1354,56 +1348,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1354
1348
|
};
|
|
1355
1349
|
|
|
1356
1350
|
// src/components/Form/fields/MarkdownField.tsx
|
|
1357
|
-
import
|
|
1358
|
-
import {
|
|
1359
|
-
|
|
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 }) => {
|
|
1360
1363
|
const { status, error } = getStatus();
|
|
1361
|
-
const
|
|
1362
|
-
const adjustHeight = useCallback6(() => {
|
|
1363
|
-
const textarea = textareaRef.current;
|
|
1364
|
-
if (textarea) {
|
|
1365
|
-
textarea.style.blockSize = "auto";
|
|
1366
|
-
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
1367
|
-
}
|
|
1368
|
-
}, []);
|
|
1369
|
-
useEffect5(() => {
|
|
1370
|
-
adjustHeight();
|
|
1371
|
-
}, [
|
|
1372
|
-
adjustHeight
|
|
1373
|
-
]);
|
|
1374
|
-
useEffect5(() => {
|
|
1375
|
-
adjustHeight();
|
|
1376
|
-
}, [
|
|
1377
|
-
getValue(),
|
|
1378
|
-
adjustHeight
|
|
1379
|
-
]);
|
|
1380
|
-
const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
|
|
1381
|
-
type,
|
|
1382
|
-
onValueChange
|
|
1383
|
-
]);
|
|
1364
|
+
const isRef = Ref2.isRefType(type);
|
|
1384
1365
|
const value3 = getValue();
|
|
1385
|
-
if ((readonly || layout === "static") &&
|
|
1366
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1386
1367
|
return null;
|
|
1387
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
|
+
};
|
|
1388
1405
|
return /* @__PURE__ */ React8.createElement(Input4.Root, {
|
|
1389
1406
|
validationValence: status
|
|
1390
1407
|
}, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
|
|
1391
1408
|
error,
|
|
1392
1409
|
readonly,
|
|
1393
1410
|
label
|
|
1394
|
-
}), layout === "static" ?
|
|
1395
|
-
|
|
1396
|
-
|
|
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({
|
|
1397
1440
|
placeholder,
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
})
|
|
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")));
|
|
1407
1486
|
};
|
|
1408
1487
|
|
|
1409
1488
|
// src/components/Form/fields/NumberField.tsx
|
|
@@ -1429,48 +1508,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
|
|
|
1429
1508
|
};
|
|
1430
1509
|
|
|
1431
1510
|
// src/components/Form/fields/RefField.tsx
|
|
1511
|
+
import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
|
|
1432
1512
|
import "@dxos/lit-ui/dx-tag-picker.pcss";
|
|
1433
|
-
import
|
|
1434
|
-
import {
|
|
1435
|
-
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
1436
|
-
import {
|
|
1437
|
-
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";
|
|
1438
1517
|
import { DXN } from "@dxos/keys";
|
|
1439
1518
|
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1440
|
-
import { Button, Icon as
|
|
1519
|
+
import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1441
1520
|
import { ParentLabelAnnotationId } from "@dxos/schema";
|
|
1442
|
-
import {
|
|
1521
|
+
import { translationKey as translationKey7 } from "#translations";
|
|
1443
1522
|
|
|
1444
1523
|
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1445
1524
|
import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
|
|
1446
|
-
import { Popover, useTranslation as
|
|
1447
|
-
import { Combobox
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
value: "__create__",
|
|
1453
|
-
label: t(createOptionLabel[0], {
|
|
1454
|
-
ns: createOptionLabel[1].ns,
|
|
1455
|
-
text: query
|
|
1456
|
-
}),
|
|
1457
|
-
icon: createOptionIcon,
|
|
1458
|
-
classNames: "flex items-center gap-2",
|
|
1459
|
-
closeOnSelect: false,
|
|
1460
|
-
onSelect: () => {
|
|
1461
|
-
onCreateItemSelect(query);
|
|
1462
|
-
}
|
|
1463
|
-
});
|
|
1464
|
-
};
|
|
1465
|
-
var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
|
|
1466
|
-
const { t } = useTranslation5(translationKey);
|
|
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);
|
|
1467
1531
|
const [showForm, setShowForm] = useState3(false);
|
|
1468
1532
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1469
|
-
const { results, handleSearch } = useSearchListResults({
|
|
1533
|
+
const { results, query, handleSearch } = useSearchListResults({
|
|
1470
1534
|
items: options
|
|
1471
1535
|
});
|
|
1472
|
-
const handleFormSave = useCallback8((values) => {
|
|
1473
|
-
onCreate?.(values);
|
|
1536
|
+
const handleFormSave = useCallback8(async (values) => {
|
|
1537
|
+
await onCreate?.(values);
|
|
1474
1538
|
setShowForm(false);
|
|
1475
1539
|
setFormInitialValue("");
|
|
1476
1540
|
}, [
|
|
@@ -1492,22 +1556,31 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
|
|
|
1492
1556
|
}, [
|
|
1493
1557
|
createSchema
|
|
1494
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
|
+
}
|
|
1495
1575
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1496
1576
|
...props,
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
[createInitialValuePath]: formInitialValue
|
|
1505
|
-
} : {},
|
|
1506
|
-
onSave: handleFormSave,
|
|
1507
|
-
onCancel: handleFormCancel
|
|
1508
|
-
}, /* @__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, {
|
|
1509
|
-
placeholder: t("ref field combobox input placeholder"),
|
|
1510
|
-
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
|
|
1511
1584
|
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1512
1585
|
key: option.id,
|
|
1513
1586
|
value: option.id,
|
|
@@ -1515,16 +1588,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
|
|
|
1515
1588
|
checked: selectedIds?.includes(option.id),
|
|
1516
1589
|
onSelect: () => onSelect(option.id),
|
|
1517
1590
|
classNames: "flex items-center gap-2"
|
|
1518
|
-
})),
|
|
1591
|
+
})), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
|
|
1592
|
+
query,
|
|
1519
1593
|
createOptionLabel,
|
|
1520
|
-
createOptionIcon,
|
|
1521
|
-
onCreateItemSelect: (
|
|
1522
|
-
setFormInitialValue(
|
|
1594
|
+
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
1595
|
+
onCreateItemSelect: (currentQuery) => {
|
|
1596
|
+
setFormInitialValue(currentQuery);
|
|
1523
1597
|
setShowForm(true);
|
|
1524
1598
|
}
|
|
1525
|
-
}))
|
|
1599
|
+
})), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1526
1600
|
});
|
|
1527
|
-
|
|
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";
|
|
1528
1619
|
var ObjectPicker = {
|
|
1529
1620
|
Root: Combobox.Root,
|
|
1530
1621
|
Portal: Combobox.Portal,
|
|
@@ -1539,39 +1630,41 @@ var isRefSnapshot = (val) => {
|
|
|
1539
1630
|
};
|
|
1540
1631
|
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1541
1632
|
const id = Entity.getDXN(result).toString();
|
|
1542
|
-
const parent = parentLabel ?
|
|
1633
|
+
const parent = parentLabel ? Obj2.getParent(result) : void 0;
|
|
1543
1634
|
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1544
1635
|
return {
|
|
1545
1636
|
id,
|
|
1546
1637
|
label: label ?? id
|
|
1547
1638
|
};
|
|
1548
1639
|
});
|
|
1549
|
-
var
|
|
1640
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1550
1641
|
var RefField = (props) => {
|
|
1551
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db,
|
|
1552
|
-
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);
|
|
1553
1644
|
const { status, error } = getStatus();
|
|
1554
|
-
const typename =
|
|
1645
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1555
1646
|
type
|
|
1556
1647
|
]);
|
|
1557
1648
|
const results = useResults(db, typename);
|
|
1558
|
-
const options =
|
|
1559
|
-
const parentLabel = type ?
|
|
1560
|
-
return
|
|
1649
|
+
const options = useMemo7(() => {
|
|
1650
|
+
const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
|
|
1651
|
+
return getOptions(results, {
|
|
1561
1652
|
parentLabel
|
|
1562
1653
|
});
|
|
1563
1654
|
}, [
|
|
1564
1655
|
results,
|
|
1565
|
-
|
|
1656
|
+
getOptions,
|
|
1566
1657
|
type
|
|
1567
1658
|
]);
|
|
1568
1659
|
const handleGetValue = useCallback9(() => {
|
|
1569
1660
|
const formValue = getValue();
|
|
1661
|
+
const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
|
|
1570
1662
|
const unknownToRefOption = (value3) => {
|
|
1571
|
-
const isRef =
|
|
1663
|
+
const isRef = Ref3.isRef(value3);
|
|
1572
1664
|
if (isRef || isRefSnapshot(value3)) {
|
|
1573
1665
|
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1574
|
-
const
|
|
1666
|
+
const objectId = dxnToObjectId(dxnString);
|
|
1667
|
+
const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
|
|
1575
1668
|
if (matchingOption) {
|
|
1576
1669
|
return matchingOption;
|
|
1577
1670
|
}
|
|
@@ -1583,29 +1676,37 @@ var RefField = (props) => {
|
|
|
1583
1676
|
options,
|
|
1584
1677
|
getValue
|
|
1585
1678
|
]);
|
|
1586
|
-
const handleUpdate = useCallback9((id) => {
|
|
1587
|
-
const item2 = options.find((option) => option.id === id);
|
|
1588
|
-
const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1589
|
-
onValueChange(type, ref);
|
|
1590
|
-
}, [
|
|
1591
|
-
options,
|
|
1592
|
-
type,
|
|
1593
|
-
onValueChange
|
|
1594
|
-
]);
|
|
1595
1679
|
const item = handleGetValue();
|
|
1596
|
-
const selectedIds =
|
|
1680
|
+
const selectedIds = useMemo7(() => item ? [
|
|
1597
1681
|
item.id
|
|
1598
1682
|
] : [], [
|
|
1599
1683
|
item
|
|
1600
1684
|
]);
|
|
1601
|
-
const createSchema =
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
|
|
1685
|
+
const createSchema = useSchema2(db, typename);
|
|
1686
|
+
const [open, setOpen] = useState4(false);
|
|
1687
|
+
const handleCreate = useCallback9(async (values) => {
|
|
1688
|
+
if (!createSchema || !onCreate) {
|
|
1689
|
+
return;
|
|
1605
1690
|
}
|
|
1691
|
+
const newObject = await onCreate(createSchema, values);
|
|
1692
|
+
if (newObject) {
|
|
1693
|
+
onValueChange(type, Ref3.make(newObject));
|
|
1694
|
+
}
|
|
1695
|
+
setOpen(false);
|
|
1606
1696
|
}, [
|
|
1607
1697
|
createSchema,
|
|
1608
|
-
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
|
|
1609
1710
|
]);
|
|
1610
1711
|
const handleSelect = useCallback9((id) => {
|
|
1611
1712
|
if (item?.id === id) {
|
|
@@ -1627,40 +1728,46 @@ var RefField = (props) => {
|
|
|
1627
1728
|
readonly,
|
|
1628
1729
|
label
|
|
1629
1730
|
}), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
|
|
1630
|
-
className:
|
|
1631
|
-
}, t("empty
|
|
1731
|
+
className: "text-description mb-2"
|
|
1732
|
+
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
|
|
1632
1733
|
key: item.id,
|
|
1633
1734
|
dxn: item.id,
|
|
1634
1735
|
rootclassname: "me-1"
|
|
1635
|
-
}, 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, {
|
|
1636
1740
|
asChild: true,
|
|
1637
1741
|
classNames: "p-0"
|
|
1638
1742
|
}, item ? /* @__PURE__ */ React11.createElement("div", {
|
|
1639
|
-
className: "flex gap-
|
|
1743
|
+
className: "flex gap-form-gap w-full"
|
|
1640
1744
|
}, /* @__PURE__ */ React11.createElement(Input6.Root, {
|
|
1641
1745
|
key: item.id
|
|
1642
1746
|
}, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
|
|
1643
1747
|
value: item.label,
|
|
1644
1748
|
readOnly: true,
|
|
1645
1749
|
classNames: "w-full"
|
|
1646
|
-
}))) : /* @__PURE__ */ React11.createElement(
|
|
1647
|
-
classNames: "w-full text-start gap-
|
|
1750
|
+
}))) : /* @__PURE__ */ React11.createElement(Button2, {
|
|
1751
|
+
classNames: "w-full text-start gap-form-gap"
|
|
1648
1752
|
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1649
|
-
role: "none",
|
|
1650
1753
|
className: "grow overflow-hidden"
|
|
1651
1754
|
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1652
|
-
className: "
|
|
1653
|
-
}, placeholder ?? t("ref
|
|
1755
|
+
className: "truncate text-description"
|
|
1756
|
+
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
|
|
1654
1757
|
size: 3,
|
|
1655
1758
|
icon: "ph--caret-down--bold"
|
|
1656
1759
|
}))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
|
|
1657
1760
|
classNames: "dx-card-popover-width",
|
|
1658
1761
|
options,
|
|
1659
1762
|
selectedIds,
|
|
1660
|
-
|
|
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)),
|
|
1661
1767
|
createOptionLabel,
|
|
1662
1768
|
createOptionIcon,
|
|
1663
1769
|
createInitialValuePath,
|
|
1770
|
+
createFieldMap: createFieldMap3,
|
|
1664
1771
|
onCreate: handleCreate,
|
|
1665
1772
|
onSelect: handleSelect
|
|
1666
1773
|
})))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
|
|
@@ -1702,20 +1809,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1702
1809
|
};
|
|
1703
1810
|
|
|
1704
1811
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1705
|
-
import React13, { useCallback as useCallback11, useEffect as
|
|
1812
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1706
1813
|
import { PublicKey } from "@dxos/keys";
|
|
1707
|
-
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";
|
|
1708
1815
|
import { List } from "@dxos/react-ui-list";
|
|
1709
1816
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1710
|
-
import { hues, osTranslations
|
|
1817
|
+
import { hues, osTranslations } from "@dxos/ui-theme";
|
|
1818
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1711
1819
|
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
1712
|
-
const { t } =
|
|
1820
|
+
const { t } = useTranslation8(translationKey8);
|
|
1713
1821
|
const { status, error } = getStatus();
|
|
1714
|
-
const [selected, setSelectedId] =
|
|
1715
|
-
const [isNewOption, setIsNewOption] =
|
|
1716
|
-
const inputRef =
|
|
1822
|
+
const [selected, setSelectedId] = useState5(null);
|
|
1823
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
1824
|
+
const inputRef = useRef2(null);
|
|
1717
1825
|
const options = getValue();
|
|
1718
|
-
|
|
1826
|
+
useEffect4(() => {
|
|
1719
1827
|
if (options === void 0) {
|
|
1720
1828
|
onValueChange(type, []);
|
|
1721
1829
|
}
|
|
@@ -1806,7 +1914,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1806
1914
|
type,
|
|
1807
1915
|
onValueChange
|
|
1808
1916
|
]);
|
|
1809
|
-
|
|
1917
|
+
useEffect4(() => {
|
|
1810
1918
|
if (selected && isNewOption && inputRef.current) {
|
|
1811
1919
|
inputRef.current.focus();
|
|
1812
1920
|
setIsNewOption(false);
|
|
@@ -1821,9 +1929,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1821
1929
|
error,
|
|
1822
1930
|
readonly,
|
|
1823
1931
|
label
|
|
1824
|
-
}), /* @__PURE__ */ React13.createElement("div", {
|
|
1825
|
-
role: "none"
|
|
1826
|
-
}, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1932
|
+
}), /* @__PURE__ */ React13.createElement("div", null, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1827
1933
|
items: options,
|
|
1828
1934
|
isItem: (_item) => true,
|
|
1829
1935
|
onMove: readonly ? void 0 : handleMove,
|
|
@@ -1836,10 +1942,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1836
1942
|
}, /* @__PURE__ */ React13.createElement(List.Item, {
|
|
1837
1943
|
role: "button",
|
|
1838
1944
|
item,
|
|
1839
|
-
classNames:
|
|
1840
|
-
subtleHover,
|
|
1841
|
-
"flex flex-col cursor-pointer rounded-xs"
|
|
1842
|
-
],
|
|
1945
|
+
classNames: "flex flex-col cursor-pointer rounded-xs dx-hover",
|
|
1843
1946
|
"aria-expanded": selected === item.id
|
|
1844
1947
|
}, /* @__PURE__ */ React13.createElement("div", {
|
|
1845
1948
|
className: "flex items-center"
|
|
@@ -1853,20 +1956,20 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1853
1956
|
}, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1854
1957
|
iconOnly: true,
|
|
1855
1958
|
variant: "ghost",
|
|
1856
|
-
label: t(selected === item.id ? "collapse
|
|
1959
|
+
label: t(selected === item.id ? "collapse.label" : "expand.label", {
|
|
1857
1960
|
ns: osTranslations
|
|
1858
1961
|
}),
|
|
1859
1962
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
1860
1963
|
onClick: () => handleClick(item.id)
|
|
1861
1964
|
})), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
|
|
1862
|
-
className: "flex flex-col p-form-padding gap-
|
|
1965
|
+
className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
|
|
1863
1966
|
}, /* @__PURE__ */ React13.createElement(Input8.Label, {
|
|
1864
1967
|
classNames: "text-xs"
|
|
1865
|
-
}, t("select
|
|
1866
|
-
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"
|
|
1867
1970
|
}, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
|
|
1868
1971
|
disabled: !!readonly,
|
|
1869
|
-
placeholder: t("select
|
|
1972
|
+
placeholder: t("select-option-label.placeholder"),
|
|
1870
1973
|
ref: selected === item.id ? inputRef : void 0,
|
|
1871
1974
|
value: item.title,
|
|
1872
1975
|
onChange: handleTitleChange(item.id),
|
|
@@ -1880,12 +1983,12 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1880
1983
|
disabled: !!readonly,
|
|
1881
1984
|
icon: "ph--trash--fill",
|
|
1882
1985
|
iconOnly: true,
|
|
1883
|
-
label: t("select
|
|
1986
|
+
label: t("select-option-delete.button"),
|
|
1884
1987
|
onClick: () => handleDelete(item.id)
|
|
1885
1988
|
})))))), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1886
1989
|
variant: "ghost",
|
|
1887
1990
|
icon: "ph--plus--regular",
|
|
1888
|
-
label: t("select
|
|
1991
|
+
label: t("select-option-add.button"),
|
|
1889
1992
|
onClick: handleAdd,
|
|
1890
1993
|
disabled: !!readonly,
|
|
1891
1994
|
classNames: "w-full"
|
|
@@ -1895,7 +1998,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1895
1998
|
// src/components/Form/fields/TextField.tsx
|
|
1896
1999
|
import React14, { useCallback as useCallback12 } from "react";
|
|
1897
2000
|
import { Input as Input9 } from "@dxos/react-ui";
|
|
1898
|
-
var TextField = ({ type, readonly, placeholder,
|
|
2001
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
1899
2002
|
const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
|
|
1900
2003
|
type,
|
|
1901
2004
|
onValueChange
|
|
@@ -1908,8 +2011,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
|
|
|
1908
2011
|
disabled: !!readonly,
|
|
1909
2012
|
placeholder,
|
|
1910
2013
|
value: value3,
|
|
1911
|
-
|
|
1912
|
-
|
|
2014
|
+
onBlur,
|
|
2015
|
+
onChange: handleChange
|
|
1913
2016
|
}));
|
|
1914
2017
|
};
|
|
1915
2018
|
|
|
@@ -1937,7 +2040,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1937
2040
|
// src/components/Form/fields/TupleField.tsx
|
|
1938
2041
|
import React16 from "react";
|
|
1939
2042
|
import { Input as Input11 } from "@dxos/react-ui";
|
|
1940
|
-
import { mx as
|
|
2043
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1941
2044
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1942
2045
|
var gridCols = [
|
|
1943
2046
|
"grid-cols-1",
|
|
@@ -1955,7 +2058,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1955
2058
|
readonly,
|
|
1956
2059
|
label
|
|
1957
2060
|
}), /* @__PURE__ */ React16.createElement("div", {
|
|
1958
|
-
className:
|
|
2061
|
+
className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
|
|
1959
2062
|
}, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
|
|
1960
2063
|
key: prop,
|
|
1961
2064
|
type: "number",
|
|
@@ -1974,13 +2077,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1974
2077
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1975
2078
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1976
2079
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
1977
|
-
const { t } =
|
|
1978
|
-
const [props, setProps] =
|
|
1979
|
-
|
|
2080
|
+
const { t } = useTranslation9(translationKey9);
|
|
2081
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2082
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1980
2083
|
field,
|
|
1981
2084
|
projection
|
|
1982
2085
|
]);
|
|
1983
|
-
const [schemas, setSchemas] =
|
|
2086
|
+
const [schemas, setSchemas] = useState6([]);
|
|
1984
2087
|
useAsyncEffect(async () => {
|
|
1985
2088
|
if (!registry) {
|
|
1986
2089
|
return;
|
|
@@ -1994,22 +2097,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
1994
2097
|
}, [
|
|
1995
2098
|
registry
|
|
1996
2099
|
]);
|
|
1997
|
-
const [referenceSchema, setReferenceSchema] =
|
|
1998
|
-
|
|
2100
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2101
|
+
useEffect5(() => {
|
|
1999
2102
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
2000
2103
|
}, [
|
|
2001
2104
|
schemas,
|
|
2002
2105
|
props?.referenceSchema
|
|
2003
2106
|
]);
|
|
2004
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2107
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
2005
2108
|
fieldSchema: getFormatSchema(props?.format)
|
|
2006
2109
|
});
|
|
2007
|
-
const fieldMap =
|
|
2110
|
+
const fieldMap = useMemo8(() => ({
|
|
2008
2111
|
["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
2009
2112
|
...props2,
|
|
2010
2113
|
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
2011
2114
|
value: value3,
|
|
2012
|
-
label: t(`format
|
|
2115
|
+
label: t(`format.${value3}.label`)
|
|
2013
2116
|
}))
|
|
2014
2117
|
}),
|
|
2015
2118
|
["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
@@ -2083,7 +2186,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2083
2186
|
]);
|
|
2084
2187
|
const handleSave = useCallback14((props2) => {
|
|
2085
2188
|
if (view) {
|
|
2086
|
-
|
|
2189
|
+
Obj3.update(view, () => {
|
|
2087
2190
|
projection.setFieldProjection({
|
|
2088
2191
|
field,
|
|
2089
2192
|
props: props2
|
|
@@ -2111,12 +2214,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2111
2214
|
if (!fieldSchema) {
|
|
2112
2215
|
log2.warn("invalid format", {
|
|
2113
2216
|
props
|
|
2114
|
-
}, {
|
|
2115
|
-
F: __dxlog_file2,
|
|
2116
|
-
L: 172,
|
|
2117
|
-
S: void 0,
|
|
2118
|
-
C: (f, a) => f(...a)
|
|
2119
|
-
});
|
|
2217
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2120
2218
|
return null;
|
|
2121
2219
|
}
|
|
2122
2220
|
return /* @__PURE__ */ React17.createElement(Form.Root, {
|
|
@@ -2138,161 +2236,491 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2138
2236
|
}, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
|
|
2139
2237
|
};
|
|
2140
2238
|
|
|
2141
|
-
// src/components/
|
|
2142
|
-
import
|
|
2143
|
-
import
|
|
2144
|
-
import {
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
var
|
|
2151
|
-
var
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
}
|
|
2169
|
-
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
2170
|
-
var SettingsSection = ({ title, description, children }) => {
|
|
2171
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SettingsSectionHeading, {
|
|
2172
|
-
title,
|
|
2173
|
-
description
|
|
2174
|
-
}), /* @__PURE__ */ React18.createElement("div", {
|
|
2175
|
-
className: "w-full pt-trim-md space-y-trim-md"
|
|
2176
|
-
}, children));
|
|
2177
|
-
};
|
|
2178
|
-
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2179
|
-
var SettingsSectionHeading = ({ title, description }) => {
|
|
2180
|
-
const { t } = useTranslation9(translationKey);
|
|
2181
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
|
|
2182
|
-
className: "px-trim-md mt-trim-md mb-trim-md text-xl"
|
|
2183
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
|
|
2184
|
-
className: "px-trim-md my-trim-md text-description"
|
|
2185
|
-
}, 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
|
+
}
|
|
2186
2267
|
};
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
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))));
|
|
2196
2338
|
};
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
}
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
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
|
+
}
|
|
2218
2449
|
};
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
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)
|
|
2229
2477
|
}, children);
|
|
2230
2478
|
};
|
|
2231
|
-
|
|
2479
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2232
2480
|
var SettingsItem = ({ title, description = "", children }) => {
|
|
2233
|
-
const { t } =
|
|
2234
|
-
return /* @__PURE__ */
|
|
2235
|
-
classNames:
|
|
2236
|
-
}, /* @__PURE__ */
|
|
2237
|
-
|
|
2238
|
-
}, toLocalizedString(title, t)), /* @__PURE__ */
|
|
2239
|
-
|
|
2240
|
-
}, toLocalizedString(description, t)), /* @__PURE__ */
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
}, 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)));
|
|
2244
2491
|
};
|
|
2245
2492
|
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
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"
|
|
2257
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));
|
|
2258
2666
|
};
|
|
2259
|
-
|
|
2667
|
+
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2260
2668
|
var Settings = {
|
|
2261
2669
|
Root: SettingsRoot,
|
|
2670
|
+
Viewport: SettingsViewport,
|
|
2262
2671
|
Section: SettingsSection,
|
|
2263
|
-
|
|
2264
|
-
Group: SettingsGroup,
|
|
2265
|
-
GroupButton: SettingsGroupButton,
|
|
2266
|
-
Container: SettingsContainer,
|
|
2267
|
-
Frame: SettingsFrame,
|
|
2268
|
-
FrameItem: SettingsFrameItem,
|
|
2672
|
+
Panel: SettingsPanel,
|
|
2269
2673
|
Item: SettingsItem,
|
|
2270
|
-
|
|
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))));
|
|
2271
2699
|
};
|
|
2272
2700
|
|
|
2273
2701
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2274
2702
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2275
|
-
import * as
|
|
2703
|
+
import * as Array4 from "effect/Array";
|
|
2276
2704
|
import * as Match2 from "effect/Match";
|
|
2277
|
-
import * as
|
|
2278
|
-
import * as
|
|
2279
|
-
import
|
|
2280
|
-
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as
|
|
2281
|
-
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";
|
|
2282
2709
|
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2283
|
-
import { invariant } from "@dxos/invariant";
|
|
2710
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2284
2711
|
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2285
|
-
import { IconButton as IconButton4, Input as
|
|
2712
|
+
import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
2286
2713
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2287
2714
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2288
2715
|
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2289
|
-
import { mx as mx5, osTranslations as osTranslations2
|
|
2290
|
-
|
|
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";
|
|
2291
2719
|
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2292
2720
|
const atomRegistry = useContext(RegistryContext);
|
|
2293
2721
|
const schemaReadonly = !isMutable(schema);
|
|
2294
|
-
const { t } =
|
|
2295
|
-
const projectionModel =
|
|
2722
|
+
const { t } = useTranslation12(translationKey14);
|
|
2723
|
+
const projectionModel = useMemo12(() => {
|
|
2296
2724
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2297
2725
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2298
2726
|
const model = new ProjectionModel({
|
|
@@ -2316,21 +2744,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2316
2744
|
if (from._tag !== "scope") {
|
|
2317
2745
|
return void 0;
|
|
2318
2746
|
}
|
|
2319
|
-
return
|
|
2747
|
+
return Option6.fromNullable(from.scope.feeds).pipe(Option6.flatMap((feeds2) => Array4.head(feeds2)), Option6.map(String), Option6.getOrUndefined);
|
|
2320
2748
|
}), Match2.orElse(() => void 0));
|
|
2321
2749
|
const feeds = useQuery2(db, Filter2.type(Feed.Feed));
|
|
2322
|
-
const targetRef =
|
|
2750
|
+
const targetRef = useMemo12(() => {
|
|
2323
2751
|
if (!queueTarget) {
|
|
2324
2752
|
return void 0;
|
|
2325
2753
|
}
|
|
2326
2754
|
const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
|
|
2327
|
-
return feed ?
|
|
2755
|
+
return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
|
|
2328
2756
|
}, [
|
|
2329
2757
|
queueTarget,
|
|
2330
2758
|
feeds
|
|
2331
2759
|
]);
|
|
2332
|
-
const viewSchema =
|
|
2333
|
-
const base =
|
|
2760
|
+
const viewSchema = useMemo12(() => {
|
|
2761
|
+
const base = Schema5.Struct({
|
|
2334
2762
|
query: mode === "schema" ? Format5.URL.annotations({
|
|
2335
2763
|
title: "Record type"
|
|
2336
2764
|
}) : QueryAST.Query.annotations({
|
|
@@ -2338,19 +2766,19 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2338
2766
|
})
|
|
2339
2767
|
});
|
|
2340
2768
|
if (mode === "tag") {
|
|
2341
|
-
return
|
|
2769
|
+
return Schema5.Struct({
|
|
2342
2770
|
...base.fields,
|
|
2343
2771
|
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2344
|
-
target:
|
|
2772
|
+
target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2345
2773
|
title: "Target Feed"
|
|
2346
|
-
}), ParentLabelAnnotation.set(true),
|
|
2347
|
-
}).pipe(
|
|
2774
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
2775
|
+
}).pipe(Schema5.mutable);
|
|
2348
2776
|
}
|
|
2349
|
-
return base.pipe(
|
|
2777
|
+
return base.pipe(Schema5.mutable);
|
|
2350
2778
|
}, [
|
|
2351
2779
|
mode
|
|
2352
2780
|
]);
|
|
2353
|
-
const viewValues =
|
|
2781
|
+
const viewValues = useMemo12(() => ({
|
|
2354
2782
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2355
2783
|
target: targetRef
|
|
2356
2784
|
}), [
|
|
@@ -2358,7 +2786,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2358
2786
|
view.query.ast,
|
|
2359
2787
|
targetRef
|
|
2360
2788
|
]);
|
|
2361
|
-
const fieldMap =
|
|
2789
|
+
const fieldMap = useMemo12(() => mode === "tag" ? customFields({
|
|
2362
2790
|
types,
|
|
2363
2791
|
tags
|
|
2364
2792
|
}) : void 0, [
|
|
@@ -2366,54 +2794,45 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2366
2794
|
types,
|
|
2367
2795
|
tags
|
|
2368
2796
|
]);
|
|
2369
|
-
const handleUpdate =
|
|
2797
|
+
const handleUpdate = useCallback18((values) => {
|
|
2370
2798
|
const targetValue = values.target;
|
|
2371
|
-
let
|
|
2372
|
-
if (
|
|
2373
|
-
const
|
|
2374
|
-
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);
|
|
2375
2803
|
if (feed) {
|
|
2376
|
-
|
|
2804
|
+
feedDXN = Feed.getQueueDxn(feed)?.toString();
|
|
2377
2805
|
}
|
|
2378
2806
|
}
|
|
2379
2807
|
const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
|
|
2380
|
-
onQueryChanged?.(query,
|
|
2808
|
+
onQueryChanged?.(query, feedDXN);
|
|
2381
2809
|
}, [
|
|
2382
2810
|
onQueryChanged,
|
|
2383
2811
|
mode,
|
|
2384
2812
|
feeds
|
|
2385
2813
|
]);
|
|
2386
|
-
const handleDelete =
|
|
2387
|
-
|
|
2388
|
-
F: __dxlog_file3,
|
|
2389
|
-
L: 185,
|
|
2390
|
-
S: void 0,
|
|
2391
|
-
A: [
|
|
2392
|
-
"!readonly",
|
|
2393
|
-
""
|
|
2394
|
-
]
|
|
2395
|
-
});
|
|
2814
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2815
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 126, S: void 0, A: ["!readonly", ""] });
|
|
2396
2816
|
onDelete?.(fieldId);
|
|
2397
2817
|
}, [
|
|
2398
2818
|
onDelete,
|
|
2399
2819
|
readonly
|
|
2400
2820
|
]);
|
|
2401
|
-
return /* @__PURE__ */
|
|
2402
|
-
role: "none",
|
|
2821
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
2403
2822
|
className: mx5(classNames)
|
|
2404
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */
|
|
2823
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
|
|
2405
2824
|
valence: "info",
|
|
2406
2825
|
classNames: "my-form-padding"
|
|
2407
|
-
}, /* @__PURE__ */
|
|
2826
|
+
}, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
|
|
2408
2827
|
schema: viewSchema,
|
|
2409
2828
|
values: viewValues,
|
|
2410
2829
|
fieldMap,
|
|
2411
2830
|
db,
|
|
2412
2831
|
onValuesChanged: handleUpdate
|
|
2413
|
-
}, /* @__PURE__ */
|
|
2414
|
-
label: t("fields
|
|
2832
|
+
}, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2833
|
+
label: t("fields.label"),
|
|
2415
2834
|
asChild: true
|
|
2416
|
-
}), /* @__PURE__ */
|
|
2835
|
+
}), /* @__PURE__ */ React24.createElement(FieldList, {
|
|
2417
2836
|
schema,
|
|
2418
2837
|
view,
|
|
2419
2838
|
registry,
|
|
@@ -2425,9 +2844,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2425
2844
|
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2426
2845
|
const atomRegistry = useContext(RegistryContext);
|
|
2427
2846
|
const schemaReadonly = !isMutable(schema);
|
|
2428
|
-
const { t } =
|
|
2847
|
+
const { t } = useTranslation12(translationKey14);
|
|
2429
2848
|
const [viewSnapshot] = useObject(view);
|
|
2430
|
-
const projectionModel =
|
|
2849
|
+
const projectionModel = useMemo12(() => {
|
|
2431
2850
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2432
2851
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2433
2852
|
const model = new ProjectionModel({
|
|
@@ -2442,38 +2861,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2442
2861
|
schema,
|
|
2443
2862
|
view
|
|
2444
2863
|
]);
|
|
2445
|
-
const [expandedField, setExpandedField] =
|
|
2446
|
-
const handleAdd =
|
|
2447
|
-
|
|
2448
|
-
F: __dxlog_file3,
|
|
2449
|
-
L: 250,
|
|
2450
|
-
S: void 0,
|
|
2451
|
-
A: [
|
|
2452
|
-
"!readonly",
|
|
2453
|
-
""
|
|
2454
|
-
]
|
|
2455
|
-
});
|
|
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", ""] });
|
|
2456
2867
|
const field = projectionModel.createFieldProjection();
|
|
2457
2868
|
setExpandedField(field.id);
|
|
2458
2869
|
}, [
|
|
2459
2870
|
projectionModel,
|
|
2460
2871
|
readonly
|
|
2461
2872
|
]);
|
|
2462
|
-
const handleToggleField =
|
|
2873
|
+
const handleToggleField = useCallback18((field) => {
|
|
2463
2874
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2464
2875
|
}, [
|
|
2465
2876
|
readonly
|
|
2466
2877
|
]);
|
|
2467
|
-
const handleDelete =
|
|
2468
|
-
|
|
2469
|
-
F: __dxlog_file3,
|
|
2470
|
-
L: 264,
|
|
2471
|
-
S: void 0,
|
|
2472
|
-
A: [
|
|
2473
|
-
"!readonly",
|
|
2474
|
-
""
|
|
2475
|
-
]
|
|
2476
|
-
});
|
|
2878
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2879
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 194, S: void 0, A: ["!readonly", ""] });
|
|
2477
2880
|
if (fieldId === expandedField) {
|
|
2478
2881
|
setExpandedField(void 0);
|
|
2479
2882
|
}
|
|
@@ -2483,36 +2886,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2483
2886
|
onDelete,
|
|
2484
2887
|
readonly
|
|
2485
2888
|
]);
|
|
2486
|
-
const handleMove =
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
L: 276,
|
|
2490
|
-
S: void 0,
|
|
2491
|
-
A: [
|
|
2492
|
-
"!readonly",
|
|
2493
|
-
""
|
|
2494
|
-
]
|
|
2495
|
-
});
|
|
2496
|
-
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) => {
|
|
2497
2892
|
const fields = [
|
|
2498
|
-
...
|
|
2893
|
+
...view2.projection.fields
|
|
2499
2894
|
];
|
|
2500
2895
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2501
2896
|
fields.splice(toIndex, 0, moved);
|
|
2502
|
-
|
|
2897
|
+
view2.projection.fields = fields;
|
|
2503
2898
|
});
|
|
2504
2899
|
}, [
|
|
2505
2900
|
view,
|
|
2506
2901
|
readonly
|
|
2507
2902
|
]);
|
|
2508
|
-
const handleClose =
|
|
2509
|
-
const handleHide =
|
|
2903
|
+
const handleClose = useCallback18(() => setExpandedField(void 0), []);
|
|
2904
|
+
const handleHide = useCallback18((fieldId) => {
|
|
2510
2905
|
setExpandedField(void 0);
|
|
2511
2906
|
projectionModel.hideFieldProjection(fieldId);
|
|
2512
2907
|
}, [
|
|
2513
2908
|
projectionModel
|
|
2514
2909
|
]);
|
|
2515
|
-
const handleShow =
|
|
2910
|
+
const handleShow = useCallback18((property) => {
|
|
2516
2911
|
setExpandedField(void 0);
|
|
2517
2912
|
projectionModel.showFieldProjection(property);
|
|
2518
2913
|
}, [
|
|
@@ -2521,70 +2916,67 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2521
2916
|
if (!viewSnapshot) {
|
|
2522
2917
|
return null;
|
|
2523
2918
|
}
|
|
2524
|
-
return /* @__PURE__ */
|
|
2919
|
+
return /* @__PURE__ */ React24.createElement(List2.Root, {
|
|
2525
2920
|
items: viewSnapshot.projection.fields,
|
|
2526
|
-
isItem:
|
|
2921
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2527
2922
|
getId: (field) => field.id,
|
|
2528
2923
|
onMove: readonly ? void 0 : handleMove,
|
|
2529
2924
|
readonly
|
|
2530
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2925
|
+
}, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
|
|
2531
2926
|
className: "text-sm"
|
|
2532
|
-
}, t("field
|
|
2927
|
+
}, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
|
|
2533
2928
|
role: "list",
|
|
2534
2929
|
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2535
2930
|
}, fields?.map((field) => {
|
|
2536
2931
|
const hidden = field.visible === false;
|
|
2537
|
-
return /* @__PURE__ */
|
|
2932
|
+
return /* @__PURE__ */ React24.createElement(List2.Item, {
|
|
2538
2933
|
key: field.id,
|
|
2539
2934
|
item: field,
|
|
2540
2935
|
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2541
2936
|
"aria-expanded": expandedField === field.id
|
|
2542
|
-
}, /* @__PURE__ */
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
}, /* @__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, {
|
|
2546
2940
|
disabled: readonly || schemaReadonly
|
|
2547
|
-
}), /* @__PURE__ */
|
|
2941
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
|
|
2548
2942
|
classNames: hidden && "text-subdued",
|
|
2549
2943
|
onClick: () => handleToggleField(field)
|
|
2550
|
-
}, field.path), /* @__PURE__ */
|
|
2551
|
-
label: t(hidden ? "show
|
|
2944
|
+
}, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2945
|
+
label: t(hidden ? "show-field.label" : "hide-field.label"),
|
|
2552
2946
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2553
2947
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2554
2948
|
autoHide: false,
|
|
2555
2949
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2556
2950
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2557
|
-
}), !readonly && /* @__PURE__ */
|
|
2558
|
-
label: t("delete
|
|
2951
|
+
}), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
|
|
2952
|
+
label: t("delete-field.label"),
|
|
2559
2953
|
autoHide: false,
|
|
2560
2954
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2561
2955
|
onClick: () => handleDelete(field.id),
|
|
2562
2956
|
"data-testid": "field.delete"
|
|
2563
|
-
}), /* @__PURE__ */
|
|
2957
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2564
2958
|
iconOnly: true,
|
|
2565
2959
|
variant: "ghost",
|
|
2566
|
-
label: t("toggle
|
|
2960
|
+
label: t("toggle-expand.label", {
|
|
2567
2961
|
ns: osTranslations2
|
|
2568
2962
|
}),
|
|
2569
2963
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2570
2964
|
onClick: () => handleToggleField(field),
|
|
2571
2965
|
"data-testid": "field.toggle"
|
|
2572
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
}, /* @__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, {
|
|
2576
2969
|
readonly: readonly || schemaReadonly,
|
|
2577
2970
|
registry,
|
|
2578
2971
|
projection: projectionModel,
|
|
2579
2972
|
field,
|
|
2580
2973
|
onSave: handleClose
|
|
2581
2974
|
})));
|
|
2582
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2583
|
-
role: "none",
|
|
2975
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
|
|
2584
2976
|
className: "my-form-padding"
|
|
2585
|
-
}, /* @__PURE__ */
|
|
2977
|
+
}, /* @__PURE__ */ React24.createElement(IconButton4, {
|
|
2586
2978
|
icon: "ph--plus--regular",
|
|
2587
|
-
label: t("add
|
|
2979
|
+
label: t("add-property-button.label"),
|
|
2588
2980
|
onClick: handleAdd,
|
|
2589
2981
|
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2590
2982
|
classNames: "w-full"
|
|
@@ -2592,13 +2984,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2592
2984
|
};
|
|
2593
2985
|
var customFields = ({ types, tags }) => ({
|
|
2594
2986
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2595
|
-
const handleChange =
|
|
2987
|
+
const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
|
|
2596
2988
|
onValueChange
|
|
2597
2989
|
]);
|
|
2598
|
-
return /* @__PURE__ */
|
|
2990
|
+
return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2599
2991
|
readonly,
|
|
2600
2992
|
label
|
|
2601
|
-
}), /* @__PURE__ */
|
|
2993
|
+
}), /* @__PURE__ */ React24.createElement(QueryForm, {
|
|
2602
2994
|
initialQuery: getValue(),
|
|
2603
2995
|
types,
|
|
2604
2996
|
tags,
|
|
@@ -2617,7 +3009,9 @@ export {
|
|
|
2617
3009
|
GeoPointField,
|
|
2618
3010
|
MarkdownField,
|
|
2619
3011
|
NumberField,
|
|
3012
|
+
ObjectForm,
|
|
2620
3013
|
ObjectPicker,
|
|
3014
|
+
ObjectProperties,
|
|
2621
3015
|
RefField,
|
|
2622
3016
|
SelectField,
|
|
2623
3017
|
SelectOptionField,
|
|
@@ -2627,15 +3021,18 @@ export {
|
|
|
2627
3021
|
TupleField,
|
|
2628
3022
|
ViewEditor,
|
|
2629
3023
|
cellClassesForFieldType,
|
|
3024
|
+
createSelectField,
|
|
3025
|
+
detectFieldType,
|
|
2630
3026
|
formatForDisplay,
|
|
2631
3027
|
formatForEditing,
|
|
2632
3028
|
getDefaultValue,
|
|
2633
3029
|
getFormProperties,
|
|
2634
3030
|
getRefProps,
|
|
3031
|
+
getSelectOptionsFromAst,
|
|
3032
|
+
omitHiddenFormFields,
|
|
2635
3033
|
omitId,
|
|
2636
3034
|
parseValue,
|
|
2637
3035
|
pathNotUniqueError,
|
|
2638
|
-
translations,
|
|
2639
3036
|
useFormContext,
|
|
2640
3037
|
useFormFieldState,
|
|
2641
3038
|
useFormHandler,
|