@ram_28/kf-ai-sdk 1.0.22 → 1.0.24
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/dist/auth.cjs +1 -1
- package/dist/auth.mjs +15 -15
- package/dist/components/hooks/useForm/types.d.ts +3 -5
- package/dist/components/hooks/useForm/types.d.ts.map +1 -1
- package/dist/components/hooks/useForm/useForm.d.ts.map +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.mjs +193 -194
- package/docs/QUICK_REFERENCE.md +24 -0
- package/docs/api.md +648 -0
- package/docs/datetime.md +144 -0
- package/docs/useFilter.md +58 -18
- package/docs/useForm.md +447 -588
- package/docs/useTable.md +160 -26
- package/package.json +1 -1
- package/sdk/auth/authClient.ts +2 -2
- package/sdk/components/hooks/useForm/types.ts +4 -7
- package/sdk/components/hooks/useForm/useForm.ts +5 -4
package/docs/datetime.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Date & DateTime Handling
|
|
2
|
+
|
|
3
|
+
Working with Date and DateTime fields in the SDK.
|
|
4
|
+
|
|
5
|
+
## API Response Format
|
|
6
|
+
|
|
7
|
+
The backend returns dates in encoded format:
|
|
8
|
+
- **Date**: `{ "$__d__": "YYYY-MM-DD" }`
|
|
9
|
+
- **DateTime**: `{ "$__dt__": unix_timestamp_seconds }`
|
|
10
|
+
|
|
11
|
+
## Imports
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
// Decoding & formatting for API
|
|
15
|
+
import {
|
|
16
|
+
decodeDate,
|
|
17
|
+
decodeDateTime,
|
|
18
|
+
formatDate,
|
|
19
|
+
formatDateTime,
|
|
20
|
+
parseDate,
|
|
21
|
+
parseDateTime,
|
|
22
|
+
} from "@ram_28/kf-ai-sdk/api";
|
|
23
|
+
|
|
24
|
+
// UI display formatting
|
|
25
|
+
import {
|
|
26
|
+
formatDate,
|
|
27
|
+
formatDateTime
|
|
28
|
+
} from "@ram_28/kf-ai-sdk/utils";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Decoding API Responses
|
|
32
|
+
|
|
33
|
+
Convert encoded dates to JavaScript Date objects.
|
|
34
|
+
|
|
35
|
+
### decodeDate
|
|
36
|
+
```typescript
|
|
37
|
+
const apiResponse = { "$__d__": "2025-03-15" };
|
|
38
|
+
const date = decodeDate(apiResponse);
|
|
39
|
+
// => Date object for March 15, 2025
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### decodeDateTime
|
|
43
|
+
```typescript
|
|
44
|
+
const apiResponse = { "$__dt__": 1769110463 };
|
|
45
|
+
const date = decodeDateTime(apiResponse);
|
|
46
|
+
// => Date object with full timestamp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Formatting for API Requests
|
|
50
|
+
|
|
51
|
+
Convert Date objects to strings the API expects.
|
|
52
|
+
|
|
53
|
+
### formatDate (API)
|
|
54
|
+
```typescript
|
|
55
|
+
import { formatDate } from "@ram_28/kf-ai-sdk/api";
|
|
56
|
+
|
|
57
|
+
const date = new Date(2025, 2, 15);
|
|
58
|
+
formatDate(date); // => "2025-03-15"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### formatDateTime (API)
|
|
62
|
+
```typescript
|
|
63
|
+
import { formatDateTime } from "@ram_28/kf-ai-sdk/api";
|
|
64
|
+
|
|
65
|
+
const date = new Date(2025, 2, 15, 10, 30, 45);
|
|
66
|
+
formatDateTime(date); // => "2025-03-15 10:30:45"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Formatting for UI Display
|
|
70
|
+
|
|
71
|
+
Convert Date objects to human-readable strings.
|
|
72
|
+
|
|
73
|
+
### formatDate (UI)
|
|
74
|
+
```typescript
|
|
75
|
+
import { formatDate } from "@ram_28/kf-ai-sdk/utils";
|
|
76
|
+
|
|
77
|
+
const date = new Date(2025, 2, 15);
|
|
78
|
+
formatDate(date, 'short'); // => "3/15/25"
|
|
79
|
+
formatDate(date, 'medium'); // => "Mar 15, 2025"
|
|
80
|
+
formatDate(date, 'long'); // => "March 15, 2025"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### formatDateTime (UI)
|
|
84
|
+
```typescript
|
|
85
|
+
import { formatDateTime } from "@ram_28/kf-ai-sdk/utils";
|
|
86
|
+
|
|
87
|
+
const date = new Date(2025, 2, 15, 10, 30, 45);
|
|
88
|
+
formatDateTime(date, 'short'); // => "3/15/25, 10:30 AM"
|
|
89
|
+
formatDateTime(date, 'medium'); // => "Mar 15, 2025, 10:30:45 AM"
|
|
90
|
+
formatDateTime(date, 'long'); // => "March 15, 2025 at 10:30:45 AM"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Common Patterns
|
|
94
|
+
|
|
95
|
+
### Display a date from API response
|
|
96
|
+
```typescript
|
|
97
|
+
import { decodeDate } from "@ram_28/kf-ai-sdk/api";
|
|
98
|
+
import { formatDate } from "@ram_28/kf-ai-sdk/utils";
|
|
99
|
+
|
|
100
|
+
function displayDate(encodedDate: { $__d__: string }) {
|
|
101
|
+
const date = decodeDate(encodedDate);
|
|
102
|
+
return formatDate(date, 'medium');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Usage in component
|
|
106
|
+
<span>{displayDate(record.OrderDate)}</span>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Display created/modified timestamps
|
|
110
|
+
```typescript
|
|
111
|
+
import { decodeDateTime } from "@ram_28/kf-ai-sdk/api";
|
|
112
|
+
import { formatDateTime } from "@ram_28/kf-ai-sdk/utils";
|
|
113
|
+
|
|
114
|
+
function displayTimestamp(encodedDateTime: { $__dt__: number }) {
|
|
115
|
+
const date = decodeDateTime(encodedDateTime);
|
|
116
|
+
return formatDateTime(date, 'medium');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Usage
|
|
120
|
+
<span>Created: {displayTimestamp(record._created_at)}</span>
|
|
121
|
+
<span>Modified: {displayTimestamp(record._modified_at)}</span>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Submit a date to the API
|
|
125
|
+
```typescript
|
|
126
|
+
import { formatDate } from "@ram_28/kf-ai-sdk/api";
|
|
127
|
+
|
|
128
|
+
// From a date picker value
|
|
129
|
+
const datePickerValue = "2025-03-15"; // HTML date input value
|
|
130
|
+
// Already in correct format, use directly
|
|
131
|
+
|
|
132
|
+
// From a Date object
|
|
133
|
+
const dateObj = new Date();
|
|
134
|
+
const apiValue = formatDate(dateObj); // => "2025-03-15"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Type Definitions
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import type {
|
|
141
|
+
DateEncodedType, // { $__d__: string }
|
|
142
|
+
DateTimeEncodedType, // { $__dt__: number }
|
|
143
|
+
} from "@ram_28/kf-ai-sdk/api";
|
|
144
|
+
```
|
package/docs/useFilter.md
CHANGED
|
@@ -36,40 +36,87 @@ type ConditionGroupOperatorType = "And" | "Or" | "Not";
|
|
|
36
36
|
|
|
37
37
|
// Single condition (generic for type-safe LHSField)
|
|
38
38
|
interface ConditionType<T = any> {
|
|
39
|
+
// Auto-generated unique identifier
|
|
39
40
|
id?: string;
|
|
41
|
+
|
|
42
|
+
// Comparison operator (EQ, GT, Contains, etc.)
|
|
40
43
|
Operator: ConditionOperatorType;
|
|
41
|
-
|
|
44
|
+
|
|
45
|
+
// Field name to compare
|
|
46
|
+
LHSField: keyof T | string;
|
|
47
|
+
|
|
48
|
+
// Value to compare against
|
|
42
49
|
RHSValue: any;
|
|
50
|
+
|
|
51
|
+
// Value type (default: "Constant")
|
|
43
52
|
RHSType?: "Constant" | "BOField" | "AppVariable";
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
// Condition group (can contain conditions or nested groups)
|
|
47
56
|
interface ConditionGroupType<T = any> {
|
|
57
|
+
// Auto-generated unique identifier
|
|
48
58
|
id?: string;
|
|
59
|
+
|
|
60
|
+
// Group operator (And, Or, Not)
|
|
49
61
|
Operator: ConditionGroupOperatorType;
|
|
62
|
+
|
|
63
|
+
// Nested conditions or groups
|
|
50
64
|
Condition: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
// Hook options (also used for initialState in useTable/useKanban)
|
|
54
68
|
interface UseFilterOptionsType<T = any> {
|
|
69
|
+
// Initial conditions to populate the filter
|
|
55
70
|
conditions?: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
71
|
+
|
|
72
|
+
// Root operator for combining conditions (default: "And")
|
|
56
73
|
operator?: ConditionGroupOperatorType;
|
|
57
74
|
}
|
|
58
75
|
|
|
59
76
|
// Hook return type (generic for type-safe field names)
|
|
60
77
|
interface UseFilterReturnType<T = any> {
|
|
78
|
+
// ============================================================
|
|
79
|
+
// STATE
|
|
80
|
+
// ============================================================
|
|
81
|
+
|
|
82
|
+
// Current root operator (And, Or, Not)
|
|
61
83
|
operator: ConditionGroupOperatorType;
|
|
84
|
+
|
|
85
|
+
// All conditions and groups at root level
|
|
62
86
|
items: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
87
|
+
|
|
88
|
+
// API-ready filter payload (undefined if no conditions)
|
|
63
89
|
payload: FilterType<T> | undefined;
|
|
90
|
+
|
|
91
|
+
// True when at least one condition exists
|
|
64
92
|
hasConditions: boolean;
|
|
65
93
|
|
|
94
|
+
// ============================================================
|
|
95
|
+
// METHODS
|
|
96
|
+
// ============================================================
|
|
97
|
+
|
|
98
|
+
// Add a condition, optionally to a parent group. Returns the new condition's ID
|
|
66
99
|
addCondition: (condition: Omit<ConditionType<T>, "id">, parentId?: string) => string;
|
|
100
|
+
|
|
101
|
+
// Add a condition group, optionally to a parent group. Returns the new group's ID
|
|
67
102
|
addConditionGroup: (operator: ConditionGroupOperatorType, parentId?: string) => string;
|
|
103
|
+
|
|
104
|
+
// Update a condition's properties (Operator, LHSField, RHSValue)
|
|
68
105
|
updateCondition: (id: string, updates: Partial<Omit<ConditionType<T>, "id">>) => void;
|
|
106
|
+
|
|
107
|
+
// Change a group's operator (And, Or, Not)
|
|
69
108
|
updateGroupOperator: (id: string, operator: ConditionGroupOperatorType) => void;
|
|
109
|
+
|
|
110
|
+
// Remove a condition or group by ID
|
|
70
111
|
removeCondition: (id: string) => void;
|
|
112
|
+
|
|
113
|
+
// Get a condition or group by ID
|
|
71
114
|
getCondition: (id: string) => ConditionType<T> | ConditionGroupType<T> | undefined;
|
|
115
|
+
|
|
116
|
+
// Remove all conditions and groups
|
|
72
117
|
clearAllConditions: () => void;
|
|
118
|
+
|
|
119
|
+
// Change the root operator
|
|
73
120
|
setRootOperator: (operator: ConditionGroupOperatorType) => void;
|
|
74
121
|
}
|
|
75
122
|
```
|
|
@@ -126,18 +173,14 @@ Use the generic type parameter to get TypeScript validation on field names.
|
|
|
126
173
|
|
|
127
174
|
```tsx
|
|
128
175
|
import { useFilter } from "@ram_28/kf-ai-sdk/filter";
|
|
176
|
+
import { Product, type ProductForRole } from "../sources";
|
|
177
|
+
import { Roles } from "../sources/roles";
|
|
129
178
|
|
|
130
|
-
|
|
131
|
-
_id: string;
|
|
132
|
-
Title: string;
|
|
133
|
-
Price: number;
|
|
134
|
-
Category: string;
|
|
135
|
-
Stock: number;
|
|
136
|
-
}
|
|
179
|
+
type BuyerProduct = ProductForRole<typeof Roles.Buyer>;
|
|
137
180
|
|
|
138
181
|
function TypeSafeFilter() {
|
|
139
182
|
// Pass the type parameter for type-safe LHSField
|
|
140
|
-
const filter = useFilter<
|
|
183
|
+
const filter = useFilter<BuyerProduct>();
|
|
141
184
|
|
|
142
185
|
const addCategoryFilter = () => {
|
|
143
186
|
filter.addCondition({
|
|
@@ -150,7 +193,7 @@ function TypeSafeFilter() {
|
|
|
150
193
|
const addInvalidFilter = () => {
|
|
151
194
|
filter.addCondition({
|
|
152
195
|
Operator: "EQ",
|
|
153
|
-
LHSField: "InvalidField", // TypeScript error: not a key of
|
|
196
|
+
LHSField: "InvalidField", // TypeScript error: not a key of BuyerProduct
|
|
154
197
|
RHSValue: "test",
|
|
155
198
|
});
|
|
156
199
|
};
|
|
@@ -173,16 +216,13 @@ function TypeSafeFilter() {
|
|
|
173
216
|
```tsx
|
|
174
217
|
import { useFilter } from "@ram_28/kf-ai-sdk/filter";
|
|
175
218
|
import type { UseFilterOptionsType } from "@ram_28/kf-ai-sdk/filter/types";
|
|
219
|
+
import { Product, type ProductForRole } from "../sources";
|
|
220
|
+
import { Roles } from "../sources/roles";
|
|
176
221
|
|
|
177
|
-
|
|
178
|
-
_id: string;
|
|
179
|
-
Title: string;
|
|
180
|
-
Price: number;
|
|
181
|
-
Category: string;
|
|
182
|
-
}
|
|
222
|
+
type BuyerProduct = ProductForRole<typeof Roles.Buyer>;
|
|
183
223
|
|
|
184
224
|
// Type-safe filter options
|
|
185
|
-
const initialFilter: UseFilterOptionsType<
|
|
225
|
+
const initialFilter: UseFilterOptionsType<BuyerProduct> = {
|
|
186
226
|
conditions: [
|
|
187
227
|
{ Operator: "EQ", LHSField: "Category", RHSValue: "Electronics" },
|
|
188
228
|
{ Operator: "GT", LHSField: "Price", RHSValue: 100 },
|
|
@@ -191,7 +231,7 @@ const initialFilter: UseFilterOptionsType<Product> = {
|
|
|
191
231
|
};
|
|
192
232
|
|
|
193
233
|
// Use with useFilter
|
|
194
|
-
const filter = useFilter<
|
|
234
|
+
const filter = useFilter<BuyerProduct>(initialFilter);
|
|
195
235
|
```
|
|
196
236
|
|
|
197
237
|
---
|