Skip to content

Commit

Permalink
Add source information and reporting timeframe data in export
Browse files Browse the repository at this point in the history
  • Loading branch information
barshathakuri committed Dec 8, 2023
1 parent b059574 commit 4da2f34
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 25 deletions.
5 changes: 4 additions & 1 deletion src/views/DrefApplicationExport/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@
"drefApplicationExportRisk": "Risk",
"drefApplicationExportMitigation": "Mitigation action",
"drefApplicationSupportingDocumentation": "Supporting Documentation",
"drefAssessmentReportLink": "Assessment Report"
"drefAssessmentReportLink": "Assessment Report",
"SourceInformationSectionHeading": "Source Information",
"sourceInformationSourceNameTitle": "Source Name",
"sourceInformationSourceLinkTitle": "Source Link"
}
}
39 changes: 39 additions & 0 deletions src/views/DrefApplicationExport/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ export function Component() {
|| pmerDefined
|| communicationDefined;

const SourceInformationDefined = isDefined(drefResponse)
&& isDefined(drefResponse.source_information)
&& drefResponse.source_information.length > 0;

const showBudgetOverview = isTruthyString(drefResponse?.budget_file_details?.file);

const nsContactText = [
Expand Down Expand Up @@ -458,6 +462,41 @@ export function Component() {
{strings.drefApplicationSupportingDocumentation}
</Link>
)}
{SourceInformationDefined && (
<Container
heading={strings.SourceInformationSectionHeading}
childrenContainerClassName={styles.sourceInformationList}
headingLevel={3}
>
<div className={styles.nameTitle}>
{strings.sourceInformationSourceNameTitle}
</div>
<div className={styles.linkTitle}>
{strings.sourceInformationSourceLinkTitle}
</div>
{drefResponse?.source_information?.map(
(source, index) => (
<Fragment key={source.id}>
<DescriptionText className={styles.name}>
<div className={styles.nameList}>
{`${index + 1}. ${source.source_name}`}
</div>
</DescriptionText>
<DescriptionText className={styles.link}>
<Link
href={source.source_link}
external
withUnderline
>
{source?.source_link}
</Link>
</DescriptionText>
</Fragment>
),
)}

</Container>
)}
</>
)}
{showPreviousOperations && (
Expand Down
12 changes: 11 additions & 1 deletion src/views/DrefApplicationExport/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,28 @@
}
}

.risk-list {
.risk-list,
.source-information-list {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: var(--go-ui-width-separator-md);

.risk,
.name,
.link,
.mitigation {
background-color: var(--pdf-element-bg);
padding: var(--go-ui-spacing-xs);
}

.name-list {
display: flex;
gap: var(--go-ui-spacing-sm);
}

.risk-title,
.name-title,
.link-title,
.mitigation-title {
background-color: var(--pdf-element-bg);
padding: var(--go-ui-spacing-xs);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"namespace": "drefApplicationForm",
"strings": {
"sourceInformationNameLabel": "Sources of information (optional) name",
"sourceInformationLinkLabel": "Sources of information (optional) link",
"sourceInformationDeleteButton": "Delete Source Information"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {
type ArrayError,
useFormObject,
getErrorObject,
type SetValueArg,
} from '@togglecorp/toggle-form';
import { DeleteBinTwoLineIcon } from '@ifrc-go/icons';
import { randomString } from '@togglecorp/fujs';

import NonFieldError from '#components/NonFieldError';
import Button from '#components/Button';
import TextArea from '#components/TextArea';
import useTranslation from '#hooks/useTranslation';

import { type PartialDref } from '../../schema';
import i18n from './i18n.json';
import styles from './styles.module.css';

type SourceInformationFormFields = NonNullable<PartialDref['source_information']>[number];

interface Props {
value: SourceInformationFormFields;
error: ArrayError<SourceInformationFormFields> | undefined;
onChange: (value: SetValueArg<SourceInformationFormFields>, index: number) => void;
onRemove: (index: number) => void;
index: number;
disabled?: boolean;
}

function SourceInformation(props: Props) {
const {
error: errorFromProps,
onChange,
value,
index,
onRemove,
disabled,
} = props;

const strings = useTranslation(i18n);

const onFieldChange = useFormObject(
index,
onChange,
() => ({
client_id: randomString(),
}),
);

const error = (value && value.client_id && errorFromProps)
? getErrorObject(errorFromProps?.[value.client_id])
: undefined;

return (
<div className={styles.riskSecurityInput}>
<NonFieldError error={error} />
<TextArea
className={styles.input}
label={strings.sourceInformationNameLabel}
name="source_name"
value={value.source_name}
error={error?.source_name}
onChange={onFieldChange}
disabled={disabled}
withAsterisk
/>
<TextArea
className={styles.input}
label={strings.sourceInformationLinkLabel}
name="source_link"
value={value.source_link}
error={error?.source_link}
onChange={onFieldChange}
disabled={disabled}
withAsterisk
/>
<Button
className={styles.removeButton}
name={index}
onClick={onRemove}
variant="tertiary"
disabled={disabled}
title={strings.sourceInformationDeleteButton}
>
<DeleteBinTwoLineIcon />
</Button>
</div>
);
}

export default SourceInformation;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.risk-security-input {
display: flex;
align-items: flex-start;
gap: var(--go-ui-spacing-md);

.input {
flex-basis: 0;
flex-grow: 1;
}

.remove-button {
flex-shrink: 0;
}
}
5 changes: 4 additions & 1 deletion src/views/DrefApplicationForm/EventDetail/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"drefFormWhatWhereWhen": "What happened, where and when?",
"drefOperationalLearningPlatformLabel": "To access the Operational Learning Dashboard and check learnings for the country, click",
"drefOperationalLearningPlatformLink": "HERE",
"drefFormSelectImages": "Select images"
"drefFormSelectImages": "Select images",
"drefFormSourceInformationAddButton": "Add New Source Information",
"drefFormSourceInformationTitle": "Source Information",
"drefFormSourceInformationDescription": "Add the links and the name of the sources, the name will be shown in the export, as an hyperlink."
}
}
96 changes: 77 additions & 19 deletions src/views/DrefApplicationForm/EventDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { useCallback } from 'react';
import {
type Error,
type EntriesAsList,
getErrorObject,
useFormArray,
} from '@togglecorp/toggle-form';
import { WikiHelpSectionLineIcon } from '@ifrc-go/icons';
import { randomString } from '@togglecorp/fujs';

import { resolveUrl } from '#utils/resolveUrl';
import Container from '#components/Container';
Expand All @@ -12,6 +15,8 @@ import TextInput from '#components/TextInput';
import BooleanInput from '#components/BooleanInput';
import TextArea from '#components/TextArea';
import DateInput from '#components/DateInput';
import NonFieldError from '#components/NonFieldError';
import Button from '#components/Button';
import useTranslation from '#hooks/useTranslation';
import GoSingleFileInput from '#components/domain/GoSingleFileInput';
import Link from '#components/Link';
Expand All @@ -26,10 +31,13 @@ import {
} from '../common';
import { type PartialDref } from '../schema';

import SourceInformationInput from './SourceInformationInput';
import i18n from './i18n.json';
import styles from './styles.module.css';

type Value = PartialDref;
type SourceInformationFormFields = NonNullable<PartialDref['source_information']>[number];

interface Props {
value: Value;
setFieldValue: (...entries: EntriesAsList<Value>) => void;
Expand Down Expand Up @@ -58,6 +66,27 @@ function EventDetail(props: Props) {

const error = getErrorObject(formError);

const {
setValue: onSourceInformationChange,
removeValue: onSourceInformationRemove,
} = useFormArray<'source_information', SourceInformationFormFields>(
'source_information',
setFieldValue,
);

const handleSourceInformationAdd = useCallback(() => {
const newSourceInformationItem: SourceInformationFormFields = {
client_id: randomString(),
};

setFieldValue(
(oldValue: SourceInformationFormFields[] | undefined) => (
[...(oldValue ?? []), newSourceInformationItem]
),
'source_information' as const,
);
}, [setFieldValue]);

const operationalLearningPlatformUrl = resolveUrl(window.location.origin, 'preparedness#operational-learning');

return (
Expand Down Expand Up @@ -352,25 +381,6 @@ function EventDetail(props: Props) {
</GoSingleFileInput>
</InputSection>
)}
{value.type_of_dref !== TYPE_LOAN && (
<InputSection
title={strings.drefFormUploadPhotos}
description={strings.drefFormUploadPhotosLimitation}
contentSectionClassName={styles.imageInputContent}
>
<MultiImageWithCaptionInput
label={strings.drefFormSelectImages}
url="/api/v2/dref-files/multiple/"
name="images_file"
value={value.images_file}
onChange={setFieldValue}
fileIdToUrlMap={fileIdToUrlMap}
setFileIdToUrlMap={setFileIdToUrlMap}
error={getErrorObject(error?.images_file)}
disabled={disabled}
/>
</InputSection>
)}
{value.type_of_dref !== TYPE_ASSESSMENT && value.type_of_dref !== TYPE_LOAN && (
<InputSection
title={strings.drefFormScopeAndScaleEvent}
Expand All @@ -385,6 +395,54 @@ function EventDetail(props: Props) {
/>
</InputSection>
)}
{value.type_of_dref !== TYPE_LOAN && (
<>
<InputSection
title={strings.drefFormSourceInformationTitle}
description={strings.drefFormSourceInformationDescription}
>
<NonFieldError error={getErrorObject(error?.source_information)} />
{value.source_information?.map((source, index) => (
<SourceInformationInput
key={source.client_id}
index={index}
value={source}
onChange={onSourceInformationChange}
onRemove={onSourceInformationRemove}
error={getErrorObject(error?.risk_security)}
disabled={disabled}
/>
))}
<div className={styles.actions}>
<Button
name={undefined}
onClick={handleSourceInformationAdd}
variant="secondary"
disabled={disabled}
>
{strings.drefFormSourceInformationAddButton}
</Button>
</div>
</InputSection>
<InputSection
title={strings.drefFormUploadPhotos}
description={strings.drefFormUploadPhotosLimitation}
contentSectionClassName={styles.imageInputContent}
>
<MultiImageWithCaptionInput
label={strings.drefFormSelectImages}
url="/api/v2/dref-files/multiple/"
name="images_file"
value={value.images_file}
onChange={setFieldValue}
fileIdToUrlMap={fileIdToUrlMap}
setFileIdToUrlMap={setFileIdToUrlMap}
error={getErrorObject(error?.images_file)}
disabled={disabled}
/>
</InputSection>
</>
)}
</Container>
</div>
);
Expand Down
Loading

0 comments on commit 4da2f34

Please sign in to comment.