@tellescope/react-components 1.160.0 → 1.161.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/lib/cjs/Forms/forms.d.ts +5 -3
- package/lib/cjs/Forms/forms.d.ts.map +1 -1
- package/lib/cjs/Forms/forms.js +13 -7
- package/lib/cjs/Forms/forms.js.map +1 -1
- package/lib/cjs/Forms/hooks.d.ts +6 -3
- package/lib/cjs/Forms/hooks.d.ts.map +1 -1
- package/lib/cjs/Forms/hooks.js +92 -77
- package/lib/cjs/Forms/hooks.js.map +1 -1
- package/lib/cjs/Forms/inputs.d.ts +1 -1
- package/lib/cjs/Forms/inputs.d.ts.map +1 -1
- package/lib/cjs/Forms/inputs.js +3 -2
- package/lib/cjs/Forms/inputs.js.map +1 -1
- package/lib/cjs/Forms/types.d.ts +1 -0
- package/lib/cjs/Forms/types.d.ts.map +1 -1
- package/lib/cjs/mui.d.ts +1 -0
- package/lib/cjs/mui.d.ts.map +1 -1
- package/lib/cjs/mui.js.map +1 -1
- package/lib/cjs/mui.native.js +1 -1
- package/lib/cjs/mui.native.js.map +1 -1
- package/lib/esm/CMS/components.d.ts +0 -1
- package/lib/esm/CMS/components.d.ts.map +1 -1
- package/lib/esm/Forms/form_responses.d.ts +0 -1
- package/lib/esm/Forms/form_responses.d.ts.map +1 -1
- package/lib/esm/Forms/forms.d.ts +7 -5
- package/lib/esm/Forms/forms.d.ts.map +1 -1
- package/lib/esm/Forms/forms.js +14 -8
- package/lib/esm/Forms/forms.js.map +1 -1
- package/lib/esm/Forms/hooks.d.ts +6 -4
- package/lib/esm/Forms/hooks.d.ts.map +1 -1
- package/lib/esm/Forms/hooks.js +93 -78
- package/lib/esm/Forms/hooks.js.map +1 -1
- package/lib/esm/Forms/inputs.d.ts +2 -2
- package/lib/esm/Forms/inputs.d.ts.map +1 -1
- package/lib/esm/Forms/inputs.js +3 -2
- package/lib/esm/Forms/inputs.js.map +1 -1
- package/lib/esm/Forms/inputs.native.d.ts +0 -1
- package/lib/esm/Forms/inputs.native.d.ts.map +1 -1
- package/lib/esm/Forms/types.d.ts +1 -0
- package/lib/esm/Forms/types.d.ts.map +1 -1
- package/lib/esm/controls.d.ts +2 -2
- package/lib/esm/inputs.d.ts +1 -1
- package/lib/esm/inputs.native.d.ts +0 -1
- package/lib/esm/inputs.native.d.ts.map +1 -1
- package/lib/esm/layout.d.ts +1 -1
- package/lib/esm/mui.d.ts +1 -0
- package/lib/esm/mui.d.ts.map +1 -1
- package/lib/esm/mui.js.map +1 -1
- package/lib/esm/mui.native.js +1 -1
- package/lib/esm/mui.native.js.map +1 -1
- package/lib/esm/state.d.ts +52 -52
- package/lib/esm/theme.native.d.ts +0 -1
- package/lib/esm/theme.native.d.ts.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/Forms/forms.tsx +30 -7
- package/src/Forms/hooks.tsx +49 -24
- package/src/Forms/inputs.tsx +3 -2
- package/src/Forms/types.ts +1 -0
- package/src/mui.native.tsx +1 -1
- package/src/mui.tsx +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellescope/react-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.161.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/cjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"@reduxjs/toolkit": "^1.6.2",
|
|
48
48
|
"@stripe/react-stripe-js": "^2.9.0",
|
|
49
49
|
"@stripe/stripe-js": "^1.52.1",
|
|
50
|
-
"@tellescope/constants": "^1.
|
|
51
|
-
"@tellescope/sdk": "^1.
|
|
52
|
-
"@tellescope/types-client": "^1.
|
|
53
|
-
"@tellescope/types-models": "^1.
|
|
54
|
-
"@tellescope/types-utilities": "^1.
|
|
55
|
-
"@tellescope/utilities": "^1.
|
|
56
|
-
"@tellescope/validation": "^1.
|
|
50
|
+
"@tellescope/constants": "^1.161.0",
|
|
51
|
+
"@tellescope/sdk": "^1.161.0",
|
|
52
|
+
"@tellescope/types-client": "^1.161.0",
|
|
53
|
+
"@tellescope/types-models": "^1.161.0",
|
|
54
|
+
"@tellescope/types-utilities": "^1.161.0",
|
|
55
|
+
"@tellescope/utilities": "^1.161.0",
|
|
56
|
+
"@tellescope/validation": "^1.161.0",
|
|
57
57
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
58
58
|
"@typescript-eslint/parser": "^4.33.0",
|
|
59
59
|
"css-to-react-native": "^3.0.0",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
81
81
|
"react-native": "^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.71.0"
|
|
82
82
|
},
|
|
83
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "da815332a8a6b56596e7d5fdaa24a83956d34e50",
|
|
84
84
|
"publishConfig": {
|
|
85
85
|
"access": "public"
|
|
86
86
|
}
|
package/src/Forms/forms.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
2
|
-
import { Button, CircularProgress, Flex, LoadingButton, Modal, Paper, Styled, Typography, form_display_text_for_language, useFileUpload, useFormResponses, useSession } from "../index"
|
|
3
|
-
import { useListForFormFields, useOrganizationTheme, useTellescopeForm, WithOrganizationTheme, Response, FileResponse } from "./hooks"
|
|
2
|
+
import { Button, CircularProgress, Flex, LinearProgress, LoadingButton, Modal, Paper, Styled, Typography, form_display_text_for_language, useFileUpload, useFormResponses, useSession } from "../index"
|
|
3
|
+
import { useListForFormFields, useOrganizationTheme, useTellescopeForm, WithOrganizationTheme, Response, FileResponse, NextFieldLogicOptions } from "./hooks"
|
|
4
4
|
import { ChangeHandler, FormInputs } from "./types"
|
|
5
5
|
import { AddressInput, AllergiesInput, AppointmentBookingInput, ConditionsInput, DatabaseSelectInput, DateInput, DateStringInput, DropdownInput, EmailInput, EmotiiInput, FileInput, FilesInput, HeightInput, HiddenValueInput, InsuranceInput, LanguageSelect, MedicationsInput, MultipleChoiceInput, NumberInput, PhoneInput, Progress, RankingInput, RatingInput, RedirectInput, RelatedContactsInput, SignatureInput, StringInput, StringLongInput, StripeInput, TableInput, TimeInput, defaultButtonStyles } from "./inputs"
|
|
6
6
|
import { PRIMARY_HEX } from "@tellescope/constants"
|
|
7
7
|
import { FormResponse, FormField, Form, Enduser } from "@tellescope/types-client"
|
|
8
8
|
import { FormResponseAnswerFileValue, OrganizationTheme } from "@tellescope/types-models"
|
|
9
|
-
import { field_can_autosubmit, formatted_date, objects_equivalent, remove_script_tags, truncate_string } from "@tellescope/utilities"
|
|
9
|
+
import { field_can_autosubmit, formatted_date, object_is_empty, objects_equivalent, read_local_storage, remove_script_tags, responses_satisfy_conditions, truncate_string } from "@tellescope/utilities"
|
|
10
10
|
import { Divider } from "@mui/material"
|
|
11
11
|
|
|
12
12
|
export const TellescopeFormContainer = ({ businessId, organizationIds, ...props } : {
|
|
@@ -132,6 +132,9 @@ export const QuestionForField = ({
|
|
|
132
132
|
goToNextField,
|
|
133
133
|
spacing,
|
|
134
134
|
isSinglePage,
|
|
135
|
+
rootResponseId,
|
|
136
|
+
isInQuestionGroup,
|
|
137
|
+
logicOptions,
|
|
135
138
|
} : {
|
|
136
139
|
spacing?: number,
|
|
137
140
|
form?: Form,
|
|
@@ -142,7 +145,9 @@ export const QuestionForField = ({
|
|
|
142
145
|
field: FormField,
|
|
143
146
|
setCustomerId: React.Dispatch<React.SetStateAction<string | undefined>>,
|
|
144
147
|
isSinglePage?: boolean,
|
|
145
|
-
|
|
148
|
+
isInQuestionGroup?: boolean,
|
|
149
|
+
logicOptions?: NextFieldLogicOptions,
|
|
150
|
+
} & Pick<TellescopeFormProps, "rootResponseId" | "goToNextField" | "groupId" | "groupInstance" | "submit" | "formResponseId" | 'enduserId' | 'isPreviousDisabled' | 'goToPreviousField' | 'enduser' | 'handleDatabaseSelect' | 'onAddFile' | 'onFieldChange' | 'fields' | 'customInputs' | 'responses' | 'selectedFiles' | 'validateField'>) => {
|
|
146
151
|
const String = customInputs?.['string'] ?? StringInput
|
|
147
152
|
const StringLong = customInputs?.['stringLong'] ?? StringLongInput
|
|
148
153
|
const Email = customInputs?.['email'] ?? EmailInput
|
|
@@ -183,6 +188,13 @@ export const QuestionForField = ({
|
|
|
183
188
|
), [field.feedback, value])
|
|
184
189
|
|
|
185
190
|
if (!value) return null
|
|
191
|
+
if (
|
|
192
|
+
isInQuestionGroup
|
|
193
|
+
&& field.groupShowCondition && !object_is_empty(field.groupShowCondition)
|
|
194
|
+
&& !responses_satisfy_conditions(responses, field.groupShowCondition, logicOptions)
|
|
195
|
+
) {
|
|
196
|
+
return null
|
|
197
|
+
}
|
|
186
198
|
return (
|
|
187
199
|
// margin leaves room for error message in Question Group
|
|
188
200
|
<Flex column flex={1} style={{ marginBottom: spacing ?? 25 }} id={field.id}>
|
|
@@ -254,7 +266,7 @@ export const QuestionForField = ({
|
|
|
254
266
|
<Height field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
255
267
|
)
|
|
256
268
|
: field.type === 'Redirect' ? (
|
|
257
|
-
<Redirect responses={responses} enduser={enduser} groupId={groupId} groupInsance={groupInstance} submit={submit} field={field} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
269
|
+
<Redirect rootResponseId={rootResponseId} formResponseId={formResponseId} responses={responses} enduser={enduser} groupId={groupId} groupInsance={groupInstance} submit={submit} field={field} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
258
270
|
)
|
|
259
271
|
: field.type === 'Related Contacts' ? (
|
|
260
272
|
<RelatedContacts field={field} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
@@ -337,13 +349,15 @@ export const QuestionForField = ({
|
|
|
337
349
|
<Flex key={id} flex={1}>
|
|
338
350
|
<QuestionForField groupId={groupId} groupInstance={groupInstance} customInputs={customInputs} field={match} fields={fields} handleDatabaseSelect={handleDatabaseSelect}
|
|
339
351
|
enduser={enduser} goToPreviousField={goToPreviousField} isPreviousDisabled={isPreviousDisabled} goToNextField={goToNextField}
|
|
340
|
-
form={form} formResponseId={formResponseId} submit={submit}
|
|
352
|
+
form={form} formResponseId={formResponseId} rootResponseId={rootResponseId} submit={submit}
|
|
341
353
|
repeats={repeats} onRepeatsChange={onRepeatsChange} setCustomerId={setCustomerId}
|
|
342
354
|
value={value} file={file}
|
|
343
355
|
onAddFile={onAddFile} onFieldChange={onFieldChange}
|
|
344
356
|
responses={responses} selectedFiles={selectedFiles}
|
|
345
357
|
validateField={validateField} enduserId={enduserId}
|
|
346
358
|
spacing={field.options?.groupPadding}
|
|
359
|
+
logicOptions={logicOptions}
|
|
360
|
+
isInQuestionGroup
|
|
347
361
|
/>
|
|
348
362
|
</Flex>
|
|
349
363
|
)
|
|
@@ -428,6 +442,7 @@ export const TellescopeSingleQuestionFlow: typeof TellescopeForm = ({
|
|
|
428
442
|
formResponseId,
|
|
429
443
|
groupId,
|
|
430
444
|
groupInstance,
|
|
445
|
+
logicOptions,
|
|
431
446
|
}) => {
|
|
432
447
|
const beforeunloadHandler = React.useCallback((e: BeforeUnloadEvent) => {
|
|
433
448
|
try {
|
|
@@ -525,6 +540,7 @@ export const TellescopeSingleQuestionFlow: typeof TellescopeForm = ({
|
|
|
525
540
|
responses={responses} selectedFiles={selectedFiles}
|
|
526
541
|
validateField={validateField}
|
|
527
542
|
groupId={groupId} groupInstance={groupInstance}
|
|
543
|
+
logicOptions={logicOptions}
|
|
528
544
|
/>
|
|
529
545
|
</Flex>
|
|
530
546
|
</Flex>
|
|
@@ -622,6 +638,13 @@ export const ThanksMessage = ({
|
|
|
622
638
|
<Typography style={{ marginTop: 25, alignSelf: 'center' }}>{thanksMessage || DEFAULT_THANKS_MESSAGE}</Typography>
|
|
623
639
|
)
|
|
624
640
|
}
|
|
641
|
+
{read_local_storage('redirecting_public_group') === 'true' &&
|
|
642
|
+
<>
|
|
643
|
+
<Typography style={{ marginTop: 25, alignSelf: 'center' }}>
|
|
644
|
+
Redirecting to next form... <CircularProgress size={20} color="primary" />
|
|
645
|
+
</Typography>
|
|
646
|
+
</>
|
|
647
|
+
}
|
|
625
648
|
{downloadComponent &&
|
|
626
649
|
<Flex justifyContent="center" style={{ marginTop: 15, marginBottom: 15 }}>
|
|
627
650
|
{downloadComponent}
|
|
@@ -987,7 +1010,7 @@ export const TellescopeSinglePageForm: React.JSXElementConstructor<TellescopeFor
|
|
|
987
1010
|
<Flex key={activeField.id} style={{ marginBottom: 5 }}>
|
|
988
1011
|
<Flex column flex={1}>
|
|
989
1012
|
<QuestionForField isSinglePage fields={fields} field={activeField} handleDatabaseSelect={handleDatabaseSelect}
|
|
990
|
-
enduserId={props.enduserId} formResponseId={props.formResponseId} submit={submit}
|
|
1013
|
+
enduserId={props.enduserId} formResponseId={props.formResponseId} rootResponseId={rootResponseId} submit={submit}
|
|
991
1014
|
enduser={enduser} goToPreviousField={goToPreviousField} isPreviousDisabled={isPreviousDisabled} goToNextField={goToNextField}
|
|
992
1015
|
repeats={repeats} onRepeatsChange={setRepeats} setCustomerId={setCustomerId}
|
|
993
1016
|
value={value} file={file}
|
package/src/Forms/hooks.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { WithTheme, contact_is_valid, useFileUpload, useFormFields, useFormRespo
|
|
|
9
9
|
import ReactGA from "react-ga4";
|
|
10
10
|
|
|
11
11
|
import isEmail from "validator/lib/isEmail"
|
|
12
|
-
import { append_current_utm_params, field_can_autoadvance, getLocalTimezone, get_time_values, get_utm_params, is_object, object_is_empty, responses_satisfy_conditions } from "@tellescope/utilities"
|
|
12
|
+
import { append_current_utm_params, field_can_autoadvance, getLocalTimezone, get_time_values, get_utm_params, is_object, object_is_empty, responses_satisfy_conditions, update_local_storage } from "@tellescope/utilities"
|
|
13
13
|
|
|
14
14
|
export const useFlattenedTree = (root?: FormFieldNode) => {
|
|
15
15
|
const flat: FormField[] = []
|
|
@@ -194,14 +194,16 @@ export const useTreeForFormFields = (_fields: FormField[]) => {
|
|
|
194
194
|
return nodesForId[fields.find(s => s.previousFields.find(p => p.type === 'root'))?.id ?? '']
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
export
|
|
197
|
+
export type NextFieldLogicOptions = {
|
|
198
198
|
urlLogicValue?: string,
|
|
199
199
|
dateOfBirth?: string,
|
|
200
200
|
gender?: string,
|
|
201
201
|
state?: string,
|
|
202
202
|
form?: Form,
|
|
203
203
|
activeResponses?: FormResponseValue[], // current and previous answers (not future answers)
|
|
204
|
-
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export const getNextField = (activeField: FormFieldNode, currentValue: Response, responses: FormResponseValue[], options?: NextFieldLogicOptions) => {
|
|
205
207
|
if (activeField.children.length === 0) {
|
|
206
208
|
return
|
|
207
209
|
}
|
|
@@ -360,6 +362,7 @@ interface UseTellescopeFormOptions {
|
|
|
360
362
|
context?: string,
|
|
361
363
|
urlLogicValue?: string,
|
|
362
364
|
enduser?: Partial<Enduser>,
|
|
365
|
+
isPublicForm?: boolean,
|
|
363
366
|
}
|
|
364
367
|
|
|
365
368
|
const OrganizationThemeContext = createContext(null as any as {
|
|
@@ -508,7 +511,7 @@ const shouldCallout = (field: FormField | undefined, value: FormResponseValueAns
|
|
|
508
511
|
|
|
509
512
|
export type Response = FormResponseValue & { touched: boolean, includeInSubmit: boolean, field: FormField }
|
|
510
513
|
export type FileResponse = { fieldId: string, fieldTitle: string, blobs?: FileBlob[] }
|
|
511
|
-
export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlanId, calendarEventId, context, ga4measurementId, rootResponseId, parentResponseId, accessCode, existingResponses, automationStepId, enduserId, formResponseId, fields, isInternalNote, formTitle, submitRedirectURL,enduser }: UseTellescopeFormOptions) => {
|
|
514
|
+
export const useTellescopeForm = ({ isPublicForm, form, urlLogicValue, customization, carePlanId, calendarEventId, context, ga4measurementId, rootResponseId, parentResponseId, accessCode, existingResponses, automationStepId, enduserId, formResponseId, fields, isInternalNote, formTitle, submitRedirectURL,enduser }: UseTellescopeFormOptions) => {
|
|
512
515
|
const { amPm, hoursAmPm, minutes } = get_time_values(new Date())
|
|
513
516
|
|
|
514
517
|
const root = useTreeForFormFields(fields)
|
|
@@ -675,6 +678,15 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
675
678
|
selectedFiles.find(f => f.fieldId === activeField.value.id)
|
|
676
679
|
)
|
|
677
680
|
|
|
681
|
+
const logicOptions: NextFieldLogicOptions = {
|
|
682
|
+
urlLogicValue,
|
|
683
|
+
activeResponses: responses.filter(r => r.includeInSubmit),
|
|
684
|
+
dateOfBirth: enduser?.dateOfBirth,
|
|
685
|
+
gender: enduser?.gender,
|
|
686
|
+
state: enduser?.state,
|
|
687
|
+
form,
|
|
688
|
+
}
|
|
689
|
+
|
|
678
690
|
const handleDatabaseSelect = useCallback((databaseRecords: Pick<DatabaseRecord, "values" | "databaseId">[]) => {
|
|
679
691
|
try {
|
|
680
692
|
// no need to update if there's no prepopulation
|
|
@@ -794,6 +806,15 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
794
806
|
if (!value) return "Value not provided"
|
|
795
807
|
if (!file) return "File not provided"
|
|
796
808
|
|
|
809
|
+
// if question is in group, and question is hidden in group, don't validate
|
|
810
|
+
if (
|
|
811
|
+
field.isInGroup
|
|
812
|
+
&& field.groupShowCondition && !object_is_empty(field.groupShowCondition)
|
|
813
|
+
&& !responses_satisfy_conditions(responses, field.groupShowCondition, logicOptions)
|
|
814
|
+
) {
|
|
815
|
+
return null
|
|
816
|
+
}
|
|
817
|
+
|
|
797
818
|
if (value.answer.type === 'Insurance') {
|
|
798
819
|
if (value.answer.value?.relationshipDetails?.dateOfBirth && !isDateString(value.answer.value.relationshipDetails.dateOfBirth)) {
|
|
799
820
|
return "Enter date of birth in MM-DD-YYYY format"
|
|
@@ -1014,7 +1035,7 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1014
1035
|
}
|
|
1015
1036
|
|
|
1016
1037
|
return null
|
|
1017
|
-
}, [responses, selectedFiles, currentValue, activeField, repeats, sessionType])
|
|
1038
|
+
}, [responses, selectedFiles, currentValue, activeField, repeats, sessionType, logicOptions])
|
|
1018
1039
|
|
|
1019
1040
|
// nested Question Group fields are disabled, so it's safe to avoid recursion multiple times
|
|
1020
1041
|
const validateField = useCallback((field: FormField) => {
|
|
@@ -1058,14 +1079,7 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1058
1079
|
const nextField = (
|
|
1059
1080
|
!currentValue ? undefined
|
|
1060
1081
|
: (
|
|
1061
|
-
getNextField(activeField, currentValue, responses,
|
|
1062
|
-
urlLogicValue,
|
|
1063
|
-
form,
|
|
1064
|
-
activeResponses: responses.filter(r => r.includeInSubmit),
|
|
1065
|
-
dateOfBirth: enduser?.dateOfBirth,
|
|
1066
|
-
gender: enduser?.gender,
|
|
1067
|
-
state: enduser?.state,
|
|
1068
|
-
})
|
|
1082
|
+
getNextField(activeField, currentValue, responses, logicOptions)
|
|
1069
1083
|
)
|
|
1070
1084
|
)
|
|
1071
1085
|
|
|
@@ -1155,6 +1169,12 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1155
1169
|
const match = responses.find(r => r.fieldId === f?.id)
|
|
1156
1170
|
if (!match || responsesToSubmit.find(r => r.fieldId === match.fieldId)) continue
|
|
1157
1171
|
|
|
1172
|
+
// hidden in group by conditional logic
|
|
1173
|
+
if ((
|
|
1174
|
+
match.field.groupShowCondition && !object_is_empty(match.field.groupShowCondition)
|
|
1175
|
+
&& !responses_satisfy_conditions(responses, match.field.groupShowCondition, logicOptions)
|
|
1176
|
+
)) continue
|
|
1177
|
+
|
|
1158
1178
|
responsesToSubmit.push(match)
|
|
1159
1179
|
}
|
|
1160
1180
|
}
|
|
@@ -1162,7 +1182,8 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1162
1182
|
const errors: { enduserId: string, message: string }[] = []
|
|
1163
1183
|
for (const eId of [enduserId, ...(options?.otherEnduserIds ?? [])]) {
|
|
1164
1184
|
try {
|
|
1165
|
-
|
|
1185
|
+
update_local_storage('redirecting_public_group', '')
|
|
1186
|
+
const { formResponse, nextFormGroupPublicURL } = await session.api.form_responses.submit_form_response({
|
|
1166
1187
|
accessCode : (
|
|
1167
1188
|
accessCode
|
|
1168
1189
|
|| (await (
|
|
@@ -1186,6 +1207,12 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1186
1207
|
productIds: responsesToSubmit.flatMap(r => r.field?.options?.productIds ?? []),
|
|
1187
1208
|
utm: get_utm_params(),
|
|
1188
1209
|
})
|
|
1210
|
+
|
|
1211
|
+
// do actual redirect later to prevent popup
|
|
1212
|
+
if (isPublicForm && nextFormGroupPublicURL) {
|
|
1213
|
+
update_local_storage('redirecting_public_group', 'true')
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1189
1216
|
if (!options?.otherEnduserIds?.length) { // only track for signle submission
|
|
1190
1217
|
if (ga4measurementId) {
|
|
1191
1218
|
ReactGA.event({
|
|
@@ -1206,6 +1233,10 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1206
1233
|
options?.onSuccess?.(formResponse)
|
|
1207
1234
|
}
|
|
1208
1235
|
}
|
|
1236
|
+
|
|
1237
|
+
if (isPublicForm && nextFormGroupPublicURL) {
|
|
1238
|
+
window.location.href = nextFormGroupPublicURL
|
|
1239
|
+
}
|
|
1209
1240
|
} catch(err: any) {
|
|
1210
1241
|
if (options?.onBulkErrors) { // only track for signle submission
|
|
1211
1242
|
errors.push({ enduserId: eId, message: err?.message || err?.toString() })
|
|
@@ -1229,7 +1260,7 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1229
1260
|
} finally {
|
|
1230
1261
|
setSubmittingStatus(undefined)
|
|
1231
1262
|
}
|
|
1232
|
-
}, [accessCode, automationStepId, enduserId, responses, selectedFiles, session, handleUpload, existingResponses, ga4measurementId, rootResponseId, parentResponseId, calendarEventId, goBackURL])
|
|
1263
|
+
}, [accessCode, automationStepId, enduserId, responses, selectedFiles, session, handleUpload, existingResponses, ga4measurementId, rootResponseId, parentResponseId, calendarEventId, goBackURL, logicOptions])
|
|
1233
1264
|
|
|
1234
1265
|
const isNextDisabled = useCallback(() => {
|
|
1235
1266
|
if (activeField.children.length === 0) {
|
|
@@ -1274,14 +1305,7 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1274
1305
|
|
|
1275
1306
|
try { window.scrollTo({ top: 0 }) } catch(err) {} // scroll to top if needed
|
|
1276
1307
|
setActiveField(activeField => {
|
|
1277
|
-
let newField = getNextField(activeField, currentValue, responses,
|
|
1278
|
-
urlLogicValue,
|
|
1279
|
-
form,
|
|
1280
|
-
activeResponses: responses.filter(r => r.includeInSubmit),
|
|
1281
|
-
dateOfBirth: enduser?.dateOfBirth,
|
|
1282
|
-
gender: enduser?.gender,
|
|
1283
|
-
state: enduser?.state,
|
|
1284
|
-
})
|
|
1308
|
+
let newField = getNextField(activeField, currentValue, responses, logicOptions)
|
|
1285
1309
|
|
|
1286
1310
|
// when autoadvancing, prevent adding duplicates by checking whether already on stack
|
|
1287
1311
|
if (newField !== undefined && !prevFieldStackRef.current.find(v => v.value.id === activeField?.value.id)) {
|
|
@@ -1291,7 +1315,7 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1291
1315
|
|
|
1292
1316
|
return newField || activeField
|
|
1293
1317
|
})
|
|
1294
|
-
}, [prevFieldStackRef, currentValue, isNextDisabled, updateFormResponse, session, responses,
|
|
1318
|
+
}, [prevFieldStackRef, currentValue, isNextDisabled, updateFormResponse, session, responses, logicOptions])
|
|
1295
1319
|
|
|
1296
1320
|
useEffect(() => {
|
|
1297
1321
|
if (!autoAdvanceRef.current) return
|
|
@@ -1420,5 +1444,6 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
1420
1444
|
setCustomerId,
|
|
1421
1445
|
customization,
|
|
1422
1446
|
handleDatabaseSelect,
|
|
1447
|
+
logicOptions,
|
|
1423
1448
|
}
|
|
1424
1449
|
}
|
package/src/Forms/inputs.tsx
CHANGED
|
@@ -2944,7 +2944,8 @@ export const HeightInput = ({ field, value={} as any, onChange, ...props }: Form
|
|
|
2944
2944
|
</Grid>
|
|
2945
2945
|
)
|
|
2946
2946
|
|
|
2947
|
-
export const RedirectInput = ({ groupId, groupInsance, formResponseId, field, submit, value={} as any, onChange, responses, enduser, ...props }: FormInputProps<'Redirect'>) => {
|
|
2947
|
+
export const RedirectInput = ({ groupId, groupInsance, rootResponseId, formResponseId, field, submit, value={} as any, onChange, responses, enduser, ...props }: FormInputProps<'Redirect'>) => {
|
|
2948
|
+
console.log('formResponseId', formResponseId, 'rootResponseId', rootResponseId)
|
|
2948
2949
|
const session = useResolvedSession()
|
|
2949
2950
|
|
|
2950
2951
|
let eId = ''
|
|
@@ -3007,7 +3008,7 @@ export const RedirectInput = ({ groupId, groupInsance, formResponseId, field, su
|
|
|
3007
3008
|
session.api.form_responses.prepare_form_response({
|
|
3008
3009
|
enduserId: session.userInfo.id || eId,
|
|
3009
3010
|
formId: field.options.redirectFormId,
|
|
3010
|
-
rootResponseId: formResponseId,
|
|
3011
|
+
rootResponseId: rootResponseId || formResponseId,
|
|
3011
3012
|
parentResponseId: formResponseId,
|
|
3012
3013
|
})
|
|
3013
3014
|
.then(({ fullURL }) => (
|
package/src/Forms/types.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface FormInputProps<K extends keyof AnswerForType> {
|
|
|
26
26
|
goToNextField?: () => void,
|
|
27
27
|
isPreviousDisabled?: () => boolean,
|
|
28
28
|
formResponseId?: string,
|
|
29
|
+
rootResponseId?: string,
|
|
29
30
|
submit?: () => Promise<void>,
|
|
30
31
|
groupId?: string,
|
|
31
32
|
groupInsance?: string,
|
package/src/mui.native.tsx
CHANGED
|
@@ -189,7 +189,7 @@ export const Typography = ({ children, onClick, onPress, color, style, ...props
|
|
|
189
189
|
const colorStyle = { color: color ? useTheme().colors[color] : undefined }
|
|
190
190
|
|
|
191
191
|
return (
|
|
192
|
-
<MuiText onPress={onPress ?? onClick} style={{ ...colorStyle, ...convert_CSS_to_RNStyles(style) }}>
|
|
192
|
+
<MuiText {...props} onPress={onPress ?? onClick} style={{ ...colorStyle, ...convert_CSS_to_RNStyles(style) }}>
|
|
193
193
|
{children}
|
|
194
194
|
</MuiText>
|
|
195
195
|
)
|
package/src/mui.tsx
CHANGED
|
@@ -263,6 +263,7 @@ export type TypographyProps = {
|
|
|
263
263
|
component?: 'span' | 'p' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5',
|
|
264
264
|
noWrap?: boolean,
|
|
265
265
|
title?: string,
|
|
266
|
+
selectable?: boolean,
|
|
266
267
|
} & Clickable
|
|
267
268
|
export const Typography = ({ children, onClick, onPress, component='span', ...props}: TypographyProps & ClickableWeb) => {
|
|
268
269
|
return <MuiTypography onClick={onClick ?? onPress} component={component} {...props}>{children}</MuiTypography>
|