<NcCheckboxRadioSwitch v-bind="selectAllBind" @update:checked="onToggleAll" />
</th>
- <!-- Actions multiple if some are selected -->
- <FilesListTableHeaderActions v-if="!isNoneSelected"
- :current-view="currentView"
- :selected-nodes="selectedNodes" />
-
<!-- Columns display -->
- <template v-else>
- <!-- Link to file -->
- <th class="files-list__column files-list__row-name files-list__column--sortable"
- :aria-sort="ariaSortForMode('basename')">
- <!-- Icon or preview -->
- <span class="files-list__row-icon" />
-
- <!-- Name -->
- <FilesListTableHeaderButton :name="t('files', 'Name')" mode="basename" />
- </th>
-
- <!-- Actions -->
- <th class="files-list__row-actions" />
-
- <!-- Size -->
- <th v-if="isSizeAvailable"
- :class="{'files-list__column--sortable': isSizeAvailable}"
- class="files-list__column files-list__row-size"
- :aria-sort="ariaSortForMode('size')">
- <FilesListTableHeaderButton :name="t('files', 'Size')" mode="size" />
- </th>
-
- <!-- Mtime -->
- <th v-if="isMtimeAvailable"
- :class="{'files-list__column--sortable': isMtimeAvailable}"
- class="files-list__column files-list__row-mtime"
- :aria-sort="ariaSortForMode('mtime')">
- <FilesListTableHeaderButton :name="t('files', 'Modified')" mode="mtime" />
- </th>
-
- <!-- Custom views columns -->
- <th v-for="column in columns"
- :key="column.id"
- :class="classForColumn(column)"
- :aria-sort="ariaSortForMode(column.id)">
- <FilesListTableHeaderButton v-if="!!column.sort" :name="column.title" :mode="column.id" />
- <span v-else>
- {{ column.title }}
- </span>
- </th>
- </template>
+
+ <!-- Link to file -->
+ <th class="files-list__column files-list__row-name files-list__column--sortable"
+ :aria-sort="ariaSortForMode('basename')">
+ <!-- Icon or preview -->
+ <span class="files-list__row-icon" />
+
+ <!-- Name -->
+ <FilesListTableHeaderButton :name="t('files', 'Name')" mode="basename" />
+ </th>
+
+ <!-- Actions -->
+ <th class="files-list__row-actions" />
+
+ <!-- Size -->
+ <th v-if="isSizeAvailable"
+ class="files-list__column files-list__row-size"
+ :class="{ 'files-list__column--sortable': isSizeAvailable }"
+ :aria-sort="ariaSortForMode('size')">
+ <FilesListTableHeaderButton :name="t('files', 'Size')" mode="size" />
+ </th>
+
+ <!-- Mtime -->
+ <th v-if="isMtimeAvailable"
+ class="files-list__column files-list__row-mtime"
+ :class="{ 'files-list__column--sortable': isMtimeAvailable }"
+ :aria-sort="ariaSortForMode('mtime')">
+ <FilesListTableHeaderButton :name="t('files', 'Modified')" mode="mtime" />
+ </th>
+
+ <!-- Custom views columns -->
+ <th v-for="column in columns"
+ :key="column.id"
+ :class="classForColumn(column)"
+ :aria-sort="ariaSortForMode(column.id)">
+ <FilesListTableHeaderButton v-if="!!column.sort" :name="column.title" :mode="column.id" />
+ <span v-else>
+ {{ column.title }}
+ </span>
+ </th>
</tr>
</template>
}"
:scroll-to-index="scrollToIndex"
:caption="caption">
+ <template v-if="!isNoneSelected" #header-overlay>
+ <FilesListTableHeaderActions :current-view="currentView"
+ :selected-nodes="selectedNodes" />
+ </template>
+
<template #before>
<!-- Headers -->
<FilesListHeader v-for="header in sortedHeaders"
import { action as sidebarAction } from '../actions/sidebarAction.ts'
import { useUserConfigStore } from '../store/userconfig.ts'
+import { useSelectionStore } from '../store/selection.js'
import FileEntry from './FileEntry.vue'
import FileEntryGrid from './FileEntryGrid.vue'
import filesListWidthMixin from '../mixins/filesListWidth.ts'
import VirtualList from './VirtualList.vue'
import logger from '../logger.js'
+import FilesListTableHeaderActions from './FilesListTableHeaderActions.vue'
export default defineComponent({
name: 'FilesListVirtual',
FilesListTableFooter,
FilesListTableHeader,
VirtualList,
+ FilesListTableHeaderActions,
},
mixins: [
setup() {
const userConfigStore = useUserConfigStore()
+ const selectionStore = useSelectionStore()
return {
userConfigStore,
+ selectionStore,
}
},
const virtualListNote = t('files', 'This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list.')
return `${viewCaption}\n${sortableCaption}\n${virtualListNote}`
},
+
+ selectedNodes() {
+ return this.selectionStore.selected
+ },
+
+ isNoneSelected() {
+ return this.selectedNodes.length === 0
+ },
},
watch: {
--clickable-area: 44px;
--icon-preview-size: 32px;
+ position: relative;
overflow: auto;
height: 100%;
will-change: scroll-position;
display: block;
}
+ .files-list__thead-overlay {
+ position: absolute;
+ top: 0;
+ left: var(--row-height); // Save space for a row checkbox
+ right: 0;
+ z-index: 1000;
+
+ display: flex;
+ align-items: center;
+
+ // Reuse row styles
+ background-color: var(--color-main-background);
+ border-bottom: 1px solid var(--color-border);
+ height: var(--row-height);
+ }
+
.files-list__thead,
.files-list__tfoot {
display: flex;