@tellescope/react-components 1.152.0 → 1.153.1
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/CMS/components.d.ts +1 -0
- package/lib/cjs/CMS/components.d.ts.map +1 -1
- package/lib/cjs/Forms/form_responses.d.ts +1 -0
- package/lib/cjs/Forms/form_responses.d.ts.map +1 -1
- package/lib/cjs/Forms/forms.d.ts.map +1 -1
- package/lib/cjs/Forms/forms.js +55 -44
- package/lib/cjs/Forms/forms.js.map +1 -1
- package/lib/cjs/Forms/hooks.d.ts +2 -1
- package/lib/cjs/Forms/hooks.d.ts.map +1 -1
- package/lib/cjs/Forms/hooks.js.map +1 -1
- package/lib/cjs/Forms/inputs.d.ts +2 -0
- package/lib/cjs/Forms/inputs.d.ts.map +1 -1
- package/lib/cjs/Forms/inputs.js +111 -10
- package/lib/cjs/Forms/inputs.js.map +1 -1
- package/lib/cjs/Forms/types.d.ts +1 -1
- package/lib/cjs/Forms/types.d.ts.map +1 -1
- package/lib/cjs/controls.d.ts +2 -2
- package/lib/cjs/inputs.native.d.ts +1 -0
- package/lib/cjs/inputs.native.d.ts.map +1 -1
- package/lib/cjs/inputs_shared.d.ts +4 -1
- package/lib/cjs/inputs_shared.d.ts.map +1 -1
- package/lib/cjs/inputs_shared.js +7 -1
- package/lib/cjs/inputs_shared.js.map +1 -1
- package/lib/cjs/state.d.ts +36 -0
- package/lib/cjs/state.d.ts.map +1 -1
- package/lib/cjs/state.js +19 -3
- package/lib/cjs/state.js.map +1 -1
- package/lib/esm/CMS/components.d.ts +1 -0
- package/lib/esm/CMS/components.d.ts.map +1 -1
- package/lib/esm/Forms/form_responses.d.ts +1 -0
- package/lib/esm/Forms/form_responses.d.ts.map +1 -1
- package/lib/esm/Forms/forms.d.ts.map +1 -1
- package/lib/esm/Forms/forms.js +57 -46
- package/lib/esm/Forms/forms.js.map +1 -1
- package/lib/esm/Forms/hooks.d.ts +2 -1
- package/lib/esm/Forms/hooks.d.ts.map +1 -1
- package/lib/esm/Forms/hooks.js.map +1 -1
- package/lib/esm/Forms/inputs.d.ts +2 -0
- package/lib/esm/Forms/inputs.d.ts.map +1 -1
- package/lib/esm/Forms/inputs.js +109 -10
- package/lib/esm/Forms/inputs.js.map +1 -1
- package/lib/esm/Forms/types.d.ts +1 -1
- package/lib/esm/Forms/types.d.ts.map +1 -1
- package/lib/esm/controls.d.ts +2 -2
- package/lib/esm/inputs.native.d.ts +1 -0
- package/lib/esm/inputs.native.d.ts.map +1 -1
- package/lib/esm/inputs_shared.d.ts +4 -1
- package/lib/esm/inputs_shared.d.ts.map +1 -1
- package/lib/esm/inputs_shared.js +6 -1
- package/lib/esm/inputs_shared.js.map +1 -1
- package/lib/esm/state.d.ts +36 -0
- package/lib/esm/state.d.ts.map +1 -1
- package/lib/esm/state.js +15 -0
- package/lib/esm/state.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/Forms/forms.tsx +18 -3
- package/src/Forms/hooks.tsx +1 -1
- package/src/Forms/inputs.tsx +136 -8
- package/src/Forms/types.ts +1 -1
- package/src/inputs_shared.tsx +13 -2
- package/src/state.tsx +22 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellescope/react-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.153.1",
|
|
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.153.1",
|
|
51
|
+
"@tellescope/sdk": "^1.153.1",
|
|
52
|
+
"@tellescope/types-client": "^1.153.1",
|
|
53
|
+
"@tellescope/types-models": "^1.153.1",
|
|
54
|
+
"@tellescope/types-utilities": "^1.153.1",
|
|
55
|
+
"@tellescope/utilities": "^1.153.1",
|
|
56
|
+
"@tellescope/validation": "^1.153.1",
|
|
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": "0ad06bdf4ec4ea7871d68bedfc10fd1154fc742b",
|
|
84
84
|
"publishConfig": {
|
|
85
85
|
"access": "public"
|
|
86
86
|
}
|
package/src/Forms/forms.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useMemo, useState } from "react"
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, 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, 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"
|
|
@@ -168,6 +168,8 @@ 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
|
|
172
|
+
const Conditions = customInputs?.['Conditions'] ?? ConditionsInput
|
|
171
173
|
|
|
172
174
|
const validationMessage = validateField(field)
|
|
173
175
|
|
|
@@ -242,6 +244,12 @@ export const QuestionForField = ({
|
|
|
242
244
|
: field.type === 'Emotii' ? (
|
|
243
245
|
<Emotii enduser={enduser} enduserId={enduserId} field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
244
246
|
)
|
|
247
|
+
: field.type === 'Allergies' ? (
|
|
248
|
+
<Allergies enduser={enduser} enduserId={enduserId} field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
249
|
+
)
|
|
250
|
+
: field.type === 'Conditions' ? (
|
|
251
|
+
<Conditions enduser={enduser} enduserId={enduserId} field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
252
|
+
)
|
|
245
253
|
: field.type === 'Height' ? (
|
|
246
254
|
<Height field={field} disabled={value.disabled} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<any>} form={form} />
|
|
247
255
|
)
|
|
@@ -431,6 +439,7 @@ export const TellescopeSingleQuestionFlow: typeof TellescopeForm = ({
|
|
|
431
439
|
}, [])
|
|
432
440
|
|
|
433
441
|
const [uploading, setUploading] = useState(false)
|
|
442
|
+
const [autosubmitting, setAutoSubmitting] = useState(false)
|
|
434
443
|
|
|
435
444
|
useEffect(() => {
|
|
436
445
|
// ensure redirect question doesn't trip this alert
|
|
@@ -445,6 +454,7 @@ export const TellescopeSingleQuestionFlow: typeof TellescopeForm = ({
|
|
|
445
454
|
return onSuccess?.({} as any)
|
|
446
455
|
}
|
|
447
456
|
|
|
457
|
+
|
|
448
458
|
await submit({
|
|
449
459
|
onSuccess,
|
|
450
460
|
...options,
|
|
@@ -457,13 +467,18 @@ export const TellescopeSingleQuestionFlow: typeof TellescopeForm = ({
|
|
|
457
467
|
})
|
|
458
468
|
}, [isPreview, onSuccess, submit, beforeunloadHandler])
|
|
459
469
|
|
|
470
|
+
const autoSubmitRef = useRef(false)
|
|
460
471
|
useEffect(() => {
|
|
461
472
|
if (!activeField.value.options?.autoSubmit) {
|
|
462
473
|
return
|
|
463
474
|
}
|
|
475
|
+
if (autoSubmitRef.current) return
|
|
464
476
|
|
|
465
477
|
if (responses.find(r => r.fieldId === activeField.value.id && field_can_autosubmit(activeField.value) && r.answer.value)) {
|
|
478
|
+
autoSubmitRef.current = true
|
|
479
|
+
setAutoSubmitting(true)
|
|
466
480
|
handleSubmit()
|
|
481
|
+
.finally(() => setAutoSubmitting(false))
|
|
467
482
|
}
|
|
468
483
|
}, [handleSubmit, responses, activeField])
|
|
469
484
|
|
|
@@ -547,7 +562,7 @@ export const TellescopeSingleQuestionFlow: typeof TellescopeForm = ({
|
|
|
547
562
|
setUploading(!!selectedFiles.find(r => !!r.blobs?.length))
|
|
548
563
|
return handleSubmit({ onFileUploadsDone: () => setUploading(false) })
|
|
549
564
|
}}
|
|
550
|
-
disabled={!!validationMessage || currentValue.field?.options?.disableNext === true}
|
|
565
|
+
disabled={!!validationMessage || currentValue.field?.options?.disableNext === true || autosubmitting}
|
|
551
566
|
submitText={form_display_text_for_language(form, "Submit")}
|
|
552
567
|
submittingText={
|
|
553
568
|
submittingStatus === 'uploading-files'
|
package/src/Forms/hooks.tsx
CHANGED
|
@@ -668,7 +668,7 @@ export const useTellescopeForm = ({ form, urlLogicValue, customization, carePlan
|
|
|
668
668
|
selectedFiles.find(f => f.fieldId === activeField.value.id)
|
|
669
669
|
)
|
|
670
670
|
|
|
671
|
-
const handleDatabaseSelect = useCallback((databaseRecords: DatabaseRecord[]) => {
|
|
671
|
+
const handleDatabaseSelect = useCallback((databaseRecords: Pick<DatabaseRecord, "values" | "databaseId">[]) => {
|
|
672
672
|
try {
|
|
673
673
|
// no need to update if there's no prepopulation
|
|
674
674
|
if (!fields?.find(f => f.prepopulateFromDatabase?.databaseId && f.prepopulateFromDatabase?.field)) return
|
package/src/Forms/inputs.tsx
CHANGED
|
@@ -3,9 +3,9 @@ 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
|
-
import { Enduser, EnduserRelationship, FormResponseValue, InsuranceRelationship, MultipleChoiceOptions, TellescopeGender } from "@tellescope/types-models"
|
|
8
|
+
import { DatabaseSelectResponse, Enduser, EnduserRelationship, FormResponseValue, InsuranceRelationship, MultipleChoiceOptions, TellescopeGender } from "@tellescope/types-models"
|
|
9
9
|
import { VALID_STATES, emailValidator, phoneValidator } from "@tellescope/validation"
|
|
10
10
|
import Slider from '@mui/material/Slider';
|
|
11
11
|
import LinearProgress from '@mui/material/LinearProgress';
|
|
@@ -1661,7 +1661,7 @@ const choicesForDatabase: {
|
|
|
1661
1661
|
} = {}
|
|
1662
1662
|
|
|
1663
1663
|
const LOAD_CHOICES_LIMIT = 500
|
|
1664
|
-
const useDatabaseChoices = ({ databaseId='', field } : { databaseId?: string, field: FormField }) => {
|
|
1664
|
+
const useDatabaseChoices = ({ databaseId='', field, otherAnswers } : { databaseId?: string, field: FormField, otherAnswers?: DatabaseSelectResponse[] }) => {
|
|
1665
1665
|
const session = useResolvedSession()
|
|
1666
1666
|
const [renderCount, setRenderCount] = useState(0)
|
|
1667
1667
|
|
|
@@ -1697,13 +1697,20 @@ const useDatabaseChoices = ({ databaseId='', field } : { databaseId?: string, fi
|
|
|
1697
1697
|
|
|
1698
1698
|
return {
|
|
1699
1699
|
doneLoading: choicesForDatabase[databaseId]?.done ?? false,
|
|
1700
|
-
choices:
|
|
1700
|
+
choices: [
|
|
1701
|
+
...choicesForDatabase[databaseId]?.records ?? [],
|
|
1702
|
+
...(otherAnswers || []).map(v => ({
|
|
1703
|
+
id: v.text,
|
|
1704
|
+
databaseId,
|
|
1705
|
+
values: [{ label: field.options?.databaseLabel || '', type: 'Text', value: v.text }],
|
|
1706
|
+
}) as Pick<DatabaseRecord, 'id' | 'values' | 'databaseId'>)
|
|
1707
|
+
],
|
|
1701
1708
|
renderCount,
|
|
1702
1709
|
}
|
|
1703
1710
|
}
|
|
1704
1711
|
|
|
1705
1712
|
|
|
1706
|
-
const label_for_database_record = (field: FormField, record?: DatabaseRecord) => {
|
|
1713
|
+
const label_for_database_record = (field: FormField, record?: Pick<DatabaseRecord, 'values'>) => {
|
|
1707
1714
|
if (!record) return ''
|
|
1708
1715
|
|
|
1709
1716
|
const addedLabels = (
|
|
@@ -1722,14 +1729,34 @@ const label_for_database_record = (field: FormField, record?: DatabaseRecord) =>
|
|
|
1722
1729
|
)
|
|
1723
1730
|
}
|
|
1724
1731
|
|
|
1732
|
+
const get_other_answers = (_value?: DatabaseSelectResponse[], typing?: string) => {
|
|
1733
|
+
try {
|
|
1734
|
+
const existing = (
|
|
1735
|
+
(_value || [])
|
|
1736
|
+
.filter(v => typeof v === 'string' || v.recordId === v.text)
|
|
1737
|
+
.map(v => typeof v === 'string' ? { databaseId: '', recordId: v, text: v } : v)
|
|
1738
|
+
)
|
|
1739
|
+
if (typing) {
|
|
1740
|
+
existing.push({ text: typing, databaseId: '', recordId: typing })
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
return existing
|
|
1744
|
+
} catch(err) { console.error(err) }
|
|
1745
|
+
|
|
1746
|
+
return []
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1725
1749
|
export const DatabaseSelectInput = ({ field, value: _value, onChange, onDatabaseSelect, responses }: FormInputProps<'Database Select'> & {
|
|
1726
1750
|
responses: FormResponseValue[],
|
|
1727
1751
|
}) => {
|
|
1752
|
+
const [typing, setTyping] = useState('')
|
|
1728
1753
|
const { choices, doneLoading } = useDatabaseChoices({
|
|
1729
1754
|
databaseId: field.options?.databaseId,
|
|
1730
1755
|
field,
|
|
1756
|
+
otherAnswers: get_other_answers(_value, field?.options?.other ? typing : undefined),
|
|
1731
1757
|
})
|
|
1732
1758
|
|
|
1759
|
+
console.log(choices, _value)
|
|
1733
1760
|
const value = React.useMemo(() => {
|
|
1734
1761
|
try {
|
|
1735
1762
|
// if the value is a string (some single answer that was save), make sure we coerce to array
|
|
@@ -1797,7 +1824,7 @@ export const DatabaseSelectInput = ({ field, value: _value, onChange, onDatabase
|
|
|
1797
1824
|
}, [choices, filterResponse, field.options?.databaseFilter, value])
|
|
1798
1825
|
|
|
1799
1826
|
const filteredChoices = useMemo(() => {
|
|
1800
|
-
const filtered
|
|
1827
|
+
const filtered = []
|
|
1801
1828
|
|
|
1802
1829
|
const uniques = new Set<string>([])
|
|
1803
1830
|
for (const c of filteredChoicesWithPotentialDuplicates) {
|
|
@@ -1842,6 +1869,8 @@ export const DatabaseSelectInput = ({ field, value: _value, onChange, onDatabase
|
|
|
1842
1869
|
field.id,
|
|
1843
1870
|
)
|
|
1844
1871
|
}}
|
|
1872
|
+
inputValue={typing}
|
|
1873
|
+
onInputChange={(e, v) => e && setTyping(v)}
|
|
1845
1874
|
renderInput={params => <TextField {...params} InputProps={{ ...params.InputProps, sx: defaultInputProps.sx }} />}
|
|
1846
1875
|
/>
|
|
1847
1876
|
)
|
|
@@ -2781,8 +2810,6 @@ export const EmotiiInput = ({ goToNextField, goToPreviousField, field, value, on
|
|
|
2781
2810
|
const [data, setData] = useState<{ surveyRequestId: string, surveyUrl: string }>()
|
|
2782
2811
|
const [loadCount, setLoadCount] = useState(0)
|
|
2783
2812
|
|
|
2784
|
-
console.log(props.enduserId, props.enduser)
|
|
2785
|
-
|
|
2786
2813
|
const fetchRef = useRef(false)
|
|
2787
2814
|
useEffect(() => {
|
|
2788
2815
|
if (value) return
|
|
@@ -2823,4 +2850,105 @@ export const EmotiiInput = ({ goToNextField, goToPreviousField, field, value, on
|
|
|
2823
2850
|
onLoad={() => setLoadCount(l => l + 1)}
|
|
2824
2851
|
/>
|
|
2825
2852
|
)
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
type AllergyResult = {
|
|
2856
|
+
entry?: { resource: { code: { coding: { system: "http://www.fdbhealth.com/", code: string, display: string } []}} }[]
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
export const AllergiesInput = ({ goToNextField, goToPreviousField, field, value, onChange, form, formResponseId, ...props }: FormInputProps<'Allergies'>) => {
|
|
2860
|
+
const session = useResolvedSession()
|
|
2861
|
+
const [query, setQuery] = useState('')
|
|
2862
|
+
const [results, setResults] = useState<{ code: string, display: string }[]>([])
|
|
2863
|
+
|
|
2864
|
+
const fetchRef = useRef(query)
|
|
2865
|
+
useEffect(() => {
|
|
2866
|
+
if (fetchRef.current === query) return
|
|
2867
|
+
fetchRef.current = query
|
|
2868
|
+
|
|
2869
|
+
if (!query) return
|
|
2870
|
+
|
|
2871
|
+
const t = setTimeout(() => {
|
|
2872
|
+
session.api.integrations
|
|
2873
|
+
.proxy_read({
|
|
2874
|
+
integration: CANVAS_TITLE,
|
|
2875
|
+
type: 'allergies',
|
|
2876
|
+
query,
|
|
2877
|
+
})
|
|
2878
|
+
.then((r : { data: AllergyResult }) => {
|
|
2879
|
+
const deduped: typeof results = []
|
|
2880
|
+
const totalResults = (
|
|
2881
|
+
(r.data.entry || [])
|
|
2882
|
+
.flatMap(v => v?.resource?.code?.coding || [])
|
|
2883
|
+
.filter(v => v.system.includes('fdbhealth'))
|
|
2884
|
+
.map(v => ({ code: v.code, display: v.display, system: v.system }))
|
|
2885
|
+
)
|
|
2886
|
+
for (const v of totalResults) {
|
|
2887
|
+
if (deduped.find(d => d.display === v.display)) { continue }
|
|
2888
|
+
|
|
2889
|
+
deduped.push(v)
|
|
2890
|
+
}
|
|
2891
|
+
setResults(deduped)
|
|
2892
|
+
})
|
|
2893
|
+
}, 200)
|
|
2894
|
+
|
|
2895
|
+
return () => { clearTimeout(t) }
|
|
2896
|
+
}, [session, query])
|
|
2897
|
+
|
|
2898
|
+
return (
|
|
2899
|
+
<Autocomplete multiple value={value || []} options={[...results, ...(value || [])]} style={{ marginTop: 5 }}
|
|
2900
|
+
noOptionsText={query.length ? 'No results found' : 'Type to start search'}
|
|
2901
|
+
onChange={(e, v) => v && onChange(v, field.id)}
|
|
2902
|
+
getOptionLabel={v => first_letter_capitalized(v.display)} filterOptions={o => o}
|
|
2903
|
+
inputValue={query} onInputChange={(e, v) => e && setQuery(v) }
|
|
2904
|
+
renderInput={(params) => (
|
|
2905
|
+
<TextField {...params} InputProps={{ ...params.InputProps, sx: defaultInputProps.sx }}
|
|
2906
|
+
required={!field.isOptional} size="small" label="" placeholder="Search allergies..."
|
|
2907
|
+
/>
|
|
2908
|
+
)}
|
|
2909
|
+
/>
|
|
2910
|
+
)
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
export const ConditionsInput = ({ goToNextField, goToPreviousField, field, value, onChange, form, formResponseId, ...props }: FormInputProps<'Conditions'>) => {
|
|
2914
|
+
const session = useResolvedSession()
|
|
2915
|
+
const [query, setQuery] = useState('')
|
|
2916
|
+
const [results, setResults] = useState<{ code: string, display: string }[]>([])
|
|
2917
|
+
|
|
2918
|
+
const fetchRef = useRef(query)
|
|
2919
|
+
useEffect(() => {
|
|
2920
|
+
if (fetchRef.current === query) return
|
|
2921
|
+
fetchRef.current = query
|
|
2922
|
+
|
|
2923
|
+
if (!query) return
|
|
2924
|
+
|
|
2925
|
+
const t = setTimeout(() => {
|
|
2926
|
+
session.api.diagnosis_codes.getSome({ search: { query } })
|
|
2927
|
+
.then(codes => {
|
|
2928
|
+
const deduped: typeof results = []
|
|
2929
|
+
for (const v of codes) {
|
|
2930
|
+
if (deduped.find(d => d.display === v.display)) { continue }
|
|
2931
|
+
|
|
2932
|
+
deduped.push(v)
|
|
2933
|
+
}
|
|
2934
|
+
setResults(deduped)
|
|
2935
|
+
})
|
|
2936
|
+
}, 200)
|
|
2937
|
+
|
|
2938
|
+
return () => { clearTimeout(t) }
|
|
2939
|
+
}, [session, query])
|
|
2940
|
+
|
|
2941
|
+
return (
|
|
2942
|
+
<Autocomplete multiple value={value || []} options={[...results, ...(value || [])]} style={{ marginTop: 5 }}
|
|
2943
|
+
noOptionsText={query.length ? 'No results found' : 'Type to start search'}
|
|
2944
|
+
onChange={(e, v) => v && onChange(v, field.id)}
|
|
2945
|
+
getOptionLabel={v => first_letter_capitalized(v.display)} filterOptions={o => o}
|
|
2946
|
+
inputValue={query} onInputChange={(e, v) => e && setQuery(v) }
|
|
2947
|
+
renderInput={(params) => (
|
|
2948
|
+
<TextField {...params} InputProps={{ ...params.InputProps, sx: defaultInputProps.sx }}
|
|
2949
|
+
required={!field.isOptional} size="small" label="" placeholder="Search conditions..."
|
|
2950
|
+
/>
|
|
2951
|
+
)}
|
|
2952
|
+
/>
|
|
2953
|
+
)
|
|
2826
2954
|
}
|
package/src/Forms/types.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface FormInputProps<K extends keyof AnswerForType> {
|
|
|
17
17
|
size?: 'small',
|
|
18
18
|
label?: string,
|
|
19
19
|
fullWidth?: boolean,
|
|
20
|
-
onDatabaseSelect?: (r: DatabaseRecord[]) => void,
|
|
20
|
+
onDatabaseSelect?: (r: Pick<DatabaseRecord, "values" | "databaseId">[]) => void,
|
|
21
21
|
responses?: Response[]
|
|
22
22
|
title?: string,
|
|
23
23
|
enduserId?: string,
|
package/src/inputs_shared.tsx
CHANGED
|
@@ -5,8 +5,8 @@ import { LoadFunction, LoadFunctionArguments } from "@tellescope/sdk"
|
|
|
5
5
|
import { ALL_ACCESS, UNSEARCHABLE_FIELDS } from "@tellescope/constants"
|
|
6
6
|
import { SearchAPIProps, useSearchAPI } from "./hooks"
|
|
7
7
|
import { TextFieldProps } from "./mui"
|
|
8
|
-
import { AppointmentBookingPage, AppointmentLocation, AutomationTrigger, CalendarEventTemplate, CallHoldQueue, ChatRoom, Database, DatabaseRecord, Enduser, EnduserOrder, FaxLog, File, Form, FormGroup, Forum, Journey, ManagedContentRecord, MessageTemplateSnippet, Organization, PrescriptionRoute, SuggestedContact, Template, Ticket, TicketQueue, User, UserNotification } from "@tellescope/types-client"
|
|
9
|
-
import { Button, Checkbox, Flex, HoverPaper, LoadingButton, LoadingData, LoadingLinear, ScrollingList, SearchTextInput, Typography, useAppointmentBookingPages, useAppointmentLocations, useAutomationTriggers, useCalendarEventTemplates, useCallHoldQueues, useChatRooms, useDatabaseRecords, useDatabases, useEnduserOrders, useEndusers, useFaxLogs, useFiles, useFormGroups, useForms, useForums, useJourneys, useManagedContentRecords, useMessageTemplateSnippets, useNotifications, useOrganization, useOrganizations, usePrescriptionRoutes, useResolvedSession, useSession, useSuggestedContacts, useTemplates, useTicketQueues, useTickets, useUsers, value_is_loaded } from "."
|
|
8
|
+
import { AppointmentBookingPage, AppointmentLocation, AutomationTrigger, CalendarEventTemplate, CallHoldQueue, ChatRoom, Database, DatabaseRecord, DiagnosisCode, Enduser, EnduserOrder, FaxLog, File, Form, FormGroup, Forum, Journey, ManagedContentRecord, MessageTemplateSnippet, Organization, PrescriptionRoute, SuggestedContact, Template, Ticket, TicketQueue, User, UserNotification } from "@tellescope/types-client"
|
|
9
|
+
import { Button, Checkbox, Flex, HoverPaper, LoadingButton, LoadingData, LoadingLinear, ScrollingList, SearchTextInput, Typography, useAppointmentBookingPages, useAppointmentLocations, useAutomationTriggers, useCalendarEventTemplates, useCallHoldQueues, useChatRooms, useDatabaseRecords, useDatabases, useDiagnosisCodes, useEnduserOrders, useEndusers, useFaxLogs, useFiles, useFormGroups, useForms, useForums, useJourneys, useManagedContentRecords, useMessageTemplateSnippets, useNotifications, useOrganization, useOrganizations, usePrescriptionRoutes, useResolvedSession, useSession, useSuggestedContacts, useTemplates, useTicketQueues, useTickets, useUsers, value_is_loaded } from "."
|
|
10
10
|
import { SxProps } from "@mui/material"
|
|
11
11
|
import { AccessPermissions } from "@tellescope/types-models"
|
|
12
12
|
|
|
@@ -618,6 +618,17 @@ export const SuggestedContactSearch = (props: Omit<GenericSearchProps<SuggestedC
|
|
|
618
618
|
)
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
+
export const DiagnosisCodeSearch = (props: Omit<GenericSearchProps<DiagnosisCode>, 'filterKey'> & { filterKey?: string }) => {
|
|
622
|
+
const session = useSession()
|
|
623
|
+
const [, { addLocalElements }] = useDiagnosisCodes({ dontFetch: true })
|
|
624
|
+
return (
|
|
625
|
+
<ModelSearchInput filterKey="diagnoses-code" {...props}
|
|
626
|
+
searchAPI={session.api.diagnosis_codes.getSome}
|
|
627
|
+
onLoad={addLocalElements}
|
|
628
|
+
/>
|
|
629
|
+
)
|
|
630
|
+
}
|
|
631
|
+
|
|
621
632
|
export const CallHoldQueueSearch = (props: Omit<GenericSearchProps<CallHoldQueue>, 'filterKey'> & { filterKey?: string }) => {
|
|
622
633
|
const session = useSession()
|
|
623
634
|
const [, { addLocalElements }] = useCallHoldQueues({ dontFetch: true })
|
package/src/state.tsx
CHANGED
|
@@ -93,6 +93,7 @@ import {
|
|
|
93
93
|
FaxLog,
|
|
94
94
|
CallHoldQueue,
|
|
95
95
|
SuggestedContact,
|
|
96
|
+
DiagnosisCode,
|
|
96
97
|
} from "@tellescope/types-client"
|
|
97
98
|
|
|
98
99
|
import {
|
|
@@ -107,7 +108,7 @@ import {
|
|
|
107
108
|
} from '@tellescope/sdk'
|
|
108
109
|
import { value_is_loaded } from './loading'
|
|
109
110
|
import { matches_organization, object_is_empty, objects_equivalent } from '@tellescope/utilities'
|
|
110
|
-
import { ModelName, ReadFilter, SortBy } from '@tellescope/types-models'
|
|
111
|
+
import { Diagnosis, ModelName, ReadFilter, SortBy } from '@tellescope/types-models'
|
|
111
112
|
|
|
112
113
|
const RESET_CACHE_TYPE = "cache/reset" as const
|
|
113
114
|
export const resetStateAction = createAction(RESET_CACHE_TYPE)
|
|
@@ -353,6 +354,7 @@ const portalBrandingsSlice = createSliceForList<PortalBranding, 'portal_branding
|
|
|
353
354
|
const messageTemplateSnippetsSlice = createSliceForList<MessageTemplateSnippet, 'message_template_snippets'>('message_template_snippets')
|
|
354
355
|
const faxLogsSlice = createSliceForList<FaxLog, 'fax_logs'>('fax_logs')
|
|
355
356
|
const suggestedContactsSlice = createSliceForList<SuggestedContact, 'suggested_contacts'>('suggested_contacts')
|
|
357
|
+
const diagnosisCodesSlice = createSliceForList<DiagnosisCode, 'diagnosis_codes'>('diagnosis_codes')
|
|
356
358
|
|
|
357
359
|
const roleBasedAccessPermissionsSlice = createSliceForList<RoleBasedAccessPermission, 'role_based_access_permissions'>('role_based_access_permissions')
|
|
358
360
|
|
|
@@ -440,6 +442,7 @@ export const sharedConfig = {
|
|
|
440
442
|
fax_logs: faxLogsSlice.reducer,
|
|
441
443
|
call_hold_queues: callHoldQueuesSlice.reducer,
|
|
442
444
|
suggested_contacts: suggestedContactsSlice.reducer,
|
|
445
|
+
diagnosis_codes: diagnosisCodesSlice.reducer,
|
|
443
446
|
},
|
|
444
447
|
}
|
|
445
448
|
|
|
@@ -1256,6 +1259,24 @@ export const usePortalBrandings = (options={} as HookOptions<PortalBranding>) =>
|
|
|
1256
1259
|
},
|
|
1257
1260
|
)
|
|
1258
1261
|
}
|
|
1262
|
+
export const useDiagnosisCodes = (options={} as HookOptions<DiagnosisCode>) => {
|
|
1263
|
+
const session = useResolvedSession()
|
|
1264
|
+
|
|
1265
|
+
return useListStateHook('diagnosis_codes', useTypedSelector(s => s.diagnosis_codes), session, diagnosisCodesSlice,
|
|
1266
|
+
{
|
|
1267
|
+
loadQuery: session.api.diagnosis_codes.getSome,
|
|
1268
|
+
findOne: session.api.diagnosis_codes.getOne,
|
|
1269
|
+
findByIds: session.api.diagnosis_codes.getByIds,
|
|
1270
|
+
addOne: session.api.diagnosis_codes.createOne,
|
|
1271
|
+
addSome: session.api.diagnosis_codes.createSome,
|
|
1272
|
+
deleteOne: session.api.diagnosis_codes.deleteOne,
|
|
1273
|
+
updateOne: session.api.diagnosis_codes.updateOne,
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
...options,
|
|
1277
|
+
},
|
|
1278
|
+
)
|
|
1279
|
+
}
|
|
1259
1280
|
export const useEnduserProblems = (options={} as HookOptions<EnduserProblem>) => {
|
|
1260
1281
|
const session = useResolvedSession()
|
|
1261
1282
|
|