refactor(dav): migrate Settings frontend to Vue 3
- migrate deprecated props - use direct import of t rather than the mixin Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
@@ -56,6 +56,8 @@ class AvailabilitySettings implements ISettings {
|
||||
}
|
||||
}
|
||||
|
||||
\OCP\Util::addStyle(Application::APP_ID, 'settings-personal-availability');
|
||||
\OCP\Util::addScript(Application::APP_ID, 'settings-personal-availability');
|
||||
return new TemplateResponse(Application::APP_ID, 'settings-personal-availability');
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ class CalDAVSettings implements IDelegatedSettings {
|
||||
$value = $this->config->getAppValue(Application::APP_ID, $key, $default);
|
||||
$this->initialState->provideInitialState($key, $value === 'yes');
|
||||
}
|
||||
|
||||
\OCP\Util::addScript(Application::APP_ID, 'settings-admin-caldav');
|
||||
\OCP\Util::addStyle(Application::APP_ID, 'settings-admin-caldav');
|
||||
return new TemplateResponse(Application::APP_ID, 'settings-admin-caldav');
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@ class ExampleContentSettings implements ISettings {
|
||||
);
|
||||
}
|
||||
|
||||
return new TemplateResponse(Application::APP_ID, 'settings-example-content');
|
||||
\OCP\Util::addStyle(Application::APP_ID, 'settings-admin-example-content');
|
||||
\OCP\Util::addScript(Application::APP_ID, 'settings-admin-example-content');
|
||||
return new TemplateResponse(Application::APP_ID, 'settings-admin-example-content');
|
||||
}
|
||||
|
||||
public function getSection(): ?string {
|
||||
|
||||
@@ -9,46 +9,39 @@
|
||||
<NcDateTimePickerNative
|
||||
id="absence-first-day"
|
||||
v-model="firstDay"
|
||||
:label="$t('dav', 'First day')"
|
||||
:label="t('dav', 'First day')"
|
||||
class="absence__dates__picker"
|
||||
:required="true" />
|
||||
<NcDateTimePickerNative
|
||||
id="absence-last-day"
|
||||
v-model="lastDay"
|
||||
:label="$t('dav', 'Last day (inclusive)')"
|
||||
:label="t('dav', 'Last day (inclusive)')"
|
||||
class="absence__dates__picker"
|
||||
:required="true" />
|
||||
</div>
|
||||
<label for="replacement-search-input">{{ $t('dav', 'Out of office replacement (optional)') }}</label>
|
||||
<NcSelect
|
||||
ref="select"
|
||||
<label for="replacement-search-input">{{ t('dav', 'Out of office replacement (optional)') }}</label>
|
||||
<NcSelectUsers
|
||||
v-model="replacementUser"
|
||||
input-id="replacement-search-input"
|
||||
:loading="searchLoading"
|
||||
:placeholder="$t('dav', 'Name of the replacement')"
|
||||
:clear-search-on-blur="() => false"
|
||||
user-select
|
||||
:placeholder="t('dav', 'Name of the replacement')"
|
||||
:options="options"
|
||||
@search="asyncFind">
|
||||
<template #no-options="{ search }">
|
||||
{{ search ? $t('dav', 'No results.') : $t('dav', 'Start typing.') }}
|
||||
</template>
|
||||
</NcSelect>
|
||||
<NcTextField :value.sync="status" :label="$t('dav', 'Short absence status')" :required="true" />
|
||||
<NcTextArea :value.sync="message" :label="$t('dav', 'Long absence Message')" :required="true" />
|
||||
@search="asyncFind" />
|
||||
<NcTextField v-model="status" :label="t('dav', 'Short absence status')" :required="true" />
|
||||
<NcTextArea v-model="message" :label="t('dav', 'Long absence Message')" :required="true" />
|
||||
|
||||
<div class="absence__buttons">
|
||||
<NcButton
|
||||
:disabled="loading || !valid"
|
||||
variant="primary"
|
||||
type="submit">
|
||||
{{ $t('dav', 'Save') }}
|
||||
{{ t('dav', 'Save') }}
|
||||
</NcButton>
|
||||
<NcButton
|
||||
:disabled="loading || !valid"
|
||||
variant="error"
|
||||
@click="clearAbsence">
|
||||
{{ $t('dav', 'Disable absence') }}
|
||||
{{ t('dav', 'Disable absence') }}
|
||||
</NcButton>
|
||||
</div>
|
||||
</form>
|
||||
@@ -59,18 +52,18 @@ import { getCurrentUser } from '@nextcloud/auth'
|
||||
import axios from '@nextcloud/axios'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { ShareType } from '@nextcloud/sharing'
|
||||
import debounce from 'debounce'
|
||||
import NcButton from '@nextcloud/vue/components/NcButton'
|
||||
import NcDateTimePickerNative from '@nextcloud/vue/components/NcDateTimePickerNative'
|
||||
import NcSelect from '@nextcloud/vue/components/NcSelect'
|
||||
import NcSelectUsers from '@nextcloud/vue/components/NcSelectUsers'
|
||||
import NcTextArea from '@nextcloud/vue/components/NcTextArea'
|
||||
import NcTextField from '@nextcloud/vue/components/NcTextField'
|
||||
import { logger } from '../service/logger.ts'
|
||||
import { formatDateAsYMD } from '../utils/date.js'
|
||||
import { formatDateAsYMD } from '../utils/date.ts'
|
||||
|
||||
/* eslint @nextcloud/vue/no-deprecated-props: "warn" */
|
||||
export default {
|
||||
name: 'AbsenceForm',
|
||||
components: {
|
||||
@@ -78,7 +71,11 @@ export default {
|
||||
NcTextField,
|
||||
NcTextArea,
|
||||
NcDateTimePickerNative,
|
||||
NcSelect,
|
||||
NcSelectUsers,
|
||||
},
|
||||
|
||||
setup() {
|
||||
return { t }
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -228,9 +225,9 @@ export default {
|
||||
message: this.message,
|
||||
replacementUserId: this.replacementUser?.user ?? null,
|
||||
})
|
||||
showSuccess(this.$t('dav', 'Absence saved'))
|
||||
showSuccess(t('dav', 'Absence saved'))
|
||||
} catch (error) {
|
||||
showError(this.$t('dav', 'Failed to save your absence settings'))
|
||||
showError(t('dav', 'Failed to save your absence settings'))
|
||||
logger.error('Could not save absence', { error })
|
||||
} finally {
|
||||
this.loading = false
|
||||
@@ -242,9 +239,9 @@ export default {
|
||||
try {
|
||||
await axios.delete(generateOcsUrl('/apps/dav/api/v1/outOfOffice/{userId}', { userId: getCurrentUser().uid }))
|
||||
this.resetForm()
|
||||
showSuccess(this.$t('dav', 'Absence cleared'))
|
||||
showSuccess(t('dav', 'Absence cleared'))
|
||||
} catch (error) {
|
||||
showError(this.$t('dav', 'Failed to clear your absence settings'))
|
||||
showError(t('dav', 'Failed to clear your absence settings'))
|
||||
logger.error('Could not clear absence', { error })
|
||||
} finally {
|
||||
this.loading = false
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
:checked="enableDefaultContact"
|
||||
type="switch"
|
||||
@update:model-value="updateEnableDefaultContact">
|
||||
{{ $t('dav', "Add example contact to user's address book when they first log in") }}
|
||||
{{ t('dav', "Add example contact to user's address book when they first log in") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<div v-if="enableDefaultContact" class="example-contact-settings__buttons">
|
||||
<ExampleContentDownloadButton :href="downloadUrl">
|
||||
@@ -24,7 +24,7 @@
|
||||
<template #icon>
|
||||
<IconUpload :size="20" />
|
||||
</template>
|
||||
{{ $t('dav', 'Import contact') }}
|
||||
{{ t('dav', 'Import contact') }}
|
||||
</NcButton>
|
||||
<NcButton
|
||||
v-if="hasCustomDefaultContact"
|
||||
@@ -33,15 +33,15 @@
|
||||
<template #icon>
|
||||
<IconRestore :size="20" />
|
||||
</template>
|
||||
{{ $t('dav', 'Reset to default') }}
|
||||
{{ t('dav', 'Reset to default') }}
|
||||
</NcButton>
|
||||
</div>
|
||||
<NcDialog
|
||||
:open.sync="isModalOpen"
|
||||
:name="$t('dav', 'Import contacts')"
|
||||
v-model:open="isModalOpen"
|
||||
:name="t('dav', 'Import contacts')"
|
||||
:buttons="buttons">
|
||||
<div>
|
||||
<p>{{ $t('dav', 'Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?') }}</p>
|
||||
<p>{{ t('dav', 'Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?') }}</p>
|
||||
</div>
|
||||
</NcDialog>
|
||||
<input
|
||||
@@ -61,6 +61,7 @@ import IconCheck from '@mdi/svg/svg/check.svg?raw'
|
||||
import axios from '@nextcloud/axios'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { NcButton, NcCheckboxRadioSwitch, NcDialog } from '@nextcloud/vue'
|
||||
import IconAccount from 'vue-material-design-icons/Account.vue'
|
||||
@@ -69,8 +70,8 @@ import IconUpload from 'vue-material-design-icons/TrayArrowUp.vue'
|
||||
import ExampleContentDownloadButton from './ExampleContentDownloadButton.vue'
|
||||
import { logger } from '../service/logger.ts'
|
||||
|
||||
const enableDefaultContact = loadState('dav', 'enableDefaultContact')
|
||||
const hasCustomDefaultContact = loadState('dav', 'hasCustomDefaultContact')
|
||||
const enableDefaultContact = loadState('dav', 'enableDefaultContact', false)
|
||||
const hasCustomDefaultContact = loadState('dav', 'hasCustomDefaultContact', false)
|
||||
|
||||
export default {
|
||||
name: 'ExampleContactSettings',
|
||||
@@ -84,6 +85,10 @@ export default {
|
||||
ExampleContentDownloadButton,
|
||||
},
|
||||
|
||||
setup() {
|
||||
return { t }
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
enableDefaultContact,
|
||||
@@ -92,12 +97,12 @@ export default {
|
||||
loading: false,
|
||||
buttons: [
|
||||
{
|
||||
label: this.$t('dav', 'Cancel'),
|
||||
label: t('dav', 'Cancel'),
|
||||
icon: IconCancel,
|
||||
callback: () => { this.isModalOpen = false },
|
||||
},
|
||||
{
|
||||
label: this.$t('dav', 'Import'),
|
||||
label: t('dav', 'Import'),
|
||||
icon: IconCheck,
|
||||
variant: 'primary',
|
||||
callback: () => { this.clickImportInput() },
|
||||
@@ -119,7 +124,7 @@ export default {
|
||||
}).then(() => {
|
||||
this.enableDefaultContact = !this.enableDefaultContact
|
||||
}).catch(() => {
|
||||
showError(this.$t('dav', 'Error while saving settings'))
|
||||
showError(t('dav', 'Error while saving settings'))
|
||||
})
|
||||
},
|
||||
|
||||
@@ -136,11 +141,11 @@ export default {
|
||||
axios.put(generateUrl('/apps/dav/api/defaultcontact/contact'))
|
||||
.then(() => {
|
||||
this.hasCustomDefaultContact = false
|
||||
showSuccess(this.$t('dav', 'Contact reset successfully'))
|
||||
showSuccess(t('dav', 'Contact reset successfully'))
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error importing contact:', { error })
|
||||
showError(this.$t('dav', 'Error while resetting contact'))
|
||||
showError(t('dav', 'Error while resetting contact'))
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@@ -158,10 +163,10 @@ export default {
|
||||
try {
|
||||
await axios.put(generateUrl('/apps/dav/api/defaultcontact/contact'), { contactData: reader.result })
|
||||
this.hasCustomDefaultContact = true
|
||||
showSuccess(this.$t('dav', 'Contact imported successfully'))
|
||||
showSuccess(t('dav', 'Contact imported successfully'))
|
||||
} catch (error) {
|
||||
logger.error('Error importing contact:', { error })
|
||||
showError(this.$t('dav', 'Error while importing contact'))
|
||||
showError(t('dav', 'Error while importing contact'))
|
||||
} finally {
|
||||
this.loading = false
|
||||
event.target.value = ''
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</NcButton>
|
||||
</div>
|
||||
<NcDialog
|
||||
:open.sync="showImportModal"
|
||||
v-model:open="showImportModal"
|
||||
:name="t('dav', 'Import calendar event')">
|
||||
<div class="import-event-modal">
|
||||
<p>
|
||||
@@ -73,6 +73,7 @@
|
||||
<script>
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { NcButton, NcCheckboxRadioSwitch, NcDialog } from '@nextcloud/vue'
|
||||
import IconCalendarBlank from 'vue-material-design-icons/CalendarBlank.vue'
|
||||
@@ -94,6 +95,10 @@ export default {
|
||||
ExampleContentDownloadButton,
|
||||
},
|
||||
|
||||
setup() {
|
||||
return { t }
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
createExampleEvent: loadState('dav', 'create_example_event', false),
|
||||
|
||||
+3
-12
@@ -3,17 +3,8 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import Vue from 'vue'
|
||||
import { createApp } from 'vue'
|
||||
import ExampleContentSettingsSection from './views/ExampleContentSettingsSection.vue'
|
||||
|
||||
Vue.mixin({
|
||||
methods: {
|
||||
t,
|
||||
$t: t,
|
||||
},
|
||||
})
|
||||
|
||||
const View = Vue.extend(ExampleContentSettingsSection);
|
||||
|
||||
(new View({})).$mount('#settings-example-content')
|
||||
const app = createApp(ExampleContentSettingsSection)
|
||||
app.mount('#settings-example-content')
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import CalDavSettings from './views/CalDavSettings.vue'
|
||||
|
||||
const app = createApp(CalDavSettings)
|
||||
app.mount('#settings-admin-caldav')
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import Vue from 'vue'
|
||||
import Availability from './views/UserAvailability.vue'
|
||||
|
||||
Vue.prototype.$t = t
|
||||
|
||||
const View = Vue.extend(Availability);
|
||||
|
||||
(new View({})).$mount('#settings-personal-availability')
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import UserAvailability from './views/UserAvailability.vue'
|
||||
|
||||
const app = createApp(UserAvailability)
|
||||
app.mount('#settings-personal-availability')
|
||||
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import Vue from 'vue'
|
||||
import CalDavSettings from './views/CalDavSettings.vue'
|
||||
|
||||
Vue.prototype.$t = t
|
||||
|
||||
const View = Vue.extend(CalDavSettings)
|
||||
const CalDavSettingsView = new View({
|
||||
name: 'CalDavSettingsView',
|
||||
data() {
|
||||
return {
|
||||
sendInvitations: loadState('dav', 'sendInvitations'),
|
||||
generateBirthdayCalendar: loadState(
|
||||
'dav',
|
||||
'generateBirthdayCalendar',
|
||||
),
|
||||
sendEventReminders: loadState('dav', 'sendEventReminders'),
|
||||
sendEventRemindersToSharedUsers: loadState(
|
||||
'dav',
|
||||
'sendEventRemindersToSharedUsers',
|
||||
),
|
||||
sendEventRemindersPush: loadState('dav', 'sendEventRemindersPush'),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
CalDavSettingsView.$mount('#settings-admin-caldav')
|
||||
@@ -7,6 +7,15 @@ import { render } from '@testing-library/vue'
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest'
|
||||
import CalDavSettings from './CalDavSettings.vue'
|
||||
|
||||
const initialState = vi.hoisted(() => ({
|
||||
userSyncCalendarsDocUrl: 'https://docs.nextcloud.com/server/23/go.php?to=user-sync-calendars',
|
||||
sendInvitations: true,
|
||||
generateBirthdayCalendar: true,
|
||||
sendEventReminders: true,
|
||||
sendEventRemindersToSharedUsers: true,
|
||||
sendEventRemindersPush: true,
|
||||
}))
|
||||
|
||||
vi.mock('@nextcloud/axios')
|
||||
vi.mock('@nextcloud/router', () => {
|
||||
return {
|
||||
@@ -17,7 +26,7 @@ vi.mock('@nextcloud/router', () => {
|
||||
})
|
||||
vi.mock('@nextcloud/initial-state', () => {
|
||||
return {
|
||||
loadState: vi.fn(() => 'https://docs.nextcloud.com/server/23/go.php?to=user-sync-calendars'),
|
||||
loadState: vi.fn((app, key) => app === 'dav' && initialState[key]),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -32,23 +41,7 @@ describe('CalDavSettings', () => {
|
||||
})
|
||||
|
||||
test('interactions', async () => {
|
||||
const TLUtils = render(
|
||||
CalDavSettings,
|
||||
{
|
||||
data() {
|
||||
return {
|
||||
sendInvitations: true,
|
||||
generateBirthdayCalendar: true,
|
||||
sendEventReminders: true,
|
||||
sendEventRemindersToSharedUsers: true,
|
||||
sendEventRemindersPush: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
(Vue) => {
|
||||
Vue.prototype.$t = vi.fn((app, text) => text)
|
||||
},
|
||||
)
|
||||
const TLUtils = render(CalDavSettings)
|
||||
const sendInvitations = TLUtils.getByLabelText('Send invitations to attendees')
|
||||
expect(sendInvitations).toBeChecked()
|
||||
const generateBirthdayCalendar = TLUtils.getByLabelText('Automatically generate a birthday calendar')
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
-->
|
||||
<template>
|
||||
<NcSettingsSection
|
||||
:name="$t('dav', 'Calendar server')"
|
||||
:name="t('dav', 'Calendar server')"
|
||||
:doc-url="userSyncCalendarsDocUrl">
|
||||
<!-- Can use v-html as:
|
||||
- $t passes the translated string through DOMPurify.sanitize,
|
||||
- t passes the translated string through DOMPurify.sanitize,
|
||||
- replacement strings are not user-controlled. -->
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<p class="settings-hint" v-html="hint" />
|
||||
<p>
|
||||
<NcCheckboxRadioSwitch
|
||||
id="caldavSendInvitations"
|
||||
:checked.sync="sendInvitations"
|
||||
v-model="sendInvitations"
|
||||
type="switch">
|
||||
{{ $t('dav', 'Send invitations to attendees') }}
|
||||
{{ t('dav', 'Send invitations to attendees') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<!-- Can use v-html as:
|
||||
- $t passes the translated string through DOMPurify.sanitize,
|
||||
- t passes the translated string through DOMPurify.sanitize,
|
||||
- replacement strings are not user-controlled. -->
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<em v-html="sendInvitationsHelpText" />
|
||||
@@ -27,55 +27,55 @@
|
||||
<p>
|
||||
<NcCheckboxRadioSwitch
|
||||
id="caldavGenerateBirthdayCalendar"
|
||||
:checked.sync="generateBirthdayCalendar"
|
||||
v-model="generateBirthdayCalendar"
|
||||
type="switch"
|
||||
class="checkbox">
|
||||
{{ $t('dav', 'Automatically generate a birthday calendar') }}
|
||||
{{ t('dav', 'Automatically generate a birthday calendar') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<em>
|
||||
{{ $t('dav', 'Birthday calendars will be generated by a background job.') }}
|
||||
{{ t('dav', 'Birthday calendars will be generated by a background job.') }}
|
||||
</em>
|
||||
<br>
|
||||
<em>
|
||||
{{ $t('dav', 'Hence they will not be available immediately after enabling but will show up after some time.') }}
|
||||
{{ t('dav', 'Hence they will not be available immediately after enabling but will show up after some time.') }}
|
||||
</em>
|
||||
</p>
|
||||
<p>
|
||||
<NcCheckboxRadioSwitch
|
||||
id="caldavSendEventReminders"
|
||||
:checked.sync="sendEventReminders"
|
||||
v-model="sendEventReminders"
|
||||
type="switch">
|
||||
{{ $t('dav', 'Send notifications for events') }}
|
||||
{{ t('dav', 'Send notifications for events') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<!-- Can use v-html as:
|
||||
- $t passes the translated string through DOMPurify.sanitize,
|
||||
- t passes the translated string through DOMPurify.sanitize,
|
||||
- replacement strings are not user-controlled. -->
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<em v-html="sendEventRemindersHelpText" />
|
||||
<br>
|
||||
<em>
|
||||
{{ $t('dav', 'Notifications are sent via background jobs, so these must occur often enough.') }}
|
||||
{{ t('dav', 'Notifications are sent via background jobs, so these must occur often enough.') }}
|
||||
</em>
|
||||
</p>
|
||||
<p class="indented">
|
||||
<NcCheckboxRadioSwitch
|
||||
id="caldavSendEventRemindersToSharedGroupMembers"
|
||||
:checked.sync="sendEventRemindersToSharedUsers"
|
||||
v-model="sendEventRemindersToSharedUsers"
|
||||
type="switch"
|
||||
:disabled="!sendEventReminders">
|
||||
{{ $t('dav', 'Send reminder notifications to calendar sharees as well') }}
|
||||
{{ t('dav', 'Send reminder notifications to calendar sharees as well') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<em>
|
||||
{{ $t('dav', 'Reminders are always sent to organizers and attendees.') }}
|
||||
{{ t('dav', 'Reminders are always sent to organizers and attendees.') }}
|
||||
</em>
|
||||
</p>
|
||||
<p class="indented">
|
||||
<NcCheckboxRadioSwitch
|
||||
id="caldavSendEventRemindersPush"
|
||||
:checked.sync="sendEventRemindersPush"
|
||||
v-model="sendEventRemindersPush"
|
||||
type="switch"
|
||||
:disabled="!sendEventReminders">
|
||||
{{ $t('dav', 'Enable notifications for events via push') }}
|
||||
{{ t('dav', 'Enable notifications for events via push') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</p>
|
||||
</NcSettingsSection>
|
||||
@@ -84,6 +84,7 @@
|
||||
<script>
|
||||
import axios from '@nextcloud/axios'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
|
||||
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
|
||||
@@ -97,15 +98,32 @@ export default {
|
||||
NcSettingsSection,
|
||||
},
|
||||
|
||||
setup() {
|
||||
return { t }
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
userSyncCalendarsDocUrl,
|
||||
sendInvitations: loadState('dav', 'sendInvitations'),
|
||||
generateBirthdayCalendar: loadState(
|
||||
'dav',
|
||||
'generateBirthdayCalendar',
|
||||
),
|
||||
|
||||
sendEventReminders: loadState('dav', 'sendEventReminders'),
|
||||
sendEventRemindersToSharedUsers: loadState(
|
||||
'dav',
|
||||
'sendEventRemindersToSharedUsers',
|
||||
),
|
||||
|
||||
sendEventRemindersPush: loadState('dav', 'sendEventRemindersPush'),
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
hint() {
|
||||
const translated = this.$t(
|
||||
const translated = t(
|
||||
'dav',
|
||||
'Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}.',
|
||||
)
|
||||
@@ -116,14 +134,14 @@ export default {
|
||||
},
|
||||
|
||||
sendInvitationsHelpText() {
|
||||
const translated = this.$t('dav', 'Please make sure to properly set up {emailopen}the email server{linkclose}.')
|
||||
const translated = t('dav', 'Please make sure to properly set up {emailopen}the email server{linkclose}.')
|
||||
return translated
|
||||
.replace('{emailopen}', '<a href="../admin#mail_general_settings">')
|
||||
.replace('{linkclose}', '</a>')
|
||||
},
|
||||
|
||||
sendEventRemindersHelpText() {
|
||||
const translated = this.$t('dav', 'Please make sure to properly set up {emailopen}the email server{linkclose}.')
|
||||
const translated = t('dav', 'Please make sure to properly set up {emailopen}the email server{linkclose}.')
|
||||
return translated
|
||||
.replace('{emailopen}', '<a href="../admin#mail_general_settings">')
|
||||
.replace('{linkclose}', '</a>')
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
\OCP\Util::addScript('dav', 'settings-admin-caldav', 'core');
|
||||
|
||||
?>
|
||||
|
||||
<div id="settings-admin-caldav"></div>
|
||||
|
||||
-2
@@ -4,8 +4,6 @@
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
\OCP\Util::addScript('dav', 'settings-example-content', 'core');
|
||||
|
||||
?>
|
||||
|
||||
<div id="settings-example-content"></div>
|
||||
@@ -4,8 +4,6 @@
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
\OCP\Util::addScript('dav', 'settings-personal-availability', 'core');
|
||||
|
||||
?>
|
||||
|
||||
<div id="settings-personal-availability"></div>
|
||||
|
||||
@@ -31,11 +31,6 @@ module.exports = {
|
||||
dashboard: {
|
||||
main: path.join(__dirname, 'apps/dashboard/src', 'main.js'),
|
||||
},
|
||||
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-example-content': path.join(__dirname, 'apps/dav/src', 'settings-example-content.js'),
|
||||
},
|
||||
files: {
|
||||
sidebar: path.join(__dirname, 'apps/files/src', 'sidebar.ts'),
|
||||
main: path.join(__dirname, 'apps/files/src', 'main.ts'),
|
||||
|
||||
@@ -7,6 +7,11 @@ import { createAppConfig } from '@nextcloud/vite-config'
|
||||
import { resolve } from 'node:path'
|
||||
|
||||
const modules = {
|
||||
dav: {
|
||||
'settings-admin-caldav': resolve(import.meta.dirname, 'apps/dav/src', 'settings-admin.ts'),
|
||||
'settings-admin-example-content': resolve(import.meta.dirname, 'apps/dav/src', 'settings-admin-example-content.ts'),
|
||||
'settings-personal-availability': resolve(import.meta.dirname, 'apps/dav/src', 'settings-personal-availability.ts'),
|
||||
},
|
||||
sharebymail: {
|
||||
'admin-settings': resolve(import.meta.dirname, 'apps/sharebymail/src', 'settings-admin.ts'),
|
||||
},
|
||||
|
||||
Generated
+61
@@ -10,7 +10,9 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@mdi/svg": "^7.4.47",
|
||||
"@nextcloud/axios": "^2.5.2",
|
||||
"@nextcloud/calendar-availability-vue": "^3.0.0",
|
||||
"@nextcloud/dialogs": "^7.1.0",
|
||||
"@nextcloud/password-confirmation": "^6.0.1",
|
||||
"@nextcloud/paths": "^2.2.1",
|
||||
@@ -1951,6 +1953,12 @@
|
||||
"integrity": "sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@mdi/svg": {
|
||||
"version": "7.4.47",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/svg/-/svg-7.4.47.tgz",
|
||||
"integrity": "sha512-WQ2gDll12T9WD34fdRFgQVgO8bag3gavrAgJ0frN4phlwdJARpE6gO1YvLEMJR0KKgoc+/Ea/A0Pp11I00xBvw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@microsoft/api-extractor": {
|
||||
"version": "7.53.2",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.53.2.tgz",
|
||||
@@ -2148,6 +2156,41 @@
|
||||
"browserslist": "^4.26.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@nextcloud/calendar-availability-vue": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/calendar-availability-vue/-/calendar-availability-vue-3.0.0.tgz",
|
||||
"integrity": "sha512-6B4oWgVcvoYvdM8G3avD/XcpWbuEIEu5bXkfvH+rM8R12s7NpIvKmwNSyXOwXjzIeJQRIkcimEn9Am4pVfM1lg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nextcloud/logger": "^3.0.2",
|
||||
"ical.js": "^2.2.1",
|
||||
"icalzone": "^0.0.1",
|
||||
"uuid": "^12.0.0",
|
||||
"vue-material-design-icons": "^5.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^22.0.0",
|
||||
"npm": "^10.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nextcloud/l10n": "^1.4 || ^2.0 || ^3.0.0",
|
||||
"@nextcloud/vue": "^9",
|
||||
"vue": "^3.5.17"
|
||||
}
|
||||
},
|
||||
"node_modules/@nextcloud/calendar-availability-vue/node_modules/uuid": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-12.0.0.tgz",
|
||||
"integrity": "sha512-USe1zesMYh4fjCA8ZH5+X5WIVD0J4V1Jksm1bFTVBX2F/cwSXt0RO5w/3UXbdLKmZX65MiWV+hwhSS8p6oBTGA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@nextcloud/capabilities": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/capabilities/-/capabilities-1.2.0.tgz",
|
||||
@@ -9330,6 +9373,18 @@
|
||||
"url": "https://github.com/sponsors/EvanHahn"
|
||||
}
|
||||
},
|
||||
"node_modules/ical.js": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ical.js/-/ical.js-2.2.1.tgz",
|
||||
"integrity": "sha512-yK/UlPbEs316igb/tjRgbFA8ZV75rCsBJp/hWOatpyaPNlgw0dGDmU+FoicOcwX4xXkeXOkYiOmCqNPFpNPkQg==",
|
||||
"license": "MPL-2.0"
|
||||
},
|
||||
"node_modules/icalzone": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/icalzone/-/icalzone-0.0.1.tgz",
|
||||
"integrity": "sha512-ln0AM3fMSLLuJijuWuRzwrN0Tg+BG8ADi7ha6slmC7ZqOijagif5I6b4Nl4/vPSXWexnxyrHiEof8VxDOllXVQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
@@ -16576,6 +16631,12 @@
|
||||
"eslint": "^8.57.0 || ^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-material-design-icons": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-5.3.1.tgz",
|
||||
"integrity": "sha512-6UNEyhlTzlCeT8ZeX5WbpUGFTTPSbOoTQeoASTv7X4Ylh0pe8vltj+36VMK56KM0gG8EQVoMK/Qw/6evalg8lA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue-resize": {
|
||||
"version": "2.0.0-alpha.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz",
|
||||
|
||||
@@ -39,7 +39,9 @@
|
||||
"extends @nextcloud/browserslist-config"
|
||||
],
|
||||
"dependencies": {
|
||||
"@mdi/svg": "^7.4.47",
|
||||
"@nextcloud/axios": "^2.5.2",
|
||||
"@nextcloud/calendar-availability-vue": "^3.0.0",
|
||||
"@nextcloud/dialogs": "^7.1.0",
|
||||
"@nextcloud/password-confirmation": "^6.0.1",
|
||||
"@nextcloud/paths": "^2.2.1",
|
||||
|
||||
Reference in New Issue
Block a user