When the learners tab is enabled and is accessible, the contributions of a learner can be viewed by sorting them into Posts, Responses and Comments, by selecting a specific learner. This implements the new design of authored/reported tabs. https://openedx.atlassian.net/browse/TNL-8844
216 lines
5.5 KiB
JavaScript
216 lines
5.5 KiB
JavaScript
/* eslint-disable import/prefer-default-export */
|
|
import snakeCase from 'lodash.snakecase';
|
|
|
|
import { ensureConfig, getConfig, snakeCaseObject } from '@edx/frontend-platform';
|
|
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
|
|
|
ensureConfig([
|
|
'LMS_BASE_URL',
|
|
], 'Posts API service');
|
|
|
|
const apiBaseUrl = getConfig().LMS_BASE_URL;
|
|
|
|
export const threadsApiUrl = `${apiBaseUrl}/api/discussion/v1/threads/`;
|
|
export const coursesApiUrl = `${apiBaseUrl}/api/discussion/v1/courses/`;
|
|
|
|
/**
|
|
* Fetches all the threads in the given course and topic.
|
|
* @param {string} courseId
|
|
* @param {string} author
|
|
* @param {[string]} topicIds List of topics to limit threads to
|
|
* @param {number} page
|
|
* @param {number} pageSize
|
|
* @param {string} textSearch A search string to match.
|
|
* @param {ThreadOrdering} orderBy The results wil be sorted on this basis.
|
|
* @param {boolean} following If true, only threads followed by the current user will be returned.
|
|
* @param {boolean} flagged If true, only threads that have been reported will be returned.
|
|
* @param {string} threadType Can be 'discussion' or 'question'.
|
|
* @param {ThreadViewStatus} view Set to "unread" on "unanswered" to filter to only those statuses.
|
|
* @returns {Promise<{}>}
|
|
*/
|
|
export async function getThreads(
|
|
courseId, {
|
|
topicIds,
|
|
page,
|
|
pageSize,
|
|
textSearch,
|
|
orderBy,
|
|
following,
|
|
view,
|
|
author,
|
|
flagged,
|
|
threadType,
|
|
} = {},
|
|
) {
|
|
const params = snakeCaseObject({
|
|
courseId,
|
|
page,
|
|
pageSize,
|
|
topicId: topicIds && topicIds.join(','),
|
|
textSearch,
|
|
threadType,
|
|
orderBy: snakeCase(orderBy),
|
|
following,
|
|
view,
|
|
requestedFields: 'profile_image',
|
|
author,
|
|
flagged,
|
|
});
|
|
|
|
const { data } = await getAuthenticatedHttpClient().get(threadsApiUrl, { params });
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Fetches a single thread.
|
|
* @param {string} threadId
|
|
* @returns {Promise<{}>}
|
|
*/
|
|
export async function getThread(threadId) {
|
|
const params = { requested_fields: 'profile_image' };
|
|
const url = `${threadsApiUrl}${threadId}/`;
|
|
const { data } = await getAuthenticatedHttpClient().get(url, { params });
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Posts a new thread.
|
|
* @param {string} courseId
|
|
* @param {string} topicId
|
|
* @param {ThreadType} type The thread's type (either "question" or "discussion")
|
|
* @param {string} title
|
|
* @param {string} content
|
|
* @param {number} cohort
|
|
* @param {boolean} following Follow the thread after creating
|
|
* @param {boolean} anonymous Should the thread be anonymous to all users
|
|
* @param {boolean} anonymousToPeers Should the thread be anonymous to peers
|
|
* @returns {Promise<{}>}
|
|
*/
|
|
export async function postThread(
|
|
courseId,
|
|
topicId,
|
|
type,
|
|
title,
|
|
content,
|
|
{
|
|
following,
|
|
cohort,
|
|
anonymous,
|
|
anonymousToPeers,
|
|
} = {},
|
|
) {
|
|
const postData = snakeCaseObject({
|
|
courseId,
|
|
topicId,
|
|
type,
|
|
title,
|
|
raw_body: content,
|
|
following,
|
|
anonymous,
|
|
anonymousToPeers,
|
|
groupId: cohort,
|
|
});
|
|
|
|
const { data } = await getAuthenticatedHttpClient()
|
|
.post(threadsApiUrl, postData);
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Updates an existing thread.
|
|
* @param {string} threadId
|
|
* @param {string} topicId
|
|
* @param {ThreadType} type The thread's type (either "question" or "discussion")
|
|
* @param {string} title
|
|
* @param {string} content
|
|
* @param {boolean} flagged
|
|
* @param {boolean} voted
|
|
* @param {boolean} read
|
|
* @param {boolean} following
|
|
* @param {boolean} closed
|
|
* @param {boolean} pinned
|
|
* @param {string} editReasonCode
|
|
* @param {string} closeReasonCode
|
|
* @returns {Promise<{}>}
|
|
*/
|
|
export async function updateThread(threadId, {
|
|
flagged,
|
|
voted,
|
|
read,
|
|
topicId,
|
|
type,
|
|
title,
|
|
content,
|
|
following,
|
|
closed,
|
|
pinned,
|
|
editReasonCode,
|
|
closeReasonCode,
|
|
} = {}) {
|
|
const url = `${threadsApiUrl}${threadId}/`;
|
|
const patchData = snakeCaseObject({
|
|
topicId,
|
|
abuse_flagged: flagged,
|
|
voted,
|
|
read,
|
|
type,
|
|
title,
|
|
raw_body: content,
|
|
following,
|
|
closed,
|
|
pinned,
|
|
editReasonCode,
|
|
closeReasonCode,
|
|
});
|
|
const { data } = await getAuthenticatedHttpClient()
|
|
.patch(url, patchData, { headers: { 'Content-Type': 'application/merge-patch+json' } });
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Deletes a thread.
|
|
* @param {string} threadId
|
|
*/
|
|
export async function deleteThread(threadId) {
|
|
const url = `${threadsApiUrl}${threadId}/`;
|
|
await getAuthenticatedHttpClient()
|
|
.delete(url);
|
|
}
|
|
|
|
/**
|
|
* Upload a file.
|
|
* @param {Blob} blob The file body
|
|
* @param {string} filename
|
|
* @param {string} courseId
|
|
* @param {string} threadKey
|
|
* @returns {Promise<{ location: string }>}
|
|
*/
|
|
export async function uploadFile(blob, filename, courseId, threadKey) {
|
|
const uploadUrl = `${coursesApiUrl}${courseId}/upload`;
|
|
const formData = new FormData();
|
|
formData.append('thread_key', threadKey);
|
|
formData.append('uploaded_file', blob, filename);
|
|
const { data } = await getAuthenticatedHttpClient().post(uploadUrl, formData);
|
|
if (data.developer_message) {
|
|
throw new Error(data.developer_message);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Get the posts by a specific user in a course's discussions
|
|
*
|
|
* @param {string} courseId Course ID of the course
|
|
* @param {string} username Username of the user
|
|
* @returns API Response object in the format
|
|
* {
|
|
* results: [array of posts],
|
|
* pagination: {count, num_pages, next, previous}
|
|
* }
|
|
*/
|
|
export async function getUserPosts(courseId, username) {
|
|
const { data } = await getAuthenticatedHttpClient()
|
|
.get(threadsApiUrl, { params: { course_id: courseId, author: username } });
|
|
return data;
|
|
}
|