Skip to content

Commit 443fd6f

Browse files
committed
fix: allow create companies from company input
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
1 parent d75ded1 commit 443fd6f

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

src/components/mui/formik-inputs/company-input-mui.js

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,30 @@
1414
import React, { useState, useEffect, useMemo } from "react";
1515
import PropTypes from "prop-types";
1616
import TextField from "@mui/material/TextField";
17-
import Autocomplete from "@mui/material/Autocomplete";
17+
import Autocomplete, { createFilterOptions } from "@mui/material/Autocomplete";
1818
import CircularProgress from "@mui/material/CircularProgress";
1919
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
2020
import { useField } from "formik";
2121
import { queryCompanies } from "../../../actions/company-actions";
2222
import { DEBOUNCE_WAIT_250 } from "../../../utils/constants";
2323

24+
const filter = createFilterOptions();
25+
2426
const CompanyInputMUI = ({
2527
id,
2628
name,
2729
placeholder,
2830
plainValue,
2931
isMulti = false,
32+
allowCreate = false,
3033
...rest
3134
}) => {
3235
const [field, meta, helpers] = useField(name);
3336
const [options, setOptions] = useState([]);
3437
const [open, setOpen] = useState(false);
3538
const [inputValue, setInputValue] = useState("");
3639
const [loading, setLoading] = useState(false);
40+
const [isDebouncing, setIsDebouncing] = useState(false);
3741

3842
const { value } = field;
3943
const error = meta.touched && meta.error;
@@ -44,6 +48,7 @@ const CompanyInputMUI = ({
4448
return;
4549
}
4650

51+
setIsDebouncing(false);
4752
setLoading(true);
4853

4954
const normalize = (results) =>
@@ -60,11 +65,13 @@ const CompanyInputMUI = ({
6065

6166
useEffect(() => {
6267
if (inputValue) {
68+
setIsDebouncing(true);
6369
const delayDebounce = setTimeout(() => {
6470
fetchOptions(inputValue);
6571
}, DEBOUNCE_WAIT_250);
6672
return () => clearTimeout(delayDebounce);
6773
}
74+
setIsDebouncing(false);
6875
}, [inputValue]);
6976

7077
const selectedValue = useMemo(() => {
@@ -96,30 +103,66 @@ const CompanyInputMUI = ({
96103
}));
97104
} else {
98105
theValue = plainValue
99-
? newValue.label
100-
: { id: parseInt(newValue.value), name: newValue.label };
106+
? newValue.inputValue || newValue.label
107+
: {
108+
id: newValue.inputValue ? 0 : parseInt(newValue.value),
109+
name: newValue.inputValue || newValue.label
110+
};
101111
}
102112

103113
helpers.setValue(theValue);
104114
};
105115

116+
const handleFilterOptions = (options, params) => {
117+
const filtered = filter(options, params);
118+
119+
if (!allowCreate || loading || isDebouncing) return filtered;
120+
121+
const { inputValue } = params;
122+
const isExisting = options.some(
123+
(option) => inputValue.toLowerCase() === option.label.toLowerCase()
124+
);
125+
126+
if (inputValue !== "" && !isExisting) {
127+
filtered.push({
128+
inputValue,
129+
value: null,
130+
label: `Create "${inputValue}"`
131+
});
132+
}
133+
return filtered;
134+
};
135+
136+
const getOptionLabel = (option) => {
137+
if (option.inputValue) {
138+
return option.inputValue;
139+
}
140+
return option.label || "";
141+
};
142+
106143
return (
107144
<Autocomplete
108145
open={open}
109146
onOpen={() => setOpen(true)}
110147
onClose={() => setOpen(false)}
111148
options={options}
112149
value={selectedValue}
113-
getOptionLabel={(option) => option.label}
150+
getOptionLabel={getOptionLabel}
114151
isOptionEqualToValue={(option, value) => option.value === value.value}
115152
onInputChange={(_, newInputValue) => {
116153
setInputValue(newInputValue);
117154
}}
155+
filterOptions={handleFilterOptions}
118156
multiple={isMulti}
119157
onChange={handleChange}
120158
loading={loading}
121159
fullWidth
122160
popupIcon={<ExpandMoreIcon />}
161+
renderOption={(props, option) => (
162+
<li {...props} key={option.value ?? `create-${option.inputValue}`}>
163+
{option.label}
164+
</li>
165+
)}
123166
renderInput={(params) => (
124167
<TextField
125168
{...params}
@@ -156,7 +199,8 @@ CompanyInputMUI.propTypes = {
156199
name: PropTypes.string.isRequired,
157200
placeholder: PropTypes.string,
158201
plainValue: PropTypes.bool,
159-
isMulti: PropTypes.bool
202+
isMulti: PropTypes.bool,
203+
allowCreate: PropTypes.bool
160204
};
161205

162206
export default CompanyInputMUI;

src/pages/sponsors/sponsor-users-list-page/components/process-request-form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
216216
placeholder={T.translate(
217217
"sponsor_users.process_request.select_company"
218218
)}
219+
allowCreate
219220
/>
220221
</Grid2>
221222
</Grid2>

0 commit comments

Comments
 (0)