@sparrowengg/integrations-templates-frontend 6.0.7 → 7.0.0-bulkify.2
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/README.md +663 -0
- package/dist/cjs/dynamic-mapping/components/mapping.js +4 -2
- package/dist/cjs/dynamic-mapping/components/mapping.js.map +1 -1
- package/dist/cjs/dynamic-mapping/helpers/mapping.helpers.js +10 -0
- package/dist/cjs/dynamic-mapping/helpers/mapping.helpers.js.map +1 -1
- package/dist/cjs/dynamic-mapping/hooks/use-mapping-data.js +44 -29
- package/dist/cjs/dynamic-mapping/hooks/use-mapping-data.js.map +1 -1
- package/dist/cjs/dynamic-mapping/index.js +4 -2
- package/dist/cjs/dynamic-mapping/index.js.map +1 -1
- package/dist/es/dynamic-mapping/components/mapping.js +4 -2
- package/dist/es/dynamic-mapping/components/mapping.js.map +1 -1
- package/dist/es/dynamic-mapping/helpers/mapping.helpers.js +10 -1
- package/dist/es/dynamic-mapping/helpers/mapping.helpers.js.map +1 -1
- package/dist/es/dynamic-mapping/hooks/use-mapping-data.js +36 -21
- package/dist/es/dynamic-mapping/hooks/use-mapping-data.js.map +1 -1
- package/dist/es/dynamic-mapping/index.js +4 -2
- package/dist/es/dynamic-mapping/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
# AppNest Templates - Integration Frontend Components
|
|
2
|
+
|
|
3
|
+
A comprehensive React component library for building integration templates with field mapping, triggers, and data import functionality. Built with TypeScript and Twigs React components.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @sparrowengg/integrations-templates-frontend
|
|
9
|
+
# or
|
|
10
|
+
yarn add @sparrowengg/integrations-templates-frontend
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 🚀 Quick Start
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Mapping, IntegrationTemplate } from '@sparrowengg/integrations-templates-frontend';
|
|
17
|
+
import '@sparrowengg/integrations-templates-frontend/dist/es/index.css';
|
|
18
|
+
|
|
19
|
+
// Basic mapping example
|
|
20
|
+
function MyMappingComponent() {
|
|
21
|
+
return (
|
|
22
|
+
<Mapping
|
|
23
|
+
integrationName="Salesforce"
|
|
24
|
+
// ... mapping props
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 🏗️ Architecture
|
|
31
|
+
|
|
32
|
+
The library is organized into several main modules:
|
|
33
|
+
|
|
34
|
+
- **Mapping** - Complex field mapping between survey data and integration fields
|
|
35
|
+
- **Single Mapping** - Simplified single-step mapping with configuration
|
|
36
|
+
- **Triggers** - Conditional trigger setup with filter conditions
|
|
37
|
+
- **Contact Import** - Contact data import with scheduling and mapping
|
|
38
|
+
- **Dynamic Mapping** - Dynamic field mapping capabilities
|
|
39
|
+
- **Filter** - Filter components for data filtering
|
|
40
|
+
- **Cascader Dropdown** - Hierarchical dropdown navigation
|
|
41
|
+
- **Integration Template** - Main wrapper component that orchestrates all modules
|
|
42
|
+
|
|
43
|
+
## 📚 Components Documentation
|
|
44
|
+
|
|
45
|
+
### Mapping Component
|
|
46
|
+
|
|
47
|
+
The Mapping component provides a comprehensive interface for mapping survey fields to integration fields with support for complex configurations, event setup, and field validation.
|
|
48
|
+
|
|
49
|
+
#### Props
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Required | Description |
|
|
52
|
+
|------|------|----------|-------------|
|
|
53
|
+
| `havingTypeDropdown` | `boolean` | ✅ | Whether to show integration field type dropdown |
|
|
54
|
+
| `onSaveMappingLoader` | `boolean` | ✅ | Loading state for save operation |
|
|
55
|
+
| `surveyDetails` | `SurveyDetails` | ✅ | Survey information object |
|
|
56
|
+
| `integrationName` | `string` | ✅ | Name of the target integration |
|
|
57
|
+
| `fields` | `FieldType[]` | ✅ | Array of mapping field configurations |
|
|
58
|
+
| `setFields` | `React.Dispatch<React.SetStateAction<FieldType[]>>` | ✅ | State setter for fields |
|
|
59
|
+
| `integrationFields` | `IntegrationFieldType[]` | ✅ | Available integration fields |
|
|
60
|
+
| `setIntegrationFields` | `React.Dispatch<React.SetStateAction<IntegrationFieldType[]>>` | ✅ | State setter for integration fields |
|
|
61
|
+
| `apiURL` | `string` | ❌ | API endpoint URL (defaults to SurveySparrow URL) |
|
|
62
|
+
| `token` | `string` | ✅ | Authentication token |
|
|
63
|
+
| `accounts` | `AccountsFieldType` | ✅ | Account selection configuration |
|
|
64
|
+
| `events` | `EventFieldType` | ✅ | Event selection configuration |
|
|
65
|
+
| `actions` | `ActionsFieldType` | ✅ | Action selection configuration |
|
|
66
|
+
| `isMappingPage` | `boolean` | ✅ | Current page state (event setup vs mapping) |
|
|
67
|
+
| `surveyType` | `string` | ✅ | Type of survey |
|
|
68
|
+
| `navigateMappingPage` | `(value?: boolean) => void` | ✅ | Navigation handler |
|
|
69
|
+
| `customList` | `CustomListFieldType` | ✅ | Custom list configuration |
|
|
70
|
+
| `oldResponse` | `OldResponseFieldType` | ✅ | Old response handling configuration |
|
|
71
|
+
| `hasPreviousMapping` | `boolean` | ✅ | Whether previous mapping exists |
|
|
72
|
+
| `onSaveHandler` | `() => void` | ✅ | Save operation handler |
|
|
73
|
+
| `editField` | `EditField \| null` | ✅ | Field being edited |
|
|
74
|
+
| `previousMappingHandler` | `(value?: boolean) => void` | ✅ | Previous mapping navigation handler |
|
|
75
|
+
| `onDeleteHandler` | `(id: string \| number) => void` | ❌ | Delete field handler |
|
|
76
|
+
| `draftHandler` | `(type: string \| null, editFieldId?: string \| number) => void` | ✅ | Draft save handler |
|
|
77
|
+
| `configuration` | `ConfigurationObject` | ✅ | Configuration setup object |
|
|
78
|
+
|
|
79
|
+
#### FieldType
|
|
80
|
+
|
|
81
|
+
| Property | Type | Required | Description |
|
|
82
|
+
|----------|------|----------|-------------|
|
|
83
|
+
| `id` | `string` | ✅ | Unique field identifier |
|
|
84
|
+
| `surveySparrowField` | `SelectOption \| null` | ✅ | Selected survey field |
|
|
85
|
+
| `integrationField` | `SelectOption \| null` | ✅ | Selected integration field |
|
|
86
|
+
| `integrationFieldType` | `SelectOption \| null` | ✅ | Integration field type |
|
|
87
|
+
| `isEssentialField` | `boolean` | ✅ | Whether field is required for integration |
|
|
88
|
+
| `essentialFieldLabel` | `string` | ❌ | Label for essential field |
|
|
89
|
+
| `mappedType` | `SelectOption` | ✅ | Field mapping type |
|
|
90
|
+
| `defaultValue` | `FormFieldValue` | ❌ | Default field value |
|
|
91
|
+
| `dependency` | `Record<string, unknown> \| null` | ✅ | Field dependencies |
|
|
92
|
+
|
|
93
|
+
#### Example
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { Mapping } from '@sparrowengg/integrations-templates-frontend';
|
|
97
|
+
|
|
98
|
+
function MappingExample() {
|
|
99
|
+
const [fields, setFields] = useState([
|
|
100
|
+
{
|
|
101
|
+
id: "email_field",
|
|
102
|
+
surveySparrowField: null,
|
|
103
|
+
integrationField: null,
|
|
104
|
+
integrationFieldType: null,
|
|
105
|
+
isEssentialField: true,
|
|
106
|
+
essentialFieldLabel: "Email",
|
|
107
|
+
mappedType: { label: "Email", value: "email" },
|
|
108
|
+
defaultValue: null,
|
|
109
|
+
dependency: null
|
|
110
|
+
}
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
const [integrationFields, setIntegrationFields] = useState([
|
|
114
|
+
{
|
|
115
|
+
id: "email",
|
|
116
|
+
label: "Email Address",
|
|
117
|
+
value: "email",
|
|
118
|
+
type: "string"
|
|
119
|
+
}
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<Mapping
|
|
124
|
+
havingTypeDropdown={true}
|
|
125
|
+
onSaveMappingLoader={false}
|
|
126
|
+
surveyDetails={{
|
|
127
|
+
surveyName: "Customer Feedback Survey",
|
|
128
|
+
surveyId: "survey_123"
|
|
129
|
+
}}
|
|
130
|
+
integrationName="Salesforce"
|
|
131
|
+
fields={fields}
|
|
132
|
+
setFields={setFields}
|
|
133
|
+
integrationFields={integrationFields}
|
|
134
|
+
setIntegrationFields={setIntegrationFields}
|
|
135
|
+
token="your_auth_token"
|
|
136
|
+
accounts={{
|
|
137
|
+
hasAccounts: true,
|
|
138
|
+
options: [{ label: "Main Account", value: "acc_1" }],
|
|
139
|
+
value: null,
|
|
140
|
+
onChangeHandler: (value) => console.log('Account selected:', value)
|
|
141
|
+
}}
|
|
142
|
+
events={{
|
|
143
|
+
hasEvents: true,
|
|
144
|
+
options: [{ label: "Contact Update", value: "contact_update" }],
|
|
145
|
+
value: null,
|
|
146
|
+
onChangeHandler: (value) => console.log('Event selected:', value)
|
|
147
|
+
}}
|
|
148
|
+
actions={{
|
|
149
|
+
hasActions: true,
|
|
150
|
+
options: [{ label: "Create Contact", value: "create_contact" }],
|
|
151
|
+
value: null,
|
|
152
|
+
onChangeHandler: (value) => console.log('Action selected:', value)
|
|
153
|
+
}}
|
|
154
|
+
isMappingPage={false}
|
|
155
|
+
surveyType="standard"
|
|
156
|
+
navigateMappingPage={(value) => console.log('Navigate to mapping:', value)}
|
|
157
|
+
customList={{ hasCustomList: false, value: null, onChangeHandler: () => {} }}
|
|
158
|
+
oldResponse={{ hasOldResponse: false, value: null, onChangeHandler: () => {} }}
|
|
159
|
+
hasPreviousMapping={false}
|
|
160
|
+
onSaveHandler={() => console.log('Mapping saved')}
|
|
161
|
+
editField={null}
|
|
162
|
+
previousMappingHandler={() => console.log('Go back')}
|
|
163
|
+
draftHandler={(type, id) => console.log('Save draft:', type, id)}
|
|
164
|
+
configuration={{
|
|
165
|
+
hasConfiguration: false,
|
|
166
|
+
configurationFields: [],
|
|
167
|
+
configuredFields: {},
|
|
168
|
+
title: "Event Configuration"
|
|
169
|
+
}}
|
|
170
|
+
/>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### SingleMapping Component
|
|
178
|
+
|
|
179
|
+
The SingleMapping component provides a simplified mapping interface with configuration steps, ideal for straightforward integration scenarios.
|
|
180
|
+
|
|
181
|
+
#### Props
|
|
182
|
+
|
|
183
|
+
| Prop | Type | Required | Description |
|
|
184
|
+
|------|------|----------|-------------|
|
|
185
|
+
| `hasPreviousMapping` | `boolean` | ❌ | Whether previous mapping exists |
|
|
186
|
+
| `integrationFields` | `IntegrationField[]` | ✅ | Available integration fields |
|
|
187
|
+
| `configuration` | `SingleMappingConfiguration` | ✅ | Configuration object |
|
|
188
|
+
| `token` | `string` | ❌ | Authentication token |
|
|
189
|
+
| `isMappingPage` | `boolean` | ✅ | Current page state |
|
|
190
|
+
| `navigateMappingPage` | `(value?: boolean) => void` | ✅ | Navigation handler |
|
|
191
|
+
| `apiURL` | `string` | ❌ | API endpoint URL |
|
|
192
|
+
| `surveyDetails` | `SurveyDetails` | ✅ | Survey information |
|
|
193
|
+
| `onSaveHandler` | `(fields: any) => void` | ✅ | Save handler |
|
|
194
|
+
| `setIntegrationFields` | `React.Dispatch<React.SetStateAction<any>>` | ✅ | Integration fields setter |
|
|
195
|
+
| `hasExistingMapping` | `boolean` | ✅ | Whether existing mapping is present |
|
|
196
|
+
| `importResponse` | `ImportResponse` | ✅ | Import response configuration |
|
|
197
|
+
| `editField` | `any` | ❌ | Field being edited |
|
|
198
|
+
| `previousMappingHandler` | `(value?: boolean) => void` | ❌ | Previous mapping handler |
|
|
199
|
+
|
|
200
|
+
#### Example
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
import { SingleMapping } from '@sparrowengg/integrations-templates-frontend';
|
|
204
|
+
|
|
205
|
+
function SingleMappingExample() {
|
|
206
|
+
const [integrationFields, setIntegrationFields] = useState([
|
|
207
|
+
{ id: 1, label: "Name", value: "name", type: "string" },
|
|
208
|
+
{ id: 2, label: "Email", value: "email", type: "email" }
|
|
209
|
+
]);
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<SingleMapping
|
|
213
|
+
integrationFields={integrationFields}
|
|
214
|
+
setIntegrationFields={setIntegrationFields}
|
|
215
|
+
configuration={{
|
|
216
|
+
importOptions: {
|
|
217
|
+
showImportOptions: true,
|
|
218
|
+
excludeResponse: {
|
|
219
|
+
id: "exclude",
|
|
220
|
+
label: "Exclude existing responses",
|
|
221
|
+
ifChecked: () => "Existing responses will be excluded",
|
|
222
|
+
ifUnchecked: () => "All responses will be included",
|
|
223
|
+
fieldType: "checkbox",
|
|
224
|
+
value: false,
|
|
225
|
+
onChangeHandler: (value) => console.log('Exclude changed:', value)
|
|
226
|
+
},
|
|
227
|
+
options: [
|
|
228
|
+
{
|
|
229
|
+
id: 1,
|
|
230
|
+
label: "Import All Data",
|
|
231
|
+
value: "all",
|
|
232
|
+
description: "Import all available data",
|
|
233
|
+
type: null
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
onChangeHandler: (value) => console.log('Import option changed:', value)
|
|
237
|
+
},
|
|
238
|
+
hasConfiguration: true,
|
|
239
|
+
configuredFields: {},
|
|
240
|
+
configurationFields: [],
|
|
241
|
+
onSaveHandler: () => console.log('Configuration saved')
|
|
242
|
+
}}
|
|
243
|
+
isMappingPage={false}
|
|
244
|
+
navigateMappingPage={(value) => console.log('Navigate:', value)}
|
|
245
|
+
surveyDetails={{
|
|
246
|
+
surveyName: "Product Feedback",
|
|
247
|
+
surveyId: "prod_survey_1"
|
|
248
|
+
}}
|
|
249
|
+
onSaveHandler={(fields) => console.log('Single mapping saved:', fields)}
|
|
250
|
+
hasExistingMapping={false}
|
|
251
|
+
importResponse={{
|
|
252
|
+
hasImportResponse: true,
|
|
253
|
+
value: { importMethod: "SEND_ALL_DATA" },
|
|
254
|
+
onChangeHandler: (value) => console.log('Import response changed:', value)
|
|
255
|
+
}}
|
|
256
|
+
/>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### Triggers Component
|
|
264
|
+
|
|
265
|
+
The Triggers component provides a comprehensive interface for setting up conditional triggers with filter conditions and notification settings.
|
|
266
|
+
|
|
267
|
+
#### Props
|
|
268
|
+
|
|
269
|
+
| Prop | Type | Required | Description |
|
|
270
|
+
|------|------|----------|-------------|
|
|
271
|
+
| `draftHandler` | `(type: string \| null, editFieldId?: string) => void` | ✅ | Draft save handler |
|
|
272
|
+
| `onSaveTriggerLoader` | `boolean` | ✅ | Loading state for save operation |
|
|
273
|
+
| `objects` | `ObjectsFieldType` | ✅ | Object selection configuration |
|
|
274
|
+
| `accounts` | `AccountsFieldType` | ✅ | Account selection configuration |
|
|
275
|
+
| `actions` | `ActionsFieldType` | ✅ | Action selection configuration |
|
|
276
|
+
| `isTriggerPage` | `boolean` | ✅ | Current page state |
|
|
277
|
+
| `navigateTriggerPage` | `(isTriggerPage: boolean) => void` | ✅ | Page navigation handler |
|
|
278
|
+
| `previousMapping` | `boolean` | ✅ | Whether previous mapping exists |
|
|
279
|
+
| `onSaveHandler` | `(editFieldId?: string) => void` | ✅ | Save operation handler |
|
|
280
|
+
| `previousMappingHandler` | `() => void` | ✅ | Previous mapping navigation |
|
|
281
|
+
| `surveyDetails` | `SurveyDetails` | ✅ | Survey information |
|
|
282
|
+
| `hasNestedCondition` | `boolean` | ✅ | Whether nested conditions are supported |
|
|
283
|
+
| `fields` | `TriggerField` | ✅ | Trigger field configuration |
|
|
284
|
+
| `token` | `string` | ✅ | Authentication token |
|
|
285
|
+
| `apiURL` | `string` | ✅ | API endpoint URL |
|
|
286
|
+
| `setFields` | `(fields: TriggerField) => void` | ✅ | Fields state setter |
|
|
287
|
+
| `shareRecipentOptions` | `SelectOption[]` | ✅ | Share recipient options |
|
|
288
|
+
| `shareChannelOptions` | `SelectOption[]` | ✅ | Share channel options |
|
|
289
|
+
| `triggerDetails` | `TriggerDetails` | ✅ | Trigger details configuration |
|
|
290
|
+
| `setTriggerDetails` | `(details: TriggerDetails) => void` | ✅ | Trigger details setter |
|
|
291
|
+
| `editField` | `EditField \| null` | ✅ | Field being edited |
|
|
292
|
+
| `fieldOptions` | `SelectOption[]` | ✅ | Available field options |
|
|
293
|
+
| `variableOptions` | `SelectOption[]` | ✅ | Available variable options |
|
|
294
|
+
|
|
295
|
+
#### TriggerField
|
|
296
|
+
|
|
297
|
+
| Property | Type | Required | Description |
|
|
298
|
+
|----------|------|----------|-------------|
|
|
299
|
+
| `id` | `string` | ✅ | Unique trigger identifier |
|
|
300
|
+
| `filters` | `FilterGroup[]` | ✅ | Array of filter groups |
|
|
301
|
+
|
|
302
|
+
#### FilterGroup
|
|
303
|
+
|
|
304
|
+
| Property | Type | Required | Description |
|
|
305
|
+
|----------|------|----------|-------------|
|
|
306
|
+
| `id` | `string` | ✅ | Filter group identifier |
|
|
307
|
+
| `conditions` | `FilterCondition[]` | ✅ | Array of filter conditions |
|
|
308
|
+
| `operator` | `'AND' \| 'OR'` | ✅ | Logical operator between conditions |
|
|
309
|
+
|
|
310
|
+
#### Example
|
|
311
|
+
|
|
312
|
+
```tsx
|
|
313
|
+
import { Triggers } from '@sparrowengg/integrations-templates-frontend';
|
|
314
|
+
|
|
315
|
+
function TriggersExample() {
|
|
316
|
+
const [triggerFields, setTriggerFields] = useState({
|
|
317
|
+
id: "trigger_1",
|
|
318
|
+
filters: [
|
|
319
|
+
{
|
|
320
|
+
id: "group_1",
|
|
321
|
+
conditions: [
|
|
322
|
+
{
|
|
323
|
+
id: "condition_1",
|
|
324
|
+
field: { label: "Score", value: "score" },
|
|
325
|
+
operator: { label: "Greater than", value: "gt" },
|
|
326
|
+
value: 8
|
|
327
|
+
}
|
|
328
|
+
],
|
|
329
|
+
operator: "AND"
|
|
330
|
+
}
|
|
331
|
+
]
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
const [triggerDetails, setTriggerDetails] = useState({
|
|
335
|
+
shareChannel: { label: "Email", value: "email" },
|
|
336
|
+
shareRecipient: { label: "Admin", value: "admin@company.com" },
|
|
337
|
+
shareType: { label: "Notification", value: "notification" }
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
return (
|
|
341
|
+
<Triggers
|
|
342
|
+
draftHandler={(type, id) => console.log('Save draft:', type, id)}
|
|
343
|
+
onSaveTriggerLoader={false}
|
|
344
|
+
objects={{
|
|
345
|
+
hasObjects: true,
|
|
346
|
+
options: [{ label: "Survey Response", value: "response" }],
|
|
347
|
+
value: { label: "Survey Response", value: "response" },
|
|
348
|
+
onChangeHandler: (value) => console.log('Object selected:', value)
|
|
349
|
+
}}
|
|
350
|
+
accounts={{
|
|
351
|
+
hasAccounts: false,
|
|
352
|
+
options: [],
|
|
353
|
+
value: null,
|
|
354
|
+
onChangeHandler: () => {}
|
|
355
|
+
}}
|
|
356
|
+
actions={{
|
|
357
|
+
hasActions: true,
|
|
358
|
+
options: [{ label: "Send Notification", value: "notify" }],
|
|
359
|
+
value: { label: "Send Notification", value: "notify" },
|
|
360
|
+
onChangeHandler: (value) => console.log('Action selected:', value)
|
|
361
|
+
}}
|
|
362
|
+
isTriggerPage={false}
|
|
363
|
+
navigateTriggerPage={(value) => console.log('Navigate to trigger page:', value)}
|
|
364
|
+
previousMapping={false}
|
|
365
|
+
onSaveHandler={(id) => console.log('Trigger saved:', id)}
|
|
366
|
+
previousMappingHandler={() => console.log('Go back')}
|
|
367
|
+
surveyDetails={{
|
|
368
|
+
surveyName: "Customer Satisfaction",
|
|
369
|
+
surveyId: "csat_survey"
|
|
370
|
+
}}
|
|
371
|
+
hasNestedCondition={true}
|
|
372
|
+
fields={triggerFields}
|
|
373
|
+
token="auth_token"
|
|
374
|
+
apiURL="https://api.example.com"
|
|
375
|
+
setFields={setTriggerFields}
|
|
376
|
+
shareRecipentOptions={[
|
|
377
|
+
{ label: "Admin", value: "admin@company.com" },
|
|
378
|
+
{ label: "Manager", value: "manager@company.com" }
|
|
379
|
+
]}
|
|
380
|
+
shareChannelOptions={[
|
|
381
|
+
{ label: "Email", value: "email" },
|
|
382
|
+
{ label: "Slack", value: "slack" }
|
|
383
|
+
]}
|
|
384
|
+
triggerDetails={triggerDetails}
|
|
385
|
+
setTriggerDetails={setTriggerDetails}
|
|
386
|
+
editField={null}
|
|
387
|
+
fieldOptions={[
|
|
388
|
+
{ label: "Score", value: "score" },
|
|
389
|
+
{ label: "Category", value: "category" }
|
|
390
|
+
]}
|
|
391
|
+
variableOptions={[
|
|
392
|
+
{ label: "Response ID", value: "response_id" },
|
|
393
|
+
{ label: "Respondent Email", value: "respondent_email" }
|
|
394
|
+
]}
|
|
395
|
+
/>
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
### ContactImport Component
|
|
403
|
+
|
|
404
|
+
The ContactImport component provides functionality for importing contact data with mapping, scheduling, and management capabilities.
|
|
405
|
+
|
|
406
|
+
#### Props
|
|
407
|
+
|
|
408
|
+
| Prop | Type | Required | Description |
|
|
409
|
+
|------|------|----------|-------------|
|
|
410
|
+
| `dashboardDescription` | `string` | ✅ | Description text for dashboard |
|
|
411
|
+
| `existingImports` | `Array<CompletedImportTypes \| ScheduledImportTypes> \| null` | ✅ | Existing import records |
|
|
412
|
+
| `hasPreviousMapping` | `boolean` | ❌ | Whether previous mapping exists |
|
|
413
|
+
| `previousMappingHandler` | `(value?: boolean) => void` | ✅ | Previous mapping handler |
|
|
414
|
+
| `onSaveHandler` | `() => void` | ✅ | Save operation handler |
|
|
415
|
+
| `isContactMappingPage` | `boolean` | ✅ | Current page state |
|
|
416
|
+
| `navigateMappingPage` | `(value?: boolean) => void` | ✅ | Navigation handler |
|
|
417
|
+
| `contactImportField` | `ContactImportFieldType` | ✅ | Contact import configuration |
|
|
418
|
+
| `setContactImportField` | `React.Dispatch<React.SetStateAction<ContactImportFieldType>>` | ✅ | Configuration setter |
|
|
419
|
+
| `listSegmentOptions` | `SelectOption[]` | ✅ | List segment options |
|
|
420
|
+
| `integrationName` | `string` | ✅ | Integration name |
|
|
421
|
+
| `contactProperties` | `ContactProperty[]` | ✅ | Available contact properties |
|
|
422
|
+
| `invitePortal` | `InvitePortalType` | ✅ | Invite portal configuration |
|
|
423
|
+
|
|
424
|
+
#### ContactImportFieldType
|
|
425
|
+
|
|
426
|
+
| Property | Type | Required | Description |
|
|
427
|
+
|----------|------|----------|-------------|
|
|
428
|
+
| `configure` | `ConfigureObject \| null` | ✅ | Configuration settings |
|
|
429
|
+
| `description` | `string \| null` | ✅ | Import description |
|
|
430
|
+
| `id` | `string \| number \| null` | ✅ | Import identifier |
|
|
431
|
+
| `fields` | `ContactFieldType[]` | ✅ | Field mappings |
|
|
432
|
+
| `invitePortal` | `boolean` | ✅ | Whether to invite to portal |
|
|
433
|
+
|
|
434
|
+
#### Example
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
import { ContactImport } from '@sparrowengg/integrations-templates-frontend';
|
|
438
|
+
|
|
439
|
+
function ContactImportExample() {
|
|
440
|
+
const [contactImportField, setContactImportField] = useState({
|
|
441
|
+
configure: null,
|
|
442
|
+
description: null,
|
|
443
|
+
id: null,
|
|
444
|
+
fields: [],
|
|
445
|
+
invitePortal: false
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
return (
|
|
449
|
+
<ContactImport
|
|
450
|
+
dashboardDescription="Manage your contact imports and sync data with your integration."
|
|
451
|
+
existingImports={[]}
|
|
452
|
+
hasPreviousMapping={false}
|
|
453
|
+
previousMappingHandler={() => console.log('Go back')}
|
|
454
|
+
onSaveHandler={() => console.log('Import saved')}
|
|
455
|
+
isContactMappingPage={false}
|
|
456
|
+
navigateMappingPage={(value) => console.log('Navigate:', value)}
|
|
457
|
+
contactImportField={contactImportField}
|
|
458
|
+
setContactImportField={setContactImportField}
|
|
459
|
+
listSegmentOptions={[
|
|
460
|
+
{ label: "All Contacts", value: "all" },
|
|
461
|
+
{ label: "Active Subscribers", value: "active" }
|
|
462
|
+
]}
|
|
463
|
+
integrationName="Mailchimp"
|
|
464
|
+
contactProperties={[
|
|
465
|
+
{ id: 1, label: "Email", value: "email", type: "email" },
|
|
466
|
+
{ id: 2, label: "First Name", value: "first_name", type: "text" }
|
|
467
|
+
]}
|
|
468
|
+
invitePortal={{
|
|
469
|
+
hasInvitePortal: true,
|
|
470
|
+
value: false,
|
|
471
|
+
onChangeHandler: (value) => console.log('Invite portal:', value)
|
|
472
|
+
}}
|
|
473
|
+
/>
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
### IntegrationTemplate Component
|
|
481
|
+
|
|
482
|
+
The IntegrationTemplate is the main orchestrating component that manages the flow between different integration steps including mapping, triggers, and dashboard views.
|
|
483
|
+
|
|
484
|
+
#### Props
|
|
485
|
+
|
|
486
|
+
| Prop | Type | Required | Description |
|
|
487
|
+
|------|------|----------|-------------|
|
|
488
|
+
| `singleMapping` | `SingleMappingType` | ❌ | Single mapping configuration |
|
|
489
|
+
| `draftHandler` | `(type: string \| null) => void` | ✅ | Draft save handler |
|
|
490
|
+
| `onMappingEditHandler` | `(field: unknown) => void` | ✅ | Mapping edit handler |
|
|
491
|
+
| `fieldOptions` | `FieldOptionsType` | ✅ | Available field options |
|
|
492
|
+
| `triggerEnabled` | `boolean` | ✅ | Whether triggers are enabled |
|
|
493
|
+
| `mappingEnabled` | `boolean` | ✅ | Whether mapping is enabled |
|
|
494
|
+
| `mappingComponent` | `React.ReactElement` | ✅ | Mapping component instance |
|
|
495
|
+
| `singleMappingComponent` | `React.ReactElement` | ❌ | Single mapping component instance |
|
|
496
|
+
| `mapping` | `MappingState` | ✅ | Mapping state object |
|
|
497
|
+
| `triggerComponent` | `React.ReactElement` | ✅ | Trigger component instance |
|
|
498
|
+
| `trigger` | `TriggerState` | ✅ | Trigger state object |
|
|
499
|
+
| `integrationName` | `string` | ✅ | Integration name |
|
|
500
|
+
| `onDeleteHandler` | `(id: string \| number) => void` | ❌ | Delete handler |
|
|
501
|
+
| `toggleDashboardField` | `(id: string \| number, status: boolean) => void` | ❌ | Dashboard field toggle |
|
|
502
|
+
| `dashboardDescription` | `string` | ✅ | Dashboard description |
|
|
503
|
+
| `mappingDescription` | `string` | ✅ | Mapping description |
|
|
504
|
+
| `triggerDescription` | `string` | ✅ | Trigger description |
|
|
505
|
+
| `handlePreviousNavigation` | `() => void` | ✅ | Previous navigation handler |
|
|
506
|
+
| `surveyType` | `string` | ❌ | Survey type |
|
|
507
|
+
| `syncMapping` | `(id: string \| number) => void` | ❌ | Sync mapping handler |
|
|
508
|
+
|
|
509
|
+
#### Example
|
|
510
|
+
|
|
511
|
+
```tsx
|
|
512
|
+
import { IntegrationTemplate, Mapping, Triggers } from '@sparrowengg/integrations-templates-frontend';
|
|
513
|
+
|
|
514
|
+
function IntegrationTemplateExample() {
|
|
515
|
+
const [mappingFields, setMappingFields] = useState({ type: "MAPPING", fields: [] });
|
|
516
|
+
const [triggerFields, setTriggerFields] = useState([]);
|
|
517
|
+
|
|
518
|
+
const mappingComponent = (
|
|
519
|
+
<Mapping
|
|
520
|
+
// ... mapping props
|
|
521
|
+
onSaveHandler={() => console.log('Mapping saved')}
|
|
522
|
+
/>
|
|
523
|
+
);
|
|
524
|
+
|
|
525
|
+
const triggerComponent = (
|
|
526
|
+
<Triggers
|
|
527
|
+
// ... trigger props
|
|
528
|
+
onSaveHandler={() => console.log('Trigger saved')}
|
|
529
|
+
/>
|
|
530
|
+
);
|
|
531
|
+
|
|
532
|
+
return (
|
|
533
|
+
<IntegrationTemplate
|
|
534
|
+
draftHandler={(type) => console.log('Save draft:', type)}
|
|
535
|
+
onMappingEditHandler={(field) => console.log('Edit mapping:', field)}
|
|
536
|
+
fieldOptions={[
|
|
537
|
+
{ label: "Email", value: "email" },
|
|
538
|
+
{ label: "Name", value: "name" }
|
|
539
|
+
]}
|
|
540
|
+
triggerEnabled={true}
|
|
541
|
+
mappingEnabled={true}
|
|
542
|
+
mappingComponent={mappingComponent}
|
|
543
|
+
mapping={{
|
|
544
|
+
mappedFields: mappingFields,
|
|
545
|
+
setMappedFields: setMappingFields
|
|
546
|
+
}}
|
|
547
|
+
triggerComponent={triggerComponent}
|
|
548
|
+
trigger={{
|
|
549
|
+
mappedFields: triggerFields,
|
|
550
|
+
setMappedFields: setTriggerFields
|
|
551
|
+
}}
|
|
552
|
+
integrationName="Salesforce"
|
|
553
|
+
dashboardDescription="Manage your Salesforce integration configurations."
|
|
554
|
+
mappingDescription="Map survey fields to Salesforce objects."
|
|
555
|
+
triggerDescription="Set up automated triggers based on survey responses."
|
|
556
|
+
handlePreviousNavigation={() => console.log('Navigate back')}
|
|
557
|
+
/>
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
## 🎨 Styling
|
|
563
|
+
|
|
564
|
+
The library includes built-in CSS styles. Make sure to import the stylesheet:
|
|
565
|
+
|
|
566
|
+
```tsx
|
|
567
|
+
import '@sparrowengg/integrations-templates-frontend/dist/es/index.css';
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
All components use the Twigs React design system and support custom theming through the ThemeProvider.
|
|
571
|
+
|
|
572
|
+
## 🔧 Advanced Usage
|
|
573
|
+
|
|
574
|
+
### Custom Theme Configuration
|
|
575
|
+
|
|
576
|
+
```tsx
|
|
577
|
+
import { ThemeProvider } from '@sparrowengg/twigs-react';
|
|
578
|
+
|
|
579
|
+
const customTheme = {
|
|
580
|
+
fonts: {
|
|
581
|
+
body: "Inter, sans-serif",
|
|
582
|
+
heading: "Inter, sans-serif"
|
|
583
|
+
},
|
|
584
|
+
colors: {
|
|
585
|
+
primary500: "#4A9CA6"
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
function App() {
|
|
590
|
+
return (
|
|
591
|
+
<ThemeProvider theme={customTheme}>
|
|
592
|
+
{/* Your components */}
|
|
593
|
+
</ThemeProvider>
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Error Handling
|
|
599
|
+
|
|
600
|
+
Components provide error states and validation feedback:
|
|
601
|
+
|
|
602
|
+
```tsx
|
|
603
|
+
// Field with validation error
|
|
604
|
+
{
|
|
605
|
+
id: "email",
|
|
606
|
+
type: "input",
|
|
607
|
+
label: "Email",
|
|
608
|
+
value: "invalid-email",
|
|
609
|
+
changeFieldValue: handleChange,
|
|
610
|
+
required: true,
|
|
611
|
+
// Error will be shown if validation fails
|
|
612
|
+
}
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Loading States
|
|
616
|
+
|
|
617
|
+
Most components support loading states for async operations:
|
|
618
|
+
|
|
619
|
+
```tsx
|
|
620
|
+
<Mapping
|
|
621
|
+
onSaveMappingLoader={true} // Shows loading spinner on save button
|
|
622
|
+
// ... other props
|
|
623
|
+
/>
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
## 🤝 TypeScript Support
|
|
627
|
+
|
|
628
|
+
The library is built with TypeScript and provides comprehensive type definitions for all components and props. Import types as needed:
|
|
629
|
+
|
|
630
|
+
```tsx
|
|
631
|
+
import type {
|
|
632
|
+
MappingProps,
|
|
633
|
+
TriggerProps,
|
|
634
|
+
SelectOption,
|
|
635
|
+
FieldType
|
|
636
|
+
} from '@sparrowengg/integrations-templates-frontend';
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
## 📖 API Reference
|
|
640
|
+
|
|
641
|
+
### Common Types
|
|
642
|
+
|
|
643
|
+
#### SelectOption
|
|
644
|
+
```tsx
|
|
645
|
+
type SelectOption = {
|
|
646
|
+
label: string;
|
|
647
|
+
value: string | number;
|
|
648
|
+
type?: string;
|
|
649
|
+
};
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
#### SurveyDetails
|
|
653
|
+
```tsx
|
|
654
|
+
type SurveyDetails = {
|
|
655
|
+
surveyName: string;
|
|
656
|
+
surveyId: string | number;
|
|
657
|
+
};
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
#### FormFieldValue
|
|
661
|
+
```tsx
|
|
662
|
+
type FormFieldValue = string | number | boolean | null | SelectOption | SelectOption[];
|
|
663
|
+
```
|
|
@@ -33,7 +33,8 @@ const Mapping = ({
|
|
|
33
33
|
setSSMappingData,
|
|
34
34
|
editField,
|
|
35
35
|
setIsInitialLoad,
|
|
36
|
-
setOriginalMappingData
|
|
36
|
+
setOriginalMappingData,
|
|
37
|
+
hasResponsePDF
|
|
37
38
|
}) => {
|
|
38
39
|
var _a, _b, _c;
|
|
39
40
|
const {
|
|
@@ -55,7 +56,8 @@ const Mapping = ({
|
|
|
55
56
|
setIsInitialLoad,
|
|
56
57
|
setOriginalMappingData,
|
|
57
58
|
ssMappingData,
|
|
58
|
-
setSSMappingData
|
|
59
|
+
setSSMappingData,
|
|
60
|
+
hasResponsePDF
|
|
59
61
|
});
|
|
60
62
|
const mappingData = hookSsMappingData;
|
|
61
63
|
const effectiveConditionData = React.useMemo(() => {
|