Skip to content

Commit fc56c9b

Browse files
feat: release analytics v2
feat: analytics v2 onboarding flow feat: analytics v2 new feature notification
1 parent 5e235f3 commit fc56c9b

19 files changed

+359
-256
lines changed

.env.development-stage

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ FEATURE_API_CREDENTIALS_TAB='true'
3939
FEATURE_PENDING_ENROLLMENT_ACTIONS='false'
4040
ANALYTICS_SUPPORTED='true'
4141

42-
# Admin onboarding flow uuids
42+
# Admin onboarding flow uuids
4343
FLOW_TRACK_LEARNER_PROGRESS_UUID="14339274-93de-4a16-b640-338bda4b70b9"
44+
FLOW_ANALYTICS_UUID="5b1f3a2c-3f4e-4d1e-8f4b-5e2f9c8b6a1d"
4445
FLOW_ORGANIZE_LEARNERS_UUID="c1d85a44-7285-415c-872d-9a89cbeaabfb"
4546
FLOW_ENROLLMENT_INSIGHTS="e75427b5-69b7-4ef7-ad75-38f7f5182a49"
4647
FLOW_SHOWCASE_COURSES_UUID="e546b3aa-b55c-44e6-8293-4bbb2f7be50a"

src/components/AdvanceAnalyticsV2.0/AnalyticsPage.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Hero from '../Hero';
88
import Engagements from './tabs/Engagements';
99
import Progress from './tabs/Progress';
1010
import Outcomes from './tabs/Outcomes';
11+
import { ANALYTICS_V2_TARGETS } from '../ProductTours/AdminOnboardingTours/constants';
1112

