@markwharton/liquidplanner 2.0.0 → 2.0.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/README.md +68 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,29 +16,36 @@ import { LPClient, resolveTaskToAssignment } from '@markwharton/liquidplanner';
|
|
|
16
16
|
const client = new LPClient({ apiToken: 'xxx', workspaceId: 123 });
|
|
17
17
|
|
|
18
18
|
// Validate credentials
|
|
19
|
-
await client.validateToken();
|
|
19
|
+
const validation = await client.validateToken();
|
|
20
|
+
if (!validation.ok) throw new Error(validation.error);
|
|
20
21
|
|
|
21
22
|
// Get workspaces
|
|
22
|
-
const
|
|
23
|
+
const wsResult = await client.getWorkspaces();
|
|
24
|
+
if (wsResult.ok) console.log(wsResult.data); // LPWorkspace[]
|
|
23
25
|
|
|
24
26
|
// Get workspace members
|
|
25
|
-
const
|
|
27
|
+
const membersResult = await client.getWorkspaceMembers();
|
|
28
|
+
if (membersResult.ok) console.log(membersResult.data); // LPMember[]
|
|
26
29
|
|
|
27
30
|
// Get user's assignments (for task picker)
|
|
28
|
-
const
|
|
31
|
+
const assignResult = await client.getMyAssignments(memberId);
|
|
32
|
+
if (assignResult.ok) console.log(assignResult.data); // LPItem[]
|
|
29
33
|
|
|
30
34
|
// Get assignments with parent task/project names resolved
|
|
31
|
-
const
|
|
35
|
+
const ctxResult = await client.getMyAssignmentsWithContext(memberId, {
|
|
32
36
|
includeProject: true // optional: also fetch project names
|
|
33
37
|
});
|
|
38
|
+
if (ctxResult.ok) console.log(ctxResult.data); // LPAssignmentWithContext[]
|
|
34
39
|
|
|
35
40
|
// Get assignments with full hierarchy path
|
|
36
|
-
const
|
|
41
|
+
const hierResult = await client.getMyAssignmentsWithContext(memberId, {
|
|
37
42
|
includeHierarchy: true // includes ancestors and hierarchyPath
|
|
38
43
|
});
|
|
44
|
+
if (hierResult.ok) console.log(hierResult.data); // LPAssignmentWithContext[]
|
|
39
45
|
|
|
40
46
|
// Get item ancestors (hierarchy chain)
|
|
41
|
-
const
|
|
47
|
+
const ancResult = await client.getItemAncestors(itemId);
|
|
48
|
+
if (ancResult.ok) console.log(ancResult.data); // LPAncestor[]
|
|
42
49
|
|
|
43
50
|
// Resolve task to assignment
|
|
44
51
|
const resolution = await resolveTaskToAssignment(client, taskId, memberId);
|
|
@@ -52,31 +59,39 @@ await client.createTimesheetEntry({
|
|
|
52
59
|
});
|
|
53
60
|
|
|
54
61
|
// Query existing entries for a date
|
|
55
|
-
const
|
|
62
|
+
const tsResult = await client.getTimesheetEntries('2026-01-29', assignmentId);
|
|
63
|
+
if (tsResult.ok) console.log(tsResult.data); // LPTimesheetEntryWithId[]
|
|
56
64
|
|
|
57
65
|
// Update an existing entry (accumulate hours)
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
const existing = tsResult.data![0];
|
|
67
|
+
await client.updateTimesheetEntry(existing.id, existing, {
|
|
68
|
+
hours: existing.hours + 1.5,
|
|
60
69
|
note: 'Additional work'
|
|
61
70
|
});
|
|
62
71
|
|
|
63
72
|
// Find items with filters
|
|
64
|
-
const
|
|
73
|
+
const lateResult = await client.findItems({
|
|
65
74
|
itemType: 'tasks',
|
|
66
75
|
taskStatusGroupNot: 'done',
|
|
67
76
|
late: true,
|
|
68
77
|
});
|
|
78
|
+
if (lateResult.ok) console.log(lateResult.data); // LPItem[]
|
|
69
79
|
|
|
70
80
|
// Get children of an item
|
|
71
|
-
const
|
|
81
|
+
const childResult = await client.getChildren(parentId);
|
|
82
|
+
if (childResult.ok) console.log(childResult.data); // LPItem[]
|
|
72
83
|
|
|
73
84
|
// Get workspace tree snapshot (cached, all hierarchy lookups resolved in memory)
|
|
74
|
-
const
|
|
85
|
+
const treeResult = await client.getWorkspaceTree();
|
|
86
|
+
if (treeResult.ok) console.log(treeResult.data); // LPWorkspaceTree
|
|
75
87
|
|
|
76
88
|
// Get a member's work with full context from the tree
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
const workResult = await client.getMyWork(memberId);
|
|
90
|
+
if (workResult.ok) {
|
|
91
|
+
const { assignments, treeItemCount } = workResult.data;
|
|
92
|
+
// Each assignment includes taskName, projectId, projectName, hierarchyPath, ancestors
|
|
93
|
+
// treeItemCount shows total items loaded (only member's assignments returned downstream)
|
|
94
|
+
}
|
|
80
95
|
```
|
|
81
96
|
|
|
82
97
|
### Tree Utilities
|
|
@@ -97,29 +112,49 @@ const path = getTreeHierarchyPath(tree, itemId);
|
|
|
97
112
|
const lateTasks = findInTree(tree, item => item.late === true);
|
|
98
113
|
```
|
|
99
114
|
|
|
100
|
-
##
|
|
115
|
+
## Result Pattern
|
|
116
|
+
|
|
117
|
+
All methods return `Result<T>` objects rather than throwing exceptions. Always check `ok` before accessing `data`:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
interface Result<T> {
|
|
121
|
+
ok: boolean;
|
|
122
|
+
data?: T; // present when ok is true
|
|
123
|
+
error?: string; // present when ok is false
|
|
124
|
+
status?: number; // HTTP status code on error
|
|
125
|
+
}
|
|
126
|
+
```
|
|
101
127
|
|
|
102
|
-
|
|
128
|
+
```typescript
|
|
129
|
+
const result = await client.getMyWork(memberId);
|
|
130
|
+
if (!result.ok) {
|
|
131
|
+
console.error(result.error, result.status);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const { assignments, treeItemCount } = result.data;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API Reference
|
|
103
138
|
|
|
104
139
|
| Method | Parameters | Returns |
|
|
105
140
|
|--------|-----------|---------|
|
|
106
|
-
| `validateToken()` | — | `
|
|
107
|
-
| `getWorkspaces()` | — | `
|
|
108
|
-
| `getWorkspaceMembers()` | — | `
|
|
109
|
-
| `getItem(itemId)` | `number` | `
|
|
110
|
-
| `getItems(itemIds)` | `number[]` | `
|
|
111
|
-
| `getItemAncestors(itemId)` | `number` | `
|
|
112
|
-
| `findAssignments(taskId)` | `number` | `
|
|
113
|
-
| `getMyAssignments(memberId)` | `number` | `
|
|
114
|
-
| `getMyAssignmentsWithContext(memberId, options?)` | `number, { includeProject?, includeHierarchy? }` | `
|
|
115
|
-
| `findItems(options)` | `LPFindItemsOptions` | `
|
|
116
|
-
| `getChildren(parentId, options?)` | `number, { itemType? }?` | `
|
|
117
|
-
| `getWorkspaceTree()` | — | `
|
|
118
|
-
| `getMyWork(memberId)` | `number` | `{ assignments
|
|
141
|
+
| `validateToken()` | — | `Result<void>` |
|
|
142
|
+
| `getWorkspaces()` | — | `Result<LPWorkspace[]>` |
|
|
143
|
+
| `getWorkspaceMembers()` | — | `Result<LPMember[]>` |
|
|
144
|
+
| `getItem(itemId)` | `number` | `Result<LPItem>` |
|
|
145
|
+
| `getItems(itemIds)` | `number[]` | `Result<LPItem[]>` |
|
|
146
|
+
| `getItemAncestors(itemId)` | `number` | `Result<LPAncestor[]>` |
|
|
147
|
+
| `findAssignments(taskId)` | `number` | `Result<LPItem[]>` |
|
|
148
|
+
| `getMyAssignments(memberId)` | `number` | `Result<LPItem[]>` |
|
|
149
|
+
| `getMyAssignmentsWithContext(memberId, options?)` | `number, { includeProject?, includeHierarchy? }` | `Result<LPAssignmentWithContext[]>` |
|
|
150
|
+
| `findItems(options)` | `LPFindItemsOptions` | `Result<LPItem[]>` |
|
|
151
|
+
| `getChildren(parentId, options?)` | `number, { itemType? }?` | `Result<LPItem[]>` |
|
|
152
|
+
| `getWorkspaceTree()` | — | `Result<LPWorkspaceTree>` |
|
|
153
|
+
| `getMyWork(memberId)` | `number` | `Result<{ assignments: LPAssignmentWithContext[], treeItemCount: number }>` |
|
|
119
154
|
| `invalidateTreeCache()` | — | `void` |
|
|
120
|
-
| `getCostCodes()` | — | `
|
|
155
|
+
| `getCostCodes()` | — | `Result<LPCostCode[]>` |
|
|
121
156
|
| `createTimesheetEntry(entry)` | `LPTimesheetEntry` | `LPSyncResult` |
|
|
122
|
-
| `getTimesheetEntries(date, itemId?)` | `string \| string[], number?` | `
|
|
157
|
+
| `getTimesheetEntries(date, itemId?)` | `string \| string[], number?` | `Result<LPTimesheetEntryWithId[]>` |
|
|
123
158
|
| `updateTimesheetEntry(entryId, existing, updates)` | `number, LPTimesheetEntryWithId, Partial<LPTimesheetEntry>` | `LPSyncResult` |
|
|
124
159
|
| `upsertTimesheetEntry(entry, options?)` | `LPTimesheetEntry, LPUpsertOptions?` | `LPSyncResult` |
|
|
125
160
|
|