diff options
author | John Molakvoæ <skjnldsv@protonmail.com> | 2023-08-09 14:59:35 +0200 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2023-08-17 18:56:37 +0200 |
commit | 410f58e43e8db767eaf0b272ab6ffde1841cd6a2 (patch) | |
tree | 5f0d2812ce7cce75b6b72c3652c81f7ae3c26bfd /apps/files/src/components/FilesListTableHeader.vue | |
parent | 998b3a2581fb873b03bcf4dc02eafb19390b3cd6 (diff) | |
download | nextcloud-server-410f58e43e8db767eaf0b272ab6ffde1841cd6a2.tar.gz nextcloud-server-410f58e43e8db767eaf0b272ab6ffde1841cd6a2.zip |
chore(files): add Headers, remove legacy methods and cleanup
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files/src/components/FilesListTableHeader.vue')
-rw-r--r-- | apps/files/src/components/FilesListTableHeader.vue | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/apps/files/src/components/FilesListTableHeader.vue b/apps/files/src/components/FilesListTableHeader.vue new file mode 100644 index 00000000000..52060d2589e --- /dev/null +++ b/apps/files/src/components/FilesListTableHeader.vue @@ -0,0 +1,213 @@ +<!-- + - @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + - + - @author John Molakvoæ <skjnldsv@protonmail.com> + - + - @license GNU AGPL version 3 or any later version + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - + --> +<template> + <tr class="files-list__row-head"> + <th class="files-list__column files-list__row-checkbox"> + <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" + @click.stop.prevent="toggleSortBy('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"> + <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"> + <FilesListTableHeaderButton :name="t('files', 'Modified')" mode="mtime" /> + </th> + + <!-- Custom views columns --> + <th v-for="column in columns" + :key="column.id" + :class="classForColumn(column)"> + <FilesListTableHeaderButton v-if="!!column.sort" :name="column.title" :mode="column.id" /> + <span v-else> + {{ column.title }} + </span> + </th> + </template> + </tr> +</template> + +<script lang="ts"> +import { translate } from '@nextcloud/l10n' +import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' +import Vue from 'vue' + +import { useFilesStore } from '../store/files.ts' +import { useSelectionStore } from '../store/selection.ts' +import FilesListTableHeaderActions from './FilesListTableHeaderActions.vue' +import FilesListTableHeaderButton from './FilesListTableHeaderButton.vue' +import filesSortingMixin from '../mixins/filesSorting.ts' +import logger from '../logger.js' + +export default Vue.extend({ + name: 'FilesListTableHeader', + + components: { + FilesListTableHeaderButton, + NcCheckboxRadioSwitch, + FilesListTableHeaderActions, + }, + + mixins: [ + filesSortingMixin, + ], + + props: { + isMtimeAvailable: { + type: Boolean, + default: false, + }, + isSizeAvailable: { + type: Boolean, + default: false, + }, + nodes: { + type: Array, + required: true, + }, + filesListWidth: { + type: Number, + default: 0, + }, + }, + + setup() { + const filesStore = useFilesStore() + const selectionStore = useSelectionStore() + return { + filesStore, + selectionStore, + } + }, + + computed: { + currentView() { + return this.$navigation.active + }, + + columns() { + // Hide columns if the list is too small + if (this.filesListWidth < 512) { + return [] + } + return this.currentView?.columns || [] + }, + + dir() { + // Remove any trailing slash but leave root slash + return (this.$route?.query?.dir || '/').replace(/^(.+)\/$/, '$1') + }, + + selectAllBind() { + const label = this.isNoneSelected || this.isSomeSelected + ? this.t('files', 'Select all') + : this.t('files', 'Unselect all') + return { + 'aria-label': label, + checked: this.isAllSelected, + indeterminate: this.isSomeSelected, + title: label, + } + }, + + selectedNodes() { + return this.selectionStore.selected + }, + + isAllSelected() { + return this.selectedNodes.length === this.nodes.length + }, + + isNoneSelected() { + return this.selectedNodes.length === 0 + }, + + isSomeSelected() { + return !this.isAllSelected && !this.isNoneSelected + }, + }, + + methods: { + classForColumn(column) { + return { + 'files-list__column': true, + 'files-list__column--sortable': !!column.sort, + 'files-list__row-column-custom': true, + [`files-list__row-${this.currentView.id}-${column.id}`]: true, + } + }, + + onToggleAll(selected) { + if (selected) { + const selection = this.nodes.map(node => node.fileid.toString()) + logger.debug('Added all nodes to selection', { selection }) + this.selectionStore.setLastIndex(null) + this.selectionStore.set(selection) + } else { + logger.debug('Cleared selection') + this.selectionStore.reset() + } + }, + + t: translate, + }, +}) +</script> + +<style scoped lang="scss"> +.files-list__column { + user-select: none; + // Make sure the cell colors don't apply to column headers + color: var(--color-text-maxcontrast) !important; + + &--sortable { + cursor: pointer; + } +} + +</style> |