Skip to content

Commit d830371

Browse files
authored
Merge pull request #7033 from LibreSign/backport/7032/stable33
[stable33] fix: external page vue3 migration
2 parents 35ee07e + 3508cc8 commit d830371

8 files changed

Lines changed: 118 additions & 5 deletions

File tree

src/ExternalApp.vue

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2026 LibreCode coop and LibreCode contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
6+
<template>
7+
<div class="external-app">
8+
<router-view />
9+
<RightSidebar />
10+
</div>
11+
</template>
12+
13+
<script setup lang="ts">
14+
import { defineOptions } from 'vue'
15+
16+
defineOptions({ name: 'LibreSignExternal' })
17+
18+
import RightSidebar from './components/RightSidebar/RightSidebar.vue'
19+
</script>
20+
21+
<style lang="scss">
22+
// Override server.css layout rules that assume authenticated header layout.
23+
// `html body #content` beats the specificity of server.css selectors.
24+
html body #content {
25+
position: fixed;
26+
inset: 0;
27+
margin: 0;
28+
width: 100vw;
29+
height: 100vh;
30+
border-radius: 0;
31+
}
32+
33+
// On mobile, NcAppSidebar relies on NcContent to overlay content.
34+
// Without it, force the sidebar to cover the viewport as a full-screen overlay.
35+
@media (max-width: 512px) {
36+
#app-sidebar {
37+
position: fixed;
38+
inset: 0;
39+
width: 100vw !important;
40+
max-width: 100vw !important;
41+
height: 100vh;
42+
z-index: 2000;
43+
}
44+
}
45+
</style>
46+
47+
<style lang="scss" scoped>
48+
.external-app {
49+
position: absolute;
50+
inset: 0;
51+
display: flex;
52+
background-color: var(--color-main-background);
53+
}
54+
</style>

src/components/RightSidebar/RightSidebar.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
- SPDX-License-Identifier: AGPL-3.0-or-later
44
-->
55
<template>
6-
<NcAppSidebar v-if="sidebarStore.isVisible"
6+
<NcAppSidebar v-if="sidebarStore.activeTab.length > 0"
77
ref="rightAppSidebar"
8+
:open="sidebarStore.isVisible"
89
:name="fileName"
910
:subtitle="subTitle"
1011
v-model:active="sidebarStore.activeTab"

src/components/Settings/Settings.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default {
5656
},
5757
data() {
5858
return {
59-
isAdmin: getCurrentUser().isAdmin,
59+
isAdmin: getCurrentUser()?.isAdmin ?? false,
6060
}
6161
},
6262
methods: {

src/external.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { createApp } from 'vue'
77
import { createPinia } from 'pinia'
88
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
99

10-
import App from './App.vue'
10+
import App from './ExternalApp.vue'
1111
import router from './router/router'
1212

1313
if (window.OCA && !window.OCA.LibreSign) {

src/store/sidebar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const useSidebarStore = defineStore('sidebar', {
99
state: () => ({
1010
show: false,
1111
activeTab: '',
12-
sidebarRoutes: ['fileslist', 'SignPDF', 'ValidationFile', 'IdDocsApprove'],
12+
sidebarRoutes: ['fileslist', 'SignPDF', 'SignPDFExternal', 'ValidationFile', 'IdDocsApprove'],
1313
}),
1414

1515
getters: {

src/tests/components/Settings/Settings.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,54 @@ describe('Settings', () => {
258258
})
259259
})
260260

261+
describe('RULE: unauthenticated users (signing via email link) do not crash the component', () => {
262+
const createUnauthenticatedWrapper = () => {
263+
getCurrentUserMock.mockReturnValue(null)
264+
265+
return mount(Settings, {
266+
global: {
267+
stubs: {
268+
NcAppNavigationItem: {
269+
name: 'NcAppNavigationItem',
270+
props: ['name', 'to', 'href', 'icon'],
271+
template: '<li><slot name="icon" /><span class="item-name">{{ name }}</span><slot /></li>',
272+
},
273+
AccountIcon: { template: '<div class="account-icon"></div>' },
274+
StarIcon: { template: '<div class="star-icon"></div>' },
275+
TuneIcon: { template: '<div class="tune-icon"></div>' },
276+
},
277+
mocks: { t },
278+
},
279+
})
280+
}
281+
282+
it('mounts without throwing when getCurrentUser returns null', () => {
283+
expect(() => createUnauthenticatedWrapper()).not.toThrow()
284+
})
285+
286+
it('isAdmin is false when getCurrentUser returns null', () => {
287+
wrapper = createUnauthenticatedWrapper()
288+
289+
expect(getWrapper().vm.isAdmin).toBe(false)
290+
})
291+
292+
it('hides the Administration link when user is unauthenticated', () => {
293+
wrapper = createUnauthenticatedWrapper()
294+
const items = getItems()
295+
const adminItem = findItemByName(items, 'Administration')
296+
297+
expect(adminItem).toBeUndefined()
298+
})
299+
300+
it('shows 2 navigation items for unauthenticated user', () => {
301+
wrapper = createUnauthenticatedWrapper()
302+
const items = getItems()
303+
304+
// Account + Rate = 2
305+
expect(items.length).toBe(2)
306+
})
307+
})
308+
261309
describe('RULE: navigation items count depends on admin status', () => {
262310
it('shows 2 items for non-admin', () => {
263311
wrapper = createWrapper(false)

src/tests/store/sidebar.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,16 @@ describe('sidebar store - visibility rules', () => {
213213
expect(store.show).toBe(true)
214214
})
215215

216+
it('keeps sidebar visible for SignPDFExternal route', () => {
217+
const store = useSidebarStore()
218+
store.show = true
219+
store.activeTab = 'sign-tab'
220+
221+
store.handleRouteChange('SignPDFExternal')
222+
223+
expect(store.show).toBe(true)
224+
})
225+
216226
it('hides sidebar for non-allowed routes', () => {
217227
const store = useSidebarStore()
218228
store.show = true

src/views/SignPDF/SignPDF.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export default {
103103
await this.initIdDocsApprove()
104104
}
105105
106-
if (this.isMobile){
106+
if (this.isMobile && this.$route?.name !== 'SignPDFExternal') {
107107
this.toggleSidebar();
108108
}
109109

0 commit comments

Comments
 (0)