Skip to content

ERA-11397 & ERA-11399 #1290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion public/locales/en-US/details-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
},
"reportFormSummary": {
"reportTypeLabel": "Event Type",
"reportedByLabel": "Reported By"
"reportedByLabel": "Reported By",
"v2SchemaFormSummary": {
"collectionHumanizedValue": "{{collectionLength}} items"
}
}
}
5 changes: 4 additions & 1 deletion public/locales/es/details-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
},
"reportFormSummary": {
"reportTypeLabel": "Tipo de evento",
"reportedByLabel": "Reportado por"
"reportedByLabel": "Reportado por",
"v2SchemaFormSummary": {
"collectionHumanizedValue": "{{collectionLength}} elementos"
}
}
}
5 changes: 4 additions & 1 deletion public/locales/fr/details-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
},
"reportFormSummary": {
"reportTypeLabel": "Type d'Évenement",
"reportedByLabel": "Complété Par"
"reportedByLabel": "Complété Par",
"v2SchemaFormSummary": {
"collectionHumanizedValue": "{{collectionLength}} éléments"
}
}
}
5 changes: 4 additions & 1 deletion public/locales/ne-NP/details-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@
},
"reportFormSummary": {
"reportTypeLabel": "घटनाका प्रकार",
"reportedByLabel": "द्वारा रिपोर्ट गरिएको"
"reportedByLabel": "द्वारा रिपोर्ट गरिएको",
"v2SchemaFormSummary": {
"collectionHumanizedValue": "{{collectionLength}} वस्तुहरू"
}
},
"addReportButtonLabel": "नयाँ घटना बनाउनुहोस्"
}
3 changes: 3 additions & 0 deletions public/locales/pt/details-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@
"reportFormSummary": {
"reportTypeLabel": "Tipo de evento",
"reportedByLabel": "Reportado por"
},
"v2SchemaFormSummary": {
"collectionHumanizedValue": "{{collectionLength}} itens"
}
}
5 changes: 4 additions & 1 deletion public/locales/sw/details-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
},
"reportFormSummary": {
"reportTypeLabel": "Aina ya Tukio",
"reportedByLabel": "Imeorodheshwa na"
"reportedByLabel": "Imeorodheshwa na",
"v2SchemaFormSummary": {
"collectionHumanizedValue": "{{collectionLength}} vitu"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import { ReactComponent as ArrowIntoIcon } from '../../../common/images/icons/ar
import { ReactComponent as ArrowUpSimpleIcon } from '../../../common/images/icons/arrow-up-simple.svg';

import { fetchEvent } from '../../../ducks/events';
import { fetchEventTypeSchema } from '../../../ducks/event-schemas';
import { selectEventSchema } from '../../../selectors/event-schemas';
import { selectEventTypeByValue } from '../../../selectors/event-types';
import { TAB_KEYS } from '../../../constants';
import useNavigate from '../../../hooks/useNavigate';

Expand All @@ -31,10 +28,6 @@ const ContainedReportListItem = ({ cardsExpanded, onCollapse, onExpand, report }
const { t } = useTranslation('details-view', { keyPrefix: 'containedReportListItem' });

const reportFromEventStore = useSelector((state) => state.data.eventStore[report.id]);
const eventSchema = useSelector((state) => reportFromEventStore
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of all the logic removed here was only to render the form summary, so it didn't make sense to keep it here. I moved it to the ReportFormSummary component keeping the parent (this component) cleaner.

? selectEventSchema(state, reportFromEventStore.event_type, reportFromEventStore.id)
: null);
const eventType = useSelector((state) => selectEventTypeByValue(state, report.event_type));

const isOpen = useMemo(() => cardsExpanded.includes(report), [cardsExpanded, report]);

Expand All @@ -46,12 +39,6 @@ const ContainedReportListItem = ({ cardsExpanded, onCollapse, onExpand, report }
}
}, [dispatch, report.id, reportFromEventStore]);

useEffect(() => {
if (!!eventType && !eventSchema) {
dispatch(fetchEventTypeSchema(report.event_type, report.id));
}
}, [dispatch, eventSchema, eventType, report.event_type, report.id]);

return <li>
<div
className={`${activitySectionStyles.itemRow} ${activitySectionStyles.collapseRow}`}
Expand Down Expand Up @@ -88,12 +75,8 @@ const ContainedReportListItem = ({ cardsExpanded, onCollapse, onExpand, report }
in={isOpen}
>
<div>
{!!reportFromEventStore && !!eventSchema
? <ReportFormSummary
report={reportFromEventStore}
schema={eventSchema.schema}
uiSchema={eventSchema.uiSchema}
/>
{!!reportFromEventStore
? <ReportFormSummary report={reportFromEventStore} />
: <div className={styles.loaderWrapper}>
<MoonLoader color={LOADER_COLOR} size={LOADER_SIZE} />
</div>}
Expand Down
56 changes: 56 additions & 0 deletions src/ReportFormSummary/V1SchemaFormSummary/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useMemo } from 'react';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to divide (and conquer) the ReportFormSummary component into 3 parts:

  • The event details that are not part of the schema (reported by, priority, location, date...) those are rendered by the parent component.
  • The form summary for v1 schemas are rendered here.
  • And the form summary for v2 schemas also have their own file now 👍

import Form from '@rjsf/bootstrap-4';

import { formValidator } from '../../utils/events';

import {
AddButton,
ArrayFieldItemTemplate,
ArrayFieldTemplate,
BaseInputTemplate,
ExternalLinkField,
MoveDownButton,
MoveUpButton,
ObjectFieldTemplate,
RemoveButton,
} from '../../SchemaFields';

import * as styles from './styles.module.scss';

// For V1 schemas, we basically hack a rjsf Form so they render all the fields for us and we styled them so they don't
// look like fields.
const V1SchemaFormSummary = ({ eventSchema, report }) => {
const { schema, uiSchema } = eventSchema;

const filteredSchema = useMemo(() => {
const { properties = {} } = schema ?? {};
const eventDetailsKeys = Object.keys(report?.event_details ?? {});

return {
...schema,
properties: Object.entries(properties).reduce((acc, [key, value]) => {
return eventDetailsKeys.includes(key) ? { ...acc, [key]: value } : acc;
}, {})
};
}, [report, schema]);

return <Form
className={styles.form}
disabled
fields={{ externalLink: ExternalLinkField }}
formData={report?.event_details}
schema={filteredSchema}
showErrorList={false}
templates={{
ArrayFieldItemTemplate,
ArrayFieldTemplate,
BaseInputTemplate,
ButtonTemplates: { AddButton, MoveDownButton, MoveUpButton, RemoveButton },
ObjectFieldTemplate,
}}
uiSchema={uiSchema}
validator={formValidator}
/>;
};

export default V1SchemaFormSummary;
113 changes: 113 additions & 0 deletions src/ReportFormSummary/V1SchemaFormSummary/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
@use '../../common/styles/vars/colors';

.form {
[class*=react-datepicker-wrapper] {
div {
border: none;
padding: 0;
height: auto;
background: transparent;
}
}

[class*=row] {
padding: 0;

> * {
padding: 0;
}
}

[class*=col-] {
padding: 0;
}

label {
color: colors.$secondary-medium-gray;
font-size: 0.875rem;
margin: 0.75rem 0 0;
}

button,
input,
[class*=control] {
background-color: transparent !important;
border: transparent;
font-size: 1rem;
height: 1.5rem !important;
margin: 0;
padding: 0;
}

[class*=control] {
min-height: 1.5rem;
}

[class*=selectWidget] {
div {
height: 1.5rem;
display: block;
padding: 0;
}

[class*=singleValue] {
color: black;
margin: 0;
}
}

legend {
border-bottom: 1px solid colors.$light-gray-border;
font-size: 1rem;
font-weight: 500;
margin: 1.5rem 0 0.5rem;
}

h5 {
font-size: 1rem;
}

hr {
margin-bottom: 0;
}

button[class*=moveButton],
button[type=submit],
svg,
[class*=addButton],
[class*=triangle],
[class*=IndicatorsContainer] {
display: none !important;
}

[class*=checkboxesWidget] {
border: none;
max-height: none;
overflow-y: hidden;

[class*=checkbox] {
margin-bottom: 0;
padding-left: 0;

label {
color: black;
font-size: 1rem;
margin: 0;
opacity: 1;

&:before {
content: "\002D";
margin-right: 0.25rem;
}
}

input {
display: none;
}

&:has(input:not(:checked)) {
display: none;
}
}
}
}
75 changes: 75 additions & 0 deletions src/ReportFormSummary/V2SchemaFormSummary/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';

import getHumanizedFieldValue from '../../utils/v2-event-schemas/getHumanizedFieldValue';
import makeFieldsFromSchema from '../../utils/v2-event-schemas/makeFieldsFromSchema';
import { FORM_ELEMENT_TYPES, ROOT_CANVAS_ID } from '../../utils/v2-event-schemas/constants';

import * as styles from './styles.module.scss';

const FieldSummary = ({ field, formData, id }) => {
const { i18n, t } = useTranslation('details-view', { keyPrefix: 'reportFormSummary.v2SchemaFormSummary' });

const gpsFormat = useSelector((state) => state.view.userPreferences.gpsFormat);

return <>
<p className={styles.fieldLabel}>{field.details.label}</p>

<p className={styles.fieldValue}>{getHumanizedFieldValue(
field,
formData[id],
'-',
i18n.language,
gpsFormat,
t
)}</p>
</>;
};

const SectionSummary = ({ details, fields, formData }) => <div className={styles.section}>
<hr className={styles.separator} />

{details.label && <p className={styles.sectionLabel}>{details.label}</p>}

<div className={styles.columns}>
<div className={`${styles.column} ${details.columns === 1 ? styles.fullWidth : styles.halfWidthLeft}`}>
{details.leftColumn.map((fieldId) => fields[fieldId].type === FORM_ELEMENT_TYPES.HEADER
? <p
className={styles[`header-${fields[fieldId].details.size.toLowerCase()}`]}
key={fieldId}>
{fields[fieldId].details.label}
</p>
: <FieldSummary
field={fields[fieldId]}
formData={formData}
id={fieldId}
key={fieldId}
/>)}
</div>

{details.columns === 2 && <div className={`${styles.column} ${styles.halfWidthRight}`}>
{details.rightColumn.map((fieldId) => <FieldSummary
field={fields[fieldId]}
formData={formData}
id={fieldId}
key={fieldId}
/>)}
</div>}
</div>
</div>;

// For V2 schemas, we have a customized rendering of the details using utility functions like makeFieldsFromSchema and
// getHumanizedFieldValue following the schema definition.
const V2SchemaFormSummary = ({ eventSchema, formData }) => {
const fields = useMemo(() => makeFieldsFromSchema(eventSchema), [eventSchema]);

return fields[ROOT_CANVAS_ID]?.details.fields.map((sectionId) => <SectionSummary
details={fields[sectionId].details}
fields={fields}
formData={formData}
key={sectionId}
/>);
};

export default V2SchemaFormSummary;
Loading