Files
frontend-app-discussions/src/discussions/posts/data/api.js
Arunmozhi 14fe0d4ea5 feat: adds content area to browse learner contributions (#84)
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
2022-04-05 08:37:09 +00:00

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;
}