|
1 | 1 | import React from 'react';
|
2 |
| -import Select from 'react-select'; |
| 2 | +import AsyncSelect from 'react-select/async'; |
3 | 3 | import { reactSelectStyles } from 'netlify-cms-ui-default/dist/esm/styles';
|
4 | 4 | import { NestedCollection } from './NestedCollection';
|
5 | 5 |
|
@@ -45,7 +45,7 @@ const Option = (props) => {
|
45 | 45 | export class ParentControl extends React.Component {
|
46 | 46 | constructor(props) {
|
47 | 47 | super(props);
|
48 |
| - this.state = { entries: [], title: '' }; |
| 48 | + this.state = { title: '', optionsLoaded: false, options: [] }; |
49 | 49 | this.selectRef = React.createRef();
|
50 | 50 | }
|
51 | 51 |
|
@@ -93,56 +93,63 @@ export class ParentControl extends React.Component {
|
93 | 93 | }
|
94 | 94 |
|
95 | 95 | async componentDidMount() {
|
96 |
| - const { forID, query, collection } = this.props; |
97 |
| - |
98 |
| - const collectionName = collection.get('name'); |
99 |
| - |
100 |
| - const { |
101 |
| - payload: { |
102 |
| - response: { hits = [] }, |
103 |
| - }, |
104 |
| - } = await query(forID, collectionName, ['path'], ''); |
105 |
| - |
106 |
| - this.setState({ |
107 |
| - entries: hits, |
108 |
| - }); |
109 |
| - |
110 | 96 | if (this.isNewRecord()) {
|
111 | 97 | this.props.onChange(this.getValue() + '/');
|
112 | 98 | // track title field so we can use it for the folder name
|
113 | 99 | const titleInput = document.querySelector('[id*=title-field]');
|
114 | 100 | titleInput.addEventListener('input', (e) => {
|
115 | 101 | const title = e.target.value;
|
116 | 102 | this.setState({ title });
|
117 |
| - const parent = this.selectRef.current.props.options[0].value; |
118 |
| - this.handleChange(parent); |
| 103 | + const selectProps = this.selectRef.current.props; |
| 104 | + const currentParent = selectProps.value?.value || '/'; |
| 105 | + this.handleChange(currentParent); |
119 | 106 | });
|
120 | 107 | }
|
121 | 108 | }
|
122 | 109 |
|
123 |
| - render() { |
124 |
| - const { forID, classNameWrapper, setActiveStyle, setInactiveStyle, collection } = this.props; |
| 110 | + async loadOptions() { |
| 111 | + if (this.state.optionsLoaded) { |
| 112 | + return this.state.options; |
| 113 | + } |
| 114 | + const { forID, query, collection } = this.props; |
| 115 | + const collectionName = collection.get('name'); |
| 116 | + const { |
| 117 | + payload: { |
| 118 | + response: { hits = [] }, |
| 119 | + }, |
| 120 | + } = await query(forID, collectionName, ['path'], ''); |
125 | 121 |
|
126 | 122 | const fullPath = this.getFullPath();
|
127 | 123 | const parentPath = this.getParent(fullPath) || '';
|
128 |
| - const parent = this.state.entries.find((e) => this.getPath(e.path) === parentPath); |
| 124 | + const parent = hits.find((e) => this.getPath(e.path) === parentPath); |
129 | 125 | const label = (parent && parent.data.title) || collection.get('label');
|
130 |
| - |
131 | 126 | const options = [
|
132 | 127 | {
|
133 | 128 | value: parentPath,
|
134 | 129 | label,
|
135 | 130 | collection: this.props.collection,
|
136 |
| - entries: this.state.entries, |
| 131 | + entries: hits, |
137 | 132 | onSelectNode: (value) => this.handleChange(value),
|
138 | 133 | },
|
139 | 134 | ];
|
140 | 135 |
|
| 136 | + this.setState({ |
| 137 | + optionsLoaded: true, |
| 138 | + options, |
| 139 | + }); |
| 140 | + |
| 141 | + return options; |
| 142 | + } |
| 143 | + |
| 144 | + render() { |
| 145 | + const { forID, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props; |
| 146 | + |
141 | 147 | return (
|
142 |
| - <Select |
143 |
| - value={options[0]} |
| 148 | + <AsyncSelect |
| 149 | + value={this.state.options[0]} |
| 150 | + loadOptions={() => this.loadOptions()} |
| 151 | + defaultOptions |
144 | 152 | inputId={forID}
|
145 |
| - options={options} |
146 | 153 | className={classNameWrapper}
|
147 | 154 | onFocus={setActiveStyle}
|
148 | 155 | onBlur={setInactiveStyle}
|
|
0 commit comments