1213
const AnalyticsPage = ({ enterpriseId }) => {
1314
const [activeTab, setActiveTab] = useState('engagements');
@@ -33,6 +34,7 @@ const AnalyticsPage = ({ enterpriseId }) => {
3334
}}
3435
>
3536
<Tab
37+
id={ANALYTICS_V2_TARGETS.ENGAGEMENTS_TAB}
3638
eventKey="engagements"
3739
title={intl.formatMessage({
3840
id: 'analytics.engagement.tab.title.heading',
@@ -45,6 +47,7 @@ const AnalyticsPage = ({ enterpriseId }) => {
4547
/>
4648
</Tab>
4749
<Tab
50+
id={ANALYTICS_V2_TARGETS.PROGRESS_TAB}
4851
eventKey="Progress"
4952
title={intl.formatMessage({
5053
id: 'advance.analytics.progress.tab.title.heading',
@@ -57,6 +60,7 @@ const AnalyticsPage = ({ enterpriseId }) => {
5760
/>
5861
</Tab>
5962
<Tab
63+
id={ANALYTICS_V2_TARGETS.OUTCOMES_TAB}
6064
eventKey="Outcomes"
6165
title={intl.formatMessage({
6266
id: 'advance.analytics.outcomes.tab.title.heading',

src/components/EnterpriseApp/EnterpriseAppRoutes.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const EnterpriseAppRoutes = ({
8282
/>
8383
)}
8484

85-
{enableAnalyticsPage && enterpriseAppPage === ROUTE_NAMES.analytics && (
85+
{enableAnalyticsPage && enterpriseAppPage === ROUTE_NAMES.analytics_v1 && features.ADMIN_V1 && (
8686
<Route
8787
key="analytics"
8888
path="/"
@@ -92,7 +92,7 @@ const EnterpriseAppRoutes = ({
9292
/>
9393
)}
9494

95-
{enableAnalyticsPage && enterpriseAppPage === ROUTE_NAMES.analytics_v2 && features.ADMIN_V2 && (
95+
{enableAnalyticsPage && enterpriseAppPage === ROUTE_NAMES.analytics && (
9696
<Route
9797
key="analytics"
9898
path="/"

src/components/EnterpriseApp/EnterpriseAppRoutes.test.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ describe('EnterpriseAppRoutes', () => {
5555
expect(screen.getByText('This feature is currently unavailable in this environment.')).toBeInTheDocument();
5656
});
5757

58-
it('renders AnalyticsV2Page when ANALYTICS_SUPPORTED is true', () => {
58+
it('renders AnalyticsV2Page when ANALYTICS_SUPPORTED and ADMIN_V1 is true', () => {
59+
mockEnterpriseAppPage = 'analytics-v1';
5960
features.ANALYTICS_SUPPORTED = true;
61+
features.ADMIN_V1 = true;
6062
renderWithProviders(defaultProps);
6163
expect(screen.getByText('AnalyticsV2Page Mock Component')).toBeInTheDocument();
6264
});
@@ -67,10 +69,9 @@ describe('EnterpriseAppRoutes', () => {
6769
renderWithProviders(defaultProps);
6870
expect(screen.getByText('AdminPage Mock Component')).toBeInTheDocument();
6971
});
70-
it('renders RevisedAnalyticsV2Page when all flags are true', () => {
71-
mockEnterpriseAppPage = 'analytics-v2';
72+
it('renders RevisedAnalyticsV2Page by default', () => {
73+
mockEnterpriseAppPage = 'analytics';
7274
features.ANALYTICS_SUPPORTED = true;
73-
features.ADMIN_V2 = true;
7475
renderWithProviders(defaultProps);
7576
expect(screen.getByText('RevisedAnalyticsV2Page Mock Component')).toBeInTheDocument();
7677
});

src/components/EnterpriseApp/data/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
export const ROUTE_NAMES = {
44
analytics: 'analytics',
5-
analytics_v2: 'analytics-v2',
5+
analytics_v1: 'analytics-v1',
66
appearance: 'appearance',
77
bulkEnrollment: 'enrollment',
88
bulkEnrollmentResults: 'bulk-enrollment-results',

src/components/ProductTours/AdminOnboardingTours/constants.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ export const ANALYTICS_INSIGHTS_TARGETS = {
3131
SKILLS: 'analytics-skills',
3232
};
3333

34+
export const ANALYTICS_V2_TARGETS = {
35+
SIDEBAR: 'analytics-sidebar',
36+
ENGAGEMENTS_TAB: 'analytics-v2-engagements-tab',
37+
PROGRESS_TAB: 'analytics-v2-progress-tab',
38+
OUTCOMES_TAB: 'analytics-v2-outcomes-tab',
39+
};
40+
3441
export const ADMINISTER_SUBSCRIPTIONS_TARGETS = {
3542
SIDEBAR: 'subscriptions-sidebar',
3643
SUBSCRIPTION_PLANS_LIST: 'subscription-plans-list',
@@ -95,6 +102,10 @@ export const ADMIN_TOUR_EVENT_NAMES = {
95102
ALLOCATE_ASSIGNMENT_DISMISS_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.allocate-assignment.dismiss',
96103
SET_UP_PREFERENCES_COMPLETED_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.set-up-preferences.completed',
97104
SET_UP_PREFERENCES_DISMISS_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.set-up-preferences.dismiss',
105+
ANALYTICS_ADVANCE_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.analytics.advance',
106+
ANALYTICS_BACK_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.analytics.back',
107+
ANALYTICS_COMPLETED_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.analytics.completed',
108+
ANALYTICS_DISMISS_EVENT_NAME: 'edx.ui.enterprise.admin-portal.admin-onboarding-tours.analytics.dismiss',
98109
};
99110

100111
export const ONBOARDING_WELCOME_MODAL_COOKIE_NAME = 'seen-onboarding-welcome-modal';

src/components/ProductTours/AdminOnboardingTours/flows/AdminOnboardingTour.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import { logError } from '@edx/frontend-platform/logging';
33

44
import {
55
ADMINISTER_SUBSCRIPTIONS_TARGETS,
6-
ANALYTICS_INSIGHTS_TARGETS,
76
CUSTOMIZE_REPORTS_SIDEBAR,
87
ORGANIZE_LEARNER_TARGETS,
98
TRACK_LEARNER_PROGRESS_TARGETS,
109
ALLOCATE_LEARNING_BUDGETS_TARGETS,
10+
ANALYTICS_V2_TARGETS,
1111
} from '../constants';
1212

1313
import { TourStep } from '../../types';
1414
import LmsApiService from '../../../../data/services/LmsApiService';
1515
import AdministerSubscriptionsFlow from './AdministerSubscriptionsFlow';
1616
import useAllocateLearningBudgetsFlow from './AllocateLearningBudgetsFlow';
17-
import AnalyticsFlow from './AnalyticsFlow';
1817
import CustomizeReportsFlow from './CustomizeReportsFlow';
1918
import LearnerProgressFlow from './LearnerProgressFlow';
19+
import AnalyticsV2Flow from './AnalyticsV2Flow';
2020
import OrganizeLearnersFlow from './OrganizeLearnersFlow';
2121
import SetUpPreferencesFlow from './SetUpPreferencesFlow';
2222
import { TOUR_TARGETS } from '../../constants';
@@ -76,7 +76,7 @@ const AdminOnboardingTour = (
7676
const administerSubscriptionsFlow = AdministerSubscriptionsFlow({
7777
currentStep, enterpriseId, enterpriseSlug, handleEndTour, handleBackTour, setCurrentStep, targetSelector,
7878
});
79-
const analyticsFlow = AnalyticsFlow({
79+
const analyticsV2Flow = AnalyticsV2Flow({
8080
handleAdvanceTour, handleBackTour, handleEndTour,
8181
});
8282
const customizeReportsFlow = CustomizeReportsFlow({ handleEndTour });
@@ -103,8 +103,8 @@ const AdminOnboardingTour = (
103103
const flowMapping = {
104104
[TRACK_LEARNER_PROGRESS_TARGETS.LEARNER_PROGRESS_SIDEBAR]: learnerProgressFlow,
105105
...Object.fromEntries(
106-
Object.values(ANALYTICS_INSIGHTS_TARGETS)
107-
.map(target => [target, analyticsFlow]),
106+
Object.values(ANALYTICS_V2_TARGETS)
107+
.map(target => [target, analyticsV2Flow]),
108108
),
109109
...Object.fromEntries(
110110
Object.values(ORGANIZE_LEARNER_TARGETS)

src/components/ProductTours/AdminOnboardingTours/flows/AnalyticsFlow.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { useIntl } from '@edx/frontend-platform/i18n';
2+
import { ANALYTICS_V2_TARGETS, ADMIN_TOUR_EVENT_NAMES } from '../constants';
3+
import messages from '../messages';
4+
import { TourStep } from '../../types';
5+
import { configuration } from '../../../../config';
6+
7+
interface CreateTourFlowsProps {
8+
handleAdvanceTour: (advanceEventName: string) => void;
9+
handleEndTour: (endEventName: string, flowUuid?: string) => void;
10+
handleBackTour: (backEventName: string) => void;
11+
}
12+
13+
const AnalyticsV2Flow = ({
14+
handleAdvanceTour,
15+
handleEndTour,
16+
handleBackTour,
17+
}: CreateTourFlowsProps): Array<TourStep> => {
18+
const intl = useIntl();
19+
const onLearnerAdvance = () => handleAdvanceTour(ADMIN_TOUR_EVENT_NAMES.ANALYTICS_ADVANCE_EVENT_NAME);
20+
const onLearnerBack = () => handleBackTour(ADMIN_TOUR_EVENT_NAMES.ANALYTICS_BACK_EVENT_NAME);
21+
22+
const analyticsV2Flow: Array<TourStep> = [{
23+
target: `#${ANALYTICS_V2_TARGETS.SIDEBAR}`,
24+
placement: 'right',
25+
title: intl.formatMessage(messages.analyticsStepOneTitle),
26+
body: intl.formatMessage(messages.analyticsStepOneBody),
27+
onAdvance: onLearnerAdvance,
28+
}, {
29+
target: `#${ANALYTICS_V2_TARGETS.ENGAGEMENTS_TAB}`,
30+
placement: 'bottom',
31+
body: intl.formatMessage(messages.analyticsStepTwoBody),
32+
onAdvance: onLearnerAdvance,
33+
onBack: onLearnerBack,
34+
}, {
35+
target: `#${ANALYTICS_V2_TARGETS.PROGRESS_TAB}`,
36+
placement: 'bottom',
37+
body: intl.formatMessage(messages.analyticsStepThreeBody),
38+
onAdvance: onLearnerAdvance,
39+
onBack: onLearnerBack,
40+
}, {
41+
target: `#${ANALYTICS_V2_TARGETS.OUTCOMES_TAB}`,
42+
placement: 'bottom',
43+
body: intl.formatMessage(messages.analyticsStepFourBody),
44+
onAdvance: onLearnerAdvance,
45+
onBack: onLearnerBack,
46+
onEnd: () => handleEndTour(
47+
ADMIN_TOUR_EVENT_NAMES.ANALYTICS_COMPLETED_EVENT_NAME,
48+
configuration.ADMIN_ONBOARDING_UUIDS.FLOW_ANALYTICS_UUID,
49+
),
50+
}];
51+
52+
return analyticsV2Flow;
53+
};
54+
55+
export default AnalyticsV2Flow;

src/components/ProductTours/AdminOnboardingTours/messages.js

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { defineMessages } from '@edx/frontend-platform/i18n';
22

33
export const ORGANIZE_LEARNERS_TITLE = 'Organize learners';
44
export const TRACK_LEARNER_PROGRESS_TITLE = 'Track learner progress';
5-
export const VIEW_ENROLLMENTS_INSIGHT_TITLE = 'View enrollment insights';
5+
export const ANALYTICS_V2_TITLE = 'View enrollment insights';
66
export const ADMINISTER_SUBSCRIPTIONS_TITLE = 'Administer subscriptions';
77
export const ALLOCATE_LEARNING_BUDGET_TITLE = 'Allocate learning budget';
88
export const CUSTOMIZE_REPORTS_TITLE = 'Customize reports';
@@ -97,6 +97,31 @@ const messages = defineMessages({
9797
defaultMessage: 'Export the report as a CSV to gain insights and organize data efficiently.',
9898
description: 'Description for the learner progress tracking step seven',
9999
},
100+
analyticsStepOneTitle: {
101+
id: 'adminPortal.productTours.adminOnboarding.analytics.title.1',
102+
defaultMessage: ANALYTICS_V2_TITLE,
103+
description: 'Title for the analytics step one',
104+
},
105+
analyticsStepOneBody: {
106+
id: 'adminPortal.productTours.adminOnboarding.analytics.body.1',
107+
defaultMessage: 'Explore insights about your learners and their enrollments. Adjust date ranges, granularity, and analytics type to view data on enrollments, engagement, completions, leaderboards, and skills tracking.',
108+
description: 'Description for the analytics tracking step one',
109+
},
110+
analyticsStepTwoBody: {
111+
id: 'adminPortal.productTours.adminOnboarding.analytics.body.2',
112+
defaultMessage: 'The Engagement tab will help you understand course enrollment, learning hours, top subjects, and completions by your learners. Filter data by date ranges, group, budget, and course.',
113+
description: 'Description for the analytics tracking step two',
114+
},
115+
analyticsStepThreeBody: {
116+
id: 'adminPortal.productTours.adminOnboarding.analytics.body.3',
117+
defaultMessage: 'The Progress tab will help you summarize completed courses by your learners. Filter data by date ranges, group, budget, and course.',
118+
description: 'Description for the analytics tracking step three',
119+
},
120+
analyticsStepFourBody: {
121+
id: 'adminPortal.productTours.adminOnboarding.analytics.body.4',
122+
defaultMessage: 'The Outcomes tab will help you visualize the skills your learner have gained from the courses. Filter data by date ranges, group, budget, and course.',
123+
description: 'Description for the analytics tracking step four',
124+
},
100125
organizeLearnersStepOneTitle: {
101126
id: 'adminPortal.productTours.adminOnboarding.organizeLearners.title.1',
102127
defaultMessage: ORGANIZE_LEARNERS_TITLE,
@@ -148,47 +173,6 @@ const messages = defineMessages({
148173
defaultMessage: '"View group" allows you to edit group details, add and remove learners, or track learner\'s progress.',
149174
description: 'Description for the organize learners flow with groups step six',
150175
},
151-
viewEnrollmentInsights: {
152-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.title.1',
153-
defaultMessage: VIEW_ENROLLMENTS_INSIGHT_TITLE,
154-
description: 'Title for the analytics step',
155-
},
156-
viewEnrollmentInsightsStepOneBody: {
157-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.body.1',
158-
defaultMessage: 'Explore insights about your learners and their enrollments. '
159-
+ 'Adjust date ranges, granularity, and analytics type to view data on enrollments, engagement '
160-
+ 'completions, leaderboards, and skills tracking.',
161-
description: 'Description for the analytics tracking step one',
162-
},
163-
viewEnrollmentInsightsStepTwoBody: {
164-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.body.2',
165-
defaultMessage: 'Adjust the date range and granularity to customize the data displayed below.',
166-
description: 'Description for the analytics tracking step two',
167-
},
168-
viewEnrollmentInsightsStepThreeBody: {
169-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.body.3',
170-
defaultMessage: 'See quick metrics for Enrollments, Distinct Courses, Daily Sessions, Learning Hours, and '
171-
+ 'completions at a glance.',
172-
description: 'Description for the analytics tracking step three',
173-
},
174-
viewEnrollmentInsightsStepFourBody: {
175-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.body.4',
176-
defaultMessage: 'Use the Enrollments, Engagements, and Completions tabs to view learner activity from different '
177-
+ 'perspectives. Scroll down for a breakdown of metrics by Course, Subject, and Individual.',
178-
description: 'Description for the analytics tracking step four',
179-
},
180-
viewEnrollmentInsightsStepFiveBody: {
181-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.body.5',
182-
defaultMessage: 'See your top learners ranked by learning hours. Download the CSV for more detailed insights. Only '
183-
+ 'learners who completed a course and at least one engagement activity are included.',
184-
description: 'Description for the analytics tracking step five',
185-
},
186-
viewEnrollmentInsightsStepSixBody: {
187-
id: 'adminPortal.productTours.adminOnboarding.viewEnrollmentInsights.body.6',
188-
defaultMessage: 'Discover the most in-demand skills in your organization based on course enrollments and completions. '
189-
+ 'Use these insights to understand learner interests and skill development trends.',
190-
description: 'Description for the analytics tracking step six',
191-
},
192176

193177
administerSubscriptionsTitle: {
194178
id: 'adminPortal.productTours.adminOnboarding.administerSubscriptions.title',

0 commit comments

Comments
 (0)