diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index 02dec49a54668..4335017615466 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -62,6 +62,7 @@
OCA\DAV\Settings\CalDAVSettingsOCA\DAV\Settings\AvailabilitySettings
+ OCA\DAV\Settings\BirthdayCalendarSettings
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index e8935f3b8b64a..71f4620101164 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -331,6 +331,7 @@
'OCA\\DAV\\ServerFactory' => $baseDir . '/../lib/ServerFactory.php',
'OCA\\DAV\\Service\\AbsenceService' => $baseDir . '/../lib/Service/AbsenceService.php',
'OCA\\DAV\\Settings\\AvailabilitySettings' => $baseDir . '/../lib/Settings/AvailabilitySettings.php',
+ 'OCA\\DAV\\Settings\\BirthdayCalendarSettings' => $baseDir . '/../lib/Settings/BirthdayCalendarSettings.php',
'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir . '/../lib/Settings/CalDAVSettings.php',
'OCA\\DAV\\SetupChecks\\NeedsSystemAddressBookSync' => $baseDir . '/../lib/SetupChecks/NeedsSystemAddressBookSync.php',
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => $baseDir . '/../lib/Storage/PublicOwnerWrapper.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 8d232d8c8b792..a6840aafec8c7 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -346,6 +346,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\ServerFactory' => __DIR__ . '/..' . '/../lib/ServerFactory.php',
'OCA\\DAV\\Service\\AbsenceService' => __DIR__ . '/..' . '/../lib/Service/AbsenceService.php',
'OCA\\DAV\\Settings\\AvailabilitySettings' => __DIR__ . '/..' . '/../lib/Settings/AvailabilitySettings.php',
+ 'OCA\\DAV\\Settings\\BirthdayCalendarSettings' => __DIR__ . '/..' . '/../lib/Settings/BirthdayCalendarSettings.php',
'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__ . '/..' . '/../lib/Settings/CalDAVSettings.php',
'OCA\\DAV\\SetupChecks\\NeedsSystemAddressBookSync' => __DIR__ . '/..' . '/../lib/SetupChecks/NeedsSystemAddressBookSync.php',
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicOwnerWrapper.php',
diff --git a/apps/dav/lib/Listener/UserPreferenceListener.php b/apps/dav/lib/Listener/UserPreferenceListener.php
index 885ebbc36c6fb..642804cbd65bf 100644
--- a/apps/dav/lib/Listener/UserPreferenceListener.php
+++ b/apps/dav/lib/Listener/UserPreferenceListener.php
@@ -3,6 +3,7 @@
declare(strict_types=1);
/**
* @copyright Copyright (c) 2022 Joas Schilling
+ * @copyright Copyright (c) 2022 Cédric Neukom
*
* @author Joas Schilling
*
@@ -24,6 +25,7 @@
*/
namespace OCA\DAV\Listener;
+use DateInterval;
use OCA\DAV\BackgroundJob\UserStatusAutomation;
use OCP\BackgroundJob\IJobList;
use OCP\Config\BeforePreferenceDeletedEvent;
@@ -42,14 +44,37 @@ public function __construct(IJobList $jobList) {
public function handle(Event $event): void {
if ($event instanceof BeforePreferenceSetEvent) {
- if ($event->getAppId() === 'dav' && $event->getConfigKey() === 'user_status_automation' && $event->getConfigValue() === 'yes') {
- $event->setValid(true);
+ if ($event->getAppId() === 'dav') {
+ switch ($event->getConfigKey()) {
+ case 'user_status_automation':
+ if ($event->getConfigValue() === 'yes') {
+ $event->setValid(true);
+
+ // Not the cleanest way, but we just add the job in the before event.
+ // If something ever turns wrong the first execution will remove the job again.
+ // We also first delete the current job, so the next run time is reset.
+ $this->jobList->remove(UserStatusAutomation::class, ['userId' => $event->getUserId()]);
+ $this->jobList->add(UserStatusAutomation::class, ['userId' => $event->getUserId()]);
+ }
+ break;
- // Not the cleanest way, but we just add the job in the before event.
- // If something ever turns wrong the first execution will remove the job again.
- // We also first delete the current job, so the next run time is reset.
- $this->jobList->remove(UserStatusAutomation::class, ['userId' => $event->getUserId()]);
- $this->jobList->add(UserStatusAutomation::class, ['userId' => $event->getUserId()]);
+ case 'birthdayCalendarReminderOffset':
+ $configValue = $event->getConfigValue();
+ if (empty($configValue)) {
+ $event->setValid(true);
+ break;
+ }
+ if ($configValue[0] === '-') {
+ $configValue = substr($configValue, 1);
+ }
+ try {
+ new DateInterval($configValue);
+ $event->setValid(true);
+ } catch (\Exception $e) {
+ // Client attempted with an invalid duration string, do nothing
+ }
+ break;
+ }
}
} elseif ($event instanceof BeforePreferenceDeletedEvent) {
if ($event->getAppId() === 'dav' && $event->getConfigKey() === 'user_status_automation') {
diff --git a/apps/dav/lib/Settings/BirthdayCalendarSettings.php b/apps/dav/lib/Settings/BirthdayCalendarSettings.php
new file mode 100644
index 0000000000000..ef34cbafcfa3d
--- /dev/null
+++ b/apps/dav/lib/Settings/BirthdayCalendarSettings.php
@@ -0,0 +1,77 @@
+
+ *
+ * @author 2022 Cédric Neukom
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+declare(strict_types=1);
+
+namespace OCA\DAV\Settings;
+
+use OCA\DAV\AppInfo\Application;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\IConfig;
+use OCP\Settings\ISettings;
+
+class BirthdayCalendarSettings implements ISettings {
+ protected IConfig $config;
+ protected IInitialState $initialState;
+ protected ?string $userId;
+
+ public function __construct(IConfig $config,
+ IInitialState $initialState,
+ ?string $userId) {
+ $this->config = $config;
+ $this->initialState = $initialState;
+ $this->userId = $userId;
+ }
+
+ public function getForm(): TemplateResponse {
+ $this->initialState->provideInitialState(
+ 'userBirthdayCalendarEnabled',
+ $this->config->getUserValue(
+ $this->userId,
+ 'dav',
+ 'generateBirthdayCalendar',
+ 'no'
+ ) === 'yes'
+ );
+
+ $this->initialState->provideInitialState(
+ 'userBirthdayCalendarReminderOffset',
+ $this->config->getUserValue(
+ $this->userId,
+ 'dav',
+ 'birthdayCalendarReminderOffset',
+ 'PT9H'
+ ),
+ );
+
+ return new TemplateResponse(Application::APP_ID, 'settings-personal-birthday-calendar');
+ }
+
+ public function getSection(): string {
+ return 'groupware';
+ }
+
+ public function getPriority(): int {
+ return 20;
+ }
+}
diff --git a/apps/dav/src/service/BirthdayCalendarService.js b/apps/dav/src/service/BirthdayCalendarService.js
new file mode 100644
index 0000000000000..ebb0acb8d2a45
--- /dev/null
+++ b/apps/dav/src/service/BirthdayCalendarService.js
@@ -0,0 +1,68 @@
+/**
+ * @copyright 2022 Cédric Neukom
+ *
+ * @author 2022 Cédric Neukom
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+import axios from '@nextcloud/axios'
+import { generateOcsUrl } from '@nextcloud/router'
+import { getClient } from '../dav/client'
+
+const CALDAV_BIRTHDAY_CALENDAR = 'contact_birthdays'
+
+/**
+ * Disable birthday calendar
+ *
+ * @returns {Promise}
+ */
+export async function disableBirthdayCalendar() {
+ const client = getClient('calendars')
+ await client.customRequest(CALDAV_BIRTHDAY_CALENDAR, {
+ method: 'DELETE',
+ })
+}
+
+/**
+ * Enable birthday calendar
+ *
+ * @returns {Promise}
+ */
+export async function enableBirthdayCalendar() {
+ const client = getClient('calendars')
+ await client.customRequest('', {
+ method: 'POST',
+ data: '',
+ })
+}
+
+/**
+ * Save birthday reminder offset. Value must be a duration (e.g. -PT15H)
+ *
+ * @param reminderOffset
+ * @returns {Promise>}
+ */
+export async function saveBirthdayReminder(reminderOffset) {
+ return await axios.post(
+ generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
+ appId: 'dav',
+ configKey: 'birthdayCalendarReminderOffset',
+ }),
+ {
+ configValue: reminderOffset,
+ }
+ )
+}
diff --git a/apps/dav/src/settings-personal-birthday-calendar.js b/apps/dav/src/settings-personal-birthday-calendar.js
new file mode 100644
index 0000000000000..3974cfd6853ae
--- /dev/null
+++ b/apps/dav/src/settings-personal-birthday-calendar.js
@@ -0,0 +1,9 @@
+import Vue from 'vue'
+import { translate } from '@nextcloud/l10n'
+import BirthdayCalendarSettings from './views/BirthdayCalendarSettings'
+
+Vue.prototype.$t = translate
+
+const View = Vue.extend(BirthdayCalendarSettings);
+
+(new View({})).$mount('#settings-personal-birthday-calendar')
diff --git a/apps/dav/src/views/BirthdayCalendarSettings.vue b/apps/dav/src/views/BirthdayCalendarSettings.vue
new file mode 100644
index 0000000000000..babb69fd331d4
--- /dev/null
+++ b/apps/dav/src/views/BirthdayCalendarSettings.vue
@@ -0,0 +1,137 @@
+
+
+
+
+ {{ $t('dav', 'Enable birthday calendar') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/dav/templates/settings-personal-birthday-calendar.php b/apps/dav/templates/settings-personal-birthday-calendar.php
new file mode 100644
index 0000000000000..01a2ef66479f8
--- /dev/null
+++ b/apps/dav/templates/settings-personal-birthday-calendar.php
@@ -0,0 +1,5 @@
+
+
+
diff --git a/dist/dav-settings-personal-birthday-calendar.js b/dist/dav-settings-personal-birthday-calendar.js
new file mode 100644
index 0000000000000..60433e6f9affa
--- /dev/null
+++ b/dist/dav-settings-personal-birthday-calendar.js
@@ -0,0 +1,3 @@
+/*! For license information please see dav-settings-personal-birthday-calendar.js.LICENSE.txt */
+!function(){var n,e={81969:function(n,e,r){"use strict";var a=r(20144),i=r(9944),o=r(26932),d=r(16453),s=r(1412),u=r.n(s),c=r(7826),l=r.n(c),f=r(67776),h=r.n(f),p=r(7811),v=r.n(p),b=r(4820),y=r(79753),m=r(81063),g=r(56580),x=r.n(g),C=r(22200),w=x()((function(n){return b.default.defaults.headers["X-Requested-With"]="XMLHttpRequest",m.getPatcher().patch("request",b.default),m.createClient((0,y.generateRemoteUrl)("dav/".concat(n,"/").concat((0,C.getCurrentUser)().uid)))}));function R(n,e,t,r,a,i,o){try{var d=n[i](o),s=d.value}catch(n){return void t(n)}d.done?e(s):Promise.resolve(s).then(r,a)}function A(n){return function(){var e=this,t=arguments;return new Promise((function(r,a){var i=n.apply(e,t);function o(n){R(i,r,a,o,d,"next",n)}function d(n){R(i,r,a,o,d,"throw",n)}o(void 0)}))}}var B="contact_birthdays";function k(){return O.apply(this,arguments)}function O(){return(O=A(regeneratorRuntime.mark((function n(){var e;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return e=w("calendars"),n.next=3,e.customRequest(B,{method:"DELETE"});case 3:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function S(){return _.apply(this,arguments)}function _(){return(_=A(regeneratorRuntime.mark((function n(){var e;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return e=w("calendars"),n.next=3,e.customRequest("",{method:"POST",data:''});case 3:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function P(n){return E.apply(this,arguments)}function E(){return(E=A(regeneratorRuntime.mark((function n(e){return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,b.default.post((0,y.generateOcsUrl)("/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"dav",configKey:"birthdayCalendarReminderOffset"}),{configValue:e});case 2:return n.abrupt("return",n.sent);case 3:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function T(n,e,t,r,a,i,o){try{var d=n[i](o),s=d.value}catch(n){return void t(n)}d.done?e(s):Promise.resolve(s).then(r,a)}var M={name:"BirthdayCalendarSettings",components:{Button:u(),CheckboxRadioSwitch:l(),SettingsSection:h(),Multiselect:v()},data:function(){var n=["","PT9H","-PT15H","-P1DT15H","-P6DT15H"],e=[t("dav","None"),t("dav","Same day (9 AM)"),t("dav","1 day before (9 AM)"),t("dav","2 days before (9 AM)"),t("dav","1 week before (9 AM)")],r=(0,d.loadState)("dav","userBirthdayCalendarEnabled"),a=(0,d.loadState)("dav","userBirthdayCalendarReminderOffset");return{saving:!1,isBirthdayCalendarEnabled:r,enableBirthdayCalendar:r,birthdayReminder:e[n.indexOf(a)],birthdayReminderOptions:e,birthdayReminderValues:n}},methods:{save:function(){var n,e=this;return(n=regeneratorRuntime.mark((function n(){return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.prev=0,e.saving=!0,n.next=4,P(e.birthdayReminderValues[e.birthdayReminderOptions.indexOf(e.birthdayReminder)]);case 4:if(!e.isBirthdayCalendarEnabled||e.enableBirthdayCalendar){n.next=9;break}return n.next=7,k();case 7:n.next=12;break;case 9:if(e.isBirthdayCalendarEnabled||!e.enableBirthdayCalendar){n.next=12;break}return n.next=12,S();case 12:e.isBirthdayCalendarEnabled=e.enableBirthdayCalendar,(0,o.s$)(t("dav","Saved birthday calendar settings")),n.next=20;break;case 16:n.prev=16,n.t0=n.catch(0),console.error("could birthday calendar settings",n.t0),(0,o.x2)(t("dav","Failed to save birthday calendar settings"));case 20:return n.prev=20,e.saving=!1,n.finish(20);case 23:case"end":return n.stop()}}),n,null,[[0,16,20,23]])})),function(){var e=this,t=arguments;return new Promise((function(r,a){var i=n.apply(e,t);function o(n){T(i,r,a,o,d,"next",n)}function d(n){T(i,r,a,o,d,"throw",n)}o(void 0)}))})()}}},j=M,$=r(93379),Z=r.n($),q=r(7795),H=r.n(q),I=r(90569),D=r.n(I),U=r(3565),V=r.n(U),F=r(19216),K=r.n(F),L=r(44589),X=r.n(L),z=r(28161),N={};N.styleTagTransform=X(),N.setAttributes=V(),N.insert=D().bind(null,"head"),N.domAPI=H(),N.insertStyleElement=K(),Z()(z.Z,N),z.Z&&z.Z.locals&&z.Z.locals;var W=(0,r(51900).Z)(j,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("SettingsSection",{attrs:{title:n.$t("dav","Birthday Calendar")}},[t("CheckboxRadioSwitch",{attrs:{checked:n.enableBirthdayCalendar},on:{"update:checked":function(e){n.enableBirthdayCalendar=e}}},[n._v("\n\t\t"+n._s(n.$t("dav","Enable birthday calendar"))+"\n\t")]),n._v(" "),t("div",{staticClass:"select-container"},[t("label",{attrs:{for:"birthdayReminder"}},[n._v("\n\t\t\t"+n._s(n.$t("dav","Birthday reminder:"))+"\n\t\t")]),n._v(" "),t("span",{staticClass:"time-zone-text"},[t("Multiselect",{attrs:{options:n.birthdayReminderOptions,disabled:!n.enableBirthdayCalendar,id:"birthdayReminder"},model:{value:n.birthdayReminder,callback:function(e){n.birthdayReminder=e},expression:"birthdayReminder"}})],1)]),n._v(" "),t("Button",{attrs:{disabled:n.saving,type:"primary"},on:{click:n.save}},[n._v("\n\t\t"+n._s(n.$t("dav","Save"))+"\n\t")])],1)}),[],!1,null,null,null).exports;a.default.prototype.$t=i.translate,new(a.default.extend(W))({}).$mount("#settings-personal-birthday-calendar")},28161:function(n,e,t){"use strict";var r=t(87537),a=t.n(r),i=t(23645),o=t.n(i)()(a());o.push([n.id,".select-container{padding:12px 12px 12px 0}.select-container>label{padding-right:22px;font-weight:bold}","",{version:3,sources:["webpack://./apps/dav/src/views/BirthdayCalendarSettings.vue"],names:[],mappings:"AAgIA,kBACC,wBAAA,CAEA,wBACC,kBAAA,CACA,gBAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.select-container {\n\tpadding: 12px 12px 12px 0;\n\n\t> label {\n\t\tpadding-right: 22px;\n\t\tfont-weight: bold;\n\t}\n}\n"],sourceRoot:""}]),e.Z=o},69862:function(){},40964:function(){}},r={};function a(n){var t=r[n];if(void 0!==t)return t.exports;var i=r[n]={id:n,loaded:!1,exports:{}};return e[n].call(i.exports,i,i.exports,a),i.loaded=!0,i.exports}a.m=e,a.amdD=function(){throw new Error("define cannot be used indirect")},a.amdO={},n=[],a.O=function(e,t,r,i){if(!t){var o=1/0;for(c=0;c=i)&&Object.keys(a.O).every((function(n){return a.O[n](t[s])}))?t.splice(s--,1):(d=!1,i0&&n[c-1][2]>i;c--)n[c]=n[c-1];n[c]=[t,r,i]},a.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return a.d(e,{a:e}),e},a.d=function(n,e){for(var t in e)a.o(e,t)&&!a.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),a.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},a.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},a.nmd=function(n){return n.paths=[],n.children||(n.children=[]),n},a.j=9340,function(){a.b=document.baseURI||self.location.href;var n={9340:0};a.O.j=function(e){return 0===n[e]};var e=function(e,t){var r,i,o=t[0],d=t[1],s=t[2],u=0;if(o.some((function(e){return 0!==n[e]}))){for(r in d)a.o(d,r)&&(a.m[r]=d[r]);if(s)var c=s(a)}for(e&&e(t);u
+ *
+ * @author 2022 Cédric Neukom
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
diff --git a/dist/dav-settings-personal-birthday-calendar.js.map b/dist/dav-settings-personal-birthday-calendar.js.map
new file mode 100644
index 0000000000000..b6285b7dc8a9c
--- /dev/null
+++ b/dist/dav-settings-personal-birthday-calendar.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"dav-settings-personal-birthday-calendar.js?v=139a8df093bea961f532","mappings":"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","sources":["webpack:///nextcloud/webpack/runtime/chunk loaded","webpack:///nextcloud/apps/dav/src/dav/client.js","webpack:///nextcloud/apps/dav/src/service/BirthdayCalendarService.js","webpack:///nextcloud/apps/dav/src/views/BirthdayCalendarSettings.vue","webpack:///nextcloud/apps/dav/src/views/BirthdayCalendarSettings.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/dav/src/views/BirthdayCalendarSettings.vue?970a","webpack://nextcloud/./apps/dav/src/views/BirthdayCalendarSettings.vue?4cde","webpack:///nextcloud/apps/dav/src/views/BirthdayCalendarSettings.vue?vue&type=template&id=4b79aad0&","webpack:///nextcloud/apps/dav/src/settings-personal-birthday-calendar.js","webpack:///nextcloud/apps/dav/src/views/BirthdayCalendarSettings.vue?vue&type=style&index=0&lang=scss&","webpack:///nextcloud/webpack/bootstrap","webpack:///nextcloud/webpack/runtime/amd define","webpack:///nextcloud/webpack/runtime/amd options","webpack:///nextcloud/webpack/runtime/compat get default export","webpack:///nextcloud/webpack/runtime/define property getters","webpack:///nextcloud/webpack/runtime/global","webpack:///nextcloud/webpack/runtime/hasOwnProperty shorthand","webpack:///nextcloud/webpack/runtime/make namespace object","webpack:///nextcloud/webpack/runtime/node module decorator","webpack:///nextcloud/webpack/runtime/runtimeId","webpack:///nextcloud/webpack/runtime/jsonp chunk loading","webpack:///nextcloud/webpack/runtime/nonce","webpack:///nextcloud/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","/*\n * @copyright 2021 Christoph Wurst \n *\n * @author 2021 Christoph Wurst \n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see .\n */\n\nimport * as webdav from 'webdav'\nimport axios from '@nextcloud/axios'\nimport memoize from 'lodash/fp/memoize'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { getCurrentUser } from '@nextcloud/auth'\n\nexport const getClient = memoize((service) => {\n\t// Add this so the server knows it is an request from the browser\n\taxios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'\n\n\t// force our axios\n\tconst patcher = webdav.getPatcher()\n\tpatcher.patch('request', axios)\n\n\treturn webdav.createClient(\n\t\tgenerateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)\n\t)\n})\n","/**\n * @copyright 2022 Cédric Neukom \n *\n * @author 2022 Cédric Neukom \n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see .\n */\nimport axios from '@nextcloud/axios'\nimport { generateOcsUrl } from '@nextcloud/router'\nimport { getClient } from '../dav/client'\n\nconst CALDAV_BIRTHDAY_CALENDAR = 'contact_birthdays'\n\n/**\n * Disable birthday calendar\n *\n * @returns {Promise}\n */\nexport async function disableBirthdayCalendar() {\n\tconst client = getClient('calendars')\n\tawait client.customRequest(CALDAV_BIRTHDAY_CALENDAR, {\n\t\tmethod: 'DELETE',\n\t})\n}\n\n/**\n * Enable birthday calendar\n *\n * @returns {Promise}\n */\nexport async function enableBirthdayCalendar() {\n\tconst client = getClient('calendars')\n\tawait client.customRequest('', {\n\t\tmethod: 'POST',\n\t\tdata: '',\n\t})\n}\n\n/**\n * Save birthday reminder offset. Value must be a duration (e.g. -PT15H)\n *\n * @param reminderOffset\n * @returns {Promise>}\n */\nexport async function saveBirthdayReminder(reminderOffset) {\n\treturn await axios.post(\n\t\tgenerateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\tappId: 'dav',\n\t\t\tconfigKey: 'birthdayCalendarReminderOffset',\n\t\t}),\n\t\t{\n\t\t\tconfigValue: reminderOffset,\n\t\t}\n\t)\n}\n","\n\n\t\n\t\t\n\t\t\t{{ $t('dav', 'Enable birthday calendar') }}\n\t\t\n\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t
\n\n\t\t\n\t\n\n\n\n\n\n","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BirthdayCalendarSettings.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BirthdayCalendarSettings.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BirthdayCalendarSettings.vue?vue&type=style&index=0&lang=scss&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BirthdayCalendarSettings.vue?vue&type=style&index=0&lang=scss&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./BirthdayCalendarSettings.vue?vue&type=template&id=4b79aad0&\"\nimport script from \"./BirthdayCalendarSettings.vue?vue&type=script&lang=js&\"\nexport * from \"./BirthdayCalendarSettings.vue?vue&type=script&lang=js&\"\nimport style0 from \"./BirthdayCalendarSettings.vue?vue&type=style&index=0&lang=scss&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('SettingsSection',{attrs:{\"title\":_vm.$t('dav', 'Birthday Calendar')}},[_c('CheckboxRadioSwitch',{attrs:{\"checked\":_vm.enableBirthdayCalendar},on:{\"update:checked\":function($event){_vm.enableBirthdayCalendar=$event}}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.$t('dav', 'Enable birthday calendar'))+\"\\n\\t\")]),_vm._v(\" \"),_c('div',{staticClass:\"select-container\"},[_c('label',{attrs:{\"for\":\"birthdayReminder\"}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.$t('dav', 'Birthday reminder:'))+\"\\n\\t\\t\")]),_vm._v(\" \"),_c('span',{staticClass:\"time-zone-text\"},[_c('Multiselect',{attrs:{\"options\":_vm.birthdayReminderOptions,\"disabled\":!_vm.enableBirthdayCalendar,\"id\":\"birthdayReminder\"},model:{value:(_vm.birthdayReminder),callback:function ($$v) {_vm.birthdayReminder=$$v},expression:\"birthdayReminder\"}})],1)]),_vm._v(\" \"),_c('Button',{attrs:{\"disabled\":_vm.saving,\"type\":\"primary\"},on:{\"click\":_vm.save}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.$t('dav', 'Save'))+\"\\n\\t\")])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import Vue from 'vue'\nimport { translate } from '@nextcloud/l10n'\nimport BirthdayCalendarSettings from './views/BirthdayCalendarSettings'\n\nVue.prototype.$t = translate\n\nconst View = Vue.extend(BirthdayCalendarSettings);\n\n(new View({})).$mount('#settings-personal-birthday-calendar')\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".select-container{padding:12px 12px 12px 0}.select-container>label{padding-right:22px;font-weight:bold}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/dav/src/views/BirthdayCalendarSettings.vue\"],\"names\":[],\"mappings\":\"AAgIA,kBACC,wBAAA,CAEA,wBACC,kBAAA,CACA,gBAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.select-container {\\n\\tpadding: 12px 12px 12px 0;\\n\\n\\t> label {\\n\\t\\tpadding-right: 22px;\\n\\t\\tfont-weight: bold;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdD = function () {\n\tthrow new Error('define cannot be used indirect');\n};","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.j = 9340;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t9340: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunknextcloud\"] = self[\"webpackChunknextcloud\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [7874], function() { return __webpack_require__(81969); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","getClient","memoize","service","axios","webdav","patch","generateRemoteUrl","getCurrentUser","uid","CALDAV_BIRTHDAY_CALENDAR","disableBirthdayCalendar","client","customRequest","method","enableBirthdayCalendar","data","saveBirthdayReminder","reminderOffset","generateOcsUrl","appId","configKey","configValue","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","attrs","$t","on","$event","_v","_s","staticClass","birthdayReminderOptions","model","value","callback","$$v","birthdayReminder","expression","saving","save","Vue","translate","BirthdayCalendarSettings","$mount","___CSS_LOADER_EXPORT___","push","module","id","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","loaded","__webpack_modules__","call","m","amdD","Error","amdO","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","length","fulfilled","j","Object","keys","every","key","splice","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","window","obj","prop","prototype","hasOwnProperty","Symbol","toStringTag","nmd","paths","children","b","document","baseURI","self","location","href","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","forEach","bind","nc","__webpack_exports__"],"sourceRoot":""}
\ No newline at end of file
diff --git a/webpack.modules.js b/webpack.modules.js
index 09be290eb10c6..cd7a4823bcbae 100644
--- a/webpack.modules.js
+++ b/webpack.modules.js
@@ -48,6 +48,7 @@ module.exports = {
dav: {
'settings-admin-caldav': path.join(__dirname, 'apps/dav/src', 'settings.js'),
'settings-personal-availability': path.join(__dirname, 'apps/dav/src', 'settings-personal-availability.js'),
+ 'settings-personal-birthday-calendar': path.join(__dirname, 'apps/dav/src', 'settings-personal-birthday-calendar.js'),
},
files: {
sidebar: path.join(__dirname, 'apps/files/src', 'sidebar.js'),