@crimson-education/sdk 0.2.0 → 0.2.2
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 +8 -8
- package/dist/core/account.d.ts +12 -1
- package/dist/core/account.js +16 -0
- package/dist/core/missionLibrary.d.ts +20 -0
- package/dist/core/missionLibrary.js +26 -0
- package/dist/core/types.d.ts +17 -0
- package/dist/iframe/auth-state.d.ts +20 -0
- package/dist/iframe/auth-state.js +71 -0
- package/dist/iframe/index.d.ts +1 -1
- package/dist/iframe/index.js +6 -1
- package/dist/index.js +1 -1
- package/dist/react/hooks/index.d.ts +2 -2
- package/dist/react/hooks/index.js +3 -1
- package/dist/react/hooks/useAccount.d.ts +14 -1
- package/dist/react/hooks/useAccount.js +24 -0
- package/dist/react/hooks/useMissionLibrary.d.ts +6 -1
- package/dist/react/hooks/useMissionLibrary.js +18 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# @crimson/sdk 使用文档
|
|
1
|
+
# @crimson-education/sdk 使用文档
|
|
2
2
|
|
|
3
|
-
`@crimson/sdk` 是一个用于访问 Crimson App(Roadmap 相关)后端接口的 TypeScript SDK,包含三层能力:
|
|
3
|
+
`@crimson-education/sdk` 是一个用于访问 Crimson App(Roadmap 相关)后端接口的 TypeScript SDK,包含三层能力:
|
|
4
4
|
|
|
5
5
|
- **Core(框架无关)**:`CrimsonClient` + 各业务 API(missions / tasks / roadmap / users / mission library)
|
|
6
6
|
- **iframe(跨域/嵌入场景)**:通过 `postMessage` 初始化鉴权信息,并提供可订阅的鉴权状态
|
|
7
|
-
- **React(可选)**:基于 `@tanstack/react-query` 的 Provider 与 Hooks(通过 `@crimson/sdk/react` 引入)
|
|
7
|
+
- **React(可选)**:基于 `@tanstack/react-query` 的 Provider 与 Hooks(通过 `@crimson-education/sdk/react` 引入)
|
|
8
8
|
|
|
9
9
|
> 说明:SDK 默认依赖运行时 `fetch`。在 Node.js 环境建议使用 Node 18+(内置 `fetch`),或自行注入/polyfill。
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
如果已发布到 npm:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npm i @crimson/sdk
|
|
20
|
+
npm i @crimson-education/sdk
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### 本地开发构建
|
|
@@ -36,7 +36,7 @@ npm run build
|
|
|
36
36
|
## 快速开始(Core)
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
|
-
import { createCrimsonClient } from "@crimson/sdk";
|
|
39
|
+
import { createCrimsonClient } from "@crimson-education/sdk";
|
|
40
40
|
|
|
41
41
|
const client = createCrimsonClient({
|
|
42
42
|
apiUrl: "https://api.example.com",
|
|
@@ -225,7 +225,7 @@ SDK 会将后端返回的 action item 做归一化,保证至少返回以下核
|
|
|
225
225
|
|
|
226
226
|
## iframe 层(嵌入/跨域场景)
|
|
227
227
|
|
|
228
|
-
入口:`@crimson/sdk`(主入口会导出 iframe 层)
|
|
228
|
+
入口:`@crimson-education/sdk`(主入口会导出 iframe 层)
|
|
229
229
|
|
|
230
230
|
典型用法:
|
|
231
231
|
|
|
@@ -268,7 +268,7 @@ window.frames[0]?.postMessage(
|
|
|
268
268
|
|
|
269
269
|
---
|
|
270
270
|
|
|
271
|
-
## React 层(`@crimson/sdk/react`)
|
|
271
|
+
## React 层(`@crimson-education/sdk/react`)
|
|
272
272
|
|
|
273
273
|
React 层通过 `peerDependencies` 声明依赖(不会强制安装):
|
|
274
274
|
|
|
@@ -278,7 +278,7 @@ React 层通过 `peerDependencies` 声明依赖(不会强制安装):
|
|
|
278
278
|
### CrimsonProvider
|
|
279
279
|
|
|
280
280
|
```tsx
|
|
281
|
-
import { CrimsonProvider } from "@crimson/sdk/react";
|
|
281
|
+
import { CrimsonProvider } from "@crimson-education/sdk/react";
|
|
282
282
|
|
|
283
283
|
export function App() {
|
|
284
284
|
return (
|
package/dist/core/account.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CrimsonClient } from "./client";
|
|
2
|
-
import type { CurrentUserRoles } from "./types";
|
|
2
|
+
import type { CurrentUserRoles, StudentSummary } from "./types";
|
|
3
3
|
export declare class AccountApi {
|
|
4
4
|
private client;
|
|
5
5
|
constructor(client: CrimsonClient);
|
|
@@ -11,4 +11,15 @@ export declare class AccountApi {
|
|
|
11
11
|
* - roles: Array of role objects with roleId and isPrimary flag
|
|
12
12
|
*/
|
|
13
13
|
getCurrentUserRoles(): Promise<CurrentUserRoles>;
|
|
14
|
+
/**
|
|
15
|
+
* Get the list of students associated with the current logged-in user.
|
|
16
|
+
*
|
|
17
|
+
* This is primarily used for staff users (Strategists, SSMs, etc.) to get
|
|
18
|
+
* their list of students for the student selection page after OAuth login.
|
|
19
|
+
*
|
|
20
|
+
* For student users, this will return an empty array.
|
|
21
|
+
*
|
|
22
|
+
* @returns Array of student summaries with basic info for display
|
|
23
|
+
*/
|
|
24
|
+
getMyStudents(): Promise<StudentSummary[]>;
|
|
14
25
|
}
|
package/dist/core/account.js
CHANGED
|
@@ -26,5 +26,21 @@ class AccountApi {
|
|
|
26
26
|
return this.client.fetch("/api/v1/account/me/roles");
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the list of students associated with the current logged-in user.
|
|
31
|
+
*
|
|
32
|
+
* This is primarily used for staff users (Strategists, SSMs, etc.) to get
|
|
33
|
+
* their list of students for the student selection page after OAuth login.
|
|
34
|
+
*
|
|
35
|
+
* For student users, this will return an empty array.
|
|
36
|
+
*
|
|
37
|
+
* @returns Array of student summaries with basic info for display
|
|
38
|
+
*/
|
|
39
|
+
getMyStudents() {
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
const response = yield this.client.fetch("/api/v1/account/me/students");
|
|
42
|
+
return response.data;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
29
45
|
}
|
|
30
46
|
exports.AccountApi = AccountApi;
|
|
@@ -15,6 +15,17 @@ export interface TemplateTaskFilters extends PaginationParams {
|
|
|
15
15
|
keywordType?: string;
|
|
16
16
|
userId?: string;
|
|
17
17
|
}
|
|
18
|
+
export interface TemplateTaskUpdateInput {
|
|
19
|
+
id?: string;
|
|
20
|
+
title?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
operation: string;
|
|
23
|
+
}
|
|
24
|
+
export interface TemplateMissionUpdateInput {
|
|
25
|
+
title?: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
tasks?: TemplateTaskUpdateInput[];
|
|
28
|
+
}
|
|
18
29
|
export interface CopyTemplateMissionInput {
|
|
19
30
|
linkId: string;
|
|
20
31
|
userId: string;
|
|
@@ -39,6 +50,15 @@ export declare class MissionLibraryApi {
|
|
|
39
50
|
* List template tasks with pagination
|
|
40
51
|
*/
|
|
41
52
|
listTemplateTasks(filters?: TemplateTaskFilters): Promise<PaginatedResult<TemplateTask>>;
|
|
53
|
+
/**
|
|
54
|
+
* Update title/description/tasks of a template mission.
|
|
55
|
+
* Should ensure the mission is a 'custom' mission before calling this.
|
|
56
|
+
* @param id {string} missionId
|
|
57
|
+
* @param raw {TemplateMission} The original template mission
|
|
58
|
+
* @param data {TemplateMissionUpdateInput} Fields to be updated
|
|
59
|
+
* @returns {Promise<TemplateMission>} The updated template mission
|
|
60
|
+
*/
|
|
61
|
+
updateTemplateMission(id: string, raw: TemplateMission, update: TemplateMissionUpdateInput): Promise<TemplateMission>;
|
|
42
62
|
/**
|
|
43
63
|
* Copy a template mission to a user's roadmap
|
|
44
64
|
*/
|
|
@@ -87,6 +87,32 @@ class MissionLibraryApi {
|
|
|
87
87
|
return this.client.fetch(path);
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Update title/description/tasks of a template mission.
|
|
92
|
+
* Should ensure the mission is a 'custom' mission before calling this.
|
|
93
|
+
* @param id {string} missionId
|
|
94
|
+
* @param raw {TemplateMission} The original template mission
|
|
95
|
+
* @param data {TemplateMissionUpdateInput} Fields to be updated
|
|
96
|
+
* @returns {Promise<TemplateMission>} The updated template mission
|
|
97
|
+
*/
|
|
98
|
+
updateTemplateMission(id, raw, update) {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
+
var _a, _b;
|
|
101
|
+
const data = {
|
|
102
|
+
title: (_a = update.title) !== null && _a !== void 0 ? _a : raw.title,
|
|
103
|
+
description: (_b = update.description) !== null && _b !== void 0 ? _b : raw.description,
|
|
104
|
+
tasks: update.tasks || [],
|
|
105
|
+
// only allow updatecustom
|
|
106
|
+
type: 'custom',
|
|
107
|
+
category: raw.category,
|
|
108
|
+
subcategory: raw.subcategory,
|
|
109
|
+
};
|
|
110
|
+
return this.client.fetch(`/roadmap/library/missions/${id}`, {
|
|
111
|
+
method: "PUT",
|
|
112
|
+
body: JSON.stringify(data),
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
90
116
|
/**
|
|
91
117
|
* Copy a template mission to a user's roadmap
|
|
92
118
|
*/
|
package/dist/core/types.d.ts
CHANGED
|
@@ -362,6 +362,23 @@ export interface CurrentUserRoles {
|
|
|
362
362
|
userId: string;
|
|
363
363
|
roles: UserRoleInfo[];
|
|
364
364
|
}
|
|
365
|
+
/**
|
|
366
|
+
* Summary information for a student (used in student selection)
|
|
367
|
+
*/
|
|
368
|
+
export interface StudentSummary {
|
|
369
|
+
userId: string;
|
|
370
|
+
firstName: string;
|
|
371
|
+
lastName: string;
|
|
372
|
+
fullName: string;
|
|
373
|
+
email: string;
|
|
374
|
+
profileImageUrl: string | null;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Response from the /api/v1/account/me/students endpoint
|
|
378
|
+
*/
|
|
379
|
+
export interface MyStudentsResponse {
|
|
380
|
+
data: StudentSummary[];
|
|
381
|
+
}
|
|
365
382
|
/**
|
|
366
383
|
* Prefilled field with value and source information
|
|
367
384
|
*/
|
|
@@ -5,3 +5,23 @@ export declare function getUserId(): string | null;
|
|
|
5
5
|
export declare function getAuthState(): AuthState;
|
|
6
6
|
export declare function subscribeToAuthState(callback: () => void): () => void;
|
|
7
7
|
export declare function persistStandaloneAuth(payload: ZoidProps): void;
|
|
8
|
+
/**
|
|
9
|
+
* Check if the app is running in iframe mode (embedded in parent window)
|
|
10
|
+
*/
|
|
11
|
+
export declare function isIframeMode(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Set token in localStorage (used after OAuth callback)
|
|
14
|
+
*/
|
|
15
|
+
export declare function setToken(token: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Set student ID in localStorage (used after student selection)
|
|
18
|
+
*/
|
|
19
|
+
export declare function setStudentId(studentId: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Set user ID in localStorage (used after OAuth callback)
|
|
22
|
+
*/
|
|
23
|
+
export declare function setUserId(userId: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Clear all auth data from localStorage (used for logout)
|
|
26
|
+
*/
|
|
27
|
+
export declare function clearAuth(): void;
|
|
@@ -6,6 +6,11 @@ exports.getUserId = getUserId;
|
|
|
6
6
|
exports.getAuthState = getAuthState;
|
|
7
7
|
exports.subscribeToAuthState = subscribeToAuthState;
|
|
8
8
|
exports.persistStandaloneAuth = persistStandaloneAuth;
|
|
9
|
+
exports.isIframeMode = isIframeMode;
|
|
10
|
+
exports.setToken = setToken;
|
|
11
|
+
exports.setStudentId = setStudentId;
|
|
12
|
+
exports.setUserId = setUserId;
|
|
13
|
+
exports.clearAuth = clearAuth;
|
|
9
14
|
const constants_1 = require("./constants");
|
|
10
15
|
const readFromLocalStorage = (key) => {
|
|
11
16
|
if (typeof window === "undefined")
|
|
@@ -123,3 +128,69 @@ function persistStandaloneAuth(payload) {
|
|
|
123
128
|
window.xprops = payload;
|
|
124
129
|
window.dispatchEvent(new CustomEvent(constants_1.XPROPS_READY_EVENT));
|
|
125
130
|
}
|
|
131
|
+
// Helper to trigger auth state change notification
|
|
132
|
+
function notifyAuthStateChange() {
|
|
133
|
+
if (typeof window === "undefined")
|
|
134
|
+
return;
|
|
135
|
+
// Invalidate cached state
|
|
136
|
+
cachedAuthState = null;
|
|
137
|
+
// Dispatch event to notify subscribers
|
|
138
|
+
window.dispatchEvent(new CustomEvent(constants_1.XPROPS_READY_EVENT));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Check if the app is running in iframe mode (embedded in parent window)
|
|
142
|
+
*/
|
|
143
|
+
function isIframeMode() {
|
|
144
|
+
if (typeof window === "undefined")
|
|
145
|
+
return false;
|
|
146
|
+
try {
|
|
147
|
+
return window.self !== window.top;
|
|
148
|
+
}
|
|
149
|
+
catch (_a) {
|
|
150
|
+
// If we can't access window.top due to cross-origin, we're in an iframe
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Set token in localStorage (used after OAuth callback)
|
|
156
|
+
*/
|
|
157
|
+
function setToken(token) {
|
|
158
|
+
if (typeof window === "undefined")
|
|
159
|
+
return;
|
|
160
|
+
writeToLocalStorage(constants_1.STORAGE_KEYS.token, token);
|
|
161
|
+
notifyAuthStateChange();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Set student ID in localStorage (used after student selection)
|
|
165
|
+
*/
|
|
166
|
+
function setStudentId(studentId) {
|
|
167
|
+
if (typeof window === "undefined")
|
|
168
|
+
return;
|
|
169
|
+
writeToLocalStorage(constants_1.STORAGE_KEYS.studentId, studentId);
|
|
170
|
+
notifyAuthStateChange();
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Set user ID in localStorage (used after OAuth callback)
|
|
174
|
+
*/
|
|
175
|
+
function setUserId(userId) {
|
|
176
|
+
if (typeof window === "undefined")
|
|
177
|
+
return;
|
|
178
|
+
writeToLocalStorage(constants_1.STORAGE_KEYS.userId, userId);
|
|
179
|
+
notifyAuthStateChange();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Clear all auth data from localStorage (used for logout)
|
|
183
|
+
*/
|
|
184
|
+
function clearAuth() {
|
|
185
|
+
if (typeof window === "undefined")
|
|
186
|
+
return;
|
|
187
|
+
try {
|
|
188
|
+
localStorage.removeItem(constants_1.STORAGE_KEYS.token);
|
|
189
|
+
localStorage.removeItem(constants_1.STORAGE_KEYS.userId);
|
|
190
|
+
localStorage.removeItem(constants_1.STORAGE_KEYS.studentId);
|
|
191
|
+
}
|
|
192
|
+
catch (_a) {
|
|
193
|
+
// Ignore storage errors
|
|
194
|
+
}
|
|
195
|
+
notifyAuthStateChange();
|
|
196
|
+
}
|
package/dist/iframe/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { setupIframeListener } from "./listener";
|
|
2
2
|
export type { CleanupFn } from "./listener";
|
|
3
|
-
export { getToken, getUserId, getStudentId, getAuthState, subscribeToAuthState, persistStandaloneAuth, } from "./auth-state";
|
|
3
|
+
export { getToken, getUserId, getStudentId, getAuthState, subscribeToAuthState, persistStandaloneAuth, isIframeMode, setToken, setStudentId, setUserId, clearAuth, } from "./auth-state";
|
|
4
4
|
export { XPROPS_READY_EVENT, STORAGE_KEYS, VIRTUAL_MISSION_ID, getDefaultAllowedOrigins, } from "./constants";
|
|
5
5
|
export type { ZoidProps, AuthState } from "./types";
|
package/dist/iframe/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDefaultAllowedOrigins = exports.VIRTUAL_MISSION_ID = exports.STORAGE_KEYS = exports.XPROPS_READY_EVENT = exports.persistStandaloneAuth = exports.subscribeToAuthState = exports.getAuthState = exports.getStudentId = exports.getUserId = exports.getToken = exports.setupIframeListener = void 0;
|
|
3
|
+
exports.getDefaultAllowedOrigins = exports.VIRTUAL_MISSION_ID = exports.STORAGE_KEYS = exports.XPROPS_READY_EVENT = exports.clearAuth = exports.setUserId = exports.setStudentId = exports.setToken = exports.isIframeMode = exports.persistStandaloneAuth = exports.subscribeToAuthState = exports.getAuthState = exports.getStudentId = exports.getUserId = exports.getToken = exports.setupIframeListener = void 0;
|
|
4
4
|
var listener_1 = require("./listener");
|
|
5
5
|
Object.defineProperty(exports, "setupIframeListener", { enumerable: true, get: function () { return listener_1.setupIframeListener; } });
|
|
6
6
|
var auth_state_1 = require("./auth-state");
|
|
@@ -10,6 +10,11 @@ Object.defineProperty(exports, "getStudentId", { enumerable: true, get: function
|
|
|
10
10
|
Object.defineProperty(exports, "getAuthState", { enumerable: true, get: function () { return auth_state_1.getAuthState; } });
|
|
11
11
|
Object.defineProperty(exports, "subscribeToAuthState", { enumerable: true, get: function () { return auth_state_1.subscribeToAuthState; } });
|
|
12
12
|
Object.defineProperty(exports, "persistStandaloneAuth", { enumerable: true, get: function () { return auth_state_1.persistStandaloneAuth; } });
|
|
13
|
+
Object.defineProperty(exports, "isIframeMode", { enumerable: true, get: function () { return auth_state_1.isIframeMode; } });
|
|
14
|
+
Object.defineProperty(exports, "setToken", { enumerable: true, get: function () { return auth_state_1.setToken; } });
|
|
15
|
+
Object.defineProperty(exports, "setStudentId", { enumerable: true, get: function () { return auth_state_1.setStudentId; } });
|
|
16
|
+
Object.defineProperty(exports, "setUserId", { enumerable: true, get: function () { return auth_state_1.setUserId; } });
|
|
17
|
+
Object.defineProperty(exports, "clearAuth", { enumerable: true, get: function () { return auth_state_1.clearAuth; } });
|
|
13
18
|
var constants_1 = require("./constants");
|
|
14
19
|
Object.defineProperty(exports, "XPROPS_READY_EVENT", { enumerable: true, get: function () { return constants_1.XPROPS_READY_EVENT; } });
|
|
15
20
|
Object.defineProperty(exports, "STORAGE_KEYS", { enumerable: true, get: function () { return constants_1.STORAGE_KEYS; } });
|
package/dist/index.js
CHANGED
|
@@ -18,5 +18,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
__exportStar(require("./core"), exports);
|
|
19
19
|
// iframe layer (postMessage communication)
|
|
20
20
|
__exportStar(require("./iframe"), exports);
|
|
21
|
-
// React layer is available via "@crimson/sdk/react" subpath
|
|
21
|
+
// React layer is available via "@crimson-education/sdk/react" subpath
|
|
22
22
|
// Do NOT export here to avoid forcing React dependency on non-React consumers
|
|
@@ -4,7 +4,7 @@ export type { UseOAuthResult } from "./useOAuth";
|
|
|
4
4
|
export { useMissions, useMissionsInfinite, useCreateMission, useUpdateMission, useDeleteMission, missionKeys, } from "./useMissions";
|
|
5
5
|
export { useTasks, useAllUserTasks, useTasksByRoadmapId, useTasksInfinite, useCreateTask, useUpdateTask, useDeleteTask, taskKeys, } from "./useTasks";
|
|
6
6
|
export { useUsers, useUser, userKeys } from "./useUsers";
|
|
7
|
-
export { useCurrentUserRoles, accountKeys } from "./useAccount";
|
|
7
|
+
export { useCurrentUserRoles, useMyStudents, accountKeys } from "./useAccount";
|
|
8
8
|
export { useRoadmapContext } from "./useRoadmapContext";
|
|
9
|
-
export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, } from "./useMissionLibrary";
|
|
9
|
+
export { useTemplateMissions, useTemplateMissionsInfinite, useTemplateTasks, useTemplateTasksInfinite, useTemplateMissionDetail, useUpdateTemplateMission, useCopyTemplateMission, useAssignBulkMission, useAssignBulkTask, useCreateFromPredefinedTasks, missionLibraryKeys, } 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.useTemplateMissionDetail = exports.useTemplateTasksInfinite = exports.useTemplateTasks = exports.useTemplateMissionsInfinite = exports.useTemplateMissions = exports.useRoadmapContext = exports.accountKeys = exports.useCurrentUserRoles = exports.userKeys = exports.useUser = exports.useUsers = 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.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.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;
|
|
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");
|
|
@@ -28,6 +28,7 @@ Object.defineProperty(exports, "useUser", { enumerable: true, get: function () {
|
|
|
28
28
|
Object.defineProperty(exports, "userKeys", { enumerable: true, get: function () { return useUsers_1.userKeys; } });
|
|
29
29
|
var useAccount_1 = require("./useAccount");
|
|
30
30
|
Object.defineProperty(exports, "useCurrentUserRoles", { enumerable: true, get: function () { return useAccount_1.useCurrentUserRoles; } });
|
|
31
|
+
Object.defineProperty(exports, "useMyStudents", { enumerable: true, get: function () { return useAccount_1.useMyStudents; } });
|
|
31
32
|
Object.defineProperty(exports, "accountKeys", { enumerable: true, get: function () { return useAccount_1.accountKeys; } });
|
|
32
33
|
var useRoadmapContext_1 = require("./useRoadmapContext");
|
|
33
34
|
Object.defineProperty(exports, "useRoadmapContext", { enumerable: true, get: function () { return useRoadmapContext_1.useRoadmapContext; } });
|
|
@@ -37,6 +38,7 @@ Object.defineProperty(exports, "useTemplateMissionsInfinite", { enumerable: true
|
|
|
37
38
|
Object.defineProperty(exports, "useTemplateTasks", { enumerable: true, get: function () { return useMissionLibrary_1.useTemplateTasks; } });
|
|
38
39
|
Object.defineProperty(exports, "useTemplateTasksInfinite", { enumerable: true, get: function () { return useMissionLibrary_1.useTemplateTasksInfinite; } });
|
|
39
40
|
Object.defineProperty(exports, "useTemplateMissionDetail", { enumerable: true, get: function () { return useMissionLibrary_1.useTemplateMissionDetail; } });
|
|
41
|
+
Object.defineProperty(exports, "useUpdateTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useUpdateTemplateMission; } });
|
|
40
42
|
Object.defineProperty(exports, "useCopyTemplateMission", { enumerable: true, get: function () { return useMissionLibrary_1.useCopyTemplateMission; } });
|
|
41
43
|
Object.defineProperty(exports, "useAssignBulkMission", { enumerable: true, get: function () { return useMissionLibrary_1.useAssignBulkMission; } });
|
|
42
44
|
Object.defineProperty(exports, "useAssignBulkTask", { enumerable: true, get: function () { return useMissionLibrary_1.useAssignBulkTask; } });
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { CurrentUserRoles } from "../../core/types";
|
|
1
|
+
import type { CurrentUserRoles, StudentSummary } from "../../core/types";
|
|
2
2
|
export declare const accountKeys: {
|
|
3
3
|
all: readonly ["account"];
|
|
4
4
|
currentUserRoles: () => readonly ["account", "currentUserRoles"];
|
|
5
|
+
myStudents: () => readonly ["account", "myStudents"];
|
|
5
6
|
};
|
|
6
7
|
/**
|
|
7
8
|
* Hook to get current user's roles
|
|
@@ -11,3 +12,15 @@ export declare const accountKeys: {
|
|
|
11
12
|
* - roles: Array of role objects with roleId and isPrimary flag
|
|
12
13
|
*/
|
|
13
14
|
export declare function useCurrentUserRoles(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<CurrentUserRoles, Error>;
|
|
15
|
+
/**
|
|
16
|
+
* Hook to get the list of students associated with the current user.
|
|
17
|
+
*
|
|
18
|
+
* This is primarily used for staff users (Strategists, SSMs, etc.) to get
|
|
19
|
+
* their list of students for the student selection page after OAuth login.
|
|
20
|
+
*
|
|
21
|
+
* For student users, this will return an empty array.
|
|
22
|
+
*
|
|
23
|
+
* @param enabled - Whether to enable the query (default: true)
|
|
24
|
+
* @returns Query result containing array of student summaries
|
|
25
|
+
*/
|
|
26
|
+
export declare function useMyStudents(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<StudentSummary[], Error>;
|
|
@@ -12,12 +12,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.accountKeys = void 0;
|
|
14
14
|
exports.useCurrentUserRoles = useCurrentUserRoles;
|
|
15
|
+
exports.useMyStudents = useMyStudents;
|
|
15
16
|
const react_query_1 = require("@tanstack/react-query");
|
|
16
17
|
const provider_1 = require("../provider");
|
|
17
18
|
// Query keys
|
|
18
19
|
exports.accountKeys = {
|
|
19
20
|
all: ["account"],
|
|
20
21
|
currentUserRoles: () => [...exports.accountKeys.all, "currentUserRoles"],
|
|
22
|
+
myStudents: () => [...exports.accountKeys.all, "myStudents"],
|
|
21
23
|
};
|
|
22
24
|
/**
|
|
23
25
|
* Hook to get current user's roles
|
|
@@ -37,3 +39,25 @@ function useCurrentUserRoles(enabled = true) {
|
|
|
37
39
|
staleTime: 1000 * 60 * 5, // 5 minutes - roles don't change often
|
|
38
40
|
});
|
|
39
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Hook to get the list of students associated with the current user.
|
|
44
|
+
*
|
|
45
|
+
* This is primarily used for staff users (Strategists, SSMs, etc.) to get
|
|
46
|
+
* their list of students for the student selection page after OAuth login.
|
|
47
|
+
*
|
|
48
|
+
* For student users, this will return an empty array.
|
|
49
|
+
*
|
|
50
|
+
* @param enabled - Whether to enable the query (default: true)
|
|
51
|
+
* @returns Query result containing array of student summaries
|
|
52
|
+
*/
|
|
53
|
+
function useMyStudents(enabled = true) {
|
|
54
|
+
const client = (0, provider_1.useCrimsonClient)();
|
|
55
|
+
return (0, react_query_1.useQuery)({
|
|
56
|
+
queryKey: exports.accountKeys.myStudents(),
|
|
57
|
+
queryFn: () => __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
return client.account.getMyStudents();
|
|
59
|
+
}),
|
|
60
|
+
enabled,
|
|
61
|
+
staleTime: 1000 * 60 * 5, // 5 minutes - student list doesn't change often
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TemplateMission, TemplateTask, MissionDetail, AssignBulkMissionInput, AssignBulkTaskInput } from "../../core/types";
|
|
2
|
-
import type { TemplateMissionFilters, TemplateTaskFilters, CopyTemplateMissionInput, CreateFromPredefinedInput } from "../../core/missionLibrary";
|
|
2
|
+
import type { TemplateMissionFilters, TemplateTaskFilters, CopyTemplateMissionInput, CreateFromPredefinedInput, TemplateMissionUpdateInput } from "../../core/missionLibrary";
|
|
3
3
|
export declare const missionLibraryKeys: {
|
|
4
4
|
all: readonly ["missionLibrary"];
|
|
5
5
|
missions: (filters?: TemplateMissionFilters) => readonly ["missionLibrary", "missions", TemplateMissionFilters | undefined];
|
|
@@ -19,6 +19,11 @@ export declare function useTemplateTasksInfinite(filters?: Omit<TemplateTaskFilt
|
|
|
19
19
|
pageSize?: number;
|
|
20
20
|
}): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<import("../../core/types").PaginatedResult<TemplateTask>, unknown>, Error>;
|
|
21
21
|
export declare function useTemplateMissionDetail(missionId: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<MissionDetail | null, Error>;
|
|
22
|
+
export declare function useUpdateTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission, Error, {
|
|
23
|
+
id: string;
|
|
24
|
+
raw: TemplateMission;
|
|
25
|
+
update: TemplateMissionUpdateInput;
|
|
26
|
+
}, unknown>;
|
|
22
27
|
export declare function useCopyTemplateMission(): import("@tanstack/react-query").UseMutationResult<TemplateMission[], Error, CopyTemplateMissionInput, unknown>;
|
|
23
28
|
export declare function useAssignBulkMission(): import("@tanstack/react-query").UseMutationResult<{
|
|
24
29
|
code: number;
|
|
@@ -16,6 +16,7 @@ exports.useTemplateMissionsInfinite = useTemplateMissionsInfinite;
|
|
|
16
16
|
exports.useTemplateTasks = useTemplateTasks;
|
|
17
17
|
exports.useTemplateTasksInfinite = useTemplateTasksInfinite;
|
|
18
18
|
exports.useTemplateMissionDetail = useTemplateMissionDetail;
|
|
19
|
+
exports.useUpdateTemplateMission = useUpdateTemplateMission;
|
|
19
20
|
exports.useCopyTemplateMission = useCopyTemplateMission;
|
|
20
21
|
exports.useAssignBulkMission = useAssignBulkMission;
|
|
21
22
|
exports.useAssignBulkTask = useAssignBulkTask;
|
|
@@ -103,6 +104,23 @@ function useTemplateMissionDetail(missionId, enabled = true) {
|
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
106
|
// --- Mutations ---
|
|
107
|
+
function useUpdateTemplateMission() {
|
|
108
|
+
const client = (0, provider_1.useCrimsonClient)();
|
|
109
|
+
const queryClient = (0, react_query_1.useQueryClient)();
|
|
110
|
+
return (0, react_query_1.useMutation)({
|
|
111
|
+
mutationFn: ({ id, raw, update }) => client.library.updateTemplateMission(id, raw, update),
|
|
112
|
+
onSuccess: (_, variables) => {
|
|
113
|
+
queryClient.invalidateQueries({
|
|
114
|
+
queryKey: exports.missionLibraryKeys.missionDetail(variables.id),
|
|
115
|
+
});
|
|
116
|
+
queryClient.invalidateQueries({
|
|
117
|
+
queryKey: exports.missionLibraryKeys.missionsInfinite({
|
|
118
|
+
groups: ['custom']
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
106
124
|
function useCopyTemplateMission() {
|
|
107
125
|
const client = (0, provider_1.useCrimsonClient)();
|
|
108
126
|
const queryClient = (0, react_query_1.useQueryClient)();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crimson-education/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Crimson SDK for accessing Crimson App APIs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
},
|
|
42
42
|
"homepage": "https://github.com/crimson-education/crimson-sdk#readme",
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"react": ">=
|
|
45
|
-
"
|
|
44
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
45
|
+
"react": ">=18.0.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"react": {
|
|
@@ -53,9 +53,12 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
+
"@tanstack/react-query": "^5.90.15",
|
|
56
57
|
"@types/node": "^24.10.1",
|
|
58
|
+
"@types/react": "^19.2.7",
|
|
57
59
|
"chai": "^6.2.1",
|
|
58
60
|
"mocha": "^11.7.5",
|
|
61
|
+
"react": "^19.2.3",
|
|
59
62
|
"typescript": "^5.0.0"
|
|
60
63
|
}
|
|
61
64
|
}
|