@crimson-education/sdk 0.3.4 → 0.3.5

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.
@@ -82,6 +82,10 @@ export declare class MissionLibraryApi {
82
82
  * List template tasks with pagination
83
83
  */
84
84
  listTemplateTasks(filters?: TemplateTaskFilters): Promise<PaginatedResult<TemplateTask>>;
85
+ /**
86
+ * List custom template tasks with pagination
87
+ */
88
+ listCustomTemplateTasks(filters?: TemplateTaskFilters): Promise<PaginatedResult<TemplateTask>>;
85
89
  /**
86
90
  * Update title/description/tasks of a template mission.
87
91
  * Should ensure the mission is a 'custom' mission before calling this.
@@ -132,6 +132,28 @@ class MissionLibraryApi {
132
132
  return this.client.fetch(path);
133
133
  });
134
134
  }
135
+ /**
136
+ * List custom template tasks with pagination
137
+ */
138
+ listCustomTemplateTasks(filters) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ const params = new URLSearchParams();
141
+ if (filters === null || filters === void 0 ? void 0 : filters.keyword) {
142
+ params.append("keyword", filters.keyword);
143
+ }
144
+ if ((filters === null || filters === void 0 ? void 0 : filters.start) !== undefined) {
145
+ params.append("start", String(filters.start));
146
+ }
147
+ if ((filters === null || filters === void 0 ? void 0 : filters.limit) !== undefined) {
148
+ params.append("limit", String(filters.limit));
149
+ }
150
+ const query = params.toString();
151
+ const path = query
152
+ ? `/roadmap/library/custom-tasks?${query}`
153
+ : "/roadmap/library/custom-tasks";
154
+ return this.client.fetch(path);
155
+ });
156
+ }
135
157
  /**
136
158
  * Update title/description/tasks of a template mission.
137
159
  * Should ensure the mission is a 'custom' mission before calling this.
@@ -1,5 +1,21 @@
1
1
  import type { CrimsonClient } from "./client";
2
2
  import type { Task, PaginationParams, PaginatedResult, ActionItemResource, AddResourceInput, UploadUrlResponse, DownloadUrlResponse, UpdateTaskResourceInput, User, ActionItemActivityBrief } from "./types";
3
+ export interface BulkCreateActionItemPayload {
4
+ missionId?: string;
5
+ roadmapId?: string;
6
+ description: string;
7
+ content?: string;
8
+ dueDate?: string;
9
+ startAt?: string;
10
+ linkId?: string;
11
+ resources?: {
12
+ title: string;
13
+ type: string;
14
+ url: string;
15
+ mediaType?: string;
16
+ orderIndex?: number;
17
+ }[];
18
+ }
3
19
  export type TaskOrderBy = "priority" | "dueDate" | "missionTitle" | "createdAt" | "description";
4
20
  export interface TaskFilters extends PaginationParams {
5
21
  status?: string[];
@@ -57,6 +73,10 @@ export declare class TasksApi {
57
73
  createStandalone(roadmapId: string, data: Omit<Partial<Task>, "roadmapMissionId" | "missionId">): Promise<Task>;
58
74
  update(id: string, data: Partial<Task>): Promise<Task>;
59
75
  delete(id: string): Promise<void>;
76
+ /**
77
+ * Bulk create action items
78
+ */
79
+ bulkCreate(items: BulkCreateActionItemPayload[]): Promise<any>;
60
80
  /**
61
81
  * Bulk delete tasks
62
82
  * @param ids - Array of task IDs to delete
@@ -40,6 +40,7 @@ const normalizeTask = (raw) => {
40
40
  isComplete,
41
41
  resources: raw.resources,
42
42
  mission: raw.mission,
43
+ linkId: raw.linkId,
43
44
  };
44
45
  };
45
46
  class TasksApi {
@@ -200,6 +201,15 @@ class TasksApi {
200
201
  method: "DELETE",
201
202
  });
202
203
  }
204
+ /**
205
+ * Bulk create action items
206
+ */
207
+ bulkCreate(items) {
208
+ return this.client.fetch('/roadmap/action-items/bulk-create', {
209
+ method: 'POST',
210
+ body: JSON.stringify({ items }),
211
+ }).then((res) => res === null || res === void 0 ? void 0 : res.map(normalizeTask));
212
+ }
203
213
  /**
204
214
  * Bulk delete tasks
205
215
  * @param ids - Array of task IDs to delete
@@ -3,11 +3,11 @@ export { useQueryClient } from "@tanstack/react-query";
3
3
  export { useOAuth, useOAuthCallback } from "./useOAuth";
4
4
  export type { UseOAuthResult } from "./useOAuth";
5
5
  export { useMissions, useMissionsInfinite, useCreateMission, useUpdateMission, useDeleteMission, missionKeys, } from "./useMissions";
6
- export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, useBulkDeleteTasks, useBulkUpdateTasks, taskKeys, useGetDownloadUrl, useTaskCreators, useTaskActivities, } from "./useTasks";
6
+ export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, useBulkDeleteTasks, useBulkUpdateTasks, taskKeys, useGetDownloadUrl, useTaskCreators, useTaskActivities, useBulkCreateActionItems, } from "./useTasks";
7
7
  export { useUsers, useUser, userKeys } from "./useUsers";
8
8
  export { useCurrentUserRoles, useMyStudents, accountKeys } from "./useAccount";
9
9
  export { useRoadmapContext } from "./useRoadmapContext";
10
- export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, useCreateTemplateMission, useDeleteTemplateMission, useTemplateMissionAddToRoadmap, useCustomTemplateMissionsInfinite, } from "./useMissionLibrary";
10
+ export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, useCreateTemplateMission, useDeleteTemplateMission, useTemplateMissionAddToRoadmap, useCustomTemplateMissionsInfinite, useCustomTemplateTasksInfinite, } from "./useMissionLibrary";
11
11
  export { useStudentProfile, useStudentPrefilledInfo, studentProfileKeys, } from "./useStudentProfile";
12
12
  export { useIndigoMe, useStudentTutors, useTutorStudents, indigoKeys, } from "./useIndigo";
13
13
  export * from "./useGradeTemplates";
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.useStudentTutors = exports.useIndigoMe = exports.studentProfileKeys = exports.useStudentPrefilledInfo = exports.useStudentProfile = exports.useCustomTemplateMissionsInfinite = exports.useTemplateMissionAddToRoadmap = exports.useDeleteTemplateMission = exports.useCreateTemplateMission = exports.missionLibraryKeys = exports.useCreateFromPredefinedTasks = exports.useAssignBulkTask = exports.useAssignBulkMission = exports.useCopyTemplateMission = exports.useUpdateTemplateMission = exports.useTemplateMissionDetail = exports.useTemplateTasksInfinite = exports.useTemplateTasks = exports.useTemplateMissionsInfinite = exports.useTemplateMissions = exports.useRoadmapContext = exports.accountKeys = exports.useMyStudents = exports.useCurrentUserRoles = exports.userKeys = exports.useUser = exports.useUsers = exports.useTaskActivities = exports.useTaskCreators = exports.useGetDownloadUrl = exports.taskKeys = exports.useBulkUpdateTasks = exports.useBulkDeleteTasks = exports.useDeleteTask = exports.useUpdateTask = exports.useCreateTask = exports.useTasksInfinite = exports.useTasksByRoadmapId = exports.useAllUserTasks = exports.useTasks = exports.missionKeys = exports.useDeleteMission = exports.useUpdateMission = exports.useCreateMission = exports.useMissionsInfinite = exports.useMissions = exports.useOAuthCallback = exports.useOAuth = exports.useQueryClient = exports.useAuthState = void 0;
18
- exports.indigoKeys = exports.useTutorStudents = void 0;
17
+ exports.studentProfileKeys = exports.useStudentPrefilledInfo = exports.useStudentProfile = exports.useCustomTemplateTasksInfinite = exports.useCustomTemplateMissionsInfinite = exports.useTemplateMissionAddToRoadmap = exports.useDeleteTemplateMission = exports.useCreateTemplateMission = exports.missionLibraryKeys = exports.useCreateFromPredefinedTasks = exports.useAssignBulkTask = exports.useAssignBulkMission = exports.useCopyTemplateMission = exports.useUpdateTemplateMission = exports.useTemplateMissionDetail = exports.useTemplateTasksInfinite = exports.useTemplateTasks = exports.useTemplateMissionsInfinite = exports.useTemplateMissions = exports.useRoadmapContext = exports.accountKeys = exports.useMyStudents = exports.useCurrentUserRoles = exports.userKeys = exports.useUser = exports.useUsers = exports.useBulkCreateActionItems = exports.useTaskActivities = exports.useTaskCreators = exports.useGetDownloadUrl = exports.taskKeys = exports.useBulkUpdateTasks = exports.useBulkDeleteTasks = exports.useDeleteTask = exports.useUpdateTask = exports.useCreateTask = exports.useTasksInfinite = exports.useTasksByRoadmapId = exports.useAllUserTasks = exports.useTasks = exports.missionKeys = exports.useDeleteMission = exports.useUpdateMission = exports.useCreateMission = exports.useMissionsInfinite = exports.useMissions = exports.useOAuthCallback = exports.useOAuth = exports.useQueryClient = exports.useAuthState = void 0;
18
+ exports.indigoKeys = exports.useTutorStudents = exports.useStudentTutors = exports.useIndigoMe = void 0;
19
19
  var useAuthState_1 = require("./useAuthState");
20
20
  Object.defineProperty(exports, "useAuthState", { enumerable: true, get: function () { return useAuthState_1.useAuthState; } });
21
21
  var react_query_1 = require("@tanstack/react-query");
@@ -44,6 +44,7 @@ Object.defineProperty(exports, "taskKeys", { enumerable: true, get: function ()
44
44
  Object.defineProperty(exports, "useGetDownloadUrl", { enumerable: true, get: function () { return useTasks_1.useGetDownloadUrl; } });
45
45
  Object.defineProperty(exports, "useTaskCreators", { enumerable: true, get: function () { return useTasks_1.useTaskCreators; } });
46
46
  Object.defineProperty(exports, "useTaskActivities", { enumerable: true, get: function () { return useTasks_1.useTaskActivities; } });
47
+ Object.defineProperty(exports, "useBulkCreateActionItems", { enumerable: true, get: function () { return useTasks_1.useBulkCreateActionItems; } });
47
48
  var useUsers_1 = require("./useUsers");
48
49
  Object.defineProperty(exports, "useUsers", { enumerable: true, get: function () { return useUsers_1.useUsers; } });
49
50
  Object.defineProperty(exports, "useUser", { enumerable: true, get: function () { return useUsers_1.useUser; } });
@@ -70,6 +71,7 @@ Object.defineProperty(exports, "useCreateTemplateMission", { enumerable: true, g
70
71
  Object.defineProperty(exports, "useDeleteTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useDeleteTemplateMission; } });
71
72
  Object.defineProperty(exports, "useTemplateMissionAddToRoadmap", { enumerable: true, get: function () { return useMissionLibrary_1.useTemplateMissionAddToRoadmap; } });
72
73
  Object.defineProperty(exports, "useCustomTemplateMissionsInfinite", { enumerable: true, get: function () { return useMissionLibrary_1.useCustomTemplateMissionsInfinite; } });
74
+ Object.defineProperty(exports, "useCustomTemplateTasksInfinite", { enumerable: true, get: function () { return useMissionLibrary_1.useCustomTemplateTasksInfinite; } });
73
75
  var useStudentProfile_1 = require("./useStudentProfile");
74
76
  Object.defineProperty(exports, "useStudentProfile", { enumerable: true, get: function () { return useStudentProfile_1.useStudentProfile; } });
75
77
  Object.defineProperty(exports, "useStudentPrefilledInfo", { enumerable: true, get: function () { return useStudentProfile_1.useStudentPrefilledInfo; } });
@@ -21,6 +21,10 @@ export declare function useTemplateTasksInfinite(filters?: Omit<TemplateTaskFilt
21
21
  enabled?: boolean;
22
22
  pageSize?: number;
23
23
  }): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<import("../../core/types").PaginatedResult<TemplateTask>, unknown>, Error>;
24
+ export declare function useCustomTemplateTasksInfinite(filters?: Omit<TemplateTaskFilters, "start" | "limit">, options?: {
25
+ enabled?: boolean;
26
+ pageSize?: number;
27
+ }): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<import("../../core/types").PaginatedResult<TemplateTask>, unknown>, Error>;
24
28
  export declare function useTemplateMissionDetail(missionId: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<MissionDetail | null, Error>;
25
29
  export declare function useUpdateTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission, Error, {
26
30
  id: string;
@@ -16,6 +16,7 @@ exports.useTemplateMissionsInfinite = useTemplateMissionsInfinite;
16
16
  exports.useCustomTemplateMissionsInfinite = useCustomTemplateMissionsInfinite;
17
17
  exports.useTemplateTasks = useTemplateTasks;
18
18
  exports.useTemplateTasksInfinite = useTemplateTasksInfinite;
19
+ exports.useCustomTemplateTasksInfinite = useCustomTemplateTasksInfinite;
19
20
  exports.useTemplateMissionDetail = useTemplateMissionDetail;
20
21
  exports.useUpdateTemplateMission = useUpdateTemplateMission;
21
22
  exports.useCreateTemplateMission = useCreateTemplateMission;
@@ -118,6 +119,27 @@ function useTemplateTasksInfinite(filters, options) {
118
119
  enabled,
119
120
  });
120
121
  }
122
+ function useCustomTemplateTasksInfinite(filters, options) {
123
+ var _a, _b;
124
+ const client = (0, provider_1.useCrimsonClient)();
125
+ const enabled = (_a = options === null || options === void 0 ? void 0 : options.enabled) !== null && _a !== void 0 ? _a : true;
126
+ const pageSize = (_b = options === null || options === void 0 ? void 0 : options.pageSize) !== null && _b !== void 0 ? _b : 20;
127
+ return (0, react_query_1.useInfiniteQuery)({
128
+ queryKey: [...exports.missionLibraryKeys.all, "custom-tasks", "infinite", filters],
129
+ queryFn: (_a) => __awaiter(this, [_a], void 0, function* ({ pageParam = 0 }) {
130
+ return client.library.listCustomTemplateTasks(Object.assign(Object.assign({}, filters), { start: pageParam, limit: pageSize }));
131
+ }),
132
+ initialPageParam: 0,
133
+ getNextPageParam: (lastPage) => {
134
+ if (!(lastPage === null || lastPage === void 0 ? void 0 : lastPage.pagination))
135
+ return undefined;
136
+ return lastPage.pagination.hasMore
137
+ ? lastPage.pagination.start + lastPage.pagination.limit
138
+ : undefined;
139
+ },
140
+ enabled,
141
+ });
142
+ }
121
143
  // --- Mission Detail ---
122
144
  function useTemplateMissionDetail(missionId, enabled = true) {
123
145
  const client = (0, provider_1.useCrimsonClient)();
@@ -30,6 +30,7 @@ export declare function useTasksInfinite(roadmapId: string | null, userId: strin
30
30
  export interface OptimisticOptions {
31
31
  optimistic?: boolean;
32
32
  }
33
+ export declare function useBulkCreateActionItems(): import("@tanstack/react-query").UseMutationResult<any, Error, any[], unknown>;
33
34
  export declare function useCreateTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Task, Error, Partial<Task>, {
34
35
  previousTasks: Task[] | undefined;
35
36
  } | undefined>;
@@ -17,6 +17,7 @@ exports.useTaskActivities = useTaskActivities;
17
17
  exports.useAllUserTasks = useAllUserTasks;
18
18
  exports.useTasksByRoadmapId = useTasksByRoadmapId;
19
19
  exports.useTasksInfinite = useTasksInfinite;
20
+ exports.useBulkCreateActionItems = useBulkCreateActionItems;
20
21
  exports.useCreateTask = useCreateTask;
21
22
  exports.useUpdateTask = useUpdateTask;
22
23
  exports.useDeleteTask = useDeleteTask;
@@ -68,98 +69,64 @@ function useTaskCreators(roadmapId, enabled = true) {
68
69
  function useTaskActivities(actionItemIds, type = "duedate", enabled = true) {
69
70
  const client = (0, provider_1.useCrimsonClient)();
70
71
  const queryClient = (0, react_query_1.useQueryClient)();
71
- // Track which IDs we know are in the cache (or have been fetched)
72
- const [cachedIds, setCachedIds] = (0, react_1.useState)(() => {
73
- const s = new Set();
74
- // We only check for existence, not staleness. Stale data will be refetched by useQueries if needed,
75
- // but we want to prevent the *initial* fetch of empty data which causes the waterfall/storm.
76
- // However, checking queryCache synchronously here is good for hydration.
77
- return s;
72
+ const STALE_TIME = 5 * 60 * 1000;
73
+ // 1. Use useQueries to READ from cache.
74
+ // We disable them so they never trigger individual fetches.
75
+ // They effectively act as observers of the cache.
76
+ const queries = (0, react_query_1.useQueries)({
77
+ queries: actionItemIds.map((id) => ({
78
+ queryKey: exports.taskKeys.activity(id, type),
79
+ // No queryFn needed because we never enable it to fetch
80
+ enabled: false,
81
+ })),
78
82
  });
79
- // Sync effect to update cachedIds from props?
80
- // actually, we should just check the cache on render or effect.
81
- // But doing it in effect allows the batch fetch to be the primary mechanism.
83
+ // 2. Manage fetching via side-effect
82
84
  (0, react_1.useEffect)(() => {
83
- if (!enabled)
85
+ if (!enabled || actionItemIds.length === 0)
84
86
  return;
85
- // Identify which IDs are missing from our "known cached" set
86
- // AND missing from the actual query cache (double check to be safe)
87
- const missing = actionItemIds.filter((id) => {
88
- if (cachedIds.has(id))
89
- return false;
90
- const data = queryClient.getQueryData(exports.taskKeys.activity(id, type));
91
- if (data) {
92
- // If it's already there (maybe from another component), we can mark it as cached
93
- // We'll update state later to avoid set-during-render warning if we did it synchronously above constantly
94
- return false;
87
+ const now = Date.now();
88
+ const idsToFetch = actionItemIds.filter((id) => {
89
+ const state = queryClient.getQueryState(exports.taskKeys.activity(id, type));
90
+ // If no data, need fetch
91
+ if (!state || !state.data)
92
+ return true;
93
+ // If data exists but is stale, need fetch
94
+ if (state.dataUpdatedAt && (now - state.dataUpdatedAt > STALE_TIME)) {
95
+ return true;
95
96
  }
96
- return true;
97
+ return false;
97
98
  });
98
- if (missing.length === 0) {
99
- // If we found some inconsistencies (e.g. they were in queryClient but not in our local state), align them
100
- if (actionItemIds.length !== cachedIds.size) {
101
- // This logic is tricky. Let's simplify:
102
- // Just fetch what we really need.
103
- }
99
+ if (idsToFetch.length === 0)
104
100
  return;
105
- }
106
- const fetchActivities = () => __awaiter(this, void 0, void 0, function* () {
101
+ // Deduplicate IDs just in case
102
+ const uniqueIdsToFetch = [...new Set(idsToFetch)];
103
+ // Perform batch fetch
104
+ const fetchBatch = () => __awaiter(this, void 0, void 0, function* () {
107
105
  try {
108
- const result = yield client.tasks.getActivities(missing, type);
109
- // Populate Cache
110
- Object.entries(result).forEach(([id, activities]) => {
106
+ const result = yield client.tasks.getActivities(uniqueIdsToFetch, type);
107
+ // Update cache for each ID
108
+ // Note: We update ALL requested IDs. If an ID is missing in result,
109
+ // it implies no activities, so we set empty array to prevent infinite refetching.
110
+ uniqueIdsToFetch.forEach(id => {
111
+ const activities = result[id] || [];
111
112
  queryClient.setQueryData(exports.taskKeys.activity(id, type), activities);
112
113
  });
113
- // Also handling IDs that returned no result (empty array) to prevent infinite re-fetching?
114
- // The API returns Record<string, ...>. If an ID is missing, we should probably set it to empty.
115
- missing.forEach(id => {
116
- if (!result[id]) {
117
- queryClient.setQueryData(exports.taskKeys.activity(id, type), []);
118
- }
119
- });
120
- // Update local state to enable the queries
121
- setCachedIds((prev) => {
122
- const next = new Set(prev);
123
- missing.forEach((id) => next.add(id));
124
- return next;
125
- });
126
114
  }
127
- catch (e) {
128
- console.error("Failed to batch fetch activities", e);
115
+ catch (error) {
116
+ console.error("Failed to batch fetch activities", error);
129
117
  }
130
118
  });
131
- fetchActivities();
132
- }, [actionItemIds, type, enabled, client, queryClient, cachedIds]); // cachedIds dep is important
133
- // Also, we need to make sure we "discover" items that are already cached
134
- // without fetching them. Use an effect to sync "initially present" items?
135
- (0, react_1.useEffect)(() => {
136
- if (!enabled)
137
- return;
138
- const present = actionItemIds.filter(id => !cachedIds.has(id) && queryClient.getQueryData(exports.taskKeys.activity(id, type)));
139
- if (present.length > 0) {
140
- setCachedIds(prev => {
141
- const next = new Set(prev);
142
- present.forEach(id => next.add(id));
143
- return next;
144
- });
145
- }
146
- }, [actionItemIds, type, enabled, queryClient, cachedIds]);
147
- const queries = (0, react_query_1.useQueries)({
148
- queries: actionItemIds.map((id) => ({
149
- queryKey: exports.taskKeys.activity(id, type),
150
- queryFn: () => __awaiter(this, void 0, void 0, function* () {
151
- const result = yield client.tasks.getActivities([id], type);
152
- return result[id] || [];
153
- }),
154
- // Only enable if we have "acknowledged" that the data is ready/cached.
155
- // OR if it was already in the cache (optimization).
156
- enabled: enabled && !!id && cachedIds.has(id),
157
- staleTime: 5 * 60 * 1000,
158
- })),
159
- });
160
- const isLoading = queries.some((q) => q.isLoading);
119
+ fetchBatch();
120
+ // We intentionally do not include queryClient deeply in deps if not needed,
121
+ // but here it's stable.
122
+ // We rely on actionItemIds changing (scroll) or enabled changing to trigger this.
123
+ // For periodic polling of staleness, one might need a timer, but for now
124
+ // check-on-mount/update is sufficient.
125
+ }, [actionItemIds, type, enabled, client, queryClient]); // STALE_TIME constant
126
+ const isLoading = queries.some((q) => !q.data && enabled); // If enabled and no data, we are effectively loading
161
127
  const data = {};
162
128
  queries.forEach((q, index) => {
129
+ // q.data comes from cache
163
130
  if (q.data) {
164
131
  data[actionItemIds[index]] = q.data;
165
132
  }
@@ -228,6 +195,16 @@ function useTasksInfinite(roadmapId, userId, filters, options) {
228
195
  enabled: !!roadmapId && !!userId && enabled,
229
196
  });
230
197
  }
198
+ function useBulkCreateActionItems() {
199
+ const client = (0, provider_1.useCrimsonClient)();
200
+ const queryClient = (0, react_query_1.useQueryClient)();
201
+ return (0, react_query_1.useMutation)({
202
+ mutationFn: (items) => client.tasks.bulkCreate(items),
203
+ onSuccess: () => {
204
+ queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
205
+ },
206
+ });
207
+ }
231
208
  function useCreateTask(options) {
232
209
  var _a;
233
210
  const client = (0, provider_1.useCrimsonClient)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crimson-education/sdk",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Crimson SDK for accessing Crimson App APIs",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",