@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.
- package/dist/core/missionLibrary.d.ts +4 -0
- package/dist/core/missionLibrary.js +22 -0
- package/dist/core/tasks.d.ts +20 -0
- package/dist/core/tasks.js +10 -0
- package/dist/react/hooks/index.d.ts +2 -2
- package/dist/react/hooks/index.js +4 -2
- package/dist/react/hooks/useMissionLibrary.d.ts +4 -0
- package/dist/react/hooks/useMissionLibrary.js +22 -0
- package/dist/react/hooks/useTasks.d.ts +1 -0
- package/dist/react/hooks/useTasks.js +55 -78
- package/package.json +1 -1
|
@@ -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.
|
package/dist/core/tasks.d.ts
CHANGED
|
@@ -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
|
package/dist/core/tasks.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
|
97
|
+
return false;
|
|
97
98
|
});
|
|
98
|
-
if (
|
|
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
|
|
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(
|
|
109
|
-
//
|
|
110
|
-
|
|
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 (
|
|
128
|
-
console.error("Failed to batch fetch activities",
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error("Failed to batch fetch activities", error);
|
|
129
117
|
}
|
|
130
118
|
});
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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)();
|