User Interface medium complexity mobile
1
Dependencies
0
Dependents
0
Entities
1
Integrations

Description

Multi-source file picker allowing coordinators to select documents or images from the device camera roll or file system. Enforces format constraints (PDF, JPEG, PNG) and the 5-attachment-per-activity limit with inline validation feedback.

Feature: Document Attachments for Activities

attachment-picker-ui

Summaries

The Attachment Picker UI enables coordinators to attach supporting evidence — photographs, scanned forms, and documents — directly to activity records from their mobile device, eliminating the need for separate file transfer workflows or desktop-based document management. This strengthens the evidential quality of reported activities, which is important for audits and funding verification by bodies such as Bufdir. By enforcing format and count constraints inline, the component prevents invalid attachments from entering the system before any upload occurs, reducing support requests and data quality issues downstream. The result is a faster, more reliable documentation workflow for field coordinators, directly improving the completeness and auditability of activity records without adding administrative overhead.

Medium complexity mobile UI component with a dependency on the attachment-upload-service for actual file transfer. The picker itself is a Flutter widget integrating with the device's native file picker and camera roll APIs — platform permission handling (iOS NSPhotoLibraryUsageDescription, Android READ_EXTERNAL_STORAGE) must be configured in the app manifest before this component can be tested on real devices. The 5-attachment-per-activity limit and allowed MIME type list (PDF, JPEG, PNG) must be confirmed with the product owner early, as they are enforced here and in the upload service. Testing must cover: permission denial flows, limit enforcement at 5 existing attachments, unsupported file type selection, and large file size rejection.

Dependency on attachment-upload-service means integration testing requires that service to be available. Low deployment risk as a UI-only component with no direct database access.

Flutter mobile widget that orchestrates multi-source file selection via a bottom sheet presenting camera roll and file system options. Uses the file_picker or image_picker package (or both) to surface native pickers. openPicker() receives the current attachment count for the activity; if count >= max, showCountLimitError() is called immediately without opening the picker. Post-selection, the picked file's MIME type is validated against the allowlist — unsupported types trigger showFormatError().

File size is checked against a configurable maxMb threshold before invoking onFileSelected(). The selected file is passed to attachment-upload-service for upload; the picker itself holds no upload logic. State management should be handled by the parent widget or a provider — the picker is stateless beyond the open/close lifecycle. Inline validation messages must use the design system's error token colours and be screen-reader accessible.

Responsibilities

  • Present source selection sheet (camera roll vs. file system)
  • Filter selectable files to allowed MIME types
  • Enforce maximum attachment count and show inline error when exceeded
  • Display selected file name and size preview before confirming upload

Interfaces

openPicker(activityId, currentCount)
onFileSelected(file)
onPickerCancelled()
showCountLimitError(max)
showFormatError(mimeType)
showSizeLimitError(maxMb)

Relationships

Dependencies (1)

Components this component depends on

Used Integrations (1)

External integrations and APIs this component relies on