Skip to content

Commit

Permalink
Merge pull request #2147 from City-of-Helsinki/hl-870
Browse files Browse the repository at this point in the history
HL-870 | Wrong number of applications on front page's tabs
  • Loading branch information
mjturt authored Jul 11, 2023
2 parents 0ba6bd5 + 2496170 commit 36b198d
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ROUTES } from 'benefit/handler/constants';
import { allApplicationStatuses } from 'benefit/handler/pages';
import { ALL_APPLICATION_STATUSES, ROUTES } from 'benefit/handler/constants';
import {
ApplicationListTableColumns,
ApplicationListTableTransforms,
} from 'benefit/handler/types/applicationList';
import { APPLICATION_STATUSES } from 'benefit-shared/constants';
import { ApplicationListItemData } from 'benefit-shared/types/application';
import {
IconSpeechbubbleText,
LoadingSpinner,
Expand All @@ -26,6 +26,8 @@ import { useApplicationList } from './useApplicationList';
export interface ApplicationListProps {
heading: string;
status: APPLICATION_STATUSES[];
list?: ApplicationListItemData[];
isLoading: boolean;
}

const buildApplicationUrl = (
Expand All @@ -41,19 +43,14 @@ const buildApplicationUrl = (
const ApplicationList: React.FC<ApplicationListProps> = ({
heading,
status,
list = [],
isLoading = true,
}) => {
const {
t,
list,
shouldShowSkeleton,
shouldHideList,
translationsBase,
getHeader,
} = useApplicationList(status);
const { t, translationsBase, getHeader } = useApplicationList();

const theme = useTheme();

const isAllStatuses: boolean = status === allApplicationStatuses;
const isAllStatuses: boolean = status === ALL_APPLICATION_STATUSES;

const columns = React.useMemo(() => {
const cols: ApplicationListTableColumns[] = [
Expand Down Expand Up @@ -186,7 +183,7 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
return cols.filter(Boolean);
}, [t, getHeader, status, theme, isAllStatuses]);

if (shouldShowSkeleton) {
if (isLoading) {
return (
<>
{heading && <$Heading>{`${heading}`}</$Heading>}
Expand All @@ -198,7 +195,7 @@ const ApplicationList: React.FC<ApplicationListProps> = ({
const statusAsString = isAllStatuses ? 'all' : status.join(',');
return (
<div data-testid={`application-list-${statusAsString}`}>
{!shouldHideList ? (
{list.length > 0 ? (
<Table
heading={`${heading} (${list.length})`}
theme={theme.components.table}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe('ApplicationList', () => {
const initialProps: ApplicationListProps = {
heading: 'Application List',
status: [APPLICATION_STATUSES.RECEIVED],
isLoading: true,
};

const getComponent = (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,87 +1,21 @@
import useApplicationsQuery from 'benefit/handler/hooks/useApplicationsQuery';
import { APPLICATION_STATUSES } from 'benefit-shared/constants';
import {
ApplicationData,
ApplicationListItemData,
} from 'benefit-shared/types/application';
import { TFunction, useTranslation } from 'next-i18next';
import { getFullName } from 'shared/utils/application.utils';
import { convertToUIDateFormat } from 'shared/utils/date.utils';

interface ApplicationListProps {
t: TFunction;
list: ApplicationListItemData[];
shouldShowSkeleton: boolean;
shouldHideList: boolean;
getHeader: (id: string) => string;
translationsBase: string;
}

const translationsBase = 'common:applications.list';

const useApplicationList = (
status: APPLICATION_STATUSES[],
excludeBatched?: boolean
): ApplicationListProps => {
const useApplicationList = (): ApplicationListProps => {
const { t } = useTranslation();
const query = useApplicationsQuery(status, '-submitted_at', excludeBatched);

const list = query.data?.map(
(application: ApplicationData): ApplicationListItemData => {
const {
id = '',
employee,
company,
submitted_at,
application_number: applicationNum,
calculation,
additional_information_needed_by,
status: applicationStatus,
unread_messages_count,
batch,
application_origin: applicationOrigin,
} = application;

return {
id,
status: applicationStatus,
companyName: company ? company.name : '-',
companyId: company ? company.business_id : '-',
employeeName:
getFullName(employee?.first_name, employee?.last_name) || '-',
submittedAt: convertToUIDateFormat(submitted_at) || '-',
additionalInformationNeededBy:
convertToUIDateFormat(additional_information_needed_by) || '-',
applicationNum,
// refactor when we have handler data
handlerName:
getFullName(
calculation?.handler_details?.first_name,
calculation?.handler_details?.last_name
) || '-',
unreadMessagesCount: unread_messages_count ?? 0,
batch: batch ?? null,
applicationOrigin,
};
}
);

const shouldShowSkeleton = query.isLoading;

const shouldHideList =
Boolean(query.error) ||
(!shouldShowSkeleton &&
Array.isArray(query.data) &&
query.data.length === 0);

const getHeader = (id: string): string =>
t(`${translationsBase}.columns.${id}`);

return {
t,
list: list || [],
shouldShowSkeleton,
shouldHideList,
getHeader,
translationsBase,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import useApplicationsQuery from 'benefit/handler/hooks/useApplicationsQuery';
import { APPLICATION_STATUSES } from 'benefit-shared/constants';
import {
ApplicationData,
ApplicationListItemData,
} from 'benefit-shared/types/application';
import { getFullName } from 'shared/utils/application.utils';
import { convertToUIDateFormat } from 'shared/utils/date.utils';

interface ApplicationListProps {
list: ApplicationListItemData[];
shouldShowSkeleton: boolean;
shouldHideList: boolean;
}

const useApplicationListData = (
status: APPLICATION_STATUSES[],
excludeBatched?: boolean
): ApplicationListProps => {
const query = useApplicationsQuery(status, '-submitted_at', excludeBatched);

const list = query.data?.map(
(application: ApplicationData): ApplicationListItemData => {
const {
id = '',
employee,
company,
submitted_at,
application_number: applicationNum,
calculation,
additional_information_needed_by,
status: applicationStatus,
unread_messages_count,
batch,
application_origin: applicationOrigin,
} = application;

return {
id,
status: applicationStatus,
companyName: company ? company.name : '-',
companyId: company ? company.business_id : '-',
employeeName:
getFullName(employee?.first_name, employee?.last_name) || '-',
submittedAt: convertToUIDateFormat(submitted_at) || '-',
additionalInformationNeededBy:
convertToUIDateFormat(additional_information_needed_by) || '-',
applicationNum,
// refactor when we have handler data
handlerName:
getFullName(
calculation?.handler_details?.first_name,
calculation?.handler_details?.last_name
) || '-',
unreadMessagesCount: unread_messages_count ?? 0,
batch: batch ?? null,
applicationOrigin,
};
}
);

const shouldShowSkeleton = query.isLoading;

const shouldHideList =
Boolean(query.error) ||
(!shouldShowSkeleton &&
Array.isArray(query.data) &&
query.data.length === 0);

return {
list: list || [],
shouldShowSkeleton,
shouldHideList,
};
};

export { useApplicationListData };
9 changes: 9 additions & 0 deletions frontend/benefit/handler/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,12 @@ export const APPLICATION_INITIAL_VALUES = {
applicationStep: DEFAULT_APPLICATION_STEP,
[APPLICATION_FIELD_KEYS.APPLICATION_ORIGIN]: APPLICATION_ORIGINS.HANDLER,
};

export const ALL_APPLICATION_STATUSES: APPLICATION_STATUSES[] = [
APPLICATION_STATUSES.RECEIVED,
APPLICATION_STATUSES.HANDLING,
APPLICATION_STATUSES.INFO_REQUIRED,
APPLICATION_STATUSES.ACCEPTED,
APPLICATION_STATUSES.DRAFT,
APPLICATION_STATUSES.REJECTED,
];
54 changes: 38 additions & 16 deletions frontend/benefit/handler/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import MainIngress from 'benefit/handler/components/mainIngress/MainIngress';
import AppContext from 'benefit/handler/context/AppContext';
import FrontPageProvider from 'benefit/handler/context/FrontPageProvider';
import { APPLICATION_STATUSES } from 'benefit-shared/constants';
import { ApplicationListItemData } from 'benefit-shared/types/application';
import { Tabs } from 'hds-react';
import { GetStaticProps, NextPage } from 'next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
Expand All @@ -13,16 +14,9 @@ import Container from 'shared/components/container/Container';
import theme from 'shared/styles/theme';

import { useApplicationList } from '../components/applicationList/useApplicationList';
import { useApplicationListData } from '../components/applicationList/useApplicationListData';
import { $BackgroundWrapper } from '../components/layout/Layout';

export const allApplicationStatuses: APPLICATION_STATUSES[] = [
APPLICATION_STATUSES.RECEIVED,
APPLICATION_STATUSES.HANDLING,
APPLICATION_STATUSES.INFO_REQUIRED,
APPLICATION_STATUSES.ACCEPTED,
APPLICATION_STATUSES.DRAFT,
APPLICATION_STATUSES.REJECTED,
];
import { ALL_APPLICATION_STATUSES } from '../constants';

const ApplicantIndex: NextPage = () => {
const {
Expand All @@ -45,17 +39,27 @@ const ApplicantIndex: NextPage = () => {

const translationBase = 'common:applications.list.headings';

const { t, list } = useApplicationList(allApplicationStatuses, true);
const { list, shouldShowSkeleton } = useApplicationListData(
ALL_APPLICATION_STATUSES,
true
);
const { t } = useApplicationList();

const getHeadingTranslation = (
headingStatus: APPLICATION_STATUSES | 'all'
): string => t(`${translationBase}.${headingStatus}`);

const getTabCount = (statuses: APPLICATION_STATUSES[]): number =>
list.filter((app: ApplicationListItemData) => statuses.includes(app.status))
.length;

const getListHeadingByStatus = (
headingStatus: APPLICATION_STATUSES | 'all',
statuses: APPLICATION_STATUSES[]
): string =>
list && list?.length > 0
? `${t(`${translationBase}.${headingStatus}`)} (${
list.filter((app) => statuses.includes(app.status)).length
})`
: `${t(`${translationBase}.${headingStatus}`)}`;
? `${getHeadingTranslation(headingStatus)} (${getTabCount(statuses)})`
: getHeadingTranslation(headingStatus);

return (
<FrontPageProvider>
Expand All @@ -65,7 +69,7 @@ const ApplicantIndex: NextPage = () => {
<Tabs theme={theme.components.tabs}>
<Tabs.TabList style={{ marginBottom: 'var(--spacing-m)' }}>
<Tabs.Tab>
{getListHeadingByStatus('all', allApplicationStatuses)}
{getListHeadingByStatus('all', ALL_APPLICATION_STATUSES)}
</Tabs.Tab>
<Tabs.Tab>
{getListHeadingByStatus(APPLICATION_STATUSES.DRAFT, [
Expand Down Expand Up @@ -97,31 +101,49 @@ const ApplicantIndex: NextPage = () => {

<Tabs.TabPanel>
<ApplicationList
isLoading={shouldShowSkeleton}
list={list}
heading={t(`${translationBase}.all`)}
status={allApplicationStatuses}
status={ALL_APPLICATION_STATUSES}
/>
</Tabs.TabPanel>

<Tabs.TabPanel>
<ApplicationList
isLoading={shouldShowSkeleton}
list={list.filter((app) =>
[APPLICATION_STATUSES.DRAFT].includes(app.status)
)}
heading={t(`${translationBase}.draft`)}
status={[APPLICATION_STATUSES.DRAFT]}
/>
</Tabs.TabPanel>

<Tabs.TabPanel>
<ApplicationList
isLoading={shouldShowSkeleton}
list={list.filter((app) =>
[APPLICATION_STATUSES.RECEIVED].includes(app.status)
)}
heading={t(`${translationBase}.received`)}
status={[APPLICATION_STATUSES.RECEIVED]}
/>
</Tabs.TabPanel>

<Tabs.TabPanel>
<ApplicationList
isLoading={shouldShowSkeleton}
list={list.filter((app) =>
[APPLICATION_STATUSES.HANDLING].includes(app.status)
)}
heading={t(`${translationBase}.handling`)}
status={[APPLICATION_STATUSES.HANDLING]}
/>
<ApplicationList
isLoading={shouldShowSkeleton}
list={list.filter((app) =>
[APPLICATION_STATUSES.INFO_REQUIRED].includes(app.status)
)}
heading={t(`${translationBase}.infoRequired`)}
status={[APPLICATION_STATUSES.INFO_REQUIRED]}
/>
Expand Down

0 comments on commit 36b198d

Please sign in to comment.