@tellescope/react-components 1.151.0 → 1.153.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/react-components",
3
- "version": "1.151.0",
3
+ "version": "1.153.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.151.0",
51
- "@tellescope/sdk": "^1.151.0",
52
- "@tellescope/types-client": "^1.151.0",
53
- "@tellescope/types-models": "^1.151.0",
54
- "@tellescope/types-utilities": "^1.151.0",
55
- "@tellescope/utilities": "^1.151.0",
56
- "@tellescope/validation": "^1.151.0",
50
+ "@tellescope/constants": "^1.153.0",
51
+ "@tellescope/sdk": "^1.153.0",
52
+ "@tellescope/types-client": "^1.153.0",
53
+ "@tellescope/types-models": "^1.153.0",
54
+ "@tellescope/types-utilities": "^1.153.0",
55
+ "@tellescope/utilities": "^1.153.0",
56
+ "@tellescope/validation": "^1.153.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": "c0fe9af3b1861edaeffeb2e7354593486c68f5c9",
83
+ "gitHead": "9433f642d09f85275831104fbdf1dd8ddc8b7a66",
84
84
  "publishConfig": {
85
85
  "access": "public"
86
86
  }
@@ -363,6 +363,22 @@ export const FormResponseView = ({ logoURL, enduser, onClose, hideHeader, respon
363
363
  )
364
364
  })}
365
365
  </div>
366
+
367
+ {(response.addenda || []).length > 0 &&
368
+ <div style={{ borderBottom: '1px solid #00000088', width: '100%', marginTop: 10, marginBottom: 10 }} />
369
+ }
370
+
371
+ {(response.addenda || []).map((a, i) => (
372
+ <div key={i} style={{ marginTop: 10 }}>
373
+ <div style={{ fontWeight: 'bold', fontSize: 15 }}>
374
+ Addendum {i + 1} by {user_display_name(findUser(a.userId, { batch: true }))} at {formatted_date(new Date(a.timestamp))}
375
+ </div>
376
+
377
+ <div style={{ fontSize: 14 }}>
378
+ {a.text.split('\n').map((v, t) => <div key={t}>{v}</div>)}
379
+ </div>
380
+ </div>
381
+ ))}
366
382
  </div>
367
383
  )
368
384
  }
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"
2
2
  import { Button, CircularProgress, Flex, LoadingButton, Modal, Paper, Styled, Typography, form_display_text_for_language, useFileUpload, useFormResponses, useSession } from "../index"
3
3
  import { useListForFormFields, useOrganizationTheme, useTellescopeForm, WithOrganizationTheme, Response, FileResponse } from "./hooks"
4
4
  import { ChangeHandler, FormInputs } from "./types"
