@gisce/react-ooui 1.2.0-rc.4 → 1.2.0-rc.41
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/actionbar/FormActionBar.d.ts.map +1 -1
- package/dist/actionbar/TreeActionBar.d.ts.map +1 -1
- package/dist/context/ActionViewContext.d.ts +5 -1
- package/dist/context/ActionViewContext.d.ts.map +1 -1
- package/dist/context/ContentRootContext.d.ts.map +1 -1
- package/dist/context/FormContext.d.ts +4 -1
- package/dist/context/FormContext.d.ts.map +1 -1
- package/dist/helpers/formHelper.d.ts +5 -3
- package/dist/helpers/formHelper.d.ts.map +1 -1
- package/dist/helpers/iconMapper.d.ts +5 -1
- package/dist/helpers/iconMapper.d.ts.map +1 -1
- package/dist/helpers/one2manyHelper.d.ts +2 -1
- package/dist/helpers/one2manyHelper.d.ts.map +1 -1
- package/dist/helpers/treeHelper.d.ts +1 -1
- package/dist/helpers/treeHelper.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/locales/ca_ES.d.ts +4 -0
- package/dist/locales/ca_ES.d.ts.map +1 -1
- package/dist/locales/en_US.d.ts +4 -0
- package/dist/locales/en_US.d.ts.map +1 -1
- package/dist/locales/es_ES.d.ts +4 -0
- package/dist/locales/es_ES.d.ts.map +1 -1
- package/dist/react-ooui.es.js +16980 -18378
- package/dist/react-ooui.es.js.map +1 -1
- package/dist/react-ooui.umd.js +78 -51
- package/dist/react-ooui.umd.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/views/ActionView.d.ts.map +1 -1
- package/dist/views/RootView.d.ts.map +1 -1
- package/dist/views/actionViews/TreeActionView.d.ts.map +1 -1
- package/dist/widgets/WidgetFactory.d.ts.map +1 -1
- package/dist/widgets/base/Integer.d.ts.map +1 -1
- package/dist/widgets/base/Label.d.ts.map +1 -1
- package/dist/widgets/base/ReferenceTree.d.ts +8 -0
- package/dist/widgets/base/ReferenceTree.d.ts.map +1 -0
- package/dist/widgets/base/many2one/Many2one.d.ts.map +1 -1
- package/dist/widgets/base/many2one/Many2oneTree.d.ts +6 -0
- package/dist/widgets/base/many2one/Many2oneTree.d.ts.map +1 -0
- package/dist/widgets/base/one2many/One2manyInput.d.ts.map +1 -1
- package/dist/widgets/custom/MultiCheckbox.d.ts.map +1 -1
- package/dist/widgets/custom/Tag.d.ts +5 -0
- package/dist/widgets/custom/Tag.d.ts.map +1 -0
- package/dist/widgets/custom/Tags.d.ts.map +1 -1
- package/dist/widgets/modals/ExportModal.d.ts +2 -2
- package/dist/widgets/modals/ExportModal.d.ts.map +1 -1
- package/dist/widgets/views/Dashboard/Dashboard.d.ts.map +1 -1
- package/dist/widgets/views/Dashboard/DashboardTree.d.ts.map +1 -1
- package/dist/widgets/views/Form.d.ts.map +1 -1
- package/dist/widgets/views/SearchTree.d.ts.map +1 -1
- package/dist/widgets/views/Tree.d.ts +2 -0
- package/dist/widgets/views/Tree.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/__tests__/iconMapper.test.ts +20 -5
- package/src/actionbar/ChangeViewButton.tsx +2 -2
- package/src/actionbar/FormActionBar.tsx +94 -11
- package/src/actionbar/TreeActionBar.tsx +86 -69
- package/src/context/ActionViewContext.tsx +7 -4
- package/src/context/ContentRootContext.tsx +15 -7
- package/src/context/FormContext.tsx +1 -1
- package/src/helpers/formHelper.ts +26 -5
- package/src/helpers/iconMapper.ts +134 -107
- package/src/helpers/one2manyHelper.ts +27 -9
- package/src/helpers/treeHelper.ts +17 -5
- package/src/index.ts +2 -0
- package/src/locales/ca_ES.tsx +4 -0
- package/src/locales/en_US.tsx +4 -0
- package/src/locales/es_ES.tsx +4 -0
- package/src/stories/Label.stories.tsx +7 -8
- package/src/stories/containers/Notebook.stories.tsx +27 -0
- package/src/stories/custom/Tag.stories.tsx +57 -0
- package/src/stories/mocks/models/crm_case.ts +7 -10
- package/src/stories/views/Tree.stories.jsx +5 -5
- package/src/types/index.ts +1 -0
- package/src/views/ActionView.tsx +15 -4
- package/src/views/RootView.tsx +7 -1
- package/src/views/actionViews/TreeActionView.tsx +10 -1
- package/src/widgets/WidgetFactory.tsx +3 -0
- package/src/widgets/base/Integer.tsx +1 -0
- package/src/widgets/base/Label.tsx +5 -9
- package/src/widgets/base/ReferenceTree.tsx +62 -0
- package/src/widgets/base/many2one/Many2one.tsx +8 -9
- package/src/widgets/base/many2one/Many2oneTree.tsx +18 -0
- package/src/widgets/base/one2many/One2manyInput.tsx +2 -0
- package/src/widgets/containers/Group.tsx +3 -3
- package/src/widgets/custom/ButtonGroup.tsx +1 -1
- package/src/widgets/custom/MultiCheckbox.tsx +1 -0
- package/src/widgets/custom/Tag.tsx +24 -0
- package/src/widgets/custom/Tags.tsx +27 -28
- package/src/widgets/modals/ExportModal.tsx +53 -15
- package/src/widgets/views/Dashboard/Dashboard.tsx +5 -1
- package/src/widgets/views/Dashboard/DashboardTree.tsx +1 -0
- package/src/widgets/views/Form.tsx +35 -24
- package/src/widgets/views/SearchTree.tsx +2 -0
- package/src/widgets/views/Tree.tsx +88 -25
- package/dist/helpers/icons/antd_icons.d.ts +0 -4
- package/dist/helpers/icons/antd_icons.d.ts.map +0 -1
- package/dist/helpers/icons/tabler_icons.d.ts +0 -4
- package/dist/helpers/icons/tabler_icons.d.ts.map +0 -1
- package/dist/ui/Fieldset.d.ts +0 -8
- package/dist/ui/Fieldset.d.ts.map +0 -1
- package/src/helpers/icons/antd_icons.ts +0 -1583
- package/src/helpers/icons/tabler_icons.ts +0 -5367
- package/src/ui/Fieldset.tsx +0 -31
|
@@ -132,13 +132,12 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
|
|
|
132
132
|
if (transformedDomain.current && transformedDomain.current.length > 0) {
|
|
133
133
|
tryFetchFirstResultOrShowSearch(inputTextRef.current as string);
|
|
134
134
|
} else {
|
|
135
|
-
const results: any[] =
|
|
136
|
-
{
|
|
135
|
+
const results: any[] =
|
|
136
|
+
await ConnectionProvider.getHandler().nameSearch({
|
|
137
137
|
model: relation,
|
|
138
138
|
payload: inputTextRef.current as string,
|
|
139
139
|
context: { ...getContext?.(), ...context },
|
|
140
|
-
}
|
|
141
|
-
);
|
|
140
|
+
});
|
|
142
141
|
|
|
143
142
|
if (results.length === 1) {
|
|
144
143
|
inputTextRef.current = undefined;
|
|
@@ -207,16 +206,16 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
|
|
|
207
206
|
|
|
208
207
|
async function parseDomain() {
|
|
209
208
|
if (widgetDomain) {
|
|
210
|
-
transformedDomain.current =
|
|
211
|
-
{
|
|
209
|
+
transformedDomain.current =
|
|
210
|
+
await ConnectionProvider.getHandler().evalDomain({
|
|
212
211
|
domain: widgetDomain,
|
|
213
212
|
values: transformPlainMany2Ones({
|
|
214
213
|
fields: getFields(),
|
|
215
214
|
values: getValues(),
|
|
216
215
|
}),
|
|
216
|
+
fields: getFields(),
|
|
217
217
|
context: getContext(),
|
|
218
|
-
}
|
|
219
|
-
);
|
|
218
|
+
});
|
|
220
219
|
}
|
|
221
220
|
|
|
222
221
|
if (domain && domain.length > 0) {
|
|
@@ -232,7 +231,7 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
|
|
|
232
231
|
}
|
|
233
232
|
|
|
234
233
|
async function onKeyDown(event: any) {
|
|
235
|
-
if (event.
|
|
234
|
+
if (event.keyCode === 13) {
|
|
236
235
|
event.preventDefault();
|
|
237
236
|
event.stopPropagation();
|
|
238
237
|
await onElementLostFocus();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Space } from "antd";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Many2oneSuffix } from "./Many2oneSuffix";
|
|
4
|
+
|
|
5
|
+
export type Many2oneTreeProps = { m2oField: any };
|
|
6
|
+
|
|
7
|
+
export const Many2oneTree = (props: Many2oneTreeProps): React.ReactElement => {
|
|
8
|
+
const { m2oField } = props;
|
|
9
|
+
if (!m2oField) {
|
|
10
|
+
return <></>;
|
|
11
|
+
}
|
|
12
|
+
return (
|
|
13
|
+
<Space>
|
|
14
|
+
<>{m2oField.value}</>
|
|
15
|
+
<Many2oneSuffix id={m2oField.id} model={m2oField.model} />
|
|
16
|
+
</Space>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
@@ -168,6 +168,7 @@ const One2manyInput: React.FC<One2manyInputProps> = (
|
|
|
168
168
|
fields: getFields(),
|
|
169
169
|
values: getValues(),
|
|
170
170
|
}),
|
|
171
|
+
fields: getFields(),
|
|
171
172
|
context: getContext(),
|
|
172
173
|
}),
|
|
173
174
|
widgetFieldName: fieldName,
|
|
@@ -573,6 +574,7 @@ const One2manyInput: React.FC<One2manyInputProps> = (
|
|
|
573
574
|
}}
|
|
574
575
|
sorter={sorter}
|
|
575
576
|
onChangeSort={setSorter}
|
|
577
|
+
context={{ ...getContext?.(), ...context }}
|
|
576
578
|
/>
|
|
577
579
|
);
|
|
578
580
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Group as GroupOoui } from "@gisce/ooui";
|
|
3
3
|
import Container from "./Container";
|
|
4
|
-
import
|
|
4
|
+
import { FieldSet } from "@gisce/react-formiga-components";
|
|
5
5
|
|
|
6
6
|
type Props = {
|
|
7
7
|
ooui: GroupOoui;
|
|
@@ -15,12 +15,12 @@ function Group(props: Props): React.ReactElement {
|
|
|
15
15
|
return (
|
|
16
16
|
<>
|
|
17
17
|
{ooui.label && showLabel ? (
|
|
18
|
-
<
|
|
18
|
+
<FieldSet label={ooui.label}>
|
|
19
19
|
<Container
|
|
20
20
|
container={ooui!.container}
|
|
21
21
|
responsiveBehaviour={responsiveBehaviour}
|
|
22
22
|
/>
|
|
23
|
-
</
|
|
23
|
+
</FieldSet>
|
|
24
24
|
) : (
|
|
25
25
|
<Container
|
|
26
26
|
container={ooui!.container}
|
|
@@ -83,7 +83,7 @@ export const ButtonGroup = (props: ButtonGroupProps) => {
|
|
|
83
83
|
type={primary ? "primary" : undefined}
|
|
84
84
|
//danger={danger ? true : undefined} This works but typescript
|
|
85
85
|
// doesn't accept
|
|
86
|
-
overlay={
|
|
86
|
+
overlay={Items({ooui: secondaryButtons})}
|
|
87
87
|
>
|
|
88
88
|
{getButtonIcon()}
|
|
89
89
|
{caption}
|
|
@@ -62,6 +62,7 @@ export const MultiCheckboxInput = (props: MultiCheckboxInputProps) => {
|
|
|
62
62
|
fields: formContext?.getFields(),
|
|
63
63
|
values: formContext.getPlainValues(),
|
|
64
64
|
}),
|
|
65
|
+
fields: formContext?.getFields(),
|
|
65
66
|
context: formContext.getContext(),
|
|
66
67
|
});
|
|
67
68
|
params = [...params, ...evaluatedDomain];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Field from "@/common/Field";
|
|
2
|
+
import { WidgetProps } from "@/types";
|
|
3
|
+
import { Tag as AntdTag } from 'antd';
|
|
4
|
+
import { colorFromString } from "@/helpers/formHelper";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const Tag = (props: WidgetProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<Field {...props}>
|
|
10
|
+
<TagInput {...props}/>
|
|
11
|
+
</Field>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const TagInput = (props) => {
|
|
16
|
+
const {ooui, value} = props;
|
|
17
|
+
if (!value) {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
const color = ooui.colors === "auto" ? colorFromString(value) : ooui.colors[value]
|
|
21
|
+
return (
|
|
22
|
+
<AntdTag color={color}>{ooui.selectionValues.get(value)}</AntdTag>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -23,7 +23,7 @@ export const Tags = (props: TagsProps) => {
|
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<Field type={"array"} {...props}>
|
|
26
|
-
<TagsInput ooui={ooui}
|
|
26
|
+
<TagsInput ooui={ooui} />
|
|
27
27
|
</Field>
|
|
28
28
|
);
|
|
29
29
|
};
|
|
@@ -31,16 +31,15 @@ export const Tags = (props: TagsProps) => {
|
|
|
31
31
|
export const TagsInput = (props: TagsInputProps) => {
|
|
32
32
|
const { value, ooui, onChange } = props;
|
|
33
33
|
const { items = [] } = value || {};
|
|
34
|
-
const itemsToShow = items
|
|
35
|
-
(item) => item.operation !== "pendingRemove"
|
|
36
|
-
|
|
34
|
+
const itemsToShow = items
|
|
35
|
+
.filter((item) => item.operation !== "pendingRemove")
|
|
36
|
+
.map((item) => item.id) as number[];
|
|
37
37
|
|
|
38
38
|
const [options, setOptions] = useState<any[]>([]);
|
|
39
39
|
const [error, setError] = useState<string>();
|
|
40
40
|
const [isLoadingOptions, setIsLoadingOptions] = useState<boolean>(false);
|
|
41
41
|
const { relation, context, readOnly, field } = ooui;
|
|
42
42
|
|
|
43
|
-
|
|
44
43
|
const formContext = useContext(FormContext) as FormContextType;
|
|
45
44
|
const { getContext } = formContext || {};
|
|
46
45
|
|
|
@@ -62,16 +61,16 @@ export const TagsInput = (props: TagsInputProps) => {
|
|
|
62
61
|
params = [["id", "in", itemsToShow]];
|
|
63
62
|
}
|
|
64
63
|
if (ooui.domain) {
|
|
65
|
-
const evaluatedDomain =
|
|
66
|
-
{
|
|
64
|
+
const evaluatedDomain =
|
|
65
|
+
await ConnectionProvider.getHandler().evalDomain({
|
|
67
66
|
domain: ooui.domain,
|
|
68
67
|
values: transformPlainMany2Ones({
|
|
69
68
|
fields: formContext?.getFields(),
|
|
70
69
|
values: formContext.getPlainValues(),
|
|
71
70
|
}),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
fields: formContext?.getFields(),
|
|
72
|
+
context: formContext.getContext(),
|
|
73
|
+
});
|
|
75
74
|
params = [...params, ...evaluatedDomain];
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -81,18 +80,17 @@ export const TagsInput = (props: TagsInputProps) => {
|
|
|
81
80
|
fields: [field],
|
|
82
81
|
context: { ...getContext?.(), ...context },
|
|
83
82
|
});
|
|
84
|
-
const options = optionsRead.map((item:any) => {
|
|
83
|
+
const options = optionsRead.map((item: any) => {
|
|
85
84
|
const value = item[field];
|
|
86
85
|
let formattedValue = value;
|
|
87
86
|
if (Array.isArray(value)) {
|
|
88
87
|
formattedValue = value[1];
|
|
89
88
|
}
|
|
90
|
-
return {label: formattedValue, value: item.id}
|
|
89
|
+
return { label: formattedValue, value: item.id };
|
|
91
90
|
});
|
|
92
91
|
setOptions(options);
|
|
93
|
-
|
|
94
92
|
} catch (err) {
|
|
95
|
-
setError(err as any)
|
|
93
|
+
setError(err as any);
|
|
96
94
|
} finally {
|
|
97
95
|
setIsLoadingOptions(false);
|
|
98
96
|
}
|
|
@@ -104,19 +102,21 @@ export const TagsInput = (props: TagsInputProps) => {
|
|
|
104
102
|
if (item.operation == "pendingRemove") {
|
|
105
103
|
return {
|
|
106
104
|
...item,
|
|
107
|
-
operation: "pendingLink"
|
|
108
|
-
}
|
|
105
|
+
operation: "pendingLink",
|
|
106
|
+
};
|
|
109
107
|
} else {
|
|
110
|
-
return item
|
|
108
|
+
return item;
|
|
111
109
|
}
|
|
112
110
|
} else {
|
|
113
|
-
return {id: item.id, operation:
|
|
111
|
+
return { id: item.id, operation: "pendingRemove" };
|
|
114
112
|
}
|
|
115
|
-
})
|
|
116
|
-
const currentIds = newItems.map(item => item.id)
|
|
117
|
-
ids.filter(id => !currentIds.includes(id)).map((id) => {
|
|
118
|
-
newItems.push({id, operation: 'pendingLink'});
|
|
119
113
|
});
|
|
114
|
+
const currentIds = newItems.map((item) => item.id);
|
|
115
|
+
ids
|
|
116
|
+
.filter((id) => !currentIds.includes(id))
|
|
117
|
+
.map((id) => {
|
|
118
|
+
newItems.push({ id, operation: "pendingLink" });
|
|
119
|
+
});
|
|
120
120
|
triggerChange(newItems);
|
|
121
121
|
};
|
|
122
122
|
|
|
@@ -130,10 +130,11 @@ export const TagsInput = (props: TagsInputProps) => {
|
|
|
130
130
|
<AntTag
|
|
131
131
|
color={colorFromString(label)}
|
|
132
132
|
onMouseDown={onPreventMouseDown}
|
|
133
|
-
style={{margin:
|
|
133
|
+
style={{ margin: "5px" }}
|
|
134
134
|
closable={closable}
|
|
135
|
-
onClose={onClose}
|
|
136
|
-
|
|
135
|
+
onClose={onClose}
|
|
136
|
+
>
|
|
137
|
+
{label}
|
|
137
138
|
</AntTag>
|
|
138
139
|
);
|
|
139
140
|
};
|
|
@@ -154,10 +155,8 @@ export const TagsInput = (props: TagsInputProps) => {
|
|
|
154
155
|
options={options}
|
|
155
156
|
onChange={onChangeSelected}
|
|
156
157
|
loading={isLoadingOptions}
|
|
157
|
-
|
|
158
|
-
</Select>
|
|
158
|
+
></Select>
|
|
159
159
|
</div>
|
|
160
160
|
</>
|
|
161
161
|
);
|
|
162
|
-
|
|
163
162
|
};
|
|
@@ -13,13 +13,13 @@ export type ExportModalProps = {
|
|
|
13
13
|
visible: boolean;
|
|
14
14
|
locale: string;
|
|
15
15
|
onClose: () => void;
|
|
16
|
-
selectedRegistersToExport?:
|
|
16
|
+
selectedRegistersToExport?: any[];
|
|
17
17
|
totalRegisters: number;
|
|
18
18
|
model: string;
|
|
19
19
|
domain: any[];
|
|
20
20
|
limit?: number;
|
|
21
|
-
treeFields?: any;
|
|
22
21
|
context?: any;
|
|
22
|
+
visibleRegisters: number;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export const ExportModal = (props: ExportModalProps) => {
|
|
@@ -29,26 +29,40 @@ export const ExportModal = (props: ExportModalProps) => {
|
|
|
29
29
|
onClose,
|
|
30
30
|
model,
|
|
31
31
|
context,
|
|
32
|
-
treeFields,
|
|
33
32
|
selectedRegistersToExport,
|
|
34
33
|
totalRegisters,
|
|
35
34
|
domain,
|
|
36
35
|
limit,
|
|
36
|
+
visibleRegisters,
|
|
37
37
|
} = props;
|
|
38
38
|
const fields = useRef<any>({});
|
|
39
39
|
|
|
40
40
|
const onSucceed = useCallback(
|
|
41
41
|
async (options: ExportOptions) => {
|
|
42
|
-
if (
|
|
42
|
+
if (
|
|
43
|
+
options.selectedKeys === undefined ||
|
|
44
|
+
options.selectedKeys.length === 0
|
|
45
|
+
) {
|
|
43
46
|
showInfo(tForLang("selectAtLeastOneField", locale));
|
|
44
47
|
return;
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
let exportDomain = domain;
|
|
51
|
+
|
|
52
|
+
if (
|
|
53
|
+
options.registersAmount === "selected" &&
|
|
54
|
+
selectedRegistersToExport?.length !== 0
|
|
55
|
+
) {
|
|
56
|
+
exportDomain = [
|
|
57
|
+
["id", "in", selectedRegistersToExport?.map((r) => r.id)],
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
|
|
47
61
|
const { datas } = await ConnectionProvider.getHandler().exportData({
|
|
48
62
|
model,
|
|
49
63
|
fields: options.selectedKeys,
|
|
50
|
-
domain:
|
|
51
|
-
limit: options.registersAmount === "all" ?
|
|
64
|
+
domain: exportDomain,
|
|
65
|
+
limit: options.registersAmount === "all" ? 0 : limit,
|
|
52
66
|
context,
|
|
53
67
|
format: options.exportType,
|
|
54
68
|
});
|
|
@@ -77,13 +91,18 @@ export const ExportModal = (props: ExportModalProps) => {
|
|
|
77
91
|
async ({ key, title }: any) => {
|
|
78
92
|
let fieldDefinition;
|
|
79
93
|
|
|
80
|
-
|
|
94
|
+
const sanitizedKey =
|
|
95
|
+
key.split("/")[key.split("/").length - 1] === "id"
|
|
96
|
+
? key.split("/").slice(0, -1).join("/")
|
|
97
|
+
: key;
|
|
98
|
+
|
|
99
|
+
if (sanitizedKey.indexOf("/") === -1) {
|
|
81
100
|
fieldDefinition = fields.current["/"];
|
|
82
101
|
} else {
|
|
83
|
-
fieldDefinition = fields.current[getParentKey(
|
|
102
|
+
fieldDefinition = fields.current[getParentKey(sanitizedKey)];
|
|
84
103
|
}
|
|
85
104
|
|
|
86
|
-
const optsForField = fieldDefinition[getChildKey(
|
|
105
|
+
const optsForField = fieldDefinition[getChildKey(sanitizedKey)];
|
|
87
106
|
const relation = optsForField.relation;
|
|
88
107
|
const viewData = await ConnectionProvider.getHandler().getFields({
|
|
89
108
|
model: relation,
|
|
@@ -91,12 +110,12 @@ export const ExportModal = (props: ExportModalProps) => {
|
|
|
91
110
|
fields: [],
|
|
92
111
|
});
|
|
93
112
|
|
|
94
|
-
fields.current[
|
|
113
|
+
fields.current[sanitizedKey] = viewData;
|
|
95
114
|
|
|
96
115
|
return convertToExportField({
|
|
97
116
|
fields: viewData,
|
|
98
117
|
parentTitle: title,
|
|
99
|
-
parentKey:
|
|
118
|
+
parentKey: sanitizedKey,
|
|
100
119
|
});
|
|
101
120
|
},
|
|
102
121
|
[fields, model, context]
|
|
@@ -108,11 +127,17 @@ export const ExportModal = (props: ExportModalProps) => {
|
|
|
108
127
|
locale={locale as Locale}
|
|
109
128
|
onSucceed={onSucceed}
|
|
110
129
|
onCancel={onClose}
|
|
111
|
-
selectedRegistersToExport={
|
|
130
|
+
selectedRegistersToExport={
|
|
131
|
+
selectedRegistersToExport &&
|
|
132
|
+
selectedRegistersToExport.length &&
|
|
133
|
+
selectedRegistersToExport.length > 0
|
|
134
|
+
? selectedRegistersToExport.length
|
|
135
|
+
: undefined
|
|
136
|
+
}
|
|
112
137
|
totalRegisters={totalRegisters}
|
|
113
138
|
onGetFieldChilds={onGetFieldChilds}
|
|
114
139
|
onGetFields={onGetFields}
|
|
115
|
-
|
|
140
|
+
visibleRegisters={visibleRegisters}
|
|
116
141
|
/>
|
|
117
142
|
);
|
|
118
143
|
};
|
|
@@ -130,14 +155,27 @@ const convertToExportField = ({
|
|
|
130
155
|
|
|
131
156
|
for (const key of Object.keys(fields)) {
|
|
132
157
|
const valuesForField = fields[key];
|
|
158
|
+
|
|
159
|
+
if (valuesForField.relation && valuesForField.is_function === true) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
133
163
|
const relationField =
|
|
134
164
|
valuesForField.type === "many2one" ||
|
|
135
165
|
valuesForField.type === "one2many" ||
|
|
136
166
|
valuesForField.type === "many2many";
|
|
137
167
|
|
|
168
|
+
let newKey = `${parentKey ? parentKey + "/" : ""}${key}`;
|
|
169
|
+
|
|
170
|
+
if (relationField) {
|
|
171
|
+
newKey += "/id";
|
|
172
|
+
}
|
|
173
|
+
|
|
138
174
|
exportFields.push({
|
|
139
|
-
key:
|
|
140
|
-
title: `${parentTitle ? parentTitle + "
|
|
175
|
+
key: newKey,
|
|
176
|
+
title: `${parentTitle ? parentTitle + " → " : ""}${
|
|
177
|
+
valuesForField.string
|
|
178
|
+
}`,
|
|
141
179
|
tooltip: valuesForField.help,
|
|
142
180
|
required: valuesForField.required,
|
|
143
181
|
isLeaf: !relationField,
|
|
@@ -308,6 +308,10 @@ function Dashboard(props: DashboardProps, ref: any) {
|
|
|
308
308
|
/>
|
|
309
309
|
);
|
|
310
310
|
} else if (initialView !== undefined) {
|
|
311
|
+
const formattedInitialView =
|
|
312
|
+
initialView && Array.isArray(initialView.id)
|
|
313
|
+
? { ...initialView, id: initialView.id[0] }
|
|
314
|
+
: initialView;
|
|
311
315
|
childContent = (
|
|
312
316
|
<ActionView
|
|
313
317
|
action_id={actionId}
|
|
@@ -319,7 +323,7 @@ function Dashboard(props: DashboardProps, ref: any) {
|
|
|
319
323
|
context={context}
|
|
320
324
|
domain={domain}
|
|
321
325
|
setCanWeClose={() => {}}
|
|
322
|
-
initialView={
|
|
326
|
+
initialView={formattedInitialView}
|
|
323
327
|
limit={limit}
|
|
324
328
|
/>
|
|
325
329
|
);
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
Row,
|
|
16
16
|
Alert,
|
|
17
17
|
Spin,
|
|
18
|
+
message,
|
|
18
19
|
} from "antd";
|
|
19
20
|
import Measure from "react-measure";
|
|
20
21
|
import { CheckOutlined, CloseOutlined } from "@ant-design/icons";
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
ContentRootContextType,
|
|
55
56
|
} from "@/context/ContentRootContext";
|
|
56
57
|
import { LocaleContext, LocaleContextType } from "@/context/LocaleContext";
|
|
58
|
+
import { convertToPlain2ManyValues } from "@/helpers/one2manyHelper";
|
|
57
59
|
|
|
58
60
|
export type FormProps = {
|
|
59
61
|
model: string;
|
|
@@ -105,7 +107,7 @@ function Form(props: FormProps, ref: any) {
|
|
|
105
107
|
defaultValues,
|
|
106
108
|
forcedValues = {},
|
|
107
109
|
} = props;
|
|
108
|
-
const { lang } = useContext(LocaleContext) as LocaleContextType;
|
|
110
|
+
const { t, lang } = useContext(LocaleContext) as LocaleContextType;
|
|
109
111
|
|
|
110
112
|
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
|
111
113
|
const [error, setError] = useState<string>();
|
|
@@ -126,7 +128,8 @@ function Form(props: FormProps, ref: any) {
|
|
|
126
128
|
const responsiveBehaviour = containerWidth < WIDTH_BREAKPOINT;
|
|
127
129
|
|
|
128
130
|
const formContext = useContext(FormContext) as FormContextType;
|
|
129
|
-
const { activeId: parentId } =
|
|
131
|
+
const { activeId: parentId, getPlainValues: getParentPlainValues } =
|
|
132
|
+
formContext || {};
|
|
130
133
|
|
|
131
134
|
const actionViewContext = useContext(
|
|
132
135
|
ActionViewContext
|
|
@@ -137,6 +140,8 @@ function Form(props: FormProps, ref: any) {
|
|
|
137
140
|
setCurrentId = undefined,
|
|
138
141
|
setFormIsLoading = undefined,
|
|
139
142
|
setAttachments = undefined,
|
|
143
|
+
title = undefined,
|
|
144
|
+
setTitle = undefined,
|
|
140
145
|
} = (rootForm ? actionViewContext : {}) || {};
|
|
141
146
|
|
|
142
147
|
const contentRootContext = useContext(
|
|
@@ -342,6 +347,7 @@ function Form(props: FormProps, ref: any) {
|
|
|
342
347
|
await antForm.validateFields();
|
|
343
348
|
return false;
|
|
344
349
|
} catch (verror) {
|
|
350
|
+
message.error(t("fillRequiredFields"));
|
|
345
351
|
return true;
|
|
346
352
|
}
|
|
347
353
|
}
|
|
@@ -398,13 +404,11 @@ function Form(props: FormProps, ref: any) {
|
|
|
398
404
|
if (valuesProps) {
|
|
399
405
|
values = valuesProps;
|
|
400
406
|
} else {
|
|
401
|
-
({
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
arch: _arch!,
|
|
407
|
-
}));
|
|
407
|
+
({ values, defaultGetCalled: hasDefaultGetCalled } =
|
|
408
|
+
await fetchValuesFromApi({
|
|
409
|
+
fields: _fields,
|
|
410
|
+
arch: _arch!,
|
|
411
|
+
}));
|
|
408
412
|
}
|
|
409
413
|
|
|
410
414
|
if (actionDomain) {
|
|
@@ -455,15 +459,13 @@ function Form(props: FormProps, ref: any) {
|
|
|
455
459
|
|
|
456
460
|
const getFormView = async (): Promise<FormView> => {
|
|
457
461
|
if (getDataFromAction) {
|
|
458
|
-
const action =
|
|
459
|
-
model
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
{
|
|
462
|
+
const action =
|
|
463
|
+
await ConnectionProvider.getHandler().getActionStringForModel(model);
|
|
464
|
+
const viewsForAction =
|
|
465
|
+
await ConnectionProvider.getHandler().getViewsForAction({
|
|
463
466
|
action,
|
|
464
467
|
context: parentContext,
|
|
465
|
-
}
|
|
466
|
-
);
|
|
468
|
+
});
|
|
467
469
|
return viewsForAction.views.get("form");
|
|
468
470
|
}
|
|
469
471
|
|
|
@@ -609,13 +611,13 @@ function Form(props: FormProps, ref: any) {
|
|
|
609
611
|
formSubmitting.current = false;
|
|
610
612
|
setFormHasChanges?.(false);
|
|
611
613
|
onCancel?.();
|
|
612
|
-
return true;
|
|
614
|
+
return { succeed: true, id: getCurrentId()! };
|
|
613
615
|
}
|
|
614
616
|
|
|
615
617
|
if (await checkIfFormHasErrors()) {
|
|
616
618
|
formSubmitting.current = false;
|
|
617
619
|
formErrorsDialog(lang);
|
|
618
|
-
return false;
|
|
620
|
+
return { succeed: false, id: getCurrentId()! };
|
|
619
621
|
}
|
|
620
622
|
|
|
621
623
|
setIsSubmitting(true);
|
|
@@ -640,6 +642,7 @@ function Form(props: FormProps, ref: any) {
|
|
|
640
642
|
setIsSubmitting(false);
|
|
641
643
|
setFormIsSaving?.(false);
|
|
642
644
|
onSubmitError?.(err);
|
|
645
|
+
message.error(t("errorWhileSavingForm"));
|
|
643
646
|
setError(err?.message ? err.message : err);
|
|
644
647
|
} finally {
|
|
645
648
|
formSubmitting.current = false;
|
|
@@ -647,7 +650,7 @@ function Form(props: FormProps, ref: any) {
|
|
|
647
650
|
setIsSubmitting(false);
|
|
648
651
|
}
|
|
649
652
|
|
|
650
|
-
return submitSucceed;
|
|
653
|
+
return { succeed: submitSucceed, id: getCurrentId()! };
|
|
651
654
|
};
|
|
652
655
|
|
|
653
656
|
const parseForm = ({
|
|
@@ -663,13 +666,20 @@ function Form(props: FormProps, ref: any) {
|
|
|
663
666
|
// TODO: Here we must inject `values` to the ooui parser in order to evaluate arch+values and get the new form container
|
|
664
667
|
ooui.parse(arch, {
|
|
665
668
|
readOnly,
|
|
666
|
-
values:
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
669
|
+
values: convertToPlain2ManyValues(
|
|
670
|
+
{
|
|
671
|
+
...values,
|
|
672
|
+
...getAdditionalValues(),
|
|
673
|
+
},
|
|
674
|
+
fields
|
|
675
|
+
),
|
|
670
676
|
});
|
|
671
677
|
setFormOoui(ooui);
|
|
672
678
|
|
|
679
|
+
if (ooui.string && ooui.string !== title) {
|
|
680
|
+
setTitle?.(ooui.string);
|
|
681
|
+
}
|
|
682
|
+
|
|
673
683
|
if (formModalContext && ooui.string)
|
|
674
684
|
formModalContext.setTitle?.(ooui.string);
|
|
675
685
|
};
|
|
@@ -695,7 +705,7 @@ function Form(props: FormProps, ref: any) {
|
|
|
695
705
|
if (
|
|
696
706
|
checkFieldsType({
|
|
697
707
|
changedFields,
|
|
698
|
-
|
|
708
|
+
formOoui: formOoui!,
|
|
699
709
|
types: [
|
|
700
710
|
"text",
|
|
701
711
|
"codeeditor",
|
|
@@ -756,6 +766,7 @@ function Form(props: FormProps, ref: any) {
|
|
|
756
766
|
...formOoui?.context,
|
|
757
767
|
},
|
|
758
768
|
},
|
|
769
|
+
parentValues: getParentPlainValues?.(),
|
|
759
770
|
onChangeFieldActionArgs: onChangeFieldAction.args,
|
|
760
771
|
});
|
|
761
772
|
|
|
@@ -307,6 +307,7 @@ function SearchTree(props: Props, ref: any) {
|
|
|
307
307
|
searchValues={searchValues}
|
|
308
308
|
/>
|
|
309
309
|
<Tree
|
|
310
|
+
context={parentContext}
|
|
310
311
|
total={totalItems}
|
|
311
312
|
limit={limit}
|
|
312
313
|
page={page}
|
|
@@ -327,6 +328,7 @@ function SearchTree(props: Props, ref: any) {
|
|
|
327
328
|
treeView.isExpandable ? fetchChildrenForRecord : undefined
|
|
328
329
|
}
|
|
329
330
|
childField={treeView.field_parent}
|
|
331
|
+
rootTree={rootTree}
|
|
330
332
|
/>
|
|
331
333
|
</>
|
|
332
334
|
);
|