Skip to content

Commit 805978c

Browse files
committed
refactor: migrate to script-setup for better Typescript support
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 484342a commit 805978c

1 file changed

Lines changed: 115 additions & 123 deletions

File tree

src/components/PasswordDialog.vue

Lines changed: 115 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,120 @@
33
- SPDX-License-Identifier: MIT
44
-->
55

6+
<script setup lang="ts">
7+
import { isAxiosError } from '@nextcloud/axios'
8+
import { computed, nextTick, onMounted, ref, useTemplateRef } from 'vue'
9+
import NcButton from '@nextcloud/vue/components/NcButton'
10+
import NcDialog from '@nextcloud/vue/components/NcDialog'
11+
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
12+
import NcPasswordField from '@nextcloud/vue/components/NcPasswordField'
13+
import { t } from '../utils/l10n.js'
14+
import { logger } from '../utils/logger.js'
15+
16+
type ICanFocus = {
17+
focus: () => void
18+
select: () => void
19+
}
20+
21+
const props = defineProps<{
22+
/**
23+
* Function to call to validate password
24+
*/
25+
validate: (password: string) => Promise<void> | void
26+
}>()
27+
28+
const emit = defineEmits<{
29+
close: [confirmed: boolean]
30+
}>()
31+
32+
onMounted(focusPasswordField)
33+
34+
const passwordInput = useTemplateRef<ICanFocus>('field')
35+
36+
const password = ref('')
37+
const loading = ref(false)
38+
const hasError = ref<boolean | 403>(false)
39+
40+
const helperText = computed(() => {
41+
if (hasError.value !== false) {
42+
if (password.value === '') {
43+
return t('Please enter your password')
44+
}
45+
46+
switch (hasError.value) {
47+
case true:
48+
return t('Unknown error while checking password')
49+
case 403:
50+
return t('Wrong password')
51+
}
52+
}
53+
54+
if (loading.value) {
55+
return t('Checking password …') // TRANSLATORS: This is a status message, shown when the system is checking the users password
56+
}
57+
58+
return ''
59+
})
60+
61+
/**
62+
* Handle confirm button click
63+
*/
64+
async function confirm(): Promise<void> {
65+
hasError.value = false
66+
loading.value = true
67+
68+
if (password.value === '') {
69+
hasError.value = true
70+
return
71+
}
72+
73+
try {
74+
await props.validate(password.value)
75+
emit('close', true)
76+
} catch (error) {
77+
if (isAxiosError(error) && error.response?.status === 403) {
78+
hasError.value = 403
79+
} else {
80+
hasError.value = true
81+
}
82+
83+
logger.error('Exception during password confirmation', { error })
84+
selectPasswordField()
85+
} finally {
86+
loading.value = false
87+
}
88+
}
89+
90+
/**
91+
* Handle the close event.
92+
*
93+
* @param open - The new status
94+
*/
95+
function close(open: boolean): void {
96+
if (!open) {
97+
emit('close', false)
98+
}
99+
}
100+
101+
/**
102+
* Focus the password field
103+
*/
104+
function focusPasswordField() {
105+
nextTick(() => {
106+
passwordInput.value!.focus()
107+
})
108+
}
109+
110+
/**
111+
* Select the password field
112+
*/
113+
function selectPasswordField() {
114+
nextTick(() => {
115+
passwordInput.value!.select()
116+
})
117+
}
118+
</script>
119+
6120
<template>
7121
<NcDialog
8122
:name="t('Authentication required')"
@@ -16,7 +130,7 @@
16130
v-model="password"
17131
:label="t('Password')"
18132
:helper-text="helperText"
19-
:error="error !== false"
133+
:error="hasError !== false"
20134
required />
21135
<NcButton
22136
class="vue-password-confirmation__submit"
@@ -32,128 +146,6 @@
32146
</NcDialog>
33147
</template>
34148

35-
<script lang="ts">
36-
import { isAxiosError } from '@nextcloud/axios'
37-
import { defineComponent } from 'vue'
38-
import NcButton from '@nextcloud/vue/components/NcButton'
39-
import NcDialog from '@nextcloud/vue/components/NcDialog'
40-
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
41-
import NcPasswordField from '@nextcloud/vue/components/NcPasswordField'
42-
import { t } from '../utils/l10n.js'
43-
import { logger } from '../utils/logger.js'
44-
45-
type ICanFocus = {
46-
focus: () => void
47-
select: () => void
48-
}
49-
50-
export default defineComponent({
51-
name: 'PasswordDialog',
52-
53-
components: {
54-
NcButton,
55-
NcDialog,
56-
NcLoadingIcon,
57-
NcPasswordField,
58-
},
59-
60-
props: {
61-
/**
62-
* Function to call to validate password
63-
*/
64-
validate: {
65-
type: Function,
66-
required: true,
67-
},
68-
},
69-
70-
emits: ['close'],
71-
72-
data() {
73-
return {
74-
password: '',
75-
loading: false,
76-
error: false as boolean | 403,
77-
}
78-
},
79-
80-
computed: {
81-
helperText() {
82-
if (this.error !== false) {
83-
if (this.password === '') {
84-
return t('Please enter your password')
85-
}
86-
87-
switch (this.error) {
88-
case true:
89-
return t('Unknown error while checking password')
90-
case 403:
91-
return t('Wrong password')
92-
}
93-
}
94-
95-
if (this.loading) {
96-
return t('Checking password …') // TRANSLATORS: This is a status message, shown when the system is checking the users password
97-
}
98-
99-
return ''
100-
},
101-
},
102-
103-
mounted() {
104-
this.focusPasswordField()
105-
},
106-
107-
methods: {
108-
t,
109-
110-
async confirm(): Promise<void> {
111-
this.error = false
112-
this.loading = true
113-
114-
if (this.password === '') {
115-
this.error = true
116-
return
117-
}
118-
119-
try {
120-
await this.validate(this.password)
121-
this.$emit('close', true)
122-
} catch (error) {
123-
if (isAxiosError(error) && error.response?.status === 403) {
124-
this.error = 403
125-
} else {
126-
this.error = true
127-
}
128-
129-
logger.error('Exception during password confirmation', { error })
130-
this.selectPasswordField()
131-
} finally {
132-
this.loading = false
133-
}
134-
},
135-
136-
close(open: boolean): void {
137-
if (!open) {
138-
this.$emit('close', false)
139-
}
140-
},
141-
142-
focusPasswordField() {
143-
this.$nextTick(() => {
144-
(this.$refs.field as ICanFocus).focus()
145-
})
146-
},
147-
148-
selectPasswordField() {
149-
this.$nextTick(() => {
150-
(this.$refs.field as ICanFocus).select()
151-
})
152-
},
153-
},
154-
})
155-
</script>
156-
157149
<style lang="scss">
158150
.vue-password-confirmation {
159151
display: flex;

0 commit comments

Comments
 (0)