diff --git a/src/components/PeopleManagement/GroupDetailPage/DownloadCsvButton.jsx b/src/components/PeopleManagement/GroupDetailPage/DownloadCsvButton.jsx index 568f1d52f..20ef7d173 100644 --- a/src/components/PeopleManagement/GroupDetailPage/DownloadCsvButton.jsx +++ b/src/components/PeopleManagement/GroupDetailPage/DownloadCsvButton.jsx @@ -7,11 +7,13 @@ import { Toast, StatefulButton, Icon, Spinner, useToggle, } from '@openedx/paragon'; import { Download, Check } from '@openedx/paragon/icons'; -import { logError } from '@edx/frontend-platform/logging'; +import { jsonToCsv } from '../utils'; +import GeneralErrorModal from '../GeneralErrorModal'; -const DownloadCsvButton = ({ data, testId, fetchData }) => { +const DownloadCsvButton = ({ data, testId }) => { const [buttonState, setButtonState] = useState('pageLoading'); const [isOpen, open, close] = useToggle(false); + const [isErrorModalOpen, openErrorModal, closeErrorModal] = useToggle(false); const intl = useIntl(); useEffect(() => { @@ -28,18 +30,28 @@ const DownloadCsvButton = ({ data, testId, fetchData }) => { return `${year}-${month}-${day}-group-detail-report.csv`; }; + const createCsvData = (jsonData) => jsonToCsv(jsonData.map(row => ({ + Email: row.memberDetails.userEmail, + Username: row.memberDetails.userName, + Enrollments: row.enrollments, + // we have to strip out the comma so it doesn't mess up the csv parsing + 'Recent action': row.recent_action.replace(/,/g, ''), + }))); + const handleClick = async () => { setButtonState('pending'); - fetchData().then((response) => { - const blob = new Blob([response.data.results], { + try { + const csv = createCsvData(data); + const blob = new Blob([csv], { type: 'text/csv', }); saveAs(blob, getCsvFileName()); open(); + } catch { + openErrorModal(); + } finally { setButtonState('complete'); - }).catch((err) => { - logError(err); - }); + } }; const toastText = intl.formatMessage({ @@ -55,6 +67,10 @@ const DownloadCsvButton = ({ data, testId, fetchData }) => { {toastText} )} + { diff --git a/src/components/PeopleManagement/GroupDetailPage/GroupMembersTable.jsx b/src/components/PeopleManagement/GroupDetailPage/GroupMembersTable.jsx index d1320d18d..95cdcfea3 100644 --- a/src/components/PeopleManagement/GroupDetailPage/GroupMembersTable.jsx +++ b/src/components/PeopleManagement/GroupDetailPage/GroupMembersTable.jsx @@ -16,7 +16,6 @@ import { } from '../constants'; import RecentActionTableCell from '../RecentActionTableCell'; import DownloadCsvButton from './DownloadCsvButton'; -import LmsApiService from '../../../data/services/LmsApiService'; import RemoveMemberModal from './RemoveMemberModal'; import GeneralErrorModal from '../GeneralErrorModal'; @@ -91,11 +90,6 @@ const GroupMembersTable = ({ refresh, setRefresh, }) => { - const fetchCsvData = async () => LmsApiService.fetchEnterpriseGroupLearners( - groupUuid, - // { ...currentFilters, search: searchQuery }, - { csv: true }, - ); const intl = useIntl(); return ( @@ -169,7 +163,6 @@ const GroupMembersTable = ({ ]} tableActions={[ , diff --git a/src/components/PeopleManagement/RecentActionTableCell.jsx b/src/components/PeopleManagement/RecentActionTableCell.jsx index cbc2fb75b..f76d04152 100644 --- a/src/components/PeopleManagement/RecentActionTableCell.jsx +++ b/src/components/PeopleManagement/RecentActionTableCell.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import formatDates from './utils'; +import { formatDates } from './utils'; const RecentActionTableCell = ({ row, diff --git a/src/components/PeopleManagement/utils.js b/src/components/PeopleManagement/utils.js index 141d82600..93819161c 100644 --- a/src/components/PeopleManagement/utils.js +++ b/src/components/PeopleManagement/utils.js @@ -6,7 +6,19 @@ import dayjs from 'dayjs'; * @param {string} timestamp unformatted date timestamp * @returns Formatted date string for display. */ -export default function formatDates(timestamp) { +export function formatDates(timestamp) { const DATE_FORMAT = 'MMMM DD, YYYY'; return dayjs(timestamp).format(DATE_FORMAT); } + +export function jsonToCsv(data) { + let csv = ''; + const headers = Object.keys(data[0]); + csv += `${headers.join(',')}\n`; + + data.forEach((row) => { + const rows = headers.map(header => row[header]).join(','); + csv += `${rows}\n`; + }); + return csv; +}