Compare commits

...

11 Commits

Author SHA1 Message Date
Ferdinand Thiessen
859206e872 fixup: disable minification for tests 2025-10-23 04:47:14 +02:00
Ferdinand Thiessen
b141126dd4 chore: compile assets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:17:01 +02:00
Ferdinand Thiessen
8ab00515c9 test(dav): add e2e tests for availability & absence
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
41bbe99ca3 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>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
cb2a605425 refactor(dav): migrate ExampleContentDownloadButton to Typescript and script-setup
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
6779c24fc1 refactor(ExampleContentSettingsSection): migrate component to script-setup
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
a1ac305334 refactor(dav): migrate UserAvailability to Typescript and script-setup
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
0a5a259e8a refactor(dav): fix single-word component name by renaming view
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
d6f76536e4 refactor(dav): migrate services to Typescript
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
16c4cd6b7d refactor(dav): migrate logger to Typescript
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:14:03 +02:00
Ferdinand Thiessen
81a8a1715a chore: adjust Vue 3 based frontend vite config for multiple apps
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-23 03:13:57 +02:00
212 changed files with 3384 additions and 3275 deletions

View File

@@ -3,6 +3,12 @@ SPDX-PackageName = "nextcloud"
SPDX-PackageSupplier = "Nextcloud <info@nextcloud.com>"
SPDX-PackageDownloadLocation = "https://github.com/nextcloud/server"
[[annotations]]
path = ["dist/rolldown-runtime-*.js"]
precedence = "aggregate"
SPDX-FileCopyrightText = "rolldown contributors"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = ["lib/l10n/**.js", "lib/l10n/**.json", "core/l10n/**.js", "core/l10n/**.json", "apps/admin_audit/l10n/**.js", "apps/admin_audit/l10n/**.json", "apps/comments/l10n/**.js", "apps/comments/l10n/**.json", "apps/dav/l10n/**.js", "apps/dav/l10n/**.json", "apps/encryption/l10n/**.js", "apps/encryption/l10n/**.json", "apps/federatedfilesharing/l10n/**.js", "apps/federatedfilesharing/l10n/**.json", "apps/federation/l10n/**.js", "apps/federation/l10n/**.json", "apps/files/l10n/**.js", "apps/files/l10n/**.json", "apps/files_external/l10n/**.js", "apps/files_external/l10n/**.json", "apps/files_sharing/l10n/**.js", "apps/files_sharing/l10n/**.json", "apps/files_trashbin/l10n/**.js", "apps/files_trashbin/l10n/**.json", "apps/files_versions/l10n/**.js", "apps/files_versions/l10n/**.json", "apps/provisioning_api/l10n/**.js", "apps/provisioning_api/l10n/**.json", "apps/settings/l10n/**.js", "apps/settings/l10n/**.json", "apps/systemtags/l10n/**.js", "apps/systemtags/l10n/**.json", "apps/updatenotification/l10n/**.js", "apps/updatenotification/l10n/**.json", "apps/user_ldap/l10n/**.js", "apps/user_ldap/l10n/**.json"]
precedence = "aggregate"

View File

@@ -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');
}

View File

@@ -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');
}

View File

@@ -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 {

View File

@@ -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.js'
import { formatDateAsYMD } from '../utils/date.js'
import { logger } from '../service/logger.ts'
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

View File

@@ -2,46 +2,11 @@
- SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div>
<CalendarAvailability
:slots.sync="slots"
:loading="loading"
:l10n-to="t('dav', 'to')"
:l10n-delete-slot="t('dav', 'Delete slot')"
:l10n-empty-day="t('dav', 'No working hours set')"
:l10n-add-slot="t('dav', 'Add slot')"
:l10n-week-day-list-label="t('dav', 'Weekdays')"
:l10n-monday="t('dav', 'Monday')"
:l10n-tuesday="t('dav', 'Tuesday')"
:l10n-wednesday="t('dav', 'Wednesday')"
:l10n-thursday="t('dav', 'Thursday')"
:l10n-friday="t('dav', 'Friday')"
:l10n-saturday="t('dav', 'Saturday')"
:l10n-sunday="t('dav', 'Sunday')"
:l10n-start-picker-label="(dayName) => t('dav', 'Pick a start time for {dayName}', { dayName })"
:l10n-end-picker-label="(dayName) => t('dav', 'Pick a end time for {dayName}', { dayName })" />
<NcCheckboxRadioSwitch v-model="automated">
{{ t('dav', 'Automatically set user status to "Do not disturb" outside of availability to mute all notifications.') }}
</NcCheckboxRadioSwitch>
<NcButton
:disabled="loading || saving"
variant="primary"
@click="save">
{{ t('dav', 'Save') }}
</NcButton>
</div>
</template>
<script setup lang="ts">
import { CalendarAvailability } from '@nextcloud/calendar-availability-vue'
import { getCapabilities } from '@nextcloud/capabilities'
import {
showError,
showSuccess,
} from '@nextcloud/dialogs'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { t } from '@nextcloud/l10n'
import { onMounted, ref } from 'vue'
@@ -52,7 +17,7 @@ import {
getEmptySlots,
saveScheduleInboxAvailability,
} from '../service/CalendarService.js'
import logger from '../service/logger.js'
import { logger } from '../service/logger.ts'
import {
disableUserStatusAutomation,
enableUserStatusAutomation,
@@ -106,6 +71,39 @@ async function save() {
}
</script>
<template>
<div>
<CalendarAvailability
v-model:slots="slots"
:loading="loading"
:l10n-to="t('dav', 'to')"
:l10n-delete-slot="t('dav', 'Delete slot')"
:l10n-empty-day="t('dav', 'No working hours set')"
:l10n-add-slot="t('dav', 'Add slot')"
:l10n-week-day-list-label="t('dav', 'Weekdays')"
:l10n-monday="t('dav', 'Monday')"
:l10n-tuesday="t('dav', 'Tuesday')"
:l10n-wednesday="t('dav', 'Wednesday')"
:l10n-thursday="t('dav', 'Thursday')"
:l10n-friday="t('dav', 'Friday')"
:l10n-saturday="t('dav', 'Saturday')"
:l10n-sunday="t('dav', 'Sunday')"
:l10n-start-picker-label="(dayName) => t('dav', 'Pick a start time for {dayName}', { dayName })"
:l10n-end-picker-label="(dayName) => t('dav', 'Pick a end time for {dayName}', { dayName })" />
<NcCheckboxRadioSwitch v-model="automated">
{{ t('dav', 'Automatically set user status to "Do not disturb" outside of availability to mute all notifications.') }}
</NcCheckboxRadioSwitch>
<NcButton
:disabled="loading || saving"
variant="primary"
@click="save">
{{ t('dav', 'Save') }}
</NcButton>
</div>
</template>
<style lang="scss" scoped>
:deep(.availability-day) {
padding: 0 10px 0 10px;

View File

@@ -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,16 +61,17 @@ 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'
import IconRestore from 'vue-material-design-icons/Restore.vue'
import IconUpload from 'vue-material-design-icons/TrayArrowUp.vue'
import ExampleContentDownloadButton from './ExampleContentDownloadButton.vue'
import logger from '../service/logger.js'
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 = ''

View File

@@ -3,8 +3,20 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<script setup lang="ts">
import { NcButton } from '@nextcloud/vue'
import IconDownload from 'vue-material-design-icons/TrayArrowDown.vue'
defineProps<{
/**
* The href link for the download
*/
href: string
}>()
</script>
<template>
<NcButton variant="tertiary" :href="href">
<NcButton variant="tertiary" :href>
<template #icon>
<slot name="icon" />
</template>
@@ -19,26 +31,6 @@
</NcButton>
</template>
<script>
import { NcButton } from '@nextcloud/vue'
import IconDownload from 'vue-material-design-icons/TrayArrowDown.vue'
export default {
name: 'ExampleContentDownloadButton',
components: {
NcButton,
IconDownload,
},
props: {
href: {
type: String,
required: true,
},
},
}
</script>
<style lang="scss" scoped>
.download-button {
display: flex;

View File

@@ -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'
@@ -80,7 +81,7 @@ import IconRestore from 'vue-material-design-icons/Restore.vue'
import IconUpload from 'vue-material-design-icons/TrayArrowUp.vue'
import ExampleContentDownloadButton from './ExampleContentDownloadButton.vue'
import * as ExampleEventService from '../service/ExampleEventService.js'
import logger from '../service/logger.js'
import { logger } from '../service/logger.ts'
export default {
name: 'ExampleEventSettings',
@@ -94,6 +95,10 @@ export default {
ExampleContentDownloadButton,
},
setup() {
return { t }
},
data() {
return {
createExampleEvent: loadState('dav', 'create_example_event', false),

View File

@@ -1,31 +0,0 @@
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
import { generateRemoteUrl } from '@nextcloud/router'
import memoize from 'lodash/fp/memoize.js'
import { createClient } from 'webdav'
export const getClient = memoize((service) => {
// init webdav client
const remote = generateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)
const client = createClient(remote)
// set CSRF token header
const setHeaders = (token) => {
client.setHeaders({
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: token ?? '',
})
}
// refresh headers when request token changes
onRequestTokenUpdate(setHeaders)
setHeaders(getRequestToken())
return client
})

View File

@@ -0,0 +1,39 @@
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { WebDAVClient } from 'webdav'
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
import { generateRemoteUrl } from '@nextcloud/router'
import { createClient } from 'webdav'
let client: WebDAVClient | undefined = undefined
/**
* Get the WebDAV client for the current user on the calendars endpoint.
*/
export function getClient(): WebDAVClient {
if (!client) {
// init webdav client
const remote = generateRemoteUrl(`dav/calendars/${getCurrentUser()!.uid}`)
client = createClient(remote)
// set CSRF token header
const setHeaders = (token) => {
client!.setHeaders({
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: token ?? '',
})
}
// refresh headers when request token changes
onRequestTokenUpdate(setHeaders)
setHeaders(getRequestToken())
}
return client
}

View File

@@ -1,17 +1,18 @@
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import {
slotsToVavailability,
vavailabilityToSlots,
} from '@nextcloud/calendar-availability-vue'
import { parseXML } from 'webdav'
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getClient } from '../dav/client.js'
import logger from './logger.js'
import { getClient } from '../dav/client.ts'
import { logger } from './logger.ts'
/**
*
* Get an object representing empty time slots for each day of the week.
*/
export function getEmptySlots() {
return {
@@ -26,12 +27,10 @@ export function getEmptySlots() {
}
/**
*
* Find the availability of the schedule inbox.
*/
export async function findScheduleInboxAvailability() {
const client = getClient('calendars')
const response = await client.customRequest('inbox', {
const response = await getClient().customRequest('inbox', {
method: 'PROPFIND',
data: `<?xml version="1.0"?>
<x0:propfind xmlns:x0="DAV:">
@@ -56,8 +55,10 @@ export async function findScheduleInboxAvailability() {
}
/**
* @param {any} slots -
* @param {any} timezoneId -
* Save the availability of the schedule inbox.
*
* @param slots - The availability slots to save.
* @param timezoneId - The timezone identifier.
*/
export async function saveScheduleInboxAvailability(slots, timezoneId) {
const all = [...Object.keys(slots).flatMap((dayId) => slots[dayId].map((slot) => ({
@@ -71,8 +72,7 @@ export async function saveScheduleInboxAvailability(slots, timezoneId) {
vavailability,
})
const client = getClient('calendars')
await client.customRequest('inbox', {
await getClient().customRequest('inbox', {
method: 'PROPPATCH',
data: `<?xml version="1.0"?>
<x0:propertyupdate xmlns:x0="DAV:">

View File

@@ -9,10 +9,9 @@ import { generateUrl } from '@nextcloud/router'
/**
* Configure the creation of example events on a user's first login.
*
* @param {boolean} enable Whether to enable or disable the feature.
* @return {Promise<void>}
* @param enable - Whether to enable or disable the feature.
*/
export async function setCreateExampleEvent(enable) {
export async function setCreateExampleEvent(enable: boolean): Promise<void> {
const url = generateUrl('/apps/dav/api/exampleEvent/enable')
await axios.post(url, {
enable,
@@ -22,10 +21,9 @@ export async function setCreateExampleEvent(enable) {
/**
* Upload a custom example event.
*
* @param {string} ics The ICS data of the event.
* @return {Promise<void>}
* @param ics - The ICS data of the event.
*/
export async function uploadExampleEvent(ics) {
export async function uploadExampleEvent(ics: string): Promise<void> {
const url = generateUrl('/apps/dav/api/exampleEvent/event')
await axios.post(url, {
ics,
@@ -34,10 +32,8 @@ export async function uploadExampleEvent(ics) {
/**
* Delete a previously uploaded custom example event.
*
* @return {Promise<void>}
*/
export async function deleteExampleEvent() {
export async function deleteExampleEvent(): Promise<void> {
const url = generateUrl('/apps/dav/api/exampleEvent/event')
await axios.delete(url)
}

View File

@@ -1,4 +1,4 @@
/**
/*!
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -9,8 +9,8 @@ import { generateOcsUrl } from '@nextcloud/router'
/**
* Enable user status automation based on availability
*/
export async function enableUserStatusAutomation() {
return await axios.post(
export async function enableUserStatusAutomation(): Promise<void> {
await axios.post(
generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
appId: 'dav',
configKey: 'user_status_automation',
@@ -24,8 +24,8 @@ export async function enableUserStatusAutomation() {
/**
* Disable user status automation based on availability
*/
export async function disableUserStatusAutomation() {
return await axios.delete(generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
export async function disableUserStatusAutomation(): Promise<void> {
await axios.delete(generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
appId: 'dav',
configKey: 'user_status_automation',
}))

View File

@@ -2,11 +2,10 @@
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getLoggerBuilder } from '@nextcloud/logger'
const logger = getLoggerBuilder()
export const logger = getLoggerBuilder()
.setApp('dav')
.detectUser()
.build()
export default logger

View File

@@ -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')

View File

@@ -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')

View File

@@ -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/Availability.vue'
Vue.prototype.$t = t
const View = Vue.extend(Availability);
(new View({})).$mount('#settings-personal-availability')

View File

@@ -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')

View File

@@ -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')

View File

@@ -6,12 +6,11 @@
/**
* Format a date as 'YYYY-MM-DD'.
*
* @param {Date} date A date instance to format.
* @return {string} 'YYYY-MM-DD'
* @param date - A date instance to format.
*/
export function formatDateAsYMD(date) {
export function formatDateAsYMD(date: Date): `${number}-${number}-${number}` {
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const month = (date.getMonth() + 1).toString().padStart(2, '0') as `${number}`
const day = date.getDate().toString().padStart(2, '0') as `${number}`
return `${year}-${month}-${day}`
}

View File

@@ -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')

View File

@@ -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>')

View File

@@ -3,39 +3,23 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<NcSettingsSection
id="example-content"
:name="$t('dav', 'Example content')"
class="example-content-setting"
:description="$t('dav', 'Example content serves to showcase the features of Nextcloud. Default content is shipped with Nextcloud, and can be replaced by custom content.')">
<ExampleContactSettings v-if="hasContactsApp" />
<ExampleEventSettings v-if="hasCalendarApp" />
</NcSettingsSection>
</template>
<script>
<script setup lang="ts">
import { loadState } from '@nextcloud/initial-state'
import { t } from '@nextcloud/l10n'
import { NcSettingsSection } from '@nextcloud/vue'
import ExampleContactSettings from '../components/ExampleContactSettings.vue'
import ExampleEventSettings from '../components/ExampleEventSettings.vue'
export default {
name: 'ExampleContentSettingsSection',
components: {
NcSettingsSection,
ExampleContactSettings,
ExampleEventSettings,
},
computed: {
hasContactsApp() {
return loadState('dav', 'contactsEnabled')
},
hasCalendarApp() {
return loadState('dav', 'calendarEnabled')
},
},
}
const hasContactsApp = loadState('dav', 'contactsEnabled')
const hasCalendarApp = loadState('dav', 'calendarEnabled')
</script>
<template>
<NcSettingsSection
id="example-content"
:name="t('dav', 'Example content')"
:description="t('dav', 'Example content serves to showcase the features of Nextcloud. Default content is shipped with Nextcloud, and can be replaced by custom content.')">
<ExampleContactSettings v-if="hasContactsApp" />
<ExampleEventSettings v-if="hasCalendarApp" />
</NcSettingsSection>
</template>

View File

@@ -2,43 +2,31 @@
- SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<script setup lang="ts">
import { loadState } from '@nextcloud/initial-state'
import { t } from '@nextcloud/l10n'
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
import AbsenceForm from '../components/AbsenceForm.vue'
import AvailabilityForm from '../components/AvailabilityForm.vue'
const hideAbsenceSettings = loadState('dav', 'hide_absence_settings', true)
</script>
<template>
<div>
<NcSettingsSection
id="availability"
:name="$t('dav', 'Availability')"
:description="$t('dav', 'If you configure your working hours, other people will see when you are out of office when they book a meeting.')">
:name="t('dav', 'Availability')"
:description="t('dav', 'If you configure your working hours, other people will see when you are out of office when they book a meeting.')">
<AvailabilityForm />
</NcSettingsSection>
<NcSettingsSection
v-if="!hideAbsenceSettings"
id="absence"
:name="$t('dav', 'Absence')"
:description="$t('dav', 'Configure your next absence period.')">
:name="t('dav', 'Absence')"
:description="t('dav', 'Configure your next absence period.')">
<AbsenceForm />
</NcSettingsSection>
</div>
</template>
<script>
import { loadState } from '@nextcloud/initial-state'
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
import AbsenceForm from '../components/AbsenceForm.vue'
import AvailabilityForm from '../components/AvailabilityForm.vue'
/* eslint vue/multi-word-component-names: "warn" */
export default {
name: 'Availability',
components: {
NcSettingsSection,
AbsenceForm,
AvailabilityForm,
},
data() {
return {
hideAbsenceSettings: loadState('dav', 'hide_absence_settings', true),
}
},
}
</script>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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'),

View File

@@ -11,10 +11,10 @@
"dev": "NODE_ENV=development vite build --mode development",
"lint": "eslint --suppressions-location ../eslint-baseline.json --no-error-on-unmatched-pattern ./apps/*/ ./core/",
"lint:fix": "eslint --suppressions-location ../eslint-baseline.json --fix --no-error-on-unmatched-pattern ./apps/*/ ./core/",
"test": "vitest run --passWithNoTests",
"test:coverage": "vitest run --passWithNoTests --coverage --reporter=default",
"test:update-snapshots": "vitest run --update",
"test:watch": "vitest watch",
"test": "vitest -c ../../vitest.config.ts run",
"test:coverage": "vitest -c ../../vitest.config.ts run --coverage --reporter=default",
"test:update-snapshots": "vitest -c ../../vitest.config.ts run --update",
"test:watch": "vitest -c ../../vitest.config.ts watch",
"watch": "NODE_ENV=development vite build --mode development --watch"
},
"browserslist": [

View File

@@ -6,9 +6,26 @@
import { createAppConfig } from '@nextcloud/vite-config'
import { resolve } from 'node:path'
export default createAppConfig({
'admin-settings': resolve(import.meta.dirname, 'apps/sharebymail/src', 'settings-admin.ts'),
}, {
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'),
},
}
// convert modules to modules entries prefied with the app id
const viteModuleEntries = Object.entries(modules)
.map(([appId, entries]) => (
Object.entries(entries)
.map(([entryName, entryPath]) => [`${appId}-${entryName}`, entryPath])
))
.flat(1)
export default createAppConfig(Object.fromEntries(viteModuleEntries), {
emptyOutputDirectory: {
additionalDirectories: [resolve(import.meta.dirname, '../..', 'dist')],
},
@@ -23,11 +40,12 @@ export default createAppConfig({
build: {
outDir: 'dist',
rollupOptions: {
experimental: {
strictExecutionOrder: true,
},
output: {
entryFileNames({ facadeModuleId }) {
const [, appId] = facadeModuleId!.match(/apps\/([^/]+)\//)!
return `${appId}-[name].mjs`
},
minify: false,
entryFileNames: '[name].mjs',
chunkFileNames: '[name]-[hash].chunk.mjs',
assetFileNames({ originalFileNames }) {
const [name] = originalFileNames
@@ -37,16 +55,25 @@ export default createAppConfig({
}
return '[name]-[hash][extname]'
},
/* advancedChunks: {
groups: [{ name: 'common', test: /[\\/]node_modules[\\/]/ }],
advancedChunks: {
groups: [
// one group for common dependencies
{ name: 'common', test: /[\\/]node_modules[\\/]/ },
// one group per app with a lower minShareCount to encourage sharing within the app
...Object.keys(modules).map((name) => ({
name,
test: new RegExp(`[\\\\/]apps[\\\\/]${name}[\\\\/]`),
minShareCount: 2,
})),
],
// only include modules in the groups if they are used at least by 3 different chunks
minShareCount: 3,
// only include modules in the groups if they are smaller than 200kb on its own
maxModuleSize: 200 * 1024,
// only include modules in the groups if they are smaller than 400kb on its own
// maxModuleSize: 400 * 1024,
// define the groups output size (not too small but also not too big!)
minSize: 50 * 1024,
maxSize: 500 * 1024,
}, */
minSize: 100 * 1024,
maxSize: 800 * 1024,
},
},
},
},

View File

@@ -1,58 +0,0 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: CC0-1.0
*/
import vue from '@vitejs/plugin-vue'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
import { defaultExclude, defineConfig } from 'vitest/config'
const gitIgnore: string[] = []
// get all files ignored in the apps directory (e.g. if putting `view` app there).
try {
const execAsync = promisify(exec)
const { stdout } = await execAsync('git check-ignore apps/*', { cwd: __dirname })
gitIgnore.push(...stdout.split('\n').filter(Boolean))
// eslint-disable-next-line no-console
console.log('Git ignored files excluded from tests: ', gitIgnore)
} catch (error) {
// we can ignore error code 1 as this just means there are no ignored files
if (error.code !== 1) {
// but otherwise something bad is happening and we should re-throw
throw error
}
}
export default defineConfig({
plugins: [vue()],
test: {
include: ['./apps/sharebymail/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
environment: 'jsdom',
environmentOptions: {
jsdom: {
url: 'http://nextcloud.local',
},
},
coverage: {
include: ['apps/*/src/**', 'core/src/**'],
exclude: ['**.spec.*', '**.test.*', '**.cy.*', 'core/src/tests/**'],
provider: 'v8',
reporter: ['lcov', 'text'],
},
setupFiles: [
'__tests__/mock-window.js',
'__tests__/setup-testing-library.js',
],
exclude: [
...defaultExclude,
...gitIgnore,
],
globalSetup: '__tests__/setup-global.js',
server: {
deps: {
inline: [/@nextcloud\//],
},
},
},
})

View File

@@ -0,0 +1,128 @@
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { clearState } from '../../support/commonUtils.ts'
describe('Calendar: Availability', { testIsolation: true }, () => {
before(() => {
clearState()
})
it('User can see the availability section in settings', () => {
cy.createRandomUser().then(($user) => {
cy.login($user)
cy.visit('/settings/user')
})
// can see the section
cy.findAllByRole('link', { name: /Availability/ })
.should('be.visible')
.click()
cy.url().should('match', /settings\/user\/availability$/)
cy.findByRole('heading', { name: /Availability/, level: 2 })
.should('be.visible')
})
it('Users can set their availability status', () => {
cy.createRandomUser().then(($user) => {
cy.login($user)
cy.visit('/settings/user/availability')
})
// can see the settings
cy.findByRole('list', { name: 'Weekdays' })
.should('be.visible')
.within(() => {
cy.contains('li', 'Friday')
.should('be.visible')
.should('contain.text', 'No working hours set')
.as('fridayItem')
.findByRole('button', { name: 'Add slot' })
.click()
})
cy.get('@fridayItem')
.findByLabelText(/start time/i)
.type('09:00')
cy.get('@fridayItem')
.findByLabelText(/end time/i)
.type('18:00')
cy.intercept('PROPPATCH', '**/remote.php/dav/calendars/*/inbox').as('saveAvailability')
cy.get('#availability')
.findByRole('button', { name: 'Save' })
.click()
cy.wait('@saveAvailability')
cy.reload()
cy.findByRole('list', { name: 'Weekdays' })
.should('be.visible')
.within(() => {
cy.contains('li', 'Friday')
.should('be.visible')
.should('not.contain.text', 'No working hours set')
})
})
it('Users can set their absence', () => {
cy.createUser({ language: 'en', password: 'password', userId: 'replacement-user' })
cy.createRandomUser().then(($user) => {
cy.login($user)
cy.visit('/settings/user/availability')
})
cy.findByRole('heading', { name: /absence/i }).scrollIntoView()
cy.findByLabelText(/First day/)
.should('be.visible')
.type('2024-12-24')
cy.findByLabelText(/Last day/)
.should('be.visible')
.type('2024-12-28')
cy.findByRole('textbox', { name: /Short absence/ })
.should('be.visible')
.type('Vacation')
cy.findByRole('textbox', { name: /Long absence/ })
.should('be.visible')
.type('Happy holidays!')
cy.intercept('GET', '**/ocs/v2.php/apps/files_sharing/api/v1/sharees?*search=replacement*').as('userSearch')
cy.findByRole('searchbox')
.should('be.visible')
.as('userSearchBox')
.click()
cy.get('@userSearchBox')
.type('replacement')
cy.wait('@userSearch')
cy.findByRole('option', { name: 'replacement-user' })
.click()
cy.intercept('POST', '**/ocs/v2.php/apps/dav/api/v1/outOfOffice/*').as('saveAbsence')
cy.get('#absence')
.findByRole('button', { name: 'Save' })
.click()
cy.wait('@saveAbsence')
cy.reload()
// see its saved
cy.findByLabelText(/First day/)
.should('have.value', '2024-12-24')
cy.findByLabelText(/Last day/)
.should('have.value', '2024-12-28')
cy.findByRole('textbox', { name: /Short absence/ })
.should('have.value', 'Vacation')
cy.findByRole('textbox', { name: /Long absence/ })
.should('have.value', 'Happy holidays!')
cy.findByRole('combobox')
.should('contain.text', 'replacement-user')
})
})

2
dist/4508-4508.js vendored
View File

@@ -1 +1 @@
"use strict";(self.webpackChunknextcloud_ui_legacy=self.webpackChunknextcloud_ui_legacy||[]).push([[4508],{64508:(e,r,i)=>{i.r(r),i.d(r,{NcCustomPickerRenderResult:()=>s.N,NcReferenceList:()=>c.a,NcReferencePicker:()=>t.N,NcReferencePickerModal:()=>t.e,NcReferenceWidget:()=>t.f,NcRichText:()=>c.N,NcSearch:()=>t.h,anyLinkProviderId:()=>t.a,default:()=>c.N,getLinkWithPicker:()=>t.g,getProvider:()=>t.b,getProviders:()=>t.c,isCustomPickerElementRegistered:()=>s.c,isWidgetRegistered:()=>s.i,registerCustomPickerElement:()=>s.e,registerWidget:()=>s.r,renderCustomPickerElement:()=>s.f,renderWidget:()=>s.a,searchProvider:()=>t.s,sortProviders:()=>t.d});var c=i(61658),t=i(90690),s=i(52781)}}]);
"use strict";(self.webpackChunknextcloud_ui_legacy=self.webpackChunknextcloud_ui_legacy||[]).push([[4508],{64508:(e,r,i)=>{i.r(r),i.d(r,{NcCustomPickerRenderResult:()=>s.N,NcReferenceList:()=>c.a,NcReferencePicker:()=>t.N,NcReferencePickerModal:()=>t.e,NcReferenceWidget:()=>t.f,NcRichText:()=>c.N,NcSearch:()=>t.h,anyLinkProviderId:()=>t.a,default:()=>c.N,getLinkWithPicker:()=>t.g,getProvider:()=>t.b,getProviders:()=>t.c,isCustomPickerElementRegistered:()=>s.c,isWidgetRegistered:()=>s.i,registerCustomPickerElement:()=>s.e,registerWidget:()=>s.r,renderCustomPickerElement:()=>s.f,renderWidget:()=>s.a,searchProvider:()=>t.s,sortProviders:()=>t.d});var c=i(7838),t=i(86432),s=i(52781)}}]);

4
dist/4743-4743.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/5258-5258.js vendored Normal file
View File

@@ -0,0 +1,2 @@
"use strict";(self.webpackChunknextcloud_ui_legacy=self.webpackChunknextcloud_ui_legacy||[]).push([[5258],{16343:(e,t,n)=>{n.d(t,{a:()=>i,e:()=>o});var c=n(56426),u=n(43850),a=n(24715);const l=(0,c.c0)("nextcloud-vue").persist(!0).build();let r;function o(e,t=10){r||(r=new u.EmojiIndex(a));const n=function(){const e=Number.parseInt(l.getItem("NcEmojiPicker::currentSkinTone")??"1");return Math.min(Math.max(e,1),6)}();let c;return e?(c=r.search(`:${e}`,t),c.length<t&&(c=c.concat(r.search(e,t-c.length)))):c=u.frequently.get(t).map(e=>r.emoji(e))||[],c.map(e=>e.getSkin(n))}function i(e){u.frequently.add(e)}},95528:(e,t,n)=>{n.r(t),n.d(t,{NcAutoCompleteResult:()=>u.N,NcMentionBubble:()=>c.N,default:()=>u.a});var c=n(36079),u=n(81651)}}]);
//# sourceMappingURL=5258-5258.js.map?v=d0482c670963edefd65f

1
dist/5258-5258.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"5258-5258.js?v=d0482c670963edefd65f","mappings":"yLAGA,MAAMA,GAAU,QAAW,iBAAiBC,SAAQ,GAAMC,QAC1D,IAAIC,EAUJ,SAASC,EAAYC,EAAOC,EAAa,IAClCH,IACHA,EAAa,IAAI,EAAAI,WAAW,IAE9B,MAAMC,EAeR,WACE,MAAMC,EAAWC,OAAOC,SAASX,EAAQY,QAAQ,mCAAqC,KACtF,OAAOC,KAAKC,IACVD,KAAKE,IACHN,EACA,GAGF,EAGJ,CA1B0BO,GACxB,IAAIC,EASJ,OARIZ,GACFY,EAAUd,EAAWe,OAAO,IAAIb,IAASC,GACrCW,EAAQE,OAASb,IACnBW,EAAUA,EAAQG,OAAOjB,EAAWe,OAAOb,EAAOC,EAAaW,EAAQE,WAGzEF,EAAU,EAAAI,WAAWC,IAAIhB,GAAYiB,IAAKC,GAAOrB,EAAWsB,MAAMD,KAAQ,GAErEP,EAAQM,IAAKE,GAAUA,EAAMC,QAAQlB,GAC9C,CACA,SAASmB,EAAeC,GACtB,EAAAP,WAAWQ,IAAID,EACjB,C","sources":["webpack:///nextcloud/node_modules/@nextcloud/vue/dist/chunks/emoji-BY_D0V5K.mjs"],"sourcesContent":["import { getBuilder } from \"@nextcloud/browser-storage\";\nimport { EmojiIndex, frequently } from \"emoji-mart-vue-fast\";\nimport data from \"emoji-mart-vue-fast/data/all.json\";\nconst storage = getBuilder(\"nextcloud-vue\").persist(true).build();\nlet emojiIndex;\nvar EmojiSkinTone = /* @__PURE__ */ ((EmojiSkinTone2) => {\n EmojiSkinTone2[EmojiSkinTone2[\"Neutral\"] = 1] = \"Neutral\";\n EmojiSkinTone2[EmojiSkinTone2[\"Light\"] = 2] = \"Light\";\n EmojiSkinTone2[EmojiSkinTone2[\"MediumLight\"] = 3] = \"MediumLight\";\n EmojiSkinTone2[EmojiSkinTone2[\"Medium\"] = 4] = \"Medium\";\n EmojiSkinTone2[EmojiSkinTone2[\"MediumDark\"] = 5] = \"MediumDark\";\n EmojiSkinTone2[EmojiSkinTone2[\"Dark\"] = 6] = \"Dark\";\n return EmojiSkinTone2;\n})(EmojiSkinTone || {});\nfunction emojiSearch(query, maxResults = 10) {\n if (!emojiIndex) {\n emojiIndex = new EmojiIndex(data);\n }\n const currentSkinTone = getCurrentSkinTone();\n let results;\n if (query) {\n results = emojiIndex.search(`:${query}`, maxResults);\n if (results.length < maxResults) {\n results = results.concat(emojiIndex.search(query, maxResults - results.length));\n }\n } else {\n results = frequently.get(maxResults).map((id) => emojiIndex.emoji(id)) || [];\n }\n return results.map((emoji) => emoji.getSkin(currentSkinTone));\n}\nfunction emojiAddRecent(emojiData) {\n frequently.add(emojiData);\n}\nfunction getCurrentSkinTone() {\n const skinTone = Number.parseInt(storage.getItem(\"NcEmojiPicker::currentSkinTone\") ?? \"1\");\n return Math.min(\n Math.max(\n skinTone,\n 1\n /* Neutral */\n ),\n 6\n /* Dark */\n );\n}\nfunction setCurrentSkinTone(skinTone) {\n skinTone = Math.min(\n Math.max(\n skinTone,\n 1\n /* Neutral */\n ),\n 6\n /* Dark */\n );\n storage.setItem(\"NcEmojiPicker::currentSkinTone\", skinTone.toString());\n}\nexport {\n EmojiSkinTone as E,\n emojiAddRecent as a,\n emojiSearch as e,\n getCurrentSkinTone as g,\n setCurrentSkinTone as s\n};\n//# sourceMappingURL=emoji-BY_D0V5K.mjs.map\n"],"names":["storage","persist","build","emojiIndex","emojiSearch","query","maxResults","EmojiIndex","currentSkinTone","skinTone","Number","parseInt","getItem","Math","min","max","getCurrentSkinTone","results","search","length","concat","frequently","get","map","id","emoji","getSkin","emojiAddRecent","emojiData","add"],"sourceRoot":""}

1
dist/5258-5258.js.map.license vendored Symbolic link
View File

@@ -0,0 +1 @@
5258-5258.js.license

1
dist/5528-5528.js vendored
View File

@@ -1 +0,0 @@
"use strict";(self.webpackChunknextcloud_ui_legacy=self.webpackChunknextcloud_ui_legacy||[]).push([[5528],{95528:(e,u,l)=>{l.r(u),l.d(u,{NcAutoCompleteResult:()=>t.N,NcMentionBubble:()=>c.N,default:()=>t.a});var c=l(36079),t=l(81651)}}]);

2
dist/7838-7838.js vendored Normal file

File diff suppressed because one or more lines are too long

351
dist/7838-7838.js.license vendored Normal file
View File

@@ -0,0 +1,351 @@
SPDX-License-Identifier: MIT
SPDX-License-Identifier: ISC
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: BSD-3-Clause
SPDX-License-Identifier: BSD-2-Clause
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: (MPL-2.0 OR Apache-2.0)
SPDX-FileCopyrightText: rhysd <lin90162@yahoo.co.jp>
SPDX-FileCopyrightText: inline-style-parser developers
SPDX-FileCopyrightText: escape-html developers
SPDX-FileCopyrightText: atomiks
SPDX-FileCopyrightText: Tobias Koppers @sokra
SPDX-FileCopyrightText: Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)
SPDX-FileCopyrightText: T. Jameson Little <t.jameson.little@gmail.com>
SPDX-FileCopyrightText: Stefan Thomas <justmoon@members.fsf.org> (http://www.justmoon.net)
SPDX-FileCopyrightText: Sindre Sorhus
SPDX-FileCopyrightText: Roman Shtylman <shtylman@gmail.com>
SPDX-FileCopyrightText: Roeland Jago Douma
SPDX-FileCopyrightText: Paul Vorbach <paul@vorba.ch> (http://paul.vorba.ch)
SPDX-FileCopyrightText: Paul Vorbach <paul@vorb.de> (http://vorb.de)
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: Max <max@nextcloud.com>
SPDX-FileCopyrightText: Matt Zabriskie
SPDX-FileCopyrightText: Mark <mark@remarkablemark.org>
SPDX-FileCopyrightText: Mapbox
SPDX-FileCopyrightText: Jeff Sagal <sagalbot@gmail.com>
SPDX-FileCopyrightText: Jacob Clevenger<https://github.com/wheatjs>
SPDX-FileCopyrightText: Guillaume Chau <guillaume.b.chau@gmail.com>
SPDX-FileCopyrightText: GitHub Inc.
SPDX-FileCopyrightText: Feross Aboukhadijeh
SPDX-FileCopyrightText: Evan You
SPDX-FileCopyrightText: Eugene Sharygin <eush77@gmail.com>
SPDX-FileCopyrightText: Eric Norris (https://github.com/ericnorris)
SPDX-FileCopyrightText: Dr.-Ing. Mario Heiderich, Cure53 <mario@cure53.de> (https://cure53.de/)
SPDX-FileCopyrightText: David Clark
SPDX-FileCopyrightText: Christoph Wurst
SPDX-FileCopyrightText: Anthony Fu <https://github.com/antfu>
SPDX-FileCopyrightText: Anthony Fu <anthonyfu117@hotmail.com>
SPDX-FileCopyrightText: Andrea Giammarchi
This file is generated from multiple sources. Included packages:
- @floating-ui/core
- version: 1.7.3
- license: MIT
- @floating-ui/dom
- version: 1.7.4
- license: MIT
- @floating-ui/utils
- version: 0.2.10
- license: MIT
- unist-util-is
- version: 3.0.0
- license: MIT
- unist-util-visit-parents
- version: 2.1.2
- license: MIT
- unist-util-visit
- version: 1.4.1
- license: MIT
- @mapbox/hast-util-table-cell-style
- version: 0.2.1
- license: BSD-2-Clause
- @nextcloud/auth
- version: 2.5.3
- license: GPL-3.0-or-later
- @nextcloud/axios
- version: 2.5.2
- license: GPL-3.0-or-later
- @nextcloud/browser-storage
- version: 0.5.0
- license: GPL-3.0-or-later
- @nextcloud/initial-state
- version: 2.2.0
- license: GPL-3.0-or-later
- @nextcloud/capabilities
- version: 1.2.0
- license: GPL-3.0-or-later
- semver
- version: 7.7.2
- license: ISC
- @nextcloud/event-bus
- version: 3.3.2
- license: GPL-3.0-or-later
- @nextcloud/initial-state
- version: 3.0.0
- license: GPL-3.0-or-later
- @nextcloud/l10n
- version: 3.4.0
- license: GPL-3.0-or-later
- @nextcloud/logger
- version: 3.0.2
- license: GPL-3.0-or-later
- @nextcloud/router
- version: 3.0.1
- license: GPL-3.0-or-later
- @nextcloud/sharing
- version: 0.3.0
- license: GPL-3.0-or-later
- @nextcloud/vue-select
- version: 3.26.0
- license: MIT
- @nextcloud/browser-storage
- version: 0.4.0
- license: GPL-3.0-or-later
- @nextcloud/initial-state
- version: 2.2.0
- license: GPL-3.0-or-later
- @nextcloud/vue
- version: 8.31.0
- license: AGPL-3.0-or-later
- @ungap/structured-clone
- version: 1.3.0
- license: ISC
- @vueuse/components
- version: 11.3.0
- license: MIT
- @vueuse/core
- version: 11.3.0
- license: MIT
- @vueuse/shared
- version: 11.3.0
- license: MIT
- axios
- version: 1.12.2
- license: MIT
- base64-js
- version: 1.5.1
- license: MIT
- charenc
- version: 0.0.2
- license: BSD-3-Clause
- comma-separated-tokens
- version: 2.0.3
- license: MIT
- crypt
- version: 0.0.2
- license: BSD-3-Clause
- css-loader
- version: 7.1.2
- license: MIT
- decode-named-character-reference
- version: 1.2.0
- license: MIT
- devlop
- version: 1.1.0
- license: MIT
- dompurify
- version: 3.2.7
- license: (MPL-2.0 OR Apache-2.0)
- escape-html
- version: 1.0.3
- license: MIT
- extend
- version: 3.0.2
- license: MIT
- floating-vue
- version: 1.0.0-beta.19
- license: MIT
- focus-trap
- version: 7.6.5
- license: MIT
- hast-to-hyperscript
- version: 10.0.3
- license: MIT
- hast-util-is-element
- version: 3.0.0
- license: MIT
- hast-util-whitespace
- version: 2.0.1
- license: MIT
- ieee754
- version: 1.2.1
- license: BSD-3-Clause
- inline-style-parser
- version: 0.1.1
- license: MIT
- is-absolute-url
- version: 4.0.1
- license: MIT
- is-buffer
- version: 1.1.6
- license: MIT
- md5
- version: 2.3.0
- license: BSD-3-Clause
- mdast-squeeze-paragraphs
- version: 6.0.0
- license: MIT
- escape-string-regexp
- version: 5.0.0
- license: MIT
- mdast-util-find-and-replace
- version: 3.0.2
- license: MIT
- mdast-util-from-markdown
- version: 2.0.2
- license: MIT
- mdast-util-newline-to-break
- version: 2.0.0
- license: MIT
- mdast-util-to-hast
- version: 13.2.0
- license: MIT
- mdast-util-to-string
- version: 4.0.0
- license: MIT
- micromark-core-commonmark
- version: 2.0.3
- license: MIT
- micromark-factory-destination
- version: 2.0.1
- license: MIT
- micromark-factory-label
- version: 2.0.1
- license: MIT
- micromark-factory-space
- version: 2.0.1
- license: MIT
- micromark-factory-title
- version: 2.0.1
- license: MIT
- micromark-factory-whitespace
- version: 2.0.1
- license: MIT
- micromark-util-character
- version: 2.1.1
- license: MIT
- micromark-util-chunked
- version: 2.0.1
- license: MIT
- micromark-util-classify-character
- version: 2.0.1
- license: MIT
- micromark-util-combine-extensions
- version: 2.0.1
- license: MIT
- micromark-util-decode-numeric-character-reference
- version: 2.0.2
- license: MIT
- micromark-util-decode-string
- version: 2.0.1
- license: MIT
- micromark-util-encode
- version: 2.0.1
- license: MIT
- micromark-util-html-tag-name
- version: 2.0.1
- license: MIT
- micromark-util-normalize-identifier
- version: 2.0.1
- license: MIT
- micromark-util-resolve-all
- version: 2.0.1
- license: MIT
- micromark-util-sanitize-uri
- version: 2.0.1
- license: MIT
- micromark-util-subtokenize
- version: 2.1.0
- license: MIT
- micromark
- version: 4.0.2
- license: MIT
- buffer
- version: 6.0.3
- license: MIT
- process
- version: 0.11.10
- license: MIT
- property-information
- version: 6.5.0
- license: MIT
- rehype-external-links
- version: 3.0.0
- license: MIT
- rehype-react
- version: 7.2.0
- license: MIT
- remark-breaks
- version: 4.0.0
- license: MIT
- remark-parse
- version: 11.0.0
- license: MIT
- remark-rehype
- version: 11.1.2
- license: MIT
- remark-unlink-protocols
- version: 1.0.0
- license: MIT
- space-separated-tokens
- version: 2.0.2
- license: MIT
- striptags
- version: 3.2.0
- license: MIT
- style-loader
- version: 4.0.0
- license: MIT
- style-to-object
- version: 0.4.4
- license: MIT
- tabbable
- version: 6.2.0
- license: MIT
- trim-lines
- version: 3.0.1
- license: MIT
- trough
- version: 2.2.0
- license: MIT
- unified
- version: 11.0.5
- license: MIT
- unist-builder
- version: 4.0.0
- license: MIT
- unist-util-is
- version: 6.0.0
- license: MIT
- unist-util-position
- version: 5.0.0
- license: MIT
- unist-util-stringify-position
- version: 4.0.0
- license: MIT
- unist-util-visit-parents
- version: 6.0.1
- license: MIT
- unist-util-visit
- version: 5.0.0
- license: MIT
- vfile-message
- version: 4.0.3
- license: MIT
- vfile
- version: 6.0.3
- license: MIT
- vue-demi
- version: 0.14.10
- license: MIT
- vue-router
- version: 3.6.5
- license: MIT
- vue
- version: 2.7.16
- license: MIT
- web-namespaces
- version: 2.0.1
- license: MIT

1
dist/7838-7838.js.map vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/7838-7838.js.map.license vendored Symbolic link
View File

@@ -0,0 +1 @@
7838-7838.js.license

2
dist/NcButton-DM3fWhE9.chunk.mjs vendored Normal file
View File

@@ -0,0 +1,2 @@
import{n as e}from"./rolldown-runtime-DiYpF8Fr.chunk.mjs";import{_i as t}from"./common-yxKQvbqc.chunk.mjs";var n=e((()=>{t()}));export{n as t};
//# sourceMappingURL=NcButton-DM3fWhE9.chunk.mjs.map

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

1
dist/NcButton-DM3fWhE9.chunk.mjs.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"NcButton-DM3fWhE9.chunk.mjs","names":[],"sources":["../node_modules/@nextcloud/vue/dist/components/NcButton/index.mjs"],"sourcesContent":["import { N } from \"../../chunks/NcButton-DkC5k3Lb.mjs\";\nexport {\n N as default\n};\n//# sourceMappingURL=index.mjs.map\n"],"x_google_ignoreList":[0],"mappings":""}

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

2
dist/NcColorPicker-D8W_pyG4.chunk.mjs vendored Normal file
View File

@@ -0,0 +1,2 @@
import{n as e}from"./rolldown-runtime-DiYpF8Fr.chunk.mjs";import{d as t,f as n}from"./common-JQNqxhkS.chunk.mjs";e((()=>{n()}))();export{t as default};
//# sourceMappingURL=NcColorPicker-D8W_pyG4.chunk.mjs.map

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

View File

@@ -0,0 +1 @@
{"version":3,"file":"NcColorPicker-D8W_pyG4.chunk.mjs","names":[],"sources":["../node_modules/@nextcloud/vue/dist/components/NcColorPicker/index.mjs"],"sourcesContent":["import { N } from \"../../chunks/NcColorPicker-Cs5tFS-S.mjs\";\nexport {\n N as default\n};\n//# sourceMappingURL=index.mjs.map\n"],"x_google_ignoreList":[0],"mappings":""}

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

View File

@@ -1 +0,0 @@
import{n as e}from"./sharebymail-admin-settings.mjs";export{e as default};

View File

@@ -1 +0,0 @@
import{t as e}from"./sharebymail-admin-settings.mjs";export{e as default};

View File

@@ -0,0 +1,2 @@
import{n as e}from"./rolldown-runtime-DiYpF8Fr.chunk.mjs";import{c as t,l as n}from"./common-JQNqxhkS.chunk.mjs";e((()=>{n()}))();export{t as default};
//# sourceMappingURL=NcDateTimePicker-DJlGrg-L.chunk.mjs.map

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

View File

@@ -0,0 +1 @@
{"version":3,"file":"NcDateTimePicker-DJlGrg-L.chunk.mjs","names":[],"sources":["../node_modules/@nextcloud/vue/dist/components/NcDateTimePicker/index.mjs"],"sourcesContent":["import { N } from \"../../chunks/NcDateTimePicker-B5u2bt7M.mjs\";\nexport {\n N as default\n};\n//# sourceMappingURL=index.mjs.map\n"],"x_google_ignoreList":[0],"mappings":""}

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

2
dist/NcSelect-DKeVC90s.chunk.mjs vendored Normal file
View File

@@ -0,0 +1,2 @@
import{n as e}from"./rolldown-runtime-DiYpF8Fr.chunk.mjs";import{_ as t,g as n}from"./common-JQNqxhkS.chunk.mjs";e((()=>{t()}))();export{n as default};
//# sourceMappingURL=NcSelect-DKeVC90s.chunk.mjs.map

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

1
dist/NcSelect-DKeVC90s.chunk.mjs.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"NcSelect-DKeVC90s.chunk.mjs","names":[],"sources":["../node_modules/@nextcloud/vue/dist/components/NcSelect/index.mjs"],"sourcesContent":["import { N } from \"../../chunks/NcSelect-BN2tEhoU.mjs\";\nexport {\n N as default\n};\n//# sourceMappingURL=index.mjs.map\n"],"x_google_ignoreList":[0],"mappings":""}

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later

View File

@@ -1 +0,0 @@
import{r as e}from"./sharebymail-admin-settings.mjs";export{e as default};

View File

@@ -1,7 +0,0 @@
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: rolldown developers
This file is generated from multiple sources. Included packages:
- rolldown
- version: 1.0.0-beta.44
- license: MIT

View File

@@ -1,7 +0,0 @@
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: rolldown developers
This file is generated from multiple sources. Included packages:
- rolldown
- version: 1.0.0-beta.44
- license: MIT

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/common-BPS_5DGx.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

24
dist/common-BPS_5DGx.chunk.mjs.license vendored Normal file
View File

@@ -0,0 +1,24 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: Evan You
SPDX-FileCopyrightText: Fedor Indutny <fedor@indutny.com>
SPDX-FileCopyrightText: Jeff Sagal <sagalbot@gmail.com>
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: date-fns developers
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- @vue/shared
- version: 3.5.22
- license: MIT
- date-fns
- version: 4.1.0
- license: MIT
- elliptic
- version: 6.6.1
- license: MIT
- vue-select
- version: 4.0.0-beta.6
- license: MIT

1
dist/common-BPS_5DGx.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: Evan You
SPDX-FileCopyrightText: Fedor Indutny <fedor@indutny.com>
SPDX-FileCopyrightText: Jeff Sagal <sagalbot@gmail.com>
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: date-fns developers
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- @vue/shared
- version: 3.5.22
- license: MIT
- date-fns
- version: 4.1.0
- license: MIT
- elliptic
- version: 6.6.1
- license: MIT
- vue-select
- version: 4.0.0-beta.6
- license: MIT

3
dist/common-BT_nQ5jL.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: @nextcloud/dialogs developers
This file is generated from multiple sources. Included packages:
- @nextcloud/dialogs
- version: 7.1.0
- license: AGPL-3.0-or-later

1
dist/common-BT_nQ5jL.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: @nextcloud/dialogs developers
This file is generated from multiple sources. Included packages:
- @nextcloud/dialogs
- version: 7.1.0
- license: AGPL-3.0-or-later

2
dist/common-BTwnNXu7.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

12
dist/common-BTwnNXu7.chunk.mjs.license vendored Normal file
View File

@@ -0,0 +1,12 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: Evan You
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- @vue/runtime-core
- version: 3.5.22
- license: MIT

1
dist/common-BTwnNXu7.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: Evan You
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
This file is generated from multiple sources. Included packages:
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- @vue/runtime-core
- version: 3.5.22
- license: MIT

2
dist/common-B_tHvS5H.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: BSD-3-Clause
SPDX-FileCopyrightText: Borys Serebrov
This file is generated from multiple sources. Included packages:
- emoji-mart-vue-fast
- version: 15.0.5
- license: BSD-3-Clause

1
dist/common-B_tHvS5H.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
SPDX-License-Identifier: BSD-3-Clause
SPDX-FileCopyrightText: Borys Serebrov
This file is generated from multiple sources. Included packages:
- emoji-mart-vue-fast
- version: 15.0.5
- license: BSD-3-Clause

2
dist/common-BlapdzXl.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

55
dist/common-BlapdzXl.chunk.mjs.license vendored Normal file
View File

@@ -0,0 +1,55 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: BSD-3-Clause
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: ISC
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText:
SPDX-FileCopyrightText: Borys Serebrov
SPDX-FileCopyrightText: Calvin Metcalf
SPDX-FileCopyrightText: Christoph Wurst
SPDX-FileCopyrightText: Daniel Cousens
SPDX-FileCopyrightText: Fedor Indutny
SPDX-FileCopyrightText: Fedor Indutny <fedor@indutny.com>
SPDX-FileCopyrightText: Matt Zabriskie
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: browserify-sign developers
SPDX-FileCopyrightText: chenkai
SPDX-FileCopyrightText: date-fns developers
This file is generated from multiple sources. Included packages:
- @ckpack/vue-color
- version: 1.6.0
- license: MIT
- @nextcloud/router
- version: 3.0.1
- license: GPL-3.0-or-later
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- asn1.js
- version: 4.10.1
- license: MIT
- axios
- version: 1.12.2
- license: MIT
- browserify-aes
- version: 1.2.0
- license: MIT
- browserify-sign
- version: 4.2.5
- license: ISC
- create-ecdh
- version: 4.0.4
- license: MIT
- date-fns
- version: 4.1.0
- license: MIT
- emoji-mart-vue-fast
- version: 15.0.5
- license: BSD-3-Clause
- hash.js
- version: 1.1.7
- license: MIT
- pbkdf2
- version: 3.1.5
- license: MIT

1
dist/common-BlapdzXl.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,55 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: BSD-3-Clause
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: ISC
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText:
SPDX-FileCopyrightText: Borys Serebrov
SPDX-FileCopyrightText: Calvin Metcalf
SPDX-FileCopyrightText: Christoph Wurst
SPDX-FileCopyrightText: Daniel Cousens
SPDX-FileCopyrightText: Fedor Indutny
SPDX-FileCopyrightText: Fedor Indutny <fedor@indutny.com>
SPDX-FileCopyrightText: Matt Zabriskie
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: browserify-sign developers
SPDX-FileCopyrightText: chenkai
SPDX-FileCopyrightText: date-fns developers
This file is generated from multiple sources. Included packages:
- @ckpack/vue-color
- version: 1.6.0
- license: MIT
- @nextcloud/router
- version: 3.0.1
- license: GPL-3.0-or-later
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- asn1.js
- version: 4.10.1
- license: MIT
- axios
- version: 1.12.2
- license: MIT
- browserify-aes
- version: 1.2.0
- license: MIT
- browserify-sign
- version: 4.2.5
- license: ISC
- create-ecdh
- version: 4.0.4
- license: MIT
- date-fns
- version: 4.1.0
- license: MIT
- emoji-mart-vue-fast
- version: 15.0.5
- license: BSD-3-Clause
- hash.js
- version: 1.1.7
- license: MIT
- pbkdf2
- version: 3.1.5
- license: MIT

2
dist/common-BmnZMg8K.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: rolldown developers
SPDX-FileCopyrightText: Fedor Indutny <fedor@indutny.com>
This file is generated from multiple sources. Included packages:
- rolldown
- version: 1.0.0-beta.44
- bn.js
- version: 4.12.2
- license: MIT

1
dist/common-BmnZMg8K.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: rolldown developers
SPDX-FileCopyrightText: Fedor Indutny <fedor@indutny.com>
This file is generated from multiple sources. Included packages:
- rolldown
- version: 1.0.0-beta.44
- bn.js
- version: 4.12.2
- license: MIT

2
dist/common-CTJeoPPu.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

36
dist/common-CTJeoPPu.chunk.mjs.license vendored Normal file
View File

@@ -0,0 +1,36 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: ISC
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: Fedor Indutny
SPDX-FileCopyrightText: GitHub Inc.
SPDX-FileCopyrightText: Matt Zabriskie
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: date-fns developers
SPDX-FileCopyrightText: readable-stream developers
This file is generated from multiple sources. Included packages:
- @nextcloud/l10n
- version: 3.4.0
- license: GPL-3.0-or-later
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- asn1.js
- version: 4.10.1
- license: MIT
- axios
- version: 1.12.2
- license: MIT
- date-fns
- version: 4.1.0
- license: MIT
- readable-stream
- version: 2.3.8
- license: MIT
- readable-stream
- version: 3.6.2
- license: MIT
- semver
- version: 7.7.3
- license: ISC

1
dist/common-CTJeoPPu.chunk.mjs.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,36 @@
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: ISC
SPDX-License-Identifier: MIT
SPDX-FileCopyrightText: Fedor Indutny
SPDX-FileCopyrightText: GitHub Inc.
SPDX-FileCopyrightText: Matt Zabriskie
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: date-fns developers
SPDX-FileCopyrightText: readable-stream developers
This file is generated from multiple sources. Included packages:
- @nextcloud/l10n
- version: 3.4.0
- license: GPL-3.0-or-later
- @nextcloud/vue
- version: 9.0.1
- license: AGPL-3.0-or-later
- asn1.js
- version: 4.10.1
- license: MIT
- axios
- version: 1.12.2
- license: MIT
- date-fns
- version: 4.1.0
- license: MIT
- readable-stream
- version: 2.3.8
- license: MIT
- readable-stream
- version: 3.6.2
- license: MIT
- semver
- version: 7.7.3
- license: ISC

2
dist/common-CbpYQqBL.chunk.mjs vendored Normal file

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More