Upgrade "@nextcloud/vue": "^7.2.0" and use md icons consistently

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
This commit is contained in:
Marcel Klehr 2022-12-12 17:44:09 +01:00
parent 3a2d033ecc
commit aa5ec41906
24 changed files with 4928 additions and 16490 deletions

20238
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
"@nextcloud/event-bus": "^2.1.1", "@nextcloud/event-bus": "^2.1.1",
"@nextcloud/initial-state": "^1.2.1", "@nextcloud/initial-state": "^1.2.1",
"@nextcloud/router": "^2.0.0", "@nextcloud/router": "^2.0.0",
"@nextcloud/vue": "^5.4.0", "@nextcloud/vue": "^7.2.0",
"@nextcloud/vue-dashboard": "^2.0.1", "@nextcloud/vue-dashboard": "^2.0.1",
"async-parallel": "^1.2.3", "async-parallel": "^1.2.3",
"clone-deep": "^4.0.1", "clone-deep": "^4.0.1",
@ -50,9 +50,9 @@
"devDependencies": { "devDependencies": {
"@nextcloud/babel-config": "^1.0.0", "@nextcloud/babel-config": "^1.0.0",
"@nextcloud/browserslist-config": "^2.3.0", "@nextcloud/browserslist-config": "^2.3.0",
"@nextcloud/eslint-config": "^6", "@nextcloud/eslint-config": "^8.1.4",
"@nextcloud/stylelint-config": "^2", "@nextcloud/stylelint-config": "^2",
"@nextcloud/webpack-vue-config": "^4", "@nextcloud/webpack-vue-config": "^5.4.0",
"@vue/test-utils": "^1.3.0" "@vue/test-utils": "^1.3.0"
}, },
"engines": { "engines": {

View File

@ -5,8 +5,7 @@
--> -->
<template> <template>
<Item <Item :title="bookmark.title"
:title="bookmark.title"
:tags="bookmark.tags" :tags="bookmark.tags"
:rename-placeholder="t('bookmarks', 'Enter new title')" :rename-placeholder="t('bookmarks', 'Enter new title')"
:select-label="t('bookmarks', 'Select bookmark')" :select-label="t('bookmarks', 'Select bookmark')"
@ -26,76 +25,76 @@
<div class="bookmark__title"> <div class="bookmark__title">
<h3 :title="bookmark.title"> <h3 :title="bookmark.title">
<span v-if="bookmark.preliminary" class="icon-loading-small bookmark__icon" /> <span v-if="bookmark.preliminary" class="icon-loading-small bookmark__icon" />
<figure <figure v-else
v-else
class="bookmark__icon" class="bookmark__icon"
:style="{ backgroundImage: 'url(' + iconUrl + ')' }" /> :style="{ backgroundImage: 'url(' + iconUrl + ')' }" />
{{ bookmark.title }} {{ bookmark.title }}
</h3> </h3>
<span <span v-if="bookmark.description"
v-if="bookmark.description"
v-tooltip="bookmark.description" v-tooltip="bookmark.description"
class="bookmark__description"><figure class="icon-file" /> class="bookmark__description"><figure class="icon-file" />
{{ bookmark.description }}</span> {{ bookmark.description }}</span>
</div> </div>
</template> </template>
<template #actions> <template #actions>
<ActionButton <NcActionButton :close-after-click="true"
icon="icon-info"
:close-after-click="true"
@click="onDetails"> @click="onDetails">
<template #icon>
<InformationVariantIcon />
</template>
{{ t('bookmarks', 'Details') }} {{ t('bookmarks', 'Details') }}
</ActionButton> </NcActionButton>
<ActionCheckbox @change="onSelect"> <NcActionCheckbox @change="onSelect">
{{ t('bookmarks', 'Select bookmark') }} {{ t('bookmarks', 'Select bookmark') }}
</ActionCheckbox> </NcActionCheckbox>
<ActionButton <NcActionButton :close-after-click="true"
icon="icon-rename"
:close-after-click="true"
@click="onRename"> @click="onRename">
<template #icon>
<PencilIcon />
</template>
{{ t('bookmarks', 'Rename') }} {{ t('bookmarks', 'Rename') }}
</ActionButton> </NcActionButton>
<ActionButton <NcActionButton :close-after-click="true"
:close-after-click="true"
@click="onCopyUrl"> @click="onCopyUrl">
<template #icon> <template #icon>
<ContentCopyIcon :fill-color="colorMainText" /> <ContentCopyIcon />
</template> </template>
{{ t('bookmarks', 'Copy link') }} {{ t('bookmarks', 'Copy link') }}
</ActionButton> </NcActionButton>
<ActionButton :close-after-click="true" @click="onMove"> <NcActionButton :close-after-click="true" @click="onMove">
<template #icon> <template #icon>
<FolderMoveIcon <FolderMoveIcon />
:fill-color="colorMainText" />
</template> </template>
{{ t('bookmarks', 'Move') }} {{ t('bookmarks', 'Move') }}
</ActionButton> </NcActionButton>
<ActionButton :close-after-click="true" @click="onCopy"> <NcActionButton :close-after-click="true" @click="onCopy">
<template #icon> <template #icon>
<FolderPlusIcon <FolderPlusIcon />
:fill-color="colorMainText" />
</template> </template>
{{ t('bookmarks', 'Add to folders') }} {{ t('bookmarks', 'Add to folders') }}
</ActionButton> </NcActionButton>
<ActionButton <NcActionButton :close-after-click="true"
icon="icon-delete"
:close-after-click="true"
@click="onDelete"> @click="onDelete">
<template #icon>
<DeleteIcon />
</template>
{{ t('bookmarks', 'Delete') }} {{ t('bookmarks', 'Delete') }}
</ActionButton> </NcActionButton>
</template> </template>
</Item> </Item>
</template> </template>
<script> <script>
import Item from './Item' import Item from './Item.vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import { NcActionButton, NcActionCheckbox } from '@nextcloud/vue'
import ActionCheckbox from '@nextcloud/vue/dist/Components/ActionCheckbox' import FolderPlusIcon from 'vue-material-design-icons/FolderPlus.vue'
import FolderPlusIcon from 'vue-material-design-icons/FolderPlus' import FolderMoveIcon from 'vue-material-design-icons/FolderMove.vue'
import FolderMoveIcon from 'vue-material-design-icons/FolderMove' import ContentCopyIcon from 'vue-material-design-icons/ContentCopy.vue'
import ContentCopyIcon from 'vue-material-design-icons/ContentCopy' import PencilIcon from 'vue-material-design-icons/Pencil.vue'
import InformationVariantIcon from 'vue-material-design-icons/InformationVariant.vue'
import DeleteIcon from 'vue-material-design-icons/Delete.vue'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
import { actions, mutations } from '../store/' import { actions, mutations } from '../store/index.js'
import copy from 'copy-text-to-clipboard' import copy from 'copy-text-to-clipboard'
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'
@ -103,11 +102,14 @@ export default {
name: 'Bookmark', name: 'Bookmark',
components: { components: {
Item, Item,
ActionButton, NcActionButton,
ActionCheckbox, NcActionCheckbox,
FolderPlusIcon, FolderPlusIcon,
FolderMoveIcon, FolderMoveIcon,
ContentCopyIcon, ContentCopyIcon,
PencilIcon,
InformationVariantIcon,
DeleteIcon,
}, },
props: { props: {
bookmark: { bookmark: {

View File

@ -13,26 +13,27 @@
</template> </template>
<div v-else-if="bookmark.textContent" class="content" v-html="content" /> <div v-else-if="bookmark.textContent" class="content" v-html="content" />
<div v-else> <div v-else>
<EmptyContent icon="icon-download"> <NcEmptyContent :title="t('bookmarks', 'Content pending')"
{{ t('bookmarks', 'Content pending') }} :description="t('bookmarks', 'This content is being downloaded for offline use. Please check back later.')">
<template #desc> <template #icon>
{{ t('bookmarks', 'This content is being downloaded for offline use. Please check back later.') }} <DownloadIcon />
</template> </template>
</EmptyContent> </NcEmptyContent>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import DownloadIcon from 'vue-material-design-icons/Download.vue'
import sanitizeHtml from 'sanitize-html' import sanitizeHtml from 'sanitize-html'
import { generateUrl, generateRemoteUrl } from '@nextcloud/router' import { generateUrl, generateRemoteUrl } from '@nextcloud/router'
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent' import { NcEmptyContent } from '@nextcloud/vue'
const MIN_TEXT_LENGTH = 350 const MIN_TEXT_LENGTH = 350
export default { export default {
name: 'BookmarkContent', name: 'BookmarkContent',
components: { EmptyContent }, components: { NcEmptyContent, DownloadIcon },
computed: { computed: {
isActive() { isActive() {
if (!this.$store.state.sidebar) return false if (!this.$store.state.sidebar) return false
@ -68,7 +69,7 @@ export default {
<style> <style>
.bookmark-content { .bookmark-content {
position: absolute; position: absolute;
top: 50px;/* nc header bar */ top: 0;
left: 0; left: 0;
right: max( min(27vw, 500px), 300px); /* side bar */ right: max( min(27vw, 500px), 300px); /* side bar */
bottom: 0; bottom: 0;

View File

@ -6,62 +6,77 @@
<template> <template>
<div class="bulkediting"> <div class="bulkediting">
<Actions :primary="true" :menu-title="selectionDescription"> <NcActions :primary="true" :menu-title="selectionDescription">
<ActionButton icon="icon-external" close-after-click @click="onBulkOpen"> <NcActionButton close-after-click @click="onBulkOpen">
{{ t('bookmarks', 'Open all selected') }}
</ActionButton>
<ActionButton close-after-click @click="onBulkMove">
<template #icon> <template #icon>
<FolderMoveIcon :fill-color="colorMainText" class="action-button-mdi-icon" /> <OpenInNewIcon />
</template>
{{ t('bookmarks', 'Open all selected') }}
</NcActionButton>
<NcActionButton close-after-click @click="onBulkMove">
<template #icon>
<FolderMoveIcon />
</template> </template>
{{ t('bookmarks', 'Move selection') }} {{ t('bookmarks', 'Move selection') }}
</ActionButton> </NcActionButton>
<ActionButton v-if="!selectedFolders.length" close-after-click @click="onBulkCopy"> <NcActionButton v-if="!selectedFolders.length" close-after-click @click="onBulkCopy">
<template #icon> <template #icon>
<FolderPlusIcon :fill-color="colorMainText" class="action-button-mdi-icon" /> <FolderPlusIcon />
</template> </template>
{{ t('bookmarks', 'Add to folders') }} {{ t('bookmarks', 'Add to folders') }}
</ActionButton> </NcActionButton>
<ActionInput <NcActionInput v-if="!selectedFolders.length"
v-if="!selectedFolders.length"
:value="selectionTags" :value="selectionTags"
icon="icon-tag"
type="multiselect" type="multiselect"
:options="allTags" :options="allTags"
:multiple="true" :multiple="true"
:taggable="true" :taggable="true"
@tag="onBulkTag([...selectionTags, $event])" @tag="onBulkTag([...selectionTags, $event])"
@input="onBulkTag"> @input="onBulkTag">
<template #icon>
<TagIcon />
</template>
{{ t('bookmarks', 'Edit tags of selection') }} {{ t('bookmarks', 'Edit tags of selection') }}
</ActionInput> </NcActionInput>
<ActionButton icon="icon-delete" close-after-click @click="onBulkDelete"> <NcActionButton close-after-click @click="onBulkDelete">
<template #icon>
<DeleteIcon />
</template>
{{ t('bookmarks', 'Delete selection') }} {{ t('bookmarks', 'Delete selection') }}
</ActionButton> </NcActionButton>
<ActionSeparator /> <NcActionSeparator />
<ActionButton icon="icon-checkmark" @click="onSelectAll"> <NcActionButton @click="onSelectAll">
<template #icon>
<SelectAllIcon />
</template>
{{ t('bookmarks', 'Select all') }} {{ t('bookmarks', 'Select all') }}
</ActionButton> </NcActionButton>
<ActionButton icon="icon-close" @click="onCancelSelection"> <NcActionButton @click="onCancelSelection">
<template #icon>
<SelectOffIcon />
</template>
{{ t('bookmarks', 'Cancel selection') }} {{ t('bookmarks', 'Cancel selection') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
</div> </div>
</template> </template>
<script> <script>
import Actions from '@nextcloud/vue/dist/Components/Actions' import { NcActions, NcActionSeparator, NcActionButton, NcActionInput } from '@nextcloud/vue'
import ActionInput from '@nextcloud/vue/dist/Components/ActionInput' import FolderPlusIcon from 'vue-material-design-icons/FolderPlus.vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import FolderMoveIcon from 'vue-material-design-icons/FolderMove.vue'
import ActionSeparator from '@nextcloud/vue/dist/Components/ActionSeparator' import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
import FolderPlusIcon from 'vue-material-design-icons/FolderPlus' import TagIcon from 'vue-material-design-icons/Tag.vue'
import FolderMoveIcon from 'vue-material-design-icons/FolderMove' import SelectAllIcon from 'vue-material-design-icons/SelectAll.vue'
import { actions, mutations } from '../store' import SelectOffIcon from 'vue-material-design-icons/SelectOff.vue'
import intersection from 'lodash/intersection' import DeleteIcon from 'vue-material-design-icons/Delete.vue'
import { actions, mutations } from '../store/index.js'
import intersection from 'lodash/intersection.js'
export default { export default {
name: 'BulkEditing', name: 'BulkEditing',
components: { ActionInput, ActionSeparator, FolderPlusIcon, FolderMoveIcon, ActionButton, Actions }, components: { NcActionInput, NcActionSeparator, FolderPlusIcon, FolderMoveIcon, NcActionButton, NcActions, OpenInNewIcon, TagIcon, SelectAllIcon, SelectOffIcon, DeleteIcon },
data() { data() {
return { return {
selectionTags: [], selectionTags: [],
@ -151,5 +166,6 @@ export default {
opacity: 1 !important; opacity: 1 !important;
padding: 0 !important; padding: 0 !important;
margin-top: 1px; margin-top: 1px;
min-width: 500px;
} }
</style> </style>

View File

@ -7,24 +7,28 @@
<template> <template>
<div :class="['controls', $store.state.public && 'wide']"> <div :class="['controls', $store.state.public && 'wide']">
<div class="controls__left"> <div class="controls__left">
<Actions v-if="$route.name === routes.FOLDER"> <NcActions v-if="$route.name === routes.FOLDER">
<ActionButton @click="onClickBack"> <NcActionButton @click="onClickBack">
<ArrowLeftIcon slot="icon" :size="18" :fill-color="colorMainText" /> <template #icon>
<ArrowLeftIcon />
</template>
{{ t('bookmarks', 'Go back') }} {{ t('bookmarks', 'Go back') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
<template v-if="$route.name === routes.FOLDER"> <template v-if="$route.name === routes.FOLDER">
<h2><FolderIcon :size="18" :fill-color="colorMainText" /> <span>{{ folder.title }}</span></h2> <h2><FolderIcon /> <span>{{ folder.title }}</span></h2>
<Actions v-if="permissions.canShare"> <NcActions v-if="permissions.canShare">
<ActionButton icon="icon-share" :close-after-click="true" @click="onOpenFolderShare"> <NcActionButton :close-after-click="true" @click="onOpenFolderShare">
<template #icon>
<ShareVariantIcon />
</template>
{{ t('bookmarks', 'Share folder') }} {{ t('bookmarks', 'Share folder') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
</template> </template>
<template v-if="$route.name === routes.TAGS"> <template v-if="$route.name === routes.TAGS">
<span class="icon-tag" /> <TagIcon />
<Multiselect <NcMultiselect class="controls__tags"
class="controls__tags"
:value="tags" :value="tags"
:auto-limit="false" :auto-limit="false"
:limit="7" :limit="7"
@ -33,101 +37,102 @@
:placeholder="t('bookmarks', 'Select one or more tags')" :placeholder="t('bookmarks', 'Select one or more tags')"
@input="onTagsChange" /> @input="onTagsChange" />
</template> </template>
<Actions <NcActions v-if="!isPublic"
v-if="!isPublic"
v-tooltip="t('bookmarks', 'New')" v-tooltip="t('bookmarks', 'New')"
:title="t('bookmarks', 'New')" :title="t('bookmarks', 'New')">
:default-icon="'icon-add'"> <template #icon>
<ActionButton <PlusIcon />
icon="icon-link" </template>
:close-after-click="true" <NcActionButton :close-after-click="true"
@click="onAddBookmark"> @click="onAddBookmark">
<template #icon>
<EarthIcon />
</template>
{{ {{
t('bookmarks', 'New bookmark') t('bookmarks', 'New bookmark')
}} }}
</ActionButton> </NcActionButton>
<ActionButton <NcActionButton :close-after-click="true"
icon="icon-folder"
:close-after-click="true"
@click="onAddFolder"> @click="onAddFolder">
<template #icon>
<FolderIcon />
</template>
{{ t('bookmarks', 'New folder') }} {{ t('bookmarks', 'New folder') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
<BulkEditing v-if="hasSelection" /> <BulkEditing v-if="hasSelection" />
</div> </div>
<div class="controls__right"> <div class="controls__right">
<Actions> <NcActions>
<ActionButton <NcActionButton @click="onToggleViewMode">
:icon=" <template #icon>
viewMode === 'list' <ViewListIcon v-if="viewMode !== 'list'" />
? 'icon-toggle-pictures' <ViewGridIcon v-else />
: 'icon-toggle-filelist' </template>
"
@click="onToggleViewMode">
{{ viewMode === 'list' ? t('bookmarks', 'Change to grid view') : t('bookmarks', 'Change to list view') }} {{ viewMode === 'list' ? t('bookmarks', 'Change to grid view') : t('bookmarks', 'Change to list view') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
<Actions v-tooltip="sortingOptions[sorting].description"> <NcActions v-tooltip="sortingOptions[sorting].description">
<template #icon> <template #icon>
<component :is="sortingOptions[sorting].icon" :size="20" :fill-color="colorMainText" /> <component :is="sortingOptions[sorting].icon" :size="20" :fill-color="colorMainText" />
</template> </template>
<ActionButton v-for="(option, key) in sortingOptions" <NcActionButton v-for="(option, key) in sortingOptions"
:key="key" :key="key"
:close-after-click="true" :close-after-click="true"
@click="onChangeSorting(key)"> @click="onChangeSorting(key)">
<template #icon> <template #icon>
<component :is="option.icon" <component :is="option.icon"
:size="20"
:fill-color="key === sorting? colorPrimaryElement : colorMainText" /> :fill-color="key === sorting? colorPrimaryElement : colorMainText" />
</template> </template>
{{ option.description }} {{ option.description }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
<Actions force-menu> <NcActions force-menu>
<template #icon> <template #icon>
<RssIcon :fill-color="colorMainText" :size="20" class="action-button-mdi-icon" /> <RssIcon />
</template> </template>
<ActionButton <NcActionButton :title="t('bookmarks', 'Copy RSS Feed of current view')"
:title="t('bookmarks', 'Copy RSS Feed of current view')"
:close-after-click="true" :close-after-click="true"
@click="copyRssUrl"> @click="copyRssUrl">
<template #icon> <template #icon>
<RssIcon :fill-color="colorMainText" :size="20" class="action-button-mdi-icon" /> <RssIcon />
</template> </template>
{{ !$store.state.public? t('bookmarks', 'The RSS feed requires authentication with your Nextcloud credentials') : '' }} {{ !$store.state.public? t('bookmarks', 'The RSS feed requires authentication with your Nextcloud credentials') : '' }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect' import { NcMultiselect, NcActions, NcActionButton, NcActionInput, NcActionRouter } from '@nextcloud/vue'
import Actions from '@nextcloud/vue/dist/Components/Actions' import EarthIcon from 'vue-material-design-icons/Earth.vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import ViewGridIcon from 'vue-material-design-icons/ViewGrid.vue'
import ActionInput from '@nextcloud/vue/dist/Components/ActionInput' import ViewListIcon from 'vue-material-design-icons/ViewList.vue'
import ActionRouter from '@nextcloud/vue/dist/Components/ActionRouter' import PlusIcon from 'vue-material-design-icons/Plus.vue'
import FolderIcon from 'vue-material-design-icons/Folder' import FolderIcon from 'vue-material-design-icons/Folder.vue'
import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft' import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft.vue'
import RssIcon from 'vue-material-design-icons/Rss' import RssIcon from 'vue-material-design-icons/Rss.vue'
import SortAlphabeticalAscendingIcon from 'vue-material-design-icons/SortAlphabeticalAscending' import SortAlphabeticalAscendingIcon from 'vue-material-design-icons/SortAlphabeticalAscending.vue'
import SortBoolAscendingIcon from 'vue-material-design-icons/SortBoolAscending' import SortBoolAscendingIcon from 'vue-material-design-icons/SortBoolAscending.vue'
import SortClockAscendingOutlineIcon from 'vue-material-design-icons/SortClockAscendingOutline' import SortClockAscendingOutlineIcon from 'vue-material-design-icons/SortClockAscendingOutline.vue'
import SortCalendarAscendingIcon from 'vue-material-design-icons/SortCalendarAscending' import SortCalendarAscendingIcon from 'vue-material-design-icons/SortCalendarAscending.vue'
import SortAscendingIcon from 'vue-material-design-icons/SortAscending' import SortAscendingIcon from 'vue-material-design-icons/SortAscending.vue'
import { actions, mutations } from '../store/' import ShareVariantIcon from 'vue-material-design-icons/ShareVariant.vue'
import TagIcon from 'vue-material-design-icons/Tag.vue'
import { actions, mutations } from '../store/index.js'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
import BulkEditing from './BulkEditing' import BulkEditing from './BulkEditing.vue'
import copy from 'copy-text-to-clipboard' import copy from 'copy-text-to-clipboard'
export default { export default {
name: 'Controls', name: 'Controls',
components: { components: {
BulkEditing, BulkEditing,
Multiselect, NcMultiselect,
Actions, NcActions,
ActionButton, NcActionButton,
ActionInput, NcActionInput,
ActionRouter, NcActionRouter,
RssIcon, RssIcon,
SortAscendingIcon, SortAscendingIcon,
SortCalendarAscendingIcon, SortCalendarAscendingIcon,
@ -136,6 +141,12 @@ export default {
SortBoolAscendingIcon, SortBoolAscendingIcon,
FolderIcon, FolderIcon,
ArrowLeftIcon, ArrowLeftIcon,
PlusIcon,
ViewGridIcon,
ViewListIcon,
EarthIcon,
ShareVariantIcon,
TagIcon,
}, },
props: {}, props: {},
data() { data() {
@ -277,7 +288,7 @@ export default {
</script> </script>
<style> <style>
.controls { .controls {
padding: 0 8px 0 44px; padding: 4px 8px 0 44px;
display: flex; display: flex;
position: absolute; position: absolute;
z-index: 100; z-index: 100;
@ -291,9 +302,8 @@ export default {
.controls h2 { .controls h2 {
margin: 0; margin: 0;
margin-left: 10px; margin-left: 10px;
margin-right: 10px;
display: flex; display: flex;
position: relative;
top: -2px;
flex-shrink: 0; flex-shrink: 0;
} }
@ -301,11 +311,6 @@ export default {
margin-left: 5px; margin-left: 5px;
} }
.controls h2 > .material-design-icon {
position: relative;
top: 3px;
}
.controls .action-item { .controls .action-item {
height: 45px; height: 45px;
} }
@ -334,12 +339,6 @@ export default {
flex: 1; flex: 1;
} }
.controls__tags .multiselect__tags {
border-top: none !important;
border-left: none !important;
border-right: none !important;
}
.controls__right { .controls__right {
flex: 2; flex: 2;
display: flex; display: flex;

View File

@ -5,25 +5,25 @@
--> -->
<template> <template>
<Modal v-if="showModal" :title="title" @close="onClose"> <NcModal v-if="showNcModal" :title="title" @close="onClose">
<div class="copy-dialog"> <div class="copy-dialog">
<FolderPicker :title="title" :filter="filterFolders" @submit="onSubmit" /> <FolderPicker :title="title" :filter="filterFolders" @submit="onSubmit" />
</div> </div>
</Modal> </NcModal>
</template> </template>
<script> <script>
import Modal from '@nextcloud/vue/dist/Components/Modal' import { NcModal } from '@nextcloud/vue'
import { actions, mutations } from '../store/' import { actions, mutations } from '../store/index.js'
import FolderPicker from './FolderPicker' import FolderPicker from './FolderPicker.vue'
export default { export default {
name: 'CopyDialog', name: 'CopyDialog',
components: { components: {
FolderPicker, FolderPicker,
Modal, NcModal,
}, },
computed: { computed: {
showModal() { showNcModal() {
return this.$store.state.displayCopyDialog return this.$store.state.displayCopyDialog
}, },
selection() { selection() {
@ -40,7 +40,7 @@ export default {
methods: { methods: {
async onSubmit(folderId) { async onSubmit(folderId) {
this.$store.commit(mutations.DISPLAY_COPY_DIALOG, false) this.$store.commit(mutations.DISPLAY_COPY_DIALOG, false)
await this.$store.dispatch(actions.COPY_SELECTION, folderId) await this.$store.dispatch(actions.NcNcModal, folderId)
this.$store.commit(mutations.RESET_SELECTION) this.$store.commit(mutations.RESET_SELECTION)
}, },
onClose() { onClose() {

View File

@ -6,41 +6,52 @@
<template> <template>
<div class="bookmarkslist__emptyBookmarks"> <div class="bookmarkslist__emptyBookmarks">
<EmptyContent icon="icon-favorite"> <NcEmptyContent :title="t('bookmarks', 'Welcome to Bookmarks')" :description="t('bookmarks', 'This app allows you to manage links to your favorite places on the web. Sort your bookmarks into folders, label them with tags and share them with others! The app will regularly check all your links for availability and display unavailable links. If you add a link to a file on the web, the file will be automatically downloaded to your Nextcloud Files. You can also import bookmarks exported from other services or directly sync bookmarks from all your browsers with this app.')">
{{ t('bookmarks', 'Welcome to Bookmarks') }} <template #icon>
<template #desc> <StarShootingIcon />
<p>{{ t('bookmarks', 'This app allows you to manage links to your favorite places on the web.') }}</p> </template>
<p /> <template #action>
<p>{{ t('bookmarks', 'Sort your bookmarks into folders, label them with tags and share them with others! The app will regularly check all your links for availability and display unavailable links. If you add a link to a file on the web, the file will be automatically downloaded to your Nextcloud Files. You can also import bookmarks exported from other services or directly sync bookmarks from all your browsers with this app.') }}</p>
<p />
<input ref="import" <input ref="import"
type="file" type="file"
class="import" class="import"
size="5" size="5"
@change="onImportSubmit"> @change="onImportSubmit">
<button @click="onCreateOpen"> <NcButton @click="onCreateOpen">
<template #icon>
<PlusIcon />
</template>
{{ t('bookmarks', 'Add a bookmark') }} {{ t('bookmarks', 'Add a bookmark') }}
</button> </NcButton>
<button @click="onImportOpen"> <NcButton @click="onImportOpen">
<span :class="{'icon-upload': !importing, 'icon-loading-small': importing}" /> {{ t('bookmarks', 'Import bookmarks') }} <template #icon>
</button> <UploadIcon v-if="!importing" />
<button @click="onSyncOpen"> <NcLoadingIcon v-else />
<SyncIcon :fill-color="colorMainText" :size="18" :style="{opacity: 0.5, display: 'inline'}" /> {{ t('bookmarks', 'Sync with your browser') }} </template>
</button> {{ t('bookmarks', 'Import bookmarks') }}
</NcButton>
<NcButton @click="onSyncOpen">
<template #icon>
<SyncIcon />
</template>
{{ t('bookmarks', 'Sync with your browser') }}
</NcButton>
</template> </template>
</EmptyContent> </NcEmptyContent>
</div> </div>
</template> </template>
<script> <script>
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent' import { NcEmptyContent, NcButton, NcLoadingIcon } from '@nextcloud/vue'
import { actions, mutations } from '../store' import { actions, mutations } from '../store/index.js'
import { privateRoutes } from '../router' import { privateRoutes } from '../router.js'
import SyncIcon from 'vue-material-design-icons/Sync' import SyncIcon from 'vue-material-design-icons/Sync.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import UploadIcon from 'vue-material-design-icons/Upload.vue'
import StarShootingIcon from 'vue-material-design-icons/StarShooting.vue'
export default { export default {
name: 'FirstRun', name: 'FirstRun',
components: { EmptyContent, SyncIcon }, components: { NcEmptyContent, SyncIcon, NcButton, PlusIcon, UploadIcon, NcLoadingIcon, StarShootingIcon },
data() { data() {
return { importing: false } return { importing: false }
}, },
@ -84,13 +95,7 @@ export default {
left: -1000px; left: -1000px;
} }
.material-design-icon { button {
position: relative;
top: 4px;
display: inline-flex;
}
p {
margin-bottom: 15px; margin-bottom: 15px;
} }
</style> </style>

View File

@ -39,52 +39,69 @@
</div> </div>
</template> </template>
<template #actions> <template #actions>
<ActionButton icon="icon-info" :close-after-click="true" @click="onDetails"> <NcActionButton :close-after-click="true" @click="onDetails">
<template #icon>
<InformationVariantIcon />
</template>
{{ t('bookmarks', 'Details') }} {{ t('bookmarks', 'Details') }}
</ActionButton> </NcActionButton>
<ActionCheckbox @change="clickSelect"> <NcActionCheckbox @change="clickSelect">
{{ t('bookmarks', 'Select folder') }} {{ t('bookmarks', 'Select folder') }}
</ActionCheckbox> </NcActionCheckbox>
<ActionButton v-if="permissions.canShare" <NcActionButton v-if="permissions.canShare"
icon="icon-share" icon="icon-share"
:close-after-click="true" :close-after-click="true"
@click="onShare"> @click="onShare">
<template #icon>
<ShareVariantIcon />
</template>
{{ t('bookmarks', 'Share folder') }} {{ t('bookmarks', 'Share folder') }}
</ActionButton> </NcActionButton>
<ActionButton icon="icon-rename" :close-after-click="true" @click="onRename"> <NcActionButton :close-after-click="true" @click="onRename">
<template #icon>
<PencilIcon />
</template>
{{ t('bookmarks', 'Rename folder') }} {{ t('bookmarks', 'Rename folder') }}
</ActionButton> </NcActionButton>
<ActionButton :close-after-click="true" @click="onMove"> <NcActionButton :close-after-click="true" @click="onMove">
<template #icon> <template #icon>
<FolderMoveIcon :fill-color="colorMainText" /> <FolderMoveIcon :fill-color="colorMainText" />
</template> </template>
{{ t('bookmarks', 'Move folder') }} {{ t('bookmarks', 'Move folder') }}
</ActionButton> </NcActionButton>
<ActionButton icon="icon-delete" :close-after-click="true" @click="onDelete"> <NcActionButton :close-after-click="true" @click="onDelete">
<template #icon>
<DeleteIcon />
</template>
{{ t('bookmarks', 'Delete folder') }} {{ t('bookmarks', 'Delete folder') }}
</ActionButton> </NcActionButton>
</template> </template>
</Item> </Item>
</template> </template>
<script> <script>
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import FolderMoveIcon from 'vue-material-design-icons/FolderMove' import FolderMoveIcon from 'vue-material-design-icons/FolderMove.vue'
import FolderIcon from 'vue-material-design-icons/Folder' import FolderIcon from 'vue-material-design-icons/Folder.vue'
import ShareVariantIcon from 'vue-material-design-icons/ShareVariant' import ShareVariantIcon from 'vue-material-design-icons/ShareVariant.vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import DeleteIcon from 'vue-material-design-icons/Delete.vue'
import ActionCheckbox from '@nextcloud/vue/dist/Components/ActionCheckbox' import PencilIcon from 'vue-material-design-icons/Pencil.vue'
import { actions, mutations } from '../store/' import InformationVariantIcon from 'vue-material-design-icons/InformationVariant.vue'
import Item from './Item' import { NcActionButton, NcActionCheckbox } from '@nextcloud/vue'
import { actions, mutations } from '../store/index.js'
import Item from './Item.vue'
export default { export default {
name: 'Folder', name: 'Folder',
components: { components: {
Item, Item,
ActionButton, NcActionButton,
ActionCheckbox, NcActionCheckbox,
FolderIcon, FolderIcon,
FolderMoveIcon, FolderMoveIcon,
ShareVariantIcon, ShareVariantIcon,
DeleteIcon,
PencilIcon,
InformationVariantIcon,
}, },
props: { props: {
folder: { folder: {

View File

@ -5,16 +5,16 @@
--> -->
<template> <template>
<AppContentList :show-details="showDetails" @update:show-details="$emit('update:show-details', $event)"> <NcAppContentList :show-details="showDetails" @update:show-details="$emit('update:show-details', $event)">
<TreeFolder v-for="folder in rootFolder.children" <TreeFolder v-for="folder in rootFolder.children"
:key="folder.id" :key="folder.id"
:folder="folder" :folder="folder"
@select="onSelect($event)" /> @select="onSelect($event)" />
</AppContentList> </NcAppContentList>
</template> </template>
<script> <script>
import AppContentList from '@nextcloud/vue/dist/Components/AppContentList' import { NcAppContentList } from '@nextcloud/vue'
import TreeFolder from './TreeFolder' import TreeFolder from './TreeFolder'
import { privateRoutes } from '../router' import { privateRoutes } from '../router'
@ -22,7 +22,7 @@ export default {
name: 'FolderOverview', name: 'FolderOverview',
components: { components: {
TreeFolder, TreeFolder,
AppContentList, NcAppContentList,
}, },
props: { props: {
showDetails: { showDetails: {

View File

@ -8,12 +8,12 @@
<div class="folderpicker"> <div class="folderpicker">
<h2>{{ title }}</h2> <h2>{{ title }}</h2>
<div class="currentfolder"> <div class="currentfolder">
<Actions v-if="currentFolder.id !== -1"> <NcActions v-if="currentFolder.id !== -1">
<ActionButton @click="onSelect(currentFolder.parent_folder)"> <NcActionButton @click="onSelect(currentFolder.parent_folder)">
<ArrowLeftIcon slot="icon" :size="18" :fill-color="colorMainText" /> <ArrowLeftIcon slot="icon" :size="18" :fill-color="colorMainText" />
{{ t('bookmarks', 'Go back') }} {{ t('bookmarks', 'Go back') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
<h2 v-if="currentFolder.id !== -1"> <h2 v-if="currentFolder.id !== -1">
<FolderIcon :fill-color="colorMainText" /><span>{{ currentFolder.title }}</span> <FolderIcon :fill-color="colorMainText" /><span>{{ currentFolder.title }}</span>
</h2> </h2>
@ -35,19 +35,18 @@
</template> </template>
<script> <script>
import Actions from '@nextcloud/vue/dist/Components/Actions' import { NcActions, NcActionButton } from '@nextcloud/vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import FolderIcon from 'vue-material-design-icons/Folder.vue'
import FolderIcon from 'vue-material-design-icons/Folder' import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft.vue'
import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft' import HomeIcon from 'vue-material-design-icons/Home.vue'
import HomeIcon from 'vue-material-design-icons/Home' import TreeFolder from './TreeFolder.vue'
import TreeFolder from './TreeFolder'
export default { export default {
name: 'FolderPicker', name: 'FolderPicker',
components: { components: {
TreeFolder, TreeFolder,
Actions, NcActions,
ActionButton, NcActionButton,
FolderIcon, FolderIcon,
ArrowLeftIcon, ArrowLeftIcon,
HomeIcon, HomeIcon,

View File

@ -5,21 +5,21 @@
--> -->
<template> <template>
<Modal v-if="show" :title="t('bookmarks', 'Select folder')" @close="onClose"> <NcModal v-if="show" :title="t('bookmarks', 'Select folder')" @close="onClose">
<div class="folderpicker-dialog"> <div class="folderpicker-dialog">
<FolderPicker :title="t('bookmarks', 'Select folder')" @submit="onSelect" /> <FolderPicker :title="t('bookmarks', 'Select folder')" @submit="onSelect" />
</div> </div>
</Modal> </NcModal>
</template> </template>
<script> <script>
import Modal from '@nextcloud/vue/dist/Components/Modal' import { NcModal } from '@nextcloud/vue'
import FolderPicker from './FolderPicker' import FolderPicker from './FolderPicker.vue'
export default { export default {
name: 'FolderPickerDialog', name: 'FolderPickerDialog',
components: { components: {
FolderPicker, FolderPicker,
Modal, NcModal,
}, },
props: { props: {
value: { value: {

View File

@ -5,8 +5,7 @@
--> -->
<template> <template>
<div <div v-drop-target="{allow: allowDrop, drop: (e) => $emit('drop', e)}"
v-drop-target="{allow: allowDrop, drop: (e) => $emit('drop', e)}"
:class="{ :class="{
item: true, item: true,
active, active,
@ -16,16 +15,14 @@
:draggable="draggable && !renaming" :draggable="draggable && !renaming"
@dragstart="onDragStart"> @dragstart="onDragStart">
<template v-if="!renaming"> <template v-if="!renaming">
<a <a :href="url"
:href="url"
class="item__clickLink" class="item__clickLink"
tabindex="0" tabindex="0"
target="_blank" target="_blank"
@click="onClick" @click="onClick"
@contextmenu="onRightClick"> @contextmenu="onRightClick">
<div v-if="editable && selectable" ref="checkbox" class="item__checkbox"> <div v-if="editable && selectable" ref="checkbox" class="item__checkbox">
<input :checked="selected" class="checkbox" type="checkbox"><label <input :checked="selected" class="checkbox" type="checkbox"><label v-tooltip="selectLabel"
v-tooltip="selectLabel"
:aria-label="selectLabel" :aria-label="selectLabel"
@click="$event.preventDefault(); $event.stopImmediatePropagation(); $emit('select');" /> @click="$event.preventDefault(); $event.stopImmediatePropagation(); $emit('select');" />
</div> </div>
@ -38,48 +35,46 @@
</div> </div>
<div v-if="editable && !selected" <div v-if="editable && !selected"
ref="actions" ref="actions"
class="item__actions" class="item__NcActions"
@click="$event.preventDefault(); $event.stopPropagation()"> @click="$event.preventDefault(); $event.stopPropagation()">
<Actions ref="actions"> <NcActions ref="actions">
<slot name="actions" /> <slot name="actions" />
</Actions> </NcActions>
</div> </div>
</a> </a>
</template> </template>
<div v-else class="item__rename"> <div v-else class="item__rename">
<slot name="icon" /> <slot name="icon" />
<input <input ref="input"
ref="input"
v-model="newTitle" v-model="newTitle"
type="text" type="text"
:placeholder="renamePlaceholder" :placeholder="renamePlaceholder"
@keyup.enter="onRenameSubmit"> @keyup.enter="onRenameSubmit">
<Actions> <NcActions>
<ActionButton icon="icon-checkmark" @click="onRenameSubmit"> <NcActionButton icon="icon-checkmark" @click="onRenameSubmit">
{{ t('bookmarks', 'Submit') }} {{ t('bookmarks', 'Submit') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
<Actions> <NcActions>
<ActionButton icon="icon-close" @click="$emit('rename-cancel')"> <NcActionButton icon="icon-close" @click="$emit('rename-cancel')">
{{ t('bookmarks', 'Cancel') }} {{ t('bookmarks', 'Cancel') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Vue from 'vue' import Vue from 'vue'
import Actions from '@nextcloud/vue/dist/Components/Actions' import { NcActions, NcActionButton } from '@nextcloud/vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import TagLine from './TagLine.vue'
import TagLine from './TagLine' import DragImage from './DragImage.vue'
import DragImage from './DragImage' import { mutations } from '../store/index.js'
import { mutations } from '../store'
export default { export default {
name: 'Item', name: 'Item',
components: { components: {
Actions, NcActions,
ActionButton, NcActionButton,
TagLine, TagLine,
}, },
props: { props: {
@ -308,7 +303,7 @@ export default {
box-shadow: #aaa 0 0 3px inset; box-shadow: #aaa 0 0 3px inset;
} }
.item__actions { .item__NcActions {
flex: 0; flex: 0;
} }

View File

@ -1,17 +1,17 @@
<template> <template>
<Modal v-if="showModal" :can-close="false"> <NcModal v-if="showNcModal" :can-close="false">
<div class="loading icon-loading"> <div class="loading icon-loading">
<h3>{{ title }}</h3> <h3>{{ title }}</h3>
</div> </div>
</Modal> </NcModal>
</template> </template>
<script> <script>
import Modal from '@nextcloud/vue/dist/Components/Modal' import { NcModal } from '@nextcloud/vue'
export default { export default {
name: 'LoadingModal', name: 'LoadingModal',
components: { components: {
Modal, NcModal,
}, },
data() { data() {
return { return {
@ -22,7 +22,7 @@ export default {
moveSelection: this.t('bookmkarks', 'Moving selection'), moveSelection: this.t('bookmkarks', 'Moving selection'),
copySelection: this.t('bookmkarks', 'Adding selection to folders'), copySelection: this.t('bookmkarks', 'Adding selection to folders'),
}, },
showModal: false, showNcModal: false,
showTimeout: null, showTimeout: null,
} }
}, },
@ -43,11 +43,11 @@ export default {
state(newState, previous) { state(newState, previous) {
if (this.state && !previous) { if (this.state && !previous) {
this.showTimeout = setTimeout(() => { this.showTimeout = setTimeout(() => {
this.showModal = true this.showNcModal = true
}, 500) }, 500)
} else if (!this.state && previous) { } else if (!this.state && previous) {
clearTimeout(this.showTimeout) clearTimeout(this.showTimeout)
this.showModal = false this.showNcModal = false
} }
}, },
}, },

View File

@ -5,25 +5,25 @@
--> -->
<template> <template>
<Modal v-if="showModal" :title="title" @close="onClose"> <NcModal v-if="showNcModal" :title="title" @close="onClose">
<div class="move-dialog"> <div class="move-dialog">
<FolderPicker :title="title" :filter="filterFolders" @submit="onSubmit" /> <FolderPicker :title="title" :filter="filterFolders" @submit="onSubmit" />
</div> </div>
</Modal> </NcModal>
</template> </template>
<script> <script>
import Modal from '@nextcloud/vue/dist/Components/Modal' import { NcModal } from '@nextcloud/vue'
import { actions, mutations } from '../store/' import { actions, mutations } from '../store/index.js'
import FolderPicker from './FolderPicker' import FolderPicker from './FolderPicker.vue'
export default { export default {
name: 'MoveDialog', name: 'MoveDialog',
components: { components: {
FolderPicker, FolderPicker,
Modal, NcModal,
}, },
computed: { computed: {
showModal() { showNcModal() {
return this.$store.state.displayMoveDialog return this.$store.state.displayMoveDialog
}, },
selection() { selection() {

View File

@ -5,142 +5,140 @@
--> -->
<template> <template>
<AppNavigation class="navigation"> <NcAppNavigation class="navigation">
<template #list> <template #list>
<AppNavigationItem key="menu-home" <NcAppNavigationItem key="menu-home"
:to="{ name: routes.HOME }" :to="{ name: routes.HOME }"
icon="icon-home"
:title="t('bookmarks', 'All bookmarks')" :title="t('bookmarks', 'All bookmarks')"
:exact="true"> :exact="true">
<AppNavigationCounter slot="counter"> <HomeIcon slot="icon" />
<NcAppNavigationCounter slot="counter">
{{ allBookmarksCount | largeNumbers }} {{ allBookmarksCount | largeNumbers }}
</AppNavigationCounter> </NcAppNavigationCounter>
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem key="menu-recent" <NcAppNavigationItem key="menu-recent"
:to="{ name: routes.RECENT }" :to="{ name: routes.RECENT }"
:title="t('bookmarks', 'Recent')"> :title="t('bookmarks', 'Recent')">
<HistoryIcon slot="icon" :size="18" :fill-color="colorMainText" /> <HistoryIcon slot="icon" />
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem <NcAppNavigationItem key="menu-shared-folders"
key="menu-shared-folders"
:to="{ name: routes.SHARED_FOLDERS }" :to="{ name: routes.SHARED_FOLDERS }"
:title="t('bookmarks', 'Shared with you')"> :title="t('bookmarks', 'Shared with you')">
<ShareVariantIcon slot="icon" :size="18" :fill-color="colorMainText" /> <ShareVariantIcon slot="icon" />
<AppNavigationCounter v-show="Boolean(sharedFoldersCount)" slot="counter"> <NcAppNavigationCounter v-show="Boolean(sharedFoldersCount)" slot="counter">
{{ sharedFoldersCount | largeNumbers }} {{ sharedFoldersCount | largeNumbers }}
</AppNavigationCounter> </NcAppNavigationCounter>
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem <NcAppNavigationItem key="menu-archived"
key="menu-archived"
:to="{ name: routes.ARCHIVED }" :to="{ name: routes.ARCHIVED }"
:title="t('bookmarks', 'Files')"> :title="t('bookmarks', 'Files')">
<FileDocumentMultipleIcon slot="icon" <FileDocumentMultipleIcon slot="icon" />
:size="18" <NcAppNavigationCounter v-show="Boolean(archivedBookmarksCount)" slot="counter">
:fill-color="colorMainText" />
<AppNavigationCounter v-show="Boolean(archivedBookmarksCount)" slot="counter">
{{ archivedBookmarksCount }} {{ archivedBookmarksCount }}
</AppNavigationCounter> </NcAppNavigationCounter>
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem <NcAppNavigationItem key="menu-duplicated"
key="menu-duplicated"
:to="{ name: routes.DUPLICATED }" :to="{ name: routes.DUPLICATED }"
:title="t('bookmarks', 'Duplicates')"> :title="t('bookmarks', 'Duplicates')">
<VectorLinkIcon slot="icon" :size="18" :fill-color="colorMainText" /> <VectorLinkIcon slot="icon" />
<AppNavigationCounter v-show="Boolean(duplicatedBookmarksCount)" slot="counter"> <NcAppNavigationCounter v-show="Boolean(duplicatedBookmarksCount)" slot="counter">
{{ duplicatedBookmarksCount | largeNumbers }} {{ duplicatedBookmarksCount | largeNumbers }}
</AppNavigationCounter> </NcAppNavigationCounter>
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem <NcAppNavigationItem key="menu-unavailable"
key="menu-unavailable"
:to="{ name: routes.UNAVAILABLE }" :to="{ name: routes.UNAVAILABLE }"
:title="t('bookmarks', 'Broken links')"> :title="t('bookmarks', 'Broken links')">
<LinkVariantOffIcon slot="icon" :size="18" :fill-color="colorMainText" /> <LinkVariantOffIcon slot="icon" />
<AppNavigationCounter v-show="Boolean(unavailableBookmarksCount)" slot="counter"> <NcAppNavigationCounter v-show="Boolean(unavailableBookmarksCount)" slot="counter">
{{ unavailableBookmarksCount | largeNumbers }} {{ unavailableBookmarksCount | largeNumbers }}
</AppNavigationCounter> </NcAppNavigationCounter>
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationSpacer /> <NcAppNavigationSpacer />
<AppNavigationNewItem key="menu-new-tag" <NcAppNavigationNewItem key="menu-new-tag"
:title="t('bookmarks', 'New tag')" :title="t('bookmarks', 'New tag')"
@new-item="onNewTag"> @new-item="onNewTag">
<TagPlusIcon slot="icon" :size="18" :fill-color="colorMainText" /> <TagPlusIcon slot="icon" />
</AppNavigationNewItem> </NcAppNavigationNewItem>
<template v-if="Boolean(tags.length)"> <template v-if="Boolean(tags.length)">
<AppNavigationItem key="menu-tags" <NcAppNavigationItem key="menu-tags"
:title="t('bookmarks', 'Search tags')" :title="t('bookmarks', 'Search tags')"
@click="onSearchTags"> @click="onSearchTags">
<TagMultipleIcon slot="icon" :size="18" :fill-color="colorMainText" /> <TagMultipleIcon slot="icon" />
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem v-for="tag in tags" <NcAppNavigationItem v-for="tag in tags"
:key="'tag-'+tag.name" :key="'tag-'+tag.name"
v-drop-target="{allow: (e) => allowDropOnTag(tag.name, e), drop: (e) => onDropOnTag(tag.name, e)}" v-drop-target="{allow: (e) => allowDropOnTag(tag.name, e), drop: (e) => onDropOnTag(tag.name, e)}"
icon="icon-tag"
:to="tag.route" :to="tag.route"
:force-menu="true" :force-menu="true"
:edit-label="t('bookmarks', 'Rename')" :edit-label="t('bookmarks', 'Rename')"
:editable="!isPublic" :editable="!isPublic"
:title="tag.name" :title="tag.name"
@update:title="onRenameTag(tag.name, $event)"> @update:title="onRenameTag(tag.name, $event)">
<AppNavigationCounter slot="counter"> <TagIcon slot="icon" />
<NcAppNavigationCounter slot="counter">
{{ tag.count | largeNumbers }} {{ tag.count | largeNumbers }}
</AppNavigationCounter> </NcAppNavigationCounter>
<template v-if="!isPublic" slot="actions"> <template v-if="!isPublic" slot="actions">
<ActionButton icon="icon-delete" :close-after-click="true" @click="onDeleteTag(tag.name)"> <NcActionButton :close-after-click="true" @click="onDeleteTag(tag.name)">
<template #icon>
<DeleteIcon />
</template>
{{ t('bookmarks', 'Delete') }} {{ t('bookmarks', 'Delete') }}
</ActionButton> </NcActionButton>
</template> </template>
</AppNavigationItem> </NcAppNavigationItem>
<AppNavigationItem key="menu-untagged" <NcAppNavigationItem key="menu-untagged"
:to="{ name: routes.UNTAGGED }" :to="{ name: routes.UNTAGGED }"
:title="t('bookmarks', 'Untagged')"> :title="t('bookmarks', 'Untagged')">
<TagOffIcon slot="icon" :size="18" :fill-color="colorMainText" /> <TagOffIcon slot="icon" />
</AppNavigationItem> </NcAppNavigationItem>
</template> </template>
<template v-if="Number(bookmarksLimit) > 0"> <template v-if="Number(bookmarksLimit) > 0">
<AppNavigationSpacer /> <NcAppNavigationSpacer />
<AppNavigationItem :pinned="true" icon="icon-quota" :title="t('bookmarks', '{used} bookmarks of {available} available', {used: allBookmarksCount, available: bookmarksLimit})"> <NcAppNavigationItem :pinned="true" :title="t('bookmarks', '{used} bookmarks of {available} available', {used: allBookmarksCount, available: bookmarksLimit})">
<template #icon>
<GaugeIcon />
</template>
<ProgressBar :val="allBookmarksCount" :max="bookmarksLimit" /> <ProgressBar :val="allBookmarksCount" :max="bookmarksLimit" />
</AppNavigationItem> </NcAppNavigationItem>
</template> </template>
</template> </template>
<template #footer> <template #footer>
<AppNavigationSettings v-if="!isPublic"> <NcAppNavigationSettings v-if="!isPublic">
<Settings /> <Settings />
</AppNavigationSettings> </NcAppNavigationSettings>
</template> </template>
</AppNavigation> </NcAppNavigation>
</template> </template>
<script> <script>
import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation' import { NcActionButton, NcAppNavigation, NcAppNavigationItem, NcAppNavigationNewItem, NcAppNavigationCounter, NcAppNavigationSettings, NcAppNavigationSpacer } from '@nextcloud/vue'
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem' import HomeIcon from 'vue-material-design-icons/Home.vue'
import AppNavigationNewItem from '@nextcloud/vue/dist/Components/AppNavigationNewItem' import HistoryIcon from 'vue-material-design-icons/History.vue'
import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter' import TagOffIcon from 'vue-material-design-icons/TagOff.vue'
import AppNavigationSettings from '@nextcloud/vue/dist/Components/AppNavigationSettings' import LinkVariantOffIcon from 'vue-material-design-icons/LinkVariantOff.vue'
import AppNavigationSpacer from '@nextcloud/vue/dist/Components/AppNavigationSpacer' import ShareVariantIcon from 'vue-material-design-icons/ShareVariant.vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import FileDocumentMultipleIcon from 'vue-material-design-icons/FileDocumentMultiple.vue'
import HistoryIcon from 'vue-material-design-icons/History' import TagPlusIcon from 'vue-material-design-icons/TagPlus.vue'
import TagOffIcon from 'vue-material-design-icons/TagOff' import TagMultipleIcon from 'vue-material-design-icons/TagMultiple.vue'
import LinkVariantOffIcon from 'vue-material-design-icons/LinkVariantOff' import VectorLinkIcon from 'vue-material-design-icons/VectorLink.vue'
import ShareVariantIcon from 'vue-material-design-icons/ShareVariant' import TagIcon from 'vue-material-design-icons/Tag.vue'
import FileDocumentMultipleIcon from 'vue-material-design-icons/FileDocumentMultiple' import DeleteIcon from 'vue-material-design-icons/Delete.vue'
import TagPlusIcon from 'vue-material-design-icons/TagPlus' import GaugeIcon from 'vue-material-design-icons/Gauge.vue'
import TagMultipleIcon from 'vue-material-design-icons/TagMultiple'
import VectorLinkIcon from 'vue-material-design-icons/VectorLink'
import ProgressBar from 'vue-simple-progress' import ProgressBar from 'vue-simple-progress'
import Settings from './Settings' import Settings from './Settings.vue'
import { actions, mutations } from '../store/' import { actions, mutations } from '../store/index.js'
export default { export default {
name: 'Navigation', name: 'Navigation',
components: { components: {
AppNavigation, NcAppNavigation,
AppNavigationItem, NcAppNavigationItem,
AppNavigationNewItem, NcAppNavigationNewItem,
AppNavigationCounter, NcAppNavigationCounter,
AppNavigationSettings, NcAppNavigationSettings,
AppNavigationSpacer, NcAppNavigationSpacer,
ActionButton, NcActionButton,
Settings, Settings,
ProgressBar, ProgressBar,
HistoryIcon, HistoryIcon,
@ -151,6 +149,10 @@ export default {
FileDocumentMultipleIcon, FileDocumentMultipleIcon,
ShareVariantIcon, ShareVariantIcon,
VectorLinkIcon, VectorLinkIcon,
HomeIcon,
TagIcon,
DeleteIcon,
GaugeIcon,
}, },
filters: { filters: {

View File

@ -6,57 +6,79 @@
<template> <template>
<div class="bookmarkslist__emptyBookmarks"> <div class="bookmarkslist__emptyBookmarks">
<EmptyContent v-if="$route.name === routes.ARCHIVED"> <NcEmptyContent v-if="$route.name === routes.ARCHIVED"
{{ t('bookmarks', 'No bookmarked files') }} :title="t('bookmarks', 'No bookmarked files')"
<template #desc> :description="t('bookmarks', 'Bookmarks to files like photos or PDFs will automatically be saved to your Nextcloud files, so you can still find them even when the link goes offline.')">
{{ t('bookmarks', 'Bookmarks to files like photos or PDFs will automatically be saved to your Nextcloud files, so you can still find them even when the link goes offline.') }} <template #icon>
<FileDocumentMultipleIcon />
</template> </template>
</EmptyContent> </NcEmptyContent>
<EmptyContent v-else-if="$route.name === routes.UNAVAILABLE"> <NcEmptyContent v-else-if="$route.name === routes.UNAVAILABLE"
{{ t('bookmarks', 'No broken links') }} :title="t('bookmarks', 'No broken links')"
<template #desc> :description="t('bookmarks', 'Bookmarked links are checked regularly and the ones that cannot be reached are listed here.')">
{{ t('bookmarks', 'Bookmarked links are checked regularly and the ones that cannot be reached are listed here.') }} <template #icon>
<LinkVariantOffIcon />
</template> </template>
</EmptyContent> </NcEmptyContent>
<EmptyContent v-else-if="$route.name === routes.SHARED_FOLDERS"> <NcEmptyContent v-else-if="$route.name === routes.SHARED_FOLDERS"
{{ t('bookmarks', 'No shared folders') }} :title="t('bookmarks', 'No shared folders')"
<template #desc> :description="t('bookmarks', 'You can share bookmark folders with others. All folders shared with you are listed here.')">
{{ t('bookmarks', 'You can share bookmark folders with others. All folders shared with you are listed here.') }} <template #icon>
<ShareVariantIcon />
</template> </template>
</EmptyContent> </NcEmptyContent>
<EmptyContent v-else-if="$route.name === routes.DUPLICATED"> <NcEmptyContent v-else-if="$route.name === routes.DUPLICATED"
{{ t('bookmarks', 'No duplicated bookmarks') }} :title="t('bookmarks', 'No duplicated bookmarks')"
<template #desc> :description="t('bookmarks', 'One bookmark can be in multiple folders at once. Updating it will update all copies. All duplicated bookmarks are listed here for convenience.')">
{{ t('bookmarks', 'One bookmark can be in multiple folders at once. Updating it will update all copies. All duplicated bookmarks are listed here for convenience.') }} <template #icon>
<VectorLinkIcon />
</template> </template>
</EmptyContent> </NcEmptyContent>
<EmptyContent v-else icon="icon-favorite"> <NcEmptyContent v-else
{{ t('bookmarks', 'No bookmarks here') }} :title="t('bookmarks', 'No bookmarks here')"
<template v-if="!isPublic" #desc> :description="t('bookmarks', 'Add bookmarks manually or import bookmarks from a HTML file.')">
<p>{{ t('bookmarks', 'Add bookmarks manually or import bookmarks from a HTML file.') }}</p> <template #icon>
<StarShootingIcon />
</template>
<template v-if="!isPublic" #action>
<input ref="import" <input ref="import"
type="file" type="file"
class="import" class="import"
size="5" size="5"
@change="onImportSubmit"> @change="onImportSubmit">
<button @click="onCreateOpen"> <NcButton @click="onCreateOpen">
<template #icon>
<PlusIcon />
</template>
{{ t('bookmarks', 'Add a bookmark') }} {{ t('bookmarks', 'Add a bookmark') }}
</button> </NcButton>
<button @click="onImportOpen"> <NcButton @click="onImportOpen">
<span :class="{'icon-upload': !importing, 'icon-loading-small': importing}" /> {{ t('bookmarks', 'Import bookmarks') }} <template #icon>
</button> <UploadIcon v-if="!importing" />
<NcLoadingIcon v-else />
</template>
{{ t('bookmarks', 'Import bookmarks') }}
</NcButton>
</template> </template>
</EmptyContent> </NcEmptyContent>
</div> </div>
</template> </template>
<script> <script>
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent' import { NcEmptyContent, NcButton, NcLoadingIcon } from '@nextcloud/vue'
import { actions, mutations } from '../store' import { actions, mutations } from '../store/index.js'
import { privateRoutes } from '../router' import { privateRoutes } from '../router.js'
import StarShootingIcon from 'vue-material-design-icons/StarShooting.vue'
import UploadIcon from 'vue-material-design-icons/Upload.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import ShareVariantIcon from 'vue-material-design-icons/ShareVariant.vue'
import VectorLinkIcon from 'vue-material-design-icons/VectorLink.vue'
import LinkVariantOffIcon from 'vue-material-design-icons/LinkVariantOff.vue'
import FileDocumentMultipleIcon from 'vue-material-design-icons/FileDocumentMultiple.vue'
export default { export default {
name: 'NoBookmarks', name: 'NoBookmarks',
components: { EmptyContent }, components: { NcEmptyContent, StarShootingIcon, NcButton, NcLoadingIcon, UploadIcon, PlusIcon, ShareVariantIcon, VectorLinkIcon, LinkVariantOffIcon, FileDocumentMultipleIcon },
data() { data() {
return { importing: false } return { importing: false }
}, },
@ -97,13 +119,7 @@ export default {
left: -1000px; left: -1000px;
} }
.material-design-icon { button {
position: relative;
top: 4px;
display: inline-flex;
}
p {
margin-bottom: 15px; margin-bottom: 15px;
} }
</style> </style>

View File

@ -5,8 +5,7 @@
--> -->
<template> <template>
<AppSidebar <NcAppSidebar v-if="isActive"
v-if="isActive"
class="sidebar" class="sidebar"
:title="bookmark.title" :title="bookmark.title"
:title-editable="editingTitle" :title-editable="editingTitle"
@ -19,50 +18,70 @@
@dismiss-editing="onEditTitleCancel" @dismiss-editing="onEditTitleCancel"
@close="onClose"> @close="onClose">
<template v-if="!editingTitle" slot="secondary-actions"> <template v-if="!editingTitle" slot="secondary-actions">
<ActionButton icon="icon-rename" @click="onEditTitle" /> <NcActionButton @click="onEditTitle">
<template #icon>
<PencilIcon />
</template>
</NcActionButton>
</template> </template>
<template v-if="editingTitle" slot="secondary-actions"> <template v-if="editingTitle" slot="secondary-actions">
<ActionButton icon="icon-close" @click="onEditTitleCancel" /> <NcActionButton @click="onEditTitleCancel">
<template #icon>
<CloseIcon />
</template>
</NcActionButton>
</template> </template>
<AppSidebarTab <NcAppSidebarTab id="bookmark-details"
id="bookmark-details"
:name="t('bookmarks', 'Details')" :name="t('bookmarks', 'Details')"
icon="icon-info"
:order="0"> :order="0">
<template #icon>
<InformationVariantIcon />
</template>
<div> <div>
<div v-if="!editingUrl" class="details__line"> <div v-if="!editingUrl" class="details__line">
<span class="icon-external" :aria-label="t('bookmarks', 'Link')" :title="t('bookmarks', 'Link')" /> <OpenInNewIcon :aria-label="t('bookmarks', 'Link')" :title="t('bookmarks', 'Link')" />
<a class="details__url" :href="bookmark.url">{{ bookmark.url }}</a> <a class="details__url" :href="bookmark.url">{{ bookmark.url }}</a>
<Actions v-if="isEditable" class="details__action"> <NcActions v-if="isEditable" class="details__action">
<ActionButton icon="icon-rename" @click="onEditUrl" /> <NcActionButton @click="onEditUrl">
</Actions> <template #icon>
<PencilIcon />
</template>
</NcActionButton>
</NcActions>
</div> </div>
<div v-else class="details__line"> <div v-else class="details__line">
<span class="icon-external" :aria-label="t('bookmarks', 'Link')" :title="t('bookmarks', 'Link')" /> <OpenInNewIcon :aria-label="t('bookmarks', 'Link')" :title="t('bookmarks', 'Link')" />
<input v-model="url" class="details__url"> <input v-model="url" class="details__url">
<Actions class="details__action"> <NcActions class="details__action">
<ActionButton icon="icon-confirm" @click="onEditUrlSubmit" /> <NcActionButton @click="onEditUrlSubmit">
</Actions> <template #icon>
<Actions class="details__action"> <ArrowRightIcon />
<ActionButton icon="icon-close" @click="onEditUrlCancel" /> </template>
</Actions> </NcActionButton>
</NcActions>
<NcActions class="details__action">
<NcActionButton @click="onEditUrlCancel">
<template #icon>
<CloseIcon />
</template>
</NcActionButton>
</NcActions>
</div> </div>
<div class="details__line"> <div class="details__line">
<FolderIcon :fill-color="colorMainText" size="18" /> <FolderIcon />
<div class="folders"> <div class="folders">
<span v-for="folderId in bookmark.folders" <span v-for="folderId in bookmark.folders"
:key="folderId" :key="folderId"
v-tooltip="getFolderPath(folderId)" v-tooltip="getFolderPath(folderId)"
class="folders__folder" class="folders__folder"
@click="onOpenFolder(folderId)"> @click="onOpenFolder(folderId)">
<FolderIcon :fill-color="colorMainText" /> {{ getFolder(folderId).title || (getFolder(folderId).parent_folder ? t('bookmarks', 'Untitled folder') : t('bookmarks', 'Root folder')) }} <FolderIcon /> {{ getFolder(folderId).title || (getFolder(folderId).parent_folder ? t('bookmarks', 'Untitled folder') : t('bookmarks', 'Root folder')) }}
</span> </span>
</div> </div>
</div> </div>
<div class="details__line"> <div class="details__line">
<span class="icon-tag" :aria-label="t('bookmarks', 'Tags')" :title="t('bookmarks', 'Tags')" /> <TagIcon :aria-label="t('bookmarks', 'Tags')" :title="t('bookmarks', 'Tags')" />
<Multiselect <NcMultiselect class="tags"
class="tags"
:value="tags" :value="tags"
:auto-limit="false" :auto-limit="false"
:limit="7" :limit="7"
@ -76,12 +95,10 @@
@tag="onAddTag" /> @tag="onAddTag" />
</div> </div>
<div class="details__line"> <div class="details__line">
<span class="icon-edit" <PencilBoxIcon role="figure"
role="figure"
:aria-label="t('bookmarks', 'Notes')" :aria-label="t('bookmarks', 'Notes')"
:title="t('bookmarks', 'Notes')" /> :title="t('bookmarks', 'Notes')" />
<RichContenteditable <NcRichContenteditable :value.sync="bookmark.description"
:value.sync="bookmark.description"
:contenteditable="isEditable" :contenteditable="isEditable"
:auto-complete="() => {}" :auto-complete="() => {}"
:placeholder="t('bookmarks', 'Notes for this bookmark …')" :placeholder="t('bookmarks', 'Notes for this bookmark …')"
@ -95,40 +112,31 @@
<a class="button" :href="archivedFileUrl" target="_blank"><FileDocumentIcon :size="18" :fill-color="colorMainText" /> {{ t('bookmarks', 'Open file') }}</a> <a class="button" :href="archivedFileUrl" target="_blank"><FileDocumentIcon :size="18" :fill-color="colorMainText" /> {{ t('bookmarks', 'Open file') }}</a>
<a class="button" :href="archivedFile" target="_blank"><span class="icon-files-dark" /> {{ t('bookmarks', 'Open file location') }}</a> <a class="button" :href="archivedFile" target="_blank"><span class="icon-files-dark" /> {{ t('bookmarks', 'Open file location') }}</a>
</div> </div>
</AppSidebarTab> </NcAppSidebarTab>
<AppSidebarTab v-if="!isPublic" </NcAppSidebar>
id="bookmark-projects"
:name="t('bookmarks', 'Projects')"
icon="icon-projects"
:order="1">
<CollectionList v-if="bookmark"
:id="''+bookmark.id"
:name="bookmark.title"
type="bookmarks" />
</AppSidebarTab>
</AppSidebar>
</template> </template>
<script> <script>
import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar' import { NcAppSidebar, NcRichContenteditable, NcActionButton, NcActions, NcMultiselect, NcAppSidebarTab } from '@nextcloud/vue'
import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab' import FileDocumentIcon from 'vue-material-design-icons/FileDocument.vue'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect' import FolderIcon from 'vue-material-design-icons/Folder.vue'
import Actions from '@nextcloud/vue/dist/Components/Actions' import InformationVariantIcon from 'vue-material-design-icons/InformationVariant.vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import PencilIcon from 'vue-material-design-icons/Pencil.vue'
import RichContenteditable from '@nextcloud/vue/dist/Components/RichContenteditable' import ArrowRightIcon from 'vue-material-design-icons/ArrowRight.vue'
import FileDocumentIcon from 'vue-material-design-icons/FileDocument' import TagIcon from 'vue-material-design-icons/Tag.vue'
import FolderIcon from 'vue-material-design-icons/Folder' import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
import { CollectionList } from 'nextcloud-vue-collections' import CloseIcon from 'vue-material-design-icons/Close.vue'
import PencilBoxIcon from 'vue-material-design-icons/PencilBox.vue'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import { generateRemoteUrl, generateUrl } from '@nextcloud/router' import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
import humanizeDuration from 'humanize-duration' import humanizeDuration from 'humanize-duration'
import { actions, mutations } from '../store/' import { actions, mutations } from '../store/index.js'
const MAX_RELATIVE_DATE = 1000 * 60 * 60 * 24 * 7 // one week const MAX_RELATIVE_DATE = 1000 * 60 * 60 * 24 * 7 // one week
export default { export default {
name: 'SidebarBookmark', name: 'SidebarBookmark',
components: { AppSidebar, AppSidebarTab, Multiselect, Actions, ActionButton, RichContenteditable, FileDocumentIcon, FolderIcon, CollectionList }, components: { NcAppSidebar, NcAppSidebarTab, NcMultiselect, NcActions, NcActionButton, NcRichContenteditable, FileDocumentIcon, FolderIcon, InformationVariantIcon, PencilIcon, ArrowRightIcon, TagIcon, OpenInNewIcon, CloseIcon, PencilBoxIcon },
data() { data() {
return { return {
title: '', title: '',

View File

@ -5,29 +5,29 @@
--> -->
<template> <template>
<AppSidebar <NcAppSidebar
v-if="isActive" v-if="isActive"
class="sidebar" class="sidebar"
:title="folder.title" :title="folder.title"
:active.sync="activeTab" :active.sync="activeTab"
@close="onClose"> @close="onClose">
<AppSidebarTab id="folder-details" <NcAppSidebarTab id="folder-details"
:name="t('bookmarks', 'Details')" :name="t('bookmarks', 'Details')"
icon="icon-info" icon="icon-info"
:order="0"> :order="0">
<h3>{{ t('bookmarks', 'Owner') }}</h3> <h3>{{ t('bookmarks', 'Owner') }}</h3>
<UserBubble :user="folder.userId" :display-name="folder.userId" /> <NcUserBubble :user="folder.userId" :display-name="folder.userId" />
<h3>{{ t('bookmarks', 'Bookmarks') }}</h3> <h3>{{ t('bookmarks', 'Bookmarks') }}</h3>
{{ bookmarkCount }} {{ bookmarkCount }}
</AppSidebarTab> </NcAppSidebarTab>
<AppSidebarTab v-if="isSharable" <NcAppSidebarTab v-if="isSharable"
id="folder-sharing" id="folder-sharing"
:name="t('bookmarks', 'Sharing')" :name="t('bookmarks', 'Sharing')"
icon="icon-shared" icon="icon-shared"
:order="1"> :order="1">
<div class="participant-select"> <div class="participant-select">
<figure :class="{'icon-user': true, 'share__avatar': true }" /> <figure :class="{'icon-user': true, 'share__avatar': true }" />
<Multiselect v-model="participant" <NcMultiselect v-model="participant"
label="displayName" label="displayName"
track-by="user" track-by="user"
class="participant-select__selection" class="participant-select__selection"
@ -52,27 +52,27 @@
:fill-color="colorMainText" /> :fill-color="colorMainText" />
</div> </div>
</div> </div>
<Actions class="share__actions"> <NcActions class="share__actions">
<template v-if="publicLink"> <template v-if="publicLink">
<ActionButton icon="icon-clippy" @click="onCopyPublicLink"> <NcActionButton icon="icon-clippy" @click="onCopyPublicLink">
{{ t('bookmarks', 'Copy link') }} {{ t('bookmarks', 'Copy link') }}
</ActionButton> </NcActionButton>
<ActionButton icon="icon-clippy" @click="onCopyRssLink"> <NcActionButton icon="icon-clippy" @click="onCopyRssLink">
{{ t('bookmarks', 'Copy RSS feed') }} {{ t('bookmarks', 'Copy RSS feed') }}
</ActionButton> </NcActionButton>
<ActionSeparator /> <NcActionSeparator />
<ActionButton icon="icon-delete" @click="onDeletePublicLink"> <NcActionButton icon="icon-delete" @click="onDeletePublicLink">
{{ t('bookmarks', 'Delete link') }} {{ t('bookmarks', 'Delete link') }}
</ActionButton> </NcActionButton>
</template> </template>
<ActionButton v-else icon="icon-add" @click="onAddPublicLink"> <NcActionButton v-else icon="icon-add" @click="onAddPublicLink">
{{ t('bookmarks', 'Create public link') }} {{ t('bookmarks', 'Create public link') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
</div> </div>
<div v-for="share of shares" :key="share.id"> <div v-for="share of shares" :key="share.id">
<div class="share"> <div class="share">
<Avatar :user="share.participant" class="share__avatar" :size="44" /> <NcAvatar :user="share.participant" class="share__avatar" :size="44" />
<h3 class="share__title"> <h3 class="share__title">
{{ share.participant }} {{ share.participant }}
</h3> </h3>
@ -98,21 +98,21 @@
:fill-color="colorMainText" /> :fill-color="colorMainText" />
</div> </div>
</div> </div>
<Actions class="share__actions"> <NcActions class="share__actions">
<ActionCheckbox :checked="share.canWrite" @update:checked="onEditShare(share.id, {canWrite: $event, canShare: share.canShare})"> <NcActionCheckbox :checked="share.canWrite" @update:checked="onEditShare(share.id, {canWrite: $event, canShare: share.canShare})">
{{ t('bookmarks', 'Allow editing') }} {{ t('bookmarks', 'Allow editing') }}
</ActionCheckbox> </NcActionCheckbox>
<ActionCheckbox :checked="share.canShare" @update:checked="onEditShare(share.id, {canWrite: share.canWrite, canShare: $event})"> <NcActionCheckbox :checked="share.canShare" @update:checked="onEditShare(share.id, {canWrite: share.canWrite, canShare: $event})">
{{ t('bookmarks', 'Allow resharing') }} {{ t('bookmarks', 'Allow resharing') }}
</ActionCheckbox> </NcActionCheckbox>
<ActionButton icon="icon-delete" @click="onDeleteShare(share.id)"> <NcActionButton icon="icon-delete" @click="onDeleteShare(share.id)">
{{ t('bookmarks', 'Remove share') }} {{ t('bookmarks', 'Remove share') }}
</ActionButton> </NcActionButton>
</Actions> </NcActions>
</div> </div>
</div> </div>
</AppSidebarTab> </NcAppSidebarTab>
<AppSidebarTab v-if="!isPublic" <NcAppSidebarTab v-if="!isPublic"
id="bookmark-projects" id="bookmark-projects"
:name="t('bookmarks', 'Projects')" :name="t('bookmarks', 'Projects')"
icon="icon-projects" icon="icon-projects"
@ -121,19 +121,11 @@
:id="''+folder.id" :id="''+folder.id"
:name="folder.title" :name="folder.title"
type="bookmarks-folder" /> type="bookmarks-folder" />
</AppSidebarTab> </NcAppSidebarTab>
</AppSidebar> </NcAppSidebar>
</template> </template>
<script> <script>
import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar' import { NcAppSidebar, NcUserBubble, NcActionSeparator, NcActionCheckbox, NcActionButton, NcActions, NcMultiselect, NcAvatar, NcAppSidebarTab } from '@nextcloud/vue'
import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab'
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import ActionCheckbox from '@nextcloud/vue/dist/Components/ActionCheckbox'
import ActionSeparator from '@nextcloud/vue/dist/Components/ActionSeparator'
import UserBubble from '@nextcloud/vue/dist/Components/UserBubble'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl, generateOcsUrl } from '@nextcloud/router' import { generateUrl, generateOcsUrl } from '@nextcloud/router'
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'
@ -146,7 +138,7 @@ import { CollectionList } from 'nextcloud-vue-collections'
export default { export default {
name: 'SidebarFolder', name: 'SidebarFolder',
components: { AppSidebar, AppSidebarTab, Avatar, Multiselect, ActionButton, ActionCheckbox, Actions, UserBubble, ActionSeparator, EyeIcon, PencilIcon, ShareAllIcon, CollectionList }, components: { NcAppSidebar, NcAppSidebarTab, NcAvatar, NcMultiselect, NcActionButton, NcActionCheckbox, NcActions, NcUserBubble, NcActionSeparator, EyeIcon, PencilIcon, ShareAllIcon, CollectionList },
data() { data() {
return { return {
participantSearchResults: [], participantSearchResults: [],

View File

@ -8,14 +8,12 @@
<div id="bookmarks"> <div id="bookmarks">
<figure v-if="loading" class="icon-loading loading" /> <figure v-if="loading" class="icon-loading loading" />
<figure v-if="!loading && success" class="icon-checkmark success" /> <figure v-if="!loading && success" class="icon-checkmark success" />
<SettingsSection <NcSettingsSection :title="t('bookmarks', 'Privacy')"
:title="t('bookmarks', 'Privacy')"
:description="t('bookmarks', :description="t('bookmarks',
'Bookmarks will try to access web pages that you add to automatically add information about them.' 'Bookmarks will try to access web pages that you add to automatically add information about them.'
)"> )">
<p> <p>
<input <input id="enableScraping"
id="enableScraping"
v-model="settings['privacy.enableScraping']" v-model="settings['privacy.enableScraping']"
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
@ -26,9 +24,8 @@
) )
}}</label> }}</label>
</p> </p>
</SettingsSection> </NcSettingsSection>
<SettingsSection <NcSettingsSection :title="t('bookmarks', 'Performance') "
:title="t('bookmarks', 'Performance') "
:description="t('bookmarks', :description="t('bookmarks',
'In an installation with a lot of users it may be useful to restrict the number of bookmarks per account.' 'In an installation with a lot of users it may be useful to restrict the number of bookmarks per account.'
)"> )">
@ -46,9 +43,8 @@
step="1" step="1"
@input="onChange"></label> @input="onChange"></label>
</p> </p>
</SettingsSection> </NcSettingsSection>
<SettingsSection <NcSettingsSection :title="t('bookmarks', 'Previews')"
:title="t('bookmarks', 'Previews')"
:description="t('bookmarks', :description="t('bookmarks',
'In order to display real screenshots of your bookmarked websites, Bookmarks can use third-party services to generate previews.' 'In order to display real screenshots of your bookmarked websites, Bookmarks can use third-party services to generate previews.'
)"> )">
@ -62,32 +58,28 @@
</p> </p>
<p> <p>
<label>{{ t('bookmarks', 'Screeenly API URL') }} <label>{{ t('bookmarks', 'Screeenly API URL') }}
<input <input v-model="settings['previews.screenly.url']"
v-model="settings['previews.screenly.url']"
type="text" type="text"
placeholder="https://screeenly.example.com/api/v1/fullsize" placeholder="https://screeenly.example.com/api/v1/fullsize"
@input="onChange"></label> @input="onChange"></label>
</p> </p>
<p> <p>
<label>{{ t('bookmarks', 'Screeenly API key') }} <label>{{ t('bookmarks', 'Screeenly API key') }}
<input <input v-model="settings['previews.screenly.token']"
v-model="settings['previews.screenly.token']"
type="text" type="text"
@input="onChange"></label> @input="onChange"></label>
</p> </p>
<h3>{{ t('bookmarks', 'Webshot') }}</h3> <h3>{{ t('bookmarks', 'Webshot') }}</h3>
<p> <p>
<label>{{ t('bookmarks', 'Webshot API URL') }} <label>{{ t('bookmarks', 'Webshot API URL') }}
<input <input v-model="settings['previews.webshot.url']"
v-model="settings['previews.webshot.url']"
type="text" type="text"
@input="onChange"></label> @input="onChange"></label>
</p> </p>
<h3>{{ t('bookmarks', 'ScreenshotMachine') }}</h3> <h3>{{ t('bookmarks', 'ScreenshotMachine') }}</h3>
<p> <p>
<label>{{ t('bookmarks', 'ScreenshotMachine API key') }} <label>{{ t('bookmarks', 'ScreenshotMachine API key') }}
<input <input v-model="settings['previews.screenshotmachine.key']"
v-model="settings['previews.screenshotmachine.key']"
type="text" type="text"
@input="onChange"></label> @input="onChange"></label>
</p> </p>
@ -99,18 +91,17 @@
</p> </p>
<p> <p>
<label>{{ t('bookmarks', 'Pageres ENV variables') }} <label>{{ t('bookmarks', 'Pageres ENV variables') }}
<input <input v-model="settings['previews.pageres.env']"
v-model="settings['previews.pageres.env']"
placeholder="CHROMIUM_PATH=/usr/bin/chromium-browser PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=false" placeholder="CHROMIUM_PATH=/usr/bin/chromium-browser PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=false"
type="text" type="text"
@input="onChange"></label> @input="onChange"></label>
</p> </p>
</SettingsSection> </NcSettingsSection>
</div> </div>
</template> </template>
<script> <script>
import SettingsSection from '@nextcloud/vue/dist/Components/SettingsSection' import { NcSettingsSection } from '@nextcloud/vue'
import { loadState } from '@nextcloud/initial-state' import { loadState } from '@nextcloud/initial-state'
const SETTINGS = [ const SETTINGS = [
@ -125,7 +116,7 @@ const SETTINGS = [
export default { export default {
name: 'ViewAdmin', name: 'ViewAdmin',
components: { SettingsSection }, components: { NcSettingsSection },
data() { data() {
const settings = loadState('bookmarks', 'adminSettings') const settings = loadState('bookmarks', 'adminSettings')
for (const setting of SETTINGS) { for (const setting of SETTINGS) {

View File

@ -5,7 +5,7 @@
--> -->
<template> <template>
<Content app-name="bookmarks"> <NcContent app-name="bookmarks">
<div class="bookmarklet"> <div class="bookmarklet">
<h2><figure :class="loading? 'icon-loading-small' : 'icon-link'" /> {{ t('bookmarks', 'Add a bookmark') }}</h2> <h2><figure :class="loading? 'icon-loading-small' : 'icon-link'" /> {{ t('bookmarks', 'Add a bookmark') }}</h2>
<div v-if="exists" class="bookmarklet__exists"> <div v-if="exists" class="bookmarklet__exists">
@ -18,8 +18,7 @@
<input v-model="bookmark.url" type="text" :placeholder="t('bookmarks', 'Enter bookmark URL')"> <input v-model="bookmark.url" type="text" :placeholder="t('bookmarks', 'Enter bookmark URL')">
</label> </label>
<label><figure class="icon-tag" /> {{ t('bookmarks', 'Tags') }} <label><figure class="icon-tag" /> {{ t('bookmarks', 'Tags') }}
<Multiselect <NcMultiselect class="sidebar__tags"
class="sidebar__tags"
:value="bookmark.tags" :value="bookmark.tags"
:auto-limit="false" :auto-limit="false"
:limit="7" :limit="7"
@ -38,8 +37,7 @@
<FolderPickerDialog v-model="folder" :show="showPicker" @close="showPicker = false" /> <FolderPickerDialog v-model="folder" :show="showPicker" @close="showPicker = false" />
</label> </label>
<label>{{ t('bookmarks', 'Notes') }}</label> <label>{{ t('bookmarks', 'Notes') }}</label>
<div <div class="bookmarklet__notes"
class="bookmarklet__notes"
contenteditable contenteditable
@input="onNotesChange"> @input="onNotesChange">
{{ description }} {{ description }}
@ -48,21 +46,20 @@
<span class="icon-confirm-white" />{{ t('bookmarks', 'Save') }} <span class="icon-confirm-white" />{{ t('bookmarks', 'Save') }}
</button> </button>
</div> </div>
</Content> </NcContent>
</template> </template>
<script> <script>
import Content from '@nextcloud/vue/dist/Components/Content' import { NcContent, NcMultiselect } from '@nextcloud/vue'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect' import { actions } from '../store/index.js'
import { actions } from '../store/' import FolderPickerDialog from './FolderPickerDialog.vue'
import FolderPickerDialog from './FolderPickerDialog'
export default { export default {
name: 'ViewBookmarklet', name: 'ViewBookmarklet',
components: { components: {
FolderPickerDialog, FolderPickerDialog,
Content, NcContent,
Multiselect, NcMultiselect,
}, },
props: { props: {
title: { title: {

View File

@ -5,39 +5,38 @@
--> -->
<template> <template>
<Content app-name="bookmarks"> <NcContent app-name="bookmarks">
<Navigation /> <Navigation />
<AppContent :show-details.sync="showDetails"> <NcAppContent :show-details.sync="showDetails">
<template v-if="isFolderView && !smallScreen && folders.length" #list> <template v-if="isFolderView && !smallScreen && folders.length" #list>
<FolderOverview :show-details.sync="showDetails" /> <FolderOverview :show-details.sync="showDetails" />
</template> </template>
<Controls /> <Controls />
<BookmarksList /> <BookmarksList />
</AppContent> </NcAppContent>
<SidebarBookmark /> <SidebarBookmark />
<SidebarFolder /> <SidebarFolder />
<MoveDialog /> <MoveDialog />
<CopyDialog /> <CopyDialog />
<LoadingModal /> <LoadingModal />
<BookmarkContent /> <BookmarkContent />
</Content> </NcContent>
</template> </template>
<script> <script>
import Content from '@nextcloud/vue/dist/Components/Content' import { NcContent, NcAppContent } from '@nextcloud/vue'
import AppContent from '@nextcloud/vue/dist/Components/AppContent' import Navigation from './Navigation.vue'
import Navigation from './Navigation' import FolderOverview from './FolderOverview.vue'
import FolderOverview from './FolderOverview' import BookmarksList from './BookmarksList.vue'
import BookmarksList from './BookmarksList' import Controls from './Controls.vue'
import Controls from './Controls' import SidebarBookmark from './SidebarBookmark.vue'
import SidebarBookmark from './SidebarBookmark' import SidebarFolder from './SidebarFolder.vue'
import SidebarFolder from './SidebarFolder' import MoveDialog from './MoveDialog.vue'
import MoveDialog from './MoveDialog' import CopyDialog from './CopyDialog.vue'
import CopyDialog from './CopyDialog' import { privateRoutes } from '../router.js'
import { privateRoutes } from '../router' import { actions, mutations } from '../store/index.js'
import { actions, mutations } from '../store/' import LoadingModal from './LoadingModal.vue'
import LoadingModal from './LoadingModal' import BookmarkContent from './BookmarkContent.vue'
import BookmarkContent from './BookmarkContent'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
export default { export default {
@ -46,8 +45,8 @@ export default {
BookmarkContent, BookmarkContent,
LoadingModal, LoadingModal,
Navigation, Navigation,
Content, NcContent,
AppContent, NcAppContent,
FolderOverview, FolderOverview,
Controls, Controls,
BookmarksList, BookmarksList,
@ -210,14 +209,7 @@ export default {
} }
</script> </script>
<style> <style>
#app-content { .app-content {
max-width: calc(100vw - 300px); position: relative !important;
min-width: 0;
}
@media only screen and (max-width: 720px) {
#app-content {
max-width: 100%;
}
} }
</style> </style>

View File

@ -5,29 +5,28 @@
--> -->
<template> <template>
<Content app-name="bookmarks"> <NcContent app-name="bookmarks">
<AppContent> <NcAppContent>
<Controls /> <Controls />
<BookmarksList :loading="!!loading.bookmarks" :bookmarks="bookmarks" /> <BookmarksList :loading="!!loading.bookmarks" :bookmarks="bookmarks" />
</AppContent> </NcAppContent>
<BookmarkContent /> <BookmarkContent />
</Content> </NcContent>
</template> </template>
<script> <script>
import Content from '@nextcloud/vue/dist/Components/Content' import { NcContent, NcAppContent } from '@nextcloud/vue'
import AppContent from '@nextcloud/vue/dist/Components/AppContent' import BookmarksList from './BookmarksList.vue'
import BookmarksList from './BookmarksList' import Controls from './Controls.vue'
import Controls from './Controls' import { actions, mutations } from '../store/index.js'
import { actions, mutations } from '../store/' import BookmarkContent from './BookmarkContent.vue'
import BookmarkContent from './BookmarkContent'
export default { export default {
name: 'ViewPublic', name: 'ViewPublic',
components: { components: {
BookmarkContent, BookmarkContent,
Content, NcContent,
AppContent, NcAppContent,
Controls, Controls,
BookmarksList, BookmarksList,
}, },

View File

@ -6,8 +6,9 @@
'use strict' 'use strict'
import { version } from '../package.json' import PackageJson from '../package.json'
const { version } = PackageJson
const rev = '#1' const rev = '#1'
const DYNAMIC_CACHE = `dynamic-cache-${version}` + rev const DYNAMIC_CACHE = `dynamic-cache-${version}` + rev