Skip to content

Commit 547f7b7

Browse files
committed
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 <[email protected]>
1 parent 6c4a7c3 commit 547f7b7

20 files changed

+186
-133
lines changed

apps/dav/lib/Settings/AvailabilitySettings.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public function getForm(): TemplateResponse {
5656
}
5757
}
5858

59+
\OCP\Util::addStyle(Application::APP_ID, 'settings-personal-availability');
60+
\OCP\Util::addScript(Application::APP_ID, 'settings-personal-availability');
5961
return new TemplateResponse(Application::APP_ID, 'settings-personal-availability');
6062
}
6163

apps/dav/lib/Settings/CalDAVSettings.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ public function getForm(): TemplateResponse {
4444
$value = $this->config->getAppValue(Application::APP_ID, $key, $default);
4545
$this->initialState->provideInitialState($key, $value === 'yes');
4646
}
47+
48+
\OCP\Util::addScript(Application::APP_ID, 'settings-admin-caldav');
49+
\OCP\Util::addStyle(Application::APP_ID, 'settings-admin-caldav');
4750
return new TemplateResponse(Application::APP_ID, 'settings-admin-caldav');
4851
}
4952

apps/dav/lib/Settings/ExampleContentSettings.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public function getForm(): TemplateResponse {
5353
);
5454
}
5555

56-
return new TemplateResponse(Application::APP_ID, 'settings-example-content');
56+
\OCP\Util::addStyle(Application::APP_ID, 'settings-admin-example-content');
57+
\OCP\Util::addScript(Application::APP_ID, 'settings-admin-example-content');
58+
return new TemplateResponse(Application::APP_ID, 'settings-admin-example-content');
5759
}
5860

5961
public function getSection(): ?string {

apps/dav/src/components/AbsenceForm.vue

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,39 @@
99
<NcDateTimePickerNative
1010
id="absence-first-day"
1111
v-model="firstDay"
12-
:label="$t('dav', 'First day')"
12+
:label="t('dav', 'First day')"
1313
class="absence__dates__picker"
1414
:required="true" />
1515
<NcDateTimePickerNative
1616
id="absence-last-day"
1717
v-model="lastDay"
18-
:label="$t('dav', 'Last day (inclusive)')"
18+
:label="t('dav', 'Last day (inclusive)')"
1919
class="absence__dates__picker"
2020
:required="true" />
2121
</div>
22-
<label for="replacement-search-input">{{ $t('dav', 'Out of office replacement (optional)') }}</label>
23-
<NcSelect
24-
ref="select"
22+
<label for="replacement-search-input">{{ t('dav', 'Out of office replacement (optional)') }}</label>
23+
<NcSelectUsers
2524
v-model="replacementUser"
2625
input-id="replacement-search-input"
2726
:loading="searchLoading"
28-
:placeholder="$t('dav', 'Name of the replacement')"
29-
:clear-search-on-blur="() => false"
30-
user-select
27+
:placeholder="t('dav', 'Name of the replacement')"
3128
:options="options"
32-
@search="asyncFind">
33-
<template #no-options="{ search }">
34-
{{ search ? $t('dav', 'No results.') : $t('dav', 'Start typing.') }}
35-
</template>
36-
</NcSelect>
37-
<NcTextField :value.sync="status" :label="$t('dav', 'Short absence status')" :required="true" />
38-
<NcTextArea :value.sync="message" :label="$t('dav', 'Long absence Message')" :required="true" />
29+
@search="asyncFind" />
30+
<NcTextField v-model="status" :label="t('dav', 'Short absence status')" :required="true" />
31+
<NcTextArea v-model="message" :label="t('dav', 'Long absence Message')" :required="true" />
3932

4033
<div class="absence__buttons">
4134
<NcButton
4235
:disabled="loading || !valid"
4336
variant="primary"
4437
type="submit">
45-
{{ $t('dav', 'Save') }}
38+
{{ t('dav', 'Save') }}
4639
</NcButton>
4740
<NcButton
4841
:disabled="loading || !valid"
4942
variant="error"
5043
@click="clearAbsence">
51-
{{ $t('dav', 'Disable absence') }}
44+
{{ t('dav', 'Disable absence') }}
5245
</NcButton>
5346
</div>
5447
</form>
@@ -59,26 +52,30 @@ import { getCurrentUser } from '@nextcloud/auth'
5952
import axios from '@nextcloud/axios'
6053
import { showError, showSuccess } from '@nextcloud/dialogs'
6154
import { loadState } from '@nextcloud/initial-state'
55+
import { t } from '@nextcloud/l10n'
6256
import { generateOcsUrl } from '@nextcloud/router'
6357
import { ShareType } from '@nextcloud/sharing'
6458
import debounce from 'debounce'
6559
import NcButton from '@nextcloud/vue/components/NcButton'
6660
import NcDateTimePickerNative from '@nextcloud/vue/components/NcDateTimePickerNative'
67-
import NcSelect from '@nextcloud/vue/components/NcSelect'
61+
import NcSelectUsers from '@nextcloud/vue/components/NcSelectUsers'
6862
import NcTextArea from '@nextcloud/vue/components/NcTextArea'
6963
import NcTextField from '@nextcloud/vue/components/NcTextField'
7064
import { logger } from '../service/logger.ts'
71-
import { formatDateAsYMD } from '../utils/date.js'
65+
import { formatDateAsYMD } from '../utils/date.ts'
7266
73-
/* eslint @nextcloud/vue/no-deprecated-props: "warn" */
7467
export default {
7568
name: 'AbsenceForm',
7669
components: {
7770
NcButton,
7871
NcTextField,
7972
NcTextArea,
8073
NcDateTimePickerNative,
81-
NcSelect,
74+
NcSelectUsers,
75+
},
76+
77+
setup() {
78+
return { t }
8279
},
8380
8481
data() {
@@ -228,9 +225,9 @@ export default {
228225
message: this.message,
229226
replacementUserId: this.replacementUser?.user ?? null,
230227
})
231-
showSuccess(this.$t('dav', 'Absence saved'))
228+
showSuccess(t('dav', 'Absence saved'))
232229
} catch (error) {
233-
showError(this.$t('dav', 'Failed to save your absence settings'))
230+
showError(t('dav', 'Failed to save your absence settings'))
234231
logger.error('Could not save absence', { error })
235232
} finally {
236233
this.loading = false
@@ -242,9 +239,9 @@ export default {
242239
try {
243240
await axios.delete(generateOcsUrl('/apps/dav/api/v1/outOfOffice/{userId}', { userId: getCurrentUser().uid }))
244241
this.resetForm()
245-
showSuccess(this.$t('dav', 'Absence cleared'))
242+
showSuccess(t('dav', 'Absence cleared'))
246243
} catch (error) {
247-
showError(this.$t('dav', 'Failed to clear your absence settings'))
244+
showError(t('dav', 'Failed to clear your absence settings'))
248245
logger.error('Could not clear absence', { error })
249246
} finally {
250247
this.loading = false

apps/dav/src/components/ExampleContactSettings.vue

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
:checked="enableDefaultContact"
1010
type="switch"
1111
@update:model-value="updateEnableDefaultContact">
12-
{{ $t('dav', "Add example contact to user's address book when they first log in") }}
12+
{{ t('dav', "Add example contact to user's address book when they first log in") }}
1313
</NcCheckboxRadioSwitch>
1414
<div v-if="enableDefaultContact" class="example-contact-settings__buttons">
1515
<ExampleContentDownloadButton :href="downloadUrl">
@@ -24,7 +24,7 @@
2424
<template #icon>
2525
<IconUpload :size="20" />
2626
</template>
27-
{{ $t('dav', 'Import contact') }}
27+
{{ t('dav', 'Import contact') }}
2828
</NcButton>
2929
<NcButton
3030
v-if="hasCustomDefaultContact"
@@ -33,15 +33,15 @@
3333
<template #icon>
3434
<IconRestore :size="20" />
3535
</template>
36-
{{ $t('dav', 'Reset to default') }}
36+
{{ t('dav', 'Reset to default') }}
3737
</NcButton>
3838
</div>
3939
<NcDialog
40-
:open.sync="isModalOpen"
41-
:name="$t('dav', 'Import contacts')"
40+
v-model:open="isModalOpen"
41+
:name="t('dav', 'Import contacts')"
4242
:buttons="buttons">
4343
<div>
44-
<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>
44+
<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>
4545
</div>
4646
</NcDialog>
4747
<input
@@ -61,6 +61,7 @@ import IconCheck from '@mdi/svg/svg/check.svg?raw'
6161
import axios from '@nextcloud/axios'
6262
import { showError, showSuccess } from '@nextcloud/dialogs'
6363
import { loadState } from '@nextcloud/initial-state'
64+
import { t } from '@nextcloud/l10n'
6465
import { generateUrl } from '@nextcloud/router'
6566
import { NcButton, NcCheckboxRadioSwitch, NcDialog } from '@nextcloud/vue'
6667
import IconAccount from 'vue-material-design-icons/Account.vue'
@@ -69,8 +70,8 @@ import IconUpload from 'vue-material-design-icons/TrayArrowUp.vue'
6970
import ExampleContentDownloadButton from './ExampleContentDownloadButton.vue'
7071
import { logger } from '../service/logger.ts'
7172
72-
const enableDefaultContact = loadState('dav', 'enableDefaultContact')
73-
const hasCustomDefaultContact = loadState('dav', 'hasCustomDefaultContact')
73+
const enableDefaultContact = loadState('dav', 'enableDefaultContact', false)
74+
const hasCustomDefaultContact = loadState('dav', 'hasCustomDefaultContact', false)
7475
7576
export default {
7677
name: 'ExampleContactSettings',
@@ -84,6 +85,10 @@ export default {
8485
ExampleContentDownloadButton,
8586
},
8687
88+
setup() {
89+
return { t }
90+
},
91+
8792
data() {
8893
return {
8994
enableDefaultContact,
@@ -92,12 +97,12 @@ export default {
9297
loading: false,
9398
buttons: [
9499
{
95-
label: this.$t('dav', 'Cancel'),
100+
label: t('dav', 'Cancel'),
96101
icon: IconCancel,
97102
callback: () => { this.isModalOpen = false },
98103
},
99104
{
100-
label: this.$t('dav', 'Import'),
105+
label: t('dav', 'Import'),
101106
icon: IconCheck,
102107
variant: 'primary',
103108
callback: () => { this.clickImportInput() },
@@ -119,7 +124,7 @@ export default {
119124
}).then(() => {
120125
this.enableDefaultContact = !this.enableDefaultContact
121126
}).catch(() => {
122-
showError(this.$t('dav', 'Error while saving settings'))
127+
showError(t('dav', 'Error while saving settings'))
123128
})
124129
},
125130
@@ -136,11 +141,11 @@ export default {
136141
axios.put(generateUrl('/apps/dav/api/defaultcontact/contact'))
137142
.then(() => {
138143
this.hasCustomDefaultContact = false
139-
showSuccess(this.$t('dav', 'Contact reset successfully'))
144+
showSuccess(t('dav', 'Contact reset successfully'))
140145
})
141146
.catch((error) => {
142147
logger.error('Error importing contact:', { error })
143-
showError(this.$t('dav', 'Error while resetting contact'))
148+
showError(t('dav', 'Error while resetting contact'))
144149
})
145150
.finally(() => {
146151
this.loading = false
@@ -158,10 +163,10 @@ export default {
158163
try {
159164
await axios.put(generateUrl('/apps/dav/api/defaultcontact/contact'), { contactData: reader.result })
160165
this.hasCustomDefaultContact = true
161-
showSuccess(this.$t('dav', 'Contact imported successfully'))
166+
showSuccess(t('dav', 'Contact imported successfully'))
162167
} catch (error) {
163168
logger.error('Error importing contact:', { error })
164-
showError(this.$t('dav', 'Error while importing contact'))
169+
showError(t('dav', 'Error while importing contact'))
165170
} finally {
166171
this.loading = false
167172
event.target.value = ''

apps/dav/src/components/ExampleEventSettings.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
</NcButton>
4242
</div>
4343
<NcDialog
44-
:open.sync="showImportModal"
44+
v-model:open="showImportModal"
4545
:name="t('dav', 'Import calendar event')">
4646
<div class="import-event-modal">
4747
<p>
@@ -73,6 +73,7 @@
7373
<script>
7474
import { showError, showSuccess } from '@nextcloud/dialogs'
7575
import { loadState } from '@nextcloud/initial-state'
76+
import { t } from '@nextcloud/l10n'
7677
import { generateUrl } from '@nextcloud/router'
7778
import { NcButton, NcCheckboxRadioSwitch, NcDialog } from '@nextcloud/vue'
7879
import IconCalendarBlank from 'vue-material-design-icons/CalendarBlank.vue'
@@ -94,6 +95,10 @@ export default {
9495
ExampleContentDownloadButton,
9596
},
9697
98+
setup() {
99+
return { t }
100+
},
101+
97102
data() {
98103
return {
99104
createExampleEvent: loadState('dav', 'create_example_event', false),

apps/dav/src/settings-example-content.js renamed to apps/dav/src/settings-admin-example-content.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,8 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import { t } from '@nextcloud/l10n'
7-
import Vue from 'vue'
6+
import { createApp } from 'vue'
87
import ExampleContentSettingsSection from './views/ExampleContentSettingsSection.vue'
98

10-
Vue.mixin({
11-
methods: {
12-
t,
13-
$t: t,
14-
},
15-
})
16-
17-
const View = Vue.extend(ExampleContentSettingsSection);
18-
19-
(new View({})).$mount('#settings-example-content')
9+
const app = createApp(ExampleContentSettingsSection)
10+
app.mount('#settings-example-content')

apps/dav/src/settings-admin.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { createApp } from 'vue'
7+
import CalDavSettings from './views/CalDavSettings.vue'
8+
9+
const app = createApp(CalDavSettings)
10+
app.mount('#settings-admin-caldav')

apps/dav/src/settings-personal-availability.js

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { createApp } from 'vue'
7+
import UserAvailability from './views/UserAvailability.vue'
8+
9+
const app = createApp(UserAvailability)
10+
app.mount('#settings-personal-availability')

0 commit comments

Comments
 (0)