Content
View differences
Updated by Marc Alcobé 12 days ago
**As a** mobile app user
**I want** an Index page in the Meetings module that lists all my upcoming/past meetings and meeting series, with filtering and quick actions
**so that** I can quickly find, open, manage, and maintain my meeting schedule from the OpenProject Mobile App.
### Acceptance Criteria
* The Meetings Index is accessible from the app’s main navigation and opens as the default screen of the Meetings module.
* The Meetings Index shows a header with:
* A **Project filter** dropdown defaulting to **All projects**
* A **Scope filter** dropdown defaulting to **My meetings**
* A **Create (+)** action button
* Tapping the **Project filter** opens a searchable list of projects (same as Work Packages module) including:
* A scrollable list of projects the user can access
* Selecting a project updates the list and keeps the user on the Index
* Tapping the **Query filter** opens a list of scope options including at minimum:
* Default
* Meeting series
* Involvement
* The Index supports a search field (or search trigger) that filters the currently displayed list by meeting title.
* The Index provides a segmented control to switch between:
* **Upcoming** (default)
* **Past**
* In **Upcoming**, meetings are grouped into sections at minimum:
* **Today**
* **Tomorrow**
* **Later this week**
* **Next week and later**
* In **Past**, meetings are listed without groups in chronological order (closest to today first), and each meeting shows its date/time.
* Each meeting row displays:
* Meeting series name (if its a recurrent meeting)
* Meeting date and start time
* Meeting title
* Meeting duration
* Meeting location/URL if present (truncated with ellipsis when too long)
* Meetings that belong to a meeting series must be visually identifiable (recurring icon and series name) on the Index.
* Tapping a meeting row opens the **Meeting agenda** screen for that occurrence. (Implemented in <mention class="mention" data-id="75100" data-type="work_package" data-text="###75100">###75100</mention>)
* Each meeting row includes an overflow menu (“…”) with context actions.
* “View meeting series” (when the meeting is part of a series): this open the meeting series index page
* “Add to calendar” (Implemented in <mention class="mention" data-id="66656" data-type="work_package" data-text="###66656">###66656</mention>)
* “Delete occurrence”: this prompts a confirmation dialog and:
* On confirm, removes the occurrence from the list and add the toast bar with undo action
* On cancel, leaves it unchanged
* From the Index, a user can open a **Meeting series details** screen (either by “View meeting series” or by selecting a series item in a “Recurring meetings” scope).
* The Meeting series details screen shows:
* Series title
* Recurrence pattern summary (e.g., “Every week on Friday at 10:00” with timezone)
* A section “Agenda open” listing upcoming open occurrences
* A section “Planned” listing scheduled upcoming occurrences with their dates
* An overflow action for more with:
* “Edit template” (Implemented in <mention class="mention" data-id="75224" data-type="work_package" data-text="###75224">###75224</mention>)
* “Add to calendar” (Implemented in <mention class="mention" data-id="66656" data-type="work_package" data-text="###66656">###66656</mention>)
* “End meeting series”: this will change the finish meeting series date to today so no further meetings of the series will occur on the future but keep the past ones.
* “Delete meeting series”: prompts a confirmation dialog and:
* On confirm, removes the series and all occurrences, upcoming and past and display the toast bar with undo action
* In the Meeting series details screen:
* Each occurrence row provides an overflow menu with at minimum:
* “Open” (for eligible occurrences)
* “Cancel this occurrence”: this prompts a confirmation dialog and:
* On confirm, marks that occurrence as canceled and it no longer appears as upcoming in the Index
* On cancel, leaves it unchanged
* The Index reflects changes immediately after actions (delete/cancel/end) without requiring app restart.
* Empty states are handled:
* If no meetings match filters, show a clear empty state message and no empty section headers.
* Empty state message: "No meetings found matching the filter criteria"
* _The illustration for this empty screen needs to be designed \[TBD\]_
* Loading and error states are handled:
* While loading, show a loading skeleton list
* On error, show an error message with retry
* The displayed meeting times respect the user’s timezone and clearly indicate timezone where applicable (this should come from the API).
### Technical Notes
* Data model implications
* Introduce/confirm entities:
* **MeetingOccurrence** (id, meetingSeriesId?, title, startAt, endAt/duration, location/url, projectId, participants, status: scheduled/canceled/deleted, isOpen/agendaState if applicable)
* **MeetingSeries** (id, title, projectId, recurrenceRule, timezone, templateId, seriesStatus: active/ended/deleted)
* **MeetingTemplate** (id, content/agenda template fields)
* The Index list can be backed by a unified “meetings feed” endpoint returning occurrences plus series metadata needed for row rendering.
* API dependencies or contracts (OpenProject API v3 alignment)
* If reusing OpenProject API v3 patterns, ensure:
* Stable identifiers for occurrence vs series
* Hypermedia links between occurrence ↔ series ↔ template
* Required operations:
* List occurrences with filters: project, scope, search term, time window (upcoming/past)
* Retrieve series details including upcoming occurrences
* Delete occurrence
* Cancel occurrence (distinct from delete, if cancellation must preserve history)
* End series
* Delete series
* Fetch templates and edit template navigation target
* Backend vs frontend responsibilities
* Backend
* Compute section grouping boundaries (optional) or provide enough data for client grouping
* Enforce permission checks for destructive actions (delete/cancel/end)
* Define business rules: what happens to past occurrences when series is deleted/ended
* Frontend
* Apply grouping into “Today / Tomorrow / Later this week / Next week and later” based on user timezone
* Render row metadata consistently (duration formatting, URL truncation)
* Provide optimistic updates with rollback on failure for delete/cancel/end actions
* Caching, state, and performance considerations
* Cache last successful Index response per filter combination (project + scope + upcoming/past + search term).
* Debounce search input to avoid excessive queries.
* Pagination or incremental loading for “Past” to avoid large lists.
* Ensure actions invalidate only the relevant cached segments (e.g., delete occurrence invalidates upcoming list and series detail if the occurrence belongs to the opened series).
* Known constraints, tradeoffs, and risks
* Timezone edge cases around midnight and week boundaries can cause mis-grouping; grouping must use user timezone consistently.
* Distinguish “Delete occurrence” vs “Cancel this occurrence” semantics to avoid data loss and user confusion.
* Recurrence rule compatibility (RRULE variants) may limit editing or accurate previews on mobile.
### Permissions and Visibility Considerations
* The Meetings Index only shows meetings in projects the user can access.
* “My meetings” scope only includes meetings where the user is an attendee/organiser (define involvement rules explicitly).
* Actions visibility depends on role/permissions:
* Only users with meeting management permissions can:
* Delete occurrence
* Cancel occurrence
* End meeting series
* Delete meeting series
* Edit template
* If a user can view but not manage:
* Overflow menu hides destructive actions and shows read-only actions only (e.g., Add to calendar, View meeting series).
* If a meeting is in a read-only state (e.g., past, closed, already canceled):
* Actions that are not applicable must be hidden or disabled with explanatory text.
### Translation Considerations
* Localize all UI labels and section headers, including:
* “Meetings”, “All projects”, “My meetings”, “Upcoming”, “Past”
* Group headers: “Today”, “Tomorrow”, “Later this week”, “Next week and later”, “Agenda open”, “Planned”
* Menu actions: “View meeting series”, “Add to calendar”, “Delete occurrence”, “Edit template”, “End meeting series”, “Delete meeting series”, “Cancel this occurrence”, “Open”
* Confirmation dialog titles, bodies, and buttons
* Do NOT translate:
* Project names
* Meeting titles (user-generated content) unless they are system templates explicitly marked translatable
* URLs
* Timezone abbreviations (e.g., CEST) and IANA timezone identifiers
* Recurrence rule strings if shown in any debug/advanced view
### Out of Scope
* Triggering Full calendar integration configuration (accounts, permissions, OS-level settings) beyond triggering “Add to calendar”. As will be implemented in <mention class="mention" data-id="66656" data-type="work_package" data-text="###66656">###66656</mention>
* Offline creation or offline editing of meetings/series/templates.
* Cross-device sync conflict resolution details (assumed handled by backend).
* Advanced sorting customization beyond the defined upcoming/past grouping and default chronological ordering within groups.
* The rest of the meeting module included in other features of the parent Epic
**I want** an Index page in the Meetings module that lists all my upcoming/past meetings and meeting series, with filtering and quick actions
**so that** I can quickly find, open, manage, and maintain my meeting schedule from the OpenProject Mobile App.
### Acceptance Criteria
* The Meetings Index is accessible from the app’s main navigation and opens as the default screen of the Meetings module.
* The Meetings Index shows a header with:
* A **Project filter** dropdown defaulting to **All projects**
* A **Scope filter** dropdown defaulting to **My meetings**
* A **Create (+)** action button
* Tapping the **Project filter** opens a searchable list of projects (same as Work Packages module) including:
* A scrollable list of projects the user can access
* Selecting a project updates the list and keeps the user on the Index
* Tapping the **Query filter** opens a list of scope options including at minimum:
* Default
* Meeting series
* Involvement
* The Index supports a search field (or search trigger) that filters the currently displayed list by meeting title.
* The Index provides a segmented control to switch between:
* **Upcoming** (default)
* **Past**
* In **Upcoming**, meetings are grouped into sections at minimum:
* **Today**
* **Tomorrow**
* **Later this week**
* **Next week and later**
* In **Past**, meetings are listed without groups in chronological order (closest to today first), and each meeting shows its date/time.
* Each meeting row displays:
* Meeting series name (if its a recurrent meeting)
* Meeting date and start time
* Meeting title
* Meeting duration
* Meeting location/URL if present (truncated with ellipsis when too long)
* Meetings that belong to a meeting series must be visually identifiable (recurring icon and series name) on the Index.
* Tapping a meeting row opens the **Meeting agenda** screen for that occurrence. (Implemented in <mention class="mention" data-id="75100" data-type="work_package" data-text="###75100">###75100</mention>)
* Each meeting row includes an overflow menu (“…”) with context actions.
* “View meeting series” (when the meeting is part of a series): this open the meeting series index page
* “Add to calendar” (Implemented in <mention class="mention" data-id="66656" data-type="work_package" data-text="###66656">###66656</mention>)
* “Delete occurrence”: this prompts a confirmation dialog and:
* On confirm, removes the occurrence from the list and add the toast bar with undo action
* On cancel, leaves it unchanged
* From the Index, a user can open a **Meeting series details** screen (either by “View meeting series” or by selecting a series item in a “Recurring meetings” scope).
* The Meeting series details screen shows:
* Series title
* Recurrence pattern summary (e.g., “Every week on Friday at 10:00” with timezone)
* A section “Agenda open” listing upcoming open occurrences
* A section “Planned” listing scheduled upcoming occurrences with their dates
* An overflow action for more with:
* “Edit template” (Implemented in <mention class="mention" data-id="75224" data-type="work_package" data-text="###75224">###75224</mention>)
* “Add to calendar” (Implemented in <mention class="mention" data-id="66656" data-type="work_package" data-text="###66656">###66656</mention>)
* “End meeting series”: this will change the finish meeting series date to today so no further meetings of the series will occur on the future but keep the past ones.
* “Delete meeting series”: prompts a confirmation dialog and:
* On confirm, removes the series and all occurrences, upcoming and past and display the toast bar with undo action
* In the Meeting series details screen:
* Each occurrence row provides an overflow menu with at minimum:
* “Open” (for eligible occurrences)
* “Cancel this occurrence”: this prompts a confirmation dialog and:
* On confirm, marks that occurrence as canceled and it no longer appears as upcoming in the Index
* On cancel, leaves it unchanged
* The Index reflects changes immediately after actions (delete/cancel/end) without requiring app restart.
* Empty states are handled:
* If no meetings match filters, show a clear empty state message and no empty section headers.
* Empty state message: "No meetings found matching the filter criteria"
* _The illustration for this empty screen needs to be designed \[TBD\]_
* Loading and error states are handled:
* While loading, show a loading skeleton list
* On error, show an error message with retry
* The displayed meeting times respect the user’s timezone and clearly indicate timezone where applicable (this should come from the API).
### Technical Notes
* Data model implications
* Introduce/confirm entities:
* **MeetingOccurrence** (id, meetingSeriesId?, title, startAt, endAt/duration, location/url, projectId, participants, status: scheduled/canceled/deleted, isOpen/agendaState if applicable)
* **MeetingSeries** (id, title, projectId, recurrenceRule, timezone, templateId, seriesStatus: active/ended/deleted)
* **MeetingTemplate** (id, content/agenda template fields)
* The Index list can be backed by a unified “meetings feed” endpoint returning occurrences plus series metadata needed for row rendering.
* API dependencies or contracts (OpenProject API v3 alignment)
* If reusing OpenProject API v3 patterns, ensure:
* Stable identifiers for occurrence vs series
* Hypermedia links between occurrence ↔ series ↔ template
* Required operations:
* List occurrences with filters: project, scope, search term, time window (upcoming/past)
* Retrieve series details including upcoming occurrences
* Delete occurrence
* Cancel occurrence (distinct from delete, if cancellation must preserve history)
* End series
* Delete series
* Fetch templates and edit template navigation target
* Backend vs frontend responsibilities
* Backend
* Compute section grouping boundaries (optional) or provide enough data for client grouping
* Enforce permission checks for destructive actions (delete/cancel/end)
* Define business rules: what happens to past occurrences when series is deleted/ended
* Frontend
* Apply grouping into “Today / Tomorrow / Later this week / Next week and later” based on user timezone
* Render row metadata consistently (duration formatting, URL truncation)
* Provide optimistic updates with rollback on failure for delete/cancel/end actions
* Caching, state, and performance considerations
* Cache last successful Index response per filter combination (project + scope + upcoming/past + search term).
* Debounce search input to avoid excessive queries.
* Pagination or incremental loading for “Past” to avoid large lists.
* Ensure actions invalidate only the relevant cached segments (e.g., delete occurrence invalidates upcoming list and series detail if the occurrence belongs to the opened series).
* Known constraints, tradeoffs, and risks
* Timezone edge cases around midnight and week boundaries can cause mis-grouping; grouping must use user timezone consistently.
* Distinguish “Delete occurrence” vs “Cancel this occurrence” semantics to avoid data loss and user confusion.
* Recurrence rule compatibility (RRULE variants) may limit editing or accurate previews on mobile.
### Permissions and Visibility Considerations
* The Meetings Index only shows meetings in projects the user can access.
* “My meetings” scope only includes meetings where the user is an attendee/organiser (define involvement rules explicitly).
* Actions visibility depends on role/permissions:
* Only users with meeting management permissions can:
* Delete occurrence
* Cancel occurrence
* End meeting series
* Delete meeting series
* Edit template
* If a user can view but not manage:
* Overflow menu hides destructive actions and shows read-only actions only (e.g., Add to calendar, View meeting series).
* If a meeting is in a read-only state (e.g., past, closed, already canceled):
* Actions that are not applicable must be hidden or disabled with explanatory text.
### Translation Considerations
* Localize all UI labels and section headers, including:
* “Meetings”, “All projects”, “My meetings”, “Upcoming”, “Past”
* Group headers: “Today”, “Tomorrow”, “Later this week”, “Next week and later”, “Agenda open”, “Planned”
* Menu actions: “View meeting series”, “Add to calendar”, “Delete occurrence”, “Edit template”, “End meeting series”, “Delete meeting series”, “Cancel this occurrence”, “Open”
* Confirmation dialog titles, bodies, and buttons
* Do NOT translate:
* Project names
* Meeting titles (user-generated content) unless they are system templates explicitly marked translatable
* URLs
* Timezone abbreviations (e.g., CEST) and IANA timezone identifiers
* Recurrence rule strings if shown in any debug/advanced view
### Out of Scope
* Triggering
* Offline creation or offline editing of meetings/series/templates.
* Cross-device sync conflict resolution details (assumed handled by backend).
* Advanced sorting customization beyond the defined upcoming/past grouping and default chronological ordering within groups.
* The rest of the meeting module included in other features of the parent Epic