@engagebay/engagebay-form-module 1.0.2-beta.10 → 1.0.2-beta.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engagebay/engagebay-form-module",
3
- "version": "1.0.2-beta.10",
3
+ "version": "1.0.2-beta.3",
4
4
  "description": "Provide base form components to reacho",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -16,6 +16,7 @@
16
16
  "@heroicons/react": ">=2.1.5",
17
17
  "@reduxjs/toolkit": ">=2.2.7",
18
18
  "@tippyjs/react": ">=4.2.6",
19
+ "@types/lodash": ">=4.17.7",
19
20
  "@types/react-redux": ">=7.1.33",
20
21
  "axios": ">=1.7.2",
21
22
  "clsx": ">=2.1.1",
@@ -31,6 +32,7 @@
31
32
  "@heroicons/react": ">=2.1.5",
32
33
  "@reduxjs/toolkit": ">=2.2.7",
33
34
  "@tippyjs/react": ">=4.2.6",
35
+ "@types/lodash": ">=4.17.7",
34
36
  "@types/react-redux": ">=7.1.33",
35
37
  "axios": ">=1.7.2",
36
38
  "clsx": ">=2.1.1",
package/src/api/index.ts CHANGED
@@ -1,16 +1,10 @@
1
1
  import axios, {AxiosInstance, AxiosRequestConfig} from "axios";
2
2
  import {FormFieldSchema} from "../form/schema/FormFieldSchema";
3
3
 
