@tellescope/react-components 1.171.1 → 1.172.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/react-components",
3
- "version": "1.171.1",
3
+ "version": "1.172.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.171.1",
51
- "@tellescope/sdk": "^1.171.1",
52
- "@tellescope/types-client": "^1.171.1",
53
- "@tellescope/types-models": "^1.171.1",
54
- "@tellescope/types-utilities": "^1.171.1",
55
- "@tellescope/utilities": "^1.171.1",
56
- "@tellescope/validation": "^1.171.1",
50
+ "@tellescope/constants": "^1.172.0",
51
+ "@tellescope/sdk": "^1.172.0",
52
+ "@tellescope/types-client": "^1.172.0",
53
+ "@tellescope/types-models": "^1.172.0",
54
+ "@tellescope/types-utilities": "^1.172.0",
55
+ "@tellescope/utilities": "^1.172.0",
56
+ "@tellescope/validation": "^1.172.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",
@@ -84,7 +84,7 @@
84
84
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.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": "6909a4e4706eae5a624b226e781893775d20bb42",
87
+ "gitHead": "91a22b59bb059b03006713f1c20d9746850bfe53",
88
88
  "publishConfig": {
89
89
  "access": "public"
90
90
  }
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
2
2
  import { Button, CircularProgress, FileBlob, FileUploadHandler, Flex, LinearProgress, LoadingButton, Modal, Paper, Styled, Typography, form_display_text_for_language, useFileUpload, useFormResponses, useSession } from "../index"
3
3
  import { useListForFormFields, useOrganizationTheme, useTellescopeForm, WithOrganizationTheme, Response, FileResponse, NextFieldLogicOptions } from "./hooks"
4
4
  import { ChangeHandler, FormInputs } from "./types"
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, RichTextInput, SignatureInput, StringInput, StringLongInput, StripeInput, TableInput, TimeInput, defaultButtonStyles } from "./inputs"
5
+ import { AddressInput, AllergiesInput, AppointmentBookingInput, ChargeebeeInput, ConditionsInput, DatabaseSelectInput, DateInput, DateStringInput, DropdownInput, EmailInput, EmotiiInput, FileInput, FilesInput, HeightInput, HiddenValueInput, InsuranceInput, LanguageSelect, MedicationsInput, MultipleChoiceInput, NumberInput, PhoneInput, Progress, RankingInput, RatingInput, RedirectInput, RelatedContactsInput, RichTextInput, 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"
@@ -161,6 +161,7 @@ export const QuestionForField = ({
161
161
  const Signature = customInputs?.['signature'] ?? SignatureInput
162
162
  const MultipleChoice = customInputs?.['multiple_choice'] ?? MultipleChoiceInput
163
163
  const Stripe = customInputs?.['Stripe'] ?? StripeInput
164
+ const Chargebee = customInputs?.['Chargebee'] ?? ChargeebeeInput
164
165
  const File = customInputs?.['file'] ?? FileInput
165
166
  const Files = customInputs?.['files'] ?? FilesInput
166
167
  const Ranking = customInputs?.['ranking'] ?? RankingInput
@@ -287,6 +288,9 @@ export const QuestionForField = ({
287
288
  : field.type === 'Stripe' ? (
288
289
  <Stripe field={field} value={value.answer.value as string} onChange={onFieldChange as ChangeHandler<any>} setCustomerId={setCustomerId} form={form} />
289
290
  )
291
+ : field.type === 'Chargebee' ? (
292
+ <Chargebee field={field} value={value.answer.value as any} onChange={onFieldChange as ChangeHandler<'Chargebee'>} setCustomerId={setCustomerId} form={form} />
293
+ )
290
294
  : field.type === 'stringLong' ? (
291
295
  <StringLong field={field} disabled={value.disabled} value={value.answer.value as string} onChange={onFieldChange as ChangeHandler<'string' | 'stringLong'>} form={form} />
292
296
  )
@@ -1415,6 +1415,26 @@ export const useTellescopeForm = ({ isPublicForm, form, urlLogicValue, customiza
1415
1415
  })
1416
1416
  .catch(console.error)
1417
1417
  }
1418
+
1419
+ const cbSaveField = fields.find(f => f.id === fieldId && (f.type === 'Chargebee'))
1420
+ if (cbSaveField && typeof value === 'object' && (formResponseId || accessCode)) {
1421
+ session.api.form_responses.save_field_response({
1422
+ accessCode,
1423
+ formResponseId,
1424
+ response: {
1425
+ answer: {
1426
+ type: cbSaveField.type as "Chargebee",
1427
+ value,
1428
+ } as any,
1429
+ fieldId: cbSaveField.id,
1430
+ fieldTitle: cbSaveField.title,
1431
+ externalId: cbSaveField.externalId,
1432
+ fieldDescription: cbSaveField.description,
1433
+ fieldHtmlDescription: cbSaveField.htmlDescription,
1434
+ },
1435
+ })
1436
+ .catch(console.error)
1437
+ }
1418
1438
  }, [fields])
1419
1439
 
1420
1440
  const onAddFile = useCallback((blobs?: FileBlob | FileBlob[], fieldId=activeField.value.id) => {
@@ -3312,4 +3312,52 @@ export const ConditionsInput = ({ goToNextField, goToPreviousField, field, value
3312
3312
 
3313
3313
  export const RichTextInput = ({ field, value, onChange }: FormInputProps<'Rich Text'>) => (
3314
3314
  <WYSIWYG initialHTML={value} onChange={v => onChange(v, field.id)} style={{ width: '100%' }} editorStyle={{ width: '100%' }} />
3315
- )
3315
+ )
3316
+
3317
+ export const ChargeebeeInput = ({ field, value, onChange, setCustomerId }: FormInputProps<'Chargebee'> & {
3318
+ setCustomerId: React.Dispatch<React.SetStateAction<string | undefined>>,
3319
+ }) => {
3320
+ const session = useResolvedSession()
3321
+ const [url, setUrl] = useState('')
3322
+ const [error, setError] = useState('')
3323
+
3324
+ const [loadCount, setLoadCount] = useState(0)
3325
+
3326
+ const fetchRef = useRef(false)
3327
+ useEffect(() => {
3328
+ if (fetchRef.current) return
3329
+ fetchRef.current = true
3330
+
3331
+ session.api.form_responses.chargebee_details({ fieldId: field.id })
3332
+ .then(({ url }) => setUrl(url))
3333
+ .catch(setError)
3334
+ }, [session])
3335
+
3336
+ const loadAnswerRef = useRef(false)
3337
+ useEffect(() => {
3338
+ if (loadCount !== 2) return
3339
+ if (loadAnswerRef.current) return
3340
+ loadAnswerRef.current = true
3341
+
3342
+ onChange({ url }, field.id)
3343
+ }, [loadCount, url])
3344
+
3345
+ if (value || loadCount === 2) {
3346
+ return (
3347
+ <Grid container alignItems="center" wrap="nowrap">
3348
+ <CheckCircleOutline color="success" />
3349
+
3350
+ <Typography sx={{ ml: 1, fontSize: 20 }}>
3351
+ Your purchase was successful
3352
+ </Typography>
3353
+ </Grid>
3354
+ )
3355
+ }
3356
+ if (error && typeof error === 'string') return <Typography color="error">{error}</Typography>
3357
+ if (!url) return <LinearProgress />
3358
+ return (
3359
+ <iframe src={url} title="Checkout" style={{ border: 'none', width: '100%', height: 700 }}
3360
+ onLoad={() => setLoadCount(l => l + 1)}
3361
+ />
3362
+ )
3363
+ }
package/src/controls.tsx CHANGED
@@ -206,6 +206,8 @@ interface DownloadButton {
206
206
  Icon?: typeof DownloadIcon
207
207
  label?: string,
208
208
  preferInBrowser?: boolean,
209
+ offsetX?: number,
210
+ offsetY?: number,
209
211
  }
210
212
 
211
213
  export const DownloadFileIconButton = ({ preferInBrowser, publicURL, secureName, label="Download File", Icon=DownloadIcon, onDownload, onError, ...props }: DownloadButton) => {