mirror of https://github.com/nextcloud/bookmarks
Merge branch 'enh/design-upgrades'
This commit is contained in:
commit
dbf531abb6
|
@ -10957,6 +10957,11 @@
|
|||
"vue-style-loader": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"vue-material-design-icons": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-4.8.0.tgz",
|
||||
"integrity": "sha512-NNbwK/a14mk92ofBvJa6oBdWi+SO2f27pimoCWziirrbN5Nmt9q0pzELOfvqyy0ncoMJ2BLkd8KfQuXIAhL3Fw=="
|
||||
},
|
||||
"vue-multiselect": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.6.tgz",
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"humanize-duration": "^3.23.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue-material-design-icons": "^4.8.0",
|
||||
"vue-router": "^3.4.3",
|
||||
"vue-simple-progress": "^1.1.1",
|
||||
"vuex": "^3.5.1",
|
||||
|
|
|
@ -44,8 +44,9 @@
|
|||
<ActionButton icon="icon-rename" @click="onRename">
|
||||
{{ t('bookmarks', 'Rename') }}
|
||||
</ActionButton>
|
||||
<ActionButton icon="icon-category-files" @click="onMove">
|
||||
<ActionButton @click="onMove">
|
||||
{{ t('bookmarks', 'Move') }}
|
||||
<FolderMoveIcon #icon />
|
||||
</ActionButton>
|
||||
<ActionButton icon="icon-delete" @click="onDelete">
|
||||
{{ t('bookmarks', 'Delete') }}
|
||||
|
@ -74,6 +75,7 @@
|
|||
import Vue from 'vue'
|
||||
import Actions from '@nextcloud/vue/dist/Components/Actions'
|
||||
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/'
|
||||
|
@ -85,6 +87,7 @@ export default {
|
|||
Actions,
|
||||
ActionButton,
|
||||
TagLine,
|
||||
FolderMoveIcon,
|
||||
},
|
||||
props: {
|
||||
bookmark: {
|
||||
|
|
|
@ -71,15 +71,12 @@
|
|||
</ActionButton>
|
||||
</Actions>
|
||||
<Actions>
|
||||
<ActionButton :icon="'icon-category-monitoring'" @click="openRssUrl">
|
||||
<ActionButton icon="icon-category-integration" @click="openRssUrl">
|
||||
{{ t('bookmarks', 'RSS Feed') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<div v-if="hasSelection" class="controls__bulkediting">
|
||||
{{
|
||||
selectionDescription
|
||||
}}
|
||||
<Actions>
|
||||
<div v-if="hasSelection" class="breadcrumbs__bulkediting">
|
||||
<Actions :primary="true" :menu-title="selectionDescription">
|
||||
<ActionButton icon="icon-category-files" @click="onBulkMove">
|
||||
{{ t('bookmarks', 'Move selection') }}
|
||||
</ActionButton>
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
<template>
|
||||
<div :class="{folder: true, 'folder--gridview': viewMode === 'grid', active: selected,}">
|
||||
<div :class="{folder: true, 'folder--gridview': viewMode === 'grid', active: selected,}" @click="onSelect">
|
||||
<div v-if="isEditable" class="folder__checkbox">
|
||||
<input v-model="selected" class="checkbox" type="checkbox"><label
|
||||
:aria-label="t('bookmarks', 'Select folder')"
|
||||
@click="clickSelect" />
|
||||
</div>
|
||||
<figure :class="{'folder__icon': true, 'shared': !isOwner && !isPublic || isSharedPublicly || isShared }" @click="onSelect" />
|
||||
<FolderIcon fill-color="#0082c9" :class="'folder__icon'" @click="onSelect" />
|
||||
<ShareVariantIcon v-if="(isShared || !isOwner) || isSharedPublicly"
|
||||
fill-color="#ffffff"
|
||||
:class="['folder__icon', 'shared']" />
|
||||
<template v-if="!renaming">
|
||||
<h3
|
||||
class="folder__title"
|
||||
:title="folder.title"
|
||||
@click="onSelect">
|
||||
:title="folder.title">
|
||||
{{ folder.title }}
|
||||
</h3>
|
||||
|
||||
<div class="folder__tags">
|
||||
<div v-if="!isOwner && !isPublic" class="folder__tag">
|
||||
<div v-if="!isOwner && !isSharedPublicly" class="folder__tag">
|
||||
{{ t('bookmarks', 'Shared by {user}', {user: folder.userId}) }}
|
||||
</div>
|
||||
<div v-if="isOwner && isShared" class="folder__tag">
|
||||
{{ t('bookmarks','Shared privately') }}
|
||||
</div>
|
||||
<div v-if="isSharedPublicly" class="folder__tag">
|
||||
{{ t('bookmarks', 'Public') }}
|
||||
</div>
|
||||
</div>
|
||||
<Actions v-if="isEditable" class="folder__actions">
|
||||
<div v-if="count" class="folder__count folder__tag" v-text="count" />
|
||||
<Actions v-if="isEditable" ref="actions" class="folder__actions">
|
||||
<ActionButton icon="icon-info" @click="onDetails">
|
||||
{{ t('bookmarks', 'Details') }}
|
||||
</ActionButton>
|
||||
|
@ -59,6 +56,8 @@
|
|||
<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/'
|
||||
|
@ -68,6 +67,8 @@ export default {
|
|||
components: {
|
||||
Actions,
|
||||
ActionButton,
|
||||
FolderIcon,
|
||||
ShareVariantIcon,
|
||||
},
|
||||
props: {
|
||||
folder: {
|
||||
|
@ -113,6 +114,9 @@ export default {
|
|||
selected() {
|
||||
return this.selectedFolders.map(f => f.id).includes(this.folder.id)
|
||||
},
|
||||
count() {
|
||||
return this.$store.state.countsByFolder[this.folder.id] > 99 ? '99+' : this.$store.state.countsByFolder[this.folder.id] || ''
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch(actions.LOAD_SHARES_OF_FOLDER, this.folder.id)
|
||||
|
@ -131,8 +135,10 @@ export default {
|
|||
this.$store.commit(mutations.ADD_SELECTION_FOLDER, this.folder)
|
||||
this.$store.commit(mutations.DISPLAY_MOVE_DIALOG, true)
|
||||
},
|
||||
onSelect() {
|
||||
onSelect(e) {
|
||||
if (this.$refs.actions.$el.contains(e.target)) return
|
||||
this.$router.push({ name: this.routes.FOLDER, params: { folder: this.folder.id } })
|
||||
e.preventDefault()
|
||||
},
|
||||
async onRename() {
|
||||
this.renaming = true
|
||||
|
@ -144,12 +150,13 @@ export default {
|
|||
this.$store.dispatch(actions.SAVE_FOLDER, this.folder.id)
|
||||
this.renaming = false
|
||||
},
|
||||
clickSelect() {
|
||||
clickSelect(e) {
|
||||
if (!this.selected) {
|
||||
this.$store.commit(mutations.ADD_SELECTION_FOLDER, this.folder)
|
||||
} else {
|
||||
this.$store.commit(mutations.REMOVE_SELECTION_FOLDER, this.folder)
|
||||
}
|
||||
e.stopPropagation()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -191,27 +198,28 @@ export default {
|
|||
background-size: cover;
|
||||
margin: 15px;
|
||||
cursor: pointer;
|
||||
background-image: url('/svg/core/filetypes/folder?color=0082c9'), url('/index.php/svg/core/filetypes/folder?color=0082c9'), var(--icon-folder-000);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.folder__icon.shared {
|
||||
background-image: var(--icon-share-fff), url('/svg/core/filetypes/folder?color=0082c9'), url('/index.php/svg/core/filetypes/folder?color=0082c9'), var(--icon-folder-000);
|
||||
background-size: 9px, cover, cover, cover !important;
|
||||
}
|
||||
|
||||
.folder--gridview .folder__icon.shared {
|
||||
background-size: 30px, cover, cover, cover !important;
|
||||
transform: scale(0.5);
|
||||
position: absolute;
|
||||
left: 35px;
|
||||
top: 2px;
|
||||
height:auto;
|
||||
width:auto;
|
||||
}
|
||||
|
||||
.folder--gridview .folder__icon {
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
left: calc(45% - 35px);
|
||||
transform: scale(3);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.folder--gridview .folder__icon.shared {
|
||||
transform: translate(100%, 90%);
|
||||
}
|
||||
|
||||
.folder__title {
|
||||
|
@ -253,8 +261,22 @@ export default {
|
|||
background-color: var(--color-primary-light);
|
||||
}
|
||||
|
||||
.folder__count {
|
||||
font-size: 12px;
|
||||
height: 24px;
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.folder--gridview .folder__count {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.folder__actions {
|
||||
flex: 0;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.folder__title input {
|
||||
|
|
|
@ -1,59 +1,61 @@
|
|||
<template>
|
||||
<AppNavigation>
|
||||
<AppNavigation class="navigation">
|
||||
<AppNavigationNew
|
||||
v-if="!isPublic"
|
||||
:text="t('bookmarks', 'New Bookmark')"
|
||||
:disabled="false"
|
||||
button-class="icon-add"
|
||||
@click="onNewBookmark" />
|
||||
<template #list>
|
||||
<AppNavigationNew
|
||||
v-if="!isPublic"
|
||||
:text="t('bookmarks', 'New Bookmark')"
|
||||
:disabled="false"
|
||||
button-class="icon-add"
|
||||
@click="onNewBookmark" />
|
||||
<ul>
|
||||
<AppNavigationItem key="menu-home"
|
||||
:to="{ name: routes.HOME }"
|
||||
icon="icon-home"
|
||||
:title="t('bookmarks', 'All Bookmarks')">
|
||||
<AppNavigationCounter slot="counter">
|
||||
{{ allBookmarksCount }}
|
||||
</AppNavigationCounter>
|
||||
</AppNavigationItem>
|
||||
<AppNavigationItem key="menu-recent"
|
||||
:to="{ name: routes.RECENT }"
|
||||
icon="icon-category-monitoring"
|
||||
:title="t('bookmarks', 'Recent Bookmarks')" />
|
||||
<AppNavigationItem key="menu-untagged"
|
||||
:to="{ name: routes.UNAVAILABLE }"
|
||||
icon="icon-link"
|
||||
:title="t('bookmarks', 'Unavailable')" />
|
||||
<AppNavigationItem key="menu-untagged"
|
||||
:to="{ name: routes.UNTAGGED }"
|
||||
icon="icon-category-disabled"
|
||||
:title="t('bookmarks', 'Untagged')" />
|
||||
<AppNavigationSpacer />
|
||||
<AppNavigationItem v-for="tag in tags"
|
||||
:key="'tag-'+tag.name"
|
||||
icon="icon-tag"
|
||||
:to="tag.route"
|
||||
:force-menu="true"
|
||||
:edit-label="t('bookmarks', 'Rename')"
|
||||
:editable="!isPublic"
|
||||
:title="tag.name"
|
||||
@update:title="onRenameTag(tag.name, $event)">
|
||||
<AppNavigationCounter slot="counter">
|
||||
{{ tag.count }}
|
||||
</AppNavigationCounter>
|
||||
<template v-if="!isPublic" slot="actions">
|
||||
<ActionButton icon="icon-delete" @click="onDeleteTag(tag.name)">
|
||||
{{ t('bookmarks', 'Delete') }}
|
||||
</ActionButton>
|
||||
</template>
|
||||
</AppNavigationItem>
|
||||
<template v-if="Number(bookmarksLimit) > 0">
|
||||
<AppNavigationSpacer />
|
||||
<AppNavigationItem :pinned="true" icon="icon-quota" :title="t('bookmarks', '{used} bookmarks of {available} available', {used: allBookmarksCount, available: bookmarksLimit})">
|
||||
<ProgressBar :val="allBookmarksCount" :max="bookmarksLimit" />
|
||||
</AppNavigationItem>
|
||||
<AppNavigationItem key="menu-home"
|
||||
:to="{ name: routes.HOME }"
|
||||
icon="icon-home"
|
||||
:title="t('bookmarks', 'All Bookmarks')"
|
||||
:exact="true">
|
||||
<AppNavigationCounter slot="counter">
|
||||
{{ allBookmarksCount }}
|
||||
</AppNavigationCounter>
|
||||
</AppNavigationItem>
|
||||
<AppNavigationItem key="menu-recent"
|
||||
:to="{ name: routes.RECENT }"
|
||||
:title="t('bookmarks', 'Recent Bookmarks')">
|
||||
<HistoryIcon slot="icon" :size="18" />
|
||||
</AppNavigationItem>
|
||||
<AppNavigationItem key="menu-unavailable"
|
||||
:to="{ name: routes.UNAVAILABLE }"
|
||||
:title="t('bookmarks', 'Unavailable')">
|
||||
<LinkVariantOffIcon slot="icon" :size="18" />
|
||||
</AppNavigationItem>
|
||||
<AppNavigationSpacer />
|
||||
<AppNavigationItem key="menu-untagged"
|
||||
:to="{ name: routes.UNTAGGED }"
|
||||
:title="t('bookmarks', 'Untagged')">
|
||||
<TagOffIcon slot="icon" :size="18" />
|
||||
</AppNavigationItem>
|
||||
<AppNavigationItem v-for="tag in tags"
|
||||
:key="'tag-'+tag.name"
|
||||
icon="icon-tag"
|
||||
:to="tag.route"
|
||||
:force-menu="true"
|
||||
:edit-label="t('bookmarks', 'Rename')"
|
||||
:editable="!isPublic"
|
||||
:title="tag.name"
|
||||
@update:title="onRenameTag(tag.name, $event)">
|
||||
<AppNavigationCounter slot="counter">
|
||||
{{ tag.count }}
|
||||
</AppNavigationCounter>
|
||||
<template v-if="!isPublic" slot="actions">
|
||||
<ActionButton icon="icon-delete" @click="onDeleteTag(tag.name)">
|
||||
{{ t('bookmarks', 'Delete') }}
|
||||
</ActionButton>
|
||||
</template>
|
||||
</ul>
|
||||
</AppNavigationItem>
|
||||
<template v-if="Number(bookmarksLimit) > 0">
|
||||
<AppNavigationSpacer />
|
||||
<AppNavigationItem :pinned="true" icon="icon-quota" :title="t('bookmarks', '{used} bookmarks of {available} available', {used: allBookmarksCount, available: bookmarksLimit})">
|
||||
<ProgressBar :val="allBookmarksCount" :max="bookmarksLimit" />
|
||||
</AppNavigationItem>
|
||||
</template>
|
||||
</template>
|
||||
<template #footer>
|
||||
<AppNavigationSettings v-if="!isPublic">
|
||||
|
@ -71,6 +73,9 @@ import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCo
|
|||
import AppNavigationSettings from '@nextcloud/vue/dist/Components/AppNavigationSettings'
|
||||
import AppNavigationSpacer from '@nextcloud/vue/dist/Components/AppNavigationSpacer'
|
||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
import HistoryIcon from 'vue-material-design-icons/History'
|
||||
import TagOffIcon from 'vue-material-design-icons/TagOff'
|
||||
import LinkVariantOffIcon from 'vue-material-design-icons/LinkVariantOff'
|
||||
import ProgressBar from 'vue-simple-progress'
|
||||
import Settings from './Settings'
|
||||
import { actions, mutations } from '../store/'
|
||||
|
@ -87,6 +92,9 @@ export default {
|
|||
ActionButton,
|
||||
Settings,
|
||||
ProgressBar,
|
||||
HistoryIcon,
|
||||
TagOffIcon,
|
||||
LinkVariantOffIcon,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
|
@ -126,3 +134,9 @@ export default {
|
|||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.navigation .material-design-icon {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
</style>
|
||||
|
|
15
webpack.js
15
webpack.js
|
@ -8,6 +8,19 @@ const config = {
|
|||
'service-worker': path.join(__dirname, 'src', 'service-worker.js'),
|
||||
flow: path.join(__dirname, 'src', 'flow.js'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = merge(config, webpackConfig)
|
||||
const mergedConfigs = merge(config, webpackConfig)
|
||||
|
||||
// Remove duplicate rules by the `test` key
|
||||
mergedConfigs.module.rules = mergedConfigs.module.rules.filter((v, i, a) => a.findIndex(t => (t.test.toString() === v.test.toString())) === i)
|
||||
|
||||
module.exports = mergedConfigs
|
||||
|
|
Loading…
Reference in New Issue