diff options
Diffstat (limited to 'apps/files/src/components/FilesListHeader.vue')
-rw-r--r-- | apps/files/src/components/FilesListHeader.vue | 205 |
1 files changed, 31 insertions, 174 deletions
diff --git a/apps/files/src/components/FilesListHeader.vue b/apps/files/src/components/FilesListHeader.vue index d36c9dd46a6..74dc224a39b 100644 --- a/apps/files/src/components/FilesListHeader.vue +++ b/apps/files/src/components/FilesListHeader.vue @@ -20,194 +20,51 @@ - --> <template> - <tr> - <th class="files-list__column files-list__row-checkbox"> - <NcCheckboxRadioSwitch v-bind="selectAllBind" @update:checked="onToggleAll" /> - </th> - - <!-- Actions multiple if some are selected --> - <FilesListHeaderActions 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 --> - <FilesListHeaderButton :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"> - <FilesListHeaderButton :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"> - <FilesListHeaderButton :name="t('files', 'Modified')" mode="mtime" /> - </th> - - <!-- Custom views columns --> - <th v-for="column in columns" - :key="column.id" - :class="classForColumn(column)"> - <FilesListHeaderButton v-if="!!column.sort" :name="column.title" :mode="column.id" /> - <span v-else> - {{ column.title }} - </span> - </th> - </template> - </tr> + <div v-show="enabled" :class="`files-list__header-${header.id}`"> + <span ref="mount" /> + </div> </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 FilesListHeaderActions from './FilesListHeaderActions.vue' -import FilesListHeaderButton from './FilesListHeaderButton.vue' -import filesSortingMixin from '../mixins/filesSorting.ts' -import logger from '../logger.js' - -export default Vue.extend({ +/** + * This component is used to render custom + * elements provided by an API. Vue doesn't allow + * to directly render an HTMLElement, so we can do + * this magic here. + */ +export default { name: 'FilesListHeader', - - components: { - FilesListHeaderButton, - NcCheckboxRadioSwitch, - FilesListHeaderActions, - }, - - mixins: [ - filesSortingMixin, - ], - props: { - isMtimeAvailable: { - type: Boolean, - default: false, - }, - isSizeAvailable: { - type: Boolean, - default: false, + header: { + type: Object, + required: true, }, - nodes: { - type: Array, + currentFolder: { + type: Object, required: true, }, - filesListWidth: { - type: Number, - default: 0, + currentView: { + type: Object, + required: true, }, }, - - 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 + enabled() { + console.debug('Enabled', this.header.id) + return this.header.enabled(this.currentFolder, this.currentView) }, }, - - 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() + watch: { + enabled(enabled) { + if (!enabled) { + return } + this.header.updated(this.currentFolder, this.currentView) }, - - 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; - } + mounted() { + console.debug('Mounted', this.header.id) + this.header.render(this.$refs.mount, this.currentFolder, this.currentView) + }, } - -</style> +</script> |