@tellescope/react-components 1.206.0 → 1.208.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.
Files changed (69) hide show
  1. package/lib/cjs/Forms/forms.d.ts +2 -0
  2. package/lib/cjs/Forms/forms.d.ts.map +1 -1
  3. package/lib/cjs/Forms/forms.js +7 -4
  4. package/lib/cjs/Forms/forms.js.map +1 -1
  5. package/lib/cjs/Forms/hooks.d.ts.map +1 -1
  6. package/lib/cjs/Forms/hooks.js +41 -36
  7. package/lib/cjs/Forms/hooks.js.map +1 -1
  8. package/lib/cjs/Forms/inputs.d.ts.map +1 -1
  9. package/lib/cjs/Forms/inputs.js +4 -1
  10. package/lib/cjs/Forms/inputs.js.map +1 -1
  11. package/lib/cjs/inputs_shared.d.ts.map +1 -1
  12. package/lib/cjs/inputs_shared.js +25 -1
  13. package/lib/cjs/inputs_shared.js.map +1 -1
  14. package/lib/cjs/layout.d.ts +5 -1
  15. package/lib/cjs/layout.d.ts.map +1 -1
  16. package/lib/cjs/layout.js +3 -3
  17. package/lib/cjs/layout.js.map +1 -1
  18. package/lib/cjs/state.d.ts +37 -0
  19. package/lib/cjs/state.d.ts.map +1 -1
  20. package/lib/cjs/state.js +19 -3
  21. package/lib/cjs/state.js.map +1 -1
  22. package/lib/cjs/table.d.ts +2 -1
  23. package/lib/cjs/table.d.ts.map +1 -1
  24. package/lib/cjs/table.js +3 -2
  25. package/lib/cjs/table.js.map +1 -1
  26. package/lib/esm/CMS/components.d.ts +0 -1
  27. package/lib/esm/CMS/components.d.ts.map +1 -1
  28. package/lib/esm/Forms/form_responses.d.ts +0 -1
  29. package/lib/esm/Forms/form_responses.d.ts.map +1 -1
  30. package/lib/esm/Forms/forms.d.ts +5 -3
  31. package/lib/esm/Forms/forms.d.ts.map +1 -1
  32. package/lib/esm/Forms/forms.js +7 -4
  33. package/lib/esm/Forms/forms.js.map +1 -1
  34. package/lib/esm/Forms/hooks.d.ts +0 -1
  35. package/lib/esm/Forms/hooks.d.ts.map +1 -1
  36. package/lib/esm/Forms/hooks.js +42 -37
  37. package/lib/esm/Forms/hooks.js.map +1 -1
  38. package/lib/esm/Forms/inputs.d.ts +1 -1
  39. package/lib/esm/Forms/inputs.d.ts.map +1 -1
  40. package/lib/esm/Forms/inputs.js +5 -2
  41. package/lib/esm/Forms/inputs.js.map +1 -1
  42. package/lib/esm/controls.d.ts +2 -2
  43. package/lib/esm/inputs.d.ts +1 -1
  44. package/lib/esm/inputs.native.d.ts +0 -1
  45. package/lib/esm/inputs.native.d.ts.map +1 -1
  46. package/lib/esm/inputs_shared.d.ts.map +1 -1
  47. package/lib/esm/inputs_shared.js +25 -1
  48. package/lib/esm/inputs_shared.js.map +1 -1
  49. package/lib/esm/layout.d.ts +5 -1
  50. package/lib/esm/layout.d.ts.map +1 -1
  51. package/lib/esm/layout.js +3 -3
  52. package/lib/esm/layout.js.map +1 -1
  53. package/lib/esm/state.d.ts +81 -44
  54. package/lib/esm/state.d.ts.map +1 -1
  55. package/lib/esm/state.js +15 -0
  56. package/lib/esm/state.js.map +1 -1
  57. package/lib/esm/table.d.ts +2 -1
  58. package/lib/esm/table.d.ts.map +1 -1
  59. package/lib/esm/table.js +3 -2
  60. package/lib/esm/table.js.map +1 -1
  61. package/lib/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +11 -11
  63. package/src/Forms/forms.tsx +6 -3
  64. package/src/Forms/hooks.tsx +8 -4
  65. package/src/Forms/inputs.tsx +6 -2
  66. package/src/inputs_shared.tsx +17 -1
  67. package/src/layout.tsx +5 -2
  68. package/src/state.tsx +22 -0
  69. package/src/table.tsx +6 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/react-components",
