Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
29a7f7f
feat(files_trashbin): migrate to vue
skjnldsv Jan 13, 2023
03c3277
feat(files): switch to pinia
skjnldsv Feb 4, 2023
638b3df
perf(files): update files store by chunks
skjnldsv Feb 4, 2023
2ff1c00
fix(files_trashbin): previews crop support
skjnldsv Feb 5, 2023
b761039
perf(files): fetch previews faster and cache properly
skjnldsv Mar 17, 2023
10010fc
feat(files): sorting
skjnldsv Mar 21, 2023
f330813
feat(files): custom columns
skjnldsv Mar 22, 2023
0db210a
chore(deps): cleanup unused deps and audit
skjnldsv Mar 22, 2023
0b4da61
feat(files): actions api
skjnldsv Mar 23, 2023
3c3050c
feat(files): implement sorting per view
skjnldsv Mar 24, 2023
0e764f7
fix(files): fix custom render components reactivity
skjnldsv Mar 24, 2023
0f717d4
feat(accessibility): add files table caption and summary
skjnldsv Mar 24, 2023
e85eb4c
fix(files): selection and render performance
skjnldsv Mar 24, 2023
f28944e
feat(files): propagate restore and delete events
skjnldsv Mar 25, 2023
bda286c
perf(files): less verbose
skjnldsv Mar 25, 2023
6358e97
fix(files): inline action styling
skjnldsv Mar 25, 2023
2b25199
fix(files): accessibility tab into recycled invisible files rows
skjnldsv Mar 25, 2023
7215a9a
fix(files): breadcrumbs accessibility title
skjnldsv Mar 28, 2023
4942747
fix(files): use inline NcActions
skjnldsv Mar 28, 2023
60b74e3
feat(files): batch actions
skjnldsv Mar 28, 2023
044e824
chore(deps): update lockfile
skjnldsv Mar 28, 2023
c7c9ee1
feat(files): move userconfig to dedicated store and fix crop previews
skjnldsv Mar 31, 2023
a66cae0
fix(deps): update webdav 5 usage
skjnldsv Mar 31, 2023
014a57e
fix: improved preview handling
skjnldsv Apr 4, 2023
bdbe477
feat(files): add FileAction service
skjnldsv Apr 4, 2023
904348b
chore(npm): build assets
skjnldsv Apr 4, 2023
1361182
chore(eslint): clean and fix
skjnldsv Apr 4, 2023
f060e5a
fix(tests): update jsunit tests after dep and files update
skjnldsv Apr 4, 2023
d432e0c
fix(cypress): component testing with pinia
skjnldsv Apr 5, 2023
8298bb4
fix:(files-checker): add cypress.d.ts and custom.d.ts
skjnldsv Apr 5, 2023
ea3e77d
fix(files): better wording and catch single action run
skjnldsv Apr 5, 2023
5b3900e
fix(tests): acceptance
skjnldsv Apr 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(accessibility): add files table caption and summary
Signed-off-by: John Molakvoæ <[email protected]>
  • Loading branch information
skjnldsv committed Apr 6, 2023
commit 0f717d408f73e02a0c0555f242936b75845b3a91
9 changes: 3 additions & 6 deletions apps/files/src/components/FileEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,9 @@
<!-- Actions -->
<td :class="`files-list__row-actions-${uniqueId}`" class="files-list__row-actions">
<!-- Inline actions -->
<template v-if="false" v-for="action in enabledInlineActions">
<CustomElementRender v-if="false"
:key="action.id"
:element="action.renderInline(source, currentView)" />
<NcButton v-else
:key="action.id"
<template v-for="action in enabledInlineActions">
<!-- TODO: implement CustomElementRender -->
<NcButton :key="action.id"
type="tertiary"
@click="onActionClick(action)">
<template #icon>
Expand Down
160 changes: 160 additions & 0 deletions apps/files/src/components/FilesListFooter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<!--
- @copyright Copyright (c) 2019 Gary Kim <[email protected]>
-
- @author Gary Kim <[email protected]>
-
- @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>
<th class="files-list__row-checkbox">
<span class="hidden-visually">{{ t('files', 'Total rows summary') }}</span>
</th>

<!-- Link to file -->
<td class="files-list__row-name">
<!-- Icon or preview -->
<span class="files-list__row-icon" />

<!-- Summary -->
<span>{{ summary }}</span>
</td>

<!-- Actions -->
<td class="files-list__row-actions" />

<!-- Size -->
<td v-if="isSizeAvailable" class="files-list__column files-list__row-size">
<span>{{ totalSize }}</span>
</td>

<!-- Custom views columns -->
<th v-for="column in columns"
:key="column.id"
:class="classForColumn(column)">
<span>{{ column.summary?.(nodes, currentView) }}</span>
</th>
</tr>
</template>

<script lang="ts">
import { formatFileSize } from '@nextcloud/files'
import { translate } from '@nextcloud/l10n'
import Vue from 'vue'

import Navigation from '../services/Navigation'
import { useFilesStore } from '../store/files'
import { usePathsStore } from '../store/paths'

export default Vue.extend({
name: 'FilesListFooter',

components: {
},

props: {
isSizeAvailable: {
type: Boolean,
default: false,
},
nodes: {
type: Array,
required: true,
},
summary: {
type: String,
default: '',
},
},

setup() {
const pathsStore = usePathsStore()
const filesStore = useFilesStore()
return {
filesStore,
pathsStore,
}
},

computed: {
currentView() {
return this.$navigation.active
},

dir() {
// Remove any trailing slash but leave root slash
return (this.$route?.query?.dir || '/').replace(/^(.+)\/$/, '$1')
},

currentFolder() {
if (!this.currentView?.id) {
return
}

if (this.dir === '/') {
return this.filesStore.getRoot(this.currentView.id)
}
const fileId = this.pathsStore.getPath(this.currentView.id, this.dir)
return this.filesStore.getNode(fileId)
},

columns() {
return this.currentView?.columns || []
},

totalSize() {
// If we have the size already, let's use it
if (this.currentFolder?.size) {
return formatFileSize(this.currentFolder.size, true)
}

// Otherwise let's compute it
return formatFileSize(this.nodes.reduce((total, node) => total + node.size || 0, 0), true)
},
},

methods: {
classForColumn(column) {
return {
'files-list__row-column-custom': true,
[`files-list__row-${this.currentView.id}-${column.id}`]: true,
}
},

t: translate,
},
})
</script>

<style scoped lang="scss">
@import '../mixins/fileslist-row.scss';

// Scoped row
tr {
padding-bottom: 300px;
border-top: 1px solid var(--color-border);
// Prevent hover effect on the whole row
background-color: transparent !important;
}

td {
user-select: none;
// Make sure the cell colors don't apply to column headers
color: var(--color-text-maxcontrast) !important;
}

</style>
30 changes: 0 additions & 30 deletions apps/files/src/components/FilesListHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@
<script lang="ts">
import { mapState } from 'pinia'
import { translate } from '@nextcloud/l10n'
import MenuDown from 'vue-material-design-icons/MenuDown.vue'
import MenuUp from 'vue-material-design-icons/MenuUp.vue'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import Vue from 'vue'

Expand Down Expand Up @@ -168,16 +165,6 @@ export default Vue.extend({
}
},

sortAriaLabel(column) {
const direction = this.isAscSorting
? this.t('files', 'ascending')
: this.t('files', 'descending')
return this.t('files', 'Sort list by {column} ({direction})', {
column,
direction,
})
},

onToggleAll(selected) {
if (selected) {
const selection = this.nodes.map(node => node.attributes.fileid.toString())
Expand All @@ -189,23 +176,6 @@ export default Vue.extend({
}
},

toggleSortBy(key) {
// If we're already sorting by this key, flip the direction
if (this.sortingMode === key) {
this.sortingStore.toggleSortingDirection(this.currentView.id)
return
}
// else sort ASC by this new key
this.sortingStore.setSortingBy(key, this.currentView.id)
},

toggleSortByCustomColumn(column) {
if (!column.sort) {
return
}
this.toggleSortBy(column.id)
},

t: translate,
},
})
Expand Down
24 changes: 18 additions & 6 deletions apps/files/src/components/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,20 @@
<FileEntry :is-size-available="isSizeAvailable" :source="item" />
</template>

<!-- <template #before>
<caption v-show="false" class="files-list__caption">
{{ summary }}
<template #before>
<!-- Accessibility description -->
<caption class="hidden-visually">
{{ currentView.caption || '' }}
{{ t('files', 'This list is not fully rendered for performances reasons. The files will be rendered as you navigate through the list.') }}
</caption>
</template> -->

<template #before>
<FilesListHeader :nodes="nodes" :is-size-available="isSizeAvailable" />
<!-- Thead-->
<FilesListHeader :is-size-available="isSizeAvailable" :nodes="nodes" />
</template>

<template #after>
<!-- Tfoot-->
<FilesListFooter :is-size-available="isSizeAvailable" :nodes="nodes" :summary="summary" />
</template>
</RecycleScroller>
</template>
Expand All @@ -54,6 +60,7 @@ import Vue from 'vue'

import FileEntry from './FileEntry.vue'
import FilesListHeader from './FilesListHeader.vue'
import FilesListFooter from './FilesListFooter.vue'

export default Vue.extend({
name: 'FilesListVirtual',
Expand All @@ -62,9 +69,14 @@ export default Vue.extend({
RecycleScroller,
FileEntry,
FilesListHeader,
FilesListFooter,
},

props: {
currentView: {
type: Object,
required: true,
},
nodes: {
type: Array,
required: true,
Expand Down
2 changes: 1 addition & 1 deletion apps/files/src/services/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface Column {
sort?: (nodeA: Node, nodeB: Node) => number
/** Custom summary of the column to display at the end of the list.
Will not be displayed if nothing is provided */
summary?: (node: Node[]) => string
summary?: (node: Node[], view: Navigation) => string
}

export interface Navigation {
Expand Down
5 changes: 4 additions & 1 deletion apps/files/src/views/FilesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@
</NcEmptyContent>

<!-- File list -->
<FilesListVirtual v-else ref="filesListVirtual" :nodes="dirContents" />
<FilesListVirtual v-else
ref="filesListVirtual"
:current-view="currentView"
:nodes="dirContents" />
</NcAppContent>
</template>

Expand Down
1 change: 1 addition & 0 deletions apps/files_trashbin/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const Navigation = window.OCP.Files.Navigation as NavigationService
Navigation.register({
id: 'trashbin',
name: t('files_trashbin', 'Deleted files'),
caption: t('files_trashbin', 'List of files that have been deleted.'),

icon: DeleteSvg,
order: 50,
Expand Down