UI: Refactor folders/bookmarks into a common item component

This commit is contained in:
Marcel Klehr 2020-08-26 20:00:34 +02:00
parent ee21d15c8d
commit 99f021ef40
6 changed files with 396 additions and 426 deletions

View File

@ -1,94 +1,62 @@
<template>
<div
:class="{
bookmark: true,
active: isOpen || selected,
'bookmark--gridview': viewMode === 'grid'
}"
:style="{
background:
viewMode === 'grid'
? `linear-gradient(0deg, var(--color-main-background) 25%, rgba(0, 212, 255, 0) 50%), url('${imageUrl}')`
: undefined
}">
<a
:href="url"
class="bookmark__click-link"
target="_blank" />
<template v-if="!renaming">
<div v-if="isEditable" class="bookmark__checkbox">
<input v-model="selected" class="checkbox" type="checkbox"><label
v-tooltip="t('bookmarks', 'Select bookmark')"
:aria-label="t('bookmarks', 'Select bookmark')"
@click="clickSelect" />
</div>
<div class="bookmark__labels">
<a :href="url" target="_blank" class="bookmark__title">
<h3 :title="bookmark.title">
<figure
class="bookmark__icon"
:style="{ backgroundImage: 'url(' + iconUrl + ')' }" />
{{ bookmark.title }}
</h3>
</a>
<Item :title="bookmark.title"
:tags="bookmark.tags"
:rename-placeholder="t('bookmarks', 'Enter new title')"
:select-label="t('bookmarks', 'Select bookmark')"
:active="isActive"
:editable="isEditable"
:selected="selected"
:renaming="renaming"
:background="background"
:url="url"
@select="onSelect"
@rename="onRenameSubmit"
@rename-cancel="renaming = false">
<template #title>
<div class="bookmark__title">
<h3 :title="bookmark.title">
<figure
class="bookmark__icon"
:style="{ backgroundImage: 'url(' + iconUrl + ')' }" />
{{ bookmark.title }}
</h3>
<span
v-if="bookmark.description"
v-tooltip="bookmark.description"
class="bookmark__description"><figure class="icon-file" />
{{ bookmark.description }}</span>
</div>
<TagLine :tags="bookmark.tags" />
<Actions v-if="isEditable" class="bookmark__actions">
<ActionButton icon="icon-info" :close-after-click="true" @click="onDetails">
{{ t('bookmarks', 'Details') }}
</ActionButton>
<ActionButton icon="icon-rename" :close-after-click="true" @click="onRename">
{{ t('bookmarks', 'Rename') }}
</ActionButton>
<ActionButton :close-after-click="true" @click="onMove">
{{ t('bookmarks', 'Move') }}
<FolderMoveIcon #icon :fill-color="colorMainText" />
</ActionButton>
<ActionButton icon="icon-delete" :close-after-click="true" @click="onDelete">
{{ t('bookmarks', 'Delete') }}
</ActionButton>
</Actions>
</template>
<h3 v-else class="bookmark__title">
<figure
class="bookmark__icon"
:style="{ backgroundImage: 'url(' + iconUrl + ')' }" />
<input
ref="input"
v-model="title"
type="text"
:placeholder="t('bookmarks', 'Enter bookmark title')"
@keyup.enter="onRenameSubmit">
<Actions>
<ActionButton icon="icon-checkmark" @click="onRenameSubmit">
{{ t('bookmarks', 'Save') }}
</ActionButton>
</Actions>
</h3>
</div>
<template #actions>
<ActionButton icon="icon-info" :close-after-click="true" @click="onDetails">
{{ t('bookmarks', 'Details') }}
</ActionButton>
<ActionButton icon="icon-rename" :close-after-click="true" @click="onRename">
{{ t('bookmarks', 'Rename') }}
</ActionButton>
<ActionButton :close-after-click="true" @click="onMove">
{{ t('bookmarks', 'Move') }}
<FolderMoveIcon #icon :fill-color="colorMainText" />
</ActionButton>
<ActionButton icon="icon-delete" :close-after-click="true" @click="onDelete">
{{ t('bookmarks', 'Delete') }}
</ActionButton>
</template>
</Item>
</template>
<script>
import Vue from 'vue'
import Actions from '@nextcloud/vue/dist/Components/Actions'
import Item from './Item'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import FolderMoveIcon from 'vue-material-design-icons/FolderMove'
import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl } from '@nextcloud/router'
import { actions, mutations } from '../store/'
import TagLine from './TagLine'
export default {
name: 'Bookmark',
components: {
Actions,
Item,
ActionButton,
TagLine,
FolderMoveIcon,
},
props: {
@ -115,7 +83,9 @@ export default {
},
imageUrl() {
return this.apiUrl + '/bookmark/' + this.bookmark.id + '/image' + (this.$store.state.public ? '?token=' + this.$store.state.authToken : '')
},
background() {
return this.viewMode === 'grid' ? `linear-gradient(0deg, var(--color-main-background) 25%, rgba(0, 212, 255, 0) 50%), url('${this.imageUrl}')` : undefined
},
url() {
return this.bookmark.url
@ -145,6 +115,9 @@ export default {
selected() {
return this.selectedBookmarks.map(b => b.id).includes(this.bookmark.id)
},
isActive() {
return this.isOpen || this.selected
},
},
created() {},
methods: {
@ -164,15 +137,13 @@ export default {
},
async onRename() {
this.renaming = true
await Vue.nextTick()
this.$refs.input.focus()
},
async onRenameSubmit() {
this.bookmark.title = this.title
async onRenameSubmit(title) {
this.bookmark.title = title
await this.$store.dispatch(actions.SAVE_BOOKMARK, this.bookmark.id)
this.renaming = false
},
clickSelect() {
onSelect() {
if (!this.selected) {
this.$store.commit(mutations.ADD_SELECTION_BOOKMARK, this.bookmark)
} else {
@ -183,26 +154,6 @@ export default {
}
</script>
<style>
.bookmark {
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
background-position: center !important;
background-size: cover !important;
background-color: var(--color-main-background);
position: relative;
padding: 0 8px 0 10px;
}
.bookmark.active,
.bookmark:hover,
.bookmark:focus {
background: var(--color-background-dark);
}
.bookmark__checkbox {
display: inline-block;
}
.bookmark__icon {
display: inline-block;
@ -215,13 +166,6 @@ export default {
top: 3px;
}
.bookmark__labels {
display: flex;
flex: 1;
text-overflow: ellipsis;
overflow: hidden;
}
.bookmark__title {
display: flex;
}
@ -235,7 +179,6 @@ export default {
.bookmark__title > h3 {
margin: 0;
padding: 15px 0;
}
.bookmark__description {
@ -253,69 +196,18 @@ export default {
display: none !important;
}
.bookmark--gridview.active {
border-color: var(--color-primary-element);
}
.bookmark--gridview .bookmark__description {
.item--gridview .bookmark__description {
flex: 0;
}
.bookmark--gridview .bookmark__description figure {
.item--gridview .bookmark__description figure {
display: inline-block !important;
position: relative;
top: 5px;
}
.bookmark--gridview .bookmark__checkbox {
position: absolute;
top: 10px;
left: 10px;
background: white;
border-radius: var(--border-radius);
}
.bookmark__actions {
flex: 0;
}
.bookmark__title > input {
width: 100%;
border-top: none;
border-left: none;
border-right: none;
}
.bookmark__title button {
height: 20px;
}
.bookmark--gridview .tagline {
position: absolute;
bottom: 47px;
left: 10px;
margin: 0;
}
.bookmark--gridview .bookmark__checkbox input[type='checkbox'].checkbox + label::before {
margin: 0 3px 3px 3px;
}
.bookmark--gridview .bookmark__icon {
margin: 0 5px 0 10px;
}
.bookmark__click-link {
bottom: 0;
display: none;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.bookmark--gridview .bookmark__click-link {
display: block;
.item--gridview .bookmark__icon {
margin: 0 5px 0 8px;
}
</style>

View File

@ -1,43 +1,25 @@
<template>
<div class="create-bookmark">
<span class="create-bookmark__title">
<figure class="icon-link create-bookmark__icon" />
<input
ref="input"
v-model="url"
type="text"
:disabled="creating"
:placeholder="t('bookmarks', 'Enter a link')"
@keyup.enter="submit">
</span>
<Actions>
<ActionButton
:icon="creating ? 'icon-loading' : 'icon-confirm'"
@click="submit">
{{ t('bookmarks', 'Create') }}
</ActionButton>
</Actions>
<Actions>
<ActionButton
icon="icon-close"
@click="cancel">
{{ t('bookmarks', 'Cancel') }}
</ActionButton>
</Actions>
</div>
<Item :selectable="false"
:renaming="true"
title=""
:editable="true"
:rename-placeholder="t('bookmarks', 'Enter a link')"
select-label=""
@rename="submit"
@rename-cancel="cancel">
<template #icon>
<EarthIcon :fill-color="colorMainText" class="icon" />
</template>
</Item>
</template>
<script>
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import EarthIcon from 'vue-material-design-icons/Earth'
import Item from './Item'
import { actions, mutations } from '../store/'
export default {
name: 'CreateBookmark',
components: { Actions, ActionButton },
data() {
return {
url: '',
}
},
components: { Item, EarthIcon },
computed: {
creating() {
return this.$store.state.loading.createBookmark
@ -53,9 +35,9 @@ export default {
this.$refs.input.focus()
},
methods: {
submit() {
submit(url) {
this.$store.dispatch(actions.CREATE_BOOKMARK, {
url: this.url,
url,
...(this.isFolderView && { folders: [this.$route.params.folder] }),
...(this.isTagView && { tags: this.$route.params.tags.split(',') }),
})
@ -69,48 +51,22 @@ export default {
},
}
</script>
<style>
.create-bookmark {
border-bottom: 1px solid var(--color-border);
padding: 5px;
display: flex;
align-items: center;
position: relative;
}
.create-bookmark__icon {
display: inline-block;
flex-shrink: 0;
<style scoped>
.icon {
flex-grow: 0;
height: 20px;
width: 20px;
background-size: cover;
margin: 0 10px;
position: relative;
top: 10px;
margin: 0 15px;
cursor: pointer;
}
.bookmarkslist--gridview .create-bookmark__icon {
height: 100px;
width: 100px;
.item--gridview .icon {
background-size: cover;
position: absolute;
top: 30px;
left: 60px;
}
.create-bookmark__title {
display: flex;
flex-grow: 1;
}
.create-bookmark button {
height: 20px;
}
.create-bookmark input {
border-top: none;
border-left: none;
border-right: none;
width: 100%;
top: 20%;
left: calc(45% - 50px);
transform: scale(4);
transform-origin: top left;
}
</style>

View File

@ -1,44 +1,25 @@
<template>
<div class="create-folder">
<span class="create-folder__title">
<figure class="icon-folder create-folder__icon" />
<input
ref="input"
v-model="title"
type="text"
:disabled="loading"
:placeholder="t('bookmarks', 'Enter folder title')"
@keyup.enter="submit">
</span>
<Actions>
<ActionButton
:icon="loading ? 'icon-loading' : 'icon-confirm'"
@click="submit">
{{ t('bookmarks', 'Create') }}
</ActionButton>
</Actions>
<Actions>
<ActionButton
icon="icon-close"
@click="cancel">
{{ t('bookmarks', 'Cancel') }}
</ActionButton>
</Actions>
</div>
<Item :selectable="false"
:renaming="true"
title=""
:editable="true"
:rename-placeholder="t('bookmarks', 'Enter a title')"
select-label=""
@rename="submit"
@rename-cancel="cancel">
<template #icon>
<FolderIcon :fill-color="colorPrimaryElement" class="icon" />
</template>
</Item>
</template>
<script>
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import FolderIcon from 'vue-material-design-icons/Folder'
import Item from './Item'
import { actions, mutations } from '../store/'
export default {
name: 'CreateFolder',
components: { Actions, ActionButton },
data() {
return {
title: '',
}
},
components: { Item, FolderIcon },
computed: {
loading() {
return this.$store.state.loading.createFolder
@ -48,11 +29,11 @@ export default {
this.$refs.input.focus()
},
methods: {
submit() {
submit(title) {
const parentFolder = this.$route.params.folder
this.$store.dispatch(actions.CREATE_FOLDER, {
parentFolder,
title: this.title,
title,
})
},
cancel() {
@ -64,48 +45,22 @@ export default {
},
}
</script>
<style>
.create-folder {
border-bottom: 1px solid var(--color-border);
padding: 5px;
display: flex;
align-items: center;
position: relative;
}
.create-folder__icon {
display: inline-block;
flex-shrink: 0;
<style scoped>
.icon {
flex-grow: 0;
height: 20px;
width: 20px;
background-size: cover;
margin: 0 10px;
position: relative;
top: 8px;
margin: 0 15px;
cursor: pointer;
}
.bookmarkslist--gridview .create-folder__icon {
height: 100px;
width: 100px;
.item--gridview .icon {
background-size: cover;
position: absolute;
top: 30px;
left: 60px;
}
.create-folder__title {
display: flex;
flex-grow: 1;
}
.create-folder button {
height: 20px;
}
.create-folder input {
border-top: none;
border-left: none;
border-right: none;
width: 100%;
top: 20%;
left: calc(45% - 50px);
transform: scale(4);
transform-origin: top left;
}
</style>

View File

@ -1,81 +1,61 @@
<template>
<div :class="{folder: true, 'folder--gridview': viewMode === 'grid', active: selected}"
tabindex="0"
@click="onSelect"
@keypress="onEnter">
<div v-if="isEditable" ref="checkbox" class="folder__checkbox">
<input :id="'select'+folder.id"
:value="selected"
class="checkbox"
type="checkbox"><label
v-tooltip="t('bookmarks', 'Select folder')"
:aria-label="t('bookmarks', 'Select folder')"
:for="'select'+folder.id"
@click="clickSelect" />
</div>
<FolderIcon :fill-color="colorPrimaryElement" :class="'folder__icon'" @click="onSelect" />
<ShareVariantIcon v-if="(isShared || !isOwner) || isSharedPublicly"
:fill-color="colorPrimaryText"
:class="['folder__icon', 'shared']" />
<template v-if="!renaming">
<h3
class="folder__title"
:title="folder.title">
<Item :active="selected"
:editable="isEditable"
:selected="selected"
:title="folder.title"
:renaming="renaming"
:select-label="t('bookmarks', 'Select folder')"
:rename-placeholder="t('bookmarks', 'Enter folder title')"
@select="clickSelect"
@rename="onRenameSubmit"
@rename-cancel="renaming = false"
@click="onSelect">
<template #icon>
<FolderIcon :fill-color="colorPrimaryElement" :class="'folder__icon'" @click="onSelect" />
<ShareVariantIcon v-if="(isShared || !isOwner) || isSharedPublicly"
:fill-color="colorPrimaryText"
:class="['folder__icon', 'shared']" />
</template>
<template #title>
<h3 class="folder__title">
{{ folder.title }}
</h3>
</template>
<template #tags>
<div class="folder__tags">
<div v-if="!isOwner && !isSharedPublicly" class="folder__tag">
{{ t('bookmarks', 'Shared by {user}', {user: folder.userId}) }}
</div>
</div>
<Actions v-if="isEditable"
ref="actions"
class="folder__actions"
:close-after-click="true">
<ActionButton icon="icon-info" :close-after-click="true" @click="onDetails">
{{ t('bookmarks', 'Details') }}
</ActionButton>
<ActionButton icon="icon-rename" :close-after-click="true" @click="onRename">
{{ t('bookmarks', 'Rename') }}
</ActionButton>
<ActionButton icon="icon-category-files" :close-after-click="true" @click="onMove">
{{ t('bookmarks', 'Move') }}
</ActionButton>
<ActionButton icon="icon-delete" :close-after-click="true" @click="onDelete">
{{ t('bookmarks', 'Delete') }}
</ActionButton>
</Actions>
</template>
<template v-else>
<span class="folder__title">
<input ref="input"
v-model="title"
type="text"
:placeholder="t('bookmarks', 'Enter folder title')"
@keyup.enter="onRenameSubmit">
<Actions>
<ActionButton icon="icon-checkmark" @click="onRenameSubmit">
{{ t('bookmarks', 'Save') }}
</ActionButton>
</Actions>
</span>
<template #actions>
<ActionButton icon="icon-info" :close-after-click="true" @click="onDetails">
{{ t('bookmarks', 'Details') }}
</ActionButton>
<ActionButton icon="icon-rename" :close-after-click="true" @click="onRename">
{{ t('bookmarks', 'Rename') }}
</ActionButton>
<ActionButton icon="icon-category-files" :close-after-click="true" @click="onMove">
{{ t('bookmarks', 'Move') }}
</ActionButton>
<ActionButton icon="icon-delete" :close-after-click="true" @click="onDelete">
{{ t('bookmarks', 'Delete') }}
</ActionButton>
</template>
</div>
</Item>
</template>
<script>
import Vue from 'vue'
import { getCurrentUser } from '@nextcloud/auth'
import FolderIcon from 'vue-material-design-icons/Folder'
import ShareVariantIcon from 'vue-material-design-icons/ShareVariant'
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import { actions, mutations } from '../store/'
import Item from './Item'
export default {
name: 'Folder',
components: {
Actions,
Item,
ActionButton,
FolderIcon,
ShareVariantIcon,
@ -87,7 +67,7 @@ export default {
},
},
data() {
return { renaming: false, title: this.folder.title }
return { renaming: false }
},
computed: {
viewMode() {
@ -143,20 +123,14 @@ export default {
this.$store.commit(mutations.DISPLAY_MOVE_DIALOG, true)
},
onSelect(e) {
if (this.$refs.actions.$el === e.target
|| this.$refs.actions.$el.contains(e.target)
|| this.$refs.checkbox.contains(e.target)
|| this.$refs.checkbox === e.target) return
this.$router.push({ name: this.routes.FOLDER, params: { folder: this.folder.id } })
e.preventDefault()
},
async onRename() {
this.renaming = true
await Vue.nextTick()
this.$refs.input.focus()
},
onRenameSubmit() {
this.folder.title = this.title
onRenameSubmit(title) {
this.folder.title = title
this.$store.dispatch(actions.SAVE_FOLDER, this.folder.id)
this.renaming = false
},
@ -176,42 +150,12 @@ export default {
}
</script>
<style>
.folder {
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
position: relative;
padding: 0 8px 0 10px;
}
.folder.active,
.folder:hover,
.folder:focus {
background: var(--color-background-dark);
}
.folder--gridview.active {
border-color: var(--color-primary-element);
}
.folder__checkbox {
display: inline-block;
}
.folder--gridview .folder__checkbox {
position: absolute;
top: 10px;
left: 10px;
background: white;
border-radius: var(--border-radius);
}
.folder__icon {
flex-grow: 0;
height: 20px;
width: 20px;
background-size: cover;
margin: 15px;
margin: 0 15px;
cursor: pointer;
}
@ -224,16 +168,16 @@ export default {
width:auto;
}
.folder--gridview .folder__icon {
.item--gridview .folder__icon {
background-size: cover;
position: absolute;
top: 20%;
left: calc(45% - 35px);
transform: scale(3);
left: calc(45% - 50px);
transform: scale(4);
transform-origin: top left;
}
.folder--gridview .folder__icon.shared {
.item--gridview .folder__icon.shared {
transform: translate(100%, 90%);
}
@ -244,10 +188,9 @@ export default {
white-space: nowrap;
cursor: pointer;
margin: 0;
padding: 15px 0;
}
.folder--gridview .folder__title {
.item--gridview .folder__title {
margin-left: 15px;
}
@ -260,7 +203,7 @@ export default {
margin: 0 15px;
}
.folder--gridview .folder__tags {
.item--gridview .folder__tags {
position: absolute;
bottom: 47px;
left: 10px;
@ -275,20 +218,4 @@ export default {
margin-right: 3px;
background-color: var(--color-primary-light);
}
.folder__actions {
flex: 0;
padding: 4px 0;
}
.folder__title input {
width: 100%;
border-top: none;
border-left: none;
border-right: none;
}
.folder__title button {
height: 20px;
}
</style>

238
src/components/Item.vue Normal file
View File

@ -0,0 +1,238 @@
<template>
<div
:class="{
item: true,
active,
'item--gridview': viewMode === 'grid'
}"
:style="{ background }">
<template v-if="!renaming">
<a
:href="url"
class="item__clickLink"
tabindex="0"
target="_blank"
@click="onClick">
<div v-if="editable" class="item__checkbox">
<input :value="selected" class="checkbox" type="checkbox"><label
v-tooltip="selectLabel"
:aria-label="selectLabel"
@click="$emit('select')" />
</div>
<slot name="icon" />
<div class="item__labels">
<slot name="title" />
</div>
<slot name="tags">
<TagLine ref="tags" :tags="tags" />
</slot>
<div v-if="editable"
class="item__actions"
@click="$event.preventDefault(); $event.stopPropagation()">
<Actions>
<slot name="actions" />
</Actions>
</div>
</a>
</template>
<div v-else class="item__rename">
<slot name="icon" />
<input
ref="input"
v-model="newTitle"
type="text"
:placeholder="renamePlaceholder"
@keyup.enter="onRenameSubmit">
<Actions>
<ActionButton icon="icon-checkmark" @click="onRenameSubmit">
{{ t('bookmarks', 'Cancel') }}
</ActionButton>
</Actions>
<Actions>
<ActionButton icon="icon-close" @click="$emit('rename-cancel')">
{{ t('bookmarks', 'Cancel') }}
</ActionButton>
</Actions>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import TagLine from './TagLine'
export default {
name: 'Item',
components: {
Actions,
ActionButton,
TagLine,
},
props: {
title: {
type: String,
required: true,
},
url: {
type: String,
default: undefined,
},
active: {
type: Boolean,
default: false,
},
editable: {
type: Boolean,
default: false,
},
selected: {
type: Boolean,
default: false,
},
renaming: {
type: Boolean,
default: false,
},
selectLabel: {
type: String,
required: true,
},
renamePlaceholder: {
type: String,
required: true,
},
background: {
type: String,
default: undefined,
},
tags: {
type: Array,
default: undefined,
},
},
data() {
return {
newTitle: this.title,
}
},
computed: {
viewMode() {
return this.$store.state.viewMode
},
},
watch: {
async renaming() {
if (this.renaming) {
await Vue.nextTick()
this.$refs.input.focus()
}
},
},
methods: {
async onRenameSubmit(event) {
this.$emit('rename', this.newTitle)
},
onClick(e) {
if (this.$refs.actions.$el === e.target
|| this.$refs.actions.$el.contains(e.target)
|| this.$refs.checkbox.contains(e.target)
|| this.$refs.checkbox === e.target
|| this.$refs.tags.$el.contains(e.target)
|| this.$refs.tags.$el === e.target) {
e.stopImmediatePropagation()
return
}
this.$emit('click', e)
},
},
}
</script>
<style>
.item {
border-bottom: 1px solid var(--color-border);
background-position: center !important;
background-size: cover !important;
background-color: var(--color-main-background);
position: relative;
}
.item--gridview {
width: 250px;
height: 200px;
background: var(--color-main-background);
border: 1px solid var(--color-border);
box-shadow: #efefef7d 0px 0 13px 0px inset;
border-radius: var(--border-radius);
}
.item__clickLink,
.item__rename {
display: flex;
align-items: center;
padding: 0 8px 0 10px;
}
.item--gridview .item__clickLink,
.item--gridview .item__rename {
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: 0;
display: flex;
align-items: flex-end;
padding: 0 8px 5px 10px;
}
.item.active,
.item:hover,
.item:focus {
background: var(--color-background-dark);
}
.item.item--gridview.active {
border-color: var(--color-primary-element);
}
.item__checkbox {
display: inline-block;
}
.item__labels {
display: flex;
flex: 1;
text-overflow: ellipsis;
overflow: hidden;
margin: 10px 0;
}
.item:not(.item--gridview) .item__rename input {
width: 100%;
}
.item--gridview .item__checkbox {
position: absolute;
top: 10px;
left: 10px;
background: white;
border-radius: var(--border-radius);
}
.item__actions {
flex: 0;
}
.item--gridview .tagline {
position: absolute;
bottom: 47px;
left: 10px;
margin: 0;
}
.item--gridview .item__checkbox input[type='checkbox'].checkbox + label::before {
margin: 0 3px 3px 3px;
}
</style>

View File

@ -4,7 +4,7 @@
:key="tag"
class="tagline__tag"
role="button"
@click="clickTag(tag)">
@click="clickTag($event, tag)">
{{ tag }}
</div>
</div>
@ -31,7 +31,9 @@ export default {
},
created() {},
methods: {
clickTag(tag) {
clickTag(e, tag) {
e.preventDefault()
e.stopImmediatePropagation()
this.$router.push({ name: this.routes.TAGS, params: { tags: tag } })
},
},