4
- let baseURL;
5
- try {
6
- baseURL = (window as any).DEFAULT_HOST ||
7
- (window as any).parent.DEFAULT_HOST
8
- } catch (error) {
9
-
10
- }
11
-
12
4
  const BASE_API: AxiosRequestConfig = {
13
- baseURL: baseURL ?? "",
5
+ baseURL:
6
+ (window as any).REACHO_BASE_URL ||
7
+ (window as any).parent.REACHO_BASE_URL,
14
8
  timeout: 30000,
15
9
  headers: {
16
10
  "Content-Type": "application/json",
@@ -34,7 +34,6 @@ import {
34
34
  FormFieldType,
35
35
  OptionMappingConfig,
36
36
  } from "./schema/FormFieldSchema";
37
- import Typeahead2 from "./formfields/Typeahead2";
38
37
 
39
38
  /**
40
39
  * @property {React.FC<FormFieldComponentPropSchema>} component - React component for a form field.
@@ -140,9 +139,6 @@ const formFieldComponents: FormComponentSchema = {
140
139
  [FormFieldType[FormFieldType.TYPEAHEAD_MULTI_SELECT]]: {
141
140
  component: TypeaheadMultiSelect,
142
141
  },
143
- [FormFieldType[FormFieldType.TYPEAHEAD_2]]: {
144
- component: Typeahead2,
145
- },
146
142
  [FormFieldType[FormFieldType.COMBO_SELECT]]: {
147
143
  component: ComboSelect,
148
144
  },
@@ -21,6 +21,7 @@ import FormField from "../FormField";
21
21
  import RenderFormField from "../util/RenderFormField";
22
22
  import { TrashIcon, XMarkIcon } from "@heroicons/react/24/outline";
23
23
  import Tippy from "@tippyjs/react";
24
+ import { set } from "lodash";
24
25
 
25
26
  const defaultBusinessHours = {
26
27
  MONDAY: {
@@ -123,8 +124,9 @@ export const BusinessHoursField: React.FC<FormFieldComponentPropSchema> = (
123
124
  <div className="w-full sm:w-full text-end mr-[2.3em]">
124
125
  <button
125
126
  type="button"
126
- className={`text-end text-primary cursor-pointer font-[13px] font-medium ${getValues(`${mappedName}.sessions`)?.length > 1 ? "mr-9" : ""
127
- }`}
127
+ className={`text-end text-primary cursor-pointer font-[13px] font-medium ${
128
+ getValues(`${mappedName}.sessions`)?.length > 1 ? "mr-9" : ""
129
+ }`}
128
130
  onClick={() => {
129
131
  const lastEndTime =
130
132
  getValues(`${mappedName}.sessions`)?.[
@@ -31,32 +31,18 @@ const DatePicker: React.FC<FormFieldComponentPropSchema> = (
31
31
  }, [props.fieldConfig.forceUpdate]);
32
32
 
33
33
  let registerOptions: RegisterOptions = registerFormField(props.fieldConfig);
34
- //registerOptions.valueAsDate = true;
34
+ registerOptions.valueAsDate = true;
35
35
  let hookProps = formContext.register(props.fieldConfig.name, registerOptions);
36
36
 
37
37
  function getInput() {
38
- const rawStart =
39
- initialDate?.startDate ||
40
- props.fieldConfig.defaultValue ||
41
- "";
42
- const rawEnd =
43
- initialDate?.endDate ||
44
- props.fieldConfig.defaultValue ||
45
- "";
46
- const toDate = (v: string | Date | null | undefined): Date | null => {
47
- if (v == null || v === "") return null;
48
- return moment(v).isValid() ? moment(v).toDate() : null;
49
- };
50
- const value = {
51
- startDate: toDate(rawStart),
52
- endDate: toDate(rawEnd),
53
- };
54
- // Calendar opens on selected date's month/year (must be a Date instance)
55
- const startFrom = value.startDate instanceof Date ? value.startDate : new Date();
56
38
  return (
57
39
  <Datepicker
58
- value={value}
59
- startFrom={startFrom}
40
+ value={
41
+ initialDate || {
42
+ startDate: props.fieldConfig.defaultValue,
43
+ endDate: props.fieldConfig.defaultValue,
44
+ }
45
+ }
60
46
  {...hookProps}
61
47
  placeholder={
62
48
  props.fieldConfig.placeholder
@@ -67,7 +53,13 @@ const DatePicker: React.FC<FormFieldComponentPropSchema> = (
67
53
  popoverDirection="down"
68
54
  useRange={false}
69
55
  inputName={props.fieldConfig.name}
70
- key={props.fieldConfig.name + "_" + rawStart + "_" + rawEnd}
56
+ key={
57
+ props.fieldConfig.name +
58
+ "_" +
59
+ initialDate.startDate +
60
+ "_" +
61
+ initialDate.endDate
62
+ }
71
63
  containerClassName={"relative"}
72
64
  minDate={props.fieldConfig.minDate}
73
65
  maxDate={props.fieldConfig.maxDate}
@@ -28,7 +28,7 @@ const NumberField: React.FC<FormFieldComponentPropSchema> = (
28
28
  step={props.fieldConfig.decimalAllowed ? 0.01 : 1}
29
29
  defaultValue={props.fieldConfig.defaultValue as string}
30
30
  className={`form-input ${
31
- props.fieldConfig.customClassNames?.fieldClassName || "flex-1"
31
+ props.fieldConfig.customClassNames?.fieldClassName || "flex-1 !w-60"
32
32
  }`}
33
33
  onKeyDown={(e) => {
34
34
  props.fieldConfig.onKeyDown && props.fieldConfig.onKeyDown(e);
@@ -58,6 +58,8 @@ const Typeahead: React.FC<FormFieldComponentPropSchema> = (
58
58
  let url = props.fieldConfig.fetchUrl;
59
59
  if (_query) {
60
60
  url = url.includes("?") ? url + "&q=" + _query : url + "?q=" + _query;
61
+ } else {
62
+ url = url.includes("?") ? url + "&q=" + null : url + "?q=" + null;
61
63
  }
62
64
 
63
65
  let response = await (props.fieldConfig.disableHeaderInFetch
@@ -97,9 +99,7 @@ const Typeahead: React.FC<FormFieldComponentPropSchema> = (
97
99
  let url = props.fieldConfig.fetchUrl;
98
100
 
99
101
  if (value)
100
- url = url.includes("?")
101
- ? url + "&values=" + value
102
- : url + "?values=" + value;
102
+ url = url.includes("?") ? url + "&q=" + value : url + "?q=" + value;
103
103
 
104
104
  let response = await (props.fieldConfig.disableHeaderInFetch
105
105
  ? axios.get(url)
@@ -60,6 +60,8 @@ const TypeaheadMultiSelect: React.FC<FormFieldComponentPropSchema> = (
60
60
  let url = props.fieldConfig.fetchUrl;
61
61
  if (_query) {
62
62
  url = url.includes("?") ? url + "&q=" + _query : url + "?q=" + _query;
63
+ } else {
64
+ url = url.includes("?") ? url + "&q=" + null : url + "?q=" + null;
63
65
  }
64
66
  const axiosInstance = getAxiosInstance(
65
67
  formContext.axiosInstance,
@@ -108,9 +110,7 @@ const TypeaheadMultiSelect: React.FC<FormFieldComponentPropSchema> = (
108
110
 
109
111
  let url = props.fieldConfig.fetchUrl;
110
112
 
111
- url = url.includes("?")
112
- ? url + "&values=" + value
113
- : url + "?values=" + value;
113
+ url = url = url.includes("?") ? url + "&q=" + value : url + "?q=" + value;
114
114
 
115
115
  let response = await (props.fieldConfig.disableHeaderInFetch
116
116
  ? axios.get(url)
@@ -126,16 +126,16 @@ const TypeaheadMultiSelect: React.FC<FormFieldComponentPropSchema> = (
126
126
  ...data,
127
127
  props.fieldConfig.dropdownFieldConfig?.isSuggestionBox && values
128
128
  ? values
129
- .filter(
130
- (value) =>
131
- data.some((d) => d.value !== value) || data.length == 0,
132
- )
133
- .map((val) => ({ label: val, value: val }))
129
+ .filter(
130
+ (value) =>
131
+ data.some((d) => d.value !== value) || data.length == 0,
132
+ )
133
+ .map((val) => ({ label: val, value: val }))
134
134
  : [],
135
135
  ].flat(),
136
136
  );
137
137
  }
138
- } catch (err) { }
138
+ } catch (err) {}
139
139
  };
140
140
 
141
141
  const updateListOptions = (data: any) => {
@@ -179,7 +179,7 @@ const TypeaheadMultiSelect: React.FC<FormFieldComponentPropSchema> = (
179
179
  className={
180
180
  props.fieldConfig.customClassNames?.fieldClassName
181
181
  ? "form-listbox-select " +
182
- props.fieldConfig.customClassNames?.fieldClassName
182
+ props.fieldConfig.customClassNames?.fieldClassName
183
183
  : "form-listbox-select"
184
184
  }
185
185
  >
@@ -37,7 +37,6 @@ export enum FormFieldType {
37
37
  DYNAMIC_MULTI_SELECT = "DYNAMIC_MULTI_SELECT",
38
38
 
39
39
  TYPEAHEAD = "TYPEAHEAD",
40
- TYPEAHEAD_2 = "TYPEAHEAD_2",
41
40
  TYPEAHEAD_MULTI_SELECT = "TYPEAHEAD_MULTI_SELECT",
42
41
  PHONE_NUMBER_INPUT = "PHONE_NUMBER_INPUT",
43
42
  SWITCH = "SWITCH",
@@ -130,13 +129,10 @@ export type FormFieldSchema = {
130
129
  submitOnChange?: boolean;
131
130
  formFieldPattern?: FormFieldPatternsImpl[];
132
131
  fetchUrl?: string;
133
- fetchSavedDataUrl?: string;
134
132
  postUrl?: string;
135
133
  fileAccept?: string;
136
134
  icon?: ReactNode;
137
135
  outputFormat?: OutputFormatType;
138
- isMultiple?: boolean;
139
- allowedMinQueryLength?: number;
140
136
  children?: FormFieldSchema[];
141
137
  defaultOptions?: FieldOptionsSchema[];
142
138
  optionsConfig?: OptionMappingConfig;
@@ -102,15 +102,15 @@ const RenderListOptions = forwardRef<HTMLUListElement, RenderListOptionsProps>(
102
102
 
103
103
  const filteredList = query
104
104
  ? resultList.filter((item) => {
105
- const normalizedLabel = fieldConfig.dropdownFieldConfig
106
- ?.isCaseSensitive
107
- ? item.label
108
- : item.label.toLowerCase();
105
+ const normalizedLabel = fieldConfig.dropdownFieldConfig
106
+ ?.isCaseSensitive
107
+ ? item.label
108
+ : item.label.toLowerCase();
109
109
 
110
- return normalizedLabel
111
- .replace(/\s+/g, "")
112
- .includes(caseSensitive.replace(/\s+/g, ""));
113
- })
110
+ return normalizedLabel
111
+ .replace(/\s+/g, "")
112
+ .includes(caseSensitive.replace(/\s+/g, ""));
113
+ })
114
114
  : resultList;
115
115
 
116
116
  let nullGroupOptions: any[] = [];
@@ -127,15 +127,13 @@ const RenderListOptions = forwardRef<HTMLUListElement, RenderListOptionsProps>(
127
127
  }, {});
128
128
 
129
129
  const handleQueryCallback = useCallback(() => {
130
- if (filteredList.length < 5 && isTypeahead) {
130
+ if (filteredList.length == 0 && isTypeahead) {
131
131
  queryCallback && queryCallback(query);
132
132
  }
133
133
  }, [filteredList]);
134
134
 
135
135
  useEffect(() => {
136
- if (formField == FormFieldType.TYPEAHEAD_2)
137
- queryCallback && queryCallback(query);
138
- else handleQueryCallback();
136
+ handleQueryCallback();
139
137
  }, [query]);
140
138
 
141
139
  let enableCreateFlag =
@@ -145,7 +143,6 @@ const RenderListOptions = forwardRef<HTMLUListElement, RenderListOptionsProps>(
145
143
 
146
144
  let validTypeaheadFields = [
147
145
  FormFieldType.TYPEAHEAD,
148
- FormFieldType.TYPEAHEAD_2,
149
146
  FormFieldType.TYPEAHEAD_MULTI_SELECT,
150
147
  ];
151
148
  let isTypeahead: boolean = validTypeaheadFields.indexOf(formField) > -1;
@@ -169,10 +166,11 @@ const RenderListOptions = forwardRef<HTMLUListElement, RenderListOptionsProps>(
169
166
  key={option.value}
170
167
  disabled={option.isDisabled}
171
168
  onClick={() => setTimeout(resetToDefault, 300)}
172
- className={`form-listbox-option ${selected
173
- ? " bg-gray-100 text-gray-900"
174
- : "hover:bg-gray-100 text-gray-700"
175
- }`}
169
+ className={`form-listbox-option ${
170
+ selected
171
+ ? " bg-gray-100 text-gray-900"
172
+ : "hover:bg-gray-100 text-gray-700"
173
+ }`}
176
174
  value={option.value}
177
175
  >
178
176
  {fieldConfig.fieldOptionWrapper ? (
@@ -181,8 +179,9 @@ const RenderListOptions = forwardRef<HTMLUListElement, RenderListOptionsProps>(
181
179
  <>
182
180
  <div className="flex items-center justify-between gap-x-1.5">
183
181
  <span
184
- className={`block truncate w-full ${fieldConfig.customClassNames?.optionClassName} space-x-2 ${selected ? "font-medium" : "font-normal"
185
- }`}
182
+ className={`block truncate w-full ${fieldConfig.customClassNames?.optionClassName} space-x-2 ${
183
+ selected ? "font-medium" : "font-normal"
184
+ }`}
186
185
  >
187
186
  {option.icon && (
188
187
  <span className="listbox-svg">{option.icon}</span>
@@ -204,7 +203,7 @@ const RenderListOptions = forwardRef<HTMLUListElement, RenderListOptionsProps>(
204
203
  )}
205
204
  </span>
206
205
  {isTypeahead &&
207
- !fieldConfig.dropdownFieldConfig?.isSuggestionBox ? (
206
+ !fieldConfig.dropdownFieldConfig?.isSuggestionBox ? (
208
207
  <input
209
208
  type="checkbox"
210
209
  className="form-checkbox"
@@ -400,28 +399,28 @@ export function renderListBoxValue(
400
399
  {values.length > 1
401
400
  ? `${values.length} selected`
402
401
  : listOptions.find((option) => option.value == value[0])?.label ||
403
- values[0]}
402
+ values[0]}
404
403
  </span>
405
404
  {getDeleteButton()}
406
405
  </span>
407
406
  ) : (
408
407
  Array.isArray(values) &&
409
- values.map((opt: any) => {
410
- const option = listOptions.find((option) => option.value == opt);
411
- if (!option && values.length == 0) return getPlaceholder();
408
+ values.map((opt: any) => {
409
+ const option = listOptions.find((option) => option.value == opt);
410
+ if (!option && values.length == 0) return getPlaceholder();
412
411
 
413
- return (
414
- <span key={option?.value} className="form-selected-badge">
415
- <Tippy content={option?.label} delay={500}>
416
- <span className="form-selected-badge-name">
417
- {option?.label}
418
- </span>
419
- </Tippy>
412
+ return (
413
+ <span key={option?.value} className="form-selected-badge">
414
+ <Tippy content={option?.label} delay={500}>
415
+ <span className="form-selected-badge-name">
416
+ {option?.label}
417
+ </span>
418
+ </Tippy>
420
419
 
421
- {getDeleteButton(opt)}
422
- </span>
423
- );
424
- })
420
+ {getDeleteButton(opt)}
421
+ </span>
422
+ );
423
+ })
425
424
  );
426
425
  };
427
426
  const getDeleteButton = (option?: string) => {
@@ -453,10 +452,9 @@ export function renderListBoxValue(
453
452
  )
454
453
  );
455
454
  };
456
- let outputFormat =
457
- fieldConfig.outputFormat != undefined
458
- ? fieldConfig.outputFormat === OutputFormatType.STRING
459
- : false;
455
+ let outputFormat = fieldConfig.outputFormat
456
+ ? fieldConfig.outputFormat === OutputFormatType.ARRAY
457
+ : false;
460
458
  const getPlaceholder = () => (
461
459
  <span className="form-placeholder">
462
460
  {fieldConfig.placeholder || "Select any option"}
@@ -1,283 +0,0 @@
1
- import React, {
2
- useCallback,
3
- useContext,
4
- useEffect,
5
- useMemo,
6
- useRef,
7
- useState,
8
- } from "react";
9
-
10
- import { Listbox, ListboxButton } from "@headlessui/react";
11
- import { RegisterOptions } from "react-hook-form";
12
-
13
- import { FormContext } from "../context/FormContext";
14
- import { getListOption, getListOptions } from "../FormFieldUtils";
15
- import {
16
- FieldOptionsSchema,
17
- FormFieldComponentPropSchema,
18
- FormFieldType,
19
- } from "../schema/FormFieldSchema";
20
- import { handleChange, registerFormField } from "../util";
21
- import RenderFormField from "../util/RenderFormField";
22
- import RenderListOptions, {
23
- renderListBoxValue,
24
- } from "../util/RenderListOptions";
25
- import axios from "axios";
26
- import { getAxiosInstance } from "../../api";
27
-
28
- const Typeahead2: React.FC<FormFieldComponentPropSchema> = (
29
- props: FormFieldComponentPropSchema,
30
- ) => {
31
- const dynamicSelectRef = useRef<HTMLUListElement>(null);
32
- const abortControllerRef = useRef<AbortController | null>(null);
33
- const formContext = useContext(FormContext);
34
- let registerOptions: RegisterOptions = registerFormField(props.fieldConfig);
35
- let hookProps = formContext.register(props.fieldConfig.name, registerOptions);
36
- const [listOptions, setListOptions] = useState<FieldOptionsSchema[]>([]);
37
- const [selectedValues, setSelectedValues] = useState<FieldOptionsSchema[]>(
38
- [],
39
- );
40
- const [loading, setLoading] = useState<boolean>(false);
41
-
42
- useEffect(() => {
43
- if (
44
- !formContext.getValues(props.fieldConfig.name) &&
45
- props.fieldConfig.defaultValue
46
- ) {
47
- formContext.setValue(
48
- props.fieldConfig.name,
49
- props.fieldConfig.defaultValue,
50
- );
51
- }
52
- let values: any | any[] | undefined =
53
- formContext.getValues(props.fieldConfig.name) ||
54
- props.fieldConfig.defaultValue;
55
-
56
- if (values && selectedValues.length < 1) {
57
- if (props.fieldConfig.fetchSavedDataUrl) {
58
- fetchValue(values);
59
- } else {
60
- setSelectedValues(
61
- Array.isArray(values)
62
- ? values.map((val: any) => ({ label: val, value: val }))
63
- : [values],
64
- );
65
- }
66
- }
67
- }, []);
68
-
69
-
70
-
71
- const fetchData = useMemo(() => {
72
- let timeoutId: ReturnType<typeof setTimeout>;
73
-
74
- return (_query: string | undefined) => {
75
- // Clear the previous timer
76
- if (timeoutId) clearTimeout(timeoutId);
77
-
78
- // Set a new timer
79
- timeoutId = setTimeout(async () => {
80
- // 1. Cancel the previous request if it's still pending
81
- if (abortControllerRef.current) {
82
- abortControllerRef.current.abort();
83
- }
84
-
85
- // 2. Create a new controller for the current request
86
- const controller = new AbortController();
87
- abortControllerRef.current = controller;
88
-
89
- if (!_query || (props.fieldConfig.allowedMinQueryLength && _query.length < props.fieldConfig.allowedMinQueryLength) || _query.length < 3) {
90
- setListOptions([]);
91
- setLoading(false);
92
- return;
93
- }
94
- setLoading(true);
95
- try {
96
- if (!props.fieldConfig.fetchUrl) return;
97
-
98
- let url = props.fieldConfig.fetchUrl;
99
-
100
- url = url.includes("?") ? url + "&q=" + _query : url + "?q=" + _query;
101
-
102
- const axiosInstance = getAxiosInstance(
103
- formContext.axiosInstance,
104
- props.fieldConfig,
105
- );
106
- const response = await axiosInstance.get(url);
107
-
108
- if (controller === abortControllerRef.current) {
109
- if (response?.data) {
110
- const data: FieldOptionsSchema[] = getListOptions(
111
- response?.data,
112
- props.fieldConfig.optionsConfig,
113
- );
114
- setListOptions([...data]);
115
-
116
- if (props.fieldConfig.fetchCallback) {
117
- props.fieldConfig.fetchCallback(response);
118
- }
119
- }
120
- }
121
- } catch (err) {
122
- console.error("Fetch error:", err);
123
- } finally {
124
- // Only stop loading if this was the "active" request
125
- if (controller === abortControllerRef.current) {
126
- setLoading(false);
127
- }
128
- }
129
- }, 250);
130
- };
131
- }, []);
132
-
133
- // Cleanup on unmount
134
- useEffect(() => {
135
- return () => {
136
- abortControllerRef.current?.abort();
137
- };
138
- }, []);
139
-
140
- const fetchValue = async (value: string | any | any[]) => {
141
- try {
142
- if (
143
- props.fieldConfig.ignoreFetchValue ||
144
- !props.fieldConfig.fetchSavedDataUrl
145
- ) {
146
- return;
147
- }
148
-
149
- let url = props.fieldConfig.fetchSavedDataUrl;
150
-
151
- // url = url.includes("?")
152
- // ? url + "&values=" + value
153
- // : url + "?values=" + value;
154
-
155
- let response = await (props.fieldConfig.disableHeaderInFetch
156
- ? axios.post(url, Array.isArray(value) ? value : [value])
157
- : formContext.axiosInstance?.post(
158
- url,
159
- Array.isArray(value) ? value : [value],
160
- ));
161
- if (response?.data) {
162
- const data: FieldOptionsSchema[] = getListOptions(
163
- response?.data,
164
- props.fieldConfig.optionsConfig,
165
- );
166
- let values: any[] = formContext.getValues(props.fieldConfig.name) || [];
167
- setSelectedValues(
168
- [
169
- ...data,
170
- props.fieldConfig.dropdownFieldConfig?.isSuggestionBox &&
171
- values &&
172
- Array.isArray(values)
173
- ? values
174
- .filter(
175
- (value) =>
176
- data.some((d) => d.value !== value) || data.length == 0,
177
- )
178
- .map((val) => ({ label: val, value: val }))
179
- : [],
180
- ].flat(),
181
- );
182
- }
183
- } catch (err) { }
184
- };
185
-
186
- const updateListOptions = (data: any) => {
187
- const resData: FieldOptionsSchema = getListOption(
188
- data,
189
- props.fieldConfig.optionsConfig,
190
- );
191
- setListOptions([]);
192
- setSelectedValues((prev) =>
193
- props.fieldConfig.isMultiple ? [...prev, resData] : [resData],
194
- );
195
- let result = formContext.getValues(props.fieldConfig.name) || [];
196
- result = !props.fieldConfig.isMultiple
197
- ? resData.value
198
- : result.includes(resData.value)
199
- ? [...result.filter((v: string) => v != resData.value), resData.value]
200
- : [...result, resData.value];
201
- formContext.setValue(props.fieldConfig.name, result);
202
- };
203
-
204
- const getInput = () => {
205
- return (
206
- <Listbox
207
- as={"div"}
208
- {...hookProps}
209
- value={
210
- props.fieldConfig.isMultiple
211
- ? formContext.getValues(props.fieldConfig.name)
212
- ? formContext.getValues(props.fieldConfig.name)
213
- : []
214
- : formContext.getValues(props.fieldConfig.name)
215
- }
216
- name={props.fieldConfig.name}
217
- defaultValue={props.fieldConfig.defaultValue}
218
- key={props.fieldConfig.name}
219
- className={"relative form-listbox flex-1 overflow-hidden"}
220
- onChange={(selectedOptions) => {
221
- let currentValue = formContext.getValues(props.fieldConfig.name);
222
- const newValue =
223
- currentValue === selectedOptions ? null : selectedOptions;
224
-
225
- if (props.fieldConfig.isMultiple) {
226
- currentValue = listOptions.filter((op) =>
227
- selectedOptions.includes(op.value),
228
- );
229
- setSelectedValues((prev) => [...prev, ...currentValue]);
230
- } else {
231
- const selected = listOptions.find((o) => o.value == newValue);
232
- selected && setSelectedValues([selected]);
233
- }
234
- setListOptions([]);
235
- handleChange(
236
- newValue,
237
- formContext,
238
- props.fieldConfig,
239
- props.onChange,
240
- );
241
- }}
242
- multiple={props.fieldConfig.isMultiple}
243
- >
244
- <ListboxButton
245
- className={
246
- props.fieldConfig.customClassNames?.fieldClassName
247
- ? "form-listbox-select " +
248
- props.fieldConfig.customClassNames?.fieldClassName
249
- : "form-listbox-select"
250
- }
251
- >
252
- {renderListBoxValue(
253
- formContext,
254
- props.fieldConfig,
255
- [...selectedValues, ...listOptions],
256
- props.onChange,
257
- )}
258
- </ListboxButton>
259
- <RenderListOptions
260
- formContext={formContext}
261
- onChange={props.onChange}
262
- formField={FormFieldType.TYPEAHEAD_2}
263
- ref={dynamicSelectRef}
264
- fieldConfig={props.fieldConfig}
265
- listOptions={listOptions}
266
- setListOptions={setListOptions}
267
- loading={loading}
268
- setLoading={setLoading}
269
- createCallback={(data) => updateListOptions(data)}
270
- queryCallback={(query) => fetchData(query)}
271
- />
272
- </Listbox>
273
- );
274
- };
275
- if (props.fieldConfig.hideWhenNoResults && listOptions.length == 0) {
276
- return <></>;
277
- }
278
-
279
- return (
280
- <RenderFormField fieldConfig={props.fieldConfig} getInput={getInput} />
281
- );
282
- };
283
- export default Typeahead2;