diff --git a/CHANGELOG.md b/CHANGELOG.md index ba5fa34d40cea8b42d0141f802e17f3f8384bc89..58eb29e4478bd16447e8ff261bf9fa3e875cd714 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,38 @@ - # Changelog +## 4.6.7 - 2024-03-19 +### Fixed +- Missing events in week view + +## 4.6.6 - 2024-03-04 +### Fixed +- Outdated holiday calendars +- FreeBusy - free for all blocks +- Appointment rounding + +## 4.6.5 - 2024-02-15 +### Fixed +- "Send Email" checkbox renamed to "Request reply" +- "Invitation sent" rephrased to "Awaiting response" +- Disabled resharing of incoming calendar shares +- Booking date not displayed in appointment booking popover +- Appointment slots not being bookable when the time doesn't fit into duration or increment + +## 4.6.4 - 2024-01-18 +### Fixed +- Guests being added to talk rooms not open for guests + +## 4.6.3 - 2024-01-10 +### Fixed +- Rate limit appointment booking and config creation +- Apointment confirmation modal button style +- Filtering in sharing search +- Attachment folder picker opening twice + +## 4.6.2 - 2024-01-03 +### Fixed +- Uploading attachments in Firefox + ## 4.6.1 - 2023-12-21 ### Fixed - Localisation for month view diff --git a/appinfo/info.xml b/appinfo/info.xml index 259148298760c3f131b3b7f1f71a941d805bae09..09e84b443f45c88bc4dbcd77aebe1942d5462386 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -15,7 +15,7 @@ * ☑️ Tasks! See tasks with a due date directly in the calendar * 🙈 **We’re not reinventing the wheel!** Based on the great [c-dav library](https://github.com/nextcloud/cdav-library), [ical.js](https://github.com/mozilla-comm/ical.js) and [fullcalendar](https://github.com/fullcalendar/fullcalendar) libraries. ]]> - 4.6.1 + 4.6.7 agpl Anna Larch Nextcloud Groupware Team diff --git a/l10n/sv.js b/l10n/sv.js index ce1b50f80f88f045a3e0e01c0b1f657cc500b7e1..ede38fb3ad3b08f32abb23fefbac79a4ecf9f40d 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -13,11 +13,8 @@ OC.L10N.register( "Cheers!" : "Ha de fint!", "Upcoming events" : "Kommande händelser", "More events" : "Fler händelser", -<<<<<<< HEAD -======= "No more events today" : "Inga fler händelser idag", "No upcoming events" : "Inga kommande händelser", ->>>>>>> a05a13fec008e7f7c13a2bb31304277ce587c11d "%1$s with %2$s" : "%1$s med %2$s", "Calendar" : "Kalender", "New booking {booking}" : "Ny bokning {booking}", @@ -42,27 +39,6 @@ OC.L10N.register( "Comment:" : "Kommentar:", "You have a new appointment booking \"%s\" from %s" : "Du har en ny mötesbokning \"%s\" från %s", "Dear %s, %s (%s) booked an appointment with you." : "%s, %s (%s) bokade ett möte med dig.", -<<<<<<< HEAD - "Anniversary" : "Jubileum", - "Appointment" : "Bokning", - "Business" : "Företag", - "Education" : "Utbildning", - "Holiday" : "Ledighet", - "Meeting" : "Möte", - "Miscellaneous" : "Diverse", - "Non-working hours" : "Icke-arbetstid", - "Not in office" : "Inte på kontoret", - "Personal" : "Privat", - "Phone call" : "Telefonsamtal", - "Sick day" : "Sjukdag", - "Special occasion" : "Speciellt tillfälle", - "Travel" : "Resa", - "Vacation" : "Semester", - "Custom Categories" : "Anpassade kategorier", - "Collaborative Tags" : "Samarbetstaggar", - "Standard Categories" : "Standardkategorier", -======= ->>>>>>> a05a13fec008e7f7c13a2bb31304277ce587c11d "A Calendar app for Nextcloud" : "En kalender-app för Nextcloud", "The Calendar app is a user interface for Nextcloud's CalDAV server. Easily sync events from various devices with your Nextcloud and edit them online.\n\n* 🚀 **Integration with other Nextcloud apps!** Currently Contacts - more to come.\n* 🌐 **WebCal Support!** Want to see your favorite team’s matchdays in your calendar? No problem!\n* 🙋 **Attendees!** Invite people to your events\n* ⌚️ **Free/Busy!** See when your attendees are available to meet\n* ⏰ **Reminders!** Get alarms for events inside your browser and via email\n* 🔍 Search! Find your events at ease\n* ☑️ Tasks! See tasks with a due date directly in the calendar\n* 🙈 **We’re not reinventing the wheel!** Based on the great [c-dav library](https://github.com/nextcloud/cdav-library), [ical.js](https://github.com/mozilla-comm/ical.js) and [fullcalendar](https://github.com/fullcalendar/fullcalendar) libraries." : "Kalendar-appen är ett gränssnitt till Nextclouds CalDAV server. Synkronisera händelser enkelt från diverse enheter till Nextcloud samt redigera dem online.\n\n* 🚀 **Integrerad med andra Nextcloud-appar!** För tillfället Kontakter - fler på väg.\n* 🌐 **WebCal Support!** Vill du se ditt favoritlags matchdagar i din kalender? Inga problem!\n* 🙋 **Deltagare!** Bjud in andra deltagare till dina aktiviteter\n* ⌚️ **Ledig/Upptagen!** Se när andra deltagare har ledig tid\n* ⏰ **Påminnelser!** Få påminnelser för aktiviteter i webbläsaren och på e-mail.\n* 🔍 Sök! Hitta dina event lätt!\n* ☑️ Uppgifter! Se dina uppgifters slutdatum direkt i kalendern\n* 🙈 **Vi uppfinner inte hjulet igen!** Appen är baserad på de fantastiska biblioteken [c-dav library](https://github.com/nextcloud/cdav-library), [ical.js](https://github.com/mozilla-comm/ical.js) och [fullcalendar](https://github.com/fullcalendar/fullcalendar).", "Previous day" : "Föregående dag", @@ -322,10 +298,7 @@ OC.L10N.register( "Create Talk room for this event" : "Skapa ett rum i Talk för denna händelse", "Show busy times" : "Visa upptagna tider", "No attendees yet" : "Inga deltagare ännu", -<<<<<<< HEAD -======= "You do not own this calendar, so you cannot add attendees to this event" : "Du äger inte den här kalendern, så du kan inte lägga till deltagare till denna händelse", ->>>>>>> a05a13fec008e7f7c13a2bb31304277ce587c11d "Successfully appended link to talk room to location." : "Länk till rum i Talk tillagd i plats.", "Successfully appended link to talk room to description." : "Länk till rum i Talk tillagd i beskrivningen.", "Error creating Talk room" : "Kunde inte skapa rum i Talk", @@ -418,10 +391,7 @@ OC.L10N.register( "Select date" : "Välj datum", "Select slot" : "Välj tid", "No slots available" : "Inga tider tillgängliga", -<<<<<<< HEAD -======= "Could not fetch slots" : "Det gick inte att hämta platser", ->>>>>>> a05a13fec008e7f7c13a2bb31304277ce587c11d "The slot for your appointment has been confirmed" : "Tiden för ditt möte har bekräftats", "Appointment Details:" : "Mötesdetaljer:", "Time:" : "Tid:", @@ -433,10 +403,7 @@ OC.L10N.register( "Please book a different slot:" : "Vänligen boka en annan tid:", "Book an appointment with {name}" : "Boka ett möte med {name}", "No public appointments found for {name}" : "Inga offentliga möten hittades för {name}", -<<<<<<< HEAD -======= "Personal" : "Privat", ->>>>>>> a05a13fec008e7f7c13a2bb31304277ce587c11d "The automatic time zone detection determined your time zone to be UTC.\nThis is most likely the result of security measures of your web browser.\nPlease set your time zone manually in the calendar settings." : "Den automatiska tidszon-detekteringen fastställde din tidszon till UTC.\nDetta är troligtvis resultatet av säkerhetsinställningar i din webbläsare.\nVänligen ställ in din tidszon manuellt i kalenderinställningarna.", "Your configured time zone ({timezoneId}) was not found. Falling back to UTC.\nPlease change your time zone in the settings and report this issue." : "Din tidszon ({timezoneId}) hittades inte. Återgår till UTC.\nVänligen ändra din tidszon i inställningarna och rapportera detta problem.", "Create a new event" : "Skapa en ny händelse", @@ -460,8 +427,6 @@ OC.L10N.register( "Show more details" : "Visa mer information", "Subscribe to {name}" : "Prenumerera på {name}", "Export {name}" : "Exportera {name}", -<<<<<<< HEAD -======= "Anniversary" : "Jubileum", "Appointment" : "Bokning", "Business" : "Företag", @@ -476,7 +441,6 @@ OC.L10N.register( "Special occasion" : "Speciellt tillfälle", "Travel" : "Resa", "Vacation" : "Semester", ->>>>>>> a05a13fec008e7f7c13a2bb31304277ce587c11d "Midnight on the day the event starts" : "Midnatt den dagen evenemanget börjar", "_%n day before the event at {formattedHourMinute}_::_%n days before the event at {formattedHourMinute}_" : ["%n dagar före händelsen klockan {formattedHourMinute}","%n dag före händelsen klockan {formattedHourMinute}"], "_%n week before the event at {formattedHourMinute}_::_%n weeks before the event at {formattedHourMinute}_" : ["%n veckor före händelsen klockan {formattedHourMinute}","%n vecka före händelsen klockan {formattedHourMinute}"], @@ -677,4 +641,4 @@ OC.L10N.register( "Appointment not found" : "Mötet hittades inte", "User not found" : "Användaren hittades inte" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=2; plural=(n != 1);"); \ No newline at end of file diff --git a/lib/Controller/AppointmentConfigController.php b/lib/Controller/AppointmentConfigController.php index 84260799a5cfefea2cc98b946f77cc35d9a70f4f..a2603958b10e2266c4d70c259dec782c8728112a 100644 --- a/lib/Controller/AppointmentConfigController.php +++ b/lib/Controller/AppointmentConfigController.php @@ -35,6 +35,7 @@ use OCA\Calendar\Http\JsonResponse; use OCA\Calendar\Service\Appointments\AppointmentConfigService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\UserRateLimit; use OCP\IRequest; use Psr\Log\LoggerInterface; use function array_keys; @@ -147,7 +148,9 @@ class AppointmentConfigController extends Controller { * @param int|null $end * @param int|null $futureLimit * @return JsonResponse + * @UserRateThrottle(limit=10, period=1200) */ + #[UserRateLimit(limit: 10, period: 1200)] public function create( string $name, string $description, diff --git a/lib/Controller/BookingController.php b/lib/Controller/BookingController.php index 7697fd26e39e970f861cfbf81205a8012d8b8193..c51895b4453ba7933aca2dc7bc1e1859cdba1fdb 100644 --- a/lib/Controller/BookingController.php +++ b/lib/Controller/BookingController.php @@ -37,6 +37,8 @@ use OCA\Calendar\Service\Appointments\AppointmentConfigService; use OCA\Calendar\Service\Appointments\BookingService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\AnonRateLimit; +use OCP\AppFramework\Http\Attribute\UserRateLimit; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\AppFramework\Utility\ITimeFactory; @@ -162,7 +164,12 @@ class BookingController extends Controller { * @param string $description * @param string $timeZone * @return JsonResponse + * + * @AnonRateThrottle(limit=10, period=1200) + * @UserRateThrottle(limit=10, period=300) */ + #[AnonRateLimit(limit: 10, period: 1200)] + #[UserRateLimit(limit: 10, period: 300)] public function bookSlot(int $appointmentConfigId, int $start, int $end, diff --git a/lib/Service/Appointments/AvailabilityGenerator.php b/lib/Service/Appointments/AvailabilityGenerator.php index e25d38f30f17c7d695e4f08741e26f21cb0ae0d3..6fdc2a5c267667531d91368df97e98e8fcc5df14 100644 --- a/lib/Service/Appointments/AvailabilityGenerator.php +++ b/lib/Service/Appointments/AvailabilityGenerator.php @@ -63,13 +63,14 @@ class AvailabilityGenerator { $now + $bufferBeforeStart, ($config->getStart() ?? $now) + $bufferBeforeStart ); - // Always round to "beautiful" slot starts according to slot length + + // Always round to "beautiful" slot starts // E.g. 5m slots should only be available at 10:20 and 10:25, not at 10:17 // when the user opens the page at 10:17. // But only do this when the time isn't already a "pretty" time if ($earliestStart % $config->getIncrement() !== 0) { - $roundTo = (int)round(($config->getIncrement()) / 300) * 300; - $earliestStart = (int)ceil($earliestStart / $roundTo) * $roundTo; + $roundTo = (int)(round(($config->getIncrement()) / 300) * 300); + $earliestStart = (int)(ceil($earliestStart / $roundTo) * $roundTo); } $latestEnd = min( @@ -94,8 +95,7 @@ class AvailabilityGenerator { $timeZone = $availabilityRule['timezoneId']; $slots = $availabilityRule['slots']; - $applicableSlots = $this->filterDates($start, $slots, $timeZone); - + $applicableSlots = $this->filterDates($start, $slots, $timeZone, $config->getIncrement()); $intervals = []; foreach ($applicableSlots as $slot) { if ($slot->getEnd() <= $earliestStart || $slot->getStart() >= $latestEnd) { @@ -121,7 +121,7 @@ class AvailabilityGenerator { * * @return Interval[] */ - private function filterDates(int $start, array $availabilityArray, string $timeZone): array { + private function filterDates(int $start, array $availabilityArray, string $timeZone, int $duration): array { $tz = new DateTimeZone($timeZone); // First, transform all timestamps to DateTime Objects $availabilityRules = []; @@ -131,9 +131,15 @@ class AvailabilityGenerator { continue; } foreach ($availabilitySlots as $slot) { + // Fix "not-pretty" timeslots + // A slot from 10:10 to 10:40 could be generated but isn't bookable + // So we round them to the next highest time that is pretty for that slot + $roundTo = (int)round(($duration) / 300) * 300; + $prettyStart = (int)ceil($slot['start'] / $roundTo) * $roundTo; + $prettyEnd = (int)ceil($slot['end'] / $roundTo) * $roundTo; $availabilityRules[$key][] = [ - 'start' => (new DateTimeImmutable())->setTimezone($tz)->setTimestamp($slot['start']), - 'end' => (new DateTimeImmutable())->setTimezone($tz)->setTimestamp($slot['end']) + 'start' => (new DateTimeImmutable())->setTimezone($tz)->setTimestamp($prettyStart), + 'end' => (new DateTimeImmutable())->setTimezone($tz)->setTimestamp($prettyEnd) ]; } } diff --git a/package-lock.json b/package-lock.json index 8d71cec6f22c22d1bdb4890f4bda0ac342fe765d..ff2d3c2ddfcf836490b52efa9c9561c6f507f218 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,23 @@ { "name": "calendar", - "version": "4.6.1", + "version": "4.6.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "calendar", - "version": "4.6.1", + "version": "4.6.7", "license": "agpl", "dependencies": { - "@fullcalendar/core": "6.1.9", - "@fullcalendar/daygrid": "6.1.9", - "@fullcalendar/interaction": "6.1.9", - "@fullcalendar/list": "6.1.9", - "@fullcalendar/multimonth": "6.1.9", - "@fullcalendar/resource": "6.1.9", - "@fullcalendar/resource-timeline": "6.1.9", - "@fullcalendar/timegrid": "6.1.9", - "@fullcalendar/vue": "6.1.9", + "@fullcalendar/core": "6.1.11", + "@fullcalendar/daygrid": "6.1.11", + "@fullcalendar/interaction": "6.1.11", + "@fullcalendar/list": "6.1.11", + "@fullcalendar/multimonth": "6.1.11", + "@fullcalendar/resource": "6.1.11", + "@fullcalendar/resource-timeline": "6.1.11", + "@fullcalendar/timegrid": "6.1.11", + "@fullcalendar/vue": "6.1.11", "@nextcloud/auth": "^2.2.1", "@nextcloud/axios": "^2.4.0", "@nextcloud/calendar-availability-vue": "^1.0.1", @@ -2014,121 +2014,121 @@ "integrity": "sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==" }, "node_modules/@fullcalendar/core": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.9.tgz", - "integrity": "sha512-eeG+z9BWerdsU9Ac6j16rpYpPnE0wxtnEHiHrh/u/ADbGTR3hCOjCD9PxQOfhOTHbWOVs7JQunGcksSPu5WZBQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.11.tgz", + "integrity": "sha512-TjG7c8sUz+Vkui2FyCNJ+xqyu0nq653Ibe99A66LoW95oBo6tVhhKIaG1Wh0GVKymYiqAQN/OEdYTuj4ay27kA==", "dependencies": { "preact": "~10.12.1" } }, "node_modules/@fullcalendar/daygrid": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.9.tgz", - "integrity": "sha512-o/6joH/7lmVHXAkbaa/tUbzWYnGp/LgfdiFyYPkqQbjKEeivNZWF1WhHqFbhx0zbFONSHtrvkjY2bjr+Ef2quQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.11.tgz", + "integrity": "sha512-hF5jJB7cgUIxWD5MVjj8IU407HISyLu7BWXcEIuTytkfr8oolOXeCazqnnjmRbnFOncoJQVstTtq6SIhaT32Xg==", "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/interaction": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.9.tgz", - "integrity": "sha512-I3FGnv0kKZpIwujg3HllbKrciNjTqeTYy3oJG226oAn7lV6wnrrDYMmuGmA0jPJAGN46HKrQqKN7ItxQRDec4Q==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.11.tgz", + "integrity": "sha512-ynOKjzuPwEAMgTQ6R/Z2zvzIIqG4p8/Qmnhi1q0vzPZZxSIYx3rlZuvpEK2WGBZZ1XEafDOP/LGfbWoNZe+qdg==", "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/list": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.9.tgz", - "integrity": "sha512-OCKdC1Gz26cJ5QsXdQyXVyzVu23ypT2xzyAR+Wc8jEytcJLWXw2a914m/MVax8n8EHuaIYY2exhsy/eaSU0XNA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.11.tgz", + "integrity": "sha512-9Qx8uvik9pXD12u50FiHwNzlHv4wkhfsr+r03ycahW7vEeIAKCsIZGTkUfFP+96I5wHihrfLazu1cFQG4MPiuw==", "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/multimonth": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.9.tgz", - "integrity": "sha512-YpH1NL6RzdM1wO2nFJ3pNMo9xhd6i2WuE+e7SnGi7q1lO+ZZ77h5Fja5JKcpuIQUFHpi+m6vTzihIV8DT44NnQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.11.tgz", + "integrity": "sha512-7DbPC+AAlaKnquGVdw1Z85Q3nSZ4GZ1NcVIk4k7bLnqDlntwHPPsrDlSIzUWKcN0q5/u7jQHm4PU1m3LAl70Sg==", "dependencies": { - "@fullcalendar/daygrid": "~6.1.9" + "@fullcalendar/daygrid": "~6.1.11" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/premium-common": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.9.tgz", - "integrity": "sha512-hbyXAPU0r9psO0oH22ge0GCxQhlHQ0KJRJhAM2KkTTfYUSAYgaaYfX9cUC6ysNE7T1gZ5JDlYDu/xskwPymyvA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.11.tgz", + "integrity": "sha512-3WsSizkGDJEu+AlgQlFXKI+/DYCYTRp0PQRz0vS63qKBEUsVzfSD0oi/7jCylZJlCUteIjbi4Hu1I2I5o6UHrQ==", "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/resource": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.9.tgz", - "integrity": "sha512-A0yQs08WNxx7XeQlAZ9gkmiJOuNOjwpiusnnNSWw/xriNoXmWasDih9ury3GcTjJ8T13Y9d+E6IgxLZgBejTZQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.11.tgz", + "integrity": "sha512-hxTQQ+eywfcC28JeyQEdJov+Jqa73zy4xU0Gg7DTTOVlS2lFVrQKM5aMXW8iz800rPbvHFAyVwfFNHclJrRoeQ==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/resource-timeline": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.9.tgz", - "integrity": "sha512-lXv37zTbaAYMrx6xgGLlWGNCzhH+RwyX41BwlzzVgfZXKrW0QlwjyxKrSgZeFQr9mNta5ACqPH1FeZffzBVO0Q==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.11.tgz", + "integrity": "sha512-RIQOwGxN8n2jSIOsEGUjzoGgdYDZq8t4sUvSUfnahGwyCesMqsYNmpA+58PFy/BHPIgxyvy8awH2CnjjSN7Uiw==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.9", - "@fullcalendar/scrollgrid": "~6.1.9", - "@fullcalendar/timeline": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11", + "@fullcalendar/scrollgrid": "~6.1.11", + "@fullcalendar/timeline": "~6.1.11" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.9", - "@fullcalendar/resource": "~6.1.9" + "@fullcalendar/core": "~6.1.11", + "@fullcalendar/resource": "~6.1.11" } }, "node_modules/@fullcalendar/scrollgrid": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.9.tgz", - "integrity": "sha512-mrdNb0kgDrs15oesKFfr475UYEuqAEQmxBJB2IjQVUL1v213ZqY1TYzgXsIQhVmyGudosVbBOaiQ+vb0zMk8HA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.11.tgz", + "integrity": "sha512-GRhhU8ACHqgfxdMnP59VPThfNG3Stkp9zq1sLnI992g1fZQ+V2UhYvl5qhu3eEVSp2KTDPx4NaoR35cQGrC1Mw==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/timegrid": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.9.tgz", - "integrity": "sha512-le7UV05wVE1Trdr054kgJXTwa+A1pEI8nlCBnPWdcyrL+dTLoPvQ4AWEVCnV7So+4zRYaCqnqGXfCJsj0RQa0g==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.11.tgz", + "integrity": "sha512-0seUHK/ferH89IeuCvV4Bib0zWjgK0nsptNdmAc9wDBxD/d9hm5Mdti0URJX6bDoRtsSfRDu5XsRcrzwoc+AUQ==", "dependencies": { - "@fullcalendar/daygrid": "~6.1.9" + "@fullcalendar/daygrid": "~6.1.11" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/timeline": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.9.tgz", - "integrity": "sha512-0WuLvJpIsJZPYUuVlRsELdOUOuw6Tizer5pF93/EoHoQa7ZKMWvQY/6H+foxGXBszjHMFpIjRFlltDytL9VbGQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.11.tgz", + "integrity": "sha512-MGUEAHlFBWxpuhSWhZbHOtD9i+b8GZjqNV82MH+vwPHq1Jjqe8qj9Wby00vKikdWH+RuAB+IuiKjQaROEU0Ecw==", "dependencies": { - "@fullcalendar/premium-common": "~6.1.9", - "@fullcalendar/scrollgrid": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11", + "@fullcalendar/scrollgrid": "~6.1.11" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.9" + "@fullcalendar/core": "~6.1.11" } }, "node_modules/@fullcalendar/vue": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/vue/-/vue-6.1.9.tgz", - "integrity": "sha512-cJet86Zq0MhAn+VNO6QByZOmv4P8vgfkQJC9PkgMZAzLnVHMQGPgEpV492i5BGEXeLelmaAhynZvLv15C4XbPQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/vue/-/vue-6.1.11.tgz", + "integrity": "sha512-Vb8GxKDErp7+cDyD/6F2nlCs4iHyfhpoQ2JUx60bjXHcx1RqgENdFCfSvfHEMc2Gbrg72TzI9CpITEGDZ8SUng==", "peerDependencies": { - "@fullcalendar/core": "~6.1.9", + "@fullcalendar/core": "~6.1.11", "vue": "^2.6.12" } }, @@ -19264,92 +19264,92 @@ "integrity": "sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==" }, "@fullcalendar/core": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.9.tgz", - "integrity": "sha512-eeG+z9BWerdsU9Ac6j16rpYpPnE0wxtnEHiHrh/u/ADbGTR3hCOjCD9PxQOfhOTHbWOVs7JQunGcksSPu5WZBQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.11.tgz", + "integrity": "sha512-TjG7c8sUz+Vkui2FyCNJ+xqyu0nq653Ibe99A66LoW95oBo6tVhhKIaG1Wh0GVKymYiqAQN/OEdYTuj4ay27kA==", "requires": { "preact": "~10.12.1" } }, "@fullcalendar/daygrid": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.9.tgz", - "integrity": "sha512-o/6joH/7lmVHXAkbaa/tUbzWYnGp/LgfdiFyYPkqQbjKEeivNZWF1WhHqFbhx0zbFONSHtrvkjY2bjr+Ef2quQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.11.tgz", + "integrity": "sha512-hF5jJB7cgUIxWD5MVjj8IU407HISyLu7BWXcEIuTytkfr8oolOXeCazqnnjmRbnFOncoJQVstTtq6SIhaT32Xg==", "requires": {} }, "@fullcalendar/interaction": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.9.tgz", - "integrity": "sha512-I3FGnv0kKZpIwujg3HllbKrciNjTqeTYy3oJG226oAn7lV6wnrrDYMmuGmA0jPJAGN46HKrQqKN7ItxQRDec4Q==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.11.tgz", + "integrity": "sha512-ynOKjzuPwEAMgTQ6R/Z2zvzIIqG4p8/Qmnhi1q0vzPZZxSIYx3rlZuvpEK2WGBZZ1XEafDOP/LGfbWoNZe+qdg==", "requires": {} }, "@fullcalendar/list": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.9.tgz", - "integrity": "sha512-OCKdC1Gz26cJ5QsXdQyXVyzVu23ypT2xzyAR+Wc8jEytcJLWXw2a914m/MVax8n8EHuaIYY2exhsy/eaSU0XNA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.11.tgz", + "integrity": "sha512-9Qx8uvik9pXD12u50FiHwNzlHv4wkhfsr+r03ycahW7vEeIAKCsIZGTkUfFP+96I5wHihrfLazu1cFQG4MPiuw==", "requires": {} }, "@fullcalendar/multimonth": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.9.tgz", - "integrity": "sha512-YpH1NL6RzdM1wO2nFJ3pNMo9xhd6i2WuE+e7SnGi7q1lO+ZZ77h5Fja5JKcpuIQUFHpi+m6vTzihIV8DT44NnQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.11.tgz", + "integrity": "sha512-7DbPC+AAlaKnquGVdw1Z85Q3nSZ4GZ1NcVIk4k7bLnqDlntwHPPsrDlSIzUWKcN0q5/u7jQHm4PU1m3LAl70Sg==", "requires": { - "@fullcalendar/daygrid": "~6.1.9" + "@fullcalendar/daygrid": "~6.1.11" } }, "@fullcalendar/premium-common": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.9.tgz", - "integrity": "sha512-hbyXAPU0r9psO0oH22ge0GCxQhlHQ0KJRJhAM2KkTTfYUSAYgaaYfX9cUC6ysNE7T1gZ5JDlYDu/xskwPymyvA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/premium-common/-/premium-common-6.1.11.tgz", + "integrity": "sha512-3WsSizkGDJEu+AlgQlFXKI+/DYCYTRp0PQRz0vS63qKBEUsVzfSD0oi/7jCylZJlCUteIjbi4Hu1I2I5o6UHrQ==", "requires": {} }, "@fullcalendar/resource": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.9.tgz", - "integrity": "sha512-A0yQs08WNxx7XeQlAZ9gkmiJOuNOjwpiusnnNSWw/xriNoXmWasDih9ury3GcTjJ8T13Y9d+E6IgxLZgBejTZQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource/-/resource-6.1.11.tgz", + "integrity": "sha512-hxTQQ+eywfcC28JeyQEdJov+Jqa73zy4xU0Gg7DTTOVlS2lFVrQKM5aMXW8iz800rPbvHFAyVwfFNHclJrRoeQ==", "requires": { - "@fullcalendar/premium-common": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11" } }, "@fullcalendar/resource-timeline": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.9.tgz", - "integrity": "sha512-lXv37zTbaAYMrx6xgGLlWGNCzhH+RwyX41BwlzzVgfZXKrW0QlwjyxKrSgZeFQr9mNta5ACqPH1FeZffzBVO0Q==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/resource-timeline/-/resource-timeline-6.1.11.tgz", + "integrity": "sha512-RIQOwGxN8n2jSIOsEGUjzoGgdYDZq8t4sUvSUfnahGwyCesMqsYNmpA+58PFy/BHPIgxyvy8awH2CnjjSN7Uiw==", "requires": { - "@fullcalendar/premium-common": "~6.1.9", - "@fullcalendar/scrollgrid": "~6.1.9", - "@fullcalendar/timeline": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11", + "@fullcalendar/scrollgrid": "~6.1.11", + "@fullcalendar/timeline": "~6.1.11" } }, "@fullcalendar/scrollgrid": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.9.tgz", - "integrity": "sha512-mrdNb0kgDrs15oesKFfr475UYEuqAEQmxBJB2IjQVUL1v213ZqY1TYzgXsIQhVmyGudosVbBOaiQ+vb0zMk8HA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/scrollgrid/-/scrollgrid-6.1.11.tgz", + "integrity": "sha512-GRhhU8ACHqgfxdMnP59VPThfNG3Stkp9zq1sLnI992g1fZQ+V2UhYvl5qhu3eEVSp2KTDPx4NaoR35cQGrC1Mw==", "requires": { - "@fullcalendar/premium-common": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11" } }, "@fullcalendar/timegrid": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.9.tgz", - "integrity": "sha512-le7UV05wVE1Trdr054kgJXTwa+A1pEI8nlCBnPWdcyrL+dTLoPvQ4AWEVCnV7So+4zRYaCqnqGXfCJsj0RQa0g==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.11.tgz", + "integrity": "sha512-0seUHK/ferH89IeuCvV4Bib0zWjgK0nsptNdmAc9wDBxD/d9hm5Mdti0URJX6bDoRtsSfRDu5XsRcrzwoc+AUQ==", "requires": { - "@fullcalendar/daygrid": "~6.1.9" + "@fullcalendar/daygrid": "~6.1.11" } }, "@fullcalendar/timeline": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.9.tgz", - "integrity": "sha512-0WuLvJpIsJZPYUuVlRsELdOUOuw6Tizer5pF93/EoHoQa7ZKMWvQY/6H+foxGXBszjHMFpIjRFlltDytL9VbGQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/timeline/-/timeline-6.1.11.tgz", + "integrity": "sha512-MGUEAHlFBWxpuhSWhZbHOtD9i+b8GZjqNV82MH+vwPHq1Jjqe8qj9Wby00vKikdWH+RuAB+IuiKjQaROEU0Ecw==", "requires": { - "@fullcalendar/premium-common": "~6.1.9", - "@fullcalendar/scrollgrid": "~6.1.9" + "@fullcalendar/premium-common": "~6.1.11", + "@fullcalendar/scrollgrid": "~6.1.11" } }, "@fullcalendar/vue": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@fullcalendar/vue/-/vue-6.1.9.tgz", - "integrity": "sha512-cJet86Zq0MhAn+VNO6QByZOmv4P8vgfkQJC9PkgMZAzLnVHMQGPgEpV492i5BGEXeLelmaAhynZvLv15C4XbPQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@fullcalendar/vue/-/vue-6.1.11.tgz", + "integrity": "sha512-Vb8GxKDErp7+cDyD/6F2nlCs4iHyfhpoQ2JUx60bjXHcx1RqgENdFCfSvfHEMc2Gbrg72TzI9CpITEGDZ8SUng==", "requires": {} }, "@humanwhocodes/config-array": { diff --git a/package.json b/package.json index 63a28c5f9bae61005f221c52cac5e50e52537db1..f57ae4fc4094963986a1e184ee6544b53c15b6e6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "calendar", "description": "A calendar app for Nextcloud. Easily sync events from various devices, share and edit them online.", - "version": "4.6.1", + "version": "4.6.7", "author": "Georg Ehrke ", "contributors": [ "Georg Ehrke ", @@ -36,15 +36,15 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@fullcalendar/core": "6.1.9", - "@fullcalendar/daygrid": "6.1.9", - "@fullcalendar/interaction": "6.1.9", - "@fullcalendar/list": "6.1.9", - "@fullcalendar/multimonth": "6.1.9", - "@fullcalendar/resource": "6.1.9", - "@fullcalendar/resource-timeline": "6.1.9", - "@fullcalendar/timegrid": "6.1.9", - "@fullcalendar/vue": "6.1.9", + "@fullcalendar/core": "6.1.11", + "@fullcalendar/daygrid": "6.1.11", + "@fullcalendar/interaction": "6.1.11", + "@fullcalendar/list": "6.1.11", + "@fullcalendar/multimonth": "6.1.11", + "@fullcalendar/resource": "6.1.11", + "@fullcalendar/resource-timeline": "6.1.11", + "@fullcalendar/timegrid": "6.1.11", + "@fullcalendar/vue": "6.1.11", "@nextcloud/auth": "^2.2.1", "@nextcloud/axios": "^2.4.0", "@nextcloud/calendar-availability-vue": "^1.0.1", @@ -140,7 +140,7 @@ "clover" ], "transformIgnorePatterns": [ - "/node_modules/(?!(@fullcalendar|uuid)).+\\.js$" + "/node_modules/(?!(@fullcalendar|uuid|webdav)).+\\.js$" ], "setupFilesAfterEnv": [ "./tests/javascript/jest.setup.js", diff --git a/src/components/AppNavigation/CalendarList/CalendarListItem.vue b/src/components/AppNavigation/CalendarList/CalendarListItem.vue index 5ae7b728eb0ddab8d394e1efbb712a756abe5cb8..1351242a453c6d4dbfd3e4f30f7e10776b823574 100644 --- a/src/components/AppNavigation/CalendarList/CalendarListItem.vue +++ b/src/components/AppNavigation/CalendarList/CalendarListItem.vue @@ -139,6 +139,12 @@ export default { * @return {boolean} */ canBeShared() { + // The backend falsely reports incoming editable shares as being shareable + // Ref https://github.com/nextcloud/calendar/issues/5755 + if (this.calendar.isSharedWithMe) { + return false + } + return this.calendar.canBeShared || this.calendar.canBePublished }, /** diff --git a/src/components/AppNavigation/EditCalendarModal.vue b/src/components/AppNavigation/EditCalendarModal.vue index 4250dd8bd8c7a29cfde66857a6790b499714128e..4b74ab7b61ed13b791d6f465afcbb2bb6dd70f16 100644 --- a/src/components/AppNavigation/EditCalendarModal.vue +++ b/src/components/AppNavigation/EditCalendarModal.vue @@ -141,6 +141,12 @@ export default { * @return {boolean} */ canBeShared() { + // The backend falsely reports incoming editable shares as being shareable + // Ref https://github.com/nextcloud/calendar/issues/5755 + if (this.calendar.isSharedWithMe) { + return false + } + return this.calendar.canBeShared || this.calendar.canBePublished }, diff --git a/src/components/AppNavigation/Settings/SettingsAttachmentsFolder.vue b/src/components/AppNavigation/Settings/SettingsAttachmentsFolder.vue index 7a41c99fba2bcf12e39109b69c53cbaec09e9ae3..8e16f2c9612a2d8ee0e4be45add05b4b6665b983 100644 --- a/src/components/AppNavigation/Settings/SettingsAttachmentsFolder.vue +++ b/src/components/AppNavigation/Settings/SettingsAttachmentsFolder.vue @@ -30,7 +30,6 @@ @input="debounceSaveAttachmentsFolder(attachmentsFolder)" @change="debounceSaveAttachmentsFolder(attachmentsFolder)" @click="selectCalendarFolder" - @focus.once="selectCalendarFolder" @keyboard.enter="selectCalendarFolder" /> diff --git a/src/components/AppointmentConfigModal.vue b/src/components/AppointmentConfigModal.vue index 2d35cd0f8888a6f98e01e6cd5d9af3564f86af3d..27a655034a3a87695c43f50aec910a76d3465e8a 100644 --- a/src/components/AppointmentConfigModal.vue +++ b/src/components/AppointmentConfigModal.vue @@ -134,6 +134,10 @@ + + {{ t('calendar', 'It seems a rate limit has been reached. Please try again later.') }} + import { CalendarAvailability } from '@nextcloud/calendar-availability-vue' -import { NcModal as Modal, NcButton, NcCheckboxRadioSwitch } from '@nextcloud/vue' +import { NcModal as Modal, NcButton, NcCheckboxRadioSwitch, NcNoteCard } from '@nextcloud/vue' import TextInput from './AppointmentConfigModal/TextInput.vue' import TextArea from './AppointmentConfigModal/TextArea.vue' import AppointmentConfig from '../models/appointmentConfig.js' @@ -177,6 +181,7 @@ export default { Confirmation, NcButton, NcCheckboxRadioSwitch, + NcNoteCard, }, props: { config: { @@ -194,6 +199,7 @@ export default { enablePreparationDuration: false, enableFollowupDuration: false, enableFutureLimit: false, + rateLimitingReached: false, showConfirmation: false, } }, @@ -282,6 +288,8 @@ export default { this.editing.calendarFreeBusyUris = this.editing.calendarFreeBusyUris.filter(uri => uri !== this.calendarUrlToUri(calendar.url)) }, async save() { + this.rateLimitingReached = false + if (!this.enablePreparationDuration) { this.editing.preparationDuration = this.defaultConfig.preparationDuration } @@ -307,6 +315,9 @@ export default { } this.showConfirmation = true } catch (error) { + if (error?.response?.status === 429) { + this.rateLimitingReached = true + } logger.error('Failed to save config', { error, config, isNew: this.isNew }) } }, diff --git a/src/components/AppointmentConfigModal/Confirmation.vue b/src/components/AppointmentConfigModal/Confirmation.vue index 44d7edb8ff4d2ccfddfec9af4030e489cdfb683e..07c1a76185d8a6a8da5f22807212a8efd6853d5e 100644 --- a/src/components/AppointmentConfigModal/Confirmation.vue +++ b/src/components/AppointmentConfigModal/Confirmation.vue @@ -28,12 +28,11 @@
- + {{ t('calendar', 'Preview') }} - + {{ t('calendar', 'Copy link') }} diff --git a/src/components/Appointments/AppointmentDetails.vue b/src/components/Appointments/AppointmentDetails.vue index 89cccb40a0a3d3a1fbd3d61f43266cff0eb375b3..aa087974d13930e38958d05a37b1692f0deee4ab 100644 --- a/src/components/Appointments/AppointmentDetails.vue +++ b/src/components/Appointments/AppointmentDetails.vue @@ -15,7 +15,7 @@ {{ config.name }}
- {{ startTime }} - {{ endTime }} + {{date}} {{ startTime }} - {{ endTime }}
{{ config.description }} @@ -53,10 +53,14 @@ :disabled="isLoading" />
-
+ + {{ $t('calendar', 'It seems a rate limit has been reached. Please try again later.') }} + + {{ $t('calendar', 'Could not book the appointment. Please try again later or contact the organizer.') }} -
+
@@ -73,10 +77,11 @@ import { NcButton, NcLoadingIcon, NcModal as Modal, + NcNoteCard, } from '@nextcloud/vue' import autosize from '../../directives/autosize.js' -import { timeStampToLocaleTime } from '../../utils/localeTime.js' +import { timeStampToLocaleTime, timeStampToLocaleDate } from '../../utils/localeTime.js' export default { name: 'AppointmentDetails', @@ -85,6 +90,7 @@ export default { NcButton, NcLoadingIcon, Modal, + NcNoteCard, }, directives: { autosize, @@ -110,6 +116,10 @@ export default { required: true, type: String, }, + showRateLimitingWarning: { + required: true, + type: Boolean, + }, showError: { required: true, type: Boolean, @@ -134,6 +144,9 @@ export default { endTime() { return timeStampToLocaleTime(this.timeSlot.end, this.timeZoneId) }, + date() { + return timeStampToLocaleDate(this.timeSlot.start, this.timeZoneId) + } }, methods: { save() { diff --git a/src/components/Editor/Attachments/AttachmentsList.vue b/src/components/Editor/Attachments/AttachmentsList.vue index 2220c74c11cabb02817fa6bc665b5282e4da9c45..c95d82ba7e9784e1675f54170ab25c10aeef7ec1 100644 --- a/src/components/Editor/Attachments/AttachmentsList.vue +++ b/src/components/Editor/Attachments/AttachmentsList.vue @@ -65,10 +65,6 @@ import { NcActionButton, } from '@nextcloud/vue' -import { - mapState, -} from 'vuex' - import Upload from 'vue-material-design-icons/Upload.vue' import Close from 'vue-material-design-icons/Close.vue' import Folder from 'vue-material-design-icons/Folder.vue' @@ -77,10 +73,10 @@ import Plus from 'vue-material-design-icons/Plus.vue' import { generateUrl } from '@nextcloud/router' import { getFilePickerBuilder, showError } from '@nextcloud/dialogs' +import logger from '../../../utils/logger.js' import { uploadLocalAttachment, getFileInfo, - createFolder, } from '../../../services/attachmentService.js' import { parseXML } from 'webdav' @@ -109,7 +105,6 @@ export default { data() { return { uploading: false, - folderCreated: false, } }, computed: { @@ -119,9 +114,6 @@ export default { attachments() { return this.calendarObjectInstance.attachments }, - ...mapState({ - attachmentsFolder: state => state.settings.attachmentsFolder, - }), }, methods: { addAttachmentWithProperty(calendarObjectInstance, sharedData) { @@ -142,7 +134,7 @@ export default { const filename = await picker.pick(t('calendar', 'Choose a file to share as a link')) if (!this.isDuplicateAttachment(filename)) { // TODO do not share Move this to PHP - const data = await getFileInfo(filename, this.currentUser.dav) + const data = await getFileInfo(filename, this.currentUser.dav.userId) const davRes = await parseXML(data) const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop davRespObj.fileName = filename @@ -168,24 +160,25 @@ export default { this.$refs.localAttachments.click() }, async onLocalAttachmentSelected(e) { - if (!this.folderCreated) { - await createFolder(this.attachmentsFolder, this.currentUser.userId) - this.folderCreated = true - } - const attachments = await uploadLocalAttachment(this.attachmentsFolder, e, this.currentUser.dav, this.attachments) - // TODO do not share file, move to PHP - attachments.map(async attachment => { - const data = await getFileInfo(`${this.attachmentsFolder}/${attachment.path}`, this.currentUser.dav) - const davRes = await parseXML(data) - const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop - davRespObj.fileName = attachment.path - davRespObj.url = generateUrl(`/f/${davRespObj.fileid}`) - davRespObj.value = davRespObj.url - this.addAttachmentWithProperty(this.calendarObjectInstance, davRespObj) - }) - - e.target.value = '' + try { + const attachmentsFolder = await this.$store.dispatch('createAttachmentsFolder') + const attachments = await uploadLocalAttachment(attachmentsFolder, Array.from(e.target.files), this.currentUser.dav, this.attachments) + // TODO do not share file, move to PHP + attachments.map(async attachment => { + const data = await getFileInfo(`${attachmentsFolder}/${attachment.path}`, this.currentUser.dav.userId) + const davRes = await parseXML(data) + const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop + davRespObj.fileName = attachment.path + davRespObj.url = generateUrl(`/f/${davRespObj.fileid}`) + davRespObj.value = davRespObj.url + this.addAttachmentWithProperty(this.calendarObjectInstance, davRespObj) + }) + e.target.value = '' + } catch (error) { + logger.error('Could not upload attachment(s)', { error }) + showError(t('calendar', 'Could not upload attachment(s)')) + } }, getIcon(mime) { return OC.MimeType.getIconUrl(mime) diff --git a/src/components/Editor/AvatarParticipationStatus.vue b/src/components/Editor/AvatarParticipationStatus.vue index f599791638ab9924313f75dcb5c338a991dc69fc..d89961606115e43c9f243850c53df9cc57ef29c8 100644 --- a/src/components/Editor/AvatarParticipationStatus.vue +++ b/src/components/Editor/AvatarParticipationStatus.vue @@ -119,7 +119,7 @@
- {{ t('calendar', 'Invitation sent') }} + {{ t('calendar', 'Awaiting response') }}