Skip to content

Commit

Permalink
HAI-1463 Change frontend to use hanke status returned from backend
Browse files Browse the repository at this point in the history
Status of hanke can be either DRAFT, PUBLIC or ENDED and this
information is returned from backend. Changed frontend to keep
track of the backend state.

At this point this affects displaying draft state notification
if hanke status is DRAFT as well as displaying
Add application button in hanke form and hanke view
if hanke status is PUBLIC.

Also removed the saveType field as it's not needed anymore.
  • Loading branch information
markohaarni committed Oct 12, 2023
1 parent 0e70262 commit ac1b2e0
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 90 deletions.
44 changes: 16 additions & 28 deletions src/domain/hanke/edit/HankeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,17 @@ import HankeFormHaitat from './HankeFormHaitat';
import HankeFormSummary from './HankeFormSummary';
import FormNotifications from './components/FormNotifications';
import './HankeForm.styles.scss';
import { HankeData, HANKE_SAVETYPE } from '../../types/hanke';
import { HankeData } from '../../types/hanke';
import { convertFormStateToHankeData } from './utils';
import api from '../../api/api';
import MultipageForm from '../../forms/MultipageForm';
import FormActions from '../../forms/components/FormActions';
import { useLocalizedRoutes } from '../../../common/hooks/useLocalizedRoutes';
import ApplicationAddDialog from '../../application/components/ApplicationAddDialog';

async function saveHanke({
data,
saveType = HANKE_SAVETYPE.DRAFT,
}: {
data: HankeDataFormState;
saveType?: HANKE_SAVETYPE;
navigateTo?: string;
}) {
if (!data.alueet?.length) {
return data;
}

async function saveHanke({ data }: { data: HankeDataFormState; navigateTo?: string }) {
const requestData = {
...convertFormStateToHankeData(data),
saveType,
};

const response = data.hankeTunnus
Expand Down Expand Up @@ -76,7 +64,7 @@ const HankeForm: React.FC<React.PropsWithChildren<Props>> = ({

const {
register,
formState: { errors, isDirty, isValid },
formState: { errors, isDirty },
getValues,
setValue,
handleSubmit,
Expand All @@ -85,6 +73,7 @@ const HankeForm: React.FC<React.PropsWithChildren<Props>> = ({
const isNewHanke = !formData.hankeTunnus;

const formValues = getValues();
const isHankePublic = formValues.status === 'PUBLIC';
const formHeading = isNewHanke
? t('hankeForm:pageHeaderNew')
: t('hankeForm:pageHeaderEdit', { hankeTunnus: formData.hankeTunnus });
Expand All @@ -99,9 +88,8 @@ const HankeForm: React.FC<React.PropsWithChildren<Props>> = ({
onSuccess(data, { navigateTo }) {
setValue('hankeTunnus', data.hankeTunnus);
setValue('tormaystarkasteluTulos', data.tormaystarkasteluTulos);
if (data.alueet) {
setShowNotification('success');
}
setValue('status', data.status);
setShowNotification('success');
if (navigateTo) {
navigate(navigateTo);
}
Expand All @@ -119,13 +107,12 @@ const HankeForm: React.FC<React.PropsWithChildren<Props>> = ({
function save() {
hankeMutation.mutate({
data: getValues(),
saveType: HANKE_SAVETYPE.SUBMIT,
navigateTo: HANKEPORTFOLIO.path,
});
}

function saveAndAddApplication() {
hankeMutation.mutate({ data: getValues(), saveType: HANKE_SAVETYPE.SUBMIT });
hankeMutation.mutate({ data: getValues() });
setShowAddApplicationDialog(true);
}

Expand Down Expand Up @@ -210,14 +197,15 @@ const HankeForm: React.FC<React.PropsWithChildren<Props>> = ({
)}
{lastStep && (
<>
<Button
variant="secondary"
iconLeft={<IconPlusCircle aria-hidden />}
onClick={saveAndAddApplication}
disabled={!isValid}
>
{t('hankeForm:saveAndAddButton')}
</Button>
{isHankePublic && (
<Button
variant="secondary"
iconLeft={<IconPlusCircle aria-hidden />}
onClick={saveAndAddApplication}
>
{t('hankeForm:saveAndAddButton')}
</Button>
)}
<Button
variant="primary"
iconLeft={<IconSaveDiskette aria-hidden />}
Expand Down
4 changes: 3 additions & 1 deletion src/domain/hanke/edit/components/ContactsSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const ContactSummary: React.FC<{ contact: HankeContact | HankeMuuTaho }> = ({ co
if (CONTACT_FORMFIELD.TYYPPI in contact) {
return (
<div style={{ marginBottom: 'var(--spacing-s)' }}>
<p>{t(`form:yhteystiedot:contactType:${contact.tyyppi}`)}</p>
{contact.tyyppi !== undefined && (
<p>{t(`form:yhteystiedot:contactType:${contact.tyyppi}`)}</p>
)}
<p>{contact.nimi}</p>
<p>{contact.ytunnus}</p>
<p>{contact.email}</p>
Expand Down
30 changes: 13 additions & 17 deletions src/domain/hanke/edit/components/HankeDraftStateNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Notification } from 'hds-react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { HankeData } from '../../../types/hanke';
import { useIsHankeValid } from '../hooks/useIsHankeValid';

type Props = {
/** Hanke data */
Expand All @@ -12,28 +11,25 @@ type Props = {
};

/**
* Show hanke draft state notification if there are missing required fields in hanke
* Show hanke draft state notification if it's status is DRAFT
*/
const HankeDraftStateNotification: React.FC<Props> = ({ hanke, className }) => {
const { t } = useTranslation();

// Check if hanke has all the required fields filled
const isHankeValid = useIsHankeValid(hanke);

if (isHankeValid) {
return null;
if (hanke.status === 'DRAFT') {
return (
<Notification
size="small"
label={t('hankePortfolio:draftStateLabel')}
className={className}
type="alert"
>
{t('hankePortfolio:draftState')}
</Notification>
);
}

return (
<Notification
size="small"
label={t('hankePortfolio:draftStateLabel')}
className={className}
type="alert"
>
{t('hankePortfolio:draftState')}
</Notification>
);
return null;
};

export default HankeDraftStateNotification;
2 changes: 1 addition & 1 deletion src/domain/hanke/hankeUsers/UserRightsCheck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function UserRightsCheck({
requiredRight: keyof typeof Rights;
/** hankeTunnus of the hanke that the right is required for */
hankeTunnus?: string;
children: React.ReactElement;
children: React.ReactElement | null;
}) {
const { data: signedInUser } = useUserRightsForHanke(hankeTunnus);

Expand Down
13 changes: 10 additions & 3 deletions src/domain/hanke/hankeView/HankeView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,20 @@ test('Draft state notification is rendered when hanke is in draft state', async
expect(draftStateElements[0]).toBeInTheDocument();
});

test('Add application and End hanke buttons are disabled when hanke is in draft state', async () => {
test('Add application button is displayed when hanke is in PUBLIC state', async () => {
render(<HankeViewContainer hankeTunnus="HAI22-2" />);

await waitForLoadingToFinish();

expect(screen.queryByRole('button', { name: /lisää hakemus/i })).toBeInTheDocument();
});

test('Add application button is hidden when hanke is not in PUBLIC state', async () => {
render(<HankeViewContainer hankeTunnus="HAI22-1" />);

await waitForLoadingToFinish();

expect(screen.getByRole('button', { name: /lisää hakemus/i })).toBeDisabled();
expect(screen.getByRole('button', { name: /päätä hanke/i })).toBeDisabled();
expect(screen.queryByRole('button', { name: /lisää hakemus/i })).not.toBeInTheDocument();
});

test('Draft state notification is not rendered when hanke is not in draft state', async () => {
Expand Down
32 changes: 14 additions & 18 deletions src/domain/hanke/hankeView/HankeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import OwnHankeMap from '../../map/components/OwnHankeMap/OwnHankeMap';
import OwnHankeMapHeader from '../../map/components/OwnHankeMap/OwnHankeMapHeader';
import CompressedAreaIndex from '../hankeIndexes/CompressedAreaIndex';
import HankeDraftStateNotification from '../edit/components/HankeDraftStateNotification';
import { useIsHankeValid } from '../edit/hooks/useIsHankeValid';
import { SKIP_TO_ELEMENT_ID } from '../../../common/constants/constants';
import { useApplicationsForHanke } from '../../application/hooks/useApplications';
import ApplicationList from '../../application/components/ApplicationList';
Expand Down Expand Up @@ -160,7 +159,6 @@ const HankeView: React.FC<Props> = ({
setShowAddApplicationDialog(false);
}

const isHankeValid = useIsHankeValid(hankeData);
const isCancelPossible = applicationsResponse
? canHankeBeCancelled(applicationsResponse.applications)
: true;
Expand All @@ -175,7 +173,9 @@ const HankeView: React.FC<Props> = ({

const areasTotalSurfaceArea = calculateTotalSurfaceArea(hankeData.alueet);

const { omistajat, rakennuttajat, toteuttajat, muut, tormaystarkasteluTulos, alueet } = hankeData;
const { omistajat, rakennuttajat, toteuttajat, muut, tormaystarkasteluTulos, alueet, status } =
hankeData;
const isHankePublic = status === 'PUBLIC';

const tabList = features.hanke ? (
<TabList className={styles.tabList}>
Expand Down Expand Up @@ -228,15 +228,16 @@ const HankeView: React.FC<Props> = ({
</Button>
</UserRightsCheck>
<UserRightsCheck requiredRight="EDIT_APPLICATIONS" hankeTunnus={hankeData.hankeTunnus}>
<Button
variant="primary"
iconLeft={<IconPlusCircle aria-hidden="true" />}
theme="coat"
onClick={addApplication}
disabled={!isHankeValid}
>
{t('hankeList:buttons:addApplication')}
</Button>
{isHankePublic ? (
<Button
variant="primary"
iconLeft={<IconPlusCircle aria-hidden="true" />}
theme="coat"
onClick={addApplication}
>
{t('hankeList:buttons:addApplication')}
</Button>
) : null}
</UserRightsCheck>
</FeatureFlags>
<FeatureFlags flags={['hanke', 'accessRights']}>
Expand All @@ -251,12 +252,7 @@ const HankeView: React.FC<Props> = ({
</FeatureFlags>
<FeatureFlags flags={['hanke']}>
<UserRightsCheck requiredRight="DELETE" hankeTunnus={hankeData.hankeTunnus}>
<Button
variant="primary"
iconLeft={<IconCross aria-hidden="true" />}
theme="black"
disabled={!isHankeValid}
>
<Button variant="primary" iconLeft={<IconCross aria-hidden="true" />} theme="black">
{t('hankeList:buttons:endHanke')}
</Button>
</UserRightsCheck>
Expand Down
10 changes: 10 additions & 0 deletions src/domain/hanke/portfolio/HankePortfolio.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,14 @@ describe.only('HankePortfolio', () => {
expect(screen.queryAllByTestId('hankeEditLink')).toHaveLength(1);
});
});

test('Should show draft state notification for hankkeet that are in draft state', async () => {
render(<HankePortfolioComponent hankkeet={hankeList} />);

expect(
screen.getAllByText(
'Hanke on luonnostilassa. Alueiden haittatiedot ja muut pakolliset tiedot on täytettävä hankkeen julkaisemiseksi ja lupien lisäämiseksi.',
),
).toHaveLength(1);
});
});
22 changes: 11 additions & 11 deletions src/domain/mocks/data/hankkeet-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-11-27T11:33:17.0875Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -41,7 +41,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2022-11-27T11:43:43.481215Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'PUBLIC',
liikennehaittaindeksi: {
indeksi: 4.0,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -240,7 +240,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2022-11-27T11:44:22.443735Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'PUBLIC',
omistajat: [
{
id: 1,
Expand Down Expand Up @@ -343,7 +343,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-11-27T12:07:41.210244Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -366,7 +366,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2022-11-23T10:37:36.362778Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -389,7 +389,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-11-30T13:43:13.599591Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -412,7 +412,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-11-30T13:43:15.322044Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -435,8 +435,8 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-11-30T13:43:24.301796Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
omistajat: [],
status: 'DRAFT',
rakennuttajat: [],
toteuttajat: [],
muut: [],
Expand All @@ -458,7 +458,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-11-30T13:43:27.330822Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -481,7 +481,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-12-01T14:22:11.838844Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand All @@ -504,7 +504,7 @@ const hankkeet: HankeDataDraft[] = [
createdAt: '2020-12-01T14:34:24.443622Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand Down
2 changes: 1 addition & 1 deletion src/domain/mocks/hankeDraft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const hankeDraft: HankeDataDraft = {
createdAt: '2023-11-27T11:33:17.0875Z',
modifiedBy: null,
modifiedAt: null,
saveType: 'DRAFT',
status: 'DRAFT',
omistajat: [],
rakennuttajat: [],
toteuttajat: [],
Expand Down
Loading

0 comments on commit ac1b2e0

Please sign in to comment.