Skip to content

Commit

Permalink
fix: updated render logic for customer users table
Browse files Browse the repository at this point in the history
  • Loading branch information
katrinan029 committed Sep 12, 2024
1 parent 837e412 commit 6c963e6
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import { useState } from 'react';
import { useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Form, Skeleton } from '@openedx/paragon';
import useAllAssociatedPlans from '../data/hooks/useAllAssociatedPlans';
import LearnerCreditPlanCard from './LearnerCreditPlanCard';
import SubscriptionPlanCard from './SubscriptionPlanCard';

const CustomerPlanContainer = ({ slug }) => {
const { id } = useParams();
const {
activePolicies,
activeSubscriptions,
countOfActivePlans,
countOfAllPlans,
inactivePolicies,
inactiveSubscriptions,
isLoading,
} = useAllAssociatedPlans(id);
const CustomerPlanContainer = ({
slug,
activePolicies,
activeSubscriptions,
countOfActivePlans,
countOfAllPlans,
inactivePolicies,
inactiveSubscriptions,
isLoading,
}) => {
const [showInactive, setShowInactive] = useState(false);
useEffect(() => {
if (!countOfActivePlans && countOfAllPlans) {
setShowInactive(true);

Check warning on line 20 in src/Configuration/Customers/CustomerDetailView/CustomerPlanContainer.jsx

View check run for this annotation

Codecov / codecov/patch

src/Configuration/Customers/CustomerDetailView/CustomerPlanContainer.jsx#L20

Added line #L20 was not covered by tests
}
}, []);
const renderActivePoliciesCard = activePolicies.map(policy => (
<LearnerCreditPlanCard key={policy.uuid} isActive slug={slug} policy={policy} />
));
Expand All @@ -31,19 +33,13 @@ const CustomerPlanContainer = ({ slug }) => {
<SubscriptionPlanCard key={subscription.uuid} isActive={false} slug={slug} subscription={subscription} />
));

const hasActivePlans = activePolicies.length > 0 || renderActiveSubscriptions.length > 0;

if (!hasActivePlans) {
return null;
}

return (
<div>
{!isLoading ? (
<div>
<div className="d-flex justify-content-between">
<h2>Associated subsidy plans ({showInactive ? countOfAllPlans : countOfActivePlans})</h2>
{(countOfAllPlans !== countOfActivePlans) && (
{(countOfAllPlans > countOfActivePlans && countOfActivePlans) ? (
<Form.Switch
className="ml-2.5 mt-2.5"
checked={showInactive}
Expand All @@ -54,7 +50,7 @@ const CustomerPlanContainer = ({ slug }) => {
>
Show inactive
</Form.Switch>
)}
) : null}

Check warning on line 53 in src/Configuration/Customers/CustomerDetailView/CustomerPlanContainer.jsx

View check run for this annotation

Codecov / codecov/patch

src/Configuration/Customers/CustomerDetailView/CustomerPlanContainer.jsx#L53

Added line #L53 was not covered by tests
</div>
<hr />
{renderActivePoliciesCard}
Expand All @@ -73,6 +69,35 @@ const CustomerPlanContainer = ({ slug }) => {

CustomerPlanContainer.propTypes = {
slug: PropTypes.string.isRequired,
activePolicies: PropTypes.arrayOf(PropTypes.shape({
uuid: PropTypes.string.isRequired,
subsidyActiveDatetime: PropTypes.string.isRequired,
subsidyExpirationDatetime: PropTypes.string.isRequired,
policyType: PropTypes.string.isRequired,
created: PropTypes.string.isRequired,
})).isRequired,
activeSubscriptions: PropTypes.arrayOf(PropTypes.shape({
uuid: PropTypes.string.isRequired,
startDate: PropTypes.string.isRequired,
expirationDate: PropTypes.string.isRequired,
created: PropTypes.string.isRequired,
})).isRequired,
countOfActivePlans: PropTypes.number.isRequired,
countOfAllPlans: PropTypes.number.isRequired,
inactivePolicies: PropTypes.arrayOf(PropTypes.shape({
uuid: PropTypes.string.isRequired,
subsidyActiveDatetime: PropTypes.string.isRequired,
subsidyExpirationDatetime: PropTypes.string.isRequired,
policyType: PropTypes.string.isRequired,
created: PropTypes.string.isRequired,
})).isRequired,
inactiveSubscriptions: PropTypes.arrayOf(PropTypes.shape({
uuid: PropTypes.string.isRequired,
startDate: PropTypes.string.isRequired,
expirationDate: PropTypes.string.isRequired,
created: PropTypes.string.isRequired,
})).isRequired,
isLoading: PropTypes.bool.isRequired,
};

export default CustomerPlanContainer;
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ import { getEnterpriseCustomer } from '../data/utils';
import CustomerIntegrations from './CustomerIntegrations';
import EnterpriseCustomerUsersTable from './EnterpriseCustomerUsersTable';
import CustomerPlanContainer from './CustomerPlanContainer';
import useAllAssociatedPlans from '../data/hooks/useAllAssociatedPlans';

const CustomerViewContainer = () => {
const { id } = useParams();
const [enterpriseCustomer, setEnterpriseCustomer] = useState({});
const [isLoading, setIsLoading] = useState(true);
const intl = useIntl();
const associatedPlans = useAllAssociatedPlans(id);

const fetchData = useCallback(
async () => {
Expand All @@ -38,6 +40,23 @@ const CustomerViewContainer = () => {
fetchData();
}, []);

const renderPlanContainer = () => {
if (!isLoading && !associatedPlans.isLoading && associatedPlans.countOfAllPlans) {
return (

Check warning on line 45 in src/Configuration/Customers/CustomerDetailView/CustomerViewContainer.jsx

View check run for this annotation

Codecov / codecov/patch

src/Configuration/Customers/CustomerDetailView/CustomerViewContainer.jsx#L45

Added line #L45 was not covered by tests
<Stack gap={2}>
<CustomerPlanContainer slug={enterpriseCustomer.slug} {...associatedPlans} />
</Stack>
);
}
if (!associatedPlans.isLoading && !associatedPlans.countOfAllPlans) {
return false;
}
if (associatedPlans.isLoading) {
return <Skeleton height={230} />;
}
return null;

Check warning on line 57 in src/Configuration/Customers/CustomerDetailView/CustomerViewContainer.jsx

View check run for this annotation

Codecov / codecov/patch

src/Configuration/Customers/CustomerDetailView/CustomerViewContainer.jsx#L57

Added line #L57 was not covered by tests
};

return (
<div>
{!isLoading ? (
Expand All @@ -64,11 +83,9 @@ const CustomerViewContainer = () => {
</Stack>
</Container>
<Container className="mt-4">
<Stack gap={2}>
{!isLoading ? <CustomerPlanContainer slug={enterpriseCustomer.slug} /> : <Skeleton height={230} />}
</Stack>
{renderPlanContainer()}
</Container>
<Container className="mt-4">
<Container className="mt-4 mb-4">
<Stack gap={2}>
<CustomerIntegrations
slug={enterpriseCustomer.slug}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,60 @@ const EnterpriseCustomerUsersTable = () => {
isLoading,
enterpriseUsersTableData,
fetchEnterpriseUsersData,
showTable,
} = useCustomerUsersTableData(id);

if (!enterpriseUsersTableData.itemCount) {
return null;
}

return (
<div>
<h2>Associated users ({enterpriseUsersTableData.itemCount})</h2>
<hr />
<DataTable
isLoading={isLoading}
isExpandable
isPaginated
manualPagination
isFilterable
manualFilters
initialState={{
pageSize: 8,
pageIndex: 0,
sortBy: [],
filters: [],
}}
defaultColumnValues={{ Filter: TextFilter }}
fetchData={fetchEnterpriseUsersData}
data={enterpriseUsersTableData.results}
itemCount={enterpriseUsersTableData.itemCount}
pageCount={enterpriseUsersTableData.pageCount}
columns={[
{
id: 'details',
Header: 'User details',
accessor: 'details',
Cell: EnterpriseCustomerUserDetail,
},
{
id: 'administrator',
Header: 'Administrator',
accessor: 'administrator',
disableFilters: true,
Cell: AdministratorCell,
},
{
id: 'learner',
Header: 'Learner',
accessor: 'learner',
disableFilters: true,
Cell: LearnerCell,
},
]}
/>
{showTable ? (
<div>
<h2>Associated users {enterpriseUsersTableData.itemCount > 0
&& <span>({enterpriseUsersTableData.itemCount})</span>}
</h2>
<hr />
<DataTable
isLoading={isLoading}
isExpandable
isPaginated
manualPagination
isFilterable
manualFilters
initialState={{
pageSize: 8,
pageIndex: 0,
sortBy: [],
filters: [],
}}
defaultColumnValues={{ Filter: TextFilter }}
fetchData={fetchEnterpriseUsersData}
data={enterpriseUsersTableData.results}
itemCount={enterpriseUsersTableData.itemCount}
pageCount={enterpriseUsersTableData.pageCount}
columns={[
{
id: 'details',
Header: 'User details',
accessor: 'details',
Cell: EnterpriseCustomerUserDetail,
},
{
id: 'administrator',
Header: 'Administrator',
accessor: 'administrator',
disableFilters: true,
Cell: AdministratorCell,
},
{
id: 'learner',
Header: 'Learner',
accessor: 'learner',
disableFilters: true,
Cell: LearnerCell,
},
]}
/>
</div>
) : null}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import userEvent from '@testing-library/user-event';
import { getConfig } from '@edx/frontend-platform';
import { IntlProvider } from '@edx/frontend-platform/i18n';

import useAllAssociatedPlans from '../../data/hooks/useAllAssociatedPlans';
import { formatDate } from '../../data/utils';
import CustomerPlanContainer from '../CustomerPlanContainer';

Expand All @@ -19,11 +18,6 @@ jest.mock('@edx/frontend-platform', () => ({
getConfig: jest.fn(),
}));

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ id: 'test-uuid' }),
}));

const CUSTOMER_SLUG = 'test-slug';

describe('CustomerPlanContainer', () => {
Expand All @@ -44,7 +38,7 @@ describe('CustomerPlanContainer', () => {
ENTERPRISE_ACCESS_BASE_URL: 'http:www.enterprise-access.com',
LICENSE_MANAGER_URL: 'http:www.license-manager.com',
}));
useAllAssociatedPlans.mockReturnValue({
const mockProps = {
isLoading: false,
activePolicies: [{
subsidyActiveDatetime: '2024-08-23T20:02:57.651943Z',
Expand All @@ -71,10 +65,10 @@ describe('CustomerPlanContainer', () => {
policyType: 'learnerCredit',
isSubsidyActive: false,
}],
});
};
render(
<IntlProvider locale="en">
<CustomerPlanContainer slug={CUSTOMER_SLUG} />
<CustomerPlanContainer slug={CUSTOMER_SLUG} {...mockProps} />
</IntlProvider>,
);
const djangoLinks = screen.getAllByRole('link', { name: 'Open in Django' });
Expand All @@ -99,26 +93,4 @@ describe('CustomerPlanContainer', () => {
await waitFor(() => expect(screen.getByText('Associated subsidy plans (3)')).toBeInTheDocument());
expect(screen.getByText('Inactive')).toBeInTheDocument();
});
it('does not render CustomerPlanContainer data', async () => {
getConfig.mockImplementation(() => ({
ADMIN_PORTAL_BASE_URL: 'http://www.testportal.com',
ENTERPRISE_ACCESS_BASE_URL: 'http:www.enterprise-access.com',
LICENSE_MANAGER_URL: 'http:www.license-manager.com',
}));
useAllAssociatedPlans.mockReturnValue({
isLoading: false,
activePolicies: [],
activeSubscriptions: [],
countOfActivePlans: 0,
countOfAllPlans: 0,
inactiveSubscriptions: [],
inactivePolicies: [],
});
render(
<IntlProvider locale="en">
<CustomerPlanContainer slug={CUSTOMER_SLUG} />
</IntlProvider>,
);
expect(screen.queryByText('Associated subsidy plans (0)')).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const mockData = {
],
},
fetchEnterpriseUsersData: mockFetchEnterpriseUsersData,
showTable: true,
};

jest.mock('../../data/hooks/useCustomerUsersTableData');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
useCallback, useMemo, useState,
useCallback, useMemo, useState, useEffect,
} from 'react';
import { camelCaseObject } from '@edx/frontend-platform/utils';
import { logError } from '@edx/frontend-platform/logging';
Expand All @@ -9,6 +9,7 @@ import LmsApiService from '../../../../data/services/EnterpriseApiService';

const useCustomerUsersTableData = (enterpriseUuid) => {
const [isLoading, setIsLoading] = useState(true);
const [showTable, setShowTable] = useState(false);
const [enterpriseUsersTableData, setEnterpriseUsersTableData] = useState({
itemCount: 0,
pageCount: 0,
Expand Down Expand Up @@ -66,10 +67,23 @@ const useCustomerUsersTableData = (enterpriseUuid) => {
[fetchEnterpriseUsersData],
);

useEffect(() => {
const args = {
pageIndex: 0,
filters: [],
sortBy: [],
};
fetchEnterpriseUsersData(args);
if (enterpriseUsersTableData.itemCount) {
setShowTable(true);

Check warning on line 78 in src/Configuration/Customers/data/hooks/useCustomerUsersTableData.js

View check run for this annotation

Codecov / codecov/patch

src/Configuration/Customers/data/hooks/useCustomerUsersTableData.js#L78

Added line #L78 was not covered by tests
}
}, [fetchEnterpriseUsersData, enterpriseUsersTableData.itemCount]);

return {
isLoading,
enterpriseUsersTableData,
fetchEnterpriseUsersData: debouncedFetchEnterpriseUsersData,
showTable,
};
};

Expand Down

0 comments on commit 6c963e6

Please sign in to comment.