diff options
author | John Molakvoæ <skjnldsv@protonmail.com> | 2023-07-13 09:58:24 +0200 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2023-08-01 16:38:06 +0200 |
commit | 38480fda3cd1f10652bc1e854207b074921e66b8 (patch) | |
tree | c4c9112123f649802c9f86d056fe6da5e89be068 /apps/files/src | |
parent | 385f987a28a535e8b6b0020693daa5347093c186 (diff) | |
download | nextcloud-server-38480fda3cd1f10652bc1e854207b074921e66b8.tar.gz nextcloud-server-38480fda3cd1f10652bc1e854207b074921e66b8.zip |
feat(files_external): migrate to vue
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files/src')
-rw-r--r-- | apps/files/src/components/CustomElementRender.vue | 31 | ||||
-rw-r--r-- | apps/files/src/components/FileEntry.vue | 31 | ||||
-rw-r--r-- | apps/files/src/services/FileAction.ts | 2 | ||||
-rw-r--r-- | apps/files/src/views/FilesList.vue | 27 |
4 files changed, 59 insertions, 32 deletions
diff --git a/apps/files/src/components/CustomElementRender.vue b/apps/files/src/components/CustomElementRender.vue index b5bcb8daf2c..62e33b06acf 100644 --- a/apps/files/src/components/CustomElementRender.vue +++ b/apps/files/src/components/CustomElementRender.vue @@ -23,7 +23,7 @@ <span /> </template> -<script> +<script lang="ts"> /** * This component is used to render custom * elements provided by an API. Vue doesn't allow @@ -46,20 +46,29 @@ export default { required: true, }, }, - computed: { - element() { - return this.render(this.source, this.currentView) - }, - }, watch: { - element() { - this.$el.replaceWith(this.element) - this.$el = this.element + source() { + this.updateRootElement() + }, + currentView() { + this.updateRootElement() }, }, mounted() { - this.$el.replaceWith(this.element) - this.$el = this.element + this.updateRootElement() + }, + methods: { + async updateRootElement() { + const span = document.createElement('span') as HTMLSpanElement + this.$el.replaceWith(span) + this.$el = span + + const element = await this.render(this.source, this.currentView) + if (element) { + this.$el.replaceWith(element) + this.$el = element + } + }, }, } </script> diff --git a/apps/files/src/components/FileEntry.vue b/apps/files/src/components/FileEntry.vue index 3257e161046..53928b961c2 100644 --- a/apps/files/src/components/FileEntry.vue +++ b/apps/files/src/components/FileEntry.vue @@ -91,8 +91,12 @@ <!-- Actions --> <td v-show="!isRenamingSmallScreen" :class="`files-list__row-actions-${uniqueId}`" class="files-list__row-actions"> - <!-- Inline actions --> - <!-- TODO: implement CustomElementRender --> + <!-- Render actions --> + <CustomElementRender v-for="action in enabledRenderActions" + :key="action.id" + :current-view="currentView" + :render="action.renderInline" + :source="source" /> <!-- Menu actions --> <NcActions v-if="active" @@ -301,15 +305,16 @@ export default Vue.extend({ return formatFileSize(size, true) }, sizeOpacity() { - const size = parseInt(this.source.size, 10) || 0 - if (!size || size < 0) { - return 1 - } - // Whatever theme is active, the contrast will pass WCAG AA // with color main text over main background and an opacity of 0.7 const minOpacity = 0.7 const maxOpacitySize = 10 * 1024 * 1024 + + const size = parseInt(this.source.size, 10) || 0 + if (!size || size < 0) { + return minOpacity + } + return minOpacity + (1 - minOpacity) * Math.pow((this.source.size / maxOpacitySize), 2) }, @@ -396,9 +401,17 @@ export default Vue.extend({ return this.enabledActions.filter(action => action?.inline?.(this.source, this.currentView)) }, + // Enabled action that are displayed inline with a custom render function + enabledRenderActions() { + if (!this.active) { + return [] + } + return this.enabledActions.filter(action => typeof action.renderInline === 'function') + }, + // Default actions enabledDefaultActions() { - return this.enabledActions.filter(action => !!action.default) + return this.enabledActions.filter(action => !!action?.default) }, // Actions shown in the menu @@ -407,7 +420,7 @@ export default Vue.extend({ // Showing inline first for the NcActions inline prop ...this.enabledInlineActions, // Then the rest - ...this.enabledActions.filter(action => action.default !== DefaultType.HIDDEN), + ...this.enabledActions.filter(action => action.default !== DefaultType.HIDDEN && typeof action.renderInline !== 'function'), ].filter((value, index, self) => { // Then we filter duplicates to prevent inline actions to be shown twice return index === self.findIndex(action => action.id === value.id) diff --git a/apps/files/src/services/FileAction.ts b/apps/files/src/services/FileAction.ts index 4798128671c..a4f7e3ddf17 100644 --- a/apps/files/src/services/FileAction.ts +++ b/apps/files/src/services/FileAction.ts @@ -74,7 +74,7 @@ interface FileActionData { * If defined, the returned html element will be * appended before the actions menu. */ - renderInline?: (file: Node, view: Navigation) => HTMLElement, + renderInline?: (file: Node, view: Navigation) => Promise<HTMLElement | null>, } export class FileAction { diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue index b14e3287939..99d7767ebc7 100644 --- a/apps/files/src/views/FilesList.vue +++ b/apps/files/src/views/FilesList.vue @@ -183,19 +183,24 @@ export default Vue.extend({ return this.isAscSorting ? results : results.reverse() } + const identifiers = [ + // Sort favorites first if enabled + ...this.userConfig.sort_favorites_first ? [v => v.attributes?.favorite !== 1] : [], + // Sort folders first if sorting by name + ...this.sortingMode === 'basename' ? [v => v.type !== 'folder'] : [], + // Use sorting mode if NOT basename (to be able to use displayName too) + ...this.sortingMode !== 'basename' ? [v => v[this.sortingMode]] : [], + // Use displayName if available, fallback to name + v => v.attributes?.displayName || v.basename, + // Finally, use basename if all previous sorting methods failed + v => v.basename, + ] + const orders = new Array(identifiers.length).fill(this.isAscSorting ? 'asc' : 'desc') + return orderBy( [...(this.currentFolder?._children || []).map(this.getNode).filter(file => file)], - [ - // Sort favorites first if enabled - ...this.userConfig.sort_favorites_first ? [v => v.attributes?.favorite !== 1] : [], - // Sort folders first if sorting by name - ...this.sortingMode === 'basename' ? [v => v.type !== 'folder'] : [], - // Use sorting mode - v => v[this.sortingMode], - // Finally, fallback to name - v => v.basename, - ], - this.isAscSorting ? ['asc', 'asc', 'asc'] : ['desc', 'desc', 'desc'], + identifiers, + orders, ) }, |