@ram_28/kf-ai-sdk 2.0.19 → 2.0.20-beta.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/README.md +8 -16
- package/dist/{FileField-CZjS2uLh.js → FileField-BWrSHNRq.js} +3 -3
- package/dist/{FileField-DU4UWo_t.cjs → FileField-eDeuzln8.cjs} +1 -1
- package/dist/api.cjs +1 -1
- package/dist/api.mjs +1 -1
- package/dist/auth/authConfig.d.ts +1 -1
- package/dist/auth/types.d.ts +1 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth.cjs +1 -1
- package/dist/auth.mjs +1 -1
- package/dist/bdo/core/Item.d.ts +4 -0
- package/dist/bdo/core/Item.d.ts.map +1 -1
- package/dist/bdo/fields/ReferenceField.d.ts +1 -1
- package/dist/bdo/fields/ReferenceField.d.ts.map +1 -1
- package/dist/bdo/fields/SelectField.d.ts +1 -1
- package/dist/bdo/fields/SelectField.d.ts.map +1 -1
- package/dist/bdo/fields/UserField.d.ts +1 -1
- package/dist/bdo/fields/UserField.d.ts.map +1 -1
- package/dist/bdo.cjs +1 -1
- package/dist/bdo.mjs +62 -53
- package/dist/components/hooks/useActivityForm/types.d.ts +5 -4
- package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -1
- package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -1
- package/dist/components/hooks/useActivityTable/types.d.ts +4 -5
- package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
- package/dist/components/hooks/useBDOForm/createItemProxy.d.ts +3 -2
- package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -1
- package/dist/components/hooks/useBDOTable/types.d.ts +12 -20
- package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +2 -2
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
- package/dist/{constants-Cyi942Yr.js → constants-ConHc1oS.js} +5 -5
- package/dist/constants-QX2RX-wu.cjs +1 -0
- package/dist/filter.cjs +1 -1
- package/dist/filter.mjs +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.mjs +243 -226
- package/dist/table.cjs +1 -1
- package/dist/table.mjs +16 -15
- package/dist/table.types.d.ts +1 -1
- package/dist/table.types.d.ts.map +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/dist/workflow/Activity.d.ts +5 -8
- package/dist/workflow/Activity.d.ts.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.mjs +476 -461
- package/docs/api.md +95 -0
- package/docs/bdo.md +224 -0
- package/docs/gaps.md +360 -0
- package/docs/useActivityForm.md +393 -0
- package/docs/useActivityTable.md +418 -0
- package/docs/useBDOForm.md +498 -0
- package/docs/useBDOTable.md +284 -0
- package/docs/useFilter.md +188 -0
- package/docs/workflow.md +560 -0
- package/package.json +14 -15
- package/sdk/auth/authConfig.ts +1 -1
- package/sdk/auth/types.ts +1 -1
- package/sdk/bdo/core/Item.ts +10 -1
- package/sdk/bdo/fields/ReferenceField.ts +1 -1
- package/sdk/bdo/fields/SelectField.ts +1 -1
- package/sdk/bdo/fields/UserField.ts +1 -1
- package/sdk/components/hooks/useActivityForm/types.ts +6 -4
- package/sdk/components/hooks/useActivityForm/useActivityForm.ts +73 -10
- package/sdk/components/hooks/useActivityTable/types.ts +5 -4
- package/sdk/components/hooks/useActivityTable/useActivityTable.ts +8 -10
- package/sdk/components/hooks/useBDOForm/createItemProxy.ts +58 -17
- package/sdk/components/hooks/useBDOTable/types.ts +10 -20
- package/sdk/components/hooks/useBDOTable/useBDOTable.ts +8 -12
- package/sdk/table.types.ts +0 -2
- package/sdk/types/constants.ts +1 -1
- package/sdk/workflow/Activity.ts +7 -39
- package/dist/constants-DEmYwKfC.cjs +0 -1
- package/docs/README.md +0 -57
- package/docs/bdo/README.md +0 -161
- package/docs/bdo/api_reference.md +0 -281
- package/docs/examples/bdo/create-product.md +0 -69
- package/docs/examples/bdo/edit-product-dialog.md +0 -95
- package/docs/examples/bdo/filtered-product-table.md +0 -100
- package/docs/examples/bdo/product-listing.md +0 -73
- package/docs/examples/bdo/supplier-dropdown.md +0 -60
- package/docs/examples/fields/complex-fields.md +0 -248
- package/docs/examples/fields/primitive-fields.md +0 -217
- package/docs/examples/workflow/approve-leave-request.md +0 -76
- package/docs/examples/workflow/filtered-activity-table.md +0 -101
- package/docs/examples/workflow/my-pending-requests.md +0 -90
- package/docs/examples/workflow/start-new-workflow.md +0 -47
- package/docs/examples/workflow/submit-leave-request.md +0 -72
- package/docs/examples/workflow/workflow-progress.md +0 -49
- package/docs/fields/README.md +0 -141
- package/docs/fields/api_reference.md +0 -134
- package/docs/useActivityForm/README.md +0 -244
- package/docs/useActivityForm/api_reference.md +0 -279
- package/docs/useActivityTable/README.md +0 -263
- package/docs/useActivityTable/api_reference.md +0 -294
- package/docs/useBDOForm/README.md +0 -175
- package/docs/useBDOForm/api_reference.md +0 -244
- package/docs/useBDOTable/README.md +0 -242
- package/docs/useBDOTable/api_reference.md +0 -253
- package/docs/useFilter/README.md +0 -323
- package/docs/useFilter/api_reference.md +0 -228
- package/docs/workflow/README.md +0 -158
- package/docs/workflow/api_reference.md +0 -161
- /package/docs/{useAuth/README.md → useAuth.md} +0 -0
package/docs/fields/README.md
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# Fields
|
|
2
|
-
|
|
3
|
-
Field classes are the typed metadata layer for BDO properties. 13 classes extend `BaseField<T>`, each storing raw backend meta and exposing getters + `validate()`.
|
|
4
|
-
|
|
5
|
-
## Imports
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
import {
|
|
9
|
-
StringField,
|
|
10
|
-
NumberField,
|
|
11
|
-
BooleanField,
|
|
12
|
-
DateField,
|
|
13
|
-
DateTimeField,
|
|
14
|
-
TextField,
|
|
15
|
-
SelectField,
|
|
16
|
-
ReferenceField,
|
|
17
|
-
UserField,
|
|
18
|
-
FileField,
|
|
19
|
-
ImageField,
|
|
20
|
-
ArrayField,
|
|
21
|
-
ObjectField,
|
|
22
|
-
} from "@ram_28/kf-ai-sdk/bdo";
|
|
23
|
-
import type {
|
|
24
|
-
StringFieldType,
|
|
25
|
-
NumberFieldType,
|
|
26
|
-
BooleanFieldType,
|
|
27
|
-
DateFieldType,
|
|
28
|
-
DateTimeFieldType,
|
|
29
|
-
TextFieldType,
|
|
30
|
-
SelectFieldType,
|
|
31
|
-
ReferenceFieldType,
|
|
32
|
-
UserFieldType,
|
|
33
|
-
FileFieldType,
|
|
34
|
-
ImageFieldType,
|
|
35
|
-
FileType,
|
|
36
|
-
ArrayFieldType,
|
|
37
|
-
ObjectFieldType,
|
|
38
|
-
} from "@ram_28/kf-ai-sdk/types";
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Common Mistakes (READ FIRST)
|
|
42
|
-
|
|
43
|
-
1. **`item.Title` is not the value** — Use `item.Title.get()` to read, `.set()` to write.
|
|
44
|
-
2. **Don't confuse `StringField` (class) with `StringFieldType` (type alias)** — Different modules.
|
|
45
|
-
3. **`fetchOptions()` requires a parent BDO** — Standalone fields will throw.
|
|
46
|
-
4. **SelectField meta `Type` is `"String"`** — `Constraint.Enum` differentiates it.
|
|
47
|
-
5. **Always use pre-built components for File/Image** — `<FileUpload>`, `<ImageUpload>`, `<FilePreview>`, `<ImageThumbnail>`.
|
|
48
|
-
|
|
49
|
-
## Quick Start
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
// Declare on a BDO class
|
|
53
|
-
readonly Title = new StringField({
|
|
54
|
-
_id: "Title", Name: "Title", Type: "String",
|
|
55
|
-
Constraint: { Required: true, Length: 255 },
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Access metadata
|
|
59
|
-
bdo.Title.id; // "Title"
|
|
60
|
-
bdo.Title.label; // "Title"
|
|
61
|
-
bdo.Title.required; // true
|
|
62
|
-
bdo.Title.length; // 255
|
|
63
|
-
|
|
64
|
-
// Read/write via Item proxy
|
|
65
|
-
const item = await bdo.get("abc123");
|
|
66
|
-
item.Title.get(); // "My Product"
|
|
67
|
-
item.Title.set("New"); // update
|
|
68
|
-
|
|
69
|
-
// Form binding
|
|
70
|
-
<input {...register(bdo.Title.id)} />
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## BaseField Contract
|
|
74
|
-
|
|
75
|
-
All fields share these getters: `id`, `label`, `readOnly`, `required`, `defaultValue`, `primaryKey`, `meta`.
|
|
76
|
-
|
|
77
|
-
Abstract method: `validate(value: T | undefined): ValidationResultType` → `{ valid, errors }`.
|
|
78
|
-
|
|
79
|
-
## Quick Reference
|
|
80
|
-
|
|
81
|
-
| Class | Value Type | Extra Getters | Async |
|
|
82
|
-
| ---------------------- | ------------------ | ------------------------------------------------- | ---------------- |
|
|
83
|
-
| `StringField` | `string` | `length` | — |
|
|
84
|
-
| `NumberField` | `number` | `integerPart`, `fractionPart` | — |
|
|
85
|
-
| `BooleanField` | `boolean` | — | — |
|
|
86
|
-
| `DateField` | `YYYY-MM-DD` | — | — |
|
|
87
|
-
| `DateTimeField` | ISO string | `precision` | — |
|
|
88
|
-
| `TextField` | `string` | `format` | — |
|
|
89
|
-
| `SelectField<T>` | `T` | `options` | `fetchOptions()` |
|
|
90
|
-
| `ReferenceField<TRef>` | `TRef` | `referenceBdo`, `referenceFields`, `searchFields` | `fetchOptions()` |
|
|
91
|
-
| `UserField` | `{ _id, _name }` | `businessEntity` | `fetchOptions()` |
|
|
92
|
-
| `FileField` | `FileType[]` | — | — |
|
|
93
|
-
| `ImageField` | `FileType \| null` | — | — |
|
|
94
|
-
| `ArrayField<T>` | `T[]` | `elementType` | — |
|
|
95
|
-
| `ObjectField<T>` | `T` | `properties` | — |
|
|
96
|
-
|
|
97
|
-
## Form Binding Patterns
|
|
98
|
-
|
|
99
|
-
| Field Type | Pattern | Key Detail |
|
|
100
|
-
| ---------- | ----------------------------------------- | ------------------------------------------------------------------------------ |
|
|
101
|
-
| String | `register()` | `maxLength={field.length}` |
|
|
102
|
-
| Number | `register()` with `type="number"` | `step` from `fractionPart` (e.g. `2` → `"0.01"`, none → `"1"`) |
|
|
103
|
-
| Boolean | `watch()` + `setValue()` | Checkboxes don't fire native change — never use `register()` |
|
|
104
|
-
| Date | `register()` with `type="date"` | Strict `YYYY-MM-DD` — never default to `""` |
|
|
105
|
-
| DateTime | `register()` with `type="datetime-local"` | `step="0.001"` for `"Millisecond"` precision — never default to `""` |
|
|
106
|
-
| Text | `register()` with `<textarea>` | Check `field.format` (`"Plain"` \| `"Markdown"`) for conditional rendering |
|
|
107
|
-
| Select | `watch()` + `setValue()` | Static `field.options` from `Constraint.Enum`, or dynamic via `fetchOptions()` |
|
|
108
|
-
| Reference | `watch()` + `setValue()` | Stores **full object**, not just ID — use `<ReferenceSelect>` component |
|
|
109
|
-
| User | `watch()` + `setValue()` | `{ _id, _name }` shape — use `fetchOptions()` + dropdown |
|
|
110
|
-
| File | Component only | `<FileUpload>` (edit) / `<FilePreview>` (read-only) |
|
|
111
|
-
| Image | Component only | `<ImageUpload>` (edit) / `<ImageThumbnail>` (read-only) |
|
|
112
|
-
|
|
113
|
-
## fetchOptions() Pattern
|
|
114
|
-
|
|
115
|
-
SelectField, ReferenceField, and UserField share this pattern:
|
|
116
|
-
|
|
117
|
-
```tsx
|
|
118
|
-
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
119
|
-
const { data: options = [] } = useQuery({
|
|
120
|
-
queryKey: ["options", bdo.meta._id, field.id, item._id],
|
|
121
|
-
queryFn: () => field.fetchOptions(item._id!),
|
|
122
|
-
enabled: dropdownOpen && !!item._id,
|
|
123
|
-
staleTime: Infinity,
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## UI Components
|
|
128
|
-
|
|
129
|
-
| Component | Field | Mode | Key Props |
|
|
130
|
-
| ------------------- | --------- | --------- | ------------------------------------------------- |
|
|
131
|
-
| `<ReferenceSelect>` | Reference | Edit | `bdoField`, `instanceId`, `value`, `onChange` |
|
|
132
|
-
| `<FileUpload>` | File | Edit | `field`, `value`, `boId`, `instanceId`, `fieldId` |
|
|
133
|
-
| `<ImageUpload>` | Image | Edit | `field`, `value`, `boId`, `instanceId`, `fieldId` |
|
|
134
|
-
| `<FilePreview>` | File | Read-only | `boId`, `instanceId`, `fieldId`, `value` |
|
|
135
|
-
| `<ImageThumbnail>` | Image | Read-only | `boId`, `instanceId`, `fieldId`, `value` |
|
|
136
|
-
|
|
137
|
-
## Further Reading
|
|
138
|
-
|
|
139
|
-
- [API Reference](./api_reference.md) — Type signatures for BaseField and all 13 classes
|
|
140
|
-
- [Primitive Fields](../examples/fields/primitive-fields.md) · [Complex Fields](../examples/fields/complex-fields.md)
|
|
141
|
-
- [BDO](../bdo/README.md) · [useBDOForm](../useBDOForm/README.md)
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# Fields API Reference
|
|
2
|
-
|
|
3
|
-
```typescript
|
|
4
|
-
import { StringField, NumberField, BooleanField, DateField, DateTimeField,
|
|
5
|
-
TextField, SelectField, ReferenceField, UserField,
|
|
6
|
-
FileField, ImageField, ArrayField, ObjectField } from "@ram_28/kf-ai-sdk/bdo";
|
|
7
|
-
import type { BaseFieldMetaType, ValidationResultType, SelectOptionType,
|
|
8
|
-
EditableFieldAccessorType, ReadonlyFieldAccessorType } from "@ram_28/kf-ai-sdk/bdo/types";
|
|
9
|
-
import type { StringFieldType, NumberFieldType, BooleanFieldType,
|
|
10
|
-
DateFieldType, DateTimeFieldType, TextFieldType, SelectFieldType,
|
|
11
|
-
ReferenceFieldType, UserFieldType, FileFieldType, ImageFieldType, FileType,
|
|
12
|
-
ArrayFieldType, ObjectFieldType } from "@ram_28/kf-ai-sdk/types";
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## BaseField\<T\>
|
|
16
|
-
|
|
17
|
-
Abstract base class for all field definitions. Constructor: `new(meta: BaseFieldMetaType)`.
|
|
18
|
-
|
|
19
|
-
| Property | Type | Description |
|
|
20
|
-
|----------|------|-------------|
|
|
21
|
-
| `id` | `string` | `meta._id` |
|
|
22
|
-
| `label` | `string` | `meta.Name` (falls back to `id`) |
|
|
23
|
-
| `readOnly` | `boolean` | `meta.ReadOnly ?? false` |
|
|
24
|
-
| `required` | `boolean` | `meta.Constraint?.Required ?? meta.Required ?? false` |
|
|
25
|
-
| `defaultValue` | `unknown` | `meta.DefaultValue ?? meta.Constraint?.DefaultValue` |
|
|
26
|
-
| `primaryKey` | `boolean` | `meta.Constraint?.PrimaryKey ?? false` |
|
|
27
|
-
| `meta` | `BaseFieldMetaType` | Full raw backend meta |
|
|
28
|
-
| `validate()` | `(value: T \| undefined) => ValidationResultType` | Abstract — overridden per subclass |
|
|
29
|
-
|
|
30
|
-
## All Fields
|
|
31
|
-
|
|
32
|
-
| Class | Meta Type | Extra Properties | validate() |
|
|
33
|
-
|-------|-----------|-----------------|------------|
|
|
34
|
-
| `StringField` | `StringFieldMetaType` | `length: number \| undefined` | Rejects non-string |
|
|
35
|
-
| `NumberField` | `NumberFieldMetaType` | `integerPart: number` (default 9), `fractionPart: number \| undefined` | Rejects NaN, non-number |
|
|
36
|
-
| `BooleanField` | `BooleanFieldMetaType` | — | Rejects non-boolean |
|
|
37
|
-
| `DateField` | `DateFieldMetaType` | — | Rejects non-`YYYY-MM-DD`, invalid dates |
|
|
38
|
-
| `DateTimeField` | `DateTimeFieldMetaType` | `precision: "Second" \| "Millisecond"` | Rejects unparseable date strings |
|
|
39
|
-
| `TextField` | `TextFieldMetaType` | `format: "Plain" \| "Markdown"` | Rejects non-string |
|
|
40
|
-
| `SelectField<T>` | `SelectFieldMetaType` | `options: readonly SelectOptionType<T>[]` | Rejects values not in options (skipped if empty) |
|
|
41
|
-
| `ReferenceField<TRef>` | `ReferenceFieldMetaType` | `referenceBdo: string`, `referenceFields: readonly string[]`, `searchFields: readonly string[]` | Rejects non-object, missing `_id` |
|
|
42
|
-
| `UserField` | `UserFieldMetaType` | `businessEntity: string \| undefined` | Rejects non-object, missing `_id` |
|
|
43
|
-
| `FileField` | `FileFieldMetaType` | — | Rejects non-array, items without `_id` |
|
|
44
|
-
| `ImageField` | `ImageFieldMetaType` | — | Rejects non-object, missing `_id`/`FileName` |
|
|
45
|
-
| `ArrayField<T>` | `ArrayFieldMetaType` | `elementType: BaseFieldMetaType \| undefined` | Rejects non-array |
|
|
46
|
-
| `ObjectField<T>` | `ObjectFieldMetaType` | `properties: Record<string, unknown> \| undefined` | Rejects non-object, arrays |
|
|
47
|
-
|
|
48
|
-
All validate() methods accept `undefined` and `null`.
|
|
49
|
-
|
|
50
|
-
## Async Methods
|
|
51
|
-
|
|
52
|
-
| Class | Method | Signature |
|
|
53
|
-
|-------|--------|-----------|
|
|
54
|
-
| `SelectField<T>` | `fetchOptions` | `(instanceId?: string) => Promise<SelectOptionType<T>[]>` |
|
|
55
|
-
| `ReferenceField<TRef>` | `fetchOptions` | `(instanceId?: string) => Promise<TRef[]>` |
|
|
56
|
-
| `UserField` | `fetchOptions` | `(instanceId?: string) => Promise<UserFieldType[]>` |
|
|
57
|
-
|
|
58
|
-
`instanceId` defaults to `"draft"`. Requires field to be bound to a parent BDO.
|
|
59
|
-
|
|
60
|
-
## Types
|
|
61
|
-
|
|
62
|
-
### SelectOptionType\<T\>
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
interface SelectOptionType<T = string> {
|
|
66
|
-
value: T;
|
|
67
|
-
label: string;
|
|
68
|
-
disabled?: boolean;
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### FileType
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
interface FileType {
|
|
76
|
-
_id: string;
|
|
77
|
-
_name: string;
|
|
78
|
-
FileName: string;
|
|
79
|
-
FileExtension: string;
|
|
80
|
-
Size: number;
|
|
81
|
-
ContentType: string;
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### ValidationResultType
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
interface ValidationResultType {
|
|
89
|
-
valid: boolean;
|
|
90
|
-
errors: string[];
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Runtime Accessor Types
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
interface EditableFieldAccessorType<T> {
|
|
98
|
-
get(): T | undefined;
|
|
99
|
-
getOrDefault(fallback: T): T;
|
|
100
|
-
set(value: T): void;
|
|
101
|
-
validate(): ValidationResultType;
|
|
102
|
-
readonly label: string;
|
|
103
|
-
readonly required: boolean;
|
|
104
|
-
readonly readOnly: boolean;
|
|
105
|
-
readonly defaultValue: unknown;
|
|
106
|
-
readonly meta: BaseFieldMetaType;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// ReadonlyFieldAccessorType<T> — same but no set()
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Value Type Aliases
|
|
113
|
-
|
|
114
|
-
| Type | Resolves To |
|
|
115
|
-
|------|-------------|
|
|
116
|
-
| `StringFieldType` | `string` |
|
|
117
|
-
| `TextFieldType` | `string` |
|
|
118
|
-
| `NumberFieldType` | `number` |
|
|
119
|
-
| `BooleanFieldType` | `boolean` |
|
|
120
|
-
| `DateFieldType` | `YYYY-MM-DD` (template literal) |
|
|
121
|
-
| `DateTimeFieldType` | `YYYY-MM-DDThh:mm:ssZ` (template literal) |
|
|
122
|
-
| `SelectFieldType<T>` | `T` |
|
|
123
|
-
| `ReferenceFieldType<TRef>` | `TRef` |
|
|
124
|
-
| `UserFieldType` | `{ _id: string; _name: string }` |
|
|
125
|
-
| `ImageFieldType` | `FileType \| null` |
|
|
126
|
-
| `FileFieldType` | `FileType[]` |
|
|
127
|
-
| `ArrayFieldType<T>` | `T[]` |
|
|
128
|
-
| `ObjectFieldType<T>` | `T` |
|
|
129
|
-
|
|
130
|
-
### Supported File Extensions
|
|
131
|
-
|
|
132
|
-
**Image fields** — jpg, jpeg, png, gif, webp, bmp, tiff, tif, heic, heif
|
|
133
|
-
|
|
134
|
-
**File fields** — all image extensions plus: mp4, mov, avi, webm, mkv, m4v, wmv, flv, pdf, doc, docx, xls, xlsx, ppt, pptx, txt, csv, zip
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
# useActivityForm
|
|
2
|
-
|
|
3
|
-
Form hook for workflow activities with automatic per-field sync and a single `handleSubmit` to complete the activity and advance the workflow.
|
|
4
|
-
|
|
5
|
-
## When to Use
|
|
6
|
-
|
|
7
|
-
**Use `useActivityForm` when:**
|
|
8
|
-
|
|
9
|
-
- Building a form for a workflow activity (employee leave request, manager approval, etc.)
|
|
10
|
-
- You need `handleSubmit` to complete the activity and advance the workflow
|
|
11
|
-
- Fields from prior activities should appear as readonly context
|
|
12
|
-
|
|
13
|
-
**Use something else when:**
|
|
14
|
-
|
|
15
|
-
- Building a BDO record form — use [`useBDOForm`](../useBDOForm/README.md) instead
|
|
16
|
-
- Listing activity instances in a table — use [`useActivityTable`](../useActivityTable/README.md) instead
|
|
17
|
-
|
|
18
|
-
## Imports
|
|
19
|
-
|
|
20
|
-
```tsx
|
|
21
|
-
import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Quick Start
|
|
25
|
-
|
|
26
|
-
```tsx
|
|
27
|
-
import { useMemo } from "react";
|
|
28
|
-
import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
|
|
29
|
-
import { EmployeeInputActivity } from "@/workflow/leave";
|
|
30
|
-
|
|
31
|
-
function LeaveRequestForm({ instanceId }: { instanceId: string }) {
|
|
32
|
-
const activity = useMemo(() => new EmployeeInputActivity(), []);
|
|
33
|
-
|
|
34
|
-
const { register, handleSubmit, errors, isLoading, isSubmitting } =
|
|
35
|
-
useActivityForm(activity, { activity_instance_id: instanceId });
|
|
36
|
-
|
|
37
|
-
if (isLoading) return <p>Loading...</p>;
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<form>
|
|
41
|
-
<label>{activity.StartDate.label}</label>
|
|
42
|
-
<input type="date" {...register(activity.StartDate.id)} />
|
|
43
|
-
{errors.StartDate && <p>{errors.StartDate.message}</p>}
|
|
44
|
-
|
|
45
|
-
<label>{activity.EndDate.label}</label>
|
|
46
|
-
<input type="date" {...register(activity.EndDate.id)} />
|
|
47
|
-
{errors.EndDate && <p>{errors.EndDate.message}</p>}
|
|
48
|
-
|
|
49
|
-
<button type="button" disabled={isSubmitting}
|
|
50
|
-
onClick={handleSubmit(() => {}, console.error)}>
|
|
51
|
-
Submit Request
|
|
52
|
-
</button>
|
|
53
|
-
</form>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Usage Guide
|
|
59
|
-
|
|
60
|
-
### Registering Fields
|
|
61
|
-
|
|
62
|
-
Use the Activity instance's field to get the field ID, label, and metadata — never hardcode field names as strings.
|
|
63
|
-
|
|
64
|
-
```tsx
|
|
65
|
-
<label>{activity.StartDate.label} {activity.StartDate.required && <span>*</span>}</label>
|
|
66
|
-
<input type="date" {...register(activity.StartDate.id)} />
|
|
67
|
-
{errors.StartDate && <p>{errors.StartDate.message}</p>}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
For **select, reference, boolean, and other custom components** that don't fire native change events, use `watch()` + `setValue()` instead of `register()` (see [Fields — Selection & Reference](../fields/README.md#selection--reference-fields) for full patterns):
|
|
71
|
-
|
|
72
|
-
```tsx
|
|
73
|
-
<Select
|
|
74
|
-
value={watch(activity.LeaveType.id) ?? ""}
|
|
75
|
-
onValueChange={(v) => setValue(activity.LeaveType.id, v)}
|
|
76
|
-
>
|
|
77
|
-
<SelectTrigger>
|
|
78
|
-
<SelectValue placeholder="Select leave type" />
|
|
79
|
-
</SelectTrigger>
|
|
80
|
-
<SelectContent>
|
|
81
|
-
{activity.LeaveType.options.map((opt) => (
|
|
82
|
-
<SelectItem key={opt.value} value={opt.value}>
|
|
83
|
-
{opt.label}
|
|
84
|
-
</SelectItem>
|
|
85
|
-
))}
|
|
86
|
-
</SelectContent>
|
|
87
|
-
</Select>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Readonly fields are auto-disabled by `register()` — no manual disable needed.
|
|
91
|
-
|
|
92
|
-
### Context-Derived Readonly Fields
|
|
93
|
-
|
|
94
|
-
When a workflow has multiple activities, fields from prior activities appear as readonly context. The hook discovers them automatically from BP metadata, and `register()` returns `{ disabled: true }` for them.
|
|
95
|
-
|
|
96
|
-
In a manager approval form, the employee's StartDate, EndDate, LeaveType, and LeaveDays are readonly context, while ManagerApproved and ManagerReason are editable:
|
|
97
|
-
|
|
98
|
-
```tsx
|
|
99
|
-
import { useMemo } from "react";
|
|
100
|
-
import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
|
|
101
|
-
import { ManagerApprovalActivity } from "@/workflow/leave";
|
|
102
|
-
|
|
103
|
-
function ManagerApprovalForm({ instanceId }: { instanceId: string }) {
|
|
104
|
-
const activity = useMemo(() => new ManagerApprovalActivity(), []);
|
|
105
|
-
|
|
106
|
-
const { register, handleSubmit, errors, isLoading, isSubmitting, watch, setValue } =
|
|
107
|
-
useActivityForm(activity, { activity_instance_id: instanceId });
|
|
108
|
-
|
|
109
|
-
if (isLoading) return <p>Loading...</p>;
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<div>
|
|
113
|
-
{/* Readonly context from employee's activity — auto-disabled */}
|
|
114
|
-
<label>{activity.StartDate.label}</label>
|
|
115
|
-
<input type="date" {...register(activity.StartDate.id)} className="bg-gray-100" />
|
|
116
|
-
|
|
117
|
-
<label>{activity.EndDate.label}</label>
|
|
118
|
-
<input type="date" {...register(activity.EndDate.id)} className="bg-gray-100" />
|
|
119
|
-
|
|
120
|
-
<label>{activity.LeaveDays.label}</label>
|
|
121
|
-
<input type="number" {...register(activity.LeaveDays.id)} className="bg-gray-100" />
|
|
122
|
-
|
|
123
|
-
{/* Editable manager decision fields */}
|
|
124
|
-
<div>
|
|
125
|
-
<input
|
|
126
|
-
type="checkbox"
|
|
127
|
-
checked={watch(activity.ManagerApproved.id) ?? false}
|
|
128
|
-
onChange={(e) => setValue(activity.ManagerApproved.id, e.target.checked)}
|
|
129
|
-
/>
|
|
130
|
-
<label>
|
|
131
|
-
{activity.ManagerApproved.label}
|
|
132
|
-
{activity.ManagerApproved.required && <span> *</span>}
|
|
133
|
-
</label>
|
|
134
|
-
{errors.ManagerApproved && <p>{errors.ManagerApproved.message}</p>}
|
|
135
|
-
</div>
|
|
136
|
-
|
|
137
|
-
<label>{activity.ManagerReason.label}</label>
|
|
138
|
-
<textarea {...register(activity.ManagerReason.id)} rows={3} />
|
|
139
|
-
{errors.ManagerReason && <p>{errors.ManagerReason.message}</p>}
|
|
140
|
-
|
|
141
|
-
<button type="button" disabled={isSubmitting}
|
|
142
|
-
onClick={handleSubmit(() => {}, console.error)}>
|
|
143
|
-
Complete Review
|
|
144
|
-
</button>
|
|
145
|
-
</div>
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Validation
|
|
151
|
-
|
|
152
|
-
Validation happens automatically. The hook validates field types, constraints (required, length, integerPart/fractionPart), and backend expression rules — all without any manual configuration.
|
|
153
|
-
|
|
154
|
-
Errors appear in `errors.FieldName.message`:
|
|
155
|
-
|
|
156
|
-
```tsx
|
|
157
|
-
{errors.StartDate && <p>{errors.StartDate.message}</p>}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Handling Submit
|
|
161
|
-
|
|
162
|
-
Per-field sync automatically saves changes on blur/change via `activity.update()`, so there's no need for a manual save button. When the user is ready, `handleSubmit` validates the form, sends any remaining dirty fields, then completes the activity to advance the workflow.
|
|
163
|
-
|
|
164
|
-
`handleSubmit` is curried: `(onSuccess?, onError?) => (event?) => Promise<void>`.
|
|
165
|
-
|
|
166
|
-
- **`onSuccess(result)`** — Called with `CreateUpdateResponseType` (`{ _id: string }`) after the activity is completed.
|
|
167
|
-
- **`onError(error)`** — Called with `FieldErrors` (validation failure) or `Error` (API failure).
|
|
168
|
-
|
|
169
|
-
```tsx
|
|
170
|
-
<button type="button" disabled={isSubmitting}
|
|
171
|
-
onClick={handleSubmit(() => { toast.success("Submitted"); onClose(); }, console.error)}>
|
|
172
|
-
Submit Request
|
|
173
|
-
</button>
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
To validate before showing a confirmation dialog, use `trigger()`:
|
|
177
|
-
|
|
178
|
-
```tsx
|
|
179
|
-
const handleSubmitWithConfirm = async () => {
|
|
180
|
-
const valid = await trigger();
|
|
181
|
-
if (!valid) return;
|
|
182
|
-
// Show confirmation UI, then invoke:
|
|
183
|
-
handleSubmit(onSuccess, onError)(); // note the double invocation — curried
|
|
184
|
-
};
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
> **Don't** call `activity.update()` or `activity.complete()` manually — `handleSubmit` does it for you.
|
|
188
|
-
|
|
189
|
-
### Working with `item`
|
|
190
|
-
|
|
191
|
-
`item` represents the current activity instance. Each field on `item` is an accessor with methods to read, write, and validate that field's value.
|
|
192
|
-
|
|
193
|
-
**Instance-level members:**
|
|
194
|
-
|
|
195
|
-
```tsx
|
|
196
|
-
const { item } = useActivityForm(activity, { activity_instance_id: instanceId });
|
|
197
|
-
|
|
198
|
-
item._id; // current activity instance ID
|
|
199
|
-
item.toJSON(); // all form values as plain object
|
|
200
|
-
await item.validate(); // trigger validation for all fields
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
**Field-level accessors** (`item.FieldName`):
|
|
204
|
-
|
|
205
|
-
```tsx
|
|
206
|
-
// Read/write
|
|
207
|
-
item.StartDate.get(); // current value
|
|
208
|
-
item.LeaveDays.getOrDefault(0); // value or fallback
|
|
209
|
-
item.StartDate.set("2026-03-01"); // update value
|
|
210
|
-
|
|
211
|
-
// Validate
|
|
212
|
-
item.StartDate.validate(); // { valid: boolean, errors: string[] }
|
|
213
|
-
|
|
214
|
-
// Metadata
|
|
215
|
-
item.StartDate.label; // display label
|
|
216
|
-
item.StartDate.required; // is required?
|
|
217
|
-
item.StartDate.readOnly; // is readonly?
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
**When to use `item` vs `register`/`watch`/`setValue`:**
|
|
221
|
-
|
|
222
|
-
- Use `register()` for standard HTML inputs (text, number, date)
|
|
223
|
-
- Use `watch()` + `setValue()` for custom components (select, checkbox, reference)
|
|
224
|
-
- Use `item.Field.get()` / `item.Field.set()` for programmatic read/write (event handlers, computed logic)
|
|
225
|
-
|
|
226
|
-
## Further Reading
|
|
227
|
-
|
|
228
|
-
- [API Reference](./api_reference.md) — All options, return values, and type definitions
|
|
229
|
-
- [Fields](../fields/README.md) — All 13 field classes, constraint getters, and attachment methods
|
|
230
|
-
- [Submit Leave Request](../examples/workflow/submit-leave-request.md) — Employee form submission
|
|
231
|
-
- [Approve Leave Request](../examples/workflow/approve-leave-request.md) — Manager approval with readonly context
|
|
232
|
-
- [Start New Workflow](../examples/workflow/start-new-workflow.md) — `workflow.start()` flow
|
|
233
|
-
- [Primitive Fields](../examples/fields/primitive-fields.md) — Form with String, Number, Boolean, Date, DateTime, Text
|
|
234
|
-
- [Complex Fields](../examples/fields/complex-fields.md) — Form with Select, Reference, User, File, Image
|
|
235
|
-
|
|
236
|
-
## Common Mistakes
|
|
237
|
-
|
|
238
|
-
- **Don't forget `useMemo` on the Activity.** `new ActivityClass()` must be wrapped in `useMemo(() => ..., [])`. Re-creating the instance on every render breaks the hook.
|
|
239
|
-
- **Don't create a manual save button.** Per-field sync handles auto-saving on blur/change. `handleSubmit` is for completing the activity, not saving drafts.
|
|
240
|
-
- **Don't set date `defaultValues` to empty string.** Use `undefined` instead. Empty strings cause type validation errors for Date and DateTime fields.
|
|
241
|
-
- **Don't use `register()` for select, checkbox, or reference components.** They don't fire native change events. Use `watch()` + `setValue()`.
|
|
242
|
-
- **Don't call `activity.update()` or `activity.complete()` manually.** `handleSubmit` handles the API calls. Calling them yourself will double-submit.
|
|
243
|
-
- **Don't render the form before `isLoading` is false.** The activity data and metadata are being fetched. Guard with `if (isLoading) return <Loading />`.
|
|
244
|
-
- **Don't forget `activity_instance_id` is required.** This is the activity instance ID (from `workflow.start()` or `getInProgressList()`), not a BDO record ID.
|