Skip to content

Commit 066ce10

Browse files
authored
Merge pull request #7009 from LibreSign/backport/7008/stable33
[stable33] fix: files list grid toggle and status chip
2 parents 23bacc6 + 25a04d5 commit 066ce10

5 files changed

Lines changed: 91 additions & 18 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { describe, expect, it } from 'vitest'
7+
import { mount } from '@vue/test-utils'
8+
9+
import FileEntryStatus from '../../../views/FilesList/FileEntry/FileEntryStatus.vue'
10+
11+
function mountStatus(props: { status: number; statusText: string; signers?: unknown[] }) {
12+
return mount(FileEntryStatus, {
13+
props: {
14+
signers: [],
15+
...props,
16+
},
17+
})
18+
}
19+
20+
describe('FileEntryStatus.vue', () => {
21+
it('renders nothing when statusText is "none"', () => {
22+
const wrapper = mountStatus({ status: 0, statusText: 'none' })
23+
expect(wrapper.find('.status-chip').exists()).toBe(false)
24+
})
25+
26+
it('renders chip when statusText is not "none"', () => {
27+
const wrapper = mountStatus({ status: 3, statusText: 'Signed' })
28+
expect(wrapper.find('.status-chip').exists()).toBe(true)
29+
})
30+
31+
it('displays the statusText inside the chip', () => {
32+
const wrapper = mountStatus({ status: 3, statusText: 'Signed' })
33+
expect(wrapper.find('.status-chip__text').text()).toBe('Signed')
34+
})
35+
36+
it.each([
37+
{ status: -1, expected: 'status-chip--not-libresign' },
38+
{ status: 0, expected: 'status-chip--draft' },
39+
{ status: 1, expected: 'status-chip--available' },
40+
{ status: 2, expected: 'status-chip--partial' },
41+
{ status: 3, expected: 'status-chip--signed' },
42+
{ status: 4, expected: 'status-chip--deleted' },
43+
{ status: 5, expected: 'status-chip--signing' },
44+
])('applies variant class "$expected" for status $status', ({ status, expected }) => {
45+
const wrapper = mountStatus({ status, statusText: 'any' })
46+
expect(wrapper.find('.status-chip').classes()).toContain(expected)
47+
})
48+
49+
it('falls back to draft variant for unknown status', () => {
50+
const wrapper = mountStatus({ status: 99, statusText: 'Unknown' })
51+
expect(wrapper.find('.status-chip').classes()).toContain('status-chip--draft')
52+
})
53+
54+
it('chip does not apply any inline style that would override the nowrap fix', () => {
55+
const wrapper = mountStatus({ status: 3, statusText: 'Signed' })
56+
const chip = wrapper.find('.status-chip')
57+
// white-space is controlled by scoped CSS (nowrap); no inline style should override it
58+
expect(chip.exists()).toBe(true)
59+
expect(chip.attributes('style')).toBeUndefined()
60+
})
61+
})

src/tests/views/FilesList/FilesList.spec.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,6 @@ describe('FilesList.vue rendering rules', () => {
127127
mocks: {
128128
$route: routeMock,
129129
},
130-
stubs: {
131-
ListViewIcon: {
132-
template: '<i class="list-view-icon" />',
133-
},
134-
},
135130
},
136131
})
137132
}
@@ -145,6 +140,7 @@ describe('FilesList.vue rendering rules', () => {
145140

146141
expect(wrapper.vm.mdiFolder).toBeTruthy()
147142
expect(wrapper.vm.mdiViewGrid).toBeTruthy()
143+
expect(wrapper.vm.mdiViewList).toBeTruthy()
148144
})
149145

150146
it('shows empty-state request action when user can request sign', async () => {
@@ -193,4 +189,17 @@ describe('FilesList.vue rendering rules', () => {
193189
const iconWithPath = wrapper.findAll('.nc-icon').find((node) => !!node.attributes('data-path'))
194190
expect(iconWithPath?.attributes('data-path')).toBe(wrapper.vm.mdiViewGrid)
195191
})
192+
193+
it('renders list toggle icon path when in grid mode', async () => {
194+
const filesStore = useFilesStore()
195+
const userConfigStore = useUserConfigStore()
196+
vi.spyOn(filesStore, 'getAllFiles').mockResolvedValue({})
197+
userConfigStore.files_list_grid_view = true
198+
199+
const wrapper = mountComponent()
200+
await flushPromises()
201+
202+
const iconWithPath = wrapper.findAll('.nc-icon').find((node) => !!node.attributes('data-path'))
203+
expect(iconWithPath?.attributes('data-path')).toBe(wrapper.vm.mdiViewList)
204+
})
196205
})

src/views/FilesList/FileEntry/FileEntryStatus.vue

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,23 @@ export default {
5252
--chip-size: 24px;
5353
--chip-radius: 12px;
5454
55-
display: inline-block;
55+
display: inline-flex;
56+
align-items: center;
5657
min-height: var(--chip-size);
5758
max-width: 100%;
58-
padding: 4px 12px;
59+
padding: 4px 10px;
5960
border-radius: var(--chip-radius);
6061
line-height: 1.3;
6162
text-align: center;
62-
white-space: pre-wrap;
63-
word-wrap: break-word;
64-
overflow-wrap: break-word;
65-
hyphens: auto;
63+
white-space: nowrap;
6664
vertical-align: middle;
6765
6866
&__text {
6967
display: inline-block;
7068
max-width: 100%;
71-
white-space: pre-wrap;
72-
word-wrap: break-word;
73-
overflow-wrap: break-word;
69+
white-space: nowrap;
70+
overflow: hidden;
71+
text-overflow: ellipsis;
7472
}
7573
7674
&--error {

src/views/FilesList/FilesList.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
variant="tertiary"
3232
@click="toggleGridView">
3333
<template #icon>
34-
<ListViewIcon v-if="userConfigStore.files_list_grid_view" />
35-
<NcIconSvgWrapper :path="mdiViewGrid" v-else />
34+
<NcIconSvgWrapper v-if="userConfigStore.files_list_grid_view" :path="mdiViewList" />
35+
<NcIconSvgWrapper v-else :path="mdiViewGrid" />
3636
</template>
3737
</NcButton>
3838
</div>
@@ -77,6 +77,7 @@ import HomeSvg from '@mdi/svg/svg/home.svg?raw'
7777
import {
7878
mdiFolder,
7979
mdiViewGrid,
80+
mdiViewList,
8081
} from '@mdi/js'
8182
8283
import NcAppContent from '@nextcloud/vue/components/NcAppContent'
@@ -120,6 +121,7 @@ export default {
120121
sidebarStore,
121122
mdiFolder,
122123
mdiViewGrid,
124+
mdiViewList,
123125
}
124126
},
125127
data() {

src/views/FilesList/FilesListVirtual.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,11 @@ tbody.files-list__tbody.files-list__tbody--grid {
581581
position: absolute;
582582
top: var(--item-padding);
583583
inset-inline-end: var(--item-padding);
584-
width: var(--clickable-area);
585-
height: var(--clickable-area);
584+
width: auto;
585+
max-width: calc(var(--row-width) - 2 * var(--item-padding));
586+
height: auto;
587+
min-height: var(--clickable-area);
588+
justify-content: flex-end;
586589
}
587590
588591
.files-list__row-signers {

0 commit comments

Comments
 (0)