5
- import { AddressInput, AppointmentBookingInput, 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"
5
+ import { AddressInput, AllergiesInput, AppointmentBookingInput, 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"
@@ -168,6 +168,7 @@ export const QuestionForField = ({
168
168
  const Redirect = customInputs?.['Redirect'] ?? RedirectInput
169
169
  const HiddenValue = customInputs?.['Hidden Value'] ?? HiddenValueInput
170
170
  const Emotii = customInputs?.['Emotii'] ?? EmotiiInput
171
+ const Allergies = customInputs?.['Allergies'] ?? AllergiesInput
171
172
 
172
173
  const validationMessage = validateField(field)
173
174
 
@@ -242,6 +243,9 @@ export const QuestionForField = ({
242
243
  : field.type === 'Emotii' ? (
243
244
  <Emotii enduser={enduser} enduserId={enduserId} field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
244
245
  )
246
+ : field.type === 'Allergies' ? (
247
+ <Allergies enduser={enduser} enduserId={enduserId} field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
248
+ )
245
249
  : field.type === 'Height' ? (
246
250
  <Height field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
247
251
  )
@@ -3,7 +3,7 @@ import axios from "axios"
3
3
  import { Autocomplete, Box, Button, Checkbox, Divider, FormControl, FormControlLabel, FormLabel, Grid, InputLabel, MenuItem, Radio, RadioGroup, Select, SxProps, TextField, TextFieldProps, Typography } from "@mui/material"
4
4
  import { FormInputProps } from "./types"
5
5
  import { useDropzone } from "react-dropzone"
6
- import { EMOTII_TITLE, INSURANCE_RELATIONSHIPS, INSURANCE_RELATIONSHIPS_CANVAS, PRIMARY_HEX, RELATIONSHIP_TYPES, TELLESCOPE_GENDERS } from "@tellescope/constants"
6
+ import { CANVAS_TITLE, EMOTII_TITLE, INSURANCE_RELATIONSHIPS, INSURANCE_RELATIONSHIPS_CANVAS, PRIMARY_HEX, RELATIONSHIP_TYPES, TELLESCOPE_GENDERS } from "@tellescope/constants"
7
7
  import { MM_DD_YYYY_to_YYYY_MM_DD, capture_is_supported, downloadFile, 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"
8
8
  import { Enduser, EnduserRelationship, FormResponseValue, InsuranceRelationship, MultipleChoiceOptions, TellescopeGender } from "@tellescope/types-models"
9
9
  import { VALID_STATES, emailValidator, phoneValidator } from "@tellescope/validation"
@@ -559,6 +559,30 @@ export const InsuranceInput = ({ field, value, onChange, form, responses, enduse
559
559
  />
560
560
  </Grid>
561
561
 
562
+ <Grid item xs={12} sm={6}>
563
+ <TextField InputProps={defaultInputProps} required={false} fullWidth value={value?.planName ?? ''}
564
+ onChange={e => onChange({ ...value, planName: e.target.value }, field.id)}
565
+ label={form_display_text_for_language(form, "Plan Name", '')}
566
+ size="small"
567
+ />
568
+ </Grid>
569
+
570
+ <Grid item xs={12} sm={6}>
571
+ <DateStringInput size="small" label="Plan Start Date"
572
+ field={{
573
+ ...field,
574
+ isOptional: true, //field.isOptional || field.options?.billingProvider === 'Candid'
575
+ }}
576
+ value={value?.startDate || ''}
577
+ onChange={startDate =>
578
+ onChange({
579
+ ...value,
580
+ startDate,
581
+ }, field.id)
582
+ }
583
+ />
584
+ </Grid>
585
+
562
586
  {field.options?.includeGroupNumber &&
563
587
  <Grid item xs={12}>
564
588
  <TextField InputProps={defaultInputProps} fullWidth value={value?.groupNumber ?? ''}
@@ -2757,8 +2781,6 @@ export const EmotiiInput = ({ goToNextField, goToPreviousField, field, value, on
2757
2781
  const [data, setData] = useState<{ surveyRequestId: string, surveyUrl: string }>()
2758
2782
  const [loadCount, setLoadCount] = useState(0)
2759
2783
 
2760
- console.log(props.enduserId, props.enduser)
2761
-
2762
2784
  const fetchRef = useRef(false)
2763
2785
  useEffect(() => {
2764
2786
  if (value) return
@@ -2799,4 +2821,60 @@ export const EmotiiInput = ({ goToNextField, goToPreviousField, field, value, on
2799
2821
  onLoad={() => setLoadCount(l => l + 1)}
2800
2822
  />
2801
2823
  )
2824
+ }
2825
+
2826
+ type AllergyResult = {
2827
+ entry?: { resource: { code: { coding: { system: "http://www.fdbhealth.com/", code: string, display: string } []}} }[]
2828
+ }
2829
+
2830
+ export const AllergiesInput = ({ goToNextField, goToPreviousField, field, value, onChange, form, formResponseId, ...props }: FormInputProps<'Allergies'>) => {
2831
+ const session = useResolvedSession()
2832
+ const [query, setQuery] = useState('')
2833
+ const [results, setResults] = useState<{ code: string, display: string }[]>([])
2834
+
2835
+ const fetchRef = useRef(query)
2836
+ useEffect(() => {
2837
+ if (fetchRef.current === query) return
2838
+ fetchRef.current = query
2839
+
2840
+ const t = setTimeout(() => {
2841
+ session.api.integrations
2842
+ .proxy_read({
2843
+ integration: CANVAS_TITLE,
2844
+ type: 'allergies',
2845
+ query,
2846
+ })
2847
+ .then((r : { data: AllergyResult }) => {
2848
+ const deduped: typeof results = []
2849
+ const totalResults = (
2850
+ (r.data.entry || [])
2851
+ .flatMap(v => v?.resource?.code?.coding || [])
2852
+ .filter(v => v.system.includes('fdbhealth'))
2853
+ .map(v => ({ code: v.code, display: v.display, system: v.system }))
2854
+ )
2855
+ for (const v of totalResults) {
2856
+ if (deduped.find(d => d.display === v.display)) { continue }
2857
+
2858
+ deduped.push(v)
2859
+ }
2860
+ setResults(deduped)
2861
+ })
2862
+ }, 99)
2863
+
2864
+ return () => { clearTimeout(t) }
2865
+ }, [session, query])
2866
+
2867
+ return (
2868
+ <Autocomplete multiple value={value || []} options={[...results, ...(value || [])]} style={{ marginTop: 5 }}
2869
+ noOptionsText={query.length ? 'No results found' : 'Type to start search'}
2870
+ onChange={(e, v) => v && onChange(v, field.id)}
2871
+ getOptionLabel={v => first_letter_capitalized(v.display)} filterOptions={o => o}
2872
+ inputValue={query} onInputChange={(e, v) => e && setQuery(v) }
2873
+ renderInput={(params) => (
2874
+ <TextField {...params} InputProps={{ ...params.InputProps, sx: defaultInputProps.sx }}
2875
+ required={!field.isOptional} size="small" label="" placeholder="Search allergies..."
2876
+ />
2877
+ )}
2878
+ />
2879
+ )
2802
2880
  }