aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/src/components/FilesListTableHeader.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/src/components/FilesListTableHeader.vue')
-rw-r--r--apps/files/src/components/FilesListTableHeader.vue89
1 files changed, 53 insertions, 36 deletions
diff --git a/apps/files/src/components/FilesListTableHeader.vue b/apps/files/src/components/FilesListTableHeader.vue
index 148ce3bc4e5..23e631199eb 100644
--- a/apps/files/src/components/FilesListTableHeader.vue
+++ b/apps/files/src/components/FilesListTableHeader.vue
@@ -1,29 +1,12 @@
<!--
- - @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
- -
- - @author John Molakvoæ <skjnldsv@protonmail.com>
- -
- - @license AGPL-3.0-or-later
- -
- - 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/>.
- -
- -->
+ - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
<template>
<tr class="files-list__row-head">
<th class="files-list__column files-list__row-checkbox"
@keyup.esc.exact="resetSelection">
- <NcCheckboxRadioSwitch v-bind="selectAllBind" @update:checked="onToggleAll" />
+ <NcCheckboxRadioSwitch v-bind="selectAllBind" data-cy-files-list-selection-checkbox @update:checked="onToggleAll" />
</th>
<!-- Columns display -->
@@ -41,6 +24,14 @@
<!-- Actions -->
<th class="files-list__row-actions" />
+ <!-- Mime -->
+ <th v-if="isMimeAvailable"
+ class="files-list__column files-list__row-mime"
+ :class="{ 'files-list__column--sortable': isMimeAvailable }"
+ :aria-sort="ariaSortForMode('mime')">
+ <FilesListTableHeaderButton :name="t('files', 'File type')" mode="mime" />
+ </th>
+
<!-- Size -->
<th v-if="isSizeAvailable"
class="files-list__column files-list__row-size"
@@ -71,24 +62,28 @@
</template>
<script lang="ts">
+import type { Node } from '@nextcloud/files'
+import type { PropType } from 'vue'
+import type { FileSource } from '../types.ts'
+
import { translate as t } from '@nextcloud/l10n'
-import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
-import Vue from 'vue'
+import { useHotKey } from '@nextcloud/vue/composables/useHotKey'
+import { defineComponent } from 'vue'
+import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
import { useFilesStore } from '../store/files.ts'
+import { useNavigation } from '../composables/useNavigation'
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'
+import logger from '../logger.ts'
-export default Vue.extend({
+export default defineComponent({
name: 'FilesListTableHeader',
components: {
FilesListTableHeaderButton,
NcCheckboxRadioSwitch,
- FilesListTableHeaderActions,
},
mixins: [
@@ -96,6 +91,10 @@ export default Vue.extend({
],
props: {
+ isMimeAvailable: {
+ type: Boolean,
+ default: false,
+ },
isMtimeAvailable: {
type: Boolean,
default: false,
@@ -105,7 +104,7 @@ export default Vue.extend({
default: false,
},
nodes: {
- type: Array,
+ type: Array as PropType<Node[]>,
required: true,
},
filesListWidth: {
@@ -117,17 +116,17 @@ export default Vue.extend({
setup() {
const filesStore = useFilesStore()
const selectionStore = useSelectionStore()
+ const { currentView } = useNavigation()
+
return {
filesStore,
selectionStore,
+
+ currentView,
}
},
computed: {
- currentView() {
- return this.$navigation.active
- },
-
columns() {
// Hide columns if the list is too small
if (this.filesListWidth < 512) {
@@ -168,8 +167,23 @@ export default Vue.extend({
},
},
+ created() {
+ // ctrl+a selects all
+ useHotKey('a', this.onToggleAll, {
+ ctrl: true,
+ stop: true,
+ prevent: true,
+ })
+
+ // Escape key cancels selection
+ useHotKey('Escape', this.resetSelection, {
+ stop: true,
+ prevent: true,
+ })
+ },
+
methods: {
- ariaSortForMode(mode: string): ARIAMixin['ariaSort'] {
+ ariaSortForMode(mode: string): 'ascending'|'descending'|null {
if (this.sortingMode === mode) {
return this.isAscSorting ? 'ascending' : 'descending'
}
@@ -181,13 +195,13 @@ export default Vue.extend({
'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,
+ [`files-list__row-${this.currentView?.id}-${column.id}`]: true,
}
},
- onToggleAll(selected) {
+ onToggleAll(selected = true) {
if (selected) {
- const selection = this.nodes.map(node => node.fileid.toString())
+ const selection = this.nodes.map(node => node.source).filter(Boolean) as FileSource[]
logger.debug('Added all nodes to selection', { selection })
this.selectionStore.setLastIndex(null)
this.selectionStore.set(selection)
@@ -198,6 +212,9 @@ export default Vue.extend({
},
resetSelection() {
+ if (this.isNoneSelected) {
+ return
+ }
this.selectionStore.reset()
},