@learnorama/mozaik-sdk 0.12.3-staging.46.1 → 0.13.0-staging.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/api/account.d.ts +1 -1
- package/dist/api/account.js.map +1 -1
- package/dist/api/admin-catalogue.d.ts +1 -1
- package/dist/api/admin-catalogue.js.map +1 -1
- package/dist/api/admin-consumption.d.ts +1 -1
- package/dist/api/admin-consumption.js.map +1 -1
- package/dist/api/admin-contracts.d.ts +1 -1
- package/dist/api/admin-contracts.js.map +1 -1
- package/dist/api/admin-desk.d.ts +1 -1
- package/dist/api/admin-desk.js.map +1 -1
- package/dist/api/admin-licenses.d.ts +1 -1
- package/dist/api/admin-licenses.js.map +1 -1
- package/dist/api/admin-partner-selections.d.ts +1 -1
- package/dist/api/admin-partner-selections.js.map +1 -1
- package/dist/api/admin-patrons.d.ts +1 -1
- package/dist/api/admin-patrons.js.map +1 -1
- package/dist/api/admin-reviews.d.ts +1 -1
- package/dist/api/admin-reviews.js.map +1 -1
- package/dist/api/admin-roles.d.ts +1 -1
- package/dist/api/admin-roles.js.map +1 -1
- package/dist/api/admin-support.d.ts +1 -1
- package/dist/api/admin-support.js.map +1 -1
- package/dist/api/admin-tenants.d.ts +1 -1
- package/dist/api/admin-tenants.js.map +1 -1
- package/dist/api/admin-tutoring.d.ts +1 -1
- package/dist/api/admin-tutoring.js.map +1 -1
- package/dist/api/auth.d.ts +1 -1
- package/dist/api/auth.js.map +1 -1
- package/dist/api/biblio-billing-webhooks.d.ts +18 -0
- package/dist/api/biblio-billing-webhooks.js +62 -0
- package/dist/api/biblio-billing-webhooks.js.map +1 -0
- package/dist/api/biblio-billing.d.ts +192 -0
- package/dist/api/biblio-billing.js +645 -0
- package/dist/api/biblio-billing.js.map +1 -0
- package/dist/api/biblio-catalogue.d.ts +1 -1
- package/dist/api/biblio-catalogue.js.map +1 -1
- package/dist/api/biblio-home.d.ts +1 -1
- package/dist/api/biblio-home.js.map +1 -1
- package/dist/api/biblio-learning-author-profiles.d.ts +108 -0
- package/dist/api/biblio-learning-author-profiles.js +331 -0
- package/dist/api/biblio-learning-author-profiles.js.map +1 -0
- package/dist/api/biblio-learning-authoring.d.ts +168 -0
- package/dist/api/biblio-learning-authoring.js +586 -0
- package/dist/api/biblio-learning-authoring.js.map +1 -0
- package/dist/api/biblio-learning-editorial.d.ts +54 -0
- package/dist/api/biblio-learning-editorial.js +149 -0
- package/dist/api/biblio-learning-editorial.js.map +1 -0
- package/dist/api/biblio-learning-feedback.d.ts +60 -0
- package/dist/api/biblio-learning-feedback.js +180 -0
- package/dist/api/biblio-learning-feedback.js.map +1 -0
- package/dist/api/biblio-learning-finance.d.ts +186 -0
- package/dist/api/biblio-learning-finance.js +622 -0
- package/dist/api/biblio-learning-finance.js.map +1 -0
- package/dist/api/biblio-learning-integrations.d.ts +60 -0
- package/dist/api/biblio-learning-integrations.js +215 -0
- package/dist/api/biblio-learning-integrations.js.map +1 -0
- package/dist/api/biblio-learning-membership.d.ts +24 -0
- package/dist/api/biblio-learning-membership.js +69 -0
- package/dist/api/biblio-learning-membership.js.map +1 -0
- package/dist/api/biblio-learning.d.ts +222 -0
- package/dist/api/biblio-learning.js +697 -0
- package/dist/api/biblio-learning.js.map +1 -0
- package/dist/api/biblio-library.d.ts +1 -1
- package/dist/api/biblio-library.js.map +1 -1
- package/dist/api/biblio-nextory.d.ts +1 -1
- package/dist/api/biblio-nextory.js.map +1 -1
- package/dist/api/biblio-press.d.ts +1 -1
- package/dist/api/biblio-press.js.map +1 -1
- package/dist/api/biblio-search.d.ts +1 -1
- package/dist/api/biblio-search.js.map +1 -1
- package/dist/api/biblio-telemetry.d.ts +1 -1
- package/dist/api/biblio-telemetry.js.map +1 -1
- package/dist/api/consumption.d.ts +1 -1
- package/dist/api/consumption.js.map +1 -1
- package/dist/api/cvs-app.d.ts +1 -1
- package/dist/api/cvs-app.js.map +1 -1
- package/dist/api/cvs-documents.d.ts +1 -1
- package/dist/api/cvs-documents.js.map +1 -1
- package/dist/api/cvs-favorites.d.ts +1 -1
- package/dist/api/cvs-favorites.js.map +1 -1
- package/dist/api/cvs-ils.d.ts +1 -1
- package/dist/api/cvs-ils.js.map +1 -1
- package/dist/api/cvs-loans.d.ts +1 -1
- package/dist/api/cvs-loans.js.map +1 -1
- package/dist/api/cvs-payments.d.ts +1 -1
- package/dist/api/cvs-payments.js.map +1 -1
- package/dist/api/cvs-streaming.d.ts +1 -1
- package/dist/api/cvs-streaming.js.map +1 -1
- package/dist/api/index.d.ts +11 -1
- package/dist/api/index.js +11 -1
- package/dist/api/partner-catalogue.d.ts +1 -1
- package/dist/api/partner-catalogue.js.map +1 -1
- package/dist/api/partner-reader.d.ts +1 -1
- package/dist/api/partner-reader.js.map +1 -1
- package/dist/api/profiles.d.ts +1 -1
- package/dist/api/profiles.js.map +1 -1
- package/dist/api/search.d.ts +1 -1
- package/dist/api/search.js.map +1 -1
- package/dist/api/tutoring-catalogue.d.ts +1 -1
- package/dist/api/tutoring-catalogue.js.map +1 -1
- package/dist/api/tutoring-chat.d.ts +1 -1
- package/dist/api/tutoring-chat.js.map +1 -1
- package/dist/api/tutoring-dispatch.d.ts +1 -1
- package/dist/api/tutoring-dispatch.js.map +1 -1
- package/dist/api/tutoring-practitioner.d.ts +1 -1
- package/dist/api/tutoring-practitioner.js.map +1 -1
- package/dist/api/tutoring-requests.d.ts +1 -1
- package/dist/api/tutoring-requests.js.map +1 -1
- package/dist/chunks/client2.d.ts +1 -1
- package/dist/chunks/connection.d.ts +1 -1
- package/dist/chunks/index.d.ts +10062 -3487
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +2 -2
- package/dist/models.js +329 -1
- package/dist/models.js.map +1 -1
- package/dist/react/account.d.ts +1 -1
- package/dist/react/account.js +1 -1
- package/dist/react/account.js.map +1 -1
- package/dist/react/admin-catalogue.d.ts +1 -1
- package/dist/react/admin-catalogue.js +1 -1
- package/dist/react/admin-catalogue.js.map +1 -1
- package/dist/react/admin-consumption.d.ts +1 -1
- package/dist/react/admin-consumption.js +1 -1
- package/dist/react/admin-consumption.js.map +1 -1
- package/dist/react/admin-contracts.d.ts +1 -1
- package/dist/react/admin-contracts.js +1 -1
- package/dist/react/admin-contracts.js.map +1 -1
- package/dist/react/admin-desk.d.ts +1 -1
- package/dist/react/admin-desk.js +1 -1
- package/dist/react/admin-desk.js.map +1 -1
- package/dist/react/admin-licenses.d.ts +1 -1
- package/dist/react/admin-licenses.js +1 -1
- package/dist/react/admin-licenses.js.map +1 -1
- package/dist/react/admin-partner-selections.d.ts +1 -1
- package/dist/react/admin-partner-selections.js +1 -1
- package/dist/react/admin-partner-selections.js.map +1 -1
- package/dist/react/admin-patrons.d.ts +1 -1
- package/dist/react/admin-patrons.js +1 -1
- package/dist/react/admin-patrons.js.map +1 -1
- package/dist/react/admin-reviews.d.ts +1 -1
- package/dist/react/admin-reviews.js +1 -1
- package/dist/react/admin-reviews.js.map +1 -1
- package/dist/react/admin-roles.d.ts +1 -1
- package/dist/react/admin-roles.js +1 -1
- package/dist/react/admin-roles.js.map +1 -1
- package/dist/react/admin-support.d.ts +1 -1
- package/dist/react/admin-support.js +1 -1
- package/dist/react/admin-support.js.map +1 -1
- package/dist/react/admin-tenants.d.ts +1 -1
- package/dist/react/admin-tenants.js +1 -1
- package/dist/react/admin-tenants.js.map +1 -1
- package/dist/react/admin-tutoring.d.ts +1 -1
- package/dist/react/admin-tutoring.js +1 -1
- package/dist/react/admin-tutoring.js.map +1 -1
- package/dist/react/auth.d.ts +1 -1
- package/dist/react/auth.js +1 -1
- package/dist/react/auth.js.map +1 -1
- package/dist/react/biblio-billing-webhooks.d.ts +56 -0
- package/dist/react/biblio-billing-webhooks.js +126 -0
- package/dist/react/biblio-billing-webhooks.js.map +1 -0
- package/dist/react/biblio-billing.d.ts +876 -0
- package/dist/react/biblio-billing.js +1491 -0
- package/dist/react/biblio-billing.js.map +1 -0
- package/dist/react/biblio-catalogue.d.ts +1 -1
- package/dist/react/biblio-catalogue.js +1 -1
- package/dist/react/biblio-catalogue.js.map +1 -1
- package/dist/react/biblio-home.d.ts +1 -1
- package/dist/react/biblio-home.js +1 -1
- package/dist/react/biblio-home.js.map +1 -1
- package/dist/react/biblio-learning-author-profiles.d.ts +513 -0
- package/dist/react/biblio-learning-author-profiles.js +795 -0
- package/dist/react/biblio-learning-author-profiles.js.map +1 -0
- package/dist/react/biblio-learning-authoring.d.ts +745 -0
- package/dist/react/biblio-learning-authoring.js +1335 -0
- package/dist/react/biblio-learning-authoring.js.map +1 -0
- package/dist/react/biblio-learning-editorial.d.ts +264 -0
- package/dist/react/biblio-learning-editorial.js +371 -0
- package/dist/react/biblio-learning-editorial.js.map +1 -0
- package/dist/react/biblio-learning-feedback.d.ts +280 -0
- package/dist/react/biblio-learning-feedback.js +433 -0
- package/dist/react/biblio-learning-feedback.js.map +1 -0
- package/dist/react/biblio-learning-finance.d.ts +868 -0
- package/dist/react/biblio-learning-finance.js +1439 -0
- package/dist/react/biblio-learning-finance.js.map +1 -0
- package/dist/react/biblio-learning-integrations.d.ts +237 -0
- package/dist/react/biblio-learning-integrations.js +483 -0
- package/dist/react/biblio-learning-integrations.js.map +1 -0
- package/dist/react/biblio-learning-membership.d.ts +99 -0
- package/dist/react/biblio-learning-membership.js +165 -0
- package/dist/react/biblio-learning-membership.js.map +1 -0
- package/dist/react/biblio-learning.d.ts +1047 -0
- package/dist/react/biblio-learning.js +1667 -0
- package/dist/react/biblio-learning.js.map +1 -0
- package/dist/react/biblio-library.d.ts +1 -1
- package/dist/react/biblio-library.js +1 -1
- package/dist/react/biblio-library.js.map +1 -1
- package/dist/react/biblio-nextory.d.ts +1 -1
- package/dist/react/biblio-nextory.js +1 -1
- package/dist/react/biblio-nextory.js.map +1 -1
- package/dist/react/biblio-press.d.ts +1 -1
- package/dist/react/biblio-press.js +1 -1
- package/dist/react/biblio-press.js.map +1 -1
- package/dist/react/biblio-search.d.ts +1 -1
- package/dist/react/biblio-search.js +1 -1
- package/dist/react/biblio-search.js.map +1 -1
- package/dist/react/biblio-telemetry.d.ts +1 -1
- package/dist/react/biblio-telemetry.js +1 -1
- package/dist/react/biblio-telemetry.js.map +1 -1
- package/dist/react/chat.d.ts +1 -1
- package/dist/react/consumption.d.ts +1 -1
- package/dist/react/consumption.js +1 -1
- package/dist/react/consumption.js.map +1 -1
- package/dist/react/cvs-app.d.ts +1 -1
- package/dist/react/cvs-app.js +1 -1
- package/dist/react/cvs-app.js.map +1 -1
- package/dist/react/cvs-documents.d.ts +1 -1
- package/dist/react/cvs-documents.js +1 -1
- package/dist/react/cvs-documents.js.map +1 -1
- package/dist/react/cvs-favorites.d.ts +1 -1
- package/dist/react/cvs-favorites.js +1 -1
- package/dist/react/cvs-favorites.js.map +1 -1
- package/dist/react/cvs-ils.d.ts +1 -1
- package/dist/react/cvs-ils.js +1 -1
- package/dist/react/cvs-ils.js.map +1 -1
- package/dist/react/cvs-loans.d.ts +1 -1
- package/dist/react/cvs-loans.js +1 -1
- package/dist/react/cvs-loans.js.map +1 -1
- package/dist/react/cvs-payments.d.ts +1 -1
- package/dist/react/cvs-payments.js +1 -1
- package/dist/react/cvs-payments.js.map +1 -1
- package/dist/react/cvs-streaming.d.ts +1 -1
- package/dist/react/cvs-streaming.js +1 -1
- package/dist/react/cvs-streaming.js.map +1 -1
- package/dist/react/index.d.ts +11 -1
- package/dist/react/index.js +11 -1
- package/dist/react/partner-catalogue.d.ts +1 -1
- package/dist/react/partner-catalogue.js +1 -1
- package/dist/react/partner-catalogue.js.map +1 -1
- package/dist/react/partner-reader.d.ts +1 -1
- package/dist/react/partner-reader.js +1 -1
- package/dist/react/partner-reader.js.map +1 -1
- package/dist/react/profiles.d.ts +1 -1
- package/dist/react/profiles.js +1 -1
- package/dist/react/profiles.js.map +1 -1
- package/dist/react/search.d.ts +1 -1
- package/dist/react/search.js +1 -1
- package/dist/react/search.js.map +1 -1
- package/dist/react/tutoring-catalogue.d.ts +1 -1
- package/dist/react/tutoring-catalogue.js +1 -1
- package/dist/react/tutoring-catalogue.js.map +1 -1
- package/dist/react/tutoring-chat.d.ts +1 -1
- package/dist/react/tutoring-chat.js +1 -1
- package/dist/react/tutoring-chat.js.map +1 -1
- package/dist/react/tutoring-dispatch.d.ts +1 -1
- package/dist/react/tutoring-dispatch.js +1 -1
- package/dist/react/tutoring-dispatch.js.map +1 -1
- package/dist/react/tutoring-practitioner.d.ts +1 -1
- package/dist/react/tutoring-practitioner.js +1 -1
- package/dist/react/tutoring-practitioner.js.map +1 -1
- package/dist/react/tutoring-requests.d.ts +1 -1
- package/dist/react/tutoring-requests.js +1 -1
- package/dist/react/tutoring-requests.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,1667 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { r as request } from "../chunks/client.js";
|
|
3
|
+
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
4
|
+
//#region src/react/biblio-learning/biblio-learning.ts
|
|
5
|
+
/**
|
|
6
|
+
* Generated by orval 🍺
|
|
7
|
+
* Do not edit manually.
|
|
8
|
+
* Mozaik backend
|
|
9
|
+
* Four products behind one API — Biblio, Médiathèques, the partner catalogues (Nextory and YouScribe) and Prof Express. Authentication is Keycloak SSO only, once, for all of them: see the **auth** section below for the browser flow and the three failure modes.
|
|
10
|
+
* OpenAPI spec version: 0.13.0
|
|
11
|
+
*/
|
|
12
|
+
const withQueryKey = (query, queryKey) => {
|
|
13
|
+
const result = { queryKey };
|
|
14
|
+
for (const key of Object.keys(query)) {
|
|
15
|
+
if (key === "queryKey") continue;
|
|
16
|
+
Object.defineProperty(result, key, {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
get: () => query[key]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
const getLearningStartAttemptUrl = (assessmentId) => {
|
|
25
|
+
return `/learning/assessments/${assessmentId}/attempts`;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Creates an immutable snapshot of the selected questions, ordering and pages. Course attempts need the profile's open reading session; provide lessonId when the assessment appears in multiple lessons. A lessonId without sessionId requests an allowed free preview. Path assessments use neither course session nor lesson. requestKey is scoped to profile and assessment: identical context replays the existing attempt; changed lesson/session context returns 409. Deadlines and attempt limits are enforced by the server. Preview results do not update course progress or score summaries.
|
|
29
|
+
* @summary Start or replay a scoped assessment attempt
|
|
30
|
+
*/
|
|
31
|
+
const learningStartAttempt = async (assessmentId, learningAttemptStartWrite, options) => {
|
|
32
|
+
const getHeaders = (h) => {
|
|
33
|
+
if (!h) return {};
|
|
34
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
35
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
36
|
+
const headers = {};
|
|
37
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
38
|
+
return headers;
|
|
39
|
+
};
|
|
40
|
+
return request(getLearningStartAttemptUrl(assessmentId), {
|
|
41
|
+
...options,
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: {
|
|
44
|
+
"Content-Type": "application/json",
|
|
45
|
+
...getHeaders(options?.headers)
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify(learningAttemptStartWrite)
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
const getLearningStartAttemptMutationKey = () => ["learningStartAttempt"];
|
|
51
|
+
const getLearningStartAttemptMutationOptions = (options) => {
|
|
52
|
+
const mutationKey = getLearningStartAttemptMutationKey();
|
|
53
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
54
|
+
...options,
|
|
55
|
+
mutation: {
|
|
56
|
+
...options.mutation,
|
|
57
|
+
mutationKey
|
|
58
|
+
}
|
|
59
|
+
} : {
|
|
60
|
+
mutation: { mutationKey },
|
|
61
|
+
request: void 0
|
|
62
|
+
};
|
|
63
|
+
const mutationFn = (props) => {
|
|
64
|
+
const { assessmentId, data } = props ?? {};
|
|
65
|
+
return learningStartAttempt(assessmentId, data, requestOptions);
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
mutationFn,
|
|
69
|
+
...mutationOptions
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* @summary Start or replay a scoped assessment attempt
|
|
74
|
+
*/
|
|
75
|
+
const useLearningStartAttempt = (options, queryClient) => {
|
|
76
|
+
return useMutation(getLearningStartAttemptMutationOptions(options), queryClient);
|
|
77
|
+
};
|
|
78
|
+
const getLearningReadAttemptUrl = (attemptId) => {
|
|
79
|
+
return `/learning/attempts/${attemptId}`;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Returns only an attempt owned by the effective profile. In-progress native attempts recheck their learning context; completed and historical evidence remains readable by its owner. Public questions never include answer keys. Corrections and answer grades appear after completion/expiry, or for answered questions when immediate feedback is configured. Historical attempts return retained answers and scores without inventing a replayable question definition. This read does not itself finalize an elapsed deadline.
|
|
83
|
+
* @summary Read the profile's attempt and available feedback
|
|
84
|
+
*/
|
|
85
|
+
const learningReadAttempt = async (attemptId, options) => {
|
|
86
|
+
return request(getLearningReadAttemptUrl(attemptId), {
|
|
87
|
+
...options,
|
|
88
|
+
method: "GET"
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
const getLearningReadAttemptQueryKey = (attemptId) => {
|
|
92
|
+
return [`/learning/attempts/${attemptId}`];
|
|
93
|
+
};
|
|
94
|
+
const getLearningReadAttemptQueryOptions = (attemptId, options) => {
|
|
95
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
96
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadAttemptQueryKey(attemptId);
|
|
97
|
+
const queryFn = ({ signal }) => learningReadAttempt(attemptId, {
|
|
98
|
+
signal,
|
|
99
|
+
...requestOptions
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
queryKey,
|
|
103
|
+
queryFn,
|
|
104
|
+
enabled: attemptId !== null && attemptId !== void 0,
|
|
105
|
+
...queryOptions
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* @summary Read the profile's attempt and available feedback
|
|
110
|
+
*/
|
|
111
|
+
function useLearningReadAttempt(attemptId, options, queryClient) {
|
|
112
|
+
const queryOptions = getLearningReadAttemptQueryOptions(attemptId, options);
|
|
113
|
+
const query = useQuery(queryOptions, queryClient);
|
|
114
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
115
|
+
}
|
|
116
|
+
const getLearningAbandonAttemptUrl = (attemptId) => {
|
|
117
|
+
return `/learning/attempts/${attemptId}/abandon`;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Changes the effective profile's in-progress native attempt to abandoned and records finishedAt. Saved responses remain in history; abandoning does not calculate a score or grant completion. Repeating an abandoned or other terminal native attempt returns its existing state. Imported attempts are historical evidence and cannot be abandoned.
|
|
121
|
+
* @summary Abandon an unfinished native attempt
|
|
122
|
+
*/
|
|
123
|
+
const learningAbandonAttempt = async (attemptId, options) => {
|
|
124
|
+
return request(getLearningAbandonAttemptUrl(attemptId), {
|
|
125
|
+
...options,
|
|
126
|
+
method: "POST"
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
const getLearningAbandonAttemptMutationKey = () => ["learningAbandonAttempt"];
|
|
130
|
+
const getLearningAbandonAttemptMutationOptions = (options) => {
|
|
131
|
+
const mutationKey = getLearningAbandonAttemptMutationKey();
|
|
132
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
133
|
+
...options,
|
|
134
|
+
mutation: {
|
|
135
|
+
...options.mutation,
|
|
136
|
+
mutationKey
|
|
137
|
+
}
|
|
138
|
+
} : {
|
|
139
|
+
mutation: { mutationKey },
|
|
140
|
+
request: void 0
|
|
141
|
+
};
|
|
142
|
+
const mutationFn = (props) => {
|
|
143
|
+
const { attemptId } = props ?? {};
|
|
144
|
+
return learningAbandonAttempt(attemptId, requestOptions);
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
mutationFn,
|
|
148
|
+
...mutationOptions
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* @summary Abandon an unfinished native attempt
|
|
153
|
+
*/
|
|
154
|
+
const useLearningAbandonAttempt = (options, queryClient) => {
|
|
155
|
+
return useMutation(getLearningAbandonAttemptMutationOptions(options), queryClient);
|
|
156
|
+
};
|
|
157
|
+
const getLearningAnswerQuestionUrl = (attemptId, questionKey) => {
|
|
158
|
+
return `/learning/attempts/${attemptId}/answers/${questionKey}`;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Use the selected question's key and kind-specific response object. Before finalization answers can be replaced unless immediate feedback has made the first response final. An identical saved response can be replayed after finalization; a different final answer returns 409. An elapsed deadline finalizes the attempt as expired and rejects the late answer. Uploaded reflection answers must reference this profile's completed upload reserved for this exact attempt and question. The response returns the entire attempt with only currently authorized feedback.
|
|
162
|
+
* @summary Save a question response in the owned attempt
|
|
163
|
+
*/
|
|
164
|
+
const learningAnswerQuestion = async (attemptId, questionKey, learningAnswerWrite, options) => {
|
|
165
|
+
const getHeaders = (h) => {
|
|
166
|
+
if (!h) return {};
|
|
167
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
168
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
169
|
+
const headers = {};
|
|
170
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
171
|
+
return headers;
|
|
172
|
+
};
|
|
173
|
+
return request(getLearningAnswerQuestionUrl(attemptId, questionKey), {
|
|
174
|
+
...options,
|
|
175
|
+
method: "PUT",
|
|
176
|
+
headers: {
|
|
177
|
+
"Content-Type": "application/json",
|
|
178
|
+
...getHeaders(options?.headers)
|
|
179
|
+
},
|
|
180
|
+
body: JSON.stringify(learningAnswerWrite)
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
const getLearningAnswerQuestionMutationKey = () => ["learningAnswerQuestion"];
|
|
184
|
+
const getLearningAnswerQuestionMutationOptions = (options) => {
|
|
185
|
+
const mutationKey = getLearningAnswerQuestionMutationKey();
|
|
186
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
187
|
+
...options,
|
|
188
|
+
mutation: {
|
|
189
|
+
...options.mutation,
|
|
190
|
+
mutationKey
|
|
191
|
+
}
|
|
192
|
+
} : {
|
|
193
|
+
mutation: { mutationKey },
|
|
194
|
+
request: void 0
|
|
195
|
+
};
|
|
196
|
+
const mutationFn = (props) => {
|
|
197
|
+
const { attemptId, questionKey, data } = props ?? {};
|
|
198
|
+
return learningAnswerQuestion(attemptId, questionKey, data, requestOptions);
|
|
199
|
+
};
|
|
200
|
+
return {
|
|
201
|
+
mutationFn,
|
|
202
|
+
...mutationOptions
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* @summary Save a question response in the owned attempt
|
|
207
|
+
*/
|
|
208
|
+
const useLearningAnswerQuestion = (options, queryClient) => {
|
|
209
|
+
return useMutation(getLearningAnswerQuestionMutationOptions(options), queryClient);
|
|
210
|
+
};
|
|
211
|
+
const getLearningFinishAttemptUrl = (attemptId) => {
|
|
212
|
+
return `/learning/attempts/${attemptId}/finish`;
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Requires the owned attempt's learning context. Before its deadline every selected question must have a response, including reflection and information acknowledgements. After the deadline the attempt is finalized as expired, with unanswered scored questions counted as zero. Returns corrections and a percentage score, or null for an unscored assessment. Eligible native results update score summaries and completion evidence; preview results do not. Repeating a terminal attempt returns its existing state.
|
|
216
|
+
* @summary Finalize answers and compute assessment results
|
|
217
|
+
*/
|
|
218
|
+
const learningFinishAttempt = async (attemptId, options) => {
|
|
219
|
+
return request(getLearningFinishAttemptUrl(attemptId), {
|
|
220
|
+
...options,
|
|
221
|
+
method: "POST"
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
const getLearningFinishAttemptMutationKey = () => ["learningFinishAttempt"];
|
|
225
|
+
const getLearningFinishAttemptMutationOptions = (options) => {
|
|
226
|
+
const mutationKey = getLearningFinishAttemptMutationKey();
|
|
227
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
228
|
+
...options,
|
|
229
|
+
mutation: {
|
|
230
|
+
...options.mutation,
|
|
231
|
+
mutationKey
|
|
232
|
+
}
|
|
233
|
+
} : {
|
|
234
|
+
mutation: { mutationKey },
|
|
235
|
+
request: void 0
|
|
236
|
+
};
|
|
237
|
+
const mutationFn = (props) => {
|
|
238
|
+
const { attemptId } = props ?? {};
|
|
239
|
+
return learningFinishAttempt(attemptId, requestOptions);
|
|
240
|
+
};
|
|
241
|
+
return {
|
|
242
|
+
mutationFn,
|
|
243
|
+
...mutationOptions
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* @summary Finalize answers and compute assessment results
|
|
248
|
+
*/
|
|
249
|
+
const useLearningFinishAttempt = (options, queryClient) => {
|
|
250
|
+
return useMutation(getLearningFinishAttemptMutationOptions(options), queryClient);
|
|
251
|
+
};
|
|
252
|
+
const getLearningRateExercisePageUrl = (attemptId, pageKey) => {
|
|
253
|
+
return `/learning/attempts/${attemptId}/pages/${pageKey}/self-rating`;
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Requires an owned native exercise attempt containing pageKey and full learning access. Saves a rating from 1 to 5 for this profile and exercise page; later submissions replace the rating and mark the page's self-reflection complete. Preview attempts cannot save ratings. This does not submit answers, award points or substitute for assessment completion.
|
|
257
|
+
* @summary Save a private exercise-page self-rating
|
|
258
|
+
*/
|
|
259
|
+
const learningRateExercisePage = async (attemptId, pageKey, learningSelfRatingWrite, options) => {
|
|
260
|
+
const getHeaders = (h) => {
|
|
261
|
+
if (!h) return {};
|
|
262
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
263
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
264
|
+
const headers = {};
|
|
265
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
266
|
+
return headers;
|
|
267
|
+
};
|
|
268
|
+
return request(getLearningRateExercisePageUrl(attemptId, pageKey), {
|
|
269
|
+
...options,
|
|
270
|
+
method: "PUT",
|
|
271
|
+
headers: {
|
|
272
|
+
"Content-Type": "application/json",
|
|
273
|
+
...getHeaders(options?.headers)
|
|
274
|
+
},
|
|
275
|
+
body: JSON.stringify(learningSelfRatingWrite)
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
const getLearningRateExercisePageMutationKey = () => ["learningRateExercisePage"];
|
|
279
|
+
const getLearningRateExercisePageMutationOptions = (options) => {
|
|
280
|
+
const mutationKey = getLearningRateExercisePageMutationKey();
|
|
281
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
282
|
+
...options,
|
|
283
|
+
mutation: {
|
|
284
|
+
...options.mutation,
|
|
285
|
+
mutationKey
|
|
286
|
+
}
|
|
287
|
+
} : {
|
|
288
|
+
mutation: { mutationKey },
|
|
289
|
+
request: void 0
|
|
290
|
+
};
|
|
291
|
+
const mutationFn = (props) => {
|
|
292
|
+
const { attemptId, pageKey, data } = props ?? {};
|
|
293
|
+
return learningRateExercisePage(attemptId, pageKey, data, requestOptions);
|
|
294
|
+
};
|
|
295
|
+
return {
|
|
296
|
+
mutationFn,
|
|
297
|
+
...mutationOptions
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* @summary Save a private exercise-page self-rating
|
|
302
|
+
*/
|
|
303
|
+
const useLearningRateExercisePage = (options, queryClient) => {
|
|
304
|
+
return useMutation(getLearningRateExercisePageMutationOptions(options), queryClient);
|
|
305
|
+
};
|
|
306
|
+
const getLearningReserveExerciseUploadUrl = (attemptId, questionKey) => {
|
|
307
|
+
return `/learning/attempts/${attemptId}/questions/${questionKey}/uploads`;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Requires the effective profile's in-progress, unexpired native attempt and a reflection question configured for upload or text_or_upload. The MIME type must map to one of that question's allowedUploadKinds; exercise files are limited to 50 MiB (WebVTT remains limited to 2 MiB). Reserve, PUT the exact bytes to uploadUrl, then submit response.assetId using the answer operation. The uploaded asset remains scoped to this profile, attempt and question; reservation alone does not answer it.
|
|
311
|
+
* @summary Reserve a private uploaded reflection answer
|
|
312
|
+
*/
|
|
313
|
+
const learningReserveExerciseUpload = async (attemptId, questionKey, learningUploadWrite, options) => {
|
|
314
|
+
const getHeaders = (h) => {
|
|
315
|
+
if (!h) return {};
|
|
316
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
317
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
318
|
+
const headers = {};
|
|
319
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
320
|
+
return headers;
|
|
321
|
+
};
|
|
322
|
+
return request(getLearningReserveExerciseUploadUrl(attemptId, questionKey), {
|
|
323
|
+
...options,
|
|
324
|
+
method: "POST",
|
|
325
|
+
headers: {
|
|
326
|
+
"Content-Type": "application/json",
|
|
327
|
+
...getHeaders(options?.headers)
|
|
328
|
+
},
|
|
329
|
+
body: JSON.stringify(learningUploadWrite)
|
|
330
|
+
});
|
|
331
|
+
};
|
|
332
|
+
const getLearningReserveExerciseUploadMutationKey = () => ["learningReserveExerciseUpload"];
|
|
333
|
+
const getLearningReserveExerciseUploadMutationOptions = (options) => {
|
|
334
|
+
const mutationKey = getLearningReserveExerciseUploadMutationKey();
|
|
335
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
336
|
+
...options,
|
|
337
|
+
mutation: {
|
|
338
|
+
...options.mutation,
|
|
339
|
+
mutationKey
|
|
340
|
+
}
|
|
341
|
+
} : {
|
|
342
|
+
mutation: { mutationKey },
|
|
343
|
+
request: void 0
|
|
344
|
+
};
|
|
345
|
+
const mutationFn = (props) => {
|
|
346
|
+
const { attemptId, questionKey, data } = props ?? {};
|
|
347
|
+
return learningReserveExerciseUpload(attemptId, questionKey, data, requestOptions);
|
|
348
|
+
};
|
|
349
|
+
return {
|
|
350
|
+
mutationFn,
|
|
351
|
+
...mutationOptions
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
/**
|
|
355
|
+
* @summary Reserve a private uploaded reflection answer
|
|
356
|
+
*/
|
|
357
|
+
const useLearningReserveExerciseUpload = (options, queryClient) => {
|
|
358
|
+
return useMutation(getLearningReserveExerciseUploadMutationOptions(options), queryClient);
|
|
359
|
+
};
|
|
360
|
+
const getLearningReadAttemptResourceUrl = (attemptId, assetId) => {
|
|
361
|
+
return `/learning/attempts/${attemptId}/resources/${assetId}`;
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* Checks the profile's ownership and retained assessment context. Permits selected question/page media, allowed choice media and public hints. Correction resources become available after completion/expiry or after the corresponding answer when immediate feedback is configured. A submitted reflection upload is accessible only through its owning attempt and question. Resource IDs outside this authorized set return 404; returned delivery URLs may expire.
|
|
365
|
+
* @summary Resolve a resource authorized by the owned attempt
|
|
366
|
+
*/
|
|
367
|
+
const learningReadAttemptResource = async (attemptId, assetId, options) => {
|
|
368
|
+
return request(getLearningReadAttemptResourceUrl(attemptId, assetId), {
|
|
369
|
+
...options,
|
|
370
|
+
method: "GET"
|
|
371
|
+
});
|
|
372
|
+
};
|
|
373
|
+
const getLearningReadAttemptResourceQueryKey = (attemptId, assetId) => {
|
|
374
|
+
return [`/learning/attempts/${attemptId}/resources/${assetId}`];
|
|
375
|
+
};
|
|
376
|
+
const getLearningReadAttemptResourceQueryOptions = (attemptId, assetId, options) => {
|
|
377
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
378
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadAttemptResourceQueryKey(attemptId, assetId);
|
|
379
|
+
const queryFn = ({ signal }) => learningReadAttemptResource(attemptId, assetId, {
|
|
380
|
+
signal,
|
|
381
|
+
...requestOptions
|
|
382
|
+
});
|
|
383
|
+
return {
|
|
384
|
+
queryKey,
|
|
385
|
+
queryFn,
|
|
386
|
+
enabled: attemptId !== null && attemptId !== void 0 && assetId !== null && assetId !== void 0,
|
|
387
|
+
...queryOptions
|
|
388
|
+
};
|
|
389
|
+
};
|
|
390
|
+
/**
|
|
391
|
+
* @summary Resolve a resource authorized by the owned attempt
|
|
392
|
+
*/
|
|
393
|
+
function useLearningReadAttemptResource(attemptId, assetId, options, queryClient) {
|
|
394
|
+
const queryOptions = getLearningReadAttemptResourceQueryOptions(attemptId, assetId, options);
|
|
395
|
+
const query = useQuery(queryOptions, queryClient);
|
|
396
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
397
|
+
}
|
|
398
|
+
const getLearningReserveCourseUploadUrl = (courseId) => {
|
|
399
|
+
return `/learning/author/courses/${courseId}/uploads`;
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* Requires edit authority on courseId. Reserves one immutable file with an exact byte count and declared MIME type for 15 minutes. Course files are limited to 200 MiB; WebVTT captions to 2 MiB. At most ten unexpired pending uploads may exist per profile. Send the raw bytes with authenticated PUT to uploadUrl, then use its returned assetId in the course definition. Each reservation request creates a new reservation.
|
|
403
|
+
* @summary Reserve a file upload for course authoring
|
|
404
|
+
*/
|
|
405
|
+
const learningReserveCourseUpload = async (courseId, learningUploadWrite, options) => {
|
|
406
|
+
const getHeaders = (h) => {
|
|
407
|
+
if (!h) return {};
|
|
408
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
409
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
410
|
+
const headers = {};
|
|
411
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
412
|
+
return headers;
|
|
413
|
+
};
|
|
414
|
+
return request(getLearningReserveCourseUploadUrl(courseId), {
|
|
415
|
+
...options,
|
|
416
|
+
method: "POST",
|
|
417
|
+
headers: {
|
|
418
|
+
"Content-Type": "application/json",
|
|
419
|
+
...getHeaders(options?.headers)
|
|
420
|
+
},
|
|
421
|
+
body: JSON.stringify(learningUploadWrite)
|
|
422
|
+
});
|
|
423
|
+
};
|
|
424
|
+
const getLearningReserveCourseUploadMutationKey = () => ["learningReserveCourseUpload"];
|
|
425
|
+
const getLearningReserveCourseUploadMutationOptions = (options) => {
|
|
426
|
+
const mutationKey = getLearningReserveCourseUploadMutationKey();
|
|
427
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
428
|
+
...options,
|
|
429
|
+
mutation: {
|
|
430
|
+
...options.mutation,
|
|
431
|
+
mutationKey
|
|
432
|
+
}
|
|
433
|
+
} : {
|
|
434
|
+
mutation: { mutationKey },
|
|
435
|
+
request: void 0
|
|
436
|
+
};
|
|
437
|
+
const mutationFn = (props) => {
|
|
438
|
+
const { courseId, data } = props ?? {};
|
|
439
|
+
return learningReserveCourseUpload(courseId, data, requestOptions);
|
|
440
|
+
};
|
|
441
|
+
return {
|
|
442
|
+
mutationFn,
|
|
443
|
+
...mutationOptions
|
|
444
|
+
};
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* @summary Reserve a file upload for course authoring
|
|
448
|
+
*/
|
|
449
|
+
const useLearningReserveCourseUpload = (options, queryClient) => {
|
|
450
|
+
return useMutation(getLearningReserveCourseUploadMutationOptions(options), queryClient);
|
|
451
|
+
};
|
|
452
|
+
const getLearningReadCertificateUrl = (certificateId) => {
|
|
453
|
+
return `/learning/certificates/${certificateId}`;
|
|
454
|
+
};
|
|
455
|
+
/**
|
|
456
|
+
* Returns the immutable recipient, course title, edition and issuance date recorded for this profile's certificate. Another profile's certificate is not visible. This read does not require opening a new course session; documentUrl identifies the separately authenticated PDF download.
|
|
457
|
+
* @summary Read an issued certificate owned by the profile
|
|
458
|
+
*/
|
|
459
|
+
const learningReadCertificate = async (certificateId, options) => {
|
|
460
|
+
return request(getLearningReadCertificateUrl(certificateId), {
|
|
461
|
+
...options,
|
|
462
|
+
method: "GET"
|
|
463
|
+
});
|
|
464
|
+
};
|
|
465
|
+
const getLearningReadCertificateQueryKey = (certificateId) => {
|
|
466
|
+
return [`/learning/certificates/${certificateId}`];
|
|
467
|
+
};
|
|
468
|
+
const getLearningReadCertificateQueryOptions = (certificateId, options) => {
|
|
469
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
470
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadCertificateQueryKey(certificateId);
|
|
471
|
+
const queryFn = ({ signal }) => learningReadCertificate(certificateId, {
|
|
472
|
+
signal,
|
|
473
|
+
...requestOptions
|
|
474
|
+
});
|
|
475
|
+
return {
|
|
476
|
+
queryKey,
|
|
477
|
+
queryFn,
|
|
478
|
+
enabled: certificateId !== null && certificateId !== void 0,
|
|
479
|
+
...queryOptions
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
/**
|
|
483
|
+
* @summary Read an issued certificate owned by the profile
|
|
484
|
+
*/
|
|
485
|
+
function useLearningReadCertificate(certificateId, options, queryClient) {
|
|
486
|
+
const queryOptions = getLearningReadCertificateQueryOptions(certificateId, options);
|
|
487
|
+
const query = useQuery(queryOptions, queryClient);
|
|
488
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
489
|
+
}
|
|
490
|
+
const getLearningDownloadCertificateUrl = (certificateId) => {
|
|
491
|
+
return `/learning/certificates/${certificateId}/document`;
|
|
492
|
+
};
|
|
493
|
+
/**
|
|
494
|
+
* Renders the certificate's retained recipient name, course title and issuance evidence as a PDF attachment. Only the effective profile that owns the certificate can download it. The successful response is application/pdf bytes with Content-Disposition attachment and private, no-store caching; it has no JSON body.
|
|
495
|
+
* @summary Download an owned completion certificate as PDF
|
|
496
|
+
*/
|
|
497
|
+
const learningDownloadCertificate = async (certificateId, options) => {
|
|
498
|
+
return request(getLearningDownloadCertificateUrl(certificateId), {
|
|
499
|
+
...options,
|
|
500
|
+
method: "GET"
|
|
501
|
+
});
|
|
502
|
+
};
|
|
503
|
+
const getLearningDownloadCertificateQueryKey = (certificateId) => {
|
|
504
|
+
return [`/learning/certificates/${certificateId}/document`];
|
|
505
|
+
};
|
|
506
|
+
const getLearningDownloadCertificateQueryOptions = (certificateId, options) => {
|
|
507
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
508
|
+
const queryKey = queryOptions?.queryKey ?? getLearningDownloadCertificateQueryKey(certificateId);
|
|
509
|
+
const queryFn = ({ signal }) => learningDownloadCertificate(certificateId, {
|
|
510
|
+
signal,
|
|
511
|
+
...requestOptions
|
|
512
|
+
});
|
|
513
|
+
return {
|
|
514
|
+
queryKey,
|
|
515
|
+
queryFn,
|
|
516
|
+
enabled: certificateId !== null && certificateId !== void 0,
|
|
517
|
+
...queryOptions
|
|
518
|
+
};
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* @summary Download an owned completion certificate as PDF
|
|
522
|
+
*/
|
|
523
|
+
function useLearningDownloadCertificate(certificateId, options, queryClient) {
|
|
524
|
+
const queryOptions = getLearningDownloadCertificateQueryOptions(certificateId, options);
|
|
525
|
+
const query = useQuery(queryOptions, queryClient);
|
|
526
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
527
|
+
}
|
|
528
|
+
const getLearningReadCourseUrl = (courseId) => {
|
|
529
|
+
return `/learning/courses/${courseId}`;
|
|
530
|
+
};
|
|
531
|
+
/**
|
|
532
|
+
* Returns the effective profile's enrolled edition, or the latest published edition before enrollment. Eligibility uses the shared profile, age, category and entitlement rules; an allowed preview may expose the outline with hasFullAccess=false. This GET creates no enrollment or reading session. Check upgradeAvailable and latestRevisionId before offering an explicit edition upgrade. Lesson progress and final assessment IDs are included only with full access.
|
|
533
|
+
* @summary Read the selected course edition and progress
|
|
534
|
+
*/
|
|
535
|
+
const learningReadCourse = async (courseId, options) => {
|
|
536
|
+
return request(getLearningReadCourseUrl(courseId), {
|
|
537
|
+
...options,
|
|
538
|
+
method: "GET"
|
|
539
|
+
});
|
|
540
|
+
};
|
|
541
|
+
const getLearningReadCourseQueryKey = (courseId) => {
|
|
542
|
+
return [`/learning/courses/${courseId}`];
|
|
543
|
+
};
|
|
544
|
+
const getLearningReadCourseQueryOptions = (courseId, options) => {
|
|
545
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
546
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadCourseQueryKey(courseId);
|
|
547
|
+
const queryFn = ({ signal }) => learningReadCourse(courseId, {
|
|
548
|
+
signal,
|
|
549
|
+
...requestOptions
|
|
550
|
+
});
|
|
551
|
+
return {
|
|
552
|
+
queryKey,
|
|
553
|
+
queryFn,
|
|
554
|
+
enabled: courseId !== null && courseId !== void 0,
|
|
555
|
+
...queryOptions
|
|
556
|
+
};
|
|
557
|
+
};
|
|
558
|
+
/**
|
|
559
|
+
* @summary Read the selected course edition and progress
|
|
560
|
+
*/
|
|
561
|
+
function useLearningReadCourse(courseId, options, queryClient) {
|
|
562
|
+
const queryOptions = getLearningReadCourseQueryOptions(courseId, options);
|
|
563
|
+
const query = useQuery(queryOptions, queryClient);
|
|
564
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
565
|
+
}
|
|
566
|
+
const getLearningIssueCertificateUrl = (courseId) => {
|
|
567
|
+
return `/learning/courses/${courseId}/certificate`;
|
|
568
|
+
};
|
|
569
|
+
/**
|
|
570
|
+
* Requires an existing current enrollment in a course with certification enabled. Recomputes evidence: every required lesson must be complete and every required assessment passed. Creates one certificate per profile and edition, retaining recipient name and course title as issued; repeating issuance returns the existing certificate. Evidence can support issuance without a new reading session. Use documentUrl to download the PDF.
|
|
571
|
+
* @summary Issue the profile's course completion certificate
|
|
572
|
+
*/
|
|
573
|
+
const learningIssueCertificate = async (courseId, options) => {
|
|
574
|
+
return request(getLearningIssueCertificateUrl(courseId), {
|
|
575
|
+
...options,
|
|
576
|
+
method: "POST"
|
|
577
|
+
});
|
|
578
|
+
};
|
|
579
|
+
const getLearningIssueCertificateMutationKey = () => ["learningIssueCertificate"];
|
|
580
|
+
const getLearningIssueCertificateMutationOptions = (options) => {
|
|
581
|
+
const mutationKey = getLearningIssueCertificateMutationKey();
|
|
582
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
583
|
+
...options,
|
|
584
|
+
mutation: {
|
|
585
|
+
...options.mutation,
|
|
586
|
+
mutationKey
|
|
587
|
+
}
|
|
588
|
+
} : {
|
|
589
|
+
mutation: { mutationKey },
|
|
590
|
+
request: void 0
|
|
591
|
+
};
|
|
592
|
+
const mutationFn = (props) => {
|
|
593
|
+
const { courseId } = props ?? {};
|
|
594
|
+
return learningIssueCertificate(courseId, requestOptions);
|
|
595
|
+
};
|
|
596
|
+
return {
|
|
597
|
+
mutationFn,
|
|
598
|
+
...mutationOptions
|
|
599
|
+
};
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* @summary Issue the profile's course completion certificate
|
|
603
|
+
*/
|
|
604
|
+
const useLearningIssueCertificate = (options, queryClient) => {
|
|
605
|
+
return useMutation(getLearningIssueCertificateMutationOptions(options), queryClient);
|
|
606
|
+
};
|
|
607
|
+
const getLearningEnrollUrl = (courseId) => {
|
|
608
|
+
return `/learning/courses/${courseId}/enrollment`;
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* Requires full access for the effective profile. Creates a current enrollment pinned to the published edition if none exists; otherwise retains the selected edition and progress. archived controls the reader's personal archive preference. Repeating the same preference does not duplicate enrollment. Opening a reading session is a separate explicit step.
|
|
612
|
+
* @summary Enroll in the course or set its archive preference
|
|
613
|
+
*/
|
|
614
|
+
const learningEnroll = async (courseId, courseEnrollmentWrite, options) => {
|
|
615
|
+
const getHeaders = (h) => {
|
|
616
|
+
if (!h) return {};
|
|
617
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
618
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
619
|
+
const headers = {};
|
|
620
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
621
|
+
return headers;
|
|
622
|
+
};
|
|
623
|
+
return request(getLearningEnrollUrl(courseId), {
|
|
624
|
+
...options,
|
|
625
|
+
method: "PUT",
|
|
626
|
+
headers: {
|
|
627
|
+
"Content-Type": "application/json",
|
|
628
|
+
...getHeaders(options?.headers)
|
|
629
|
+
},
|
|
630
|
+
body: JSON.stringify(courseEnrollmentWrite)
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
const getLearningEnrollMutationKey = () => ["learningEnroll"];
|
|
634
|
+
const getLearningEnrollMutationOptions = (options) => {
|
|
635
|
+
const mutationKey = getLearningEnrollMutationKey();
|
|
636
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
637
|
+
...options,
|
|
638
|
+
mutation: {
|
|
639
|
+
...options.mutation,
|
|
640
|
+
mutationKey
|
|
641
|
+
}
|
|
642
|
+
} : {
|
|
643
|
+
mutation: { mutationKey },
|
|
644
|
+
request: void 0
|
|
645
|
+
};
|
|
646
|
+
const mutationFn = (props) => {
|
|
647
|
+
const { courseId, data } = props ?? {};
|
|
648
|
+
return learningEnroll(courseId, data, requestOptions);
|
|
649
|
+
};
|
|
650
|
+
return {
|
|
651
|
+
mutationFn,
|
|
652
|
+
...mutationOptions
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
/**
|
|
656
|
+
* @summary Enroll in the course or set its archive preference
|
|
657
|
+
*/
|
|
658
|
+
const useLearningEnroll = (options, queryClient) => {
|
|
659
|
+
return useMutation(getLearningEnrollMutationOptions(options), queryClient);
|
|
660
|
+
};
|
|
661
|
+
const getLearningReadEnrollmentHistoryUrl = (courseId, params) => {
|
|
662
|
+
const normalizedParams = new URLSearchParams();
|
|
663
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
664
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
665
|
+
});
|
|
666
|
+
const stringifiedParams = normalizedParams.toString();
|
|
667
|
+
return stringifiedParams.length > 0 ? `/learning/courses/${courseId}/enrollments?${stringifiedParams}` : `/learning/courses/${courseId}/enrollments`;
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* Requires current full course access and returns this profile's enrollments only, newest enrollment ID first. isCurrent identifies the selected edition; archived is a personal list preference independent of edition selection. Earlier progress and completedAt are preserved after an upgrade.
|
|
671
|
+
* @summary List the profile's course enrollments by edition
|
|
672
|
+
*/
|
|
673
|
+
const learningReadEnrollmentHistory = async (courseId, params, options) => {
|
|
674
|
+
return request(getLearningReadEnrollmentHistoryUrl(courseId, params), {
|
|
675
|
+
...options,
|
|
676
|
+
method: "GET"
|
|
677
|
+
});
|
|
678
|
+
};
|
|
679
|
+
const getLearningReadEnrollmentHistoryQueryKey = (courseId, params) => {
|
|
680
|
+
return [`/learning/courses/${courseId}/enrollments`, ...params ? [params] : []];
|
|
681
|
+
};
|
|
682
|
+
const getLearningReadEnrollmentHistoryQueryOptions = (courseId, params, options) => {
|
|
683
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
684
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadEnrollmentHistoryQueryKey(courseId, params);
|
|
685
|
+
const queryFn = ({ signal }) => learningReadEnrollmentHistory(courseId, params, {
|
|
686
|
+
signal,
|
|
687
|
+
...requestOptions
|
|
688
|
+
});
|
|
689
|
+
return {
|
|
690
|
+
queryKey,
|
|
691
|
+
queryFn,
|
|
692
|
+
enabled: courseId !== null && courseId !== void 0,
|
|
693
|
+
...queryOptions
|
|
694
|
+
};
|
|
695
|
+
};
|
|
696
|
+
/**
|
|
697
|
+
* @summary List the profile's course enrollments by edition
|
|
698
|
+
*/
|
|
699
|
+
function useLearningReadEnrollmentHistory(courseId, params, options, queryClient) {
|
|
700
|
+
const queryOptions = getLearningReadEnrollmentHistoryQueryOptions(courseId, params, options);
|
|
701
|
+
const query = useQuery(queryOptions, queryClient);
|
|
702
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
703
|
+
}
|
|
704
|
+
const getLearningStartSessionUrl = (courseId) => {
|
|
705
|
+
return `/learning/courses/${courseId}/sessions`;
|
|
706
|
+
};
|
|
707
|
+
/**
|
|
708
|
+
* Requires full course access, creates enrollment if needed and opens a shared consumption lease pinned to the selected edition. Generate requestKey once for the opening action and reuse it after uncertain network outcomes. The key is scoped to the effective profile: the same course returns its existing session, including a closed one; reuse for another course returns 409. Use a new key for a new reading session, then open a lesson with the returned sessionId.
|
|
709
|
+
* @summary Open an entitled course reading session
|
|
710
|
+
*/
|
|
711
|
+
const learningStartSession = async (courseId, learningSessionStartWrite, options) => {
|
|
712
|
+
const getHeaders = (h) => {
|
|
713
|
+
if (!h) return {};
|
|
714
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
715
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
716
|
+
const headers = {};
|
|
717
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
718
|
+
return headers;
|
|
719
|
+
};
|
|
720
|
+
return request(getLearningStartSessionUrl(courseId), {
|
|
721
|
+
...options,
|
|
722
|
+
method: "POST",
|
|
723
|
+
headers: {
|
|
724
|
+
"Content-Type": "application/json",
|
|
725
|
+
...getHeaders(options?.headers)
|
|
726
|
+
},
|
|
727
|
+
body: JSON.stringify(learningSessionStartWrite)
|
|
728
|
+
});
|
|
729
|
+
};
|
|
730
|
+
const getLearningStartSessionMutationKey = () => ["learningStartSession"];
|
|
731
|
+
const getLearningStartSessionMutationOptions = (options) => {
|
|
732
|
+
const mutationKey = getLearningStartSessionMutationKey();
|
|
733
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
734
|
+
...options,
|
|
735
|
+
mutation: {
|
|
736
|
+
...options.mutation,
|
|
737
|
+
mutationKey
|
|
738
|
+
}
|
|
739
|
+
} : {
|
|
740
|
+
mutation: { mutationKey },
|
|
741
|
+
request: void 0
|
|
742
|
+
};
|
|
743
|
+
const mutationFn = (props) => {
|
|
744
|
+
const { courseId, data } = props ?? {};
|
|
745
|
+
return learningStartSession(courseId, data, requestOptions);
|
|
746
|
+
};
|
|
747
|
+
return {
|
|
748
|
+
mutationFn,
|
|
749
|
+
...mutationOptions
|
|
750
|
+
};
|
|
751
|
+
};
|
|
752
|
+
/**
|
|
753
|
+
* @summary Open an entitled course reading session
|
|
754
|
+
*/
|
|
755
|
+
const useLearningStartSession = (options, queryClient) => {
|
|
756
|
+
return useMutation(getLearningStartSessionMutationOptions(options), queryClient);
|
|
757
|
+
};
|
|
758
|
+
const getLearningUpgradeCourseEditionUrl = (courseId) => {
|
|
759
|
+
return `/learning/courses/${courseId}/upgrade-edition`;
|
|
760
|
+
};
|
|
761
|
+
/**
|
|
762
|
+
* Requires full course access and an existing current enrollment. Send its revisionId as expectedRevisionId and latestRevisionId as targetRevisionId. Closes open course reading sessions, retains earlier enrollment and completion evidence, and selects the target edition without copying old lesson progress. Repeating the same target succeeds; stale expectations or a target other than the latest publication return 409.
|
|
763
|
+
* @summary Move enrollment to the latest published edition
|
|
764
|
+
*/
|
|
765
|
+
const learningUpgradeCourseEdition = async (courseId, courseEditionUpgradeWrite, options) => {
|
|
766
|
+
const getHeaders = (h) => {
|
|
767
|
+
if (!h) return {};
|
|
768
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
769
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
770
|
+
const headers = {};
|
|
771
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
772
|
+
return headers;
|
|
773
|
+
};
|
|
774
|
+
return request(getLearningUpgradeCourseEditionUrl(courseId), {
|
|
775
|
+
...options,
|
|
776
|
+
method: "POST",
|
|
777
|
+
headers: {
|
|
778
|
+
"Content-Type": "application/json",
|
|
779
|
+
...getHeaders(options?.headers)
|
|
780
|
+
},
|
|
781
|
+
body: JSON.stringify(courseEditionUpgradeWrite)
|
|
782
|
+
});
|
|
783
|
+
};
|
|
784
|
+
const getLearningUpgradeCourseEditionMutationKey = () => ["learningUpgradeCourseEdition"];
|
|
785
|
+
const getLearningUpgradeCourseEditionMutationOptions = (options) => {
|
|
786
|
+
const mutationKey = getLearningUpgradeCourseEditionMutationKey();
|
|
787
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
788
|
+
...options,
|
|
789
|
+
mutation: {
|
|
790
|
+
...options.mutation,
|
|
791
|
+
mutationKey
|
|
792
|
+
}
|
|
793
|
+
} : {
|
|
794
|
+
mutation: { mutationKey },
|
|
795
|
+
request: void 0
|
|
796
|
+
};
|
|
797
|
+
const mutationFn = (props) => {
|
|
798
|
+
const { courseId, data } = props ?? {};
|
|
799
|
+
return learningUpgradeCourseEdition(courseId, data, requestOptions);
|
|
800
|
+
};
|
|
801
|
+
return {
|
|
802
|
+
mutationFn,
|
|
803
|
+
...mutationOptions
|
|
804
|
+
};
|
|
805
|
+
};
|
|
806
|
+
/**
|
|
807
|
+
* @summary Move enrollment to the latest published edition
|
|
808
|
+
*/
|
|
809
|
+
const useLearningUpgradeCourseEdition = (options, queryClient) => {
|
|
810
|
+
return useMutation(getLearningUpgradeCourseEditionMutationOptions(options), queryClient);
|
|
811
|
+
};
|
|
812
|
+
const getLearningAnswerSelectionEvidenceUrl = (params) => {
|
|
813
|
+
const normalizedParams = new URLSearchParams();
|
|
814
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
815
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
816
|
+
});
|
|
817
|
+
const stringifiedParams = normalizedParams.toString();
|
|
818
|
+
return stringifiedParams.length > 0 ? `/learning/history/answer-selections?${stringifiedParams}` : `/learning/history/answer-selections`;
|
|
819
|
+
};
|
|
820
|
+
/**
|
|
821
|
+
* Returns evidence owned by the effective profile and rejects support impersonation. Resource identifiers do not authorize access to another learner. Source flags and counters are reported evidence, not newly computed grades. Missing dates, links and scoring remain null; a recorded completion flag does not establish a native pass result. attemptId selects an owned historical attempt; unlinkedOnly=true selects rows with no stored attempt link and cannot be combined with attemptId. Optional object filters apply within that same ownership scope. Results are ordered by history ID descending and paginated after filtering. questionId optionally filters by a local question mapping. choiceId, questionId, componentKey and attemptId may be incomplete. A null attemptId in the response does not create a synthetic attempt. Selection records reveal what was retained, without reconstructing correctness or scores.
|
|
822
|
+
* @summary List my historical answer selections
|
|
823
|
+
*/
|
|
824
|
+
const learningAnswerSelectionEvidence = async (params, options) => {
|
|
825
|
+
return request(getLearningAnswerSelectionEvidenceUrl(params), {
|
|
826
|
+
...options,
|
|
827
|
+
method: "GET"
|
|
828
|
+
});
|
|
829
|
+
};
|
|
830
|
+
const getLearningAnswerSelectionEvidenceQueryKey = (params) => {
|
|
831
|
+
return [`/learning/history/answer-selections`, ...params ? [params] : []];
|
|
832
|
+
};
|
|
833
|
+
const getLearningAnswerSelectionEvidenceQueryOptions = (params, options) => {
|
|
834
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
835
|
+
const queryKey = queryOptions?.queryKey ?? getLearningAnswerSelectionEvidenceQueryKey(params);
|
|
836
|
+
const queryFn = ({ signal }) => learningAnswerSelectionEvidence(params, {
|
|
837
|
+
signal,
|
|
838
|
+
...requestOptions
|
|
839
|
+
});
|
|
840
|
+
return {
|
|
841
|
+
queryKey,
|
|
842
|
+
queryFn,
|
|
843
|
+
...queryOptions
|
|
844
|
+
};
|
|
845
|
+
};
|
|
846
|
+
/**
|
|
847
|
+
* @summary List my historical answer selections
|
|
848
|
+
*/
|
|
849
|
+
function useLearningAnswerSelectionEvidence(params, options, queryClient) {
|
|
850
|
+
const queryOptions = getLearningAnswerSelectionEvidenceQueryOptions(params, options);
|
|
851
|
+
const query = useQuery(queryOptions, queryClient);
|
|
852
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
853
|
+
}
|
|
854
|
+
const getLearningAnswerSelectionDetailUrl = (historyId) => {
|
|
855
|
+
return `/learning/history/answer-selections/${historyId}`;
|
|
856
|
+
};
|
|
857
|
+
/**
|
|
858
|
+
* Returns evidence owned by the effective profile and rejects support impersonation. Resource identifiers do not authorize access to another learner. Source flags and counters are reported evidence, not newly computed grades. Missing dates, links and scoring remain null; a recorded completion flag does not establish a native pass result. historyId identifies a retained selection record rather than a current answer or question. Optional local mappings remain null when unavailable; no grade or completion date is inferred. The source selection's recorded creation timestamp is returned as stored.
|
|
859
|
+
* @summary Read my historical answer selection
|
|
860
|
+
*/
|
|
861
|
+
const learningAnswerSelectionDetail = async (historyId, options) => {
|
|
862
|
+
return request(getLearningAnswerSelectionDetailUrl(historyId), {
|
|
863
|
+
...options,
|
|
864
|
+
method: "GET"
|
|
865
|
+
});
|
|
866
|
+
};
|
|
867
|
+
const getLearningAnswerSelectionDetailQueryKey = (historyId) => {
|
|
868
|
+
return [`/learning/history/answer-selections/${historyId}`];
|
|
869
|
+
};
|
|
870
|
+
const getLearningAnswerSelectionDetailQueryOptions = (historyId, options) => {
|
|
871
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
872
|
+
const queryKey = queryOptions?.queryKey ?? getLearningAnswerSelectionDetailQueryKey(historyId);
|
|
873
|
+
const queryFn = ({ signal }) => learningAnswerSelectionDetail(historyId, {
|
|
874
|
+
signal,
|
|
875
|
+
...requestOptions
|
|
876
|
+
});
|
|
877
|
+
return {
|
|
878
|
+
queryKey,
|
|
879
|
+
queryFn,
|
|
880
|
+
enabled: historyId !== null && historyId !== void 0,
|
|
881
|
+
...queryOptions
|
|
882
|
+
};
|
|
883
|
+
};
|
|
884
|
+
/**
|
|
885
|
+
* @summary Read my historical answer selection
|
|
886
|
+
*/
|
|
887
|
+
function useLearningAnswerSelectionDetail(historyId, options, queryClient) {
|
|
888
|
+
const queryOptions = getLearningAnswerSelectionDetailQueryOptions(historyId, options);
|
|
889
|
+
const query = useQuery(queryOptions, queryClient);
|
|
890
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
891
|
+
}
|
|
892
|
+
const getLearningListAttemptHistoryUrl = (params) => {
|
|
893
|
+
const normalizedParams = new URLSearchParams();
|
|
894
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
895
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
896
|
+
});
|
|
897
|
+
const stringifiedParams = normalizedParams.toString();
|
|
898
|
+
return stringifiedParams.length > 0 ? `/learning/history/attempts?${stringifiedParams}` : `/learning/history/attempts`;
|
|
899
|
+
};
|
|
900
|
+
/**
|
|
901
|
+
* Returns only the effective profile's attempts, ordered by startedAt descending then attemptId descending. assessment_id optionally filters this history; it never changes ownership. Historical records are retained evidence and cannot be resumed. Scores are percentages serialized as decimal strings; null means no score is available.
|
|
902
|
+
* @summary List the profile's native and historical attempts
|
|
903
|
+
*/
|
|
904
|
+
const learningListAttemptHistory = async (params, options) => {
|
|
905
|
+
return request(getLearningListAttemptHistoryUrl(params), {
|
|
906
|
+
...options,
|
|
907
|
+
method: "GET"
|
|
908
|
+
});
|
|
909
|
+
};
|
|
910
|
+
const getLearningListAttemptHistoryQueryKey = (params) => {
|
|
911
|
+
return [`/learning/history/attempts`, ...params ? [params] : []];
|
|
912
|
+
};
|
|
913
|
+
const getLearningListAttemptHistoryQueryOptions = (params, options) => {
|
|
914
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
915
|
+
const queryKey = queryOptions?.queryKey ?? getLearningListAttemptHistoryQueryKey(params);
|
|
916
|
+
const queryFn = ({ signal }) => learningListAttemptHistory(params, {
|
|
917
|
+
signal,
|
|
918
|
+
...requestOptions
|
|
919
|
+
});
|
|
920
|
+
return {
|
|
921
|
+
queryKey,
|
|
922
|
+
queryFn,
|
|
923
|
+
...queryOptions
|
|
924
|
+
};
|
|
925
|
+
};
|
|
926
|
+
/**
|
|
927
|
+
* @summary List the profile's native and historical attempts
|
|
928
|
+
*/
|
|
929
|
+
function useLearningListAttemptHistory(params, options, queryClient) {
|
|
930
|
+
const queryOptions = getLearningListAttemptHistoryQueryOptions(params, options);
|
|
931
|
+
const query = useQuery(queryOptions, queryClient);
|
|
932
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
933
|
+
}
|
|
934
|
+
const getLearningAttemptEvidenceUrl = (attemptId) => {
|
|
935
|
+
return `/learning/history/attempts/${attemptId}/evidence`;
|
|
936
|
+
};
|
|
937
|
+
/**
|
|
938
|
+
* Returns evidence owned by the effective profile and rejects support impersonation. Resource identifiers do not authorize access to another learner. Source flags and counters are reported evidence, not newly computed grades. Missing dates, links and scoring remain null; a recorded completion flag does not establish a native pass result. attemptId must identify an historical attempt. evidenceBasis distinguishes source_master_session counters from a source_session success flag. Counts describe linked recorded rows, not a reconstructed test definition. startedAt is the recorded attempt timestamp; unavailable completion or expiry dates remain null.
|
|
939
|
+
* @summary Read my historical assessment attempt evidence
|
|
940
|
+
*/
|
|
941
|
+
const learningAttemptEvidence = async (attemptId, options) => {
|
|
942
|
+
return request(getLearningAttemptEvidenceUrl(attemptId), {
|
|
943
|
+
...options,
|
|
944
|
+
method: "GET"
|
|
945
|
+
});
|
|
946
|
+
};
|
|
947
|
+
const getLearningAttemptEvidenceQueryKey = (attemptId) => {
|
|
948
|
+
return [`/learning/history/attempts/${attemptId}/evidence`];
|
|
949
|
+
};
|
|
950
|
+
const getLearningAttemptEvidenceQueryOptions = (attemptId, options) => {
|
|
951
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
952
|
+
const queryKey = queryOptions?.queryKey ?? getLearningAttemptEvidenceQueryKey(attemptId);
|
|
953
|
+
const queryFn = ({ signal }) => learningAttemptEvidence(attemptId, {
|
|
954
|
+
signal,
|
|
955
|
+
...requestOptions
|
|
956
|
+
});
|
|
957
|
+
return {
|
|
958
|
+
queryKey,
|
|
959
|
+
queryFn,
|
|
960
|
+
enabled: attemptId !== null && attemptId !== void 0,
|
|
961
|
+
...queryOptions
|
|
962
|
+
};
|
|
963
|
+
};
|
|
964
|
+
/**
|
|
965
|
+
* @summary Read my historical assessment attempt evidence
|
|
966
|
+
*/
|
|
967
|
+
function useLearningAttemptEvidence(attemptId, options, queryClient) {
|
|
968
|
+
const queryOptions = getLearningAttemptEvidenceQueryOptions(attemptId, options);
|
|
969
|
+
const query = useQuery(queryOptions, queryClient);
|
|
970
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
971
|
+
}
|
|
972
|
+
const getLearningHistoricalSelectedPagesUrl = (attemptId, params) => {
|
|
973
|
+
const normalizedParams = new URLSearchParams();
|
|
974
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
975
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
976
|
+
});
|
|
977
|
+
const stringifiedParams = normalizedParams.toString();
|
|
978
|
+
return stringifiedParams.length > 0 ? `/learning/history/attempts/${attemptId}/selected-pages?${stringifiedParams}` : `/learning/history/attempts/${attemptId}/selected-pages`;
|
|
979
|
+
};
|
|
980
|
+
/**
|
|
981
|
+
* Returns evidence owned by the effective profile and rejects support impersonation. Resource identifiers do not authorize access to another learner. Lists the retained selected-page set, ordered by page ID and paginated with one-based page/limit. A selected page is evidence of inclusion, not proof it was viewed, answered or passed. Detailed page history is available separately. No questions or correct answers are reconstructed from this set.
|
|
982
|
+
* @summary List pages selected for my historical attempt
|
|
983
|
+
*/
|
|
984
|
+
const learningHistoricalSelectedPages = async (attemptId, params, options) => {
|
|
985
|
+
return request(getLearningHistoricalSelectedPagesUrl(attemptId, params), {
|
|
986
|
+
...options,
|
|
987
|
+
method: "GET"
|
|
988
|
+
});
|
|
989
|
+
};
|
|
990
|
+
const getLearningHistoricalSelectedPagesQueryKey = (attemptId, params) => {
|
|
991
|
+
return [`/learning/history/attempts/${attemptId}/selected-pages`, ...params ? [params] : []];
|
|
992
|
+
};
|
|
993
|
+
const getLearningHistoricalSelectedPagesQueryOptions = (attemptId, params, options) => {
|
|
994
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
995
|
+
const queryKey = queryOptions?.queryKey ?? getLearningHistoricalSelectedPagesQueryKey(attemptId, params);
|
|
996
|
+
const queryFn = ({ signal }) => learningHistoricalSelectedPages(attemptId, params, {
|
|
997
|
+
signal,
|
|
998
|
+
...requestOptions
|
|
999
|
+
});
|
|
1000
|
+
return {
|
|
1001
|
+
queryKey,
|
|
1002
|
+
queryFn,
|
|
1003
|
+
enabled: attemptId !== null && attemptId !== void 0,
|
|
1004
|
+
...queryOptions
|
|
1005
|
+
};
|
|
1006
|
+
};
|
|
1007
|
+
/**
|
|
1008
|
+
* @summary List pages selected for my historical attempt
|
|
1009
|
+
*/
|
|
1010
|
+
function useLearningHistoricalSelectedPages(attemptId, params, options, queryClient) {
|
|
1011
|
+
const queryOptions = getLearningHistoricalSelectedPagesQueryOptions(attemptId, params, options);
|
|
1012
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1013
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1014
|
+
}
|
|
1015
|
+
const getLearningPageEvidenceUrl = (params) => {
|
|
1016
|
+
const normalizedParams = new URLSearchParams();
|
|
1017
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
1018
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
1019
|
+
});
|
|
1020
|
+
const stringifiedParams = normalizedParams.toString();
|
|
1021
|
+
return stringifiedParams.length > 0 ? `/learning/history/pages?${stringifiedParams}` : `/learning/history/pages`;
|
|
1022
|
+
};
|
|
1023
|
+
/**
|
|
1024
|
+
* Returns evidence owned by the effective profile and rejects support impersonation. Resource identifiers do not authorize access to another learner. Source flags and counters are reported evidence, not newly computed grades. Missing dates, links and scoring remain null; a recorded completion flag does not establish a native pass result. attemptId selects an owned historical attempt; unlinkedOnly=true selects rows with no stored attempt link and cannot be combined with attemptId. Optional object filters apply within that same ownership scope. Results are ordered by history ID descending and paginated after filtering. pageId optionally narrows to one local page identity. A returned attemptId is exposed only when it links to an owned historical attempt. responseAvailable indicates retained response evidence, not whether the bounded detail endpoint will return its serialized bytes.
|
|
1025
|
+
* @summary List my recorded page evidence
|
|
1026
|
+
*/
|
|
1027
|
+
const learningPageEvidence = async (params, options) => {
|
|
1028
|
+
return request(getLearningPageEvidenceUrl(params), {
|
|
1029
|
+
...options,
|
|
1030
|
+
method: "GET"
|
|
1031
|
+
});
|
|
1032
|
+
};
|
|
1033
|
+
const getLearningPageEvidenceQueryKey = (params) => {
|
|
1034
|
+
return [`/learning/history/pages`, ...params ? [params] : []];
|
|
1035
|
+
};
|
|
1036
|
+
const getLearningPageEvidenceQueryOptions = (params, options) => {
|
|
1037
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1038
|
+
const queryKey = queryOptions?.queryKey ?? getLearningPageEvidenceQueryKey(params);
|
|
1039
|
+
const queryFn = ({ signal }) => learningPageEvidence(params, {
|
|
1040
|
+
signal,
|
|
1041
|
+
...requestOptions
|
|
1042
|
+
});
|
|
1043
|
+
return {
|
|
1044
|
+
queryKey,
|
|
1045
|
+
queryFn,
|
|
1046
|
+
...queryOptions
|
|
1047
|
+
};
|
|
1048
|
+
};
|
|
1049
|
+
/**
|
|
1050
|
+
* @summary List my recorded page evidence
|
|
1051
|
+
*/
|
|
1052
|
+
function useLearningPageEvidence(params, options, queryClient) {
|
|
1053
|
+
const queryOptions = getLearningPageEvidenceQueryOptions(params, options);
|
|
1054
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1055
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1056
|
+
}
|
|
1057
|
+
const getLearningPageEvidenceDetailUrl = (historyId) => {
|
|
1058
|
+
return `/learning/history/pages/${historyId}`;
|
|
1059
|
+
};
|
|
1060
|
+
/**
|
|
1061
|
+
* Returns evidence owned by the effective profile and rejects support impersonation. Resource identifiers do not authorize access to another learner. Source flags and counters are reported evidence, not newly computed grades. Missing dates, links and scoring remain null; a recorded completion flag does not establish a native pass result. Returns opaque PHP-serialized answer text only when retained as source master-selection evidence and at most 65,536 UTF-8 bytes. Larger responses retain encoding and byte count but set responseOmitted=true and serializedAnswers=null. A missing response instead has null encoding/count and responseOmitted=false. Source text is evidence, never a native answer request or trusted executable serialization.
|
|
1062
|
+
* @summary Read my historical page response evidence
|
|
1063
|
+
*/
|
|
1064
|
+
const learningPageEvidenceDetail = async (historyId, options) => {
|
|
1065
|
+
return request(getLearningPageEvidenceDetailUrl(historyId), {
|
|
1066
|
+
...options,
|
|
1067
|
+
method: "GET"
|
|
1068
|
+
});
|
|
1069
|
+
};
|
|
1070
|
+
const getLearningPageEvidenceDetailQueryKey = (historyId) => {
|
|
1071
|
+
return [`/learning/history/pages/${historyId}`];
|
|
1072
|
+
};
|
|
1073
|
+
const getLearningPageEvidenceDetailQueryOptions = (historyId, options) => {
|
|
1074
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1075
|
+
const queryKey = queryOptions?.queryKey ?? getLearningPageEvidenceDetailQueryKey(historyId);
|
|
1076
|
+
const queryFn = ({ signal }) => learningPageEvidenceDetail(historyId, {
|
|
1077
|
+
signal,
|
|
1078
|
+
...requestOptions
|
|
1079
|
+
});
|
|
1080
|
+
return {
|
|
1081
|
+
queryKey,
|
|
1082
|
+
queryFn,
|
|
1083
|
+
enabled: historyId !== null && historyId !== void 0,
|
|
1084
|
+
...queryOptions
|
|
1085
|
+
};
|
|
1086
|
+
};
|
|
1087
|
+
/**
|
|
1088
|
+
* @summary Read my historical page response evidence
|
|
1089
|
+
*/
|
|
1090
|
+
function useLearningPageEvidenceDetail(historyId, options, queryClient) {
|
|
1091
|
+
const queryOptions = getLearningPageEvidenceDetailQueryOptions(historyId, options);
|
|
1092
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1093
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1094
|
+
}
|
|
1095
|
+
const getLearningListScoreHistoryUrl = (params) => {
|
|
1096
|
+
const normalizedParams = new URLSearchParams();
|
|
1097
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
1098
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
1099
|
+
});
|
|
1100
|
+
const stringifiedParams = normalizedParams.toString();
|
|
1101
|
+
return stringifiedParams.length > 0 ? `/learning/history/scores?${stringifiedParams}` : `/learning/history/scores`;
|
|
1102
|
+
};
|
|
1103
|
+
/**
|
|
1104
|
+
* Returns one stored summary per assessment in the effective profile's history, newest creation time first with assessmentId as tie-breaker. A native completion replaces its assessment's summary; this is not a best-score leaderboard. An imported aggregate may have historical=true and attemptId=null because no attempt evidence exists. assessment_id restricts the list to that assessment.
|
|
1105
|
+
* @summary List the profile's assessment score summaries
|
|
1106
|
+
*/
|
|
1107
|
+
const learningListScoreHistory = async (params, options) => {
|
|
1108
|
+
return request(getLearningListScoreHistoryUrl(params), {
|
|
1109
|
+
...options,
|
|
1110
|
+
method: "GET"
|
|
1111
|
+
});
|
|
1112
|
+
};
|
|
1113
|
+
const getLearningListScoreHistoryQueryKey = (params) => {
|
|
1114
|
+
return [`/learning/history/scores`, ...params ? [params] : []];
|
|
1115
|
+
};
|
|
1116
|
+
const getLearningListScoreHistoryQueryOptions = (params, options) => {
|
|
1117
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1118
|
+
const queryKey = queryOptions?.queryKey ?? getLearningListScoreHistoryQueryKey(params);
|
|
1119
|
+
const queryFn = ({ signal }) => learningListScoreHistory(params, {
|
|
1120
|
+
signal,
|
|
1121
|
+
...requestOptions
|
|
1122
|
+
});
|
|
1123
|
+
return {
|
|
1124
|
+
queryKey,
|
|
1125
|
+
queryFn,
|
|
1126
|
+
...queryOptions
|
|
1127
|
+
};
|
|
1128
|
+
};
|
|
1129
|
+
/**
|
|
1130
|
+
* @summary List the profile's assessment score summaries
|
|
1131
|
+
*/
|
|
1132
|
+
function useLearningListScoreHistory(params, options, queryClient) {
|
|
1133
|
+
const queryOptions = getLearningListScoreHistoryQueryOptions(params, options);
|
|
1134
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1135
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1136
|
+
}
|
|
1137
|
+
const getLearningOpenLessonUrl = (lessonId) => {
|
|
1138
|
+
return `/learning/lessons/${lessonId}/open`;
|
|
1139
|
+
};
|
|
1140
|
+
/**
|
|
1141
|
+
* With sessionId, checks this profile's open course session and edition, renews its lease and selects the lesson for subsequent activity ticks. Without sessionId, both course previews and this lesson's freePreview must be enabled. Returns authorized media delivery URLs or HTML, public attachments and any vocabulary; corrections remain attempt-scoped. Delivery URLs may expire, so request fresh resources when reopening. A preview does not enroll the profile or record full-course consumption.
|
|
1142
|
+
* @summary Open lesson resources in a session or free preview
|
|
1143
|
+
*/
|
|
1144
|
+
const learningOpenLesson = async (lessonId, learningLessonOpenWrite, options) => {
|
|
1145
|
+
const getHeaders = (h) => {
|
|
1146
|
+
if (!h) return {};
|
|
1147
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
1148
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
1149
|
+
const headers = {};
|
|
1150
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
1151
|
+
return headers;
|
|
1152
|
+
};
|
|
1153
|
+
return request(getLearningOpenLessonUrl(lessonId), {
|
|
1154
|
+
...options,
|
|
1155
|
+
method: "POST",
|
|
1156
|
+
headers: {
|
|
1157
|
+
"Content-Type": "application/json",
|
|
1158
|
+
...getHeaders(options?.headers)
|
|
1159
|
+
},
|
|
1160
|
+
body: JSON.stringify(learningLessonOpenWrite)
|
|
1161
|
+
});
|
|
1162
|
+
};
|
|
1163
|
+
const getLearningOpenLessonMutationKey = () => ["learningOpenLesson"];
|
|
1164
|
+
const getLearningOpenLessonMutationOptions = (options) => {
|
|
1165
|
+
const mutationKey = getLearningOpenLessonMutationKey();
|
|
1166
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1167
|
+
...options,
|
|
1168
|
+
mutation: {
|
|
1169
|
+
...options.mutation,
|
|
1170
|
+
mutationKey
|
|
1171
|
+
}
|
|
1172
|
+
} : {
|
|
1173
|
+
mutation: { mutationKey },
|
|
1174
|
+
request: void 0
|
|
1175
|
+
};
|
|
1176
|
+
const mutationFn = (props) => {
|
|
1177
|
+
const { lessonId, data } = props ?? {};
|
|
1178
|
+
return learningOpenLesson(lessonId, data, requestOptions);
|
|
1179
|
+
};
|
|
1180
|
+
return {
|
|
1181
|
+
mutationFn,
|
|
1182
|
+
...mutationOptions
|
|
1183
|
+
};
|
|
1184
|
+
};
|
|
1185
|
+
/**
|
|
1186
|
+
* @summary Open lesson resources in a session or free preview
|
|
1187
|
+
*/
|
|
1188
|
+
const useLearningOpenLesson = (options, queryClient) => {
|
|
1189
|
+
return useMutation(getLearningOpenLessonMutationOptions(options), queryClient);
|
|
1190
|
+
};
|
|
1191
|
+
const getLearningUpdateProgressUrl = (lessonId) => {
|
|
1192
|
+
return `/learning/lessons/${lessonId}/progress`;
|
|
1193
|
+
};
|
|
1194
|
+
/**
|
|
1195
|
+
* Requires full access to the profile's selected course edition and creates enrollment if needed. Omit note to retain it; send null to clear it. positionSeconds is allowed only for resource lessons and cannot exceed a known duration. completed=true marks only a resource lesson complete; assessment and vocabulary lessons require their own completion workflow. Completion is retained on later completed=false writes. Updates the resume lesson and recomputes course progress from required lessons.
|
|
1196
|
+
* @summary Save lesson notes, playback position or resource completion
|
|
1197
|
+
*/
|
|
1198
|
+
const learningUpdateProgress = async (lessonId, lessonProgressWrite, options) => {
|
|
1199
|
+
const getHeaders = (h) => {
|
|
1200
|
+
if (!h) return {};
|
|
1201
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
1202
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
1203
|
+
const headers = {};
|
|
1204
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
1205
|
+
return headers;
|
|
1206
|
+
};
|
|
1207
|
+
return request(getLearningUpdateProgressUrl(lessonId), {
|
|
1208
|
+
...options,
|
|
1209
|
+
method: "PUT",
|
|
1210
|
+
headers: {
|
|
1211
|
+
"Content-Type": "application/json",
|
|
1212
|
+
...getHeaders(options?.headers)
|
|
1213
|
+
},
|
|
1214
|
+
body: JSON.stringify(lessonProgressWrite)
|
|
1215
|
+
});
|
|
1216
|
+
};
|
|
1217
|
+
const getLearningUpdateProgressMutationKey = () => ["learningUpdateProgress"];
|
|
1218
|
+
const getLearningUpdateProgressMutationOptions = (options) => {
|
|
1219
|
+
const mutationKey = getLearningUpdateProgressMutationKey();
|
|
1220
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1221
|
+
...options,
|
|
1222
|
+
mutation: {
|
|
1223
|
+
...options.mutation,
|
|
1224
|
+
mutationKey
|
|
1225
|
+
}
|
|
1226
|
+
} : {
|
|
1227
|
+
mutation: { mutationKey },
|
|
1228
|
+
request: void 0
|
|
1229
|
+
};
|
|
1230
|
+
const mutationFn = (props) => {
|
|
1231
|
+
const { lessonId, data } = props ?? {};
|
|
1232
|
+
return learningUpdateProgress(lessonId, data, requestOptions);
|
|
1233
|
+
};
|
|
1234
|
+
return {
|
|
1235
|
+
mutationFn,
|
|
1236
|
+
...mutationOptions
|
|
1237
|
+
};
|
|
1238
|
+
};
|
|
1239
|
+
/**
|
|
1240
|
+
* @summary Save lesson notes, playback position or resource completion
|
|
1241
|
+
*/
|
|
1242
|
+
const useLearningUpdateProgress = (options, queryClient) => {
|
|
1243
|
+
return useMutation(getLearningUpdateProgressMutationOptions(options), queryClient);
|
|
1244
|
+
};
|
|
1245
|
+
const getLearningPathIntroductionUrl = (pathId) => {
|
|
1246
|
+
return `/learning/paths/${pathId}/introduction`;
|
|
1247
|
+
};
|
|
1248
|
+
/**
|
|
1249
|
+
* Returns a delivery descriptor, not the media bytes. The path must be active and at least one of its steps visible through the effective profile's catalogue access. Follow the returned URL promptly; delivery URLs may be temporary.
|
|
1250
|
+
* @summary Get a visible path's introduction resource
|
|
1251
|
+
*/
|
|
1252
|
+
const learningPathIntroduction = async (pathId, options) => {
|
|
1253
|
+
return request(getLearningPathIntroductionUrl(pathId), {
|
|
1254
|
+
...options,
|
|
1255
|
+
method: "GET"
|
|
1256
|
+
});
|
|
1257
|
+
};
|
|
1258
|
+
const getLearningPathIntroductionQueryKey = (pathId) => {
|
|
1259
|
+
return [`/learning/paths/${pathId}/introduction`];
|
|
1260
|
+
};
|
|
1261
|
+
const getLearningPathIntroductionQueryOptions = (pathId, options) => {
|
|
1262
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1263
|
+
const queryKey = queryOptions?.queryKey ?? getLearningPathIntroductionQueryKey(pathId);
|
|
1264
|
+
const queryFn = ({ signal }) => learningPathIntroduction(pathId, {
|
|
1265
|
+
signal,
|
|
1266
|
+
...requestOptions
|
|
1267
|
+
});
|
|
1268
|
+
return {
|
|
1269
|
+
queryKey,
|
|
1270
|
+
queryFn,
|
|
1271
|
+
enabled: pathId !== null && pathId !== void 0,
|
|
1272
|
+
...queryOptions
|
|
1273
|
+
};
|
|
1274
|
+
};
|
|
1275
|
+
/**
|
|
1276
|
+
* @summary Get a visible path's introduction resource
|
|
1277
|
+
*/
|
|
1278
|
+
function useLearningPathIntroduction(pathId, options, queryClient) {
|
|
1279
|
+
const queryOptions = getLearningPathIntroductionQueryOptions(pathId, options);
|
|
1280
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1281
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1282
|
+
}
|
|
1283
|
+
const getLearningOpenPathStepUrl = (pathId) => {
|
|
1284
|
+
return `/learning/paths/${pathId}/open`;
|
|
1285
|
+
};
|
|
1286
|
+
/**
|
|
1287
|
+
* Sets the effective profile's current position to an active path's visible step, creating progress on first use. contentId must be a member of the path and pass existing catalogue visibility checks. This records navigation; the response is not a course reader payload. Support impersonation is rejected.
|
|
1288
|
+
* @summary Record my selected path step
|
|
1289
|
+
*/
|
|
1290
|
+
const learningOpenPathStep = async (pathId, learningPathOpenWrite, options) => {
|
|
1291
|
+
const getHeaders = (h) => {
|
|
1292
|
+
if (!h) return {};
|
|
1293
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
1294
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
1295
|
+
const headers = {};
|
|
1296
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
1297
|
+
return headers;
|
|
1298
|
+
};
|
|
1299
|
+
return request(getLearningOpenPathStepUrl(pathId), {
|
|
1300
|
+
...options,
|
|
1301
|
+
method: "POST",
|
|
1302
|
+
headers: {
|
|
1303
|
+
"Content-Type": "application/json",
|
|
1304
|
+
...getHeaders(options?.headers)
|
|
1305
|
+
},
|
|
1306
|
+
body: JSON.stringify(learningPathOpenWrite)
|
|
1307
|
+
});
|
|
1308
|
+
};
|
|
1309
|
+
const getLearningOpenPathStepMutationKey = () => ["learningOpenPathStep"];
|
|
1310
|
+
const getLearningOpenPathStepMutationOptions = (options) => {
|
|
1311
|
+
const mutationKey = getLearningOpenPathStepMutationKey();
|
|
1312
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1313
|
+
...options,
|
|
1314
|
+
mutation: {
|
|
1315
|
+
...options.mutation,
|
|
1316
|
+
mutationKey
|
|
1317
|
+
}
|
|
1318
|
+
} : {
|
|
1319
|
+
mutation: { mutationKey },
|
|
1320
|
+
request: void 0
|
|
1321
|
+
};
|
|
1322
|
+
const mutationFn = (props) => {
|
|
1323
|
+
const { pathId, data } = props ?? {};
|
|
1324
|
+
return learningOpenPathStep(pathId, data, requestOptions);
|
|
1325
|
+
};
|
|
1326
|
+
return {
|
|
1327
|
+
mutationFn,
|
|
1328
|
+
...mutationOptions
|
|
1329
|
+
};
|
|
1330
|
+
};
|
|
1331
|
+
/**
|
|
1332
|
+
* @summary Record my selected path step
|
|
1333
|
+
*/
|
|
1334
|
+
const useLearningOpenPathStep = (options, queryClient) => {
|
|
1335
|
+
return useMutation(getLearningOpenPathStepMutationOptions(options), queryClient);
|
|
1336
|
+
};
|
|
1337
|
+
const getLearningReadPathProgressUrl = (pathId) => {
|
|
1338
|
+
return `/learning/paths/${pathId}/progress`;
|
|
1339
|
+
};
|
|
1340
|
+
/**
|
|
1341
|
+
* Returns only the effective profile's recorded position and does not start the path. started=false means no progress row exists, including for an unknown path ID. position is zero-based. currentContentId is null when no recorded step is currently visible; a stored position may survive later curation changes.
|
|
1342
|
+
* @summary Read my current position in a path
|
|
1343
|
+
*/
|
|
1344
|
+
const learningReadPathProgress = async (pathId, options) => {
|
|
1345
|
+
return request(getLearningReadPathProgressUrl(pathId), {
|
|
1346
|
+
...options,
|
|
1347
|
+
method: "GET"
|
|
1348
|
+
});
|
|
1349
|
+
};
|
|
1350
|
+
const getLearningReadPathProgressQueryKey = (pathId) => {
|
|
1351
|
+
return [`/learning/paths/${pathId}/progress`];
|
|
1352
|
+
};
|
|
1353
|
+
const getLearningReadPathProgressQueryOptions = (pathId, options) => {
|
|
1354
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1355
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadPathProgressQueryKey(pathId);
|
|
1356
|
+
const queryFn = ({ signal }) => learningReadPathProgress(pathId, {
|
|
1357
|
+
signal,
|
|
1358
|
+
...requestOptions
|
|
1359
|
+
});
|
|
1360
|
+
return {
|
|
1361
|
+
queryKey,
|
|
1362
|
+
queryFn,
|
|
1363
|
+
enabled: pathId !== null && pathId !== void 0,
|
|
1364
|
+
...queryOptions
|
|
1365
|
+
};
|
|
1366
|
+
};
|
|
1367
|
+
/**
|
|
1368
|
+
* @summary Read my current position in a path
|
|
1369
|
+
*/
|
|
1370
|
+
function useLearningReadPathProgress(pathId, options, queryClient) {
|
|
1371
|
+
const queryOptions = getLearningReadPathProgressQueryOptions(pathId, options);
|
|
1372
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1373
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1374
|
+
}
|
|
1375
|
+
const getLearningCloseSessionUrl = (sessionId) => {
|
|
1376
|
+
return `/learning/sessions/${sessionId}`;
|
|
1377
|
+
};
|
|
1378
|
+
/**
|
|
1379
|
+
* Closes only a session owned by the effective profile and records closedAt. Repeating the close returns the same closed session. Enrollment, answers and lesson progress are retained; this operation does not mark a lesson complete.
|
|
1380
|
+
* @summary Close a course session and its consumption lease
|
|
1381
|
+
*/
|
|
1382
|
+
const learningCloseSession = async (sessionId, options) => {
|
|
1383
|
+
return request(getLearningCloseSessionUrl(sessionId), {
|
|
1384
|
+
...options,
|
|
1385
|
+
method: "DELETE"
|
|
1386
|
+
});
|
|
1387
|
+
};
|
|
1388
|
+
const getLearningCloseSessionMutationKey = () => ["learningCloseSession"];
|
|
1389
|
+
const getLearningCloseSessionMutationOptions = (options) => {
|
|
1390
|
+
const mutationKey = getLearningCloseSessionMutationKey();
|
|
1391
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1392
|
+
...options,
|
|
1393
|
+
mutation: {
|
|
1394
|
+
...options.mutation,
|
|
1395
|
+
mutationKey
|
|
1396
|
+
}
|
|
1397
|
+
} : {
|
|
1398
|
+
mutation: { mutationKey },
|
|
1399
|
+
request: void 0
|
|
1400
|
+
};
|
|
1401
|
+
const mutationFn = (props) => {
|
|
1402
|
+
const { sessionId } = props ?? {};
|
|
1403
|
+
return learningCloseSession(sessionId, requestOptions);
|
|
1404
|
+
};
|
|
1405
|
+
return {
|
|
1406
|
+
mutationFn,
|
|
1407
|
+
...mutationOptions
|
|
1408
|
+
};
|
|
1409
|
+
};
|
|
1410
|
+
/**
|
|
1411
|
+
* @summary Close a course session and its consumption lease
|
|
1412
|
+
*/
|
|
1413
|
+
const useLearningCloseSession = (options, queryClient) => {
|
|
1414
|
+
return useMutation(getLearningCloseSessionMutationOptions(options), queryClient);
|
|
1415
|
+
};
|
|
1416
|
+
const getLearningRecordActivityUrl = (sessionId) => {
|
|
1417
|
+
return `/learning/sessions/${sessionId}/activity`;
|
|
1418
|
+
};
|
|
1419
|
+
/**
|
|
1420
|
+
* Requires this profile's open session and the lesson most recently selected with the lesson-open operation. Renews the consumption lease. active=true records server-observed elapsed time since the previous heartbeat, capped at 60 seconds per tick; active=false moves the clock forward without adding time. activeSeconds is cumulative seconds, separate from lesson completion and playback position. Heartbeats have no request key; send them only for current activity.
|
|
1421
|
+
* @summary Record an activity heartbeat for the selected lesson
|
|
1422
|
+
*/
|
|
1423
|
+
const learningRecordActivity = async (sessionId, learningActivityWrite, options) => {
|
|
1424
|
+
const getHeaders = (h) => {
|
|
1425
|
+
if (!h) return {};
|
|
1426
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
1427
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
1428
|
+
const headers = {};
|
|
1429
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
1430
|
+
return headers;
|
|
1431
|
+
};
|
|
1432
|
+
return request(getLearningRecordActivityUrl(sessionId), {
|
|
1433
|
+
...options,
|
|
1434
|
+
method: "PUT",
|
|
1435
|
+
headers: {
|
|
1436
|
+
"Content-Type": "application/json",
|
|
1437
|
+
...getHeaders(options?.headers)
|
|
1438
|
+
},
|
|
1439
|
+
body: JSON.stringify(learningActivityWrite)
|
|
1440
|
+
});
|
|
1441
|
+
};
|
|
1442
|
+
const getLearningRecordActivityMutationKey = () => ["learningRecordActivity"];
|
|
1443
|
+
const getLearningRecordActivityMutationOptions = (options) => {
|
|
1444
|
+
const mutationKey = getLearningRecordActivityMutationKey();
|
|
1445
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1446
|
+
...options,
|
|
1447
|
+
mutation: {
|
|
1448
|
+
...options.mutation,
|
|
1449
|
+
mutationKey
|
|
1450
|
+
}
|
|
1451
|
+
} : {
|
|
1452
|
+
mutation: { mutationKey },
|
|
1453
|
+
request: void 0
|
|
1454
|
+
};
|
|
1455
|
+
const mutationFn = (props) => {
|
|
1456
|
+
const { sessionId, data } = props ?? {};
|
|
1457
|
+
return learningRecordActivity(sessionId, data, requestOptions);
|
|
1458
|
+
};
|
|
1459
|
+
return {
|
|
1460
|
+
mutationFn,
|
|
1461
|
+
...mutationOptions
|
|
1462
|
+
};
|
|
1463
|
+
};
|
|
1464
|
+
/**
|
|
1465
|
+
* @summary Record an activity heartbeat for the selected lesson
|
|
1466
|
+
*/
|
|
1467
|
+
const useLearningRecordActivity = (options, queryClient) => {
|
|
1468
|
+
return useMutation(getLearningRecordActivityMutationOptions(options), queryClient);
|
|
1469
|
+
};
|
|
1470
|
+
const getLearningUploadBytesUrl = (uploadId) => {
|
|
1471
|
+
return `/learning/uploads/${uploadId}/body`;
|
|
1472
|
+
};
|
|
1473
|
+
/**
|
|
1474
|
+
* Send an authenticated raw binary PUT, not multipart or JSON, to the reservation's uploadUrl before expiresAt. The byte count must exactly match sizeBytes; file signatures are checked against the reserved MIME type and captions must be valid UTF-8 WebVTT. Ownership and upload purpose are rechecked. A same-byte replay before expiry returns the existing immutable asset; different bytes cannot overwrite it. The JSON response contains the asset ID for a course definition or reflection answer, without issuing a delivery URL.
|
|
1475
|
+
* @summary Upload the exact bytes of a reserved file
|
|
1476
|
+
*/
|
|
1477
|
+
const learningUploadBytes = async (uploadId, learningUploadBytesBody, options) => {
|
|
1478
|
+
const getHeaders = (h) => {
|
|
1479
|
+
if (!h) return {};
|
|
1480
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
1481
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
1482
|
+
const headers = {};
|
|
1483
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
1484
|
+
return headers;
|
|
1485
|
+
};
|
|
1486
|
+
return request(getLearningUploadBytesUrl(uploadId), {
|
|
1487
|
+
...options,
|
|
1488
|
+
method: "PUT",
|
|
1489
|
+
headers: {
|
|
1490
|
+
"Content-Type": "application/octet-stream",
|
|
1491
|
+
...getHeaders(options?.headers)
|
|
1492
|
+
},
|
|
1493
|
+
body: learningUploadBytesBody
|
|
1494
|
+
});
|
|
1495
|
+
};
|
|
1496
|
+
const getLearningUploadBytesMutationKey = () => ["learningUploadBytes"];
|
|
1497
|
+
const getLearningUploadBytesMutationOptions = (options) => {
|
|
1498
|
+
const mutationKey = getLearningUploadBytesMutationKey();
|
|
1499
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1500
|
+
...options,
|
|
1501
|
+
mutation: {
|
|
1502
|
+
...options.mutation,
|
|
1503
|
+
mutationKey
|
|
1504
|
+
}
|
|
1505
|
+
} : {
|
|
1506
|
+
mutation: { mutationKey },
|
|
1507
|
+
request: void 0
|
|
1508
|
+
};
|
|
1509
|
+
const mutationFn = (props) => {
|
|
1510
|
+
const { uploadId, data } = props ?? {};
|
|
1511
|
+
return learningUploadBytes(uploadId, data, requestOptions);
|
|
1512
|
+
};
|
|
1513
|
+
return {
|
|
1514
|
+
mutationFn,
|
|
1515
|
+
...mutationOptions
|
|
1516
|
+
};
|
|
1517
|
+
};
|
|
1518
|
+
/**
|
|
1519
|
+
* @summary Upload the exact bytes of a reserved file
|
|
1520
|
+
*/
|
|
1521
|
+
const useLearningUploadBytes = (options, queryClient) => {
|
|
1522
|
+
return useMutation(getLearningUploadBytesMutationOptions(options), queryClient);
|
|
1523
|
+
};
|
|
1524
|
+
const getLearningReadVocabularyUrl = (vocabularyId, params) => {
|
|
1525
|
+
const normalizedParams = new URLSearchParams();
|
|
1526
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
1527
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
1528
|
+
});
|
|
1529
|
+
const stringifiedParams = normalizedParams.toString();
|
|
1530
|
+
return stringifiedParams.length > 0 ? `/learning/vocabularies/${vocabularyId}?${stringifiedParams}` : `/learning/vocabularies/${vocabularyId}`;
|
|
1531
|
+
};
|
|
1532
|
+
/**
|
|
1533
|
+
* lesson_id must identify a lesson using this vocabulary directly or as an attachment. Full reads return the profile's position and completion evidence. preview=true additionally requires that lesson's free-preview permission and omits saved personal progress. Entries are ordered by position then entry ID; term media IDs must be resolved through the vocabulary resource operation.
|
|
1534
|
+
* @summary Read vocabulary through an authorized lesson
|
|
1535
|
+
*/
|
|
1536
|
+
const learningReadVocabulary = async (vocabularyId, params, options) => {
|
|
1537
|
+
return request(getLearningReadVocabularyUrl(vocabularyId, params), {
|
|
1538
|
+
...options,
|
|
1539
|
+
method: "GET"
|
|
1540
|
+
});
|
|
1541
|
+
};
|
|
1542
|
+
const getLearningReadVocabularyQueryKey = (vocabularyId, params) => {
|
|
1543
|
+
return [`/learning/vocabularies/${vocabularyId}`, ...params ? [params] : []];
|
|
1544
|
+
};
|
|
1545
|
+
const getLearningReadVocabularyQueryOptions = (vocabularyId, params, options) => {
|
|
1546
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1547
|
+
const queryKey = queryOptions?.queryKey ?? getLearningReadVocabularyQueryKey(vocabularyId, params);
|
|
1548
|
+
const queryFn = ({ signal }) => learningReadVocabulary(vocabularyId, params, {
|
|
1549
|
+
signal,
|
|
1550
|
+
...requestOptions
|
|
1551
|
+
});
|
|
1552
|
+
return {
|
|
1553
|
+
queryKey,
|
|
1554
|
+
queryFn,
|
|
1555
|
+
enabled: vocabularyId !== null && vocabularyId !== void 0,
|
|
1556
|
+
...queryOptions
|
|
1557
|
+
};
|
|
1558
|
+
};
|
|
1559
|
+
/**
|
|
1560
|
+
* @summary Read vocabulary through an authorized lesson
|
|
1561
|
+
*/
|
|
1562
|
+
function useLearningReadVocabulary(vocabularyId, params, options, queryClient) {
|
|
1563
|
+
const queryOptions = getLearningReadVocabularyQueryOptions(vocabularyId, params, options);
|
|
1564
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1565
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1566
|
+
}
|
|
1567
|
+
const getLearningVocabularyResourceUrl = (vocabularyId, assetId, params) => {
|
|
1568
|
+
const normalizedParams = new URLSearchParams();
|
|
1569
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
1570
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
1571
|
+
});
|
|
1572
|
+
const stringifiedParams = normalizedParams.toString();
|
|
1573
|
+
return stringifiedParams.length > 0 ? `/learning/vocabularies/${vocabularyId}/assets/${assetId}?${stringifiedParams}` : `/learning/vocabularies/${vocabularyId}/assets/${assetId}`;
|
|
1574
|
+
};
|
|
1575
|
+
/**
|
|
1576
|
+
* Checks vocabulary and lesson context exactly as the vocabulary read operation, including preview permission when preview=true. assetId must be audio or image referenced by a term or translation in this vocabulary; knowing a media ID alone grants no access. Returns delivery metadata with a potentially expiring URL.
|
|
1577
|
+
* @summary Resolve a vocabulary term's audio or image
|
|
1578
|
+
*/
|
|
1579
|
+
const learningVocabularyResource = async (vocabularyId, assetId, params, options) => {
|
|
1580
|
+
return request(getLearningVocabularyResourceUrl(vocabularyId, assetId, params), {
|
|
1581
|
+
...options,
|
|
1582
|
+
method: "GET"
|
|
1583
|
+
});
|
|
1584
|
+
};
|
|
1585
|
+
const getLearningVocabularyResourceQueryKey = (vocabularyId, assetId, params) => {
|
|
1586
|
+
return [`/learning/vocabularies/${vocabularyId}/assets/${assetId}`, ...params ? [params] : []];
|
|
1587
|
+
};
|
|
1588
|
+
const getLearningVocabularyResourceQueryOptions = (vocabularyId, assetId, params, options) => {
|
|
1589
|
+
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
1590
|
+
const queryKey = queryOptions?.queryKey ?? getLearningVocabularyResourceQueryKey(vocabularyId, assetId, params);
|
|
1591
|
+
const queryFn = ({ signal }) => learningVocabularyResource(vocabularyId, assetId, params, {
|
|
1592
|
+
signal,
|
|
1593
|
+
...requestOptions
|
|
1594
|
+
});
|
|
1595
|
+
return {
|
|
1596
|
+
queryKey,
|
|
1597
|
+
queryFn,
|
|
1598
|
+
enabled: vocabularyId !== null && vocabularyId !== void 0 && assetId !== null && assetId !== void 0,
|
|
1599
|
+
...queryOptions
|
|
1600
|
+
};
|
|
1601
|
+
};
|
|
1602
|
+
/**
|
|
1603
|
+
* @summary Resolve a vocabulary term's audio or image
|
|
1604
|
+
*/
|
|
1605
|
+
function useLearningVocabularyResource(vocabularyId, assetId, params, options, queryClient) {
|
|
1606
|
+
const queryOptions = getLearningVocabularyResourceQueryOptions(vocabularyId, assetId, params, options);
|
|
1607
|
+
const query = useQuery(queryOptions, queryClient);
|
|
1608
|
+
return withQueryKey(query, queryOptions.queryKey);
|
|
1609
|
+
}
|
|
1610
|
+
const getLearningUpdateVocabularyUrl = (vocabularyId) => {
|
|
1611
|
+
return `/learning/vocabularies/${vocabularyId}/progress`;
|
|
1612
|
+
};
|
|
1613
|
+
/**
|
|
1614
|
+
* Requires full access through lessonId and creates course enrollment if needed. position is a cursor from 0 through the entry count; completed=true requires a nonempty vocabulary and position exactly equal to its entry count. Completion is retained on subsequent writes. Completing the lesson's primary vocabulary also completes that lesson; completing an attached vocabulary does not. Updates the resume lesson and recomputes required-lesson progress.
|
|
1615
|
+
* @summary Save vocabulary position or completion
|
|
1616
|
+
*/
|
|
1617
|
+
const learningUpdateVocabulary = async (vocabularyId, vocabularyProgressWrite, options) => {
|
|
1618
|
+
const getHeaders = (h) => {
|
|
1619
|
+
if (!h) return {};
|
|
1620
|
+
if (h instanceof Headers) return Object.fromEntries(h.entries());
|
|
1621
|
+
if (Symbol.iterator in h) return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
|
|
1622
|
+
const headers = {};
|
|
1623
|
+
for (const [name, value] of Object.entries(h)) if (value !== void 0) headers[name] = value;
|
|
1624
|
+
return headers;
|
|
1625
|
+
};
|
|
1626
|
+
return request(getLearningUpdateVocabularyUrl(vocabularyId), {
|
|
1627
|
+
...options,
|
|
1628
|
+
method: "PUT",
|
|
1629
|
+
headers: {
|
|
1630
|
+
"Content-Type": "application/json",
|
|
1631
|
+
...getHeaders(options?.headers)
|
|
1632
|
+
},
|
|
1633
|
+
body: JSON.stringify(vocabularyProgressWrite)
|
|
1634
|
+
});
|
|
1635
|
+
};
|
|
1636
|
+
const getLearningUpdateVocabularyMutationKey = () => ["learningUpdateVocabulary"];
|
|
1637
|
+
const getLearningUpdateVocabularyMutationOptions = (options) => {
|
|
1638
|
+
const mutationKey = getLearningUpdateVocabularyMutationKey();
|
|
1639
|
+
const { mutation: mutationOptions, request: requestOptions } = options ? options.mutation && "mutationKey" in options.mutation && options.mutation.mutationKey ? options : {
|
|
1640
|
+
...options,
|
|
1641
|
+
mutation: {
|
|
1642
|
+
...options.mutation,
|
|
1643
|
+
mutationKey
|
|
1644
|
+
}
|
|
1645
|
+
} : {
|
|
1646
|
+
mutation: { mutationKey },
|
|
1647
|
+
request: void 0
|
|
1648
|
+
};
|
|
1649
|
+
const mutationFn = (props) => {
|
|
1650
|
+
const { vocabularyId, data } = props ?? {};
|
|
1651
|
+
return learningUpdateVocabulary(vocabularyId, data, requestOptions);
|
|
1652
|
+
};
|
|
1653
|
+
return {
|
|
1654
|
+
mutationFn,
|
|
1655
|
+
...mutationOptions
|
|
1656
|
+
};
|
|
1657
|
+
};
|
|
1658
|
+
/**
|
|
1659
|
+
* @summary Save vocabulary position or completion
|
|
1660
|
+
*/
|
|
1661
|
+
const useLearningUpdateVocabulary = (options, queryClient) => {
|
|
1662
|
+
return useMutation(getLearningUpdateVocabularyMutationOptions(options), queryClient);
|
|
1663
|
+
};
|
|
1664
|
+
//#endregion
|
|
1665
|
+
export { getLearningAbandonAttemptMutationKey, getLearningAbandonAttemptMutationOptions, getLearningAbandonAttemptUrl, getLearningAnswerQuestionMutationKey, getLearningAnswerQuestionMutationOptions, getLearningAnswerQuestionUrl, getLearningAnswerSelectionDetailQueryKey, getLearningAnswerSelectionDetailQueryOptions, getLearningAnswerSelectionDetailUrl, getLearningAnswerSelectionEvidenceQueryKey, getLearningAnswerSelectionEvidenceQueryOptions, getLearningAnswerSelectionEvidenceUrl, getLearningAttemptEvidenceQueryKey, getLearningAttemptEvidenceQueryOptions, getLearningAttemptEvidenceUrl, getLearningCloseSessionMutationKey, getLearningCloseSessionMutationOptions, getLearningCloseSessionUrl, getLearningDownloadCertificateQueryKey, getLearningDownloadCertificateQueryOptions, getLearningDownloadCertificateUrl, getLearningEnrollMutationKey, getLearningEnrollMutationOptions, getLearningEnrollUrl, getLearningFinishAttemptMutationKey, getLearningFinishAttemptMutationOptions, getLearningFinishAttemptUrl, getLearningHistoricalSelectedPagesQueryKey, getLearningHistoricalSelectedPagesQueryOptions, getLearningHistoricalSelectedPagesUrl, getLearningIssueCertificateMutationKey, getLearningIssueCertificateMutationOptions, getLearningIssueCertificateUrl, getLearningListAttemptHistoryQueryKey, getLearningListAttemptHistoryQueryOptions, getLearningListAttemptHistoryUrl, getLearningListScoreHistoryQueryKey, getLearningListScoreHistoryQueryOptions, getLearningListScoreHistoryUrl, getLearningOpenLessonMutationKey, getLearningOpenLessonMutationOptions, getLearningOpenLessonUrl, getLearningOpenPathStepMutationKey, getLearningOpenPathStepMutationOptions, getLearningOpenPathStepUrl, getLearningPageEvidenceDetailQueryKey, getLearningPageEvidenceDetailQueryOptions, getLearningPageEvidenceDetailUrl, getLearningPageEvidenceQueryKey, getLearningPageEvidenceQueryOptions, getLearningPageEvidenceUrl, getLearningPathIntroductionQueryKey, getLearningPathIntroductionQueryOptions, getLearningPathIntroductionUrl, getLearningRateExercisePageMutationKey, getLearningRateExercisePageMutationOptions, getLearningRateExercisePageUrl, getLearningReadAttemptQueryKey, getLearningReadAttemptQueryOptions, getLearningReadAttemptResourceQueryKey, getLearningReadAttemptResourceQueryOptions, getLearningReadAttemptResourceUrl, getLearningReadAttemptUrl, getLearningReadCertificateQueryKey, getLearningReadCertificateQueryOptions, getLearningReadCertificateUrl, getLearningReadCourseQueryKey, getLearningReadCourseQueryOptions, getLearningReadCourseUrl, getLearningReadEnrollmentHistoryQueryKey, getLearningReadEnrollmentHistoryQueryOptions, getLearningReadEnrollmentHistoryUrl, getLearningReadPathProgressQueryKey, getLearningReadPathProgressQueryOptions, getLearningReadPathProgressUrl, getLearningReadVocabularyQueryKey, getLearningReadVocabularyQueryOptions, getLearningReadVocabularyUrl, getLearningRecordActivityMutationKey, getLearningRecordActivityMutationOptions, getLearningRecordActivityUrl, getLearningReserveCourseUploadMutationKey, getLearningReserveCourseUploadMutationOptions, getLearningReserveCourseUploadUrl, getLearningReserveExerciseUploadMutationKey, getLearningReserveExerciseUploadMutationOptions, getLearningReserveExerciseUploadUrl, getLearningStartAttemptMutationKey, getLearningStartAttemptMutationOptions, getLearningStartAttemptUrl, getLearningStartSessionMutationKey, getLearningStartSessionMutationOptions, getLearningStartSessionUrl, getLearningUpdateProgressMutationKey, getLearningUpdateProgressMutationOptions, getLearningUpdateProgressUrl, getLearningUpdateVocabularyMutationKey, getLearningUpdateVocabularyMutationOptions, getLearningUpdateVocabularyUrl, getLearningUpgradeCourseEditionMutationKey, getLearningUpgradeCourseEditionMutationOptions, getLearningUpgradeCourseEditionUrl, getLearningUploadBytesMutationKey, getLearningUploadBytesMutationOptions, getLearningUploadBytesUrl, getLearningVocabularyResourceQueryKey, getLearningVocabularyResourceQueryOptions, getLearningVocabularyResourceUrl, learningAbandonAttempt, learningAnswerQuestion, learningAnswerSelectionDetail, learningAnswerSelectionEvidence, learningAttemptEvidence, learningCloseSession, learningDownloadCertificate, learningEnroll, learningFinishAttempt, learningHistoricalSelectedPages, learningIssueCertificate, learningListAttemptHistory, learningListScoreHistory, learningOpenLesson, learningOpenPathStep, learningPageEvidence, learningPageEvidenceDetail, learningPathIntroduction, learningRateExercisePage, learningReadAttempt, learningReadAttemptResource, learningReadCertificate, learningReadCourse, learningReadEnrollmentHistory, learningReadPathProgress, learningReadVocabulary, learningRecordActivity, learningReserveCourseUpload, learningReserveExerciseUpload, learningStartAttempt, learningStartSession, learningUpdateProgress, learningUpdateVocabulary, learningUpgradeCourseEdition, learningUploadBytes, learningVocabularyResource, useLearningAbandonAttempt, useLearningAnswerQuestion, useLearningAnswerSelectionDetail, useLearningAnswerSelectionEvidence, useLearningAttemptEvidence, useLearningCloseSession, useLearningDownloadCertificate, useLearningEnroll, useLearningFinishAttempt, useLearningHistoricalSelectedPages, useLearningIssueCertificate, useLearningListAttemptHistory, useLearningListScoreHistory, useLearningOpenLesson, useLearningOpenPathStep, useLearningPageEvidence, useLearningPageEvidenceDetail, useLearningPathIntroduction, useLearningRateExercisePage, useLearningReadAttempt, useLearningReadAttemptResource, useLearningReadCertificate, useLearningReadCourse, useLearningReadEnrollmentHistory, useLearningReadPathProgress, useLearningReadVocabulary, useLearningRecordActivity, useLearningReserveCourseUpload, useLearningReserveExerciseUpload, useLearningStartAttempt, useLearningStartSession, useLearningUpdateProgress, useLearningUpdateVocabulary, useLearningUpgradeCourseEdition, useLearningUploadBytes, useLearningVocabularyResource };
|
|
1666
|
+
|
|
1667
|
+
//# sourceMappingURL=biblio-learning.js.map
|