mirror of https://github.com/nextcloud/bookmarks
UI: Refactor folders/bookmarks into a common item component
This commit is contained in:
parent
ee21d15c8d
commit
99f021ef40
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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 } })
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue