Skip to content

ERA-9844: Photo/attachment field element#1606

Open
luixlive wants to merge 4 commits into
developfrom
ERA-9844
Open

ERA-9844: Photo/attachment field element#1606
luixlive wants to merge 4 commits into
developfrom
ERA-9844

Conversation

@luixlive

@luixlive luixlive commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Render attachment fields in the v2 event type schema form renderer that upload files using the chunked upload endpoints from the usercontent API.

Evidence

image

Relevant link(s)

Notes

I created an event type "Arrest with Attachments" were you can test attachments in sections, collections, and nested collections.

luixlive added 3 commits June 12, 2026 14:32
- Introduced a new Attachment component for file uploads in the report manager.
- Updated localization files for multiple languages to include attachment-related strings.
- Implemented chunked file upload functionality with Redux integration.
- Added tests for the new Attachment component and its associated functionalities.
- Refactored file utility functions for better handling of file uploads.
- Updated localization files for multiple languages to include new attachment-related error messages and button labels.
- Added support for displaying upload progress and handling multiple file uploads in the Attachment component.
- Refactored validation logic to merge schema and upload errors for better user feedback.
- Improved test coverage for the Attachment component and its functionalities.
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown

🚀 PR Environment Deployed

App Sync Health Image
pr-web-era-9844 ✅ Synced ✅ Healthy 710f563843db27d9003ddc615386d333c0f9023f

Access: https://era-9844.dev.pamdas.org

View in ArgoCD

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class support for attachment/photo fields in the v2 event SchemaForm renderer, including chunked uploads via the usercontent API and UI-level validation for in-progress/failed uploads.

Changes:

  • Introduces a new ATTACHMENT SchemaForm element with drag/drop, previews, upload progress, and download/expand actions.
  • Adds data.userContent Redux slice + selector to track chunked upload state and validates form submission when uploads are pending/failed.
  • Extends schema transforms + humanized value utilities and updates report i18n strings (plus dependency/tooling bumps).

Reviewed changes

Copilot reviewed 30 out of 36 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
.yarnrc.yml Bumps Yarn release reference to 4.16.0.
package.json Updates dependencies (Auth0, RJSF, axios, i18next, react, router, stylelint, vite) and Yarn version.
yarn.lock Lockfile updates corresponding to dependency bumps.
src/common/images/icons/cloud-upload.svg New icon used by attachment dropzone UI.
src/common/images/icons/video.svg New icon for video attachments.
src/common/images/icons/volume.svg New icon for audio attachments.
src/ducks/user-content/index.js New Redux duck implementing chunked upload lifecycle + abort/removal behavior.
src/ducks/user-content/index.test.js MSW-backed tests for chunked upload + reducer behaviors.
src/i18n.js Bumps i18n files version to invalidate cached translations.
src/reducers/index.js Registers userContent reducer under state.data.
src/selectors/user-content/index.js Adds memoized selector to fetch upload state by upload IDs.
src/selectors/user-content/index.test.js Tests for selectUploadStatesByIds.
src/utils/file.js Removes old file utilities module (replaced by folder-based module).
src/utils/file/index.js Adds/updates shared file utilities, including toast-based duplicate detection and base64 image fetch.
src/utils/file/index.test.js Unit tests for the new file utility module.
src/utils/v2-event-schemas/getHumanizedFieldValue/index.js Adds humanized rendering for attachment values (count-based).
src/utils/v2-event-schemas/getHumanizedFieldValue/index.test.js Tests for new attachment humanization behavior.
src/utils/v2-event-schemas/transformSchemaToFormElements/transformField/transformAttachmentField/index.js Extends attachment schema transform to include description/min/max items.
src/utils/v2-event-schemas/transformSchemaToFormElements/transformField/transformAttachmentField/index.test.js Tests for new attachment transform fields/defaults.
src/ReportManager/DetailsSection/index.js Passes report metadata through to SchemaForm for attachment rendering.
src/ReportManager/DetailsSection/SchemaForm/index.js Renders attachment fields and merges schema + upload validation errors on submit.
src/ReportManager/DetailsSection/SchemaForm/index.test.js Adds submit-time upload validation test coverage.
src/ReportManager/DetailsSection/SchemaForm/utils/useUploadValidations/index.js New hook to compute upload-related validation errors (including nested collection items).
src/ReportManager/DetailsSection/SchemaForm/utils/useUploadValidations/index.test.js Tests for upload validation logic, including nesting and precedence.
src/ReportManager/DetailsSection/SchemaForm/formElements/Attachment/index.js New Attachment field UI with upload progress, saved-file actions, drag/drop, and accessibility affordances.
src/ReportManager/DetailsSection/SchemaForm/formElements/Attachment/index.test.js Comprehensive tests for Attachment UI behavior and accessibility expectations.
src/ReportManager/DetailsSection/SchemaForm/formElements/Attachment/styles.module.scss Styling for attachment list/dropzone/progress indicator/focus states.
src/ReportManager/DetailsSection/SchemaForm/formElements/Collection/styles.module.scss Tweaks focus styling (outline vs border).
public/locales/en-US/reports.json Adds attachment field strings + upload error messages + attachment humanized value strings.
public/locales/es/reports.json Same as above (Spanish).
public/locales/fr/reports.json Same as above (French).
public/locales/ne-NP/reports.json Same as above (Nepali).
public/locales/pt/reports.json Same as above (Portuguese).
public/locales/sw/reports.json Same as above (Swahili).

Comment thread src/utils/file/index.js
Comment thread src/utils/v2-event-schemas/getHumanizedFieldValue/index.js
Comment thread src/ReportManager/DetailsSection/SchemaForm/index.test.js Outdated
- Added localization for attachment-related messages in English, Spanish, French, Nepali, Portuguese, and Swahili.
- Refactored the Attachment component to improve action button handling and state management.
- Implemented cleanup logic to clear user content on component unmount.
- Updated file utility functions to ensure proper content type handling during image fetching.
- Improved test coverage for the Attachment component and user content management.
import { API_URL } from '../../constants';
import globallyResettableReducer from '../../reducers/global-resettable';

export const COMPLETE_CHUNKED_UPLOAD_API_URL = (uploadId) => `${API_URL}usercontent/chunked-uploads/${uploadId}/complete/`;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

New duck to handle interactions with the new "user content" API. It has three actions creators:

  • clearUserContent: clears the reducer to abort request controllers and revoke object URLs. Useful when the user navigates away from an event and the form is unmounted to avoid memory leaks.
  • removeFile: same as the previous one but for a single upload.
  • startChunkedUpload: receives a file and starts a chunked upload asynchronously. It just returns the uploadId so the upload can be references from the store, that is updated with the status and upload progress of the file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The new Attachment component to render attachment fields in v2 event type schema forms. It stores an array of objects with the property uploadId and renders the field following the designs. It uploads selected files using the new user-content duck action creators and consuming its reducer.

Image

@luixlive luixlive Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

New validation hook, symmetric to useSchemaValidations, but this one to validate that attachment uploads are valid when the user tries to submit an event form. Possible errors are failed or pending uploads, and it traverses the form data to validate attachment files nested in collections.

Image

@@ -1,15 +1,20 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import isEqual from 'react-fast-compare';
import { merge } from 'lodash-es';

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

A few updates in the SchemaForm component that renders v2 event type schema forms:

  • It now receives the new metadata event property, which right now contains the attachments' files metadata.
  • Runs the new upload validations.
  • Renders attachment fields.
  • Dispatches clearUserContent to clear the user content reducer when the form is unmounted and avoid memory leaks.


const selectUserContent = (state) => state.data.userContent;

export const selectUploadStatesByIds = createSelector(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

New selector file for user-content related selectors. The only selector right now is to get upload states by ids. Used by Attachment component to select the state of its uploads.

Comment thread src/utils/file/index.js

import { showToast } from '../toast';

export const convertFileListToArray = (list) => Array.from(list ?? []);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not really a new file, but it was moved into a folder to add tests.

const use12HourFormat = shouldUse12HourFormat(language);

switch (field.type) {
case FORM_ELEMENT_TYPES.ATTACHMENT:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Humanized values of attachment fields are only the count of files attached. This text is shown in form summarized previews.

See the text "2 files":
Image

uiSchema,
formElements,
) => {
const attachmentFieldJSONSchema = jsonSchema.properties[attachmentFieldName];

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Update the transformAttachmentField method to include the new properties: description, maxItems, and minItems.

Comment thread .yarnrc.yml

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yarn and several dependencies were updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants