@luomus/laji-form 15.1.47 → 15.1.49
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.
|
@@ -81,7 +81,10 @@ class _SchemaField extends React.Component {
|
|
|
81
81
|
const props = this.functionOutputProps || this.props;
|
|
82
82
|
let { schema, uiSchema = {}, formContext, registry } = props, _props = __rest(props, ["schema", "uiSchema", "formContext", "registry"]); // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
83
83
|
const { formContext: _formContext } = registry;
|
|
84
|
-
if
|
|
84
|
+
// rjsf displays a duplicate label if 'uniqueItems' is true in some cases. We prevent that here.
|
|
85
|
+
// Example of when it shows duplicate is http://localhost:8083/?id=JX.652&local=true, "Elinympäristö" on gathering
|
|
86
|
+
// level.
|
|
87
|
+
if (props.schema.type === "array" && props.uiSchema && props.uiSchema.items && props.uiSchema.items["ui:field"]) {
|
|
85
88
|
schema = Object.assign(Object.assign({}, schema), { uniqueItems: false });
|
|
86
89
|
}
|
|
87
90
|
const options = utils_1.getUiOptions(uiSchema);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { FieldProps, JSONSchemaEnum } from "../../types";
|
|
1
3
|
/**
|
|
2
4
|
* Constructs selects from given tree.
|
|
3
5
|
* uiSchema = {"ui:options": {
|
|
@@ -5,35 +7,4 @@
|
|
|
5
7
|
* labels: [<string>]
|
|
6
8
|
* }
|
|
7
9
|
*/
|
|
8
|
-
export default
|
|
9
|
-
static propTypes: {
|
|
10
|
-
uiSchema: PropTypes.Validator<PropTypes.InferProps<{
|
|
11
|
-
"ui:options": PropTypes.Validator<PropTypes.InferProps<{
|
|
12
|
-
tree: PropTypes.Validator<object>;
|
|
13
|
-
labels: PropTypes.Requireable<(string | null | undefined)[]>;
|
|
14
|
-
uiSchema: PropTypes.Requireable<object>;
|
|
15
|
-
}>>;
|
|
16
|
-
}>>;
|
|
17
|
-
schema: PropTypes.Validator<PropTypes.InferProps<{
|
|
18
|
-
type: PropTypes.Requireable<string>;
|
|
19
|
-
}>>;
|
|
20
|
-
value: PropTypes.Requireable<string>;
|
|
21
|
-
};
|
|
22
|
-
constructor(props: any);
|
|
23
|
-
constructor(props: any, context: any);
|
|
24
|
-
getStateFromProps(props: any): {
|
|
25
|
-
schema: {
|
|
26
|
-
type: string;
|
|
27
|
-
title: any;
|
|
28
|
-
};
|
|
29
|
-
formData: {};
|
|
30
|
-
uiSchema: any;
|
|
31
|
-
idSchema: {
|
|
32
|
-
$id: any;
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
onChange: (formData: any) => void;
|
|
36
|
-
onKeyDown: (e: any) => void;
|
|
37
|
-
}
|
|
38
|
-
import * as React from "react";
|
|
39
|
-
import * as PropTypes from "prop-types";
|
|
10
|
+
export default function SelectTreeField(props: FieldProps<JSONSchemaEnum>): JSX.Element;
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
3
|
const React = require("react");
|
|
10
|
-
const PropTypes = require("prop-types");
|
|
11
4
|
const utils_1 = require("../../utils");
|
|
12
|
-
const
|
|
5
|
+
const react_1 = require("react");
|
|
13
6
|
/**
|
|
14
7
|
* Constructs selects from given tree.
|
|
15
8
|
* uiSchema = {"ui:options": {
|
|
@@ -17,127 +10,97 @@ const BaseComponent_1 = require("../BaseComponent");
|
|
|
17
10
|
* labels: [<string>]
|
|
18
11
|
* }
|
|
19
12
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
else {
|
|
32
|
-
value = formData[i];
|
|
33
|
-
}
|
|
34
|
-
this.props.onChange(value);
|
|
35
|
-
break;
|
|
13
|
+
function SelectTreeField(props) {
|
|
14
|
+
const childProps = getChildProps(props);
|
|
15
|
+
const { onChange: parentOnChange } = props;
|
|
16
|
+
const { formData: childFormData } = childProps;
|
|
17
|
+
const onChange = react_1.useCallback((formData) => {
|
|
18
|
+
let selectNames = Object.keys(formData).sort((a, b) => { return +b - +a; });
|
|
19
|
+
for (let i in selectNames) {
|
|
20
|
+
if (formData[i] !== childFormData[i]) {
|
|
21
|
+
let value;
|
|
22
|
+
if (utils_1.isEmptyString(formData[i])) {
|
|
23
|
+
value = (+i > 0) ? formData[+i - 1] : undefined;
|
|
36
24
|
}
|
|
25
|
+
else {
|
|
26
|
+
value = formData[i];
|
|
27
|
+
}
|
|
28
|
+
parentOnChange(value);
|
|
29
|
+
break;
|
|
37
30
|
}
|
|
38
|
-
};
|
|
39
|
-
this.onKeyDown = (e) => {
|
|
40
|
-
if (e.key == "Enter" && !e.ctrlKey) {
|
|
41
|
-
e.preventDefault();
|
|
42
|
-
e.stopPropagation();
|
|
43
|
-
this.props.formContext.setTimeout(() => {
|
|
44
|
-
this.props.formContext.services.focus.focusNextInput(e.shiftKey);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
getStateFromProps(props) {
|
|
50
|
-
let schema = { "type": "object", title: props.schema.title };
|
|
51
|
-
let { uiSchema } = props;
|
|
52
|
-
uiSchema = utils_1.getInnerUiSchema(props.uiSchema);
|
|
53
|
-
let formData = {};
|
|
54
|
-
let idSchema = { $id: props.idSchema.$id };
|
|
55
|
-
let dictionarifiedEnums = {};
|
|
56
|
-
props.schema.oneOf.forEach(e => {
|
|
57
|
-
dictionarifiedEnums[e.const] = e.title;
|
|
58
|
-
});
|
|
59
|
-
let { tree, labels } = utils_1.getUiOptions(props.uiSchema);
|
|
60
|
-
let levels = [];
|
|
61
|
-
let parentsMap = {};
|
|
62
|
-
let childrenMap = {};
|
|
63
|
-
let orderMap = {};
|
|
64
|
-
function getLevels(tree, depth, root) {
|
|
65
|
-
childrenMap[root] = {};
|
|
66
|
-
if (tree.children)
|
|
67
|
-
Object.keys(tree.children).forEach(key => {
|
|
68
|
-
if (!levels[depth])
|
|
69
|
-
levels[depth] = {};
|
|
70
|
-
levels[depth][key] = true;
|
|
71
|
-
parentsMap[key] = root;
|
|
72
|
-
childrenMap[root][key] = true;
|
|
73
|
-
getLevels(tree.children[key], depth + 1, key);
|
|
74
|
-
});
|
|
75
|
-
if (tree.order)
|
|
76
|
-
orderMap[root] = tree.order;
|
|
77
31
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
32
|
+
}, [childFormData, parentOnChange]);
|
|
33
|
+
const SchemaField = props.registry.fields.SchemaField;
|
|
34
|
+
return React.createElement(SchemaField, Object.assign({}, props, childProps, { onChange: onChange }));
|
|
35
|
+
}
|
|
36
|
+
exports.default = SelectTreeField;
|
|
37
|
+
const getChildProps = (props) => {
|
|
38
|
+
let schema = { "type": "object", title: props.schema.title };
|
|
39
|
+
let formData = {};
|
|
40
|
+
let idSchema = { $id: props.idSchema.$id };
|
|
41
|
+
let dictionarifiedEnums = {};
|
|
42
|
+
props.schema.oneOf.forEach(e => {
|
|
43
|
+
dictionarifiedEnums[e.const] = e.title;
|
|
44
|
+
});
|
|
45
|
+
const tree = utils_1.getUiOptions(props.uiSchema).tree;
|
|
46
|
+
let levels = [];
|
|
47
|
+
let parentsMap = {};
|
|
48
|
+
let childrenMap = {};
|
|
49
|
+
let orderMap = {};
|
|
50
|
+
function getLevels(tree, depth, root) {
|
|
51
|
+
childrenMap[root] = {};
|
|
52
|
+
if (!tree.children) {
|
|
53
|
+
return;
|
|
94
54
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
55
|
+
Object.keys(tree.children).forEach(key => {
|
|
56
|
+
if (!levels[depth])
|
|
57
|
+
levels[depth] = {};
|
|
58
|
+
levels[depth][key] = true;
|
|
59
|
+
parentsMap[key] = root;
|
|
60
|
+
childrenMap[root][key] = true;
|
|
61
|
+
getLevels(tree.children[key], depth + 1, key);
|
|
62
|
+
});
|
|
63
|
+
orderMap[root] = tree.order;
|
|
64
|
+
}
|
|
65
|
+
getLevels(tree, 0);
|
|
66
|
+
let properties = {};
|
|
67
|
+
function addSelect(depth, key, childrenKeys) {
|
|
68
|
+
let select = { type: "string", oneOf: [{ const: "", title: "" }] };
|
|
69
|
+
let order = orderMap[key];
|
|
70
|
+
if (order) {
|
|
71
|
+
childrenKeys.sort((a, b) => { return order.indexOf(a) - order.indexOf(b); });
|
|
72
|
+
}
|
|
73
|
+
childrenKeys.forEach(key => {
|
|
74
|
+
select.oneOf.push({ const: key, title: dictionarifiedEnums[key] });
|
|
75
|
+
});
|
|
76
|
+
select.title = "";
|
|
77
|
+
properties[depth] = select;
|
|
78
|
+
idSchema[depth] = { $id: idSchema.$id + "_" + depth };
|
|
79
|
+
}
|
|
80
|
+
let searchTerm = props.formData;
|
|
81
|
+
let depth = 0;
|
|
82
|
+
if (!utils_1.isEmptyString(searchTerm)) {
|
|
83
|
+
for (const level of levels) {
|
|
84
|
+
if (level[searchTerm])
|
|
85
|
+
break;
|
|
86
|
+
depth++;
|
|
113
87
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
88
|
+
}
|
|
89
|
+
let n = searchTerm;
|
|
90
|
+
let d = depth;
|
|
91
|
+
while (d >= 0) {
|
|
92
|
+
formData[d] = n;
|
|
93
|
+
if (utils_1.isEmptyString(n)) {
|
|
94
|
+
n = undefined; //object keys can't be "", so root key is in childrenMap 'undefined'.
|
|
117
95
|
}
|
|
118
|
-
|
|
119
|
-
|
|
96
|
+
addSelect(d, n, Object.keys(childrenMap[parentsMap[n]]));
|
|
97
|
+
d--;
|
|
98
|
+
n = parentsMap[n];
|
|
120
99
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
React.createElement(SchemaField, Object.assign({}, this.props, this.state, { onChange: this.onChange }))));
|
|
100
|
+
if (!utils_1.isEmptyString(searchTerm) && childrenMap[searchTerm] && Object.keys(childrenMap[searchTerm]).length) {
|
|
101
|
+
addSelect(depth + 1, searchTerm, Object.keys(childrenMap[searchTerm]));
|
|
102
|
+
formData[depth + 1] = undefined;
|
|
125
103
|
}
|
|
104
|
+
schema.properties = properties;
|
|
105
|
+
return { schema, formData, uiSchema: utils_1.getInnerUiSchema(props.uiSchema), idSchema };
|
|
126
106
|
};
|
|
127
|
-
SelectTreeField.propTypes = {
|
|
128
|
-
uiSchema: PropTypes.shape({
|
|
129
|
-
"ui:options": PropTypes.shape({
|
|
130
|
-
tree: PropTypes.object.isRequired,
|
|
131
|
-
labels: PropTypes.arrayOf(PropTypes.string),
|
|
132
|
-
uiSchema: PropTypes.object
|
|
133
|
-
}).isRequired
|
|
134
|
-
}).isRequired,
|
|
135
|
-
schema: PropTypes.shape({
|
|
136
|
-
type: PropTypes.oneOf(["string"])
|
|
137
|
-
}).isRequired,
|
|
138
|
-
value: PropTypes.string
|
|
139
|
-
};
|
|
140
|
-
SelectTreeField = __decorate([
|
|
141
|
-
BaseComponent_1.default
|
|
142
|
-
], SelectTreeField);
|
|
143
|
-
exports.default = SelectTreeField;
|
|
@@ -55,17 +55,18 @@ function SelectWidget(props) {
|
|
|
55
55
|
exports.default = SelectWidget;
|
|
56
56
|
function SearchableDrowndown(props) {
|
|
57
57
|
const { id, disabled, readonly, value, uiSchema, options, onChange, includeEmpty = true } = props;
|
|
58
|
-
const { theme } =
|
|
59
|
-
const containerRef =
|
|
60
|
-
const inputRef =
|
|
61
|
-
const dropdownRef =
|
|
62
|
-
const enumOptions =
|
|
58
|
+
const { theme } = react_1.useContext(ReactContext_1.default);
|
|
59
|
+
const containerRef = react_1.useRef(null);
|
|
60
|
+
const inputRef = react_1.useRef(null);
|
|
61
|
+
const dropdownRef = react_1.useRef(null);
|
|
62
|
+
const enumOptions = react_1.useMemo(() =>
|
|
63
63
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
64
64
|
getEnumOptions(options.enumOptions, uiSchema, includeEmpty), [options.enumOptions, uiSchema, includeEmpty]);
|
|
65
|
-
const
|
|
65
|
+
const getLabelFromValue = react_1.useCallback((value) => value !== undefined
|
|
66
66
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
67
67
|
? enumOptions.find(item => item.value === value).label
|
|
68
|
-
: "");
|
|
68
|
+
: "", [enumOptions]);
|
|
69
|
+
const [inputValue, setInputValue] = react_1.useState(getLabelFromValue(value));
|
|
69
70
|
const [inputTouched, setInputTouched] = react_1.useState(false);
|
|
70
71
|
const [filterTerm, setFilterTerm] = react_1.useState("");
|
|
71
72
|
const onInputChange = react_1.useCallback((e) => {
|
|
@@ -73,10 +74,17 @@ function SearchableDrowndown(props) {
|
|
|
73
74
|
setInputValue(value);
|
|
74
75
|
setInputTouched(true);
|
|
75
76
|
}, []);
|
|
76
|
-
|
|
77
|
+
react_1.useEffect(() => {
|
|
77
78
|
inputTouched && setFilterTerm(inputValue);
|
|
78
79
|
}, [inputTouched, inputValue]);
|
|
79
|
-
|
|
80
|
+
// Sync inputValue if value changes.
|
|
81
|
+
react_1.useEffect(() => {
|
|
82
|
+
if (inputTouched) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
setInputValue(getLabelFromValue(value));
|
|
86
|
+
}, [inputTouched, value, enumOptions, getLabelFromValue]);
|
|
87
|
+
const displayedEnums = react_1.useMemo(() => {
|
|
80
88
|
return filterTerm !== ""
|
|
81
89
|
? enumOptions.filter(({ label }) => label.toLowerCase().match(filterTerm.toLowerCase()))
|
|
82
90
|
: enumOptions;
|
|
@@ -86,7 +94,6 @@ function SearchableDrowndown(props) {
|
|
|
86
94
|
const [activeIdx, activeIdxUp, activeIdxDown, setActiveIdx] = useRangeIncrementor((displayedEnums || []).length, getDefaultActiveIdx(displayedEnums, value));
|
|
87
95
|
const onItemSelected = react_1.useCallback((item) => {
|
|
88
96
|
onChange(item.value);
|
|
89
|
-
setInputValue(item.label);
|
|
90
97
|
setInputTouched(false);
|
|
91
98
|
setActiveIdx(displayedEnums.findIndex(enu => enu.value === item.value));
|
|
92
99
|
hide();
|
|
@@ -179,13 +186,11 @@ function SearchableMultiDrowndown(props) {
|
|
|
179
186
|
const onItemSelected = react_1.useCallback((item) => {
|
|
180
187
|
var _a;
|
|
181
188
|
onChange([...(value || []), item.value]);
|
|
182
|
-
setInputValue("");
|
|
183
189
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
184
190
|
setActiveIdx(undefined);
|
|
185
191
|
}, [onChange, setActiveIdx, value]);
|
|
186
192
|
const onItemSelectedByBlur = react_1.useCallback((item) => {
|
|
187
193
|
onChange([...(value || []), item.value]);
|
|
188
|
-
setInputValue("");
|
|
189
194
|
setActiveIdx(undefined);
|
|
190
195
|
}, [onChange, setActiveIdx, value]);
|
|
191
196
|
const [isFocused, setFocused, setBlurred] = utils_1.useBooleanSetter(false);
|