Skip to content

Commit 1f2ad8c

Browse files
authored
fix: add constants, change payload structure, new company on input (#784)
* fix: add constants, wip change payload structure Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com> * fix: allow create companies from company input Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com> * fix: adjust company id validations Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com> * fix: add initial value for sponsor type on buildInitialValues function Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com> --------- Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
1 parent e3ce326 commit 1f2ad8c

4 files changed

Lines changed: 85 additions & 20 deletions

File tree

src/actions/sponsor-users-actions.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import {
2929
DEFAULT_CURRENT_PAGE,
3030
DEFAULT_ORDER_DIR,
3131
DEFAULT_PER_PAGE,
32-
DUMMY_ACTION
32+
DUMMY_ACTION,
33+
SPONSOR_USER_ASSIGNMENT_TYPE
3334
} from "../utils/constants";
3435
import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions";
3536

@@ -328,9 +329,11 @@ export const processSponsorUserRequest = (request) => async (dispatch) => {
328329
send_activation_email: request.send_email
329330
};
330331

331-
if (request.sponsor?.id) payload.sponsor_id = request.sponsor.id;
332-
else {
333-
if (request.company?.id) payload.company_id = request.company.id;
332+
if (request.sponsor_type === SPONSOR_USER_ASSIGNMENT_TYPE.EXISTING)
333+
payload.sponsor_id = request.sponsor.id;
334+
335+
if (request.sponsor_type === SPONSOR_USER_ASSIGNMENT_TYPE.NEW) {
336+
if (request.company?.id > 0) payload.company_id = request.company.id;
334337
else payload.company_name = request.company.name;
335338
payload.sponsorship_types = request.tiers.map((st) => st.id);
336339
}

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: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import MuiSponsorInput from "../../../../components/mui/formik-inputs/mui-sponso
2121
import { titleCase } from "../../../../utils/methods";
2222
import MuiFormikSwitch from "../../../../components/mui/formik-inputs/mui-formik-switch";
2323
import SponsorshipsBySummitSelectMUI from "../../../../components/mui/formik-inputs/sponsorship-summit-select-mui";
24+
import { SPONSOR_USER_ASSIGNMENT_TYPE } from "../../../../utils/constants";
2425

2526
const buildInitialValues = (data) => {
2627
const normalized = { ...data };
@@ -32,9 +33,11 @@ const buildInitialValues = (data) => {
3233
normalized.access_rights = [];
3334
normalized.send_email = true;
3435

36+
normalized.sponsor_type = SPONSOR_USER_ASSIGNMENT_TYPE.NEW;
3537
if (data.company_id !== 0 && data.sponsor)
36-
normalized.sponsor_type = "existing";
37-
else if (data.company_name) normalized.sponsor_type = "new";
38+
normalized.sponsor_type = SPONSOR_USER_ASSIGNMENT_TYPE.EXISTING;
39+
else if (data.company_name)
40+
normalized.sponsor_type = SPONSOR_USER_ASSIGNMENT_TYPE.NEW;
3841

3942
return normalized;
4043
};
@@ -50,7 +53,7 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
5053
.object()
5154
.nullable()
5255
.when("sponsor_type", {
53-
is: "existing",
56+
is: SPONSOR_USER_ASSIGNMENT_TYPE.EXISTING,
5457
then: (schema) =>
5558
schema.required(T.translate("validation.required")).shape({
5659
id: yup.number().required(),
@@ -62,10 +65,13 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
6265
.object()
6366
.nullable()
6467
.when("sponsor_type", {
65-
is: "new",
68+
is: SPONSOR_USER_ASSIGNMENT_TYPE.NEW,
6669
then: (schema) =>
6770
schema.required(T.translate("validation.required")).shape({
68-
id: yup.number().required(),
71+
id: yup
72+
.number()
73+
.min(0, T.translate("validation.required"))
74+
.required(),
6975
name: yup.string().required()
7076
}),
7177
otherwise: (schema) => schema.notRequired()
@@ -79,7 +85,7 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
7985
})
8086
)
8187
.when("sponsor_type", {
82-
is: "new",
88+
is: SPONSOR_USER_ASSIGNMENT_TYPE.NEW,
8389
then: (schema) =>
8490
schema
8591
.min(1, T.translate("validation.required", { count: 1 }))
@@ -177,13 +183,13 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
177183
}}
178184
options={[
179185
{
180-
value: "existing",
186+
value: SPONSOR_USER_ASSIGNMENT_TYPE.EXISTING,
181187
label: T.translate(
182188
"sponsor_users.process_request.assign_to_existing"
183189
)
184190
},
185191
{
186-
value: "new",
192+
value: SPONSOR_USER_ASSIGNMENT_TYPE.NEW,
187193
label: T.translate(
188194
"sponsor_users.process_request.assign_to_new"
189195
)
@@ -194,7 +200,10 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
194200
<Grid2 size={6}>
195201
<MuiSponsorInput
196202
name="sponsor"
197-
disabled={formik.values.sponsor_type === "new"}
203+
disabled={
204+
formik.values.sponsor_type ===
205+
SPONSOR_USER_ASSIGNMENT_TYPE.NEW
206+
}
198207
summitId={summit.id}
199208
placeholder={T.translate(
200209
"sponsor_users.process_request.select_sponsor"
@@ -204,15 +213,19 @@ const ProcessRequestForm = ({ request, userGroups, summit, onSubmit }) => {
204213
<Grid2 size={6}>
205214
<CompanyInputMUI
206215
name="company"
207-
disabled={formik.values.sponsor_type === "existing"}
216+
disabled={
217+
formik.values.sponsor_type ===
218+
SPONSOR_USER_ASSIGNMENT_TYPE.EXISTING
219+
}
208220
placeholder={T.translate(
209221
"sponsor_users.process_request.select_company"
210222
)}
223+
allowCreate
211224
/>
212225
</Grid2>
213226
</Grid2>
214227
<Divider sx={{ margin: "10px -16px 20px -16px" }} />
215-
{formik.values.sponsor_type === "new" && (
228+
{formik.values.sponsor_type === SPONSOR_USER_ASSIGNMENT_TYPE.NEW && (
216229
<>
217230
<Typography variant="h6" gutterBottom>
218231
{T.translate("sponsor_users.process_request.show_details")}

src/utils/constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,9 @@ export const PURCHASE_STATUS = {
256256
PENDING: "Pending",
257257
PAID: "Paid",
258258
CANCELLED: "Cancelled"
259+
}
260+
261+
export const SPONSOR_USER_ASSIGNMENT_TYPE = {
262+
EXISTING: "existing",
263+
NEW: "new"
259264
};

0 commit comments

Comments
 (0)