Skip to content

Commit

Permalink
Merge branch 'develop' into service-units-2
Browse files Browse the repository at this point in the history
  • Loading branch information
NC-jsAhonen committed Aug 1, 2023
2 parents f083865 + 278c5ee commit 92d404c
Show file tree
Hide file tree
Showing 65 changed files with 2,448 additions and 671 deletions.
18 changes: 18 additions & 0 deletions src/application/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// @flow
import {createAction} from 'redux-actions';

import type {
ApplicantInfoCheckAttributesNotFoundAction,
FetchApplicantInfoCheckAttributesAction,
ReceiveApplicantInfoCheckAttributesAction,
ReceiveUpdatedApplicantInfoCheckItemAction,
} from '$src/application/types';

export const fetchApplicantInfoCheckAttributes = (): FetchApplicantInfoCheckAttributesAction =>
createAction('mvj/application/FETCH_APPLICANT_INFO_CHECK_ATTRIBUTES')();
export const receiveApplicantInfoCheckAttributes = (payload: Object): ReceiveApplicantInfoCheckAttributesAction =>
createAction('mvj/application/RECEIVE_APPLICANT_INFO_CHECK_ATTRIBUTES')(payload);
export const applicantInfoCheckAttributesNotFound = (): ApplicantInfoCheckAttributesNotFoundAction =>
createAction('mvj/application/APPLICANT_INFO_CHECK_ATTRIBUTES_NOT_FOUND')();
export const receiveUpdatedApplicantInfoCheckItem = (payload: Object): ReceiveUpdatedApplicantInfoCheckItemAction =>
createAction('mvj/application/RECEIVE_UPDATED_APPLICANT_INFO_CHECK_ITEM')(payload);
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import FileDownloadLink from '$components/file/FileDownloadLink';
import {getApplicationAttachmentDownloadLink} from '$src/plotApplications/helpers';
import FormTextTitle from '$components/form/FormTextTitle';
import FormText from '$components/form/FormText';
import ApplicationAnswersSection from '$src/application/ApplicationAnswersSection';
import ApplicationAnswersSection from '$src/application/components/ApplicationAnswersSection';

type Props = {
section: FormSection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {SavedApplicationFormSection} from '$src/plotApplications/types';
import Collapse from '$components/collapse/Collapse';
import SubTitle from '$components/content/SubTitle';
import type {SectionExtraComponentProps} from '$src/application/types';
import ApplicationAnswersField from '$src/application/ApplicationAnswersField';
import ApplicationAnswersField from '$src/application/components/ApplicationAnswersField';

type Props = {
section: FormSection,
Expand Down
22 changes: 22 additions & 0 deletions src/application/components/_applicant-info-check.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.ApplicantInfoCheck {
&, span, a {
font-size: $font-small;
}

.row {
line-height: 1.5rem;
}
}

.ApplicantInfoCheckEdit {
&, span, a {
font-size: $font-small;
}

.ApplicantInfoCheckEditItem--dirty {
.column:nth-child(2) > * {
background-color: darken($is-dirty-color, 5%);
}
}
}

41 changes: 41 additions & 0 deletions src/application/components/infoCheck/ApplicantInfoCheck.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @flow
import React, {Component} from 'react';
import {getLabelOfOption} from '$util/helpers';
import {Column, Row} from 'react-foundation';
import {getUserFullName} from '$src/users/helpers';

type Props = {
infoChecks: Object,
infoCheckStateOptions: Object,
};

class ApplicantInfoCheck extends Component<Props> {
render(): React$Node {
const {
infoChecks,
infoCheckStateOptions,
} = this.props;

return (
<Row className="ApplicantInfoCheck">
{infoChecks.map((item) => {
const statusText = getLabelOfOption(infoCheckStateOptions, item.data.state);

return <Column small={6} key={item.kind.type}>
<Row>
<Column small={8}>
<span>{item.kind.label}</span>
</Column>
<Column small={4}>
{statusText}
{item.data.preparer && <>, {getUserFullName(item.data.preparer)}</>}
</Column>
</Row>
</Column>;
})}
</Row>
);
}
}

export default ApplicantInfoCheck;
164 changes: 164 additions & 0 deletions src/application/components/infoCheck/ApplicantInfoCheckEdit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// @flow
import React, {Component} from 'react';
import {Row} from 'react-foundation';
import {connect} from 'react-redux';
import {change} from 'redux-form';

import ApplicantInfoCheckModal from '$src/application/components/infoCheck/ApplicantInfoCheckModal';
import {ApplicantInfoCheckFieldPaths, ApplicantInfoCheckFieldTitles, ApplicantTypes} from '$src/application/enums';
import ApplicantInfoCheckEditItem from '$src/application/components/infoCheck/ApplicantInfoCheckEditItem';
import FormText from '$components/form/FormText';
import {getApplicantInfoCheckFormName} from '$src/application/helpers';

type OwnProps = {
infoCheckIds: Array<number>,
answer: Object,
submissionErrors: Array<{
id: number,
kind: ?Object,
error: ?Object | ?Array<Object>,
}>,
};

type Props = {
...OwnProps,
change: typeof change,
};

type State = {
isModalOpen: boolean,
modalCheckItem: ?Object,
checkItemForm: ?string,
modalPage: number,
};

class ApplicantInfoCheckEdit extends Component<Props, State> {
state: State = {
isModalOpen: false,
modalCheckItem: null,
checkItemForm: null,
modalPage: 0,
};

openModal = (checkItem: Object, form: string, skipToForm: boolean): void => {
this.setState(() => ({
isModalOpen: true,
modalCheckItem: checkItem,
checkItemForm: form,
modalPage: (!skipToForm && checkItem.kind.external) ? 1 : 2,
}));
};

closeModal = (): void => {
this.setState(() => ({
isModalOpen: false,
modalCheckItem: null,
checkItemForm: '',
modalPage: 0,
}));
};

setPage = (page: number): void => {
this.setState(() => ({
modalPage: page,
}));
}

saveInfoCheck = (data: Object): void => {
const {change} = this.props;
const {checkItemForm} = this.state;

if (checkItemForm) {
Object.keys(data).forEach((field) => {
change(checkItemForm, `data.${field}`, data[field]);
});

this.closeModal();
}
}

renderErrors(): React$Node {
const {submissionErrors} = this.props;

if (submissionErrors.length === 0) {
return null;
}

let content = [];
submissionErrors.map((infoCheckItem) => {
try {
if (infoCheckItem.error instanceof Array) {
content.push(<ul>
{infoCheckItem.error.map((error, i) => <li key={i}>{error}</li>)}
</ul>);
} else if (infoCheckItem.error instanceof Error) {
content.push(infoCheckItem.error.message);
} else if (typeof infoCheckItem.error === 'object') {
const errorObject: Object = infoCheckItem.error;
content.push(<ul>
{Object.keys(errorObject).map((key) => {
const fieldLabelKey = Object.keys(ApplicantInfoCheckFieldPaths).find(
(path) => ApplicantInfoCheckFieldPaths[path] === key);

return <li key={key}>
{infoCheckItem.kind?.label} - {fieldLabelKey ? ApplicantInfoCheckFieldTitles[fieldLabelKey] : key}:{' '}
{errorObject[key].length !== undefined
? errorObject[key].join(', ')
: errorObject[key]}
</li>;
})}
</ul>);
} else {
content.push(infoCheckItem.error);
}
} catch {
content.push(JSON.stringify(infoCheckItem.error));
}
});

return <FormText className="alert">
Tallennus ei onnistunut:{' '}
{content}
</FormText>;
}

render(): React$Node {
const {
isModalOpen,
modalCheckItem,
modalPage,
} = this.state;

const {
infoCheckIds,
answer,
submissionErrors,
} = this.props;

const applicantType = answer?.metadata?.applicantType;

return (
<div className="ApplicantInfoCheckEdit">
<Row>
{infoCheckIds.map((id, index) => <ApplicantInfoCheckEditItem
key={index} formName={getApplicantInfoCheckFormName(id)} openModal={this.openModal} />)}
</Row>
<ApplicantInfoCheckModal
isOpen={isModalOpen}
modalPage={modalPage}
setPage={this.setPage}
onClose={this.closeModal}
onSubmit={(data) => this.saveInfoCheck(data)}
infoCheck={modalCheckItem}
businessId={applicantType === ApplicantTypes.COMPANY ? answer.metadata.identifier : undefined}
personId={applicantType === ApplicantTypes.PERSON ? answer.metadata.identifier : undefined}
/>
{submissionErrors && this.renderErrors()}
</div>
);
}
}

export default (connect(null, {
change,
})(ApplicantInfoCheckEdit): React$ComponentType<OwnProps>);
67 changes: 67 additions & 0 deletions src/application/components/infoCheck/ApplicantInfoCheckEditItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// @flow

import React from 'react';
import flowRight from 'lodash/flowRight';
import {connect} from 'react-redux';
import {getFormValues, reduxForm} from 'redux-form';
import {Column, Row} from 'react-foundation';
import classNames from 'classnames';

import type {Attributes} from '$src/types';
import {getApplicantInfoCheckAttributes} from '$src/application/selectors';
import {getFieldOptions, getLabelOfOption} from '$util/helpers';
import {getUserFullName} from '$src/users/helpers';

type OwnProps = {
openModal: Function,
formName: string,
};

type Props = {
...OwnProps,
dirty: boolean,
infoCheckAttributes: Attributes,
formValues: Object,
};

const ApplicantInfoCheckEditItem = (({formValues, dirty, openModal, formName, infoCheckAttributes}: Props) => {
const infoCheckStatusOptions = getFieldOptions(infoCheckAttributes, 'state');
const statusText = getLabelOfOption(infoCheckStatusOptions, formValues.data.state);

return <Column
small={6}
key={formValues.kind.type}
className={classNames('ApplicantInfoCheckEditItem', {
'ApplicantInfoCheckEditItem--dirty': dirty,
})}>
<Row>
<Column small={8}>
{formValues.kind.external &&
<a onClick={() => openModal(formValues, formName, false)}>
{formValues.kind.label}
</a>}
{!formValues.kind.external && <span>{formValues.kind.label}</span>}
</Column>
<Column small={4}>
{formValues.kind.external && !formValues.data.preparer && <span>{statusText}</span>}
{(!formValues.kind.external || formValues.data.preparer) &&
<a onClick={() => openModal(formValues, formName, true)}>
{statusText}
{formValues.data.preparer && <>, {getUserFullName(formValues.data.preparer)}</>}
</a>}
</Column>
</Row>
</Column>;
});

export default (flowRight(connect((state, props) => {
const formValues = getFormValues(props.formName)(state);

return {
formValues,
form: props.formName,
infoCheckAttributes: getApplicantInfoCheckAttributes(state),
};
}), reduxForm({
destroyOnUnmount: false,
}))(ApplicantInfoCheckEditItem): React$ComponentType<OwnProps>);
Loading

0 comments on commit 92d404c

Please sign in to comment.