3
- "version": "1.206.0",
3
+ "version": "1.208.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.206.0",
51
- "@tellescope/sdk": "^1.206.0",
52
- "@tellescope/types-client": "^1.206.0",
53
- "@tellescope/types-models": "^1.206.0",
54
- "@tellescope/types-utilities": "^1.206.0",
55
- "@tellescope/utilities": "^1.206.0",
56
- "@tellescope/validation": "^1.206.0",
50
+ "@tellescope/constants": "^1.208.0",
51
+ "@tellescope/sdk": "^1.208.0",
52
+ "@tellescope/types-client": "^1.208.0",
53
+ "@tellescope/types-models": "^1.208.0",
54
+ "@tellescope/types-utilities": "^1.208.0",
55
+ "@tellescope/utilities": "^1.208.0",
56
+ "@tellescope/validation": "^1.208.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,11 +80,11 @@
80
80
  "yup": "^0.32.10"
81
81
  },
82
82
  "peerDependencies": {
83
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
84
- "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
83
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
84
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
85
85
  "react-native": "^0.65.0 || ^0.66.0 || ^0.67.0 || ^0.68.0 || ^0.71.0"
86
86
  },
87
- "gitHead": "d806743ca9f51d8abb2464d25f4d093e3b58a55f",
87
+ "gitHead": "386150ae354f2879790b6dbf5d5064eca5015b83",
88
88
  "publishConfig": {
89
89
  "access": "public"
90
90
  }
@@ -20,6 +20,7 @@ export const TellescopeFormContainer = ({ businessId, organizationIds, ...props
20
20
  logoHeight?: number,
21
21
  language?: string,
22
22
  onChangeLanguage?: (l: string) => void,
23
+ paperMinHeight?: React.CSSProperties['minHeight'],
23
24
  } & Styled) => {
24
25
  // if context already is provided, no need to duplicate
25
26
  if (props.dontAddContext) return (
@@ -33,7 +34,7 @@ export const TellescopeFormContainer = ({ businessId, organizationIds, ...props
33
34
  )
34
35
  }
35
36
 
36
- const TellescopeFormContainerWithTheme: typeof TellescopeFormContainer = ({ children, language, onChangeLanguage, style, hideBg, backgroundColor, hideLogo, logoHeight }) => {
37
+ const TellescopeFormContainerWithTheme: typeof TellescopeFormContainer = ({ paperMinHeight=575, children, language, onChangeLanguage, style, hideBg, backgroundColor, hideLogo, logoHeight }) => {
37
38
  const theme = useOrganizationTheme()
38
39
 
39
40
  const formContent = (
@@ -71,7 +72,7 @@ const TellescopeFormContainerWithTheme: typeof TellescopeFormContainer = ({ chil
71
72
  }
72
73
  return (
73
74
  <Flex flex={1} alignItems="center" justifyContent="center" style={{ backgroundColor: backgroundColor ?? theme.themeColor ?? '#ffffff', ...style }}>
74
- <Paper flex elevation={3} style={{ marginTop: 50, marginBottom: 50, padding: 20, maxWidth: 650, minWidth: 250, minHeight: 575 }}>
75
+ <Paper flex elevation={3} style={{ marginTop: 50, marginBottom: 50, padding: 20, maxWidth: 650, minWidth: 250, minHeight: paperMinHeight }}>
75
76
  {formContent}
76
77
  </Paper>
77
78
  </Flex>
@@ -96,12 +97,13 @@ export interface TellescopeFormProps extends ReturnType<typeof useTellescopeForm
96
97
  enduser?: Partial<Enduser>,
97
98
  groupId?: string,
98
99
  groupInstance?: string,
100
+ logoHeight?: number,
99
101
  }
100
102
 
101
103
  const LOGO_HEIGHT = 40
102
104
  export const TellescopeForm = (props : TellescopeFormProps & Styled & { hideBg?: boolean, theme?: OrganizationTheme, inputStyle?: React.CSSProperties }) => (
103
105
  <WithOrganizationTheme>
104
- <TellescopeFormWithContext {...props} />
106
+ <TellescopeFormWithContext {...props} logoHeight={props?.logoHeight || props?.form?.customization?.logoHeight} />
105
107
  </WithOrganizationTheme>
106
108
  )
107
109
 
@@ -697,6 +699,7 @@ const TellescopeFormWithContext: typeof TellescopeForm = (props) => {
697
699
  return (
698
700
  <TellescopeFormContainer style={props.style} dontAddContext
699
701
  hideBg={props.hideBg || props.form?.customization?.hideBg}
702
+ logoHeight={props.logoHeight}
700
703
  backgroundColor={props.backgroundColor}
701
704
  hideLogo={props?.customization?.hideLogo}
702
705
  >
@@ -9,7 +9,7 @@ import { WithTheme, contact_is_valid, useAddGTMTag, useFileUpload, useFormFields
9
9
  import ReactGA from "react-ga4";
10
10
 
11
11
  import isEmail from "validator/lib/isEmail"
12
- import { append_current_utm_params, emit_gtm_event, field_can_autoadvance, getLocalTimezone, get_time_values, get_utm_params, is_object, object_is_empty, responses_satisfy_conditions, update_local_storage } from "@tellescope/utilities"
12
+ import { append_current_utm_params, emit_gtm_event, field_can_autoadvance, getLocalTimezone, get_time_values, get_utm_params, is_object, object_is_empty, read_local_storage, responses_satisfy_conditions, update_local_storage } from "@tellescope/utilities"
13
13
 
14
14
  export const useFlattenedTree = (root?: FormFieldNode) => {
15
15
  const flat: FormField[] = []
@@ -653,9 +653,7 @@ export const useTellescopeForm = ({ dontAutoadvance, isPublicForm, form, urlLogi
653
653
  ? (
654
654
  (f.options?.default && !isNaN(parseInt(f.options.default)))
655
655
  ? parseInt(f.options.default)
656
- : f.isOptional
657
- ? undefined
658
- : (f.options?.from || 1)
656
+ : undefined // shows no selection on slider
659
657
  )
660
658
  : f.type === 'Related Contacts'
661
659
  ? (f.isOptional ? [] : [{ relationships: f?.options?.relatedContactTypes?.length === 1 ? [{ type: f.options.relatedContactTypes[0] as EnduserRelationship['type'], id: ''! } ] : [] }])
@@ -1299,6 +1297,12 @@ export const useTellescopeForm = ({ dontAutoadvance, isPublicForm, form, urlLogi
1299
1297
  if (submitRedirectURL) {
1300
1298
  (window?.top ?? window).location.href = append_current_utm_params(submitRedirectURL);
1301
1299
  }
1300
+ if (form?.redirectToBookedAppointmentOnSubmit) {
1301
+ const url = read_local_storage('tellescope_last_booking_page_join_link')
1302
+ if (url) {
1303
+ (window?.top ?? window).location.href = append_current_utm_params(url);
1304
+ }
1305
+ }
1302
1306
  } catch(err: any) {
1303
1307
  console.error(err)
1304
1308
  setSubmitErrorMessage(err?.message ?? 'An error occurred')
@@ -4,7 +4,7 @@ import { Autocomplete, Box, Button, Checkbox, Chip, Divider, FormControl, FormCo
4
4
  import { FormInputProps } from "./types"
5
5
  import { useDropzone } from "react-dropzone"
6
6
  import { CANVAS_TITLE, EMOTII_TITLE, INSURANCE_RELATIONSHIPS, INSURANCE_RELATIONSHIPS_CANVAS, PRIMARY_HEX, RELATIONSHIP_TYPES, TELLESCOPE_GENDERS } from "@tellescope/constants"
7
- import { MM_DD_YYYY_to_YYYY_MM_DD, capture_is_supported, downloadFile, emit_gtm_event, first_letter_capitalized, form_response_value_to_string, getLocalTimezone, getPublicFileURL, mm_dd_yyyy, replace_enduser_template_values, truncate_string, user_display_name } from "@tellescope/utilities"
7
+ import { MM_DD_YYYY_to_YYYY_MM_DD, capture_is_supported, downloadFile, emit_gtm_event, first_letter_capitalized, form_response_value_to_string, getLocalTimezone, getPublicFileURL, mm_dd_yyyy, replace_enduser_template_values, truncate_string, update_local_storage, user_display_name } from "@tellescope/utilities"
8
8
  import { DatabaseSelectResponse, Enduser, EnduserRelationship, FormResponseValue, InsuranceRelationship, MedicationResponse, MultipleChoiceOptions, TellescopeGender } from "@tellescope/types-models"
9
9
  import { VALID_STATES, emailValidator, phoneValidator } from "@tellescope/validation"
10
10
  import Slider from '@mui/material/Slider';
@@ -2900,7 +2900,11 @@ export const AppointmentBookingInput = ({ formResponseId, field, value, onChange
2900
2900
  }
2901
2901
  if (m?.data?.type === 'Confirmation') {
2902
2902
  setConfirming(true)
2903
- } else {
2903
+ }
2904
+ if (m?.data?.type === 'Join Link' && m?.data?.link) {
2905
+ update_local_storage('tellescope_last_booking_page_join_link', m.data.link)
2906
+ }
2907
+ else {
2904
2908
  setConfirming(false)
2905
2909
  }
2906
2910
  }
@@ -9,6 +9,7 @@ import { AgentRecord, AllergyCode, AppointmentBookingPage, AppointmentLocation,
9
9
  import { Button, Checkbox, Flex, HoverPaper, LoadingButton, LoadingData, ScrollingList, SearchTextInput, Typography, useAgentRecords, useAllergyCodes, useAppointmentBookingPages, useAppointmentLocations, useAutomationTriggers, useCalendarEventTemplates, useCallHoldQueues, useChatRooms, useDatabaseRecords, useDatabases, useDiagnosisCodes, useEnduserCustomTypes, useEnduserOrders, useEndusers, useFaxLogs, useFiles, useFormGroups, useForms, useForums, useJourneys, useManagedContentRecords, useMessageTemplateSnippets, useNotifications, useOrganization, useOrganizations, usePrescriptionRoutes, useResolvedSession, useSession, useSuggestedContacts, useTemplates, useTicketQueues, useTickets, useUsers, useWaitlists, value_is_loaded } from "."
10
10
  import { SxProps } from "@mui/material"
11
11
  import { AccessPermissions, ListOfStringsWithQualifier } from "@tellescope/types-models"
12
+ import { phoneValidator } from "@tellescope/validation"
12
13
 
13
14
  export type FilterV2 = Record<string, any>
14
15
  export type FiltersV2 = Record<string, FilterV2>
@@ -885,7 +886,22 @@ export const EnduserSearch = (props: Omit<GenericSearchProps<Enduser>, 'filterKe
885
886
  if (((session.userInfo as any)?.access as AccessPermissions)?.users?.read === ALL_ACCESS && !value_is_loaded(usersLoading)) return null
886
887
  return (
887
888
  <ModelSearchInput filterKey="endusers" {...props}
888
- searchAPI={session.api.endusers.getSome}
889
+ searchAPI={async ({ search }) => {
890
+ // handle case of formatted phone number in search bar by parsing to standard phone format and searching explicitly by phone
891
+ // in this case, also search by generic search term in case user is intending to search by something else (e.g. externalId)
892
+ try {
893
+ const phone = phoneValidator.validate()(search.query)
894
+ if (phone) {
895
+ return (
896
+ await Promise.all([
897
+ session.api.endusers.getSome({ filter: { phone }}),
898
+ session.api.endusers.getSome({ search }),
899
+ ])
900
+ ).flatMap(v => v)
901
+ }
902
+ } catch(err) {}
903
+ return session.api.endusers.getSome({ search })
904
+ }}
889
905
  onLoad={addLocalElements}
890
906
  attachSearchableFields={t => {
891
907
  const users = t.assignedTo?.map(userId => findUser(userId, { batch: true })).filter(u => u) as User[]
package/src/layout.tsx CHANGED
@@ -282,6 +282,7 @@ export type TitleComponentType = React.JSXElementConstructor<{ title?: React.Rea
282
282
  export interface ScrollingListProps <T extends { id: string | number }> extends Styled {
283
283
  items: T[],
284
284
  Item: React.JSXElementConstructor<{ item: T, index: number }>
285
+ renderItem?: (p: { item: T, index: number }) => React.ReactElement,
285
286
  title?: React.ReactNode,
286
287
  header?: React.ReactNode,
287
288
  emptyText?: React.ReactNode,
@@ -317,6 +318,7 @@ export const ScrollingList = <T extends { id: string | number }>({
317
318
  doneLoading,
318
319
  loadMore,
319
320
  Item,
321
+ renderItem,
320
322
  TitleComponent,
321
323
  titleActionsComponent,
322
324
  style,
@@ -410,7 +412,8 @@ export const ScrollingList = <T extends { id: string | number }>({
410
412
  >
411
413
  {({ data, index, style }) => (
412
414
  <div style={style}>
413
- <Item key={data[index].id} item={data[index]} index={index} />
415
+ {renderItem ? renderItem({ item: data[index], index }) : <Item key={data[index].id} item={data[index]} index={index} />}
416
+
414
417
  {index === items.length -1 && loadMore && !doneLoading?.() &&
415
418
  <div style={{ textAlign: 'center' }}>
416
419
  <LoadingButton submitText="Load Older Data" submittingText="Loading..."
@@ -424,7 +427,7 @@ export const ScrollingList = <T extends { id: string | number }>({
424
427
  </FixedSizeList>
425
428
  ) : (
426
429
  items.map((item, index) => (
427
- <Item key={item.id} item={item} index={index} />
430
+ renderItem ? renderItem({ item, index }) : <Item key={item.id} item={item} index={index} />
428
431
  ))
429
432
  )
430
433
  }
package/src/state.tsx CHANGED
@@ -99,6 +99,7 @@ import {
99
99
  EnduserEligibilityResult,
100
100
  AgentRecord,
101
101
  Waitlist,
102
+ AIConversation,
102
103
  } from "@tellescope/types-client"
103
104
 
104
105
  import {
@@ -366,6 +367,7 @@ const integrationLogsSlice = createSliceForList<IntegrationLog, 'integration_log
366
367
  const enduserEligibilityResultsSlice = createSliceForList<EnduserEligibilityResult, 'enduser_eligibility_results'>('enduser_eligibility_results')
367
368
  const agentRecordsSlice = createSliceForList<AgentRecord, 'agent_records'>('agent_records')
368
369
  const waitlistsSlice = createSliceForList<Waitlist, 'waitlists'>('waitlists')
370
+ const aiConversationsSlice = createSliceForList<AIConversation, 'ai_conversations'>('ai_conversations')
369
371
 
370
372
  const roleBasedAccessPermissionsSlice = createSliceForList<RoleBasedAccessPermission, 'role_based_access_permissions'>('role_based_access_permissions')
371
373
 
@@ -374,6 +376,7 @@ const userLogsSlice = createSliceForList<UserLog, 'user_logs'>('user_logs')
374
376
 
375
377
  export const sharedConfig = {
376
378
  reducer: {
379
+ ai_conversations: aiConversationsSlice.reducer,
377
380
  agent_records: agentRecordsSlice.reducer,
378
381
  enduser_eligibility_results: enduserEligibilityResultsSlice.reducer,
379
382
  integration_logs: integrationLogsSlice.reducer,
@@ -1312,6 +1315,25 @@ export const useEnduserEligibilityResults = (options={} as HookOptions<EnduserEl
1312
1315
  )
1313
1316
  }
1314
1317
 
1318
+ export const useAIConversations = (options={} as HookOptions<AIConversation>) => {
1319
+ const session = useSession()
1320
+
1321
+ return useListStateHook('ai_conversations', useTypedSelector(s => s.ai_conversations), session, aiConversationsSlice,
1322
+ {
1323
+ loadQuery: session.api.ai_conversations.getSome,
1324
+ findOne: session.api.ai_conversations.getOne,
1325
+ findByIds: session.api.ai_conversations.getByIds,
1326
+ addOne: session.api.ai_conversations.createOne,
1327
+ addSome: session.api.ai_conversations.createSome,
1328
+ deleteOne: session.api.ai_conversations.deleteOne,
1329
+ updateOne: session.api.ai_conversations.updateOne,
1330
+ },
1331
+ {
1332
+ ...options,
1333
+ },
1334
+ )
1335
+ }
1336
+
1315
1337
  export const useAgentRecords = (options={} as HookOptions<AgentRecord>) => {
1316
1338
  const session = useSession()
1317
1339
 
package/src/table.tsx CHANGED
@@ -769,6 +769,7 @@ export interface TableProps<T extends Item> extends WithTitle, WithHeader<T>, Wi
769
769
  columnResizeZIndex?: number,
770
770
  rowHeight?: number,
771
771
  headerHeight?: number,
772
+ onChangeColumnSorting?: (sorting: Sorting[]) => void,
772
773
  }
773
774
  export const Table = <T extends Item>({
774
775
  items,
@@ -827,6 +828,7 @@ export const Table = <T extends Item>({
827
828
  refreshFilterSuggestionsKey,
828
829
  minColumnWidth,
829
830
  columnResizeZIndex,
831
+ onChangeColumnSorting,
830
832
  }: TableProps<T> & Styled) => {
831
833
  const sortingStorageKey = (memoryId ?? '') + 'sorting'
832
834
  const cachedSortString = read_local_storage(sortingStorageKey)
@@ -883,10 +885,11 @@ export const Table = <T extends Item>({
883
885
  )
884
886
 
885
887
  useEffect(() => {
886
- if (!memoryId) return
887
-
888
+ onChangeColumnSorting?.(sorting)
889
+
890
+ if (!memoryId) return
888
891
  update_local_storage(sortingStorageKey, JSON.stringify(sorting))
889
- }, [sorting, memoryId])
892
+ }, [sorting, memoryId, onChangeColumnSorting])
890
893
 
891
894
  // sorts in place
892
895
  const applySorting = useCallback((items: T[]) => {