@dxos/react-ui-form 0.8.2-main.12df754 → 0.8.2-main.30e4dbb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +823 -524
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +661 -372
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +823 -524
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +6 -4
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +37 -34
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +14 -11
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +2 -2
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/RefField.d.ts +12 -0
- package/dist/types/src/components/Form/RefField.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.d.ts +2 -2
- package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +2 -2
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +23 -0
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -0
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +8 -0
- package/dist/types/src/hooks/useRefQueryLookupHandler.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 +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +9 -0
- package/dist/types/src/util/refs.d.ts.map +1 -0
- package/dist/types/src/util/schema.d.ts +3 -0
- package/dist/types/src/util/schema.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -25
- package/src/components/ControlSection/ControlSection.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/Form/ArrayField.tsx +8 -7
- package/src/components/Form/Defaults.tsx +4 -1
- package/src/components/Form/Form.stories.tsx +92 -43
- package/src/components/Form/Form.tsx +7 -3
- package/src/components/Form/FormContent.tsx +90 -19
- package/src/components/Form/FormContext.tsx +13 -3
- package/src/components/Form/Input.tsx +3 -9
- package/src/components/Form/RefField.tsx +197 -0
- package/src/components/Form/custom/GeoPointInput.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +6 -5
- package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/Form/index.ts +0 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -3
- package/src/components/ViewEditor/ViewEditor.tsx +12 -10
- package/src/components/deprecated/Form.tsx +6 -6
- package/src/hooks/index.ts +3 -1
- package/src/hooks/useForm.ts +3 -3
- package/src/hooks/useQueryRefOptions.ts +53 -0
- package/src/hooks/useRefQueryLookupHandler.ts +41 -0
- package/src/util/formatting.ts +15 -3
- package/src/util/index.ts +3 -1
- package/src/util/refs.ts +38 -0
- package/src/util/schema.ts +14 -0
|
@@ -181,9 +181,9 @@ var ControlFrameItem = ({ title, description, children }) => {
|
|
|
181
181
|
};
|
|
182
182
|
|
|
183
183
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
184
|
-
import
|
|
185
|
-
import { FormatEnum as
|
|
186
|
-
import { log as
|
|
184
|
+
import React14, { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo8, useState as useState5 } from "react";
|
|
185
|
+
import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
186
|
+
import { log as log3 } from "@dxos/log";
|
|
187
187
|
import { useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
188
188
|
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
189
189
|
|
|
@@ -201,15 +201,15 @@ var InputHeader = ({ children, error }) => {
|
|
|
201
201
|
return /* @__PURE__ */ React3.createElement("div", {
|
|
202
202
|
role: "none",
|
|
203
203
|
className: "flex justify-between items-center mb-1"
|
|
204
|
-
}, children, error && /* @__PURE__ */ React3.createElement(Tooltip.
|
|
205
|
-
asChild: true
|
|
204
|
+
}, children, error && /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
205
|
+
asChild: true,
|
|
206
|
+
content: error,
|
|
207
|
+
side: "bottom"
|
|
206
208
|
}, /* @__PURE__ */ React3.createElement(Icon, {
|
|
207
209
|
icon: "ph--warning--regular",
|
|
208
210
|
size: 4,
|
|
209
211
|
classNames: errorText
|
|
210
|
-
}))
|
|
211
|
-
side: "bottom"
|
|
212
|
-
}, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null), error)));
|
|
212
|
+
})));
|
|
213
213
|
};
|
|
214
214
|
|
|
215
215
|
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
@@ -546,23 +546,28 @@ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, on
|
|
|
546
546
|
};
|
|
547
547
|
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
548
548
|
const { status, error } = getStatus();
|
|
549
|
+
const value = getValue3();
|
|
550
|
+
const handleValueChange = useCallback3((value2) => onValueChange(type, value2), [
|
|
551
|
+
type,
|
|
552
|
+
onValueChange
|
|
553
|
+
]);
|
|
549
554
|
return /* @__PURE__ */ React7.createElement(Input6.Root, {
|
|
550
555
|
validationValence: status
|
|
551
556
|
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
552
557
|
error
|
|
553
558
|
}, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Select.Root, {
|
|
554
|
-
value
|
|
555
|
-
onValueChange:
|
|
559
|
+
value,
|
|
560
|
+
onValueChange: handleValueChange
|
|
556
561
|
}, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
|
|
557
562
|
classNames: "is-full",
|
|
558
563
|
disabled,
|
|
559
564
|
placeholder
|
|
560
|
-
}), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
565
|
+
}), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value: value2, label: label2 }) => (
|
|
561
566
|
// NOTE: Numeric values are converted to and from strings.
|
|
562
567
|
/* @__PURE__ */ React7.createElement(Select.Option, {
|
|
563
|
-
key: String(
|
|
564
|
-
value: String(
|
|
565
|
-
}, label2 ?? String(
|
|
568
|
+
key: String(value2),
|
|
569
|
+
value: String(value2)
|
|
570
|
+
}, label2 ?? String(value2))
|
|
566
571
|
)))))), inputOnly && /* @__PURE__ */ React7.createElement(Input6.DescriptionAndValidation, null, error));
|
|
567
572
|
};
|
|
568
573
|
var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
@@ -606,7 +611,7 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
|
|
|
606
611
|
};
|
|
607
612
|
|
|
608
613
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
609
|
-
import
|
|
614
|
+
import React13, { useEffect as useEffect7, useMemo as useMemo7, useRef as useRef3 } from "react";
|
|
610
615
|
import { mx as mx8 } from "@dxos/react-ui-theme";
|
|
611
616
|
|
|
612
617
|
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
@@ -615,13 +620,13 @@ import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@d
|
|
|
615
620
|
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
616
621
|
|
|
617
622
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
618
|
-
import React8, { createContext, useContext, useEffect as
|
|
623
|
+
import React8, { createContext, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
|
|
619
624
|
import { raise } from "@dxos/debug";
|
|
620
625
|
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
621
626
|
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
622
627
|
|
|
623
628
|
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
624
|
-
import { SchemaAST
|
|
629
|
+
import { SchemaAST } from "effect";
|
|
625
630
|
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
|
|
626
631
|
import { getValue, setValue } from "@dxos/echo-schema";
|
|
627
632
|
import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
@@ -630,12 +635,12 @@ import { log } from "@dxos/log";
|
|
|
630
635
|
import { validateSchema } from "@dxos/schema";
|
|
631
636
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
632
637
|
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
633
|
-
invariant(
|
|
638
|
+
invariant(SchemaAST.isTypeLiteral(schema.ast), void 0, {
|
|
634
639
|
F: __dxlog_file,
|
|
635
640
|
L: 93,
|
|
636
641
|
S: void 0,
|
|
637
642
|
A: [
|
|
638
|
-
"
|
|
643
|
+
"SchemaAST.isTypeLiteral(schema.ast)",
|
|
639
644
|
""
|
|
640
645
|
]
|
|
641
646
|
});
|
|
@@ -829,6 +834,81 @@ var flatMap = (errors) => {
|
|
|
829
834
|
}, {});
|
|
830
835
|
};
|
|
831
836
|
|
|
837
|
+
// packages/ui/react-ui-form/src/hooks/useRefQueryLookupHandler.ts
|
|
838
|
+
import { useCallback as useCallback5 } from "react";
|
|
839
|
+
import { getDXN } from "@dxos/echo-schema";
|
|
840
|
+
import { Filter } from "@dxos/react-client/echo";
|
|
841
|
+
import { isNonNullable } from "@dxos/util";
|
|
842
|
+
var useRefQueryLookupHandler = ({ space }) => {
|
|
843
|
+
const handleRefQueryLookup = useCallback5(async (typeInfo) => {
|
|
844
|
+
if (!space) {
|
|
845
|
+
return [];
|
|
846
|
+
}
|
|
847
|
+
const query = space.db.query(Filter.typename(typeInfo.typename));
|
|
848
|
+
const { objects } = await query.run();
|
|
849
|
+
return objects.map((object) => {
|
|
850
|
+
const dxn = getDXN(object);
|
|
851
|
+
if (!dxn) {
|
|
852
|
+
return void 0;
|
|
853
|
+
}
|
|
854
|
+
const item = {
|
|
855
|
+
dxn,
|
|
856
|
+
label: object?.name ?? object?.id ?? ""
|
|
857
|
+
};
|
|
858
|
+
return item;
|
|
859
|
+
}).filter(isNonNullable);
|
|
860
|
+
}, [
|
|
861
|
+
space
|
|
862
|
+
]);
|
|
863
|
+
return handleRefQueryLookup;
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
// packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts
|
|
867
|
+
import { useEffect as useEffect5, useState as useState4 } from "react";
|
|
868
|
+
import { log as log2 } from "@dxos/log";
|
|
869
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
|
|
870
|
+
var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
|
|
871
|
+
const [options, setOptions] = useState4([]);
|
|
872
|
+
const [loading, setLoading] = useState4(false);
|
|
873
|
+
useEffect5(() => {
|
|
874
|
+
if (!refTypeInfo || !onQueryRefOptions) {
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
const fetchOptions = async () => {
|
|
878
|
+
setLoading(true);
|
|
879
|
+
try {
|
|
880
|
+
const fetchedOptions = await onQueryRefOptions(refTypeInfo);
|
|
881
|
+
setOptions(fetchedOptions.map((option) => {
|
|
882
|
+
const dxn = option.dxn.toString();
|
|
883
|
+
return {
|
|
884
|
+
id: dxn,
|
|
885
|
+
label: option.label ?? dxn,
|
|
886
|
+
hue: "neutral"
|
|
887
|
+
};
|
|
888
|
+
}));
|
|
889
|
+
} catch (error) {
|
|
890
|
+
log2.error("Failed to fetch ref options:", error, {
|
|
891
|
+
F: __dxlog_file2,
|
|
892
|
+
L: 42,
|
|
893
|
+
S: void 0,
|
|
894
|
+
C: (f, a) => f(...a)
|
|
895
|
+
});
|
|
896
|
+
setOptions([]);
|
|
897
|
+
} finally {
|
|
898
|
+
setLoading(false);
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
void fetchOptions();
|
|
902
|
+
}, [
|
|
903
|
+
refTypeInfo,
|
|
904
|
+
onQueryRefOptions
|
|
905
|
+
]);
|
|
906
|
+
return {
|
|
907
|
+
options,
|
|
908
|
+
loading
|
|
909
|
+
};
|
|
910
|
+
};
|
|
911
|
+
|
|
832
912
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
833
913
|
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
834
914
|
var useFormContext = () => {
|
|
@@ -859,7 +939,7 @@ var useInputProps = (path = []) => {
|
|
|
859
939
|
};
|
|
860
940
|
var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
861
941
|
const form = useForm(formOptions);
|
|
862
|
-
|
|
942
|
+
useEffect6(() => {
|
|
863
943
|
if (!formRef?.current) {
|
|
864
944
|
return;
|
|
865
945
|
}
|
|
@@ -867,7 +947,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
|
867
947
|
const keyIsEnter = event.key === "Enter";
|
|
868
948
|
const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
|
|
869
949
|
const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
|
|
870
|
-
const inputOptOut = event.target.hasAttribute("data-no-submit");
|
|
950
|
+
const inputOptOut = event.target.hasAttribute("data-no-submit") || event.target.closest("[data-no-submit]") !== null;
|
|
871
951
|
const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
|
|
872
952
|
const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
|
|
873
953
|
if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
|
|
@@ -920,182 +1000,629 @@ var FormActions = ({ onCancel, readonly }) => {
|
|
|
920
1000
|
};
|
|
921
1001
|
|
|
922
1002
|
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
923
|
-
import { pipe as pipe2 } from "effect";
|
|
1003
|
+
import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
|
|
924
1004
|
import { capitalize as capitalize2 } from "effect/String";
|
|
925
|
-
import
|
|
926
|
-
import {
|
|
927
|
-
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
1005
|
+
import React12, { useMemo as useMemo6 } from "react";
|
|
1006
|
+
import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
928
1007
|
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
929
1008
|
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
930
1009
|
import { isNotFalsy } from "@dxos/util";
|
|
931
1010
|
|
|
932
1011
|
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
933
|
-
import { pipe } from "effect";
|
|
1012
|
+
import { SchemaAST as SchemaAST3, pipe } from "effect";
|
|
934
1013
|
import { capitalize } from "effect/String";
|
|
935
|
-
import React10, { useCallback as
|
|
936
|
-
import {
|
|
937
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
1014
|
+
import React10, { useCallback as useCallback6, useMemo as useMemo4 } from "react";
|
|
1015
|
+
import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
938
1016
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
939
1017
|
import { IconButton as IconButton3, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
940
1018
|
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
941
1019
|
import { getSchemaProperties } from "@dxos/schema";
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1020
|
+
|
|
1021
|
+
// packages/ui/react-ui-form/src/util/field.ts
|
|
1022
|
+
import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
|
|
1023
|
+
var parseValue = ({ type, format, value }) => {
|
|
1024
|
+
if (value === void 0 || value === null || value === "") {
|
|
1025
|
+
return void 0;
|
|
1026
|
+
}
|
|
1027
|
+
const parseScalar = (type2) => {
|
|
1028
|
+
switch (type2) {
|
|
1029
|
+
case TypeEnum.Boolean: {
|
|
1030
|
+
if (typeof value === "string") {
|
|
1031
|
+
const lowercaseValue = value.toLowerCase();
|
|
1032
|
+
if (lowercaseValue === "0" || lowercaseValue === "false") {
|
|
1033
|
+
return false;
|
|
1034
|
+
} else if (lowercaseValue === "1" || lowercaseValue === "true") {
|
|
1035
|
+
return true;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
return Boolean(value);
|
|
1039
|
+
}
|
|
1040
|
+
case TypeEnum.Number: {
|
|
1041
|
+
const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
|
|
1042
|
+
const num = Number(cleaned);
|
|
1043
|
+
return Number.isNaN(num) ? null : num;
|
|
1044
|
+
}
|
|
1045
|
+
case TypeEnum.String:
|
|
1046
|
+
case TypeEnum.Ref:
|
|
1047
|
+
return String(value);
|
|
1048
|
+
default: {
|
|
1049
|
+
return value;
|
|
1050
|
+
}
|
|
965
1051
|
}
|
|
966
|
-
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
967
|
-
prop.name,
|
|
968
|
-
prop.defaultValue
|
|
969
|
-
]));
|
|
970
1052
|
};
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1053
|
+
if (!format) {
|
|
1054
|
+
return parseScalar(type);
|
|
1055
|
+
}
|
|
1056
|
+
switch (format) {
|
|
1057
|
+
case FormatEnum.Boolean:
|
|
1058
|
+
return parseScalar(TypeEnum.Boolean);
|
|
1059
|
+
case FormatEnum.Number:
|
|
1060
|
+
case FormatEnum.Percent:
|
|
1061
|
+
case FormatEnum.Currency:
|
|
1062
|
+
return parseScalar(TypeEnum.Number);
|
|
1063
|
+
case FormatEnum.String:
|
|
1064
|
+
case FormatEnum.Markdown: {
|
|
1065
|
+
return parseScalar(TypeEnum.String);
|
|
1066
|
+
}
|
|
1067
|
+
case FormatEnum.Ref:
|
|
1068
|
+
throw new Error(`unexpected format: ${FormatEnum.Ref}`);
|
|
1069
|
+
case FormatEnum.DateTime:
|
|
1070
|
+
case FormatEnum.Date:
|
|
1071
|
+
case FormatEnum.Time:
|
|
1072
|
+
case FormatEnum.Timestamp: {
|
|
1073
|
+
const date = new Date(value);
|
|
1074
|
+
return isNaN(date.getTime()) ? null : date;
|
|
1075
|
+
}
|
|
1076
|
+
case FormatEnum.GeoPoint: {
|
|
1077
|
+
if (typeof value === "string") {
|
|
1078
|
+
const cleaned = value.replace(/[^0-9.,-]+/g, "");
|
|
1079
|
+
const parts = cleaned.split(",");
|
|
1080
|
+
if (parts.length === 2) {
|
|
1081
|
+
const lat = parseFloat(parts[0]);
|
|
1082
|
+
const long = parseFloat(parts[1]);
|
|
1083
|
+
if (!isNaN(lat) && !isNaN(long)) {
|
|
1084
|
+
return GeoLocation2.toGeoPoint({
|
|
1085
|
+
latitude: lat,
|
|
1086
|
+
longitude: long
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
return [
|
|
1092
|
+
0,
|
|
1093
|
+
0
|
|
1094
|
+
];
|
|
1095
|
+
}
|
|
1096
|
+
default: {
|
|
1097
|
+
return value;
|
|
976
1098
|
}
|
|
977
|
-
}, [
|
|
978
|
-
type,
|
|
979
|
-
elementType
|
|
980
|
-
]);
|
|
981
|
-
const handleAdd = useCallback5(() => {
|
|
982
|
-
inputProps.onValueChange(type, [
|
|
983
|
-
...values,
|
|
984
|
-
newValue
|
|
985
|
-
]);
|
|
986
|
-
}, [
|
|
987
|
-
type,
|
|
988
|
-
elementType,
|
|
989
|
-
inputProps,
|
|
990
|
-
newValue,
|
|
991
|
-
values
|
|
992
|
-
]);
|
|
993
|
-
const handleRemove = useCallback5((index) => {
|
|
994
|
-
const newValues = values.filter((_, i) => i !== index);
|
|
995
|
-
inputProps.onValueChange(type, newValues);
|
|
996
|
-
}, [
|
|
997
|
-
type,
|
|
998
|
-
inputProps,
|
|
999
|
-
values
|
|
1000
|
-
]);
|
|
1001
|
-
if (!elementType) {
|
|
1002
|
-
return null;
|
|
1003
1099
|
}
|
|
1004
|
-
return /* @__PURE__ */ React10.createElement("div", {
|
|
1005
|
-
role: "none",
|
|
1006
|
-
className: mx6(padding)
|
|
1007
|
-
}, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
|
|
1008
|
-
role: "none",
|
|
1009
|
-
className: "flex flex-col gap-1"
|
|
1010
|
-
}, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
|
|
1011
|
-
key: index,
|
|
1012
|
-
role: "none",
|
|
1013
|
-
className: "flex items-center gap-1"
|
|
1014
|
-
}, /* @__PURE__ */ React10.createElement("div", {
|
|
1015
|
-
role: "none",
|
|
1016
|
-
className: "flex-1"
|
|
1017
|
-
}, /* @__PURE__ */ React10.createElement(FormField, {
|
|
1018
|
-
property: {
|
|
1019
|
-
...property,
|
|
1020
|
-
array: false,
|
|
1021
|
-
ast: elementType
|
|
1022
|
-
},
|
|
1023
|
-
path: [
|
|
1024
|
-
...path ?? [],
|
|
1025
|
-
index
|
|
1026
|
-
],
|
|
1027
|
-
readonly,
|
|
1028
|
-
inline: true,
|
|
1029
|
-
Custom,
|
|
1030
|
-
lookupComponent
|
|
1031
|
-
})), /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1032
|
-
icon: "ph--trash--regular",
|
|
1033
|
-
iconOnly: true,
|
|
1034
|
-
label: t("button remove"),
|
|
1035
|
-
onClick: () => handleRemove(index)
|
|
1036
|
-
})))), /* @__PURE__ */ React10.createElement("div", {
|
|
1037
|
-
role: "none",
|
|
1038
|
-
className: "flex justify-between items-center plb-1"
|
|
1039
|
-
}, /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1040
|
-
icon: "ph--plus--regular",
|
|
1041
|
-
iconOnly: true,
|
|
1042
|
-
label: t("button add"),
|
|
1043
|
-
onClick: handleAdd
|
|
1044
|
-
})));
|
|
1045
1100
|
};
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1101
|
+
var cellClassesForFieldType = ({ type, format }) => {
|
|
1102
|
+
if (!format) {
|
|
1103
|
+
switch (type) {
|
|
1104
|
+
case TypeEnum.Number:
|
|
1105
|
+
return [
|
|
1106
|
+
"text-right",
|
|
1107
|
+
"font-mono"
|
|
1108
|
+
];
|
|
1109
|
+
case TypeEnum.Boolean:
|
|
1110
|
+
return [
|
|
1111
|
+
"text-right",
|
|
1112
|
+
"font-mono"
|
|
1113
|
+
];
|
|
1114
|
+
case TypeEnum.String:
|
|
1115
|
+
return void 0;
|
|
1116
|
+
case TypeEnum.Ref:
|
|
1117
|
+
return void 0;
|
|
1118
|
+
default: {
|
|
1119
|
+
return void 0;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1050
1123
|
switch (format) {
|
|
1051
|
-
case FormatEnum.GeoPoint:
|
|
1052
|
-
return GeoPointInput;
|
|
1053
1124
|
case FormatEnum.Markdown:
|
|
1054
|
-
return
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
case
|
|
1058
|
-
|
|
1059
|
-
case
|
|
1060
|
-
return
|
|
1061
|
-
|
|
1062
|
-
|
|
1125
|
+
return void 0;
|
|
1126
|
+
case FormatEnum.Time:
|
|
1127
|
+
case FormatEnum.Timestamp:
|
|
1128
|
+
case FormatEnum.DateTime:
|
|
1129
|
+
case FormatEnum.Date:
|
|
1130
|
+
case FormatEnum.Duration:
|
|
1131
|
+
return [
|
|
1132
|
+
"font-mono",
|
|
1133
|
+
"text-right"
|
|
1134
|
+
];
|
|
1135
|
+
case FormatEnum.Currency:
|
|
1136
|
+
return [
|
|
1137
|
+
"text-right"
|
|
1138
|
+
];
|
|
1139
|
+
case FormatEnum.JSON:
|
|
1140
|
+
case FormatEnum.DID:
|
|
1141
|
+
return [
|
|
1142
|
+
"font-mono"
|
|
1143
|
+
];
|
|
1144
|
+
default:
|
|
1145
|
+
return void 0;
|
|
1063
1146
|
}
|
|
1064
1147
|
};
|
|
1148
|
+
var pathNotUniqueError = (path) => ({
|
|
1149
|
+
path: "path",
|
|
1150
|
+
message: `'${path}' is already present`
|
|
1151
|
+
});
|
|
1065
1152
|
|
|
1066
|
-
// packages/ui/react-ui-form/src/
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1153
|
+
// packages/ui/react-ui-form/src/util/formatting.ts
|
|
1154
|
+
import { format as formatDate } from "date-fns/format";
|
|
1155
|
+
import { FormatEnum as FormatEnum2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
1156
|
+
var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
|
|
1157
|
+
const formatScalar = (type2) => {
|
|
1158
|
+
switch (type2) {
|
|
1159
|
+
case TypeEnum2.Boolean:
|
|
1160
|
+
return value.toLocaleString().toUpperCase();
|
|
1161
|
+
case TypeEnum2.Number:
|
|
1162
|
+
return value.toLocaleString(locale);
|
|
1163
|
+
case TypeEnum2.String:
|
|
1164
|
+
case TypeEnum2.Ref:
|
|
1165
|
+
return String(value);
|
|
1166
|
+
default: {
|
|
1167
|
+
return String(value);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
if (!format) {
|
|
1172
|
+
return formatScalar(type);
|
|
1173
|
+
}
|
|
1174
|
+
switch (format) {
|
|
1175
|
+
case FormatEnum2.Boolean: {
|
|
1176
|
+
return formatScalar(TypeEnum2.Boolean);
|
|
1177
|
+
}
|
|
1178
|
+
case FormatEnum2.Number: {
|
|
1179
|
+
return formatScalar(TypeEnum2.Number);
|
|
1180
|
+
}
|
|
1181
|
+
case FormatEnum2.String:
|
|
1182
|
+
case FormatEnum2.Ref: {
|
|
1183
|
+
return formatScalar(TypeEnum2.String);
|
|
1184
|
+
}
|
|
1185
|
+
case FormatEnum2.Percent: {
|
|
1186
|
+
return `${value * 100}%`;
|
|
1187
|
+
}
|
|
1188
|
+
case FormatEnum2.Currency: {
|
|
1189
|
+
return value.toLocaleString(locale, {
|
|
1190
|
+
style: "currency",
|
|
1191
|
+
currency: "USD",
|
|
1192
|
+
minimumFractionDigits: 2,
|
|
1193
|
+
maximumFractionDigits: 2
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
case FormatEnum2.Date: {
|
|
1197
|
+
try {
|
|
1198
|
+
return formatDate(new Date(value), "yyyy-MM-dd");
|
|
1199
|
+
} catch (error) {
|
|
1200
|
+
return "Invalid Date";
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
case FormatEnum2.Time: {
|
|
1204
|
+
try {
|
|
1205
|
+
return formatDate(new Date(value), "HH:mm:ss");
|
|
1206
|
+
} catch (error) {
|
|
1207
|
+
return "Invalid Time";
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
case FormatEnum2.DateTime: {
|
|
1211
|
+
try {
|
|
1212
|
+
return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
|
|
1213
|
+
} catch (error) {
|
|
1214
|
+
return "Invalid DateTime";
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
case FormatEnum2.GeoPoint: {
|
|
1218
|
+
if (value === null || value === void 0) {
|
|
1219
|
+
return "";
|
|
1220
|
+
}
|
|
1221
|
+
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1222
|
+
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1223
|
+
return `${latitude},${longitude}`;
|
|
1224
|
+
}
|
|
1225
|
+
return String(value);
|
|
1226
|
+
}
|
|
1227
|
+
default: {
|
|
1228
|
+
if (value === null || value === "undefined") {
|
|
1229
|
+
return "";
|
|
1230
|
+
}
|
|
1231
|
+
return String(value);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
};
|
|
1235
|
+
var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
1236
|
+
const formatScalar = (type2) => {
|
|
1237
|
+
switch (type2) {
|
|
1238
|
+
case TypeEnum2.Boolean:
|
|
1239
|
+
case TypeEnum2.Number:
|
|
1240
|
+
case TypeEnum2.String:
|
|
1241
|
+
case TypeEnum2.Ref:
|
|
1242
|
+
return String(value);
|
|
1243
|
+
default:
|
|
1244
|
+
return String(value);
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
if (!format) {
|
|
1248
|
+
return formatScalar(type);
|
|
1249
|
+
}
|
|
1250
|
+
switch (format) {
|
|
1251
|
+
case FormatEnum2.Boolean:
|
|
1252
|
+
case FormatEnum2.Number:
|
|
1253
|
+
case FormatEnum2.String:
|
|
1254
|
+
case FormatEnum2.Ref: {
|
|
1255
|
+
return formatScalar(type);
|
|
1256
|
+
}
|
|
1257
|
+
case FormatEnum2.Percent: {
|
|
1258
|
+
return String(value * 100);
|
|
1259
|
+
}
|
|
1260
|
+
case FormatEnum2.Currency: {
|
|
1261
|
+
return String(value);
|
|
1262
|
+
}
|
|
1263
|
+
case FormatEnum2.DateTime: {
|
|
1264
|
+
const date = new Date(value);
|
|
1265
|
+
return date.toISOString();
|
|
1266
|
+
}
|
|
1267
|
+
case FormatEnum2.Date: {
|
|
1268
|
+
const date = new Date(value);
|
|
1269
|
+
return date.toISOString().split("T")[0];
|
|
1270
|
+
}
|
|
1271
|
+
case FormatEnum2.Time: {
|
|
1272
|
+
const date = new Date(value);
|
|
1273
|
+
return date.toISOString().split("T")[1].split(".")[0];
|
|
1274
|
+
}
|
|
1275
|
+
case FormatEnum2.GeoPoint: {
|
|
1276
|
+
if (value === null || value === void 0) {
|
|
1277
|
+
return "";
|
|
1278
|
+
}
|
|
1279
|
+
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1280
|
+
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1281
|
+
return `${latitude},${longitude}`;
|
|
1282
|
+
}
|
|
1283
|
+
return String(value);
|
|
1284
|
+
}
|
|
1285
|
+
default: {
|
|
1286
|
+
return String(value);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
// packages/ui/react-ui-form/src/util/refs.ts
|
|
1292
|
+
import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo-schema";
|
|
1293
|
+
import { findAnnotation } from "@dxos/effect";
|
|
1294
|
+
|
|
1295
|
+
// packages/ui/react-ui-form/src/util/schema.ts
|
|
1296
|
+
import { SchemaAST as SchemaAST2 } from "effect";
|
|
1297
|
+
import { findNode } from "@dxos/effect";
|
|
1298
|
+
var findArrayElementType = (ast) => {
|
|
1299
|
+
const tupleType = findNode(ast, SchemaAST2.isTupleType);
|
|
1300
|
+
const elementType = tupleType?.rest[0]?.type;
|
|
1301
|
+
return elementType;
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
// packages/ui/react-ui-form/src/util/refs.ts
|
|
1305
|
+
var getRefProps = (property) => {
|
|
1306
|
+
const { ast, format, array } = property;
|
|
1307
|
+
if (format === FormatEnum3.Ref) {
|
|
1308
|
+
return {
|
|
1309
|
+
ast,
|
|
1310
|
+
isArray: false
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
if (array) {
|
|
1314
|
+
const elementType = findArrayElementType(ast);
|
|
1315
|
+
if (elementType) {
|
|
1316
|
+
const annotation = findAnnotation(elementType, ReferenceAnnotationId);
|
|
1317
|
+
if (annotation) {
|
|
1318
|
+
return {
|
|
1319
|
+
ast: elementType,
|
|
1320
|
+
isArray: true
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
return void 0;
|
|
1326
|
+
};
|
|
1327
|
+
|
|
1328
|
+
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
1329
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
1330
|
+
var padding = "px-2";
|
|
1331
|
+
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
1332
|
+
const { t } = useTranslation5(translationKey);
|
|
1333
|
+
const { ast, name, type, title } = property;
|
|
1334
|
+
const values = useFormValues(path ?? []) ?? [];
|
|
1335
|
+
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
1336
|
+
F: __dxlog_file3,
|
|
1337
|
+
L: 39,
|
|
1338
|
+
S: void 0,
|
|
1339
|
+
A: [
|
|
1340
|
+
"Array.isArray(values)",
|
|
1341
|
+
"`Values at path ${path?.join('.')} must be an array.`"
|
|
1342
|
+
]
|
|
1343
|
+
});
|
|
1344
|
+
const label = title ?? pipe(name, capitalize);
|
|
1345
|
+
const elementType = findArrayElementType(ast);
|
|
1346
|
+
const getDefaultObjectValue = (typeNode) => {
|
|
1347
|
+
const baseNode = findNode2(typeNode, isDiscriminatedUnion);
|
|
1348
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode2(typeNode, SchemaAST3.isTypeLiteral);
|
|
1349
|
+
if (!typeLiteral) {
|
|
1350
|
+
return {};
|
|
1351
|
+
}
|
|
1352
|
+
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
1353
|
+
prop.name,
|
|
1354
|
+
prop.defaultValue
|
|
1355
|
+
]));
|
|
1356
|
+
};
|
|
1357
|
+
const newValue = useMemo4(() => {
|
|
1358
|
+
if (type === "object" && elementType) {
|
|
1359
|
+
return getDefaultObjectValue(elementType);
|
|
1360
|
+
} else {
|
|
1361
|
+
return SimpleType.getDefaultValue(type);
|
|
1362
|
+
}
|
|
1363
|
+
}, [
|
|
1364
|
+
type,
|
|
1365
|
+
elementType
|
|
1366
|
+
]);
|
|
1367
|
+
const handleAdd = useCallback6(() => {
|
|
1368
|
+
inputProps.onValueChange(type, [
|
|
1369
|
+
...values,
|
|
1370
|
+
newValue
|
|
1371
|
+
]);
|
|
1372
|
+
}, [
|
|
1373
|
+
type,
|
|
1374
|
+
elementType,
|
|
1375
|
+
inputProps,
|
|
1376
|
+
newValue,
|
|
1377
|
+
values
|
|
1378
|
+
]);
|
|
1379
|
+
const handleRemove = useCallback6((index) => {
|
|
1380
|
+
const newValues = values.filter((_, i) => i !== index);
|
|
1381
|
+
inputProps.onValueChange(type, newValues);
|
|
1382
|
+
}, [
|
|
1383
|
+
type,
|
|
1384
|
+
inputProps,
|
|
1385
|
+
values
|
|
1386
|
+
]);
|
|
1387
|
+
if (!elementType) {
|
|
1388
|
+
return null;
|
|
1389
|
+
}
|
|
1390
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
1391
|
+
role: "none",
|
|
1392
|
+
className: mx6(padding)
|
|
1393
|
+
}, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
|
|
1394
|
+
role: "none",
|
|
1395
|
+
className: "flex flex-col gap-1"
|
|
1396
|
+
}, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
|
|
1397
|
+
key: index,
|
|
1398
|
+
role: "none",
|
|
1399
|
+
className: "flex items-center gap-1"
|
|
1400
|
+
}, /* @__PURE__ */ React10.createElement("div", {
|
|
1401
|
+
role: "none",
|
|
1402
|
+
className: "flex-1"
|
|
1403
|
+
}, /* @__PURE__ */ React10.createElement(FormField, {
|
|
1404
|
+
property: {
|
|
1405
|
+
...property,
|
|
1406
|
+
array: false,
|
|
1407
|
+
ast: elementType
|
|
1408
|
+
},
|
|
1409
|
+
path: [
|
|
1410
|
+
...path ?? [],
|
|
1411
|
+
index
|
|
1412
|
+
],
|
|
1413
|
+
readonly,
|
|
1414
|
+
inline: true,
|
|
1415
|
+
Custom,
|
|
1416
|
+
lookupComponent
|
|
1417
|
+
})), /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1418
|
+
icon: "ph--trash--regular",
|
|
1419
|
+
iconOnly: true,
|
|
1420
|
+
label: t("button remove"),
|
|
1421
|
+
onClick: () => handleRemove(index)
|
|
1422
|
+
})))), /* @__PURE__ */ React10.createElement("div", {
|
|
1423
|
+
role: "none",
|
|
1424
|
+
className: "flex justify-between items-center plb-1"
|
|
1425
|
+
}, /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1426
|
+
icon: "ph--plus--regular",
|
|
1427
|
+
iconOnly: true,
|
|
1428
|
+
label: t("button add"),
|
|
1429
|
+
onClick: handleAdd
|
|
1430
|
+
})));
|
|
1431
|
+
};
|
|
1432
|
+
|
|
1433
|
+
// packages/ui/react-ui-form/src/components/Form/RefField.tsx
|
|
1434
|
+
import React11, { useCallback as useCallback7, useMemo as useMemo5 } from "react";
|
|
1435
|
+
import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo-schema";
|
|
1436
|
+
import { findAnnotation as findAnnotation2 } from "@dxos/effect";
|
|
1437
|
+
import { DXN } from "@dxos/keys";
|
|
1438
|
+
import { Input as Input7 } from "@dxos/react-ui";
|
|
1439
|
+
import { TagPicker } from "@dxos/react-ui-tag-picker";
|
|
1440
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
1441
|
+
var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }) => {
|
|
1442
|
+
const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
|
|
1443
|
+
ast
|
|
1444
|
+
]);
|
|
1445
|
+
const { options: availableOptions, loading: _loading } = useQueryRefOptions({
|
|
1446
|
+
refTypeInfo,
|
|
1447
|
+
onQueryRefOptions
|
|
1448
|
+
});
|
|
1449
|
+
if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
|
|
1450
|
+
return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
|
|
1451
|
+
type,
|
|
1452
|
+
label,
|
|
1453
|
+
placeholder,
|
|
1454
|
+
disabled,
|
|
1455
|
+
inputOnly,
|
|
1456
|
+
getValue: getValue3,
|
|
1457
|
+
onBlur,
|
|
1458
|
+
onValueChange,
|
|
1459
|
+
...restInputProps
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
const handleGetValue = useCallback7(() => {
|
|
1463
|
+
const formValue = getValue3();
|
|
1464
|
+
const unknownToRefOption = (val) => {
|
|
1465
|
+
if (Ref.isRef(val)) {
|
|
1466
|
+
const dxnString = val.dxn.toString();
|
|
1467
|
+
const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
|
|
1468
|
+
if (matchingOption) {
|
|
1469
|
+
return matchingOption;
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
return void 0;
|
|
1473
|
+
};
|
|
1474
|
+
if (array && Array.isArray(formValue)) {
|
|
1475
|
+
return formValue.map(unknownToRefOption).filter(isNonNullable2) ?? [];
|
|
1476
|
+
}
|
|
1477
|
+
const option = unknownToRefOption(formValue);
|
|
1478
|
+
if (option) {
|
|
1479
|
+
return [
|
|
1480
|
+
option
|
|
1481
|
+
];
|
|
1482
|
+
}
|
|
1483
|
+
return [];
|
|
1484
|
+
}, [
|
|
1485
|
+
getValue3,
|
|
1486
|
+
availableOptions,
|
|
1487
|
+
array
|
|
1488
|
+
]);
|
|
1489
|
+
const handleSearch = useCallback7((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
|
|
1490
|
+
id: option.id,
|
|
1491
|
+
label: option.label,
|
|
1492
|
+
hue: option.hue
|
|
1493
|
+
})), [
|
|
1494
|
+
availableOptions
|
|
1495
|
+
]);
|
|
1496
|
+
const handleUpdate = useCallback7((ids) => {
|
|
1497
|
+
if (ids.length === 0) {
|
|
1498
|
+
onValueChange("object", void 0);
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
const refs = ids.map((id) => {
|
|
1502
|
+
const item = availableOptions.find((option) => option.id === id);
|
|
1503
|
+
if (item) {
|
|
1504
|
+
const dxn = DXN.parse(item.id);
|
|
1505
|
+
return Ref.fromDXN(dxn);
|
|
1506
|
+
}
|
|
1507
|
+
return null;
|
|
1508
|
+
}).filter(isNonNullable2);
|
|
1509
|
+
if (array) {
|
|
1510
|
+
onValueChange("object", refs);
|
|
1511
|
+
} else {
|
|
1512
|
+
onValueChange("object", refs[0]);
|
|
1513
|
+
}
|
|
1514
|
+
}, [
|
|
1515
|
+
availableOptions,
|
|
1516
|
+
array,
|
|
1517
|
+
onValueChange
|
|
1518
|
+
]);
|
|
1519
|
+
const tagPickerMode = useMemo5(() => array ? "multi-select" : "single-select", [
|
|
1520
|
+
array
|
|
1521
|
+
]);
|
|
1522
|
+
if (!refTypeInfo) {
|
|
1523
|
+
return null;
|
|
1524
|
+
}
|
|
1525
|
+
const { status, error } = restInputProps.getStatus();
|
|
1526
|
+
return /* @__PURE__ */ React11.createElement(Input7.Root, {
|
|
1527
|
+
validationValence: status
|
|
1528
|
+
}, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
|
|
1529
|
+
error
|
|
1530
|
+
}, /* @__PURE__ */ React11.createElement(Input7.Label, null, label)), /* @__PURE__ */ React11.createElement("div", {
|
|
1531
|
+
"data-no-submit": true
|
|
1532
|
+
}, /* @__PURE__ */ React11.createElement(TagPicker, {
|
|
1533
|
+
items: handleGetValue(),
|
|
1534
|
+
mode: tagPickerMode,
|
|
1535
|
+
onBlur: (event) => onBlur(event),
|
|
1536
|
+
onUpdate: handleUpdate,
|
|
1537
|
+
onSearch: handleSearch,
|
|
1538
|
+
classNames: "rounded-sm bg-input p-1.5"
|
|
1539
|
+
})), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
|
|
1540
|
+
};
|
|
1541
|
+
var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
|
|
1542
|
+
const handleOnValueChange = (_type, dxnString) => {
|
|
1543
|
+
const dxn = DXN.tryParse(dxnString);
|
|
1544
|
+
if (dxn) {
|
|
1545
|
+
onValueChange?.("object", Ref.fromDXN(dxn));
|
|
1546
|
+
} else if (dxnString === "") {
|
|
1547
|
+
onValueChange?.("object", void 0);
|
|
1548
|
+
} else {
|
|
1549
|
+
onValueChange?.("string", dxnString);
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
const handleGetValue = () => {
|
|
1553
|
+
const formValue = getValue3();
|
|
1554
|
+
if (typeof formValue === "string") {
|
|
1555
|
+
return formValue;
|
|
1556
|
+
}
|
|
1557
|
+
if (Ref.isRef(formValue)) {
|
|
1558
|
+
return formValue.dxn.toString();
|
|
1559
|
+
}
|
|
1560
|
+
return void 0;
|
|
1561
|
+
};
|
|
1562
|
+
return /* @__PURE__ */ React11.createElement(TextInput, {
|
|
1563
|
+
type,
|
|
1564
|
+
label,
|
|
1565
|
+
disabled,
|
|
1566
|
+
placeholder,
|
|
1567
|
+
inputOnly,
|
|
1568
|
+
getValue: handleGetValue,
|
|
1569
|
+
onValueChange: handleOnValueChange,
|
|
1570
|
+
...restInputProps
|
|
1571
|
+
});
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
1575
|
+
import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
|
|
1576
|
+
var getInputComponent = (type, format) => {
|
|
1577
|
+
switch (format) {
|
|
1578
|
+
case FormatEnum4.GeoPoint:
|
|
1579
|
+
return GeoPointInput;
|
|
1580
|
+
case FormatEnum4.Markdown:
|
|
1581
|
+
return MarkdownInput;
|
|
1582
|
+
}
|
|
1583
|
+
switch (type) {
|
|
1584
|
+
case "string":
|
|
1585
|
+
return TextInput;
|
|
1586
|
+
case "number":
|
|
1587
|
+
return NumberInput;
|
|
1588
|
+
case "boolean":
|
|
1589
|
+
return BooleanInput;
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
|
|
1593
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
1594
|
+
var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1595
|
+
const inputProps = useInputProps(path);
|
|
1596
|
+
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
1597
|
+
const label = useMemo6(() => title ?? pipe2(name, capitalize2), [
|
|
1598
|
+
title,
|
|
1599
|
+
name
|
|
1600
|
+
]);
|
|
1601
|
+
const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
1602
|
+
examples,
|
|
1603
|
+
description
|
|
1604
|
+
]);
|
|
1605
|
+
const FoundComponent = lookupComponent?.({
|
|
1606
|
+
prop: name,
|
|
1607
|
+
schema: Schema.make(ast),
|
|
1608
|
+
inputProps: {
|
|
1609
|
+
type,
|
|
1610
|
+
format,
|
|
1611
|
+
label,
|
|
1612
|
+
disabled: readonly,
|
|
1613
|
+
placeholder,
|
|
1614
|
+
...inputProps
|
|
1615
|
+
}
|
|
1616
|
+
});
|
|
1090
1617
|
if (FoundComponent) {
|
|
1091
|
-
return /* @__PURE__ */
|
|
1618
|
+
return /* @__PURE__ */ React12.createElement("div", {
|
|
1092
1619
|
role: "none"
|
|
1093
1620
|
}, FoundComponent);
|
|
1094
1621
|
}
|
|
1095
1622
|
const jsonPath = createJsonPath3(path ?? []);
|
|
1096
1623
|
const CustomComponent = Custom?.[jsonPath];
|
|
1097
1624
|
if (CustomComponent) {
|
|
1098
|
-
return /* @__PURE__ */
|
|
1625
|
+
return /* @__PURE__ */ React12.createElement(CustomComponent, {
|
|
1099
1626
|
type,
|
|
1100
1627
|
format,
|
|
1101
1628
|
label,
|
|
@@ -1105,8 +1632,23 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1105
1632
|
...inputProps
|
|
1106
1633
|
});
|
|
1107
1634
|
}
|
|
1635
|
+
const refProps = getRefProps(property);
|
|
1636
|
+
if (refProps) {
|
|
1637
|
+
return /* @__PURE__ */ React12.createElement(RefField, {
|
|
1638
|
+
ast: refProps.ast,
|
|
1639
|
+
array: refProps.isArray,
|
|
1640
|
+
type,
|
|
1641
|
+
format,
|
|
1642
|
+
label,
|
|
1643
|
+
placeholder,
|
|
1644
|
+
disabled: readonly,
|
|
1645
|
+
inputOnly: inline,
|
|
1646
|
+
onQueryRefOptions,
|
|
1647
|
+
...inputProps
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1108
1650
|
if (array) {
|
|
1109
|
-
return /* @__PURE__ */
|
|
1651
|
+
return /* @__PURE__ */ React12.createElement(ArrayField, {
|
|
1110
1652
|
property,
|
|
1111
1653
|
path,
|
|
1112
1654
|
inputProps,
|
|
@@ -1116,9 +1658,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1116
1658
|
}
|
|
1117
1659
|
const InputComponent = getInputComponent(type, format);
|
|
1118
1660
|
if (InputComponent) {
|
|
1119
|
-
return /* @__PURE__ */
|
|
1661
|
+
return /* @__PURE__ */ React12.createElement("div", {
|
|
1120
1662
|
role: "none"
|
|
1121
|
-
}, /* @__PURE__ */
|
|
1663
|
+
}, /* @__PURE__ */ React12.createElement(InputComponent, {
|
|
1122
1664
|
type,
|
|
1123
1665
|
format,
|
|
1124
1666
|
label,
|
|
@@ -1129,9 +1671,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1129
1671
|
}));
|
|
1130
1672
|
}
|
|
1131
1673
|
if (options) {
|
|
1132
|
-
return /* @__PURE__ */
|
|
1674
|
+
return /* @__PURE__ */ React12.createElement("div", {
|
|
1133
1675
|
role: "none"
|
|
1134
|
-
}, /* @__PURE__ */
|
|
1676
|
+
}, /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
1135
1677
|
type,
|
|
1136
1678
|
format,
|
|
1137
1679
|
disabled: readonly,
|
|
@@ -1146,24 +1688,28 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1146
1688
|
}));
|
|
1147
1689
|
}
|
|
1148
1690
|
if (type === "object") {
|
|
1149
|
-
const baseNode =
|
|
1150
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) :
|
|
1691
|
+
const baseNode = findNode3(ast, isDiscriminatedUnion2);
|
|
1692
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
|
|
1151
1693
|
if (typeLiteral) {
|
|
1152
|
-
return /* @__PURE__ */
|
|
1694
|
+
return /* @__PURE__ */ React12.createElement("div", {
|
|
1153
1695
|
role: "none"
|
|
1154
|
-
}, !inline && /* @__PURE__ */
|
|
1155
|
-
|
|
1696
|
+
}, !inline && /* @__PURE__ */ React12.createElement("h3", {
|
|
1697
|
+
className: "text-lg mbs-2 mbe-1"
|
|
1698
|
+
}, label), /* @__PURE__ */ React12.createElement(FormFields, {
|
|
1699
|
+
schema: Schema.make(typeLiteral),
|
|
1156
1700
|
path,
|
|
1157
1701
|
readonly,
|
|
1158
|
-
|
|
1702
|
+
onQueryRefOptions,
|
|
1703
|
+
Custom,
|
|
1704
|
+
lookupComponent
|
|
1159
1705
|
}));
|
|
1160
1706
|
}
|
|
1161
1707
|
}
|
|
1162
1708
|
return null;
|
|
1163
1709
|
};
|
|
1164
|
-
var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
|
|
1710
|
+
var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1165
1711
|
const values = useFormValues(path);
|
|
1166
|
-
const properties =
|
|
1712
|
+
const properties = useMemo6(() => {
|
|
1167
1713
|
const props = getSchemaProperties2(schema.ast, values);
|
|
1168
1714
|
const filtered = filter ? filter(props) : props;
|
|
1169
1715
|
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
@@ -1173,11 +1719,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
1173
1719
|
filter,
|
|
1174
1720
|
sort
|
|
1175
1721
|
]);
|
|
1176
|
-
return /* @__PURE__ */
|
|
1722
|
+
return /* @__PURE__ */ React12.createElement("div", {
|
|
1177
1723
|
role: "form",
|
|
1178
1724
|
className: mx7("flex flex-col w-full gap-2")
|
|
1179
1725
|
}, properties.map((property) => {
|
|
1180
|
-
return /* @__PURE__ */
|
|
1726
|
+
return /* @__PURE__ */ React12.createElement(FormField, {
|
|
1181
1727
|
key: property.name,
|
|
1182
1728
|
property,
|
|
1183
1729
|
path: [
|
|
@@ -1185,6 +1731,7 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
1185
1731
|
property.name
|
|
1186
1732
|
],
|
|
1187
1733
|
readonly,
|
|
1734
|
+
onQueryRefOptions,
|
|
1188
1735
|
lookupComponent,
|
|
1189
1736
|
Custom
|
|
1190
1737
|
});
|
|
@@ -1192,13 +1739,13 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
1192
1739
|
};
|
|
1193
1740
|
|
|
1194
1741
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
1195
|
-
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
1742
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1196
1743
|
const formRef = useRef3(null);
|
|
1197
|
-
const onValid =
|
|
1744
|
+
const onValid = useMemo7(() => autoSave ? onSave : void 0, [
|
|
1198
1745
|
autoSave,
|
|
1199
1746
|
onSave
|
|
1200
1747
|
]);
|
|
1201
|
-
|
|
1748
|
+
useEffect7(() => {
|
|
1202
1749
|
if (autoFocus && formRef.current) {
|
|
1203
1750
|
const input = formRef.current.querySelector("input");
|
|
1204
1751
|
if (input) {
|
|
@@ -1208,7 +1755,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
|
|
|
1208
1755
|
}, [
|
|
1209
1756
|
autoFocus
|
|
1210
1757
|
]);
|
|
1211
|
-
return /* @__PURE__ */
|
|
1758
|
+
return /* @__PURE__ */ React13.createElement(FormProvider, {
|
|
1212
1759
|
formRef,
|
|
1213
1760
|
schema,
|
|
1214
1761
|
autoSave,
|
|
@@ -1217,36 +1764,37 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
|
|
|
1217
1764
|
onValidate,
|
|
1218
1765
|
onValid,
|
|
1219
1766
|
onSave
|
|
1220
|
-
}, /* @__PURE__ */
|
|
1767
|
+
}, /* @__PURE__ */ React13.createElement("div", {
|
|
1221
1768
|
ref: formRef,
|
|
1222
1769
|
role: "none",
|
|
1223
1770
|
className: mx8("p-2", classNames),
|
|
1224
1771
|
"data-testid": testId
|
|
1225
|
-
}, /* @__PURE__ */
|
|
1772
|
+
}, /* @__PURE__ */ React13.createElement(FormFields, {
|
|
1226
1773
|
schema,
|
|
1227
1774
|
path,
|
|
1228
1775
|
readonly,
|
|
1229
1776
|
filter,
|
|
1230
1777
|
sort,
|
|
1778
|
+
onQueryRefOptions,
|
|
1231
1779
|
lookupComponent,
|
|
1232
1780
|
Custom
|
|
1233
|
-
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */
|
|
1781
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React13.createElement(FormActions, {
|
|
1234
1782
|
onCancel,
|
|
1235
1783
|
readonly
|
|
1236
1784
|
})));
|
|
1237
1785
|
};
|
|
1238
1786
|
|
|
1239
1787
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
1240
|
-
var
|
|
1788
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1241
1789
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
1242
1790
|
const { t } = useTranslation6(translationKey);
|
|
1243
|
-
const [props, setProps] =
|
|
1244
|
-
|
|
1791
|
+
const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
|
|
1792
|
+
useEffect8(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1245
1793
|
field,
|
|
1246
1794
|
projection
|
|
1247
1795
|
]);
|
|
1248
|
-
const [schemas, setSchemas] =
|
|
1249
|
-
|
|
1796
|
+
const [schemas, setSchemas] = useState5([]);
|
|
1797
|
+
useEffect8(() => {
|
|
1250
1798
|
if (!registry) {
|
|
1251
1799
|
return;
|
|
1252
1800
|
}
|
|
@@ -1264,17 +1812,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1264
1812
|
}, [
|
|
1265
1813
|
registry
|
|
1266
1814
|
]);
|
|
1267
|
-
const [referenceSchema, setReferenceSchema] =
|
|
1268
|
-
|
|
1815
|
+
const [referenceSchema, setReferenceSchema] = useState5();
|
|
1816
|
+
useEffect8(() => {
|
|
1269
1817
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
1270
1818
|
}, [
|
|
1271
1819
|
schemas,
|
|
1272
1820
|
props?.referenceSchema
|
|
1273
1821
|
]);
|
|
1274
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
1822
|
+
const [{ fieldSchema }, setFieldSchema] = useState5({
|
|
1275
1823
|
fieldSchema: getFormatSchema(props?.format)
|
|
1276
1824
|
});
|
|
1277
|
-
const handleValuesChanged =
|
|
1825
|
+
const handleValuesChanged = useCallback8((_props) => {
|
|
1278
1826
|
setFieldSchema((prev) => {
|
|
1279
1827
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
1280
1828
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -1309,7 +1857,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1309
1857
|
props.format,
|
|
1310
1858
|
props.referenceSchema
|
|
1311
1859
|
]);
|
|
1312
|
-
const handleValidate =
|
|
1860
|
+
const handleValidate = useCallback8(({ property }) => {
|
|
1313
1861
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
1314
1862
|
return [
|
|
1315
1863
|
{
|
|
@@ -1322,7 +1870,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1322
1870
|
view.fields,
|
|
1323
1871
|
field
|
|
1324
1872
|
]);
|
|
1325
|
-
const handleSave =
|
|
1873
|
+
const handleSave = useCallback8((props2) => {
|
|
1326
1874
|
projection.setFieldProjection({
|
|
1327
1875
|
field,
|
|
1328
1876
|
props: props2
|
|
@@ -1333,51 +1881,51 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1333
1881
|
field,
|
|
1334
1882
|
onSave
|
|
1335
1883
|
]);
|
|
1336
|
-
const handleCancel =
|
|
1884
|
+
const handleCancel = useCallback8(() => {
|
|
1337
1885
|
requestAnimationFrame(() => onCancel?.());
|
|
1338
1886
|
onSave();
|
|
1339
1887
|
}, [
|
|
1340
1888
|
onSave
|
|
1341
1889
|
]);
|
|
1342
|
-
const Custom =
|
|
1343
|
-
["format"]: (props2) => /* @__PURE__ */
|
|
1890
|
+
const Custom = useMemo8(() => ({
|
|
1891
|
+
["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
1344
1892
|
...props2,
|
|
1345
|
-
options: FormatEnums.filter((value) => value !==
|
|
1893
|
+
options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
|
|
1346
1894
|
value,
|
|
1347
1895
|
label: t(`format ${value}`)
|
|
1348
1896
|
}))
|
|
1349
1897
|
}),
|
|
1350
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */
|
|
1898
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
1351
1899
|
...props2,
|
|
1352
1900
|
options: schemas.map((schema) => ({
|
|
1353
1901
|
value: schema.typename
|
|
1354
1902
|
}))
|
|
1355
1903
|
}),
|
|
1356
|
-
["referencePath"]: (props2) => /* @__PURE__ */
|
|
1904
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
1357
1905
|
...props2,
|
|
1358
1906
|
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
1359
1907
|
value: p.name
|
|
1360
1908
|
})) : []
|
|
1361
1909
|
}),
|
|
1362
|
-
["options"]: (props2) => /* @__PURE__ */
|
|
1910
|
+
["options"]: (props2) => /* @__PURE__ */ React14.createElement(SelectOptionInput, props2)
|
|
1363
1911
|
}), [
|
|
1364
1912
|
t,
|
|
1365
1913
|
schemas,
|
|
1366
1914
|
referenceSchema
|
|
1367
1915
|
]);
|
|
1368
|
-
const propIsNotType =
|
|
1916
|
+
const propIsNotType = useCallback8((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
1369
1917
|
if (!fieldSchema) {
|
|
1370
|
-
|
|
1918
|
+
log3.warn("invalid format", {
|
|
1371
1919
|
props
|
|
1372
1920
|
}, {
|
|
1373
|
-
F:
|
|
1921
|
+
F: __dxlog_file4,
|
|
1374
1922
|
L: 174,
|
|
1375
1923
|
S: void 0,
|
|
1376
1924
|
C: (f, a) => f(...a)
|
|
1377
1925
|
});
|
|
1378
1926
|
return null;
|
|
1379
1927
|
}
|
|
1380
|
-
return /* @__PURE__ */
|
|
1928
|
+
return /* @__PURE__ */ React14.createElement(Form, {
|
|
1381
1929
|
key: field.id,
|
|
1382
1930
|
autoFocus: true,
|
|
1383
1931
|
values: props,
|
|
@@ -1396,31 +1944,32 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1396
1944
|
};
|
|
1397
1945
|
|
|
1398
1946
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
1399
|
-
import
|
|
1400
|
-
import {
|
|
1947
|
+
import { Schema as Schema2, SchemaAST as SchemaAST5 } from "effect";
|
|
1948
|
+
import React15, { useCallback as useCallback9, useMemo as useMemo9, useState as useState6 } from "react";
|
|
1949
|
+
import { Format } from "@dxos/echo-schema";
|
|
1401
1950
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1402
1951
|
import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1403
1952
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
1404
1953
|
import { ghostHover, inputTextLabel, mx as mx9 } from "@dxos/react-ui-theme";
|
|
1405
1954
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1406
|
-
var
|
|
1955
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
1407
1956
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
1408
|
-
var ViewMetaSchema =
|
|
1409
|
-
name:
|
|
1410
|
-
[
|
|
1957
|
+
var ViewMetaSchema = Schema2.Struct({
|
|
1958
|
+
name: Schema2.String.annotations({
|
|
1959
|
+
[SchemaAST5.TitleAnnotationId]: "View"
|
|
1411
1960
|
}),
|
|
1412
1961
|
typename: Format.URL.annotations({
|
|
1413
|
-
[
|
|
1962
|
+
[SchemaAST5.TitleAnnotationId]: "Typename"
|
|
1414
1963
|
})
|
|
1415
|
-
}).pipe(
|
|
1964
|
+
}).pipe(Schema2.mutable);
|
|
1416
1965
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
1417
1966
|
const { t } = useTranslation7(translationKey);
|
|
1418
|
-
const projection =
|
|
1967
|
+
const projection = useMemo9(() => new ViewProjection(schema.jsonSchema, view), [
|
|
1419
1968
|
schema,
|
|
1420
1969
|
view
|
|
1421
1970
|
]);
|
|
1422
|
-
const [field, setField] =
|
|
1423
|
-
const viewValues =
|
|
1971
|
+
const [field, setField] = useState6();
|
|
1972
|
+
const viewValues = useMemo9(() => {
|
|
1424
1973
|
return {
|
|
1425
1974
|
name: view.name,
|
|
1426
1975
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -1430,13 +1979,13 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1430
1979
|
}, [
|
|
1431
1980
|
view
|
|
1432
1981
|
]);
|
|
1433
|
-
const handleSelect =
|
|
1982
|
+
const handleSelect = useCallback9((field2) => {
|
|
1434
1983
|
setField((f) => f === field2 ? void 0 : field2);
|
|
1435
1984
|
}, []);
|
|
1436
|
-
const handleAdd =
|
|
1985
|
+
const handleAdd = useCallback9(() => {
|
|
1437
1986
|
invariant3(!schema.readonly, void 0, {
|
|
1438
|
-
F:
|
|
1439
|
-
L:
|
|
1987
|
+
F: __dxlog_file5,
|
|
1988
|
+
L: 77,
|
|
1440
1989
|
S: void 0,
|
|
1441
1990
|
A: [
|
|
1442
1991
|
"!schema.readonly",
|
|
@@ -1449,10 +1998,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1449
1998
|
schema,
|
|
1450
1999
|
view
|
|
1451
2000
|
]);
|
|
1452
|
-
const handleUpdate =
|
|
2001
|
+
const handleUpdate = useCallback9(({ name, typename }) => {
|
|
1453
2002
|
invariant3(!schema.readonly, void 0, {
|
|
1454
|
-
F:
|
|
1455
|
-
L:
|
|
2003
|
+
F: __dxlog_file5,
|
|
2004
|
+
L: 84,
|
|
1456
2005
|
S: void 0,
|
|
1457
2006
|
A: [
|
|
1458
2007
|
"!schema.readonly",
|
|
@@ -1472,10 +2021,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1472
2021
|
view,
|
|
1473
2022
|
onTypenameChanged
|
|
1474
2023
|
]);
|
|
1475
|
-
const handleDelete =
|
|
2024
|
+
const handleDelete = useCallback9((fieldId) => {
|
|
1476
2025
|
invariant3(!schema.readonly, void 0, {
|
|
1477
|
-
F:
|
|
1478
|
-
L:
|
|
2026
|
+
F: __dxlog_file5,
|
|
2027
|
+
L: 100,
|
|
1479
2028
|
S: void 0,
|
|
1480
2029
|
A: [
|
|
1481
2030
|
"!schema.readonly",
|
|
@@ -1491,10 +2040,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1491
2040
|
field,
|
|
1492
2041
|
onDelete
|
|
1493
2042
|
]);
|
|
1494
|
-
const handleMove =
|
|
2043
|
+
const handleMove = useCallback9((fromIndex, toIndex) => {
|
|
1495
2044
|
invariant3(!schema.readonly, void 0, {
|
|
1496
|
-
F:
|
|
1497
|
-
L:
|
|
2045
|
+
F: __dxlog_file5,
|
|
2046
|
+
L: 112,
|
|
1498
2047
|
S: void 0,
|
|
1499
2048
|
A: [
|
|
1500
2049
|
"!schema.readonly",
|
|
@@ -1511,91 +2060,95 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1511
2060
|
schema,
|
|
1512
2061
|
view.fields
|
|
1513
2062
|
]);
|
|
1514
|
-
const handleClose =
|
|
2063
|
+
const handleClose = useCallback9(() => setField(void 0), []);
|
|
1515
2064
|
const hiddenProperties = projection.getHiddenProperties();
|
|
1516
|
-
const handleHide =
|
|
2065
|
+
const handleHide = useCallback9((fieldId) => {
|
|
1517
2066
|
setField(void 0);
|
|
1518
2067
|
projection.hideFieldProjection(fieldId);
|
|
1519
2068
|
}, [
|
|
1520
2069
|
projection
|
|
1521
2070
|
]);
|
|
1522
|
-
const handleShow =
|
|
2071
|
+
const handleShow = useCallback9((property) => {
|
|
1523
2072
|
setField(void 0);
|
|
1524
2073
|
projection.showFieldProjection(property);
|
|
1525
2074
|
}, [
|
|
1526
2075
|
projection
|
|
1527
2076
|
]);
|
|
1528
|
-
return /* @__PURE__ */
|
|
2077
|
+
return /* @__PURE__ */ React15.createElement("div", {
|
|
1529
2078
|
role: "none",
|
|
1530
|
-
className: mx9("
|
|
1531
|
-
}, /* @__PURE__ */
|
|
2079
|
+
className: mx9("grid grid-rows-[1fr_1fr] min-bs-0", classNames)
|
|
2080
|
+
}, /* @__PURE__ */ React15.createElement(Form, {
|
|
1532
2081
|
autoSave: true,
|
|
1533
2082
|
schema: ViewMetaSchema,
|
|
1534
2083
|
values: viewValues,
|
|
1535
|
-
onSave: schema.readonly ? void 0 : handleUpdate
|
|
1536
|
-
|
|
2084
|
+
onSave: schema.readonly ? void 0 : handleUpdate,
|
|
2085
|
+
classNames: "min-bs-0 overflow-y-auto"
|
|
2086
|
+
}), /* @__PURE__ */ React15.createElement("div", {
|
|
2087
|
+
role: "none",
|
|
2088
|
+
className: "border-bs border-separator min-bs-0 overflow-y-auto"
|
|
2089
|
+
}, /* @__PURE__ */ React15.createElement("div", {
|
|
1537
2090
|
role: "none",
|
|
1538
2091
|
className: "p-2"
|
|
1539
|
-
}, /* @__PURE__ */
|
|
2092
|
+
}, /* @__PURE__ */ React15.createElement("label", {
|
|
1540
2093
|
className: mx9(inputTextLabel)
|
|
1541
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
2094
|
+
}, t("fields label"))), /* @__PURE__ */ React15.createElement(List2.Root, {
|
|
1542
2095
|
items: view.fields,
|
|
1543
|
-
isItem:
|
|
2096
|
+
isItem: Schema2.is(FieldSchema),
|
|
1544
2097
|
getId: (field2) => field2.id,
|
|
1545
2098
|
onMove: schema.readonly ? void 0 : handleMove
|
|
1546
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2099
|
+
}, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("div", {
|
|
1547
2100
|
role: "heading",
|
|
1548
2101
|
className: grid
|
|
1549
|
-
}, /* @__PURE__ */
|
|
2102
|
+
}, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement("div", {
|
|
1550
2103
|
className: "flex items-center text-sm"
|
|
1551
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
2104
|
+
}, t("field path label"))), /* @__PURE__ */ React15.createElement("div", {
|
|
1552
2105
|
role: "list",
|
|
1553
2106
|
className: "flex flex-col w-full"
|
|
1554
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
2107
|
+
}, fields?.map((field2) => /* @__PURE__ */ React15.createElement(List2.Item, {
|
|
1555
2108
|
key: field2.id,
|
|
1556
2109
|
item: field2,
|
|
1557
2110
|
classNames: mx9(grid, ghostHover, "cursor-pointer")
|
|
1558
|
-
}, /* @__PURE__ */
|
|
2111
|
+
}, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
|
|
1559
2112
|
onClick: () => handleSelect(field2)
|
|
1560
|
-
}, field2.path), /* @__PURE__ */
|
|
2113
|
+
}, field2.path), /* @__PURE__ */ React15.createElement("div", {
|
|
1561
2114
|
className: "flex items-center gap-2 -ml-4"
|
|
1562
|
-
}, /* @__PURE__ */
|
|
2115
|
+
}, /* @__PURE__ */ React15.createElement(List2.ItemButton, {
|
|
1563
2116
|
icon: "ph--eye-slash--regular",
|
|
1564
2117
|
disabled: view.fields.length <= 1,
|
|
1565
2118
|
onClick: () => handleHide(field2.id)
|
|
1566
|
-
}), !schema.readonly && /* @__PURE__ */
|
|
2119
|
+
}), !schema.readonly && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
|
|
1567
2120
|
icon: "ph--trash--regular",
|
|
1568
2121
|
disabled: view.fields.length <= 1,
|
|
1569
2122
|
onClick: () => handleDelete(field2.id)
|
|
1570
|
-
}))))))), hiddenProperties.length > 0 && /* @__PURE__ */
|
|
2123
|
+
}))))))), hiddenProperties.length > 0 && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", {
|
|
1571
2124
|
role: "none",
|
|
1572
2125
|
className: "p-2"
|
|
1573
|
-
}, /* @__PURE__ */
|
|
2126
|
+
}, /* @__PURE__ */ React15.createElement("label", {
|
|
1574
2127
|
className: mx9(inputTextLabel)
|
|
1575
|
-
}, t("hidden fields label"))), /* @__PURE__ */
|
|
2128
|
+
}, t("hidden fields label"))), /* @__PURE__ */ React15.createElement(List2.Root, {
|
|
1576
2129
|
items: hiddenProperties,
|
|
1577
2130
|
isItem: (item) => typeof item === "string",
|
|
1578
2131
|
getId: (property) => property
|
|
1579
|
-
}, ({ items: properties }) => /* @__PURE__ */
|
|
2132
|
+
}, ({ items: properties }) => /* @__PURE__ */ React15.createElement("div", {
|
|
1580
2133
|
role: "list",
|
|
1581
2134
|
className: "flex flex-col w-full"
|
|
1582
|
-
}, properties?.map((property) => /* @__PURE__ */
|
|
2135
|
+
}, properties?.map((property) => /* @__PURE__ */ React15.createElement(List2.Item, {
|
|
1583
2136
|
key: property,
|
|
1584
2137
|
item: property,
|
|
1585
2138
|
classNames: mx9(grid, ghostHover, "cursor-pointer")
|
|
1586
|
-
}, /* @__PURE__ */
|
|
2139
|
+
}, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, null, property), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
|
|
1587
2140
|
icon: "ph--eye--regular",
|
|
1588
2141
|
onClick: () => handleShow(property)
|
|
1589
|
-
}))))))), field && /* @__PURE__ */
|
|
2142
|
+
}))))))), field && /* @__PURE__ */ React15.createElement(FieldEditor, {
|
|
1590
2143
|
key: field.id,
|
|
1591
2144
|
view,
|
|
1592
2145
|
projection,
|
|
1593
2146
|
field,
|
|
1594
2147
|
registry,
|
|
1595
2148
|
onSave: handleClose
|
|
1596
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
2149
|
+
}), !readonly && !field && /* @__PURE__ */ React15.createElement("div", {
|
|
1597
2150
|
className: "flex p-2 justify-center"
|
|
1598
|
-
}, /* @__PURE__ */
|
|
2151
|
+
}, /* @__PURE__ */ React15.createElement(IconButton4, {
|
|
1599
2152
|
icon: "ph--plus--regular",
|
|
1600
2153
|
label: t("button add property"),
|
|
1601
2154
|
onClick: schema.readonly ? void 0 : handleAdd,
|
|
@@ -1603,264 +2156,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1603
2156
|
disabled: view.fields.length >= VIEW_FIELD_LIMIT
|
|
1604
2157
|
})));
|
|
1605
2158
|
};
|
|
1606
|
-
|
|
1607
|
-
// packages/ui/react-ui-form/src/util/field.ts
|
|
1608
|
-
import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
|
|
1609
|
-
var parseValue = ({ type, format, value }) => {
|
|
1610
|
-
if (value === void 0 || value === null || value === "") {
|
|
1611
|
-
return void 0;
|
|
1612
|
-
}
|
|
1613
|
-
const parseScalar = (type2) => {
|
|
1614
|
-
switch (type2) {
|
|
1615
|
-
case TypeEnum.Boolean: {
|
|
1616
|
-
if (typeof value === "string") {
|
|
1617
|
-
const lowercaseValue = value.toLowerCase();
|
|
1618
|
-
if (lowercaseValue === "0" || lowercaseValue === "false") {
|
|
1619
|
-
return false;
|
|
1620
|
-
} else if (lowercaseValue === "1" || lowercaseValue === "true") {
|
|
1621
|
-
return true;
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
return Boolean(value);
|
|
1625
|
-
}
|
|
1626
|
-
case TypeEnum.Number: {
|
|
1627
|
-
const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
|
|
1628
|
-
const num = Number(cleaned);
|
|
1629
|
-
return Number.isNaN(num) ? null : num;
|
|
1630
|
-
}
|
|
1631
|
-
case TypeEnum.String:
|
|
1632
|
-
case TypeEnum.Ref:
|
|
1633
|
-
return String(value);
|
|
1634
|
-
default: {
|
|
1635
|
-
return value;
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
};
|
|
1639
|
-
if (!format) {
|
|
1640
|
-
return parseScalar(type);
|
|
1641
|
-
}
|
|
1642
|
-
switch (format) {
|
|
1643
|
-
case FormatEnum3.Boolean:
|
|
1644
|
-
return parseScalar(TypeEnum.Boolean);
|
|
1645
|
-
case FormatEnum3.Number:
|
|
1646
|
-
case FormatEnum3.Percent:
|
|
1647
|
-
case FormatEnum3.Currency:
|
|
1648
|
-
return parseScalar(TypeEnum.Number);
|
|
1649
|
-
case FormatEnum3.String:
|
|
1650
|
-
case FormatEnum3.Markdown: {
|
|
1651
|
-
return parseScalar(TypeEnum.String);
|
|
1652
|
-
}
|
|
1653
|
-
case FormatEnum3.Ref:
|
|
1654
|
-
throw new Error(`unexpected format: ${FormatEnum3.Ref}`);
|
|
1655
|
-
case FormatEnum3.DateTime:
|
|
1656
|
-
case FormatEnum3.Date:
|
|
1657
|
-
case FormatEnum3.Time:
|
|
1658
|
-
case FormatEnum3.Timestamp: {
|
|
1659
|
-
const date = new Date(value);
|
|
1660
|
-
return isNaN(date.getTime()) ? null : date;
|
|
1661
|
-
}
|
|
1662
|
-
case FormatEnum3.GeoPoint: {
|
|
1663
|
-
if (typeof value === "string") {
|
|
1664
|
-
const cleaned = value.replace(/[^0-9.,-]+/g, "");
|
|
1665
|
-
const parts = cleaned.split(",");
|
|
1666
|
-
if (parts.length === 2) {
|
|
1667
|
-
const lat = parseFloat(parts[0]);
|
|
1668
|
-
const long = parseFloat(parts[1]);
|
|
1669
|
-
if (!isNaN(lat) && !isNaN(long)) {
|
|
1670
|
-
return GeoLocation2.toGeoPoint({
|
|
1671
|
-
latitude: lat,
|
|
1672
|
-
longitude: long
|
|
1673
|
-
});
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
return [
|
|
1678
|
-
0,
|
|
1679
|
-
0
|
|
1680
|
-
];
|
|
1681
|
-
}
|
|
1682
|
-
default: {
|
|
1683
|
-
return value;
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
};
|
|
1687
|
-
var cellClassesForFieldType = ({ type, format }) => {
|
|
1688
|
-
if (!format) {
|
|
1689
|
-
switch (type) {
|
|
1690
|
-
case TypeEnum.Number:
|
|
1691
|
-
return [
|
|
1692
|
-
"text-right",
|
|
1693
|
-
"font-mono"
|
|
1694
|
-
];
|
|
1695
|
-
case TypeEnum.Boolean:
|
|
1696
|
-
return [
|
|
1697
|
-
"text-right",
|
|
1698
|
-
"font-mono"
|
|
1699
|
-
];
|
|
1700
|
-
case TypeEnum.String:
|
|
1701
|
-
return void 0;
|
|
1702
|
-
case TypeEnum.Ref:
|
|
1703
|
-
return void 0;
|
|
1704
|
-
default: {
|
|
1705
|
-
return void 0;
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
switch (format) {
|
|
1710
|
-
case FormatEnum3.Markdown:
|
|
1711
|
-
return void 0;
|
|
1712
|
-
case FormatEnum3.Time:
|
|
1713
|
-
case FormatEnum3.Timestamp:
|
|
1714
|
-
case FormatEnum3.DateTime:
|
|
1715
|
-
case FormatEnum3.Date:
|
|
1716
|
-
case FormatEnum3.Duration:
|
|
1717
|
-
return [
|
|
1718
|
-
"font-mono",
|
|
1719
|
-
"text-right"
|
|
1720
|
-
];
|
|
1721
|
-
case FormatEnum3.Currency:
|
|
1722
|
-
return [
|
|
1723
|
-
"text-right"
|
|
1724
|
-
];
|
|
1725
|
-
case FormatEnum3.JSON:
|
|
1726
|
-
case FormatEnum3.DID:
|
|
1727
|
-
return [
|
|
1728
|
-
"font-mono"
|
|
1729
|
-
];
|
|
1730
|
-
default:
|
|
1731
|
-
return void 0;
|
|
1732
|
-
}
|
|
1733
|
-
};
|
|
1734
|
-
var pathNotUniqueError = (path) => ({
|
|
1735
|
-
path: "path",
|
|
1736
|
-
message: `'${path}' is already present`
|
|
1737
|
-
});
|
|
1738
|
-
|
|
1739
|
-
// packages/ui/react-ui-form/src/util/formatting.ts
|
|
1740
|
-
import { format as formatDate } from "date-fns/format";
|
|
1741
|
-
import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
1742
|
-
var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
|
|
1743
|
-
const formatScalar = (type2) => {
|
|
1744
|
-
switch (type2) {
|
|
1745
|
-
case TypeEnum2.Boolean:
|
|
1746
|
-
return value.toLocaleString().toUpperCase();
|
|
1747
|
-
case TypeEnum2.Number:
|
|
1748
|
-
return value.toLocaleString(locale);
|
|
1749
|
-
case TypeEnum2.String:
|
|
1750
|
-
case TypeEnum2.Ref:
|
|
1751
|
-
return String(value);
|
|
1752
|
-
default: {
|
|
1753
|
-
return String(value);
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
};
|
|
1757
|
-
if (!format) {
|
|
1758
|
-
return formatScalar(type);
|
|
1759
|
-
}
|
|
1760
|
-
switch (format) {
|
|
1761
|
-
case FormatEnum4.Boolean: {
|
|
1762
|
-
return formatScalar(TypeEnum2.Boolean);
|
|
1763
|
-
}
|
|
1764
|
-
case FormatEnum4.Number: {
|
|
1765
|
-
return formatScalar(TypeEnum2.Number);
|
|
1766
|
-
}
|
|
1767
|
-
case FormatEnum4.String:
|
|
1768
|
-
case FormatEnum4.Ref: {
|
|
1769
|
-
return formatScalar(TypeEnum2.String);
|
|
1770
|
-
}
|
|
1771
|
-
case FormatEnum4.Percent: {
|
|
1772
|
-
return `${value * 100}%`;
|
|
1773
|
-
}
|
|
1774
|
-
case FormatEnum4.Currency: {
|
|
1775
|
-
return value.toLocaleString(locale, {
|
|
1776
|
-
style: "currency",
|
|
1777
|
-
currency: "USD",
|
|
1778
|
-
minimumFractionDigits: 2,
|
|
1779
|
-
maximumFractionDigits: 2
|
|
1780
|
-
});
|
|
1781
|
-
}
|
|
1782
|
-
case FormatEnum4.Date: {
|
|
1783
|
-
return formatDate(new Date(value), "yyyy-MM-dd");
|
|
1784
|
-
}
|
|
1785
|
-
case FormatEnum4.Time: {
|
|
1786
|
-
return formatDate(new Date(value), "HH:mm:ss");
|
|
1787
|
-
}
|
|
1788
|
-
case FormatEnum4.DateTime: {
|
|
1789
|
-
return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
|
|
1790
|
-
}
|
|
1791
|
-
case FormatEnum4.GeoPoint: {
|
|
1792
|
-
if (value === null || value === void 0) {
|
|
1793
|
-
return "";
|
|
1794
|
-
}
|
|
1795
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1796
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1797
|
-
return `${latitude},${longitude}`;
|
|
1798
|
-
}
|
|
1799
|
-
return String(value);
|
|
1800
|
-
}
|
|
1801
|
-
default: {
|
|
1802
|
-
if (value === null || value === "undefined") {
|
|
1803
|
-
return "";
|
|
1804
|
-
}
|
|
1805
|
-
return String(value);
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
};
|
|
1809
|
-
var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
1810
|
-
const formatScalar = (type2) => {
|
|
1811
|
-
switch (type2) {
|
|
1812
|
-
case TypeEnum2.Boolean:
|
|
1813
|
-
case TypeEnum2.Number:
|
|
1814
|
-
case TypeEnum2.String:
|
|
1815
|
-
case TypeEnum2.Ref:
|
|
1816
|
-
return String(value);
|
|
1817
|
-
default:
|
|
1818
|
-
return String(value);
|
|
1819
|
-
}
|
|
1820
|
-
};
|
|
1821
|
-
if (!format) {
|
|
1822
|
-
return formatScalar(type);
|
|
1823
|
-
}
|
|
1824
|
-
switch (format) {
|
|
1825
|
-
case FormatEnum4.Boolean:
|
|
1826
|
-
case FormatEnum4.Number:
|
|
1827
|
-
case FormatEnum4.String:
|
|
1828
|
-
case FormatEnum4.Ref: {
|
|
1829
|
-
return formatScalar(type);
|
|
1830
|
-
}
|
|
1831
|
-
case FormatEnum4.Percent: {
|
|
1832
|
-
return String(value * 100);
|
|
1833
|
-
}
|
|
1834
|
-
case FormatEnum4.Currency: {
|
|
1835
|
-
return String(value);
|
|
1836
|
-
}
|
|
1837
|
-
case FormatEnum4.DateTime: {
|
|
1838
|
-
const date = new Date(value);
|
|
1839
|
-
return date.toISOString();
|
|
1840
|
-
}
|
|
1841
|
-
case FormatEnum4.Date: {
|
|
1842
|
-
const date = new Date(value);
|
|
1843
|
-
return date.toISOString().split("T")[0];
|
|
1844
|
-
}
|
|
1845
|
-
case FormatEnum4.Time: {
|
|
1846
|
-
const date = new Date(value);
|
|
1847
|
-
return date.toISOString().split("T")[1].split(".")[0];
|
|
1848
|
-
}
|
|
1849
|
-
case FormatEnum4.GeoPoint: {
|
|
1850
|
-
if (value === null || value === void 0) {
|
|
1851
|
-
return "";
|
|
1852
|
-
}
|
|
1853
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1854
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1855
|
-
return `${latitude},${longitude}`;
|
|
1856
|
-
}
|
|
1857
|
-
return String(value);
|
|
1858
|
-
}
|
|
1859
|
-
default: {
|
|
1860
|
-
return String(value);
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1864
2159
|
export {
|
|
1865
2160
|
BooleanInput,
|
|
1866
2161
|
ControlFrame,
|
|
@@ -1888,14 +2183,18 @@ export {
|
|
|
1888
2183
|
ViewEditor,
|
|
1889
2184
|
cellClassesForFieldType,
|
|
1890
2185
|
controlItemClasses,
|
|
2186
|
+
findArrayElementType,
|
|
1891
2187
|
formatForDisplay,
|
|
1892
2188
|
formatForEditing,
|
|
2189
|
+
getRefProps,
|
|
1893
2190
|
parseValue,
|
|
1894
2191
|
pathNotUniqueError,
|
|
1895
2192
|
translations_default as translations,
|
|
1896
2193
|
useForm,
|
|
1897
2194
|
useFormContext,
|
|
1898
2195
|
useFormValues,
|
|
1899
|
-
useInputProps
|
|
2196
|
+
useInputProps,
|
|
2197
|
+
useQueryRefOptions,
|
|
2198
|
+
useRefQueryLookupHandler
|
|
1900
2199
|
};
|
|
1901
2200
|
//# sourceMappingURL=index.mjs.map
|