Skip to content

Commit 81a2008

Browse files
committed
custom_fields: add support for ui section widget
* allow to rename DiscoverFieldsSection label
1 parent 0c4e066 commit 81a2008

File tree

4 files changed

+70
-23
lines changed

4 files changed

+70
-23
lines changed

src/lib/forms/widgets/custom_fields/CustomFields.js

+37-10
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
import React, { Component } from "react";
99
import PropTypes from "prop-types";
10-
import { DiscoverFieldsSection } from "./DiscoverFieldsSection";
10+
import { default as DiscoverFieldsSection } from "./DiscoverFieldsSection";
1111
import { AccordionField } from "../../AccordionField";
12-
import { loadWidgetsFromConfig } from "../loader";
12+
import { importWidget, loadWidgetsFromConfig } from "../loader";
1313
import { Container } from "semantic-ui-react";
1414

1515
export class CustomFields extends Component {
@@ -27,16 +27,18 @@ export class CustomFields extends Component {
2727
try {
2828
const { sectionsConfig, discoverFieldsConfig } =
2929
await this.loadCustomFieldsWidgets();
30-
const sections = sectionsConfig.map((sectionCfg) => {
31-
const paths = includesPaths(sectionCfg.fields, fieldPathPrefix);
32-
return { ...sectionCfg, paths };
33-
});
30+
const sections = await Promise.all(
31+
sectionsConfig.map(async (sectionCfg) => {
32+
const paths = includesPaths(sectionCfg.fields, fieldPathPrefix);
33+
const widget = await this.loadSectionWidget(sectionCfg);
34+
return { ...sectionCfg, paths, widget };
35+
})
36+
).then((values) => values);
3437

3538
const discoverFieldsSections = discoverFieldsConfig.map((sectionCfg) => {
3639
const paths = includesPaths(sectionCfg.fields, fieldPathPrefix);
3740
return { ...sectionCfg, paths };
3841
});
39-
4042
this.setState({
4143
sections: sections,
4244
discoverFieldsSections: discoverFieldsSections,
@@ -46,6 +48,26 @@ export class CustomFields extends Component {
4648
}
4749
};
4850

51+
async loadSectionWidget(sectionCfg) {
52+
const { templateLoaders, record, includesPaths, fieldPathPrefix } = this.props;
53+
const paths = includesPaths(sectionCfg.fields, fieldPathPrefix);
54+
if (sectionCfg.ui_widget) {
55+
return await importWidget(
56+
templateLoaders,
57+
{
58+
...sectionCfg,
59+
fieldPath: undefined,
60+
record,
61+
props: {
62+
includesPaths: paths,
63+
children: sectionCfg,
64+
},
65+
},
66+
false
67+
);
68+
}
69+
}
70+
4971
async loadCustomFieldsWidgets() {
5072
const { config, fieldPathPrefix, templateLoaders, record } = this.props;
5173

@@ -75,6 +97,7 @@ export class CustomFields extends Component {
7597
render() {
7698
const { sections, discoverFieldsSections } = this.state;
7799
const { templateLoaders, record } = this.props;
100+
78101
return (
79102
<>
80103
{sections &&
@@ -84,18 +107,21 @@ export class CustomFields extends Component {
84107
paths,
85108
displaySection = true,
86109
section: sectionName,
110+
widget,
87111
id: sectionId,
88112
} = section;
113+
const active = section.active !== undefined ? section.active : true;
114+
const Element = widget !== undefined ? widget : AccordionField;
89115
return displaySection ? (
90-
<AccordionField
116+
<Element
91117
key={`section-${sectionName}`}
92118
includesPaths={paths}
93119
label={sectionName}
94-
active
120+
active={active}
95121
id={sectionId}
96122
>
97123
{fields}
98-
</AccordionField>
124+
</Element>
99125
) : (
100126
<Container key="custom-fields-section">{fields}</Container>
101127
);
@@ -117,6 +143,7 @@ CustomFields.propTypes = {
117143
PropTypes.shape({
118144
section: PropTypes.string.isRequired,
119145
displaySection: PropTypes.bool,
146+
ui_widget: PropTypes.string,
120147
fields: PropTypes.arrayOf(
121148
PropTypes.shape({
122149
field: PropTypes.string.isRequired,

src/lib/forms/widgets/custom_fields/DiscoverFieldsSection.js

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import _isEmpty from "lodash/isEmpty";
22
import React, { Component } from "react";
33
import PropTypes from "prop-types";
4+
import Overridable from "react-overridable";
45
import { Divider } from "semantic-ui-react";
56
import { AccordionField } from "../../AccordionField";
67
import { FieldLabel } from "../../FieldLabel";
78
import { AddDiscoverableFieldsModal } from "./AddDiscoverableFieldsModal";
89
import isEmpty from "lodash/isEmpty";
910

10-
export class DiscoverFieldsSection extends Component {
11+
class DiscoverFieldsSection extends Component {
1112
constructor(props) {
1213
super(props);
1314
const { sections, record } = props; // sections = fields grouping, usually by domain
@@ -27,7 +28,12 @@ export class DiscoverFieldsSection extends Component {
2728
for (const section of sectionCfg) {
2829
for (const fieldCfg of section.fieldsConfig) {
2930
const { field, props, ui_widget, ...otherCfg } = fieldCfg;
30-
cfg[field] = { ui_widget: ui_widget, section: section, ...props, ...otherCfg };
31+
cfg[field] = {
32+
ui_widget: ui_widget,
33+
section: section,
34+
...props,
35+
...otherCfg,
36+
};
3137
}
3238
}
3339

@@ -92,7 +98,7 @@ export class DiscoverFieldsSection extends Component {
9298
};
9399

94100
render() {
95-
const { templateLoaders, record } = this.props;
101+
const { templateLoaders, record, discoverSectionLabel } = this.props;
96102
const { sections, tempFields, recordFields } = this.state;
97103
const existingFields = [
98104
...Object.entries(tempFields).map(([key, value]) => value.key),
@@ -104,7 +110,7 @@ export class DiscoverFieldsSection extends Component {
104110
<AccordionField
105111
key="discover-fields"
106112
includesPaths={tempFieldsPaths}
107-
label="Domain specific fields"
113+
label={discoverSectionLabel}
108114
active
109115
id="domain-specific-fields-section"
110116
>
@@ -144,4 +150,14 @@ DiscoverFieldsSection.propTypes = {
144150
templateLoaders: PropTypes.array.isRequired,
145151
sections: PropTypes.array.isRequired,
146152
record: PropTypes.object.isRequired,
153+
discoverSectionLabel: PropTypes.string,
147154
};
155+
156+
DiscoverFieldsSection.defaultProps = {
157+
discoverSectionLabel: "Domain specific fields",
158+
};
159+
160+
export default Overridable.component(
161+
"ReactInvenioForms.DiscoverFieldsSection",
162+
DiscoverFieldsSection
163+
);
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { CustomFields } from "./CustomFields";
22
export { SubjectAutocompleteDropdown } from "./SubjectAutocompleteDropdown";
3+
export { default as DiscoverFieldsSection } from "./DiscoverFieldsSection";

src/lib/forms/widgets/loader.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import React from "react";
99
*/
1010
export async function importWidget(
1111
templateLoaders,
12-
{ ui_widget: UIWidget, fieldPath, record, props }
12+
{ ui_widget: UIWidget, fieldPath, record, props },
13+
createElement = true
1314
) {
1415
let component = undefined;
15-
1616
// Try import widget from user's defined templateLoaders
1717
for (const loader of templateLoaders) {
1818
try {
@@ -33,13 +33,16 @@ export async function importWidget(
3333
console.error(`Failed to import default component ${UIWidget}.js`);
3434
throw Error("Component not found in any loader");
3535
}
36-
37-
return React.createElement(component, {
38-
...props,
39-
record: record,
40-
key: fieldPath,
41-
fieldPath: fieldPath,
42-
});
36+
if (createElement) {
37+
return React.createElement(component, {
38+
...props,
39+
record: record,
40+
key: fieldPath,
41+
fieldPath: fieldPath,
42+
});
43+
} else {
44+
return component;
45+
}
4346
}
4447

4548
/**

0 commit comments

Comments
 (0)