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