Skip to content

Commit

Permalink
feat: adds segment tracking events to groups features
Browse files Browse the repository at this point in the history
feat: adds segment tracking events to groups features

feat: adds more tracking events
  • Loading branch information
katrinan029 committed Jan 31, 2025
1 parent 16c6a9f commit c913436
Show file tree
Hide file tree
Showing 14 changed files with 263 additions and 23 deletions.
15 changes: 11 additions & 4 deletions src/components/Admin/AdminSearchForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { Form } from '@openedx/paragon';
import { Info } from '@openedx/paragon/icons';

import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';

import SearchBar from '../SearchBar';
import { formatTimestamp, updateUrl } from '../../utils';
import IconWithTooltip from '../IconWithTooltip';
import { withLocation, withNavigate } from '../../hoc';
import EVENT_NAMES from '../../eventTracking';

class AdminSearchForm extends React.Component {
componentDidUpdate(prevProps) {
Expand All @@ -31,8 +33,8 @@ class AdminSearchForm extends React.Component {
} = prevProps;

if (searchQuery !== prevSearchQuery || searchCourseQuery !== prevSearchCourseQuery
|| searchDateQuery !== prevSearchDateQuery || searchBudgetQuery !== prevSearchBudgetQuery
|| searchGroupQuery !== prevSearchGroupQuery) {
|| searchDateQuery !== prevSearchDateQuery || searchBudgetQuery !== prevSearchBudgetQuery
|| searchGroupQuery !== prevSearchGroupQuery) {
this.handleSearch();
}
}
Expand Down Expand Up @@ -69,6 +71,11 @@ class AdminSearchForm extends React.Component {
page: 1,
};
updateUrl(navigate, location.pathname, updateParams);
sendEnterpriseTrackEvent(
this.props.enterpriseId,
EVENT_NAMES.LEARNER_PROGRESS_REPORT.FILTER_BY_GROUP_DROPDOWN,
{ group: event.target.value },
);
}

render() {
Expand All @@ -81,7 +88,6 @@ class AdminSearchForm extends React.Component {
searchCourseQuery, searchDateQuery, searchQuery, searchBudgetQuery, searchGroupQuery,
},
} = this.props;

const courseTitles = Array.from(new Set(tableData.map(en => en.course_title).sort()));
const courseDates = Array.from(new Set(tableData.map(en => en.course_start_date).sort().reverse()));
const columnWidth = (budgets?.length || groups?.length) ? 'col-md-3' : 'col-md-6';
Expand Down Expand Up @@ -252,7 +258,7 @@ class AdminSearchForm extends React.Component {
</Form.Control>
</Form.Group>
</div>
) : null }
) : null}
<div className={classNames('col-12 my-2 my-md-0 px-0 px-md-2 px-lg-3', columnWidth)}>
<Form.Label id="search-email-label" className="mb-2">
<FormattedMessage
Expand Down Expand Up @@ -305,6 +311,7 @@ AdminSearchForm.propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string,
}),
enterpriseId: PropTypes.string,
// injected
intl: intlShape.isRequired,
};
Expand Down
26 changes: 25 additions & 1 deletion src/components/PeopleManagement/CreateGroupModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ import { snakeCaseObject } from '@edx/frontend-platform/utils';
import {
ActionRow, Button, FullscreenModal, StatefulButton, useToggle,
} from '@openedx/paragon';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';

import LmsApiService from '../../data/services/LmsApiService';
import SystemErrorAlertModal from '../learner-credit-management/cards/assignment-allocation-status-modals/SystemErrorAlertModal';
import CreateGroupModalContent from './CreateGroupModalContent';
import { peopleManagementQueryKeys } from './constants';
import EVENT_NAMES from '../../eventTracking';

