From a7f75f9832287c3768c6df7f3388a0baa54ad3ef Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:27:33 -0300
Subject: [PATCH 1/5] fix(files-list): replace missing ListViewIcon with
NcIconSvgWrapper using mdiViewList
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
src/views/FilesList/FilesList.vue | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/views/FilesList/FilesList.vue b/src/views/FilesList/FilesList.vue
index 68e40dfc63..2c8a1a8d4f 100644
--- a/src/views/FilesList/FilesList.vue
+++ b/src/views/FilesList/FilesList.vue
@@ -31,8 +31,8 @@
variant="tertiary"
@click="toggleGridView">
-
-
+
+
@@ -77,6 +77,7 @@ import HomeSvg from '@mdi/svg/svg/home.svg?raw'
import {
mdiFolder,
mdiViewGrid,
+ mdiViewList,
} from '@mdi/js'
import NcAppContent from '@nextcloud/vue/components/NcAppContent'
@@ -120,6 +121,7 @@ export default {
sidebarStore,
mdiFolder,
mdiViewGrid,
+ mdiViewList,
}
},
data() {
From 2f9874bd3f92e62c6cafa36f8ee11bad01b395cd Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:27:33 -0300
Subject: [PATCH 2/5] fix(files-list): prevent status chip text from wrapping
vertically
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
.../FilesList/FileEntry/FileEntryStatus.vue | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/views/FilesList/FileEntry/FileEntryStatus.vue b/src/views/FilesList/FileEntry/FileEntryStatus.vue
index d12d574a58..047ed553ed 100644
--- a/src/views/FilesList/FileEntry/FileEntryStatus.vue
+++ b/src/views/FilesList/FileEntry/FileEntryStatus.vue
@@ -52,25 +52,23 @@ export default {
--chip-size: 24px;
--chip-radius: 12px;
- display: inline-block;
+ display: inline-flex;
+ align-items: center;
min-height: var(--chip-size);
max-width: 100%;
- padding: 4px 12px;
+ padding: 4px 10px;
border-radius: var(--chip-radius);
line-height: 1.3;
text-align: center;
- white-space: pre-wrap;
- word-wrap: break-word;
- overflow-wrap: break-word;
- hyphens: auto;
+ white-space: nowrap;
vertical-align: middle;
&__text {
display: inline-block;
max-width: 100%;
- white-space: pre-wrap;
- word-wrap: break-word;
- overflow-wrap: break-word;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
&--error {
From ff49dad2dababb200b2232b64433d07c9f41b6be Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:27:33 -0300
Subject: [PATCH 3/5] fix(files-list): allow status chip to expand width in
grid view mode
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
src/views/FilesList/FilesListVirtual.vue | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/views/FilesList/FilesListVirtual.vue b/src/views/FilesList/FilesListVirtual.vue
index 8598510227..b88335da39 100644
--- a/src/views/FilesList/FilesListVirtual.vue
+++ b/src/views/FilesList/FilesListVirtual.vue
@@ -581,8 +581,11 @@ tbody.files-list__tbody.files-list__tbody--grid {
position: absolute;
top: var(--item-padding);
inset-inline-end: var(--item-padding);
- width: var(--clickable-area);
- height: var(--clickable-area);
+ width: auto;
+ max-width: calc(var(--row-width) - 2 * var(--item-padding));
+ height: auto;
+ min-height: var(--clickable-area);
+ justify-content: flex-end;
}
.files-list__row-signers {
From aaf2a2dd2fbf8064b907dbb3ee64000b07101d8b Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:27:34 -0300
Subject: [PATCH 4/5] test(files-list): update grid toggle icon tests and
remove obsolete ListViewIcon stub
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
src/tests/views/FilesList/FilesList.spec.ts | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/tests/views/FilesList/FilesList.spec.ts b/src/tests/views/FilesList/FilesList.spec.ts
index 802059efbf..0703bf671a 100644
--- a/src/tests/views/FilesList/FilesList.spec.ts
+++ b/src/tests/views/FilesList/FilesList.spec.ts
@@ -127,11 +127,6 @@ describe('FilesList.vue rendering rules', () => {
mocks: {
$route: routeMock,
},
- stubs: {
- ListViewIcon: {
- template: '',
- },
- },
},
})
}
@@ -145,6 +140,7 @@ describe('FilesList.vue rendering rules', () => {
expect(wrapper.vm.mdiFolder).toBeTruthy()
expect(wrapper.vm.mdiViewGrid).toBeTruthy()
+ expect(wrapper.vm.mdiViewList).toBeTruthy()
})
it('shows empty-state request action when user can request sign', async () => {
@@ -193,4 +189,17 @@ describe('FilesList.vue rendering rules', () => {
const iconWithPath = wrapper.findAll('.nc-icon').find((node) => !!node.attributes('data-path'))
expect(iconWithPath?.attributes('data-path')).toBe(wrapper.vm.mdiViewGrid)
})
+
+ it('renders list toggle icon path when in grid mode', async () => {
+ const filesStore = useFilesStore()
+ const userConfigStore = useUserConfigStore()
+ vi.spyOn(filesStore, 'getAllFiles').mockResolvedValue({})
+ userConfigStore.files_list_grid_view = true
+
+ const wrapper = mountComponent()
+ await flushPromises()
+
+ const iconWithPath = wrapper.findAll('.nc-icon').find((node) => !!node.attributes('data-path'))
+ expect(iconWithPath?.attributes('data-path')).toBe(wrapper.vm.mdiViewList)
+ })
})
From 16eff36126a5536409a45a8ec327f7cca258e237 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:27:34 -0300
Subject: [PATCH 5/5] test(files-list): add FileEntryStatus unit tests
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
.../views/FilesList/FileEntryStatus.spec.ts | 61 +++++++++++++++++++
1 file changed, 61 insertions(+)
create mode 100644 src/tests/views/FilesList/FileEntryStatus.spec.ts
diff --git a/src/tests/views/FilesList/FileEntryStatus.spec.ts b/src/tests/views/FilesList/FileEntryStatus.spec.ts
new file mode 100644
index 0000000000..d1e3e90464
--- /dev/null
+++ b/src/tests/views/FilesList/FileEntryStatus.spec.ts
@@ -0,0 +1,61 @@
+/**
+ * SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { describe, expect, it } from 'vitest'
+import { mount } from '@vue/test-utils'
+
+import FileEntryStatus from '../../../views/FilesList/FileEntry/FileEntryStatus.vue'
+
+function mountStatus(props: { status: number; statusText: string; signers?: unknown[] }) {
+ return mount(FileEntryStatus, {
+ props: {
+ signers: [],
+ ...props,
+ },
+ })
+}
+
+describe('FileEntryStatus.vue', () => {
+ it('renders nothing when statusText is "none"', () => {
+ const wrapper = mountStatus({ status: 0, statusText: 'none' })
+ expect(wrapper.find('.status-chip').exists()).toBe(false)
+ })
+
+ it('renders chip when statusText is not "none"', () => {
+ const wrapper = mountStatus({ status: 3, statusText: 'Signed' })
+ expect(wrapper.find('.status-chip').exists()).toBe(true)
+ })
+
+ it('displays the statusText inside the chip', () => {
+ const wrapper = mountStatus({ status: 3, statusText: 'Signed' })
+ expect(wrapper.find('.status-chip__text').text()).toBe('Signed')
+ })
+
+ it.each([
+ { status: -1, expected: 'status-chip--not-libresign' },
+ { status: 0, expected: 'status-chip--draft' },
+ { status: 1, expected: 'status-chip--available' },
+ { status: 2, expected: 'status-chip--partial' },
+ { status: 3, expected: 'status-chip--signed' },
+ { status: 4, expected: 'status-chip--deleted' },
+ { status: 5, expected: 'status-chip--signing' },
+ ])('applies variant class "$expected" for status $status', ({ status, expected }) => {
+ const wrapper = mountStatus({ status, statusText: 'any' })
+ expect(wrapper.find('.status-chip').classes()).toContain(expected)
+ })
+
+ it('falls back to draft variant for unknown status', () => {
+ const wrapper = mountStatus({ status: 99, statusText: 'Unknown' })
+ expect(wrapper.find('.status-chip').classes()).toContain('status-chip--draft')
+ })
+
+ it('chip does not apply any inline style that would override the nowrap fix', () => {
+ const wrapper = mountStatus({ status: 3, statusText: 'Signed' })
+ const chip = wrapper.find('.status-chip')
+ // white-space is controlled by scoped CSS (nowrap); no inline style should override it
+ expect(chip.exists()).toBe(true)
+ expect(chip.attributes('style')).toBeUndefined()
+ })
+})