@23blocks/block-forms 3.0.0 → 3.0.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 +296 -0
- package/dist/index.esm.js +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# @23blocks/block-forms
|
|
2
|
+
|
|
3
|
+
Forms block for the 23blocks SDK - dynamic forms, schemas, and submissions.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@23blocks/block-forms)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @23blocks/block-forms @23blocks/transport-http
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
This package provides form building and submission functionality including:
|
|
17
|
+
|
|
18
|
+
- **Forms** - Form definitions and configurations
|
|
19
|
+
- **Form Schemas** - Field definitions and validations
|
|
20
|
+
- **Form Instances** - Individual form submissions
|
|
21
|
+
- **Form Sets** - Groups of related forms
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { createHttpTransport } from '@23blocks/transport-http';
|
|
27
|
+
import { createFormsBlock } from '@23blocks/block-forms';
|
|
28
|
+
|
|
29
|
+
const transport = createHttpTransport({
|
|
30
|
+
baseUrl: 'https://api.yourapp.com',
|
|
31
|
+
headers: () => {
|
|
32
|
+
const token = localStorage.getItem('access_token');
|
|
33
|
+
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const forms = createFormsBlock(transport, {
|
|
38
|
+
apiKey: 'your-api-key',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// List forms
|
|
42
|
+
const { data: formList } = await forms.forms.list();
|
|
43
|
+
|
|
44
|
+
// Submit a form
|
|
45
|
+
const submission = await forms.formInstances.submit({
|
|
46
|
+
formId: 'form-id',
|
|
47
|
+
data: {
|
|
48
|
+
name: 'John Doe',
|
|
49
|
+
email: 'john@example.com',
|
|
50
|
+
message: 'Hello!',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Services
|
|
56
|
+
|
|
57
|
+
### forms - Form Management
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// List forms
|
|
61
|
+
const { data: formList } = await forms.forms.list({
|
|
62
|
+
limit: 20,
|
|
63
|
+
status: 'active',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Get form by ID
|
|
67
|
+
const form = await forms.forms.get('form-id');
|
|
68
|
+
|
|
69
|
+
// Create form
|
|
70
|
+
const newForm = await forms.forms.create({
|
|
71
|
+
name: 'Contact Form',
|
|
72
|
+
description: 'Contact us form',
|
|
73
|
+
status: 'active',
|
|
74
|
+
schemaId: 'schema-id',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Update form
|
|
78
|
+
await forms.forms.update('form-id', {
|
|
79
|
+
name: 'Updated Contact Form',
|
|
80
|
+
status: 'inactive',
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Delete form
|
|
84
|
+
await forms.forms.delete('form-id');
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### formSchemas - Schema Management
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// List schemas
|
|
91
|
+
const { data: schemas } = await forms.formSchemas.list();
|
|
92
|
+
|
|
93
|
+
// Get schema by ID
|
|
94
|
+
const schema = await forms.formSchemas.get('schema-id');
|
|
95
|
+
|
|
96
|
+
// Create schema
|
|
97
|
+
const newSchema = await forms.formSchemas.create({
|
|
98
|
+
name: 'Contact Schema',
|
|
99
|
+
fields: [
|
|
100
|
+
{
|
|
101
|
+
name: 'name',
|
|
102
|
+
type: 'text',
|
|
103
|
+
label: 'Your Name',
|
|
104
|
+
required: true,
|
|
105
|
+
validation: { minLength: 2, maxLength: 100 },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'email',
|
|
109
|
+
type: 'email',
|
|
110
|
+
label: 'Email Address',
|
|
111
|
+
required: true,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'message',
|
|
115
|
+
type: 'textarea',
|
|
116
|
+
label: 'Message',
|
|
117
|
+
required: true,
|
|
118
|
+
validation: { minLength: 10, maxLength: 1000 },
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'priority',
|
|
122
|
+
type: 'select',
|
|
123
|
+
label: 'Priority',
|
|
124
|
+
options: ['low', 'medium', 'high'],
|
|
125
|
+
defaultValue: 'medium',
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Update schema
|
|
131
|
+
await forms.formSchemas.update('schema-id', {
|
|
132
|
+
fields: [
|
|
133
|
+
// updated fields
|
|
134
|
+
],
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Delete schema
|
|
138
|
+
await forms.formSchemas.delete('schema-id');
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### formInstances - Form Submissions
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// List submissions
|
|
145
|
+
const { data: submissions } = await forms.formInstances.list({
|
|
146
|
+
formId: 'form-id',
|
|
147
|
+
status: 'submitted',
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Get submission by ID
|
|
151
|
+
const submission = await forms.formInstances.get('instance-id');
|
|
152
|
+
|
|
153
|
+
// Create a draft instance
|
|
154
|
+
const draft = await forms.formInstances.create({
|
|
155
|
+
formId: 'form-id',
|
|
156
|
+
data: {
|
|
157
|
+
name: 'John',
|
|
158
|
+
},
|
|
159
|
+
status: 'draft',
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Update draft
|
|
163
|
+
await forms.formInstances.update('instance-id', {
|
|
164
|
+
data: {
|
|
165
|
+
name: 'John Doe',
|
|
166
|
+
email: 'john@example.com',
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Submit form
|
|
171
|
+
const submitted = await forms.formInstances.submit({
|
|
172
|
+
formId: 'form-id',
|
|
173
|
+
data: {
|
|
174
|
+
name: 'John Doe',
|
|
175
|
+
email: 'john@example.com',
|
|
176
|
+
message: 'Hello, I have a question...',
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Delete submission
|
|
181
|
+
await forms.formInstances.delete('instance-id');
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### formSets - Form Set Management
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// List form sets
|
|
188
|
+
const { data: sets } = await forms.formSets.list();
|
|
189
|
+
|
|
190
|
+
// Get form set by ID
|
|
191
|
+
const formSet = await forms.formSets.get('set-id');
|
|
192
|
+
|
|
193
|
+
// Create form set
|
|
194
|
+
const newSet = await forms.formSets.create({
|
|
195
|
+
name: 'Onboarding Forms',
|
|
196
|
+
description: 'Forms required for new user onboarding',
|
|
197
|
+
formReferences: [
|
|
198
|
+
{ formId: 'form-1', order: 1, required: true },
|
|
199
|
+
{ formId: 'form-2', order: 2, required: false },
|
|
200
|
+
{ formId: 'form-3', order: 3, required: true },
|
|
201
|
+
],
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Update form set
|
|
205
|
+
await forms.formSets.update('set-id', {
|
|
206
|
+
formReferences: [
|
|
207
|
+
{ formId: 'form-1', order: 1, required: true },
|
|
208
|
+
{ formId: 'form-2', order: 2, required: true },
|
|
209
|
+
],
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Delete form set
|
|
213
|
+
await forms.formSets.delete('set-id');
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Types
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import type {
|
|
220
|
+
Form,
|
|
221
|
+
FormSchema,
|
|
222
|
+
FormInstance,
|
|
223
|
+
FormSet,
|
|
224
|
+
FormReference,
|
|
225
|
+
CreateFormRequest,
|
|
226
|
+
CreateFormSchemaRequest,
|
|
227
|
+
CreateFormInstanceRequest,
|
|
228
|
+
SubmitFormInstanceRequest,
|
|
229
|
+
CreateFormSetRequest,
|
|
230
|
+
} from '@23blocks/block-forms';
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Form
|
|
234
|
+
|
|
235
|
+
| Property | Type | Description |
|
|
236
|
+
|----------|------|-------------|
|
|
237
|
+
| `id` | `string` | Form ID |
|
|
238
|
+
| `uniqueId` | `string` | Unique identifier |
|
|
239
|
+
| `name` | `string` | Form name |
|
|
240
|
+
| `description` | `string` | Form description |
|
|
241
|
+
| `status` | `string` | active, inactive, archived |
|
|
242
|
+
| `schemaId` | `string` | Associated schema ID |
|
|
243
|
+
| `schema` | `FormSchema` | Schema details |
|
|
244
|
+
|
|
245
|
+
### FormSchema
|
|
246
|
+
|
|
247
|
+
| Property | Type | Description |
|
|
248
|
+
|----------|------|-------------|
|
|
249
|
+
| `id` | `string` | Schema ID |
|
|
250
|
+
| `name` | `string` | Schema name |
|
|
251
|
+
| `fields` | `Field[]` | Field definitions |
|
|
252
|
+
| `validations` | `object` | Form-level validations |
|
|
253
|
+
|
|
254
|
+
### FormInstance
|
|
255
|
+
|
|
256
|
+
| Property | Type | Description |
|
|
257
|
+
|----------|------|-------------|
|
|
258
|
+
| `id` | `string` | Instance ID |
|
|
259
|
+
| `formId` | `string` | Parent form ID |
|
|
260
|
+
| `data` | `object` | Submitted data |
|
|
261
|
+
| `status` | `string` | draft, submitted, approved, rejected |
|
|
262
|
+
| `submittedAt` | `Date` | Submission timestamp |
|
|
263
|
+
|
|
264
|
+
## Error Handling
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { isBlockErrorException, ErrorCodes } from '@23blocks/contracts';
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await forms.formInstances.submit({
|
|
271
|
+
formId: 'form-id',
|
|
272
|
+
data: { name: '' }, // Invalid - name is required
|
|
273
|
+
});
|
|
274
|
+
} catch (error) {
|
|
275
|
+
if (isBlockErrorException(error)) {
|
|
276
|
+
switch (error.code) {
|
|
277
|
+
case ErrorCodes.VALIDATION_ERROR:
|
|
278
|
+
console.log('Form validation failed:', error.meta?.errors);
|
|
279
|
+
break;
|
|
280
|
+
case ErrorCodes.NOT_FOUND:
|
|
281
|
+
console.log('Form not found');
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Related Packages
|
|
289
|
+
|
|
290
|
+
- [`@23blocks/angular`](https://www.npmjs.com/package/@23blocks/angular) - Angular integration
|
|
291
|
+
- [`@23blocks/react`](https://www.npmjs.com/package/@23blocks/react) - React integration
|
|
292
|
+
- [`@23blocks/sdk`](https://www.npmjs.com/package/@23blocks/sdk) - Full SDK package
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT - Copyright (c) 2024 23blocks
|
package/dist/index.esm.js
CHANGED
|
@@ -971,7 +971,7 @@ function createPublicFormsService(transport, _config) {
|
|
|
971
971
|
return decodeOne(response, publicFormResponseMapper);
|
|
972
972
|
},
|
|
973
973
|
async draft (urlId, data) {
|
|
974
|
-
const response = await transport.
|
|
974
|
+
const response = await transport.put(`/${urlId}/forms/public`, {
|
|
975
975
|
form_draft: {
|
|
976
976
|
data: data.data,
|
|
977
977
|
payload: data.payload
|
package/package.json
CHANGED