@engagebay/engagebay-form-module 1.0.0-beta.3-8 → 1.0.0

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/link.sh CHANGED
@@ -1,2 +1,2 @@
1
- sudo npm link /home/eb137/IdeaProjects/engagebay-frontend/node_modules/react
1
+ sudo npm link ../../../reacho-frontend/node_modules/react
2
2
  npm link
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engagebay/engagebay-form-module",
3
- "version": "1.0.0-beta.3-8",
3
+ "version": "1.0.0",
4
4
  "description": "Provide base form components to reacho",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -26,21 +26,5 @@
26
26
  "react-redux": ">=8.0.4",
27
27
  "react-tailwindcss-datepicker": ">=1.6.6",
28
28
  "redux-saga": ">=1.3.0"
29
- },
30
- "devDependencies": {
31
- "@headlessui/react": ">=2.1.2",
32
- "@heroicons/react": ">=2.1.5",
33
- "@reduxjs/toolkit": ">=2.2.7",
34
- "@tippyjs/react": ">=4.2.6",
35
- "@types/lodash": ">=4.17.7",
36
- "@types/react-redux": ">=7.1.33",
37
- "axios": ">=1.7.2",
38
- "clsx": ">=2.1.1",
39
- "moment": ">=2.30.1",
40
- "react-hook-form": ">=7.52.1",
41
- "react-popper": ">=2.3.0",
42
- "react-redux": ">=8.0.4",
43
- "react-tailwindcss-datepicker": ">=1.6.6",
44
- "redux-saga": ">=1.3.0"
45
29
  }
46
30
  }
package/src/api/index.ts CHANGED
@@ -1,5 +1,4 @@
1
- import axios, {AxiosInstance, AxiosRequestConfig} from "axios";
2
- import {FormFieldSchema} from "../form/schema/FormFieldSchema";
1
+ import axios, { AxiosRequestConfig } from "axios";
3
2
 
4
3
  const BASE_API: AxiosRequestConfig = {
5
4
  baseURL:
@@ -24,16 +23,3 @@ reachoAPI.interceptors.request.use(
24
23
  return Promise.reject(error);
25
24
  }
26
25
  );
27
-
28
- export const getAxiosInstance = (axiosInstance: AxiosInstance | undefined, fieldConfig: FormFieldSchema): AxiosInstance => {
29
-
30
- if (fieldConfig && fieldConfig.axiosInstance) {
31
- return fieldConfig.axiosInstance;
32
- }
33
-
34
- if (axiosInstance) {
35
- return axiosInstance;
36
- }
37
-
38
- return fieldConfig.disableHeaderInFetch ? axios : reachoAPI;
39
- };
package/src/form/Form.tsx CHANGED
@@ -9,11 +9,9 @@ import {
9
9
  UseFormTrigger,
10
10
  UseFormUnregister,
11
11
  UseFormResetField,
12
- Control,
13
12
  } from "react-hook-form";
14
13
  import { FormFieldSchema } from "./schema/FormFieldSchema";
15
14
  import { FormContext } from "./context/FormContext";
16
- import { AxiosInstance } from 'axios';
17
15
 
18
16
  /**
19
17
  * Props for the Form component
@@ -28,7 +26,6 @@ import { AxiosInstance } from 'axios';
28
26
  */
29
27
  type FormPropsSchema = {
30
28
  fieldSchema: FormFieldSchema[];
31
- axiosInstance?: AxiosInstance
32
29
  formData: any;
33
30
  onError?: (error: any) => void;
34
31
  onSubmit?: (data: FormData) => void;
@@ -43,7 +40,6 @@ type FormPropsSchema = {
43
40
  trigger: UseFormTrigger<any>;
44
41
  unregister: UseFormUnregister<any>;
45
42
  resetField: UseFormResetField<any>;
46
- control: Control<any, any, any>;
47
43
  }) => React.ReactNode;
48
44
  customClass?: string;
49
45
  };
@@ -136,7 +132,6 @@ export default function Form(props: FormPropsSchema): JSX.Element {
136
132
  setError,
137
133
  setFocus,
138
134
  unregister,
139
- axiosInstance: props.axiosInstance,
140
135
  }}>
141
136
  {/* Form element */}
142
137
  <form
@@ -154,7 +149,6 @@ export default function Form(props: FormPropsSchema): JSX.Element {
154
149
  trigger,
155
150
  unregister,
156
151
  resetField,
157
- control,
158
152
  })}
159
153
  </form>
160
154
  </FormContext.Provider>
@@ -17,7 +17,6 @@ import {
17
17
  UseFormWatch,
18
18
  } from "react-hook-form";
19
19
  import { FormFieldSchema } from "../schema/FormFieldSchema";
20
- import { AxiosInstance } from "axios";
21
20
 
22
21
  export interface FormContextType {
23
22
  formFields: FormFieldSchema[];
@@ -44,7 +43,6 @@ export interface FormContextType {
44
43
  // control: Control<TFieldValues, TContext>;
45
44
  // register: UseFormRegister<TFieldValues>;
46
45
  setFocus: UseFormSetFocus<any>;
47
- axiosInstance?: AxiosInstance;
48
46
  }
49
47
 
50
48
  export const FormContext = createContext({
@@ -1,316 +1,204 @@
1
1
  import {
2
- FieldAlignType,
3
- FieldOptionsSchema,
4
- FormFieldComponentPropSchema,
5
- FormFieldSchema,
6
- FormFieldType,
2
+ FieldAlignType,
3
+ FieldOptionsSchema,
4
+ FormFieldComponentPropSchema,
5
+ FormFieldSchema,
6
+ FormFieldType
7
7
  } from "../schema/FormFieldSchema";
8
- import React, {
9
- useCallback,
10
- useContext,
11
- useEffect,
12
- useMemo,
13
- useState,
14
- } from "react";
15
- import { FormContext } from "../context/FormContext";
16
- import { RegisterOptions } from "react-hook-form";
17
- import { convertToTitleCase, registerFormField } from "../util";
8
+ import React, {useCallback, useContext, useEffect, useMemo, useState} from "react";
9
+ import {FormContext} from "../context/FormContext";
10
+ import {RegisterOptions} from "react-hook-form";
11
+ import {convertToTitleCase, registerFormField} from "../util";
18
12
  import axios from "axios";
13
+ import {reachoAPI} from "../../api";
19
14
  import SwitchField from "./SwitchField";
20
15
  import FormField from "../FormField";
21
16
  import RenderFormField from "../util/RenderFormField";
22
- import { TrashIcon, XMarkIcon } from "@heroicons/react/24/outline";
17
+ import {TrashIcon, XMarkIcon} from "@heroicons/react/24/outline";
23
18
  import Tippy from "@tippyjs/react";
24
- import { set } from "lodash";
25
19
 
26
- const defaultBusinessHours = {
27
- MONDAY: {
28
- enabledDay: true,
29
- sessions: [
30
- {
31
- startTime: "10:00",
32
- endTime: "18:00",
33
- },
34
- ],
35
- },
36
- TUESDAY: {
37
- enabledDay: true,
38
- sessions: [
39
- {
40
- startTime: "10:00",
41
- endTime: "18:00",
42
- },
43
- ],
44
- },
45
- WEDNESDAY: {
46
- enabledDay: true,
47
- sessions: [
48
- {
49
- startTime: "10:00",
50
- endTime: "18:00",
51
- },
52
- ],
53
- },
54
- THURSDAY: {
55
- enabledDay: true,
56
- sessions: [
57
- {
58
- startTime: "10:00",
59
- endTime: "18:00",
60
- },
61
- ],
62
- },
63
- FRIDAY: {
64
- enabledDay: true,
65
- sessions: [
66
- {
67
- startTime: "10:00",
68
- endTime: "18:00",
69
- },
70
- ],
71
- },
72
- SATURDAY: {
73
- enabledDay: false,
74
- sessions: [
75
- {
76
- startTime: "10:00",
77
- endTime: "18:00",
78
- },
79
- ],
80
- },
81
- SUNDAY: {
82
- enabledDay: false,
83
- sessions: [
84
- {
85
- startTime: "10:00",
86
- endTime: "18:00",
87
- },
88
- ],
89
- },
90
- };
91
20
 
92
- export const BusinessHoursField: React.FC<FormFieldComponentPropSchema> = (
93
- props: FormFieldComponentPropSchema
94
- ) => {
95
- const formContext = useContext(FormContext);
96
- const [listOptions, setListOptions] = useState<any>(defaultBusinessHours);
97
- const [loading, setLoading] = useState<boolean>(false);
21
+ export const BusinessHoursField: React.FC<FormFieldComponentPropSchema> = (props: FormFieldComponentPropSchema) => {
22
+ const formContext = useContext(FormContext);
23
+ const [listOptions, setListOptions] = useState<any[]>([]);
24
+ const [loading, setLoading] = useState<boolean>(false);
98
25
 
99
- let registerOptions: RegisterOptions = registerFormField(props.fieldConfig);
100
- const hookProps = useMemo(
101
- () => formContext.register(props.fieldConfig.name, registerOptions),
102
- [formContext, props.fieldConfig.name, registerOptions]
103
- );
26
+ let registerOptions: RegisterOptions = registerFormField(props.fieldConfig);
27
+ const hookProps = useMemo(() => formContext.register(props.fieldConfig.name, registerOptions), [formContext, props.fieldConfig.name, registerOptions]);
104
28
 
105
- useEffect(() => {
106
- fetchData();
107
- }, []);
29
+ useEffect(() => {
30
+ fetchData();
31
+ }, []);
108
32
 
109
- const getTimeConfig = (mappedName: string): FormFieldSchema => {
110
- return {
111
- required: true,
112
- name: mappedName + ".sessions",
113
- wrapper: ({ children }) => {
114
- return (
115
- <div style={{ border: "1px sold #ddd", padding: "0px" }}>
116
- {children}
117
- </div>
118
- );
119
- },
120
- arrayWrapper: ({ children, append, getValues }) => {
121
- return (
122
- <>
123
- <div style={{ border: "1px sold #ddd" }}>{children}</div>
124
- <div className="w-full sm:w-full text-end mr-[2.3em]">
125
- <button
126
- type="button"
127
- className={`text-end text-primary cursor-pointer font-[13px] font-medium ${
128
- getValues(`${mappedName}.sessions`)?.length > 1 ? "mr-9" : ""
129
- }`}
130
- onClick={() => {
131
- const lastEndTime =
132
- getValues(`${mappedName}.sessions`)?.[
133
- getValues(`${mappedName}.sessions`).length - 1
134
- ]?.endTime || "08:30";
33
+ const getTimeConfig = (mappedName: string): FormFieldSchema => {
34
+ return {
35
+ required: true,
36
+ name: mappedName + ".sessions",
37
+ wrapper: ({children}) => {
38
+ return <div style={{border: '1px sold #ddd', padding: '0px'}}>{children}</div>;
39
+ },
40
+ arrayWrapper: ({children, append,getValues}) => {
41
+ return (
42
+ <>
43
+ <div style={{border: '1px sold #ddd',}}>
44
+ {children}
45
+ </div>
46
+ <div className='w-full sm:w-full text-end mr-[2.3em]'>
47
+ <button type='button' className={`text-end text-primary cursor-pointer font-[13px] font-medium ${getValues(`${mappedName}.sessions`)?.length > 1 ? "mr-9" : ''}`}
48
+ onClick={() => {
49
+ const lastEndTime = getValues(`${mappedName}.sessions`)?.[getValues(`${mappedName}.sessions`).length - 1]?.endTime || '08:30';
135
50
 
136
- const newStartTime = lastEndTime; // Start new session at last session's end time
137
- const newEndTime = "23:00"; // Calculate end time, but cap at 23:00
51
+ const newStartTime = lastEndTime; // Start new session at last session's end time
52
+ const newEndTime = "23:00"; // Calculate end time, but cap at 23:00
138
53
 
139
- append({
140
- startTime: newStartTime,
141
- endTime: newEndTime,
142
- });
143
- }}
144
- >
145
- + Add
146
- </button>
147
- </div>
148
- </>
149
- );
150
- },
151
- arrayIndexWrapper: ({
152
- mappedName,
153
- getValues,
154
- children,
155
- childByFieldName,
156
- append,
157
- prepend,
158
- remove,
159
- index,
160
- }) => {
161
- return (
162
- <div className="flex items-center gap-4 form-group !mb-2">
163
- <div>{childByFieldName("startTime")}</div>
164
- <p>To</p>
165
- <div>{childByFieldName("endTime")}</div>
166
- {index > 0 ? (
167
- <button
168
- className="Button__StyledButton-sc-1l1v2a6-0 gVdTUT"
169
- type="button"
170
- onClick={() => {
171
- remove(index);
172
- }}
173
- >
174
- {/* <TrashIcon height={18} width={18} className=""/> */}
175
- <Tippy content="Delete">
176
- <XMarkIcon
177
- aria-hidden="true"
178
- height={18}
179
- width={18}
180
- className=""
181
- />
182
- </Tippy>
183
- </button>
184
- ) : (
185
- <></>
186
- )}
187
- </div>
188
- );
189
- },
190
- formFieldType: FormFieldType.ARRAY,
191
- align: FieldAlignType.HORIZONTAL,
192
- disableDefaultWrapper: true,
193
- defaultValue: {
194
- startTime: "08:30",
195
- endTime: "18:00",
196
- },
197
- children: [
198
- {
199
- required: false,
200
- formFieldType: FormFieldType.TIME,
201
- name: "startTime",
202
- disableDefaultWrapper: true,
203
- defaultValue: "08:30",
204
- customClassNames: {
205
- fieldClassName: "border-none bg-blue-100",
206
- },
207
- },
208
- {
209
- required: false,
210
- formFieldType: FormFieldType.TIME,
211
- name: "endTime",
212
- disableDefaultWrapper: true,
213
- defaultValue: "18:00",
214
- customClassNames: {
215
- fieldClassName: "border-none bg-blue-100",
216
- },
217
- },
218
- ],
219
- };
220
- };
54
+ append({
55
+ startTime: newStartTime,
56
+ endTime: newEndTime,
57
+ });
58
+ }}
59
+ >
60
+ + Add
61
+ </button>
62
+ </div>
63
+ </>
64
+ );
65
+ },
66
+ arrayIndexWrapper: ({
67
+ mappedName,
68
+ getValues,
69
+ children,
70
+ childByFieldName,
71
+ append,
72
+ prepend,
73
+ remove,
74
+ index
75
+ }) => {
76
+ return (
77
+ <div className="flex items-center gap-4 form-group !mb-2">
78
+ <div>{childByFieldName('startTime')}</div>
79
+ <p>To</p>
80
+ <div>{childByFieldName('endTime')}</div>
81
+ {index > 0 ?
82
+ <button
83
+ className="Button__StyledButton-sc-1l1v2a6-0 gVdTUT"
84
+ type="button"
85
+ onClick={() => {
86
+ remove(index);
87
+ }}
88
+ >
89
+ {/* <TrashIcon height={18} width={18} className=""/> */}
90
+ <Tippy content="Delete">
91
+ <XMarkIcon aria-hidden="true" height={18} width={18} className="" />
92
+ </Tippy>
93
+
94
+ </button> : <></>}
95
+ </div>
221
96
 
222
- const timeConfigs = useMemo(() => {
223
- const configs: Record<string, FormFieldSchema> = {};
224
- Object.keys(listOptions || {}).forEach((day) => {
225
- configs[day] = getTimeConfig(props.fieldConfig.name + "." + day);
226
- });
227
- return configs;
228
- }, [props.fieldConfig.name, listOptions]);
97
+ );
98
+ },
99
+ formFieldType: FormFieldType.ARRAY,
100
+ align: FieldAlignType.HORIZONTAL,
101
+ disableDefaultWrapper: true,
102
+ defaultValue: {
103
+ startTime: "08:30",
104
+ endTime: "18:00"
105
+ },
106
+ children: [
107
+ {
108
+ required: false,
109
+ formFieldType: FormFieldType.TIME,
110
+ name: "startTime",
111
+ disableDefaultWrapper:true,
112
+ defaultValue: "08:30",
113
+ customClassNames: {
114
+ fieldClassName: "border-none bg-blue-100",
115
+ },
116
+ }, {
117
+ required: false,
118
+ formFieldType: FormFieldType.TIME,
119
+ name: "endTime",
120
+ disableDefaultWrapper: true,
121
+ defaultValue: "18:00",
122
+ customClassNames: {
123
+ fieldClassName: "border-none bg-blue-100",
124
+ },
125
+ },
126
+ ],
127
+ }
128
+ }
129
+ ;
229
130
 
230
- const fetchData = useCallback(async () => {
231
- setLoading(true);
232
- // if (!props.fieldConfig.fetchUrl) return;
233
- let url = "/api/core/user-prefs/get-default-business-days";
234
- if (props.fieldConfig.fetchUrl) {
235
- url = props.fieldConfig.fetchUrl;
236
- }
237
- try {
238
- let response = await (props.fieldConfig.disableHeaderInFetch
239
- ? axios.get(url)
240
- : formContext.axiosInstance?.get(url));
131
+ const fetchData = useCallback(async () => {
132
+ setLoading(true);
133
+ // if (!props.fieldConfig.fetchUrl) return;
134
+ let url = "/api/core/user-prefs/get-default-business-days";
135
+ if (props.fieldConfig.fetchUrl) {
136
+ url = props.fieldConfig.fetchUrl;
137
+ }
138
+ try {
139
+ let response = await (props.fieldConfig.disableHeaderInFetch
140
+ ? axios.get(url)
141
+ : reachoAPI.get(url));
241
142
 
242
- if (response?.data) {
243
- const data: FieldOptionsSchema[] = response.data;
244
- setListOptions(data);
245
- setLoading(false);
143
+ if (response.data) {
144
+ const data: FieldOptionsSchema[] = response.data;
145
+ setListOptions(data);
146
+ setLoading(false);
246
147
 
247
- if (props.fieldConfig.fetchCallback) {
248
- props.fieldConfig.fetchCallback(response);
249
- }
250
- } else {
251
- setListOptions(defaultBusinessHours);
252
- console.error(response?.statusText);
253
- setLoading(false);
254
- }
255
- } catch (error) {
256
- console.error("Fetch error:", error);
257
- setLoading(false);
148
+ if (props.fieldConfig.fetchCallback) {
149
+ props.fieldConfig.fetchCallback(response);
150
+ }
151
+ } else {
152
+ console.error(response.statusText);
153
+ setLoading(false);
154
+ }
155
+ } catch (error) {
156
+ console.error('Fetch error:', error);
157
+ setLoading(false);
158
+ }
159
+ },
160
+ [props.fieldConfig.fetchUrl, props.fieldConfig.optionsConfig, props.fieldConfig.fetchCallback, props.fieldConfig.disableHeaderInFetch]
161
+ );
162
+
163
+ function getInput() {
164
+ return <>
165
+ {loading?<></>:
166
+ listOptions && Object.keys(listOptions).map((day) => {
167
+ const dayInfo = listOptions[day as any];
168
+ return (
169
+ <>
170
+ <div className="flex baseline mb-6" data-testid="" key={day}>
171
+ <div className="max-w-sm space-y-2">
172
+ <div
173
+ className="group flex items-center w-full gap-x-2 text-sm font-normal leading-none text-gray-700 mt-3">
174
+ <SwitchField fieldConfig={{
175
+ name: props.fieldConfig.name + "." + day + ".enabledDay",
176
+ defaultValue: dayInfo.enabledDay,
177
+ required: false,
178
+ formFieldType: FormFieldType.SWITCH,
179
+ disableDefaultWrapper: true,
180
+ customClassNames: {
181
+ fieldClassName: "!mb-0",
182
+ },
183
+ }}/>
184
+ <p className="flex justify-between border-gray-900 text-sm text-gray-900 font-medium ml-2 w-24 leading-none">
185
+ <span className="w-full">{convertToTitleCase(day)}</span>
186
+ </p>
187
+ </div>
188
+ </div>
189
+
190
+ <div className=" flex items-center text-gray-500 focus-within:text-blue-500">
191
+ <FormField fieldConfig={getTimeConfig(props.fieldConfig.name + "." + day)}/>
192
+ </div>
193
+ </div>
194
+ </>
195
+ );
196
+ })
197
+ }
198
+ </>
258
199
  }
259
- }, [
260
- props.fieldConfig.fetchUrl,
261
- props.fieldConfig.optionsConfig,
262
- props.fieldConfig.fetchCallback,
263
- props.fieldConfig.disableHeaderInFetch,
264
- ]);
265
200
 
266
- function getInput() {
267
201
  return (
268
- <>
269
- {loading ? (
270
- <></>
271
- ) : (
272
- listOptions &&
273
- Object.keys(listOptions).map((day) => {
274
- const dayInfo = listOptions[day as any];
275
- return (
276
- <>
277
- <div className="flex baseline mb-6" data-testid="" key={day}>
278
- <div className="max-w-sm space-y-2">
279
- <div className="group flex items-center w-full gap-x-2 text-sm font-normal leading-none text-gray-700 mt-3">
280
- <SwitchField
281
- fieldConfig={{
282
- name:
283
- props.fieldConfig.name + "." + day + ".enabledDay",
284
- defaultValue: dayInfo.enabledDay,
285
- required: false,
286
- formFieldType: FormFieldType.SWITCH,
287
- disableDefaultWrapper: true,
288
- customClassNames: {
289
- fieldClassName: "!mb-0",
290
- },
291
- }}
292
- />
293
- <p className="flex justify-between border-gray-900 text-sm text-gray-900 font-medium ml-2 w-24 leading-none">
294
- <span className="w-full">
295
- {convertToTitleCase(day)}
296
- </span>
297
- </p>
298
- </div>
299
- </div>
300
-
301
- <div className=" flex items-center text-gray-500 focus-within:text-blue-500">
302
- <FormField fieldConfig={timeConfigs[day]} />
303
- </div>
304
- </div>
305
- </>
306
- );
307
- })
308
- )}
309
- </>
202
+ <RenderFormField fieldConfig={props.fieldConfig} getInput={getInput}/>
310
203
  );
311
- }
312
-
313
- return (
314
- <RenderFormField fieldConfig={props.fieldConfig} getInput={getInput} />
315
- );
316
204
  };