const CreateGroupModal = ({
isModalOpen,
Expand All @@ -24,6 +27,7 @@ const CreateGroupModal = ({
const [groupName, setGroupName] = useState('');
const [canCreateGroup, setCanCreateGroup] = useState(false);
const [canInviteMembers, setCanInviteMembers] = useState(false);
const [isCreateGroupFileUpload, setIsCreateGroupFileUpload] = useState(false);
const [isSystemErrorModalOpen, openSystemErrorModal, closeSystemErrorModal] = useToggle(false);
const handleCloseCreateGroupModal = () => {
closeModal();
Expand All @@ -38,13 +42,32 @@ const CreateGroupModal = ({
groupName,
};
let groupCreationResponse;

try {
groupCreationResponse = await LmsApiService.createEnterpriseGroup(options);
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.CREATE_GROUP_MODAL_BUTTON_SUBMIT,
{ status: 'success' },
);

if (isCreateGroupFileUpload) {
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.GROUP_CREATE_WITH_UPLOAD_CSV,
);
}
} catch (err) {
logError(err);
setCreateButtonState('error');
openSystemErrorModal();
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.CREATE_GROUP_MODAL_BUTTON_SUBMIT,
{
status: 'error',
message: err,
},
);
}

try {
Expand Down Expand Up @@ -114,6 +137,7 @@ const CreateGroupModal = ({
onEmailAddressesChange={handleEmailAddressesChange}
isGroupInvite
enterpriseUUID={enterpriseUUID}
setIsCreateGroupFileUpload={setIsCreateGroupFileUpload}
/>
</FullscreenModal>
<SystemErrorAlertModal
Expand Down
3 changes: 3 additions & 0 deletions src/components/PeopleManagement/CreateGroupModalContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useEnterpriseLearners } from '../learner-credit-management/data';

const CreateGroupModalContent = ({
onEmailAddressesChange,
setIsCreateGroupFileUpload,
onSetGroupName,
isGroupInvite,
enterpriseUUID,
Expand Down Expand Up @@ -138,6 +139,7 @@ const CreateGroupModalContent = ({
<FileUpload
memberInviteMetadata={memberInviteMetadata}
setEmailAddressesInputValue={setEmailAddressesInputValue}
setIsCreateGroupFileUpload={setIsCreateGroupFileUpload}
/>
</Col>
<Col>
Expand All @@ -161,6 +163,7 @@ CreateGroupModalContent.propTypes = {
onSetGroupName: PropTypes.func,
isGroupInvite: PropTypes.bool,
enterpriseUUID: PropTypes.string.isRequired,
setIsCreateGroupFileUpload: PropTypes.func,
};

export default CreateGroupModalContent;
32 changes: 30 additions & 2 deletions src/components/PeopleManagement/DownloadCSVButton.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import { connect } from 'react-redux';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';

import {
Icon, Spinner, StatefulButton, Toast, useToggle,
} from '@openedx/paragon';
import { Download, Check } from '@openedx/paragon/icons';
import { logError } from '@edx/frontend-platform/logging';
import { downloadCsv, getTimeStampedFilename } from '../../utils';
import EVENT_NAMES from '../../eventTracking';

const csvHeaders = ['Name', 'Email', 'Joined Organization', 'Enrollments'];

Expand All @@ -16,7 +19,12 @@ const dataEntryToRow = (entry) => {
return [name, email, joinedOrg, enrollments];
};

const DownloadCsvButton = ({ testId, fetchData, totalCt }) => {
const DownloadCsvButton = ({
enterpriseUUID,
testId,
fetchData,
totalCt,
}) => {
const [buttonState, setButtonState] = useState('pageLoading');
const [isToastOpen, openToast, closeToast] = useToggle(false);
const intl = useIntl();
Expand All @@ -34,8 +42,23 @@ const DownloadCsvButton = ({ testId, fetchData, totalCt }) => {
downloadCsv(fileName, response.results, csvHeaders, dataEntryToRow);
openToast();
setButtonState('complete');
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.DOWNLOAD_ALL_ORG_MEMBERS,
{
status: 'success',
},
);
}).catch((err) => {
logError(err);
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.DOWNLOAD_ALL_ORG_MEMBERS,
{
status: 'error',
message: err,
},
);
});
};

Expand Down Expand Up @@ -101,6 +124,11 @@ DownloadCsvButton.propTypes = {
fetchData: PropTypes.func.isRequired,
totalCt: PropTypes.number,
testId: PropTypes.string,
enterpriseUUID: PropTypes.string,
};

export default DownloadCsvButton;
const mapStateToProps = state => ({
enterpriseUUID: state.portalConfiguration.enterpriseId,
});

export default connect(mapStateToProps)(DownloadCsvButton);
19 changes: 17 additions & 2 deletions src/components/PeopleManagement/GroupDetailCard.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import PropTypes from 'prop-types';
import { useParams } from 'react-router';
import { connect } from 'react-redux';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';

import { Card, Hyperlink } from '@openedx/paragon';
import { ROUTE_NAMES } from '../EnterpriseApp/data/constants';
import EVENT_NAMES from '../../eventTracking';

const GroupDetailCard = ({ group }) => {
const GroupDetailCard = ({ enterpriseUUID, group }) => {
const { enterpriseSlug } = useParams();
return (
<Card className="group-detail-card">
Expand All @@ -15,6 +19,12 @@ const GroupDetailCard = ({ group }) => {
<Hyperlink
className="btn btn-outline-primary"
destination={`/${enterpriseSlug}/admin/${ROUTE_NAMES.peopleManagement}/${group.uuid}`}
onClick={() => {
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.VIEW_GROUP_PROGRESS_BUTTON,
);
}}
>
View group
</Hyperlink>
Expand All @@ -29,6 +39,11 @@ GroupDetailCard.propTypes = {
name: PropTypes.string.isRequired,
uuid: PropTypes.string.isRequired,
}).isRequired,
enterpriseUUID: PropTypes.string,
};

export default GroupDetailCard;
const mapStateToProps = state => ({
enterpriseUUID: state.portalConfiguration.enterpriseId,
});

export default connect(mapStateToProps)(GroupDetailCard);
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, useIntl } from '@edx/frontend-platform/i18n';
import { connect } from 'react-redux';

import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';
import {
Icon, IconButtonWithTooltip, Toast, useToggle,
} from '@openedx/paragon';
import { Download } from '@openedx/paragon/icons';
import { logError } from '@edx/frontend-platform/logging';
import GeneralErrorModal from '../GeneralErrorModal';
import { downloadCsv, getTimeStampedFilename } from '../../../utils';
import EVENT_NAMES from '../../../eventTracking';

const csvHeaders = ['Name', 'Email', 'Recent action', 'Enrollments'];

const DownloadCsvIconButton = ({
enterpriseUUID,
fetchAllData,
dataCount,
testId,
Expand Down Expand Up @@ -50,9 +54,22 @@ const DownloadCsvIconButton = ({
))) : response.results;
downloadCsv(fileName, selectedRowIdsToDownload, csvHeaders, dataEntryToRow);
openToast();
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.DOWNLOAD_GROUP_MEMBERS,
{ status: 'success' },
);
}).catch((err) => {
logError(err);
openErrorModal();
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.DOWNLOAD_GROUP_MEMBERS,
{
status: 'error',
message: err,
},
);
});
};

Expand Down Expand Up @@ -86,6 +103,7 @@ DownloadCsvIconButton.defaultProps = {
};

DownloadCsvIconButton.propTypes = {
enterpriseUUID: PropTypes.string,
fetchAllData: PropTypes.func.isRequired,
dataCount: PropTypes.number.isRequired,
testId: PropTypes.string,
Expand All @@ -95,4 +113,8 @@ DownloadCsvIconButton.propTypes = {
}),
};

export default DownloadCsvIconButton;
const mapStateToProps = state => ({
enterpriseUUID: state.portalConfiguration.enterpriseId,
});

export default connect(mapStateToProps)(DownloadCsvIconButton);
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { useParams } from 'react-router-dom';
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
import {
Breadcrumb, Card, Hyperlink, Icon, IconButton, IconButtonWithTooltip, Skeleton, useToggle,
} from '@openedx/paragon';
import { Delete, Edit } from '@openedx/paragon/icons';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';

import { useEnterpriseGroupLearnersTableData, useEnterpriseGroupUuid } from '../data/hooks';
import { ROUTE_NAMES } from '../../EnterpriseApp/data/constants';
Expand All @@ -14,8 +17,9 @@ import formatDates from '../utils';
import GroupMembersTable from './GroupMembersTable';
import AddMembersModal from '../AddMembersModal/AddMembersModal';
import { makePlural } from '../../../utils';
import EVENT_NAMES from '../../../eventTracking';

const GroupDetailPage = () => {
const GroupDetailPage = ({ enterpriseUUID }) => {
const intl = useIntl();
const { enterpriseSlug, groupUuid } = useParams();
const { data: enterpriseGroup } = useEnterpriseGroupUuid(groupUuid);
Expand Down Expand Up @@ -123,6 +127,12 @@ const GroupDetailPage = () => {
className="btn btn-primary"
target="_blank"
destination={`/${enterpriseSlug}/admin/${ROUTE_NAMES.learners}?group_uuid=${groupUuid}`}
onClick={() => {
sendEnterpriseTrackEvent(
enterpriseUUID,
EVENT_NAMES.PEOPLE_MANAGEMENT.VIEW_GROUP_BUTTON,
);
}}
>
View group progress
</Hyperlink>
Expand Down Expand Up @@ -168,4 +178,12 @@ const GroupDetailPage = () => {
);
};

export default GroupDetailPage;
GroupDetailPage.propTypes = {
enterpriseUUID: PropTypes.string,
};

const mapStateToProps = state => ({
enterpriseUUID: state.portalConfiguration.enterpriseId,
});

export default connect(mapStateToProps)(GroupDetailPage);
Loading

0 comments on commit c913436

Please sign in to comment.