@@ -402,11 +416,15 @@ Admin.defaultProps = {
},
csv: null,
table: null,
+ insightsLoading: false,
+ insights: null,
};
Admin.propTypes = {
fetchDashboardAnalytics: PropTypes.func.isRequired,
clearDashboardAnalytics: PropTypes.func.isRequired,
+ fetchDashboardInsights: PropTypes.func.isRequired,
+ clearDashboardInsights: PropTypes.func.isRequired,
enterpriseId: PropTypes.string,
searchEnrollmentsList: PropTypes.func.isRequired,
location: PropTypes.shape({
@@ -431,6 +449,8 @@ Admin.propTypes = {
}).isRequired,
}).isRequired,
table: PropTypes.shape({}),
+ insightsLoading: PropTypes.bool,
+ insights: PropTypes.objectOf(PropTypes.shape),
};
export default Admin;
diff --git a/src/containers/AdminPage/AdminPage.test.jsx b/src/containers/AdminPage/AdminPage.test.jsx
index 29c0770f40..2e30fbade3 100644
--- a/src/containers/AdminPage/AdminPage.test.jsx
+++ b/src/containers/AdminPage/AdminPage.test.jsx
@@ -28,6 +28,10 @@ const store = mockStore({
table: {
enrollments: {},
},
+ dashboardInsights: {
+ loading: null,
+ insights: null,
+ },
});
describe('
', () => {
diff --git a/src/containers/AdminPage/index.jsx b/src/containers/AdminPage/index.jsx
index 675cb1fbf5..502f7d18b6 100644
--- a/src/containers/AdminPage/index.jsx
+++ b/src/containers/AdminPage/index.jsx
@@ -9,6 +9,7 @@ import {
import Admin from '../../components/Admin';
import { paginateTable } from '../../data/actions/table';
import EnterpriseDataApiService from '../../data/services/EnterpriseDataApiService';
+import { fetchDashboardInsights, clearDashboardInsights } from '../../data/actions/dashboardInsights';
const mapStateToProps = state => ({
loading: state.dashboardAnalytics.loading,
@@ -21,6 +22,8 @@ const mapStateToProps = state => ({
enterpriseId: state.portalConfiguration.enterpriseId,
csv: state.csv,
table: state.table,
+ insightsLoading: state.dashboardInsights.loading,
+ insights: state.dashboardInsights.insights,
});
const mapDispatchToProps = dispatch => ({
@@ -33,6 +36,12 @@ const mapDispatchToProps = dispatch => ({
searchEnrollmentsList: () => {
dispatch(paginateTable('enrollments', EnterpriseDataApiService.fetchCourseEnrollments));
},
+ fetchDashboardInsights: (enterpriseId) => {
+ dispatch(fetchDashboardInsights(enterpriseId));
+ },
+ clearDashboardInsights: () => {
+ dispatch(clearDashboardInsights());
+ },
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Admin));
diff --git a/src/data/actions/dashboardInsights.js b/src/data/actions/dashboardInsights.js
new file mode 100644
index 0000000000..b9b65a040d
--- /dev/null
+++ b/src/data/actions/dashboardInsights.js
@@ -0,0 +1,41 @@
+import { logError } from '@edx/frontend-platform/logging';
+import {
+ FETCH_DASHBOARD_INSIGHTS_REQUEST,
+ FETCH_DASHBOARD_INSIGHTS_SUCCESS,
+ FETCH_DASHBOARD_INSIGHTS_FAILURE,
+ CLEAR_DASHBOARD_INSIGHTS,
+} from '../constants/dashboardInsights';
+import EnterpriseDataApiService from '../services/EnterpriseDataApiService';
+
+const fetchDashboardInsightsRequest = () => ({ type: FETCH_DASHBOARD_INSIGHTS_REQUEST });
+const fetchDashboardInsightsSuccess = data => ({
+ type: FETCH_DASHBOARD_INSIGHTS_SUCCESS,
+ payload: { data },
+});
+const fetchDashboardInsightsFailure = error => ({
+ type: FETCH_DASHBOARD_INSIGHTS_FAILURE,
+ payload: { error },
+});
+
+const fetchDashboardInsights = enterpriseId => (
+ (dispatch) => {
+ dispatch(fetchDashboardInsightsRequest());
+ return EnterpriseDataApiService.fetchDashboardInsights(enterpriseId)
+ .then((response) => {
+ dispatch(fetchDashboardInsightsSuccess(response.data));
+ })
+ .catch((error) => {
+ logError(error);
+ dispatch(fetchDashboardInsightsFailure(error));
+ });
+ }
+);
+
+const clearDashboardInsights = () => dispatch => (dispatch({
+ type: CLEAR_DASHBOARD_INSIGHTS,
+}));
+
+export {
+ fetchDashboardInsights,
+ clearDashboardInsights,
+};
diff --git a/src/data/constants/dashboardInsights.js b/src/data/constants/dashboardInsights.js
new file mode 100644
index 0000000000..05b81a28e9
--- /dev/null
+++ b/src/data/constants/dashboardInsights.js
@@ -0,0 +1,11 @@
+const FETCH_DASHBOARD_INSIGHTS_REQUEST = 'FETCH_DASHBOARD_INSIGHTS_REQUEST';
+const FETCH_DASHBOARD_INSIGHTS_SUCCESS = 'FETCH_DASHBOARD_INSIGHTS_SUCCESS';
+const FETCH_DASHBOARD_INSIGHTS_FAILURE = 'FETCH_DASHBOARD_INSIGHTS_FAILURE';
+const CLEAR_DASHBOARD_INSIGHTS = 'CLEAR_DASHBOARD_INSIGHTS';
+
+export {
+ FETCH_DASHBOARD_INSIGHTS_REQUEST,
+ FETCH_DASHBOARD_INSIGHTS_SUCCESS,
+ FETCH_DASHBOARD_INSIGHTS_FAILURE,
+ CLEAR_DASHBOARD_INSIGHTS,
+};
diff --git a/src/data/reducers/dashboardInsights.js b/src/data/reducers/dashboardInsights.js
new file mode 100644
index 0000000000..6c25972617
--- /dev/null
+++ b/src/data/reducers/dashboardInsights.js
@@ -0,0 +1,47 @@
+import {
+ FETCH_DASHBOARD_INSIGHTS_REQUEST,
+ FETCH_DASHBOARD_INSIGHTS_SUCCESS,
+ FETCH_DASHBOARD_INSIGHTS_FAILURE,
+ CLEAR_DASHBOARD_INSIGHTS,
+} from '../constants/dashboardInsights';
+
+const initialState = {
+ loading: false,
+ error: null,
+ insights: null,
+};
+
+const dashboardInsights = (state = initialState, action) => {
+ switch (action.type) {
+ case FETCH_DASHBOARD_INSIGHTS_REQUEST:
+ return {
+ ...state,
+ loading: true,
+ error: null,
+ };
+ case FETCH_DASHBOARD_INSIGHTS_SUCCESS:
+ return {
+ ...state,
+ loading: false,
+ insights: action.payload.data,
+ };
+ case FETCH_DASHBOARD_INSIGHTS_FAILURE:
+ return {
+ ...state,
+ loading: false,
+ error: action.payload.error,
+ insights: null,
+ };
+ case CLEAR_DASHBOARD_INSIGHTS:
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ insights: null,
+ };
+ default:
+ return state;
+ }
+};
+
+export default dashboardInsights;
diff --git a/src/data/reducers/index.js b/src/data/reducers/index.js
index 27b18f99f5..c3d5abfaf3 100644
--- a/src/data/reducers/index.js
+++ b/src/data/reducers/index.js
@@ -13,6 +13,7 @@ import licenseRevoke from './licenseRevoke';
import emailTemplate from './emailTemplate';
import licenseRemind from './licenseRemind';
import userSubscription from './userSubscription';
+import dashboardInsights from './dashboardInsights';
const identityReducer = (state) => {
const newState = { ...state };
@@ -36,6 +37,7 @@ const rootReducer = combineReducers({
emailTemplate,
licenseRemind,
userSubscription,
+ dashboardInsights,
});
export default rootReducer;
diff --git a/src/data/services/EnterpriseDataApiService.js b/src/data/services/EnterpriseDataApiService.js
index bf00da3de6..ef7b5078e5 100644
--- a/src/data/services/EnterpriseDataApiService.js
+++ b/src/data/services/EnterpriseDataApiService.js
@@ -9,6 +9,8 @@ class EnterpriseDataApiService {
static enterpriseBaseUrl = `${configuration.DATA_API_BASE_URL}/enterprise/api/v1/enterprise/`;
+ static enterpriseAdminBaseUrl = `${configuration.DATA_API_BASE_URL}/enterprise/api/v1/admin/`;
+
static fetchDashboardAnalytics(enterpriseId) {
const url = `${EnterpriseDataApiService.enterpriseBaseUrl}${enterpriseId}/enrollments/overview/`;
return EnterpriseDataApiService.apiClient().get(url);
@@ -111,6 +113,11 @@ class EnterpriseDataApiService {
const url = `${EnterpriseDataApiService.enterpriseBaseUrl}${enterpriseId}/${endpoint}/?${queryParams.toString()}`;
return EnterpriseDataApiService.apiClient().get(url);
}
+
+ static fetchDashboardInsights(enterpriseId) {
+ const url = `${EnterpriseDataApiService.enterpriseAdminBaseUrl}insights/${enterpriseId}`;
+ return EnterpriseDataApiService.apiClient().get(url);
+ }
}
export default EnterpriseDataApiService;
diff --git a/src/data/services/LmsApiService.js b/src/data/services/LmsApiService.js
index 2ed35e8274..31bc12fce7 100644
--- a/src/data/services/LmsApiService.js
+++ b/src/data/services/LmsApiService.js
@@ -379,6 +379,11 @@ class LmsApiService {
};
return LmsApiService.apiClient().put(`${LmsApiService.apiCredentialsUrl}${enterpriseUUID}/regenerate_credentials`, requestData);
}
+
+ static generateAIAnalyticsSummary(enterpriseUUID, formData) {
+ const url = `${LmsApiService.baseUrl}/enterprise/api/v1/analytics-summary/${enterpriseUUID}/`;
+ return LmsApiService.apiClient().post(url, formData);
+ }
}
export default LmsApiService;