Skip to content

Commit 8bc42ad

Browse files
feat: enhance RequestSignatureTab with improved UX
Improve signature request workflow in sidebar: - Add separate 'Save' and 'Send' buttons with clear actions - Show 'Edit visible signatures' when elements available - Hide edit button when document is partially/fully signed - Add visual icons: Pencil (edit), Send (send), Draw (sign), FileDocument (open) - Simplify save/request methods using store - Add status-based button visibility logic using SIGN_STATUS enum - Improve button naming: 'Request' → 'Send' for clarity Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 69833fd commit 8bc42ad

1 file changed

Lines changed: 65 additions & 57 deletions

File tree

src/Components/RightSidebar/RequestSignatureTab.vue

Lines changed: 65 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,33 @@
3030
</template>
3131
</Signers>
3232
<div class="action-buttons">
33-
<NcButton v-if="filesStore.canSave()"
33+
<NcButton v-if="showSaveButton"
3434
:variant="filesStore.canSign() ? 'secondary' : 'primary'"
3535
:disabled="hasLoading"
3636
@click="save()">
3737
<template #icon>
3838
<NcLoadingIcon v-if="hasLoading" :size="20" />
39+
<Pencil v-else-if="isSignElementsAvailable()" :size="20" />
3940
</template>
40-
{{ labelOfSaveButton }}
41+
{{ isSignElementsAvailable() ? t('libresign', 'Edit visible signatures') : t('libresign', 'Save') }}
42+
</NcButton>
43+
<NcButton v-if="showRequestButton"
44+
:variant="filesStore.canSign() ? 'secondary' : 'primary'"
45+
:disabled="hasLoading"
46+
@click="request()">
47+
<template #icon>
48+
<NcLoadingIcon v-if="hasLoading" :size="20" />
49+
<Send v-else :size="20" />
50+
</template>
51+
{{ t('libresign', 'Send') }}
4152
</NcButton>
4253
<NcButton v-if="filesStore.canSign()"
4354
variant="primary"
4455
:disabled="hasLoading"
4556
@click="sign()">
4657
<template #icon>
4758
<NcLoadingIcon v-if="hasLoading" :size="20" />
59+
<Draw v-else :size="20" />
4860
</template>
4961
{{ t('libresign', 'Sign') }}
5062
</NcButton>
@@ -54,6 +66,9 @@
5466
{{ t('libresign', 'Validate') }}
5567
</NcButton>
5668
<NcButton @click="openFile()">
69+
<template #icon>
70+
<FileDocument :size="20" />
71+
</template>
5772
{{ t('libresign', 'Open file') }}
5873
</NcButton>
5974
</div>
@@ -97,6 +112,10 @@ import svgWhatsapp from '@mdi/svg/svg/whatsapp.svg?raw'
97112
import svgXmpp from '@mdi/svg/svg/xmpp.svg?raw'
98113
99114
import Delete from 'vue-material-design-icons/Delete.vue'
115+
import Draw from 'vue-material-design-icons/Draw.vue'
116+
import FileDocument from 'vue-material-design-icons/FileDocument.vue'
117+
import Pencil from 'vue-material-design-icons/Pencil.vue'
118+
import Send from 'vue-material-design-icons/Send.vue'
100119
101120
import axios from '@nextcloud/axios'
102121
import { getCapabilities } from '@nextcloud/capabilities'
@@ -120,6 +139,7 @@ import Signers from '../Signers/Signers.vue'
120139
121140
import svgSignal from '../../../img/logo-signal-app.svg?raw'
122141
import svgTelegram from '../../../img/logo-telegram-app.svg?raw'
142+
import { SIGN_STATUS } from '../../domains/sign/enum.js'
123143
import router from '../../router/router.js'
124144
import { useFilesStore } from '../../store/files.js'
125145
import { useSidebarStore } from '../../store/sidebar.js'
@@ -147,6 +167,10 @@ export default {
147167
NcModal,
148168
NcDialog,
149169
Delete,
170+
Draw,
171+
FileDocument,
172+
Pencil,
173+
Send,
150174
Signers,
151175
IdentifySigner,
152176
VisibleElements,
@@ -174,15 +198,28 @@ export default {
174198
}
175199
},
176200
computed: {
177-
labelOfSaveButton() {
201+
showSaveButton() {
202+
if (!this.filesStore.canSave()) {
203+
return false
204+
}
178205
179-
if (this.filesStore.canSign()) {
180-
return t('libresign', 'Edit visible signatures')
206+
if (!this.isSignElementsAvailable()) {
207+
return false
181208
}
182-
if (this.isSignElementsAvailable()) {
183-
return t('libresign', 'Next')
209+
210+
const file = this.filesStore.getFile()
211+
212+
if (file.status === SIGN_STATUS.PARTIAL_SIGNED || file.status === SIGN_STATUS.SIGNED) {
213+
return false
214+
}
215+
216+
return true
217+
},
218+
showRequestButton() {
219+
if (!this.filesStore.canSave()) {
220+
return false
184221
}
185-
return t('libresign', 'Request')
222+
return this.hasSigners
186223
},
187224
hasSigners() {
188225
return this.filesStore.hasSigners(this.filesStore.getFile())
@@ -274,59 +311,30 @@ export default {
274311
},
275312
async save() {
276313
this.hasLoading = true
277-
const config = {
278-
url: generateOcsUrl('/apps/libresign/api/v1/request-signature'),
279-
data: {
280-
name: this.filesStore.getFile()?.name,
281-
users: [],
282-
},
283-
};
284-
(this.filesStore.getFile()?.signers ?? []).forEach(signer => {
285-
const user = {
286-
displayName: signer.displayName,
287-
identify: {},
314+
try {
315+
await this.filesStore.saveWithVisibleElements({ visibleElements: [] })
316+
emit('libresign:show-visible-elements')
317+
} catch (error) {
318+
if (error.response?.data?.ocs?.data?.message) {
319+
showError(error.response.data.ocs.data.message)
320+
} else if (error.response?.data?.ocs?.data?.errors) {
321+
error.response.data.ocs.data.errors.forEach(error => showError(error.message))
288322
}
289-
signer.identifyMethods.forEach(method => {
290-
user.notify = false
291-
if (method.method === 'account') {
292-
user.identify.account = method?.value?.id ?? method?.value ?? signer.uid
293-
} else if (method.method === 'email') {
294-
user.identify.email = method?.value?.id ?? method?.value ?? signer.email
295-
} else {
296-
user.identify[method.method] = method.value
297-
}
298-
})
299-
config.data.users.push(user)
300-
})
301-
if (this.filesStore.getFile()?.status) {
302-
config.data.status = this.filesStore.getFile()?.status
303-
} else if (!this.isSignElementsAvailable()) {
304-
config.data.status = 1
305-
} else {
306-
config.data.status = 0
307323
}
308-
309-
if (this.filesStore.getFile().uuid) {
310-
config.data.uuid = this.filesStore.getFile().uuid
311-
config.method = 'patch'
312-
} else {
313-
config.data.file = {
314-
fileId: this.filesStore.selectedNodeId,
324+
this.hasLoading = false
325+
},
326+
async request() {
327+
this.hasLoading = true
328+
try {
329+
const response = await this.filesStore.requestSignaturesWithVisibleElements({ visibleElements: [] })
330+
showSuccess(t('libresign', response.message))
331+
} catch (error) {
332+
if (error.response?.data?.ocs?.data?.message) {
333+
showError(error.response.data.ocs.data.message)
334+
} else if (error.response?.data?.ocs?.data?.errors) {
335+
error.response.data.ocs.data.errors.forEach(error => showError(error.message))
315336
}
316-
config.method = 'post'
317337
}
318-
await axios(config)
319-
.then(({ data }) => {
320-
this.filesStore.addFile(data.ocs.data.data)
321-
emit('libresign:show-visible-elements')
322-
})
323-
.catch(({ response }) => {
324-
if (response?.data?.ocs?.data?.message) {
325-
showError(response.data.ocs.data.message)
326-
} else if (response?.data?.ocs?.data?.errors) {
327-
response.data.ocs.data.errors.forEach(error => showError(error.message))
328-
}
329-
})
330338
this.hasLoading = false
331339
},
332340
openFile() {

0 commit comments

Comments
 (0)