summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2019-11-21 13:35:08 +0100
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2019-11-21 13:35:08 +0100
commit68ed13a6ce7e2f12194ba94f07c07aa88a69cdfa (patch)
tree6b4d505add09e9444fd471a227a827611fc6e50e
parent4174c7bea696a4d65653ab95b127a4331c66e794 (diff)
Tagging listing #1 & merging folder/tag component
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r--src/components/Folder.vue84
-rw-r--r--src/components/FolderTagPreview.vue237
-rw-r--r--src/components/Tag.vue106
-rw-r--r--src/patchedRequest.js6
-rw-r--r--src/services/AlbumContent.js3
-rw-r--r--src/services/FileList.js2
-rw-r--r--src/services/TaggedImages.js99
-rw-r--r--src/store/files.js15
-rw-r--r--src/store/systemtags.js3
-rw-r--r--src/views/Albums.vue5
-rw-r--r--src/views/EmptyContent.vue3
-rw-r--r--src/views/Tags.vue32
12 files changed, 499 insertions, 96 deletions
diff --git a/src/components/Folder.vue b/src/components/Folder.vue
index cd19d6ed..df1929de 100644
--- a/src/components/Folder.vue
+++ b/src/components/Folder.vue
@@ -21,33 +21,10 @@
-->
<template>
- <router-link :class="{'folder--clear': isEmpty}"
- class="folder"
- :to="to"
- :aria-label="ariaLabel">
- <transition name="fade">
- <div v-show="loaded"
- :class="`folder-content--grid-${fileList.length}`"
- class="folder-content"
- role="none">
- <img v-for="file in fileList"
- :key="file.fileid"
- :src="generateImgSrc(file)"
- alt=""
- @load="loaded = true">
- </div>
- </transition>
- <div
- class="folder-name">
- <span :class="[!isEmpty ? 'icon-white' : 'icon-dark', icon]"
- class="folder-name__icon"
- role="img" />
- <p :id="ariaUuid" class="folder-name__name">
- {{ basename }}
- </p>
- </div>
- <div class="cover" role="none" />
- </router-link>
+ <FolderTagPreview :id="fileid"
+ :name="basename"
+ :path="filename"
+ :file-list="fileList" />
</template>
<script>
@@ -56,9 +33,14 @@ import { mapGetters } from 'vuex'
import getAlbumContent from '../services/AlbumContent'
import cancelableRequest from '../utils/CancelableRequest'
+import FolderTagPreview from './FolderTagPreview'
export default {
name: 'Folder',
+
+ components: {
+ FolderTagPreview,
+ },
inheritAttrs: false,
props: {
@@ -74,10 +56,6 @@ export default {
type: Number,
required: true,
},
- icon: {
- type: String,
- default: 'icon-folder',
- },
showShared: {
type: Boolean,
default: false,
@@ -86,11 +64,13 @@ export default {
data() {
return {
- loaded: false,
cancelRequest: () => {},
}
},
+ beforeDestroy() {
+ this.cancelRequest('Navigated away')
+ },
computed: {
// global lists
...mapGetters([
@@ -105,38 +85,11 @@ export default {
fileList() {
return this.folderContent
? this.folderContent
- .slice(0, 4) // only get the 4 first images
.map(id => this.files[id])
.filter(file => !!file)
+ .slice(0, 4) // only get the 4 first images
: []
},
-
- // folder is empty
- isEmpty() {
- return this.fileList.length === 0
- },
-
- ariaUuid() {
- return `folder-${this.fileid}`
- },
- ariaLabel() {
- return t('photos', 'Open the "{name}" sub-directory', { name: this.basename })
- },
-
- /**
- * We do not want encoded slashes when browsing by folder
- * so we generate a new valid route object, get the final url back
- * decode it and use it as a direct string, which vue-router
- * does not encode afterwards
- * @returns {string}
- */
- to() {
- const route = Object.assign({}, this.$route, {
- // always remove first slash
- params: { path: this.filename.substr(1) },
- })
- return decodeURIComponent(this.$router.resolve(route).resolved.path)
- },
},
async created() {
@@ -160,17 +113,6 @@ export default {
beforeDestroy() {
this.cancelRequest('Navigated away')
},
-
- methods: {
- generateImgSrc({ fileid, etag }) {
- // use etag to force cache reload if file changed
- return generateUrl(`/core/preview?fileId=${fileid}&x=${256}&y=${256}&a=true&v=${etag}`)
- },
-
- fetch() {
- },
- },
-
}
</script>
diff --git a/src/components/FolderTagPreview.vue b/src/components/FolderTagPreview.vue
new file mode 100644
index 00000000..c24e6063
--- /dev/null
+++ b/src/components/FolderTagPreview.vue
@@ -0,0 +1,237 @@
+<!--
+ - @copyright Copyright (c) 2019 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>
+ <router-link :class="{'folder--clear': isEmpty}"
+ class="folder"
+ :to="to"
+ :aria-label="ariaLabel">
+ <!-- Images preview -->
+ <transition name="fade">
+ <div v-show="loaded"
+ :class="`folder-content--grid-${fileList.length}`"
+ class="folder-content"
+ role="none">
+ <img v-for="file in fileList"
+ :key="file.fileid"
+ :src="generateImgSrc(file)"
+ alt=""
+ @load="loaded = true">
+ </div>
+ </transition>
+
+ <div
+ class="folder-name">
+ <span :class="[!isEmpty ? 'icon-white' : 'icon-dark', icon]"
+ class="folder-name__icon"
+ role="img" />
+ <p :id="ariaUuid" class="folder-name__name">
+ {{ name }}
+ </p>
+ </div>
+
+ <div class="cover" role="none" />
+ </router-link>
+</template>
+
+<script>
+import { generateUrl } from '@nextcloud/router'
+
+export default {
+ name: 'FolderTagPreview',
+
+ props: {
+ icon: {
+ type: String,
+ default: 'icon-folder',
+ },
+ id: {
+ type: Number,
+ required: true,
+ },
+ name: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ fileList: {
+ type: Array,
+ default: () => [],
+ },
+ },
+
+ data() {
+ return {
+ loaded: false,
+ }
+ },
+
+ computed: {
+ // folder is empty
+ isEmpty() {
+ return this.fileList.length === 0
+ },
+
+ ariaUuid() {
+ return `folder-${this.id}`
+ },
+ ariaLabel() {
+ return t('photos', 'Open the "{name}" sub-directory', { name: this.name })
+ },
+
+ /**
+ * We do not want encoded slashes when browsing by folder
+ * so we generate a new valid route object based on the
+ * current named route, get the final url back, decode it
+ * and use it as a direct string.
+ * Which vue-router does not encode afterwards!
+ * @returns {string}
+ */
+ to() {
+ // always remove first slash, the router
+ // manage it automatically
+ const regex = /^\/?(.+)/i
+ const path = regex.exec(this.path)[1]
+
+ // apply to current route
+ const route = Object.assign({}, this.$route, {
+ params: { path },
+ })
+ // returning a string prevent vue-router to encode it again
+ return decodeURIComponent(this.$router.resolve(route).resolved.path)
+ },
+ },
+
+ methods: {
+ generateImgSrc({ fileid, etag }) {
+ // use etag to force cache reload if file changed
+ return generateUrl(`/core/preview?fileId=${fileid}&x=${256}&y=${256}&a=true&v=${etag}`)
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../mixins/FileFolder.scss';
+
+.folder-content {
+ position: absolute;
+ display: grid;
+ width: 100%;
+ height: 100%;
+ // folder layout if less than 4 pictures
+ &--grid-1 {
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+ }
+ &--grid-2 {
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr 1fr;
+ }
+ &--grid-3 {
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: 1fr 1fr;
+ img:first-child {
+ grid-column: span 2;
+ }
+ }
+ &--grid-4 {
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: 1fr 1fr;
+ }
+ img {
+ width: 100%;
+ height: 100%;
+
+ object-fit: cover;
+ }
+}
+
+$name-height: 1.2rem;
+
+.folder-name {
+ position: absolute;
+ z-index: 3;
+ display: flex;
+ overflow: hidden;
+ flex-direction: column;
+ width: 100%;
+ height: 100%;
+ transition: opacity var(--animation-quick) ease-in-out;
+ opacity: 1;
+ &__icon {
+ height: 40%;
+ margin-top: calc(30% - #{$name-height} / 2); // center name+icon
+ background-size: 40%;
+ }
+ &__name {
+ overflow: hidden;
+ height: $name-height;
+ padding: 0 10px;
+ text-align: center;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ color: var(--color-main-background);
+ text-shadow: 0 0 8px var(--color-main-text);
+ font-size: $name-height;
+ line-height: $name-height;
+ }
+}
+
+// Cover management empty/full
+.folder {
+ // if no img, let's display the folder icon as default black
+ &--clear {
+ .folder-name__icon {
+ opacity: .3;
+ }
+ .folder-name__name {
+ color: var(--color-main-text);
+ text-shadow: 0 0 8px var(--color-main-background);
+ }
+ }
+
+ // show the cover as background
+ // if there are pictures in it
+ // so we can sho the folder+name above it
+ &:not(.folder--clear) {
+ .cover {
+ opacity: .3;
+ }
+
+ // hide everything but pictures
+ // on hover/active/focus
+ &:active,
+ &:hover,
+ &:focus {
+ .folder-name,
+ .cover {
+ opacity: 0;
+ }
+ }
+ }
+}
+
+</style>
diff --git a/src/components/Tag.vue b/src/components/Tag.vue
new file mode 100644
index 00000000..2dba45aa
--- /dev/null
+++ b/src/components/Tag.vue
@@ -0,0 +1,106 @@
+<!--
+ - @copyright Copyright (c) 2019 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>
+ <FolderTagPreview :id="id"
+ icon="icon-tag"
+ :name="displayName"
+ :path="displayName"
+ :file-list="fileList" />
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+
+import getTaggedImages from '../services/TaggedImages'
+import cancelableRequest from '../utils/CancelableRequest'
+import FolderTagPreview from './FolderTagPreview'
+
+export default {
+ name: 'Tag',
+
+ components: {
+ FolderTagPreview,
+ },
+ inheritAttrs: false,
+
+ props: {
+ displayName: {
+ type: String,
+ required: true,
+ },
+ id: {
+ type: Number,
+ required: true,
+ },
+ },
+
+ data() {
+ return {
+ cancelRequest: () => {},
+ }
+ },
+
+ beforeDestroy() {
+ this.cancelRequest('Navigated away')
+ },
+ computed: {
+ // global lists
+ ...mapGetters([
+ 'files',
+ 'tags',
+ ]),
+
+ // files list of the current folder
+ folderContent() {
+ return this.tags[this.id].files
+ },
+ fileList() {
+ return this.folderContent
+ ? this.folderContent
+ .map(id => this.files[id])
+ .filter(file => !!file)
+ .slice(0, 4) // only get the 4 first images
+ : []
+ },
+ },
+
+ async created() {
+ // init cancellable request
+ const { request, cancel } = cancelableRequest(getTaggedImages)
+ this.cancelRequest = cancel
+
+ try {
+ // get data
+ const files = await request(this.id, { shared: this.showShared })
+ this.$store.dispatch('updateTag', { id: this.id, files })
+ this.$store.dispatch('appendFiles', files)
+ } catch (error) {
+ if (error.response && error.response.status) {
+ console.error('Failed to get folder content', this.id, error.response)
+ }
+ // else we just cancelled the request
+ }
+ },
+
+}
+</script>
diff --git a/src/patchedRequest.js b/src/patchedRequest.js
index ae23b19d..41b020aa 100644
--- a/src/patchedRequest.js
+++ b/src/patchedRequest.js
@@ -33,8 +33,14 @@ request.prepareRequestOptions = function(requestOptions, methodOptions) {
if (methodOptions.cancelToken && typeof methodOptions.cancelToken === 'object') {
requestOptions.cancelToken = Object.assign({}, requestOptions.cancelToken || {}, methodOptions.cancelToken)
}
+
// exploit old method
oldPrepareRequestOptions(requestOptions, methodOptions)
+
+ // allow us to override the request method
+ if (methodOptions.method && typeof methodOptions.method === 'string') {
+ requestOptions.method = methodOptions.method
+ }
}
module.exports = request
diff --git a/src/services/AlbumContent.js b/src/services/AlbumContent.js
index 3bcc74b8..9bbacbc8 100644
--- a/src/services/AlbumContent.js
+++ b/src/services/AlbumContent.js
@@ -38,14 +38,13 @@ export default async function(path = '/', options = {}) {
// fetch listing
const response = await axios.get(prefixPath + path, options)
-
const list = response.data.map(data => genFileInfo(data, prefixPath))
// filter all the files and folders
let folder = {}
const folders = []
const files = []
- console.info(allowedMimes)
+
for (const entry of list) {
// is this the current provided path ?
if (entry.filename === path) {
diff --git a/src/services/FileList.js b/src/services/FileList.js
index bfe579db..adbab9b2 100644
--- a/src/services/FileList.js
+++ b/src/services/FileList.js
@@ -70,7 +70,7 @@ export default async function(path, options) {
.then(result => getDirectoryFiles(result, remotePath + prefixPath, options.details))
.then(files => processResponsePayload(response, files, options.details))
- const list = data.map(data => genFileInfo(data, prefixPath))
+ const list = data.map(data => genFileInfo(data))
// filter all the files and folders
let folder = {}
diff --git a/src/services/TaggedImages.js b/src/services/TaggedImages.js
new file mode 100644
index 00000000..fe812264
--- /dev/null
+++ b/src/services/TaggedImages.js
@@ -0,0 +1,99 @@
+/**
+ * @copyright Copyright (c) 2019 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/>.
+ *
+ */
+
+/**
+ * @copyright Copyright (c) 2019 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/>.
+ *
+ */
+
+import { genFileInfo } from '../utils/fileUtils'
+import { getCurrentUser } from '@nextcloud/auth'
+import client from './DavClient'
+
+/**
+ * Get tagged files based on provided tag id
+ *
+ * @param {number} id the tag id to filter
+ * @param {Object} [options] optional options for axios
+ * @returns {Array} the file list
+ */
+export default async function(id, options = {}) {
+
+ const prefixPath = `/files/${getCurrentUser().uid}`
+
+ const response = await client.getDirectoryContents(prefixPath, Object.assign({}, {
+ method: 'REPORT',
+ data: `<?xml version="1.0"?>
+ <oc:filter-files
+ xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns"
+ xmlns:nc="http://nextcloud.org/ns"
+ xmlns:ocs="http://open-collaboration-services.org/ns">
+ <d:prop>
+ <d:getlastmodified />
+ <d:getetag />
+ <d:getcontenttype />
+ <d:resourcetype />
+ <oc:fileid />
+ <oc:permissions />
+ <oc:size />
+ <d:getcontentlength />
+ <nc:has-preview />
+ <nc:mount-type />
+ <nc:is-encrypted />
+ <ocs:share-permissions />
+ <oc:tags />
+ <oc:favorite />
+ <oc:comments-unread />
+ <oc:owner-id />
+ <oc:owner-display-name />
+ <oc:share-types />
+ </d:prop>
+ <oc:filter-rules>
+ <oc:systemtag>${id}</oc:systemtag>
+ </oc:filter-rules>
+ </oc:filter-files>`,
+ details: true,
+ }, options))
+
+ return response.data
+ .map(data => genFileInfo(data, prefixPath))
+ // remove prefix path from full file path
+ .map(data => Object.assign({}, data, { filename: data.filename.replace(prefixPath, '') }))
+}
diff --git a/src/store/files.js b/src/store/files.js
index a199b01f..2dc5fa8d 100644
--- a/src/store/files.js
+++ b/src/store/files.js
@@ -52,6 +52,7 @@ const mutations = {
if (state.files[fileid]) {
const subfolders = folders
.map(folder => folder.fileid)
+ // some invalid folders have an id of -1 (ext storage)
.filter(id => id >= 0)
Vue.set(state.files[fileid], 'folders', subfolders)
}
@@ -64,7 +65,7 @@ const getters = {
const actions = {
/**
- * Increment the number of contacts accepted
+ * Update files, folders and their respective subfolders
*
* @param {Object} context the store mutations
* @param {Object} data destructuring object
@@ -72,11 +73,21 @@ const actions = {
* @param {Array} data.files list of files
* @param {Array} data.folders list of folders within current folder
*/
- updateFiles(context, { folder, files, folders }) {
+ updateFiles(context, { folder, files = [], folders = [] } = {}) {
// we want all the FileInfo! Folders included!
context.commit('updateFiles', [folder, ...files, ...folders])
context.commit('setSubFolders', { fileid: folder.fileid, folders })
},
+
+ /**
+ * Append or update given files
+ *
+ * @param {Object} context the store mutations
+ * @param {Array} files list of files
+ */
+ appendFiles(context, files = []) {
+ context.commit('updateFiles', files)
+ },
}
export default { state, mutations, getters, actions }
diff --git a/src/store/systemtags.js b/src/store/systemtags.js
index 4a49e13e..d166f8a6 100644
--- a/src/store/systemtags.js
+++ b/src/store/systemtags.js
@@ -61,7 +61,8 @@ const mutations = {
const list = files.sort((a, b) => sortCompare(a, b, 'lastmod'))
// overwrite list
- Vue.set(state.tags[id], 'files', list.map(file => file.id))
+ console.info(id, list)
+ Vue.set(state.tags[id], 'files', list.map(file => file.fileid))
},
}
diff --git a/src/views/Albums.vue b/src/views/Albums.vue
index 536f2352..50718c42 100644
--- a/src/views/Albums.vue
+++ b/src/views/Albums.vue
@@ -29,12 +29,13 @@
{{ t('photos', 'An error occurred') }}
</EmptyContent>
<EmptyContent v-else-if="!loading && isEmpty" illustration-name="empty">
- {{ t('photos', 'This folder does not contain pictures') }}
+ {{ t('photos', 'No photos in here') }}
</EmptyContent>
<!-- Folder content -->
<Grid v-else>
<Navigation v-if="folder" key="navigation" v-bind="folder" />
+
<Folder v-for="dir in folderList"
:key="dir.fileid"
v-bind="dir"
@@ -182,7 +183,7 @@ export default {
if (error.response.status === 404) {
this.error = 404
setTimeout(() => {
- this.$router.push({ name: 'root' })
+ this.$router.push({ name: this.$route.name })
}, 3000)
} else {
this.error = error
diff --git a/src/views/EmptyContent.vue b/src/views/EmptyContent.vue
index f1394a61..c96c4aa2 100644
--- a/src/views/EmptyContent.vue
+++ b/src/views/EmptyContent.vue
@@ -25,6 +25,9 @@
<div v-if="haveIllustration" class="illustration" v-html="illustration" />
<div v-else class="icon-error" />
<h2><slot /></h2>
+ <p v-show="$slots.desc">
+ <slot name="desc" />
+ </p>
</div>
</template>
diff --git a/src/views/Tags.vue b/src/views/Tags.vue
index e9e37215..e8fe6110 100644
--- a/src/views/Tags.vue
+++ b/src/views/Tags.vue
@@ -22,35 +22,29 @@
<template>
<!-- Errors handlers-->
- <!-- <EmptyContent v-if="error === 404" illustration-name="folder">
- {{ t('photos', 'This folder does not exists') }}
- </EmptyContent>
- <EmptyContent v-else-if="error">
+ <EmptyContent v-if="error">
{{ t('photos', 'An error occurred') }}
</EmptyContent>
<EmptyContent v-else-if="!loading && isEmpty" illustration-name="empty">
- {{ t('photos', 'This folder does not contain pictures') }}
- </EmptyContent> -->
+ {{ t('photos', 'No tags yet') }}
+ <template #desc>
+ {{ t('photos', 'Photos with tags will show up here') }}
+ </template>
+ </EmptyContent>
<!-- Folder content -->
- <Grid v-if="isRoot">
+ <Grid v-else-if="isRoot">
<Navigation v-if="tag"
key="navigation"
:basename="tagname"
:filename="'/' + tagname"
:root-title="t('photos', 'Tags')" />
- <Folder v-for="id in tagsNames"
+ <Tag v-for="id in tagsNames"
:key="id"
v-bind="tags[id]"
:fileid="id"
- :basename="tags[id].displayName"
- icon="icon-tag" />
+ :basename="tags[id].displayName" />
</Grid>
- <!-- <Grid v-else>
- <Navigation v-if="folder" key="navigation" v-bind="folder" />
- <Folder v-for="dir in folderList" :key="dir.id" :folder="dir" />
- <File v-for="file in fileList" :key="file.id" v-bind="file" />
- </Grid> -->
</template>
<script>
@@ -59,7 +53,7 @@ import { mapGetters } from 'vuex'
import getSystemTags from '../services/SystemTags'
import EmptyContent from './EmptyContent'
-import Folder from '../components/Folder'
+import Tag from '../components/Tag'
import File from '../components/File'
import Grid from '../components/Grid'
import Navigation from '../components/Navigation'
@@ -71,7 +65,7 @@ export default {
components: {
EmptyContent,
File,
- Folder,
+ Tag,
Grid,
Navigation,
},
@@ -120,6 +114,10 @@ export default {
isRoot() {
return this.tagname === ''
},
+
+ isEmpty() {
+ return Object.keys(this.tagsNames).length === 0
+ },
},
watch: {