From 19b08b35215208bbf30cad7d1d8222613b37c1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Neukom?= Date: Thu, 28 Jul 2022 21:52:09 +0200 Subject: [PATCH 1/8] Add birthday calendar configuration to personal settings UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Neukom --- apps/dav/appinfo/info.xml | 1 + .../composer/composer/autoload_classmap.php | 1 + .../dav/composer/composer/autoload_static.php | 1 + apps/dav/l10n/en_GB.js | 3 +- apps/dav/l10n/en_GB.json | 5 +- .../lib/Listener/UserPreferenceListener.php | 39 ++++- .../lib/Settings/BirthdayCalendarSettings.php | 67 +++++++++ .../src/service/BirthdayCalendarService.js | 89 +++++++++++ .../settings-personal-birthday-calendar.js | 9 ++ .../src/views/BirthdayCalendarSettings.vue | 140 ++++++++++++++++++ .../settings-personal-birthday-calendar.php | 5 + ...dav-settings-personal-birthday-calendar.js | 3 + ...-personal-birthday-calendar.js.LICENSE.txt | 20 +++ ...settings-personal-birthday-calendar.js.map | 1 + webpack.modules.js | 1 + 15 files changed, 375 insertions(+), 10 deletions(-) create mode 100644 apps/dav/lib/Settings/BirthdayCalendarSettings.php create mode 100644 apps/dav/src/service/BirthdayCalendarService.js create mode 100644 apps/dav/src/settings-personal-birthday-calendar.js create mode 100644 apps/dav/src/views/BirthdayCalendarSettings.vue create mode 100644 apps/dav/templates/settings-personal-birthday-calendar.php create mode 100644 dist/dav-settings-personal-birthday-calendar.js create mode 100644 dist/dav-settings-personal-birthday-calendar.js.LICENSE.txt create mode 100644 dist/dav-settings-personal-birthday-calendar.js.map diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index deb99b1c33bf1..a4ef6d1e12606 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -62,6 +62,7 @@ OCA\DAV\Settings\CalDAVSettings OCA\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 b01ae68e43a38..14926a0f9dad9 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -294,6 +294,7 @@ 'OCA\\DAV\\Search\\TasksSearchProvider' => $baseDir . '/../lib/Search/TasksSearchProvider.php', 'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.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\\Storage\\PublicOwnerWrapper' => $baseDir . '/../lib/Storage/PublicOwnerWrapper.php', 'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => $baseDir . '/../lib/SystemTag/SystemTagMappingNode.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index 4c9a1dcc79381..3d131647dcffb 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -309,6 +309,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Search\\TasksSearchProvider' => __DIR__ . '/..' . '/../lib/Search/TasksSearchProvider.php', 'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.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\\Storage\\PublicOwnerWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicOwnerWrapper.php', 'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagMappingNode.php', diff --git a/apps/dav/l10n/en_GB.js b/apps/dav/l10n/en_GB.js index 11229abe9f411..e326289deb95d 100644 --- a/apps/dav/l10n/en_GB.js +++ b/apps/dav/l10n/en_GB.js @@ -64,6 +64,7 @@ OC.L10N.register( "Birthday calendars will be generated by a background job." : "Birthday calendars will be generated by a background job.", "Hence they will not be available immediately after enabling but will show up after some time." : "Hence they will not be available immediately after enabling but will show up after some time.", "Hello %s," : "Hello %s,", - "When:" : "When:" + "When:" : "When:", + "No reminder on birthday" : "None" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/en_GB.json b/apps/dav/l10n/en_GB.json index 2acf739fa3378..92c61775f8283 100644 --- a/apps/dav/l10n/en_GB.json +++ b/apps/dav/l10n/en_GB.json @@ -62,6 +62,7 @@ "Birthday calendars will be generated by a background job." : "Birthday calendars will be generated by a background job.", "Hence they will not be available immediately after enabling but will show up after some time." : "Hence they will not be available immediately after enabling but will show up after some time.", "Hello %s," : "Hello %s,", - "When:" : "When:" + "When:" : "When:", + "No reminder on birthday" : "None" },"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file +} diff --git a/apps/dav/lib/Listener/UserPreferenceListener.php b/apps/dav/lib/Listener/UserPreferenceListener.php index 947f6d3fd0147..650ee7f13002c 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; @@ -41,14 +43,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..259ec22ffd54d --- /dev/null +++ b/apps/dav/lib/Settings/BirthdayCalendarSettings.php @@ -0,0 +1,67 @@ + + * + * @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( + 'userBirthdayCalendar', + $this->config->getUserValue( + $this->userId, + 'dav', + 'user_status_automation', + 'no' + ) + ); + + 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..5c3f11d991a86 --- /dev/null +++ b/apps/dav/src/service/BirthdayCalendarService.js @@ -0,0 +1,89 @@ +/** + * @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'; + +/** + * Checks if the birthday calendar is currently enabled by looking it up at the DAV server + * + * @returns {Promise} + */ +export async function isBirthdayCalendarEnabled () { + const client = getClient('calendars') + try { + await client.customRequest(CALDAV_BIRTHDAY_CALENDAR, { + method: 'PROPFIND', + }) + return true + } catch (e) { + if(e.status === 404) { + return false + } else { + throw e + } + } +} + +/** + * 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..2052fab09dc7d --- /dev/null +++ b/apps/dav/src/views/BirthdayCalendarSettings.vue @@ -0,0 +1,140 @@ + + + + + + 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..dd5adc147bb9b --- /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={77165:function(n,e,r){"use strict";var a=r(20144),i=r(9944),o=r(26932),d=r(1412),u=r.n(d),s=r(7826),c=r.n(s),l=r(67776),f=r.n(l),p=r(7811),h=r.n(p),v=r(4820),b=r(79753),y=r(81063),m=r(56580),g=r.n(m),x=r(22200),w=g()((function(n){return v.default.defaults.headers["X-Requested-With"]="XMLHttpRequest",y.getPatcher().patch("request",v.default),y.createClient((0,b.generateRemoteUrl)("dav/".concat(n,"/").concat((0,x.getCurrentUser)().uid)))}));function R(n,e,t,r,a,i,o){try{var d=n[i](o),u=d.value}catch(n){return void t(n)}d.done?e(u):Promise.resolve(u).then(r,a)}function C(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 k="contact_birthdays";function B(){return A.apply(this,arguments)}function A(){return(A=C(regeneratorRuntime.mark((function n(){var e;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return e=w("calendars"),n.prev=1,n.next=4,e.customRequest(k,{method:"PROPFIND"});case 4:return n.abrupt("return",!0);case 7:if(n.prev=7,n.t0=n.catch(1),404!==n.t0.status){n.next=13;break}return n.abrupt("return",!1);case 13:throw n.t0;case 14:case"end":return n.stop()}}),n,null,[[1,7]])})))).apply(this,arguments)}function O(){return P.apply(this,arguments)}function P(){return(P=C(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(k,{method:"DELETE"});case 3:case"end":return n.stop()}}),n)})))).apply(this,arguments)}function S(){return _.apply(this,arguments)}function _(){return(_=C(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 E(n){return T.apply(this,arguments)}function T(){return(T=C(regeneratorRuntime.mark((function n(e){return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,v.default.post((0,b.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 M(n,e,t,r,a,i,o){try{var d=n[i](o),u=d.value}catch(n){return void t(n)}d.done?e(u):Promise.resolve(u).then(r,a)}function j(n){return function(){var e=this,t=arguments;return new Promise((function(r,a){var i=n.apply(e,t);function o(n){M(i,r,a,o,d,"next",n)}function d(n){M(i,r,a,o,d,"throw",n)}o(void 0)}))}}var $={name:"BirthdayCalendarSettings",components:{Button:u(),CheckboxRadioSwitch:c(),SettingsSection:f(),Multiselect:h()},data:function(){var n=["","PT9H","-PT15H","-P1DT15H","-P6DT15H"],e=[t("dav","No reminder on birthday"),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)")];return{loading:!0,saving:!1,isBirthdayCalendarEnabled:!1,enableBirthdayCalendar:!1,birthdayReminder:e[n.indexOf("PT9H")],birthdayReminderOptions:e,birthdayReminderValues:n}},mounted:function(){var n=this;return j(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,B();case 2:n.isBirthdayCalendarEnabled=e.sent,n.enableBirthdayCalendar=n.isBirthdayCalendarEnabled,n.loading=!1;case 5:case"end":return e.stop()}}),e)})))()},methods:{save:function(){var n=this;return j(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,n.saving=!0,e.next=4,E(n.birthdayReminderValues[n.birthdayReminderOptions.indexOf(n.birthdayReminder)]);case 4:if(!n.isBirthdayCalendarEnabled||n.enableBirthdayCalendar){e.next=9;break}return e.next=7,O();case 7:e.next=12;break;case 9:if(n.isBirthdayCalendarEnabled||!n.enableBirthdayCalendar){e.next=12;break}return e.next=12,S();case 12:n.isBirthdayCalendarEnabled=n.enableBirthdayCalendar,(0,o.s$)(t("dav","Saved birthday calendar settings")),e.next=20;break;case 16:e.prev=16,e.t0=e.catch(0),console.error("could birthday calendar settings",e.t0),(0,o.x2)(t("dav","Failed to save birthday calendar settings"));case 20:return e.prev=20,n.saving=!1,e.finish(20);case 23:case"end":return e.stop()}}),e,null,[[0,16,20,23]])})))()}}},q=r(93379),H=r.n(q),I=r(7795),Z=r.n(I),D=r(90569),U=r.n(D),F=r(3565),V=r.n(F),K=r(19216),L=r.n(K),N=r(44589),X=r.n(N),z=r(28161),W={};W.styleTagTransform=X(),W.setAttributes=V(),W.insert=U().bind(null,"head"),W.domAPI=Z(),W.insertStyleElement=L(),H()(z.Z,W),z.Z&&z.Z.locals&&z.Z.locals;var G=(0,r(51900).Z)($,(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,disabled:n.loading},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||n.loading,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(G))({}).$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:"AAmIA,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\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[u])}))?t.splice(u--,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],u=t[2],s=0;if(o.some((function(e){return 0!==n[e]}))){for(r in d)a.o(d,r)&&(a.m[r]=d[r]);if(u)var c=u(a)}for(e&&e(t);s + * + * @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..29ebeecf99e00 --- /dev/null +++ b/dist/dav-settings-personal-birthday-calendar.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dav-settings-personal-birthday-calendar.js?v=12f97b796802d60ac926","mappings":";gBAAIA,wNC2BSC,EAAYC,GAAAA,EAAQ,SAACC,GAQjC,OANAC,EAAAA,QAAAA,SAAAA,QAAAA,oBAA6C,iBAG7BC,EAAAA,aACRC,MAAM,UAAWF,EAAAA,SAElBC,EAAAA,cACNE,EAAAA,EAAAA,mBAAkB,OAAD,OAAQJ,EAAR,aAAmBK,EAAAA,EAAAA,kBAAiBC,sUCZvD,IAAMC,EAA2B,oBAO1B,SAAeC,IAAtB,gFAAO,0GACAC,EAASX,EAAU,aADnB,kBAGCW,EAAOC,cAAcH,EAA0B,CACpDI,OAAQ,aAJJ,iCAME,GANF,mCAQW,MAAb,KAAEC,OARA,2CASG,GATH,mGAqBA,SAAeC,IAAtB,gFAAO,0GACAJ,EAASX,EAAU,aADnB,SAEAW,EAAOC,cAAcH,EAA0B,CACpDI,OAAQ,WAHH,kEAYA,SAAeG,IAAtB,gFAAO,0GACAL,EAASX,EAAU,aADnB,SAEAW,EAAOC,cAAc,GAAI,CAC9BC,OAAQ,OACRI,KAAM,sEAJD,kEAcA,SAAeC,EAAtB,mFAAO,WAAqCC,GAArC,gGACOhB,EAAAA,QAAAA,MACZiB,EAAAA,EAAAA,gBAAe,iEAAkE,CAChFC,MAAO,MACPC,UAAW,mCAEZ,CACCC,YAAaJ,IAPT,saCfP,IC/DqM,ED+DrM,CACA,gCACA,YACA,WACA,wBACA,oBACA,iBAEA,KARA,WASA,OACA,GACA,OACA,SACA,WACA,YAGA,GACA,mCACA,2BACA,+BACA,gCACA,iCAGA,OACA,WACA,UACA,6BACA,0BACA,sCACA,0BACA,2BAGA,QAnCA,WAmCA,0JACA,IADA,OACA,4BADA,OAEA,qDACA,aAHA,8CAKA,SACA,KADA,WACA,0JAEA,YAFA,SAIA,mFAJA,WAMA,sDANA,gCAOA,IAPA,iCAQA,uDARA,kCASA,IATA,QAWA,sDAEA,qDAbA,kDAeA,wDAEA,8DAjBA,yBAmBA,YAnBA,mNE7FIK,EAAU,GAEdA,EAAQC,kBAAoB,IAC5BD,EAAQE,cAAgB,IAElBF,EAAQG,OAAS,SAAc,KAAM,QAE3CH,EAAQI,OAAS,IACjBJ,EAAQK,mBAAqB,IAEhB,IAAI,IAASL,GAKJ,KAAW,YAAiB,WALlD,ICFA,GAXgB,cACd,GCTW,WAAa,IAAIM,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,kBAAkB,CAACE,MAAM,CAAC,MAAQN,EAAIO,GAAG,MAAO,uBAAuB,CAACH,EAAG,sBAAsB,CAACE,MAAM,CAAC,QAAUN,EAAId,uBAAuB,SAAWc,EAAIQ,SAASC,GAAG,CAAC,iBAAiB,SAASC,GAAQV,EAAId,uBAAuBwB,KAAU,CAACV,EAAIW,GAAG,SAASX,EAAIY,GAAGZ,EAAIO,GAAG,MAAO,6BAA6B,UAAUP,EAAIW,GAAG,KAAKP,EAAG,MAAM,CAACS,YAAY,oBAAoB,CAACT,EAAG,QAAQ,CAACE,MAAM,CAAC,IAAM,qBAAqB,CAACN,EAAIW,GAAG,WAAWX,EAAIY,GAAGZ,EAAIO,GAAG,MAAO,uBAAuB,YAAYP,EAAIW,GAAG,KAAKP,EAAG,OAAO,CAACS,YAAY,kBAAkB,CAACT,EAAG,cAAc,CAACE,MAAM,CAAC,QAAUN,EAAIc,wBAAwB,UAAYd,EAAId,uBAAuB,GAAK,oBAAoB6B,MAAM,CAACC,MAAOhB,EAAoB,iBAAEiB,SAAS,SAAUC,GAAMlB,EAAImB,iBAAiBD,GAAKE,WAAW,uBAAuB,KAAKpB,EAAIW,GAAG,KAAKP,EAAG,SAAS,CAACE,MAAM,CAAC,SAAWN,EAAIqB,QAAUrB,EAAIQ,QAAQ,KAAO,WAAWC,GAAG,CAAC,MAAQT,EAAIsB,OAAO,CAACtB,EAAIW,GAAG,SAASX,EAAIY,GAAGZ,EAAIO,GAAG,MAAO,SAAS,WAAW,KACthC,IDWpB,EACA,KACA,KACA,MAI8B,QEfhCgB,EAAAA,QAAAA,UAAAA,GAAmBC,EAAAA,UAIlB,IAFYD,EAAAA,QAAAA,OAAWE,GAEvB,CAAS,IAAKC,OAAO,+GCLlBC,QAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOC,GAAI,0GAA2G,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,+DAA+D,MAAQ,GAAG,SAAW,gDAAgD,eAAiB,CAAC,sYAAsY,WAAa,MAEztB,8CCNIC,EAA2B,GAG/B,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaE,QAGrB,IAAIP,EAASE,EAAyBE,GAAY,CACjDH,GAAIG,EACJI,QAAQ,EACRD,QAAS,IAUV,OANAE,EAAoBL,GAAUM,KAAKV,EAAOO,QAASP,EAAQA,EAAOO,QAASJ,GAG3EH,EAAOQ,QAAS,EAGTR,EAAOO,QAIfJ,EAAoBQ,EAAIF,EC5BxBN,EAAoBS,KAAO,WAC1B,MAAM,IAAIC,MAAM,mCCDjBV,EAAoBW,KAAO,GZAvB1E,EAAW,GACf+D,EAAoBY,EAAI,SAASC,EAAQC,EAAUC,EAAIC,GACtD,IAAGF,EAAH,CAMA,IAAIG,EAAeC,EAAAA,EACnB,IAASC,EAAI,EAAGA,EAAIlF,EAASmF,OAAQD,IAAK,CACrCL,EAAW7E,EAASkF,GAAG,GACvBJ,EAAK9E,EAASkF,GAAG,GACjBH,EAAW/E,EAASkF,GAAG,GAE3B,IAJA,IAGIE,GAAY,EACPC,EAAI,EAAGA,EAAIR,EAASM,OAAQE,MACpB,EAAXN,GAAsBC,GAAgBD,IAAaO,OAAOC,KAAKxB,EAAoBY,GAAGa,OAAM,SAASC,GAAO,OAAO1B,EAAoBY,EAAEc,GAAKZ,EAASQ,OAC3JR,EAASa,OAAOL,IAAK,IAErBD,GAAY,EACTL,EAAWC,IAAcA,EAAeD,IAG7C,GAAGK,EAAW,CACbpF,EAAS0F,OAAOR,IAAK,GACrB,IAAIS,EAAIb,SACEZ,IAANyB,IAAiBf,EAASe,IAGhC,OAAOf,EAzBNG,EAAWA,GAAY,EACvB,IAAI,IAAIG,EAAIlF,EAASmF,OAAQD,EAAI,GAAKlF,EAASkF,EAAI,GAAG,GAAKH,EAAUG,IAAKlF,EAASkF,GAAKlF,EAASkF,EAAI,GACrGlF,EAASkF,GAAK,CAACL,EAAUC,EAAIC,IaJ/BhB,EAAoB6B,EAAI,SAAShC,GAChC,IAAIiC,EAASjC,GAAUA,EAAOkC,WAC7B,WAAa,OAAOlC,EAAgB,SACpC,WAAa,OAAOA,GAErB,OADAG,EAAoBgC,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,GCLR9B,EAAoBgC,EAAI,SAAS5B,EAAS8B,GACzC,IAAI,IAAIR,KAAOQ,EACXlC,EAAoBmC,EAAED,EAAYR,KAAS1B,EAAoBmC,EAAE/B,EAASsB,IAC5EH,OAAOa,eAAehC,EAASsB,EAAK,CAAEW,YAAY,EAAMC,IAAKJ,EAAWR,MCJ3E1B,EAAoBuC,EAAI,WACvB,GAA0B,iBAAfC,WAAyB,OAAOA,WAC3C,IACC,OAAOvE,MAAQ,IAAIwE,SAAS,cAAb,GACd,MAAOC,GACR,GAAsB,iBAAXC,OAAqB,OAAOA,QALjB,GCAxB3C,EAAoBmC,EAAI,SAASS,EAAKC,GAAQ,OAAOtB,OAAOuB,UAAUC,eAAexC,KAAKqC,EAAKC,ICC/F7C,EAAoB4B,EAAI,SAASxB,GACX,oBAAX4C,QAA0BA,OAAOC,aAC1C1B,OAAOa,eAAehC,EAAS4C,OAAOC,YAAa,CAAEjE,MAAO,WAE7DuC,OAAOa,eAAehC,EAAS,aAAc,CAAEpB,OAAO,KCLvDgB,EAAoBkD,IAAM,SAASrD,GAGlC,OAFAA,EAAOsD,MAAQ,GACVtD,EAAOuD,WAAUvD,EAAOuD,SAAW,IACjCvD,GCHRG,EAAoBsB,EAAI,gBCAxBtB,EAAoBqD,EAAIC,SAASC,SAAWC,KAAKC,SAASC,KAK1D,IAAIC,EAAkB,CACrB,KAAM,GAaP3D,EAAoBY,EAAEU,EAAI,SAASsC,GAAW,OAAoC,IAA7BD,EAAgBC,IAGrE,IAAIC,EAAuB,SAASC,EAA4B3G,GAC/D,IAKI8C,EAAU2D,EALV9C,EAAW3D,EAAK,GAChB4G,EAAc5G,EAAK,GACnB6G,EAAU7G,EAAK,GAGIgE,EAAI,EAC3B,GAAGL,EAASmD,MAAK,SAASnE,GAAM,OAA+B,IAAxB6D,EAAgB7D,MAAe,CACrE,IAAIG,KAAY8D,EACZ/D,EAAoBmC,EAAE4B,EAAa9D,KACrCD,EAAoBQ,EAAEP,GAAY8D,EAAY9D,IAGhD,GAAG+D,EAAS,IAAInD,EAASmD,EAAQhE,GAGlC,IADG8D,GAA4BA,EAA2B3G,GACrDgE,EAAIL,EAASM,OAAQD,IACzByC,EAAU9C,EAASK,GAChBnB,EAAoBmC,EAAEwB,EAAiBC,IAAYD,EAAgBC,IACrED,EAAgBC,GAAS,KAE1BD,EAAgBC,GAAW,EAE5B,OAAO5D,EAAoBY,EAAEC,IAG1BqD,EAAqBV,KAA4B,sBAAIA,KAA4B,uBAAK,GAC1FU,EAAmBC,QAAQN,EAAqBO,KAAK,KAAM,IAC3DF,EAAmBtE,KAAOiE,EAAqBO,KAAK,KAAMF,EAAmBtE,KAAKwE,KAAKF,OClDvFlE,EAAoBqE,QAAKlE,ECGzB,IAAImE,EAAsBtE,EAAoBY,OAAET,EAAW,CAAC,OAAO,WAAa,OAAOH,EAAoB,UAC3GsE,EAAsBtE,EAAoBY,EAAE0D","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=493d2e25&","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 * Checks if the birthday calendar is currently enabled by looking it up at the DAV server\n *\n * @returns {Promise}\n */\nexport async function isBirthdayCalendarEnabled () {\n\tconst client = getClient('calendars')\n\ttry {\n\t\tawait client.customRequest(CALDAV_BIRTHDAY_CALENDAR, {\n\t\t\tmethod: 'PROPFIND',\n\t\t})\n\t\treturn true\n\t} catch (e) {\n\t\tif(e.status === 404) {\n\t\t\treturn false\n\t\t} else {\n\t\t\tthrow e\n\t\t}\n\t}\n}\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\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=493d2e25&\"\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,\"disabled\":_vm.loading},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 || _vm.loading,\"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\":\"AAmIA,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\\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__(77165); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","getClient","memoize","service","axios","webdav","patch","generateRemoteUrl","getCurrentUser","uid","CALDAV_BIRTHDAY_CALENDAR","isBirthdayCalendarEnabled","client","customRequest","method","status","disableBirthdayCalendar","enableBirthdayCalendar","data","saveBirthdayReminder","reminderOffset","generateOcsUrl","appId","configKey","configValue","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","attrs","$t","loading","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 b62569694091d..bf1626af210bd 100644 --- a/webpack.modules.js +++ b/webpack.modules.js @@ -45,6 +45,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'), From 4a0c35d6567adacd7a6daa3121bbcbf1f57e726e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Neukom?= Date: Thu, 28 Jul 2022 22:11:44 +0200 Subject: [PATCH 2/8] Fix eslint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Neukom --- .../src/service/BirthdayCalendarService.js | 18 ++++++------ .../src/views/BirthdayCalendarSettings.vue | 29 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/apps/dav/src/service/BirthdayCalendarService.js b/apps/dav/src/service/BirthdayCalendarService.js index 5c3f11d991a86..3e44e92edc452 100644 --- a/apps/dav/src/service/BirthdayCalendarService.js +++ b/apps/dav/src/service/BirthdayCalendarService.js @@ -18,18 +18,18 @@ * 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"; +import axios from '@nextcloud/axios' +import { generateOcsUrl } from '@nextcloud/router' +import { getClient } from ".//apps/dav/src/dav/client" -const CALDAV_BIRTHDAY_CALENDAR = 'contact_birthdays'; +const CALDAV_BIRTHDAY_CALENDAR = 'contact_birthdays' /** * Checks if the birthday calendar is currently enabled by looking it up at the DAV server * * @returns {Promise} */ -export async function isBirthdayCalendarEnabled () { +export async function isBirthdayCalendarEnabled() { const client = getClient('calendars') try { await client.customRequest(CALDAV_BIRTHDAY_CALENDAR, { @@ -37,7 +37,7 @@ export async function isBirthdayCalendarEnabled () { }) return true } catch (e) { - if(e.status === 404) { + if (e.status === 404) { return false } else { throw e @@ -50,7 +50,7 @@ export async function isBirthdayCalendarEnabled () { * * @returns {Promise} */ -export async function disableBirthdayCalendar () { +export async function disableBirthdayCalendar() { const client = getClient('calendars') await client.customRequest(CALDAV_BIRTHDAY_CALENDAR, { method: 'DELETE', @@ -62,7 +62,7 @@ export async function disableBirthdayCalendar () { * * @returns {Promise} */ -export async function enableBirthdayCalendar () { +export async function enableBirthdayCalendar() { const client = getClient('calendars') await client.customRequest('', { method: 'POST', @@ -76,7 +76,7 @@ export async function enableBirthdayCalendar () { * @param reminderOffset * @returns {Promise>} */ -export async function saveBirthdayReminder (reminderOffset) { +export async function saveBirthdayReminder(reminderOffset) { return await axios.post( generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', { appId: 'dav', diff --git a/apps/dav/src/views/BirthdayCalendarSettings.vue b/apps/dav/src/views/BirthdayCalendarSettings.vue index 2052fab09dc7d..f8a3c9e524962 100644 --- a/apps/dav/src/views/BirthdayCalendarSettings.vue +++ b/apps/dav/src/views/BirthdayCalendarSettings.vue @@ -20,7 +20,8 @@ -->