Content
View differences
Updated by Marc Alcobé about 3 years ago
# User Story
**As a** project team member
**I want t**o see my project calendar in my personal calendar
**So that** I don't have to maintain two different calendars to organize my work.
# Use case examples
1. Release dates and other project milestones
2. Submission deadlines of artefacts that require collaboration with other team members
3. Extend certificats (e.g. SSL, SMIME)
While trying to introduce OpenProject in a team that I’m part of, I realised that there is no way to integrate the calendar with MS Outlook, Apple Calendar, Google Calendar, and the likes. It would greatly increase the visibility of project planning if people were able to see changes in their preferred calendar apps, instead of having to check the OpenProject calendar webpage. Export functionality would provide a very natural means to integrate OpenProject with existing planning and coordination routines established in teams (most of which will be using a calendar app of sorts).
# Acceptance criteria
* Separate project permission
* Menu entry to create and copy URL with the label "**Subscribe to iCalendar"**
* This menu entry opens a modal with an explanation and a warning banner. In the action bar of the modal there is the "**Copy URL**" action which will trigger the creation of the token. Once the user clicks on the button the modal closes and a toast appears on top of the screen to indicate the success or error to create and copy the token URL.
* Caching
* The calendar invite includes the main information of the work package organised in this order:
* **LOCATION:** For the work package _**URL**_
* **SUMMARY:** For the work package _**subject**_. We've decided decoded to not display the _**work package ID**_.
* **DESCRIPTION:** Containing this elements:
1. _**Project**_
2. _**Type**_Â _**Type**_ (with a square colour emoji)
3. _**Status**_
4. _**Assignee**_
5. _**Priority**_ (with a round colour emoji)
6. _**Description:**_ up _**Description**_ (up to 240 X characters of the description description)
* **ORGANIZER:** For the _**author, assignee or accountable (TBD)**_ of the work package.
* **DTSTART:** For the work package _**start date**_.
* **DTEND:** For the work package _**finish date**_.
* The event should not be editable in the calendar client side.
* All iCalendar tokens The iCalendar-token can be revoked in "My account -> Access tokens"
* The permission to subscribe to iCalendars
# Attribute mapping
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Example</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Work package attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">mapped iCal attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">iCal notes</th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">OpenProject GmbH//OpenProject Core Project//EN</td><td class="op-uc-p op-uc-table--cell">Container calendar and company</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-7-3-product-identifier.html">PRODID</a></td><td class="op-uc-p op-uc-table--cell">This is set as a part MUST in iCal and specifies who created this iCal and for what and its never represented in the UI</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">V1.0</td><td class="op-uc-p op-uc-table--cell">Version of the project roles settings. For iCal</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-7-4-version.html">VERSION</a></td><td class="op-uc-p op-uc-table--cell">This is the migration path, version of iCal and is a MUST and it is not represented in the UI</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">Work package (type of calendar entry)</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-6-1-event-component.htmlhttps://icalendar.org/iCalendar-RFC-5545/3-6-1-event-component.html">VEVENT</a> or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-6-3-journal-component.html">VJOURNAL</a></td><td class="op-uc-p op-uc-table--cell">VJOURNAL seemed the most ideal event as basically a Journal entry without need to be a meeting or a event but it is not displayed properly in a lot of calendars therefore I tried also a normal VEVENT.</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:id @community.openproject.com</td><td class="op-uc-p op-uc-table--cell">Calendar entry ID</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-7-unique-identifier.html">UID</a> (id)</td><td class="op-uc-p op-uc-table--cell">This is a MUST in iCAL and must be unique for each calendar entry in all the roles iCal and therefore is recommended to use specific methods of creation <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-7-unique-identifier.html">explained here</a></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:id</td><td class="op-uc-p op-uc-table--cell">Work package ID</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-8-1-iana-properties.html">IANA</a> (text)</td><td class="op-uc-p op-uc-table--cell">This can be added in the calendar entry as a "IANA" extra property. All compliant applications are expected to be able to parse but it can be that has they are ignored.</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://community.openproject.org/projects/openproject/work_packages/15339">.../openproject/work_packages/15339</a></td><td class="op-uc-p op-uc-table--cell">Work package URL</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-6-uniform-resource-locator.html">URL</a> (link) or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-7-location.html">LOCATION</a></td><td class="op-uc-p op-uc-table--cell">Not clear if this information is shared with the setting "**View calendars**" active iCal "URI" or should be included as an LOCATION to be displayed (or in the description)</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:subject</td><td class="op-uc-p op-uc-table--cell">Subject</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-12-summary.html">SUMMARY</a> (text)</td><td class="op-uc-p op-uc-table--cell">The subject could be directly matched as the "SUMMARY" of the calendar entry</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Delivering the first version of the new fancy product.</td><td class="op-uc-p op-uc-table--cell">Description</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-5-description.html">DESCRIPTION</a> (text)</td><td class="op-uc-p op-uc-table--cell">The description is always displayed in the calendar entries. We need to decide what is the content we want to display in this description as I assume we don't want to show the full WP description here.</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:status</td><td class="op-uc-p op-uc-table--cell">Status</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-2-categories.html">CATEGORIES</a> (text)</td><td class="op-uc-p op-uc-table--cell">"STATUS" is limited to the type of entry journal and there is not a lot of options, <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-11-status.html">see here</a></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:type</td><td class="op-uc-p op-uc-table--cell">Work package type</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-2-categories.html">CATEGORIES</a> (text)</td><td class="op-uc-p op-uc-table--cell">iCal "TYPE" will also not work here as it specifies the type of calendar not of each entry.</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:priority</td><td class="op-uc-p op-uc-table--cell">Priority</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-9-priority.html">PRIORITY</a> (integer)</td><td class="op-uc-p op-uc-table--cell">"PRIORITY" can be used to see the priority in between the elements of a calendar and they are defined by default have "**Subscribe numbers form 0 to iCalendars**" active (and 9 that can be ranged also as LOW, MEDIUM and HIGH</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:author</td><td class="op-uc-p op-uc-table--cell">Author</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-3-organizer.html">ORGANIZER</a> (cal-address) or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-2-contact.html">CONTACT</a> (text)</td><td class="op-uc-table--cell"><p class="op-uc-p">If we extract the Author and map it as Organizer this could appear in the iCal invite</p><p class="op-uc-p">This is even possible with LDAP URI</p></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:assignee</td><td class="op-uc-p op-uc-table--cell">Assignee</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-2-contact.html">CONTACT</a> (text)</td><td class="op-uc-p op-uc-table--cell">We could use the assignee and map it with the "CONTACT" reference in the calendar entry. This is even possible with LDAP URI. But cannot be used if used for Author</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">20.01.2023</td><td class="op-uc-p op-uc-table--cell">Creation date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-7-1-date-time-created.html">CREATED</a> (date-time)</td><td class="op-uc-p op-uc-table--cell">Maps the WP creation date with</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">20.01.2023</td><td class="op-uc-p op-uc-table--cell">Last modification date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-7-3-last-modified.html">LAST-MODIFIED</a> (date-time)</td><td class="op-uc-p op-uc-table--cell">We could map the last modification date in the activity with the "LAST-MODIFIED"</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:startDate</td><td class="op-uc-p op-uc-table--cell">Start date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-2-4-date-time-start.html">DTSTART</a> (date)</td><td class="op-uc-p op-uc-table--cell"></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:dueDate</td><td class="op-uc-p op-uc-table--cell">Finish date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-2-2-date-time-end.html">DTEND</a> or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-2-3-date-time-due.html">DUE</a> (date)</td><td class="op-uc-p op-uc-table--cell">Need to see what works better if "DTEND" or "DUE"</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">workPackageValue:15339:duration</td><td class="op-uc-p op-uc-table--cell">Duration</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-3-6-duration.html">DURATION</a> (duration)</td><td class="op-uc-p op-uc-table--cell"></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell"><mention class="mention" data-id="25541" data-type="work_package" data-text="#25541">#25541</mention> </td><td class="op-uc-p op-uc-table--cell">Parent work package</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-5-related-to.html">RELATED-TO</a></td><td class="op-uc-p op-uc-table--cell">Can be used to establish if the work package is related to any other way around). calendar entries (WP)</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">Any other information</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-4-comment.html">COMMENT</a> (text)</td><td class="op-uc-p op-uc-table--cell">Everything can be always added to an extra section besides the description called "COMMENT"</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">Extra custom values</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-8-1-iana-properties.html">IANA</a> (text) or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-8-2-non-standard-properties.html">X-</a> (text with other type acceptance)</td><td class="op-uc-p op-uc-table--cell">This are extra full custom properties that all compliant applications are expected to be able to parse but it can be that they are ignored.</td></tr></tbody></table></figure>
# Ideal iCal example
Using this work package as example the journal entry in a iCalendar ideal format should be:
```text
* On top of BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//OpenProject GmbH//OpenProject Core Project//EN
BEGIN:VEVENT
DTSTAMP:20230120T000000
CREATED:20230120T151920
LAST-MODIFIED:20230120T183250
DTSTART:20230112T000000
DTEND:20230415T000000
DURATION:P94D
UID:15339@community.openproject.com
WPID:15339
URL:https://community.openproject.org/projects/
openproject/work_packages/15339
ORGANIZER;CN=Max Mustermann:mailto:m.mustermann@example.com
CONTACT:Jonas Rietz\, OpenProject GmbH\, mailto:j.rietz@example.com
SUMMARY:Share project calendars using the role iCalendar format
DESCRIPTION:Work package description:/User Story/
As a admin setting checkbox will be available project team member/I want to see my project
calendar in "**Administration > my personal calendar/So that I don't
have to maintain two different calendars to organize
my work.
CATEGORIES:🟩 FEATURE,In development
PRIORITY:5
RELATED-TO:25541@community.openproject.com
END:VJOURNAL
END:VCALENDAR
```
This code has been successfully validated using the [iCalendar Validator](https://icalendar.org/validator.html#results) and it has no errors. Also you can download the ICS file that I'm using to try all this configurations [here](https://community.openproject.org/api/v3/attachments/49599/content).
# Calendar clients UI
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Work package attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">mapped iCal attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">OX</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Thunderbird</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Mailbox</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Outlook</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Yahoo</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Google Calendar</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Google Calendar (Android)</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Calendar (MAC)</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Calendar (iOS)</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">BusyCal</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">OneCalendar</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Fantastical</th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Container calendar and company</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-7-3-product-identifier.html">PRODID</a></td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Version of the iCal</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-7-4-version.html">VERSION</a></td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Work package (type of calendar entry)</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-6-1-event-component.htmlhttps://icalendar.org/iCalendar-RFC-5545/3-6-1-event-component.html">VEVENT</a> or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-6-3-journal-component.html">VJOURNAL</a></td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td><td class="op-uc-p op-uc-table--cell">-</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Calendar entry ID</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-7-unique-identifier.html">UID</a> (id)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Work package ID</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-8-1-iana-properties.html">IANA</a> (text)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Displayed with the IANA name</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Work package URL</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-6-uniform-resource-locator.html">URL</a> (link) or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-7-location.html">LOCATION</a></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>URL or Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>URL or Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>URL or Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>URL</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Location</strong></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Subject</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-12-summary.html">SUMMARY</a> (text)</td><td class="op-uc-p op-uc-table--cell"><strong>Title</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Title</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Subject</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Title</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Event title</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Title</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Title</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Event name</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Event name</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Event name</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Subject</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Subject</strong></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Description</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-5-description.html">DESCRIPTION</a> (text)</td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Notes</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Notes</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Description</strong></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Status</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-2-categories.html">CATEGORIES</a> (text)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Category</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Category</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Tags</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Work package type</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-2-categories.html">CATEGORIES</a> (text)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Category</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Category</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Tags</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Priority</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-9-priority.html">PRIORITY</a> (integer)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Priority</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Author</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-3-organizer.html">ORGANIZER</a> (cal-address) or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-2-contact.html">CONTACT</a> (text)</td><td class="op-uc-p op-uc-table--cell">Not displayed (it display you as organiser)</td><td class="op-uc-p op-uc-table--cell"><strong>Organizer</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed (it display you as organiser)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Invited (organiser)</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Invitee (organiser)</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Invitee (organiser)</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Invitee (organiser)</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Invitee (organiser)</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Organiser</strong></td><td class="op-uc-p op-uc-table--cell"><strong>People (organiser)</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Invitee (organiser)</strong></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Assignee</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-2-contact.html">CONTACT</a> (text)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Invitees</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Creation date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-7-1-date-time-created.html">CREATED</a> (date-time)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Last modification date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-7-3-last-modified.html">LAST-MODIFIED</a> (date-time)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Edited</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Start date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-2-4-date-time-start.html">DTSTART</a> (date)</td><td class="op-uc-p op-uc-table--cell"><strong>Starts on</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Starts on</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Start</strong></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Finish date</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-2-2-date-time-end.html">DTEND</a> or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-2-3-date-time-due.html">DUE</a> (date)</td><td class="op-uc-p op-uc-table--cell"><strong>Ends on</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Ends on</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Finish date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Finish date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>Due date</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End</strong></td><td class="op-uc-p op-uc-table--cell"><strong>End</strong></td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Duration</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-3-6-duration.html">DURATION</a> (duration)</td><td class="op-uc-p op-uc-table--cell">Established by dates > Working days**" which but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td><td class="op-uc-p op-uc-table--cell">Established by dates but not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Parent work package</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-4-5-related-to.html">RELATED-TO</a></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Any other information</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-1-4-comment.html">COMMENT</a> (text)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Extra custom values</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-8-1-iana-properties.html">IANA</a> (text) or <a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-8-8-2-non-standard-properties.html">X-</a> (text with other type acceptance)</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell"><strong>Displayed with the X- or IANA name</strong></td><td class="op-uc-p op-uc-table--cell">Not displayed</td><td class="op-uc-p op-uc-table--cell">Not displayed</td></tr></tbody></table></figure>
# Conclusion and iCal construction
After all the analysis, unfortunately the majority of the iCal events that are described in their documentation are not displayed at all in the most common calendar clients. Therefore we will be available once # need to use the field that are displayed in all the clients to ensure that all the work package information is completed. displayed:
# Mockups * **LOCATION:** For the work package _**URL**_
* **SUMMARY:** For the work package _**subject**_. We've decoded to not display the _**work package ID**_.
* **DESCRIPTION:** After the first discussion we decided to display this elements in the descrpition:
1. Project
2. Type (with a square colour emoji)
3. Status
4. Assignee
5. Priority (with a round colour emoji)
6. Description (up to X characters of the description)
* **ORGANIZER:** For the _**author, assignee or accountable (TBD)**_ of the work package.
* **DTSTART:** For the work package _**start date**_.
* **DTEND:** For the work package _**finish date**_.
#### With this information this would be one of the examples for a work package iCalendar event code ([download and try it here](https://community.openproject.org/api/v3/attachments/49712/content)):
```text
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//OpenProject GmbH//OpenProject Core Project//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-CALNAME:OpenProject Calendar view
BEGIN:VEVENT
UID:15339@community.openproject.com
LOCATION:https://community.openproject.org/projects/openproject/work_packages/15339
SUMMARY:Share project calendars using the iCalendar format
DESCRIPTION:Project: OpenProject\nType: 🟩 FEATURE\nStatus: In development\nAssignee: Max Mustermann\nPriority: 🟢 Medium\n\rWork package description: User Story As a project team member I want to see my project calendar in my personal calendar So that I don't have to maintain two different calendars to organize my work...
DTSTART;VALUE=DATE:20230112
DTEND;VALUE=DATE:20230415
END:VEVENT
END:VCALENDAR
```
# Calendar entries examples
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53507/content"><img style="width:189px;" src="/api/v3/attachments/49630/content"><img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53508/content">
#### Access tokens
#### style="width:661px;" src="/api/v3/attachments/49631/content">
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53509/content">
#### Permissions and roles
#### <img style="width:189px;" src="/api/v3/attachments/49629/content"><img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53510/content"> style="width:660px;" src="/api/v3/attachments/49632/content"><img class="op-uc-image op-uc-image_inline" style="width:662px;" src="/api/v3/attachments/49636/content"><img class="op-uc-image op-uc-image_inline" style="width:663px;" src="/api/v3/attachments/49634/content"><img class="op-uc-image op-uc-image_inline" style="width:661px;" src="/api/v3/attachments/49635/content"><img class="op-uc-image op-uc-image_inline" style="width:662px;" src="/api/v3/attachments/49633/content">
#### iCalendar admin settings # Mockups
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53511/content"><img src="/api/v3/attachments/49639/content"><img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53512/content"> src="/api/v3/attachments/52313/content"><img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/49640/content"><img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/49642/content">
# Figma link
https://www.figma.com/file/fIFszjTJWyd0p94SXjih58/Calendar-view?node-id=111%3A7801
# ToDo
* [x] Investigate all the possibilities of iCal and what can we display:
* [x] If we can use the field "status" for any work package status such as "scheduled"
* [x] Create an ideal example of iCal txt
* [x] Benchmark on how are the iCal parameters displayed in the calendar clients
* [x] OX
* [x] Thunderbird
* [x] Mailbox
* [x] Outlook
* [x] Yahoo
* [x] Google Calendar
* [x] Google Calendar (Android)
* [x] Calendar (Mac)
* [x] Calendar (iOS)
* [x] Basecamp
* [x] 30 Boxes
* [x] Trumba
* [x] BusyCal
* [x] OneCalendar
* [x] Fantastical
* [x] Structured
* [x] Update mockups
* [x] URL: [https://openproject.example.com/projects/demo-project/calendars/27.ics?ical\_token=c6ec6fea407cb0eca52db380daefacbe](https://openproject.example.com/projects/demo-project/calendars/27.ics?ical_token=c6ec6fea407cb0eca52db380daefacbe)
* [x] Screen to revoke all tokens (not separately)
* [x] Permissions screen (admin settings)
* [x] Decide what info is mapped in the iCal event
* [x] Calendar entry in multiple calendar clients
* [x] Add link to mockup here: https://www.figma.com/file/fIFszjTJWyd0p94SXjih58/Calendar-view?node-id=111%3A7801
* [x] Specify permissions
* [x] Investigate the capabilities to use emojis to visualise content
* [x] Work package type
* [x] Status
* [x] Priority
# Out of scope
* CalDAV (we focus on ics-files for now)
* Update calendar entries in the calendar applications (read-only, no bi-directional sync)
* Revoke iCalendar tokens individually
**As a** project team member
**I want t**o see my project calendar in my personal calendar
**So that** I don't have to maintain two different calendars to organize my work.
# Use case examples
1. Release dates and other project milestones
2. Submission deadlines of artefacts that require collaboration with other team members
3. Extend certificats (e.g. SSL, SMIME)
While trying to introduce OpenProject in a team that I’m part of, I realised that there is no way to integrate the calendar with MS Outlook, Apple Calendar, Google Calendar, and the likes. It would greatly increase the visibility of project planning if people were able to see changes in their preferred calendar apps, instead of having to check the OpenProject calendar webpage. Export functionality would provide a very natural means to integrate OpenProject with existing planning and coordination routines established in teams (most of which will be using a calendar app of sorts).
# Acceptance criteria
* Separate project permission
* Menu entry to create and copy URL with the label "**Subscribe to iCalendar"**
* This menu entry opens a modal with an explanation and a warning banner. In the action bar of the modal there is the "**Copy URL**" action which will trigger the creation of the token. Once the user clicks on the button the modal closes and a toast appears on top of the screen to indicate the success or error to create and copy the token URL.
* Caching
* The calendar invite includes the main information of the work package organised in this order:
* **LOCATION:** For the work package _**URL**_
* **SUMMARY:** For the work package _**subject**_. We've decided
* **DESCRIPTION:** Containing this elements:
1. _**Project**_
2. _**Type**_Â
3. _**Status**_
4. _**Assignee**_
5. _**Priority**_
6. _**Description:**_ up
* **ORGANIZER:** For the _**author, assignee or accountable (TBD)**_ of the work package.
* **DTSTART:** For the work package _**start date**_.
* **DTEND:** For the work package _**finish date**_.
* The event should not be editable in the calendar client side.
* All iCalendar tokens
* The permission to subscribe to iCalendars
# Attribute mapping
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Example</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Work package attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">mapped iCal attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">iCal notes</th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">OpenProject GmbH//OpenProject Core Project//EN</td><td class="op-uc-p op-uc-table--cell">Container calendar and company</td><td class="op-uc-p op-uc-table--cell"><a class="op-uc-link" href="https://icalendar.org/iCalendar-RFC-5545/3-7-3-product-identifier.html">PRODID</a></td><td class="op-uc-p op-uc-table--cell">This
# Ideal iCal example
Using this work package as example the journal entry in a iCalendar ideal format should be:
```text
* On top of
VERSION:2.0
PRODID:-//OpenProject GmbH//OpenProject Core Project//EN
BEGIN:VEVENT
DTSTAMP:20230120T000000
CREATED:20230120T151920
LAST-MODIFIED:20230120T183250
DTSTART:20230112T000000
DTEND:20230415T000000
DURATION:P94D
UID:15339@community.openproject.com
WPID:15339
URL:https://community.openproject.org/projects/
openproject/work_packages/15339
ORGANIZER;CN=Max Mustermann:mailto:m.mustermann@example.com
CONTACT:Jonas Rietz\, OpenProject GmbH\, mailto:j.rietz@example.com
SUMMARY:Share project calendars using
DESCRIPTION:Work package description:/User Story/
As
calendar
have to maintain two different calendars to organize
my work.
CATEGORIES:🟩 FEATURE,In development
PRIORITY:5
RELATED-TO:25541@community.openproject.com
END:VJOURNAL
END:VCALENDAR
```
This code has been successfully validated using the [iCalendar Validator](https://icalendar.org/validator.html#results) and it has no errors. Also you can download the ICS file that I'm using to try all this configurations [here](https://community.openproject.org/api/v3/attachments/49599/content).
#
<figure class="table op-uc-figure_align-center op-uc-figure"><table class="op-uc-table"><thead class="op-uc-table--head"><tr class="op-uc-table--row"><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Work package attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">mapped iCal attribute</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">OX</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Thunderbird</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Mailbox</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Outlook</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Yahoo</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Google Calendar</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Google Calendar (Android)</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Calendar (MAC)</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Calendar (iOS)</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">BusyCal</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">OneCalendar</th><th class="op-uc-p op-uc-table--cell op-uc-table--cell_head">Fantastical</th></tr></thead><tbody><tr class="op-uc-table--row"><td class="op-uc-p op-uc-table--cell">Container calendar
# Conclusion and iCal construction
After all the analysis, unfortunately the majority of the iCal events that are described in their documentation are not displayed at all in the most common calendar clients. Therefore we
# Mockups
* **SUMMARY:** For the work package _**subject**_. We've decoded to not display the _**work package ID**_.
* **DESCRIPTION:** After the first discussion we decided to display this elements in the descrpition:
1. Project
2. Type (with a square colour emoji)
3. Status
4. Assignee
5. Priority (with a round colour emoji)
6. Description (up to X characters of the description)
* **ORGANIZER:** For the _**author, assignee or accountable (TBD)**_ of the work package.
* **DTSTART:** For the work package _**start date**_.
* **DTEND:** For the work package _**finish date**_.
####
```text
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//OpenProject GmbH//OpenProject Core Project//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-CALNAME:OpenProject
BEGIN:VEVENT
UID:15339@community.openproject.com
LOCATION:https://community.openproject.org/projects/openproject/work_packages/15339
SUMMARY:Share project calendars using the iCalendar format
DESCRIPTION:Project: OpenProject\nType: 🟩 FEATURE\nStatus: In development\nAssignee: Max Mustermann\nPriority: 🟢 Medium\n\rWork package description: User Story As a project team member I want to see my project calendar in my personal calendar So that I don't have to maintain two different calendars to organize my work...
DTSTART;VALUE=DATE:20230112
DTEND;VALUE=DATE:20230415
END:VEVENT
END:VCALENDAR
```
#### Access tokens
####
#### Permissions and roles
#### <img
#### iCalendar admin settings
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/53511/content"><img
# Figma link
https://www.figma.com/file/fIFszjTJWyd0p94SXjih58/Calendar-view?node-id=111%3A7801
# ToDo
* [x] Investigate all the possibilities of iCal and what can we display:
* [x] If we can use the field "status" for any work package status such as "scheduled"
* [x] Create an ideal example of iCal txt
* [x] Benchmark on how are the iCal parameters displayed in the calendar clients
* [x] OX
* [x] Thunderbird
* [x] Mailbox
* [x] Outlook
* [x] Yahoo
* [x] Google Calendar
* [x] Google Calendar (Android)
* [x] Calendar (Mac)
* [x] Calendar (iOS)
* [x] Basecamp
* [x] 30 Boxes
* [x] Trumba
* [x] BusyCal
* [x] OneCalendar
* [x] Fantastical
* [x] Structured
* [x] Update mockups
* [x] URL: [https://openproject.example.com/projects/demo-project/calendars/27.ics?ical\_token=c6ec6fea407cb0eca52db380daefacbe](https://openproject.example.com/projects/demo-project/calendars/27.ics?ical_token=c6ec6fea407cb0eca52db380daefacbe)
* [x] Screen to revoke all tokens (not separately)
* [x] Permissions screen (admin settings)
* [x] Decide what info is mapped in the iCal event
* [x] Calendar entry in multiple calendar clients
* [x] Add link to mockup here: https://www.figma.com/file/fIFszjTJWyd0p94SXjih58/Calendar-view?node-id=111%3A7801
* [x] Specify permissions
* [x] Investigate the capabilities to use emojis to visualise content
* [x] Work package type
* [x] Status
* [x] Priority
# Out of scope
* CalDAV (we focus on ics-files for now)
* Update calendar entries in the calendar applications (read-only, no bi-directional sync)
* Revoke iCalendar tokens individually