@crimson-education/sdk 0.2.4 → 0.2.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.
@@ -61,6 +61,10 @@ export declare class MissionLibraryApi {
61
61
  * Create a new template mission
62
62
  */
63
63
  createTemplateMission(input: TemplateMissionCreateInput): Promise<TemplateMission>;
64
+ /**
65
+ * Delete a template mission
66
+ */
67
+ deleteTemplateMission(id: string): Promise<void>;
64
68
  /**
65
69
  * List template tasks with pagination
66
70
  */
@@ -60,6 +60,16 @@ class MissionLibraryApi {
60
60
  });
61
61
  });
62
62
  }
63
+ /**
64
+ * Delete a template mission
65
+ */
66
+ deleteTemplateMission(id) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ return this.client.fetch(`/roadmap/library/missions/${id}`, {
69
+ method: "DELETE",
70
+ });
71
+ });
72
+ }
63
73
  /**
64
74
  * List template tasks with pagination
65
75
  */
@@ -57,6 +57,24 @@ export declare class TasksApi {
57
57
  createStandalone(roadmapId: string, data: Omit<Partial<Task>, "roadmapMissionId" | "missionId">): Promise<Task>;
58
58
  update(id: string, data: Partial<Task>): Promise<Task>;
59
59
  delete(id: string): Promise<void>;
60
+ /**
61
+ * Bulk delete tasks
62
+ * @param ids - Array of task IDs to delete
63
+ */
64
+ bulkDelete(ids: string[]): Promise<{
65
+ deleted: string[];
66
+ }>;
67
+ /**
68
+ * Bulk update tasks
69
+ * @param ids - Array of task IDs to update
70
+ * @param data - Update data (dueDate, status)
71
+ */
72
+ bulkUpdate(ids: string[], data: {
73
+ dueDate?: string | null;
74
+ status?: string;
75
+ }): Promise<{
76
+ updated: any[];
77
+ }>;
60
78
  /**
61
79
  * Add resources to an action item
62
80
  * @param actionItemId - The ID of the action item
@@ -200,6 +200,27 @@ class TasksApi {
200
200
  method: "DELETE",
201
201
  });
202
202
  }
203
+ /**
204
+ * Bulk delete tasks
205
+ * @param ids - Array of task IDs to delete
206
+ */
207
+ bulkDelete(ids) {
208
+ return this.client.fetch("/roadmap/action-items/bulk-delete", {
209
+ method: "POST",
210
+ body: JSON.stringify({ ids }),
211
+ });
212
+ }
213
+ /**
214
+ * Bulk update tasks
215
+ * @param ids - Array of task IDs to update
216
+ * @param data - Update data (dueDate, status)
217
+ */
218
+ bulkUpdate(ids, data) {
219
+ return this.client.fetch("/roadmap/action-items/bulk-update", {
220
+ method: "POST",
221
+ body: JSON.stringify({ ids, data }),
222
+ });
223
+ }
203
224
  /**
204
225
  * Add resources to an action item
205
226
  * @param actionItemId - The ID of the action item
@@ -2,9 +2,9 @@ export { useAuthState } from "./useAuthState";
2
2
  export { useOAuth, useOAuthCallback } from "./useOAuth";
3
3
  export type { UseOAuthResult } from "./useOAuth";
4
4
  export { useMissions, useMissionsInfinite, useCreateMission, useUpdateMission, useDeleteMission, missionKeys, } from "./useMissions";
5
- export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, taskKeys, useGetDownloadUrl, useTaskCreators } from "./useTasks";
5
+ export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, useBulkDeleteTasks, useBulkUpdateTasks, taskKeys, useGetDownloadUrl, useTaskCreators } from "./useTasks";
6
6
  export { useUsers, useUser, userKeys } from "./useUsers";
7
7
  export { useCurrentUserRoles, useMyStudents, accountKeys } from "./useAccount";
8
8
  export { useRoadmapContext } from "./useRoadmapContext";
9
- export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, } from "./useMissionLibrary";
9
+ export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, useCreateTemplateMission, useDeleteTemplateMission, } from "./useMissionLibrary";
10
10
  export { useStudentProfile, useStudentPrefilledInfo, studentProfileKeys, } from "./useStudentProfile";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.studentProfileKeys = exports.useStudentPrefilledInfo = exports.useStudentProfile = 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.useTaskCreators = exports.useGetDownloadUrl = exports.taskKeys = 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.useAuthState = void 0;
3
+ exports.studentProfileKeys = exports.useStudentPrefilledInfo = exports.useStudentProfile = 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.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.useAuthState = void 0;
4
4
  var useAuthState_1 = require("./useAuthState");
5
5
  Object.defineProperty(exports, "useAuthState", { enumerable: true, get: function () { return useAuthState_1.useAuthState; } });
6
6
  var useOAuth_1 = require("./useOAuth");
@@ -21,6 +21,8 @@ Object.defineProperty(exports, "useTasksInfinite", { enumerable: true, get: func
21
21
  Object.defineProperty(exports, "useCreateTask", { enumerable: true, get: function () { return useTasks_1.useCreateTask; } });
22
22
  Object.defineProperty(exports, "useUpdateTask", { enumerable: true, get: function () { return useTasks_1.useUpdateTask; } });
23
23
  Object.defineProperty(exports, "useDeleteTask", { enumerable: true, get: function () { return useTasks_1.useDeleteTask; } });
24
+ Object.defineProperty(exports, "useBulkDeleteTasks", { enumerable: true, get: function () { return useTasks_1.useBulkDeleteTasks; } });
25
+ Object.defineProperty(exports, "useBulkUpdateTasks", { enumerable: true, get: function () { return useTasks_1.useBulkUpdateTasks; } });
24
26
  Object.defineProperty(exports, "taskKeys", { enumerable: true, get: function () { return useTasks_1.taskKeys; } });
25
27
  Object.defineProperty(exports, "useGetDownloadUrl", { enumerable: true, get: function () { return useTasks_1.useGetDownloadUrl; } });
26
28
  Object.defineProperty(exports, "useTaskCreators", { enumerable: true, get: function () { return useTasks_1.useTaskCreators; } });
@@ -46,6 +48,8 @@ Object.defineProperty(exports, "useAssignBulkMission", { enumerable: true, get:
46
48
  Object.defineProperty(exports, "useAssignBulkTask", { enumerable: true, get: function () { return useMissionLibrary_1.useAssignBulkTask; } });
47
49
  Object.defineProperty(exports, "useCreateFromPredefinedTasks", { enumerable: true, get: function () { return useMissionLibrary_1.useCreateFromPredefinedTasks; } });
48
50
  Object.defineProperty(exports, "missionLibraryKeys", { enumerable: true, get: function () { return useMissionLibrary_1.missionLibraryKeys; } });
51
+ Object.defineProperty(exports, "useCreateTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useCreateTemplateMission; } });
52
+ Object.defineProperty(exports, "useDeleteTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useDeleteTemplateMission; } });
49
53
  var useStudentProfile_1 = require("./useStudentProfile");
50
54
  Object.defineProperty(exports, "useStudentProfile", { enumerable: true, get: function () { return useStudentProfile_1.useStudentProfile; } });
51
55
  Object.defineProperty(exports, "useStudentPrefilledInfo", { enumerable: true, get: function () { return useStudentProfile_1.useStudentPrefilledInfo; } });
@@ -25,6 +25,7 @@ export declare function useUpdateTemplateMission(): import("@tanstack/react-quer
25
25
  update: TemplateMissionUpdateInput;
26
26
  }, unknown>;
27
27
  export declare function useCreateTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission, Error, TemplateMissionCreateInput, unknown>;
28
+ export declare function useDeleteTemplateMission(): import("@tanstack/react-query").UseMutationResult<void, Error, string, unknown>;
28
29
  export declare function useCopyTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission[], Error, CopyTemplateMissionInput, unknown>;
29
30
  export declare function useAssignBulkMission(): import("@tanstack/react-query").UseMutationResult<{
30
31
  code: number;
@@ -18,6 +18,7 @@ exports.useTemplateTasksInfinite = useTemplateTasksInfinite;
18
18
  exports.useTemplateMissionDetail = useTemplateMissionDetail;
19
19
  exports.useUpdateTemplateMission = useUpdateTemplateMission;
20
20
  exports.useCreateTemplateMission = useCreateTemplateMission;
21
+ exports.useDeleteTemplateMission = useDeleteTemplateMission;
21
22
  exports.useCopyTemplateMission = useCopyTemplateMission;
22
23
  exports.useAssignBulkMission = useAssignBulkMission;
23
24
  exports.useAssignBulkTask = useAssignBulkTask;
@@ -136,6 +137,21 @@ function useCreateTemplateMission() {
136
137
  },
137
138
  });
138
139
  }
140
+ function useDeleteTemplateMission() {
141
+ const client = (0, provider_1.useCrimsonClient)();
142
+ const queryClient = (0, react_query_1.useQueryClient)();
143
+ return (0, react_query_1.useMutation)({
144
+ mutationFn: (id) => client.library.deleteTemplateMission(id),
145
+ onSuccess: () => {
146
+ queryClient.invalidateQueries({
147
+ queryKey: exports.missionLibraryKeys.missionsInfinite(),
148
+ });
149
+ queryClient.invalidateQueries({
150
+ queryKey: exports.missionLibraryKeys.missions(),
151
+ });
152
+ },
153
+ });
154
+ }
139
155
  function useCopyTemplateMission() {
140
156
  const client = (0, provider_1.useCrimsonClient)();
141
157
  const queryClient = (0, react_query_1.useQueryClient)();
@@ -1,3 +1,4 @@
1
+ import { InfiniteData } from "@tanstack/react-query";
1
2
  import type { Mission, PaginatedResult } from "../../core/types";
2
3
  import type { MissionFilters } from "../../core/missions";
3
4
  export declare const missionKeys: {
@@ -15,10 +16,19 @@ export declare function useMissions(userId: string | null, enabled: boolean): im
15
16
  export declare function useMissionsInfinite(userId: string | null, filters?: Omit<MissionFilters, "start" | "limit">, options?: {
16
17
  enabled?: boolean;
17
18
  pageSize?: number;
18
- }): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<PaginatedResult<Mission>, unknown>, Error>;
19
- export declare function useCreateMission(): import("@tanstack/react-query").UseMutationResult<Mission, Error, Partial<Mission>, unknown>;
20
- export declare function useUpdateMission(): import("@tanstack/react-query").UseMutationResult<Mission, Error, {
19
+ }): import("@tanstack/react-query").UseInfiniteQueryResult<InfiniteData<PaginatedResult<Mission>, unknown>, Error>;
20
+ export interface OptimisticOptions {
21
+ optimistic?: boolean;
22
+ }
23
+ export declare function useCreateMission(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Mission, Error, Partial<Mission>, {
24
+ previousMissions: Mission[] | undefined;
25
+ } | undefined>;
26
+ export declare function useUpdateMission(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Mission, Error, {
21
27
  id: string;
22
28
  data: Partial<Mission>;
23
- }, unknown>;
24
- export declare function useDeleteMission(): import("@tanstack/react-query").UseMutationResult<void, Error, string, unknown>;
29
+ }, {
30
+ previousMissionsMap: Map<string, unknown>;
31
+ } | undefined>;
32
+ export declare function useDeleteMission(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<void, Error, string, {
33
+ previousMissionsMap: Map<string, unknown>;
34
+ } | undefined>;
@@ -72,32 +72,127 @@ function useMissionsInfinite(userId, filters, options) {
72
72
  enabled: !!userId && enabled,
73
73
  });
74
74
  }
75
- function useCreateMission() {
75
+ function useCreateMission(options) {
76
+ var _a;
76
77
  const client = (0, provider_1.useCrimsonClient)();
77
78
  const queryClient = (0, react_query_1.useQueryClient)();
79
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
78
80
  return (0, react_query_1.useMutation)({
79
81
  mutationFn: (data) => client.missions.create(data),
80
- onSuccess: () => {
82
+ onMutate: (newMission) => __awaiter(this, void 0, void 0, function* () {
83
+ if (!optimistic || !newMission.userId)
84
+ return;
85
+ const queryKey = exports.missionKeys.list(newMission.userId);
86
+ yield queryClient.cancelQueries({ queryKey });
87
+ const previousMissions = queryClient.getQueryData(queryKey);
88
+ if (previousMissions) {
89
+ const optimisticMission = Object.assign({ id: `temp-${Date.now()}`, title: "New Mission", status: "PLANNED", category: "General", roadmapId: "" }, newMission);
90
+ queryClient.setQueryData(queryKey, (old) => {
91
+ return old ? [...old, optimisticMission] : [optimisticMission];
92
+ });
93
+ }
94
+ return { previousMissions };
95
+ }),
96
+ onError: (err, newMission, context) => {
97
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousMissions) || !newMission.userId)
98
+ return;
99
+ queryClient.setQueryData(exports.missionKeys.list(newMission.userId), context.previousMissions);
100
+ },
101
+ onSettled: () => {
81
102
  queryClient.invalidateQueries({ queryKey: exports.missionKeys.all });
82
103
  },
83
104
  });
84
105
  }
85
- function useUpdateMission() {
106
+ function useUpdateMission(options) {
107
+ var _a;
86
108
  const client = (0, provider_1.useCrimsonClient)();
87
109
  const queryClient = (0, react_query_1.useQueryClient)();
110
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
88
111
  return (0, react_query_1.useMutation)({
89
112
  mutationFn: ({ id, data }) => client.missions.update(id, data),
90
- onSuccess: () => {
113
+ onMutate: (_a) => __awaiter(this, [_a], void 0, function* ({ id, data }) {
114
+ if (!optimistic)
115
+ return;
116
+ yield queryClient.cancelQueries({ queryKey: exports.missionKeys.all });
117
+ const previousMissionsMap = new Map();
118
+ queryClient
119
+ .getQueriesData({ queryKey: exports.missionKeys.all })
120
+ .forEach(([key, old]) => {
121
+ previousMissionsMap.set(JSON.stringify(key), old);
122
+ if (!old)
123
+ return;
124
+ // Handle Infinite Query Support
125
+ if (typeof old === "object" &&
126
+ "pages" in old &&
127
+ Array.isArray(old.pages)) {
128
+ queryClient.setQueryData(key, (oldData) => {
129
+ if (!oldData)
130
+ return oldData;
131
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.map((mission) => mission.id === id ? Object.assign(Object.assign({}, mission), data) : mission) }))) });
132
+ });
133
+ }
134
+ // Handle Standard List Support
135
+ else if (Array.isArray(old)) {
136
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.map((mission) => mission.id === id ? Object.assign(Object.assign({}, mission), data) : mission));
137
+ }
138
+ });
139
+ return { previousMissionsMap };
140
+ }),
141
+ onError: (err, { id }, context) => {
142
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousMissionsMap))
143
+ return;
144
+ context.previousMissionsMap.forEach((old, keyStr) => {
145
+ queryClient.setQueryData(JSON.parse(keyStr), old);
146
+ });
147
+ },
148
+ onSettled: () => {
91
149
  queryClient.invalidateQueries({ queryKey: exports.missionKeys.all });
92
150
  },
93
151
  });
94
152
  }
95
- function useDeleteMission() {
153
+ function useDeleteMission(options) {
154
+ var _a;
96
155
  const client = (0, provider_1.useCrimsonClient)();
97
156
  const queryClient = (0, react_query_1.useQueryClient)();
157
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
98
158
  return (0, react_query_1.useMutation)({
99
159
  mutationFn: (id) => client.missions.delete(id),
100
- onSuccess: () => {
160
+ onMutate: (id) => __awaiter(this, void 0, void 0, function* () {
161
+ if (!optimistic)
162
+ return;
163
+ yield queryClient.cancelQueries({ queryKey: exports.missionKeys.all });
164
+ const previousMissionsMap = new Map();
165
+ queryClient
166
+ .getQueriesData({ queryKey: exports.missionKeys.all })
167
+ .forEach(([key, old]) => {
168
+ previousMissionsMap.set(JSON.stringify(key), old);
169
+ if (!old)
170
+ return;
171
+ // Handle Infinite Query Support
172
+ if (typeof old === "object" &&
173
+ "pages" in old &&
174
+ Array.isArray(old.pages)) {
175
+ queryClient.setQueryData(key, (oldData) => {
176
+ if (!oldData)
177
+ return oldData;
178
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.filter((mission) => mission.id !== id) }))) });
179
+ });
180
+ }
181
+ // Handle Standard List Support
182
+ else if (Array.isArray(old)) {
183
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.filter((mission) => mission.id !== id));
184
+ }
185
+ });
186
+ return { previousMissionsMap };
187
+ }),
188
+ onError: (err, id, context) => {
189
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousMissionsMap))
190
+ return;
191
+ context.previousMissionsMap.forEach((old, keyStr) => {
192
+ queryClient.setQueryData(JSON.parse(keyStr), old);
193
+ });
194
+ },
195
+ onSettled: () => {
101
196
  queryClient.invalidateQueries({ queryKey: exports.missionKeys.all });
102
197
  },
103
198
  });
@@ -1,3 +1,4 @@
1
+ import { InfiniteData } from "@tanstack/react-query";
1
2
  import type { Task, PaginatedResult, User } from "../../core/types";
2
3
  import type { TaskFilters } from "../../core/tasks";
3
4
  export declare const taskKeys: {
@@ -19,11 +20,36 @@ export declare function useTasksByRoadmapId(roadmapId: string | null, userId: st
19
20
  export declare function useTasksInfinite(roadmapId: string | null, userId: string | null, filters?: Omit<TaskFilters, "start" | "limit">, options?: {
20
21
  enabled?: boolean;
21
22
  pageSize?: number;
22
- }): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<PaginatedResult<Task>, unknown>, Error>;
23
- export declare function useCreateTask(): import("@tanstack/react-query").UseMutationResult<Task, Error, Partial<Task>, unknown>;
24
- export declare function useUpdateTask(): import("@tanstack/react-query").UseMutationResult<Task, Error, {
23
+ }): import("@tanstack/react-query").UseInfiniteQueryResult<InfiniteData<PaginatedResult<Task>, unknown>, Error>;
24
+ export interface OptimisticOptions {
25
+ optimistic?: boolean;
26
+ }
27
+ export declare function useCreateTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Task, Error, Partial<Task>, {
28
+ previousTasks: Task[] | undefined;
29
+ } | undefined>;
30
+ export declare function useUpdateTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<Task, Error, {
25
31
  id: string;
26
32
  data: Partial<Task>;
27
- }, unknown>;
28
- export declare function useDeleteTask(): import("@tanstack/react-query").UseMutationResult<void, Error, string, unknown>;
33
+ }, {
34
+ previousTasksMap: Map<string, unknown>;
35
+ } | undefined>;
36
+ export declare function useDeleteTask(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<void, Error, string, {
37
+ previousTasksMap: Map<string, unknown>;
38
+ } | undefined>;
39
+ export declare function useBulkDeleteTasks(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<{
40
+ deleted: string[];
41
+ }, Error, string[], {
42
+ previousTasksMap: Map<string, unknown>;
43
+ } | undefined>;
44
+ export declare function useBulkUpdateTasks(options?: OptimisticOptions): import("@tanstack/react-query").UseMutationResult<{
45
+ updated: any[];
46
+ }, Error, {
47
+ ids: string[];
48
+ data: {
49
+ dueDate?: string | null;
50
+ status?: string;
51
+ };
52
+ }, {
53
+ previousTasksMap: Map<string, unknown>;
54
+ } | undefined>;
29
55
  export declare function useGetDownloadUrl(): import("@tanstack/react-query").UseMutationResult<import("../../core/types").DownloadUrlResponse, Error, string, unknown>;
@@ -19,6 +19,8 @@ exports.useTasksInfinite = useTasksInfinite;
19
19
  exports.useCreateTask = useCreateTask;
20
20
  exports.useUpdateTask = useUpdateTask;
21
21
  exports.useDeleteTask = useDeleteTask;
22
+ exports.useBulkDeleteTasks = useBulkDeleteTasks;
23
+ exports.useBulkUpdateTasks = useBulkUpdateTasks;
22
24
  exports.useGetDownloadUrl = useGetDownloadUrl;
23
25
  const react_query_1 = require("@tanstack/react-query");
24
26
  const provider_1 = require("../provider");
@@ -121,32 +123,222 @@ function useTasksInfinite(roadmapId, userId, filters, options) {
121
123
  enabled: !!roadmapId && !!userId && enabled,
122
124
  });
123
125
  }
124
- function useCreateTask() {
126
+ function useCreateTask(options) {
127
+ var _a;
125
128
  const client = (0, provider_1.useCrimsonClient)();
126
129
  const queryClient = (0, react_query_1.useQueryClient)();
130
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
127
131
  return (0, react_query_1.useMutation)({
128
132
  mutationFn: (data) => client.tasks.create(data),
129
- onSuccess: () => {
133
+ onMutate: (newTask) => __awaiter(this, void 0, void 0, function* () {
134
+ if (!optimistic || !newTask.missionId)
135
+ return;
136
+ const queryKey = exports.taskKeys.list(newTask.missionId);
137
+ yield queryClient.cancelQueries({ queryKey });
138
+ const previousTasks = queryClient.getQueryData(queryKey);
139
+ if (previousTasks) {
140
+ const optimisticTask = Object.assign({ id: `temp-${Date.now()}`, name: "New Task", status: "PLANNED", date: new Date().toISOString(), roadmapMissionId: "", userId: "" }, newTask);
141
+ queryClient.setQueryData(queryKey, (old) => {
142
+ return old ? [...old, optimisticTask] : [optimisticTask];
143
+ });
144
+ }
145
+ return { previousTasks };
146
+ }),
147
+ onError: (err, newTodo, context) => {
148
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasks) || !newTodo.missionId)
149
+ return;
150
+ queryClient.setQueryData(exports.taskKeys.list(newTodo.missionId), context.previousTasks);
151
+ },
152
+ onSettled: () => {
130
153
  queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
131
154
  },
132
155
  });
133
156
  }
134
- function useUpdateTask() {
157
+ function useUpdateTask(options) {
158
+ var _a;
135
159
  const client = (0, provider_1.useCrimsonClient)();
136
160
  const queryClient = (0, react_query_1.useQueryClient)();
161
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
137
162
  return (0, react_query_1.useMutation)({
138
163
  mutationFn: ({ id, data }) => client.tasks.update(id, data),
139
- onSuccess: () => {
164
+ onMutate: (_a) => __awaiter(this, [_a], void 0, function* ({ id, data }) {
165
+ if (!optimistic)
166
+ return;
167
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
168
+ const previousTasksMap = new Map();
169
+ // Update basic list and infinite queries
170
+ queryClient
171
+ .getQueriesData({ queryKey: exports.taskKeys.all })
172
+ .forEach(([key, old]) => {
173
+ previousTasksMap.set(JSON.stringify(key), old);
174
+ if (!old)
175
+ return;
176
+ // Handle Infinite Query Support
177
+ if (typeof old === "object" &&
178
+ "pages" in old &&
179
+ Array.isArray(old.pages)) {
180
+ queryClient.setQueryData(key, (oldData) => {
181
+ if (!oldData)
182
+ return oldData;
183
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.map((task) => task.id === id ? Object.assign(Object.assign({}, task), data) : task) }))) });
184
+ });
185
+ }
186
+ // Handle Standard List Support
187
+ else if (Array.isArray(old)) {
188
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.map((task) => task.id === id ? Object.assign(Object.assign({}, task), data) : task));
189
+ }
190
+ });
191
+ return { previousTasksMap };
192
+ }),
193
+ onError: (err, { id }, context) => {
194
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
195
+ return;
196
+ context.previousTasksMap.forEach((old, keyStr) => {
197
+ queryClient.setQueryData(JSON.parse(keyStr), old);
198
+ });
199
+ },
200
+ onSettled: () => {
140
201
  queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
141
202
  },
142
203
  });
143
204
  }
144
- function useDeleteTask() {
205
+ function useDeleteTask(options) {
206
+ var _a;
145
207
  const client = (0, provider_1.useCrimsonClient)();
146
208
  const queryClient = (0, react_query_1.useQueryClient)();
209
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
147
210
  return (0, react_query_1.useMutation)({
148
211
  mutationFn: (id) => client.tasks.delete(id),
149
- onSuccess: () => {
212
+ onMutate: (id) => __awaiter(this, void 0, void 0, function* () {
213
+ if (!optimistic)
214
+ return;
215
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
216
+ const previousTasksMap = new Map();
217
+ queryClient
218
+ .getQueriesData({ queryKey: exports.taskKeys.all })
219
+ .forEach(([key, old]) => {
220
+ previousTasksMap.set(JSON.stringify(key), old);
221
+ if (!old)
222
+ return;
223
+ // Handle Infinite Query Support
224
+ if (typeof old === "object" &&
225
+ "pages" in old &&
226
+ Array.isArray(old.pages)) {
227
+ queryClient.setQueryData(key, (oldData) => {
228
+ if (!oldData)
229
+ return oldData;
230
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.filter((task) => task.id !== id) }))) });
231
+ });
232
+ }
233
+ // Handle Standard List Support
234
+ else if (Array.isArray(old)) {
235
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.filter((task) => task.id !== id));
236
+ }
237
+ });
238
+ return { previousTasksMap };
239
+ }),
240
+ onError: (err, id, context) => {
241
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
242
+ return;
243
+ context.previousTasksMap.forEach((old, keyStr) => {
244
+ queryClient.setQueryData(JSON.parse(keyStr), old);
245
+ });
246
+ },
247
+ onSettled: () => {
248
+ queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
249
+ },
250
+ });
251
+ }
252
+ function useBulkDeleteTasks(options) {
253
+ var _a;
254
+ const client = (0, provider_1.useCrimsonClient)();
255
+ const queryClient = (0, react_query_1.useQueryClient)();
256
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
257
+ return (0, react_query_1.useMutation)({
258
+ mutationFn: (ids) => client.tasks.bulkDelete(ids),
259
+ onMutate: (ids) => __awaiter(this, void 0, void 0, function* () {
260
+ if (!optimistic)
261
+ return;
262
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
263
+ const previousTasksMap = new Map();
264
+ queryClient
265
+ .getQueriesData({ queryKey: exports.taskKeys.all })
266
+ .forEach(([key, old]) => {
267
+ previousTasksMap.set(JSON.stringify(key), old);
268
+ if (!old)
269
+ return;
270
+ // Handle Infinite Query Support
271
+ if (typeof old === "object" &&
272
+ "pages" in old &&
273
+ Array.isArray(old.pages)) {
274
+ queryClient.setQueryData(key, (oldData) => {
275
+ if (!oldData)
276
+ return oldData;
277
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.filter((task) => !ids.includes(task.id)) }))) });
278
+ });
279
+ }
280
+ // Handle Standard List Support
281
+ else if (Array.isArray(old)) {
282
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.filter((task) => !ids.includes(task.id)));
283
+ }
284
+ });
285
+ return { previousTasksMap };
286
+ }),
287
+ onError: (err, ids, context) => {
288
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
289
+ return;
290
+ context.previousTasksMap.forEach((old, keyStr) => {
291
+ queryClient.setQueryData(JSON.parse(keyStr), old);
292
+ });
293
+ },
294
+ onSettled: () => {
295
+ queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
296
+ },
297
+ });
298
+ }
299
+ function useBulkUpdateTasks(options) {
300
+ var _a;
301
+ const client = (0, provider_1.useCrimsonClient)();
302
+ const queryClient = (0, react_query_1.useQueryClient)();
303
+ const optimistic = (_a = options === null || options === void 0 ? void 0 : options.optimistic) !== null && _a !== void 0 ? _a : true;
304
+ return (0, react_query_1.useMutation)({
305
+ mutationFn: ({ ids, data, }) => client.tasks.bulkUpdate(ids, data),
306
+ onMutate: (_a) => __awaiter(this, [_a], void 0, function* ({ ids, data }) {
307
+ if (!optimistic)
308
+ return;
309
+ yield queryClient.cancelQueries({ queryKey: exports.taskKeys.all });
310
+ const previousTasksMap = new Map();
311
+ queryClient
312
+ .getQueriesData({ queryKey: exports.taskKeys.all })
313
+ .forEach(([key, old]) => {
314
+ previousTasksMap.set(JSON.stringify(key), old);
315
+ if (!old)
316
+ return;
317
+ // Handle Infinite Query Support
318
+ if (typeof old === "object" &&
319
+ "pages" in old &&
320
+ Array.isArray(old.pages)) {
321
+ queryClient.setQueryData(key, (oldData) => {
322
+ if (!oldData)
323
+ return oldData;
324
+ return Object.assign(Object.assign({}, oldData), { pages: oldData.pages.map((page) => (Object.assign(Object.assign({}, page), { data: page.data.map((task) => ids.includes(task.id) ? Object.assign(Object.assign({}, task), data) : task) }))) });
325
+ });
326
+ }
327
+ // Handle Standard List Support
328
+ else if (Array.isArray(old)) {
329
+ queryClient.setQueryData(key, (oldData) => oldData === null || oldData === void 0 ? void 0 : oldData.map((task) => ids.includes(task.id) ? Object.assign(Object.assign({}, task), data) : task));
330
+ }
331
+ });
332
+ return { previousTasksMap };
333
+ }),
334
+ onError: (err, variables, context) => {
335
+ if (!optimistic || !(context === null || context === void 0 ? void 0 : context.previousTasksMap))
336
+ return;
337
+ context.previousTasksMap.forEach((old, keyStr) => {
338
+ queryClient.setQueryData(JSON.parse(keyStr), old);
339
+ });
340
+ },
341
+ onSettled: () => {
150
342
  queryClient.invalidateQueries({ queryKey: exports.taskKeys.all });
151
343
  },
152
344
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crimson-education/sdk",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Crimson SDK for accessing Crimson App APIs",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",