Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/bookmarks.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Klehr <mklehr@gmx.net>2022-03-13 18:34:35 +0300
committerMarcel Klehr <mklehr@gmx.net>2022-03-13 18:34:35 +0300
commit74fb4510f6fb8318e805dae72738deb621124668 (patch)
tree28d37cf3296c34f5f20f644609c8b28046563aa9
parentddeb5fc9535a1393022528b351e36f2bd2309341 (diff)
Projects: Add bookmarks foldersfeature/projects
remove bookmark picker from collections.js for now as we don't have a picker, yet. Signed-off-by: Marcel Klehr <mklehr@gmx.net>
-rw-r--r--lib/AppInfo/Application.php2
-rw-r--r--lib/Collaboration/Resources/FolderResourceProvider.php90
-rw-r--r--lib/Db/FolderMapper.php4
-rw-r--r--src/collections.js100
-rw-r--r--src/components/FolderPicker.vue7
-rw-r--r--src/components/FolderPickerDialog.vue3
-rw-r--r--src/components/SidebarBookmark.vue3
-rw-r--r--src/components/SidebarFolder.vue21
8 files changed, 155 insertions, 75 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 0555ffea..312db322 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -11,6 +11,7 @@ namespace OCA\Bookmarks\AppInfo;
use Closure;
use OC\EventDispatcher\SymfonyAdapter;
use OCA\Bookmarks\Activity\ActivityPublisher;
+use OCA\Bookmarks\Collaboration\Resources\FolderResourceProvider;
use OCA\Bookmarks\Collaboration\Resources\ResourceProvider;
use OCA\Bookmarks\Dashboard\Frequent;
use OCA\Bookmarks\Dashboard\Recent;
@@ -95,6 +96,7 @@ class Application extends App implements IBootstrap {
protected function registerCollaborationResources(IProviderManager $resourceManager, SymfonyAdapter $symfonyAdapter): void {
$resourceManager->registerResourceProvider(ResourceProvider::class);
+ $resourceManager->registerResourceProvider(FolderResourceProvider::class);
$symfonyAdapter->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', static function () {
Util::addScript('bookmarks', 'bookmarks-collections');
diff --git a/lib/Collaboration/Resources/FolderResourceProvider.php b/lib/Collaboration/Resources/FolderResourceProvider.php
new file mode 100644
index 00000000..1ffc1a2c
--- /dev/null
+++ b/lib/Collaboration/Resources/FolderResourceProvider.php
@@ -0,0 +1,90 @@
+<?php
+/*
+ * Copyright (c) 2022. The Nextcloud Bookmarks contributors.
+ *
+ * This file is licensed under the Affero General Public License version 3 or later. See the COPYING file.
+ */
+
+namespace OCA\Bookmarks\Collaboration\Resources;
+
+use OCA\Bookmarks\Db\Folder;
+use OCA\Bookmarks\Db\FolderMapper;
+use OCA\Bookmarks\Service\Authorizer;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\Collaboration\Resources\IProvider;
+use OCP\Collaboration\Resources\IResource;
+use OCP\IURLGenerator;
+use OCP\IUser;
+
+class FolderResourceProvider implements IProvider {
+ public const RESOURCE_TYPE = 'bookmarks-folder';
+ /**
+ * @var IURLGenerator
+ */
+ private $url;
+ /**
+ * @var Authorizer
+ */
+ private $authorizer;
+ /**
+ * @var FolderMapper
+ */
+ private $folderMapper;
+
+ public function __construct(IURLGenerator $url, Authorizer $authorizer, FolderMapper $folderMapper) {
+ $this->url = $url;
+ $this->authorizer = $authorizer;
+ $this->folderMapper = $folderMapper;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getType(): string {
+ return self::RESOURCE_TYPE;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getResourceRichObject(IResource $resource): array {
+ $folder = $this->getFolder($resource);
+ $favicon = $this->url->imagePath('bookmarks', 'bookmarks-black.svg');
+ $resourceUrl = $this->url->linkToRouteAbsolute('bookmarks.web_view.indexfolder', ['folder' => $folder->getId()]);
+
+ return [
+ 'type' => self::RESOURCE_TYPE,
+ 'id' => $resource->getId(),
+ 'name' => $folder->getTitle(),
+ 'link' => $resourceUrl,
+ 'iconUrl' => $favicon,
+ ];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function canAccessResource(IResource $resource, ?IUser $user): bool {
+ if ($resource->getType() !== self::RESOURCE_TYPE || !($user instanceof IUser)) {
+ return false;
+ }
+ $folder = $this->getFolder($resource);
+ if ($folder === null) {
+ return false;
+ }
+ if ($folder->getUserId() === $user->getUID()) {
+ return true;
+ }
+ $permissions = $this->authorizer->getUserPermissionsForFolder($user->getUID(), $folder->getId());
+ return Authorizer::hasPermission(Authorizer::PERM_READ, $permissions);
+ }
+
+ private function getFolder(IResource $resource) : ?Folder {
+ try {
+ return $this->folderMapper->find((int) $resource->getId());
+ } catch (MultipleObjectsReturnedException|DoesNotExistException $e) {
+ return null;
+ }
+ }
+}
diff --git a/lib/Db/FolderMapper.php b/lib/Db/FolderMapper.php
index 99c93719..14ad59b6 100644
--- a/lib/Db/FolderMapper.php
+++ b/lib/Db/FolderMapper.php
@@ -59,11 +59,11 @@ class FolderMapper extends QBMapper {
/**
* @param int $id
- * @return Entity
+ * @return Folder
* @throws DoesNotExistException if not found
* @throws MultipleObjectsReturnedException if more than one result
*/
- public function find(int $id): Entity {
+ public function find(int $id): Folder {
$qb = $this->db->getQueryBuilder();
$qb
->select('*')
diff --git a/src/collections.js b/src/collections.js
index c81d16f8..83504404 100644
--- a/src/collections.js
+++ b/src/collections.js
@@ -6,70 +6,46 @@
import Vue from 'vue'
import FolderPickerDialog from './components/FolderPickerDialog'
+import { Store } from 'vuex'
+import deepClone from 'clone-deep'
+import store, { actions } from './store'
+import AppGlobal from './mixins/AppGlobal'
+import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
-// eslint-disable-next-line no-unexpected-multiline
-(function(OCP, OC) {
+// eslint-disable-next-line
+__webpack_nonce__ = btoa(OC.requestToken)
+// eslint-disable-next-line
+__webpack_public_path__ = OC.linkTo('bookmarks', 'js/')
- // eslint-disable-next-line
- __webpack_nonce__ = btoa(OC.requestToken)
- // eslint-disable-next-line
- __webpack_public_path__ = OC.linkTo('bookmarks', 'js/')
+Vue.mixin(AppGlobal)
+Vue.directive('tooltip', Tooltip)
- Vue.prototype.t = t
- Vue.prototype.n = n
- Vue.prototype.OC = OC
-
- OCP.Collaboration.registerType('bookmarks', {
- action: () => {
- return new Promise((resolve, reject) => {
- const container = document.createElement('div')
- container.id = 'bookmarks-bookmark-select'
- const body = document.getElementById('body-user')
- body.appendChild(container)
- const ComponentVM = new Vue({
- render: h => h(FolderPickerDialog),
- })
- ComponentVM.$mount(container)
- ComponentVM.$root.$on('close', () => {
- ComponentVM.$el.remove()
- ComponentVM.$destroy()
- reject(new Error('User cancelled resource selection'))
- })
- ComponentVM.$root.$on('select', (id) => {
- resolve(id)
- ComponentVM.$el.remove()
- ComponentVM.$destroy()
- })
+OCP.Collaboration.registerType('bookmarks-folder', {
+ action: () => {
+ return new Promise((resolve, reject) => {
+ const container = document.createElement('div')
+ container.id = 'bookmarks-bookmark-folder-select'
+ const body = document.getElementById('body-user')
+ body.appendChild(container)
+ const ComponentVM = new Vue({
+ render: h => h(FolderPickerDialog),
+ store: new Store(deepClone(store)),
})
- },
- typeString: t('bookmarks', 'Link to a bookmark'),
- typeIconClass: 'icon-favorite',
- })
-
- OCP.Collaboration.registerType('bookmarks::folder', {
- action: () => {
- return new Promise((resolve, reject) => {
- const container = document.createElement('div')
- container.id = 'bookmarks-bookmark-folder-select'
- const body = document.getElementById('body-user')
- body.appendChild(container)
- const ComponentVM = new Vue({
- render: h => h(FolderPickerDialog),
- })
- ComponentVM.$mount(container)
- ComponentVM.$root.$on('close', () => {
- ComponentVM.$el.remove()
- ComponentVM.$destroy()
- reject(new Error('User cancelled resource selection'))
- })
- ComponentVM.$root.$on('select', (id) => {
- resolve(id)
- ComponentVM.$el.remove()
- ComponentVM.$destroy()
- })
+ ComponentVM.$store.dispatch(actions.LOAD_FOLDERS, true)
+ ComponentVM.$mount(container)
+ window.bookmarksPicker = ComponentVM
+ ComponentVM.$root.$on('close', () => {
+ ComponentVM.$el.remove()
+ ComponentVM.$destroy()
+ reject(new Error('User cancelled resource selection'))
+ })
+ ComponentVM.$root.$on('select', (id) => {
+ resolve(id)
+ ComponentVM.$el.remove()
+ ComponentVM.$destroy()
})
- },
- typeString: t('bookmarks', 'Link to a bookmark folder'),
- typeIconClass: 'icon-favorite',
- })
-})(window.OCP, window.OC)
+ })
+ },
+ typeString: t('bookmarks', 'Link to a bookmark folder'),
+ typeIconClass: 'icon-favorite',
+})
diff --git a/src/components/FolderPicker.vue b/src/components/FolderPicker.vue
index b35c3f62..709496a9 100644
--- a/src/components/FolderPicker.vue
+++ b/src/components/FolderPicker.vue
@@ -105,12 +105,7 @@ export default {
.currentfolder h2 {
margin: 0;
-}
-
-.currentfolder h2 .material-design-icon {
- position: relative;
- top: 5px;
- margin: 0 15px;
+ display: flex;
}
.treefolder__title .material-design-icon {
diff --git a/src/components/FolderPickerDialog.vue b/src/components/FolderPickerDialog.vue
index 33010ac5..0afb9e4d 100644
--- a/src/components/FolderPickerDialog.vue
+++ b/src/components/FolderPickerDialog.vue
@@ -39,11 +39,12 @@ export default {
created() {},
methods: {
onSelect(folderId) {
+ this.$root.$emit('select', folderId)
this.$emit('input', folderId)
- this.$emit('select', folderId)
this.$emit('close')
},
onClose() {
+ this.$root.$emit('close')
this.$emit('close')
},
},
diff --git a/src/components/SidebarBookmark.vue b/src/components/SidebarBookmark.vue
index 8523e9a6..a0d411eb 100644
--- a/src/components/SidebarBookmark.vue
+++ b/src/components/SidebarBookmark.vue
@@ -95,7 +95,8 @@
<a class="button" :href="archivedFile" target="_blank"><span class="icon-files-dark" /> {{ t('bookmarks', 'Open file location') }}</a>
</div>
</AppSidebarTab>
- <AppSidebarTab id="bookmark-projects"
+ <AppSidebarTab v-if="!isPublic"
+ id="bookmark-projects"
:name="t('bookmarks', 'Projects')"
icon="icon-projects"
:order="1">
diff --git a/src/components/SidebarFolder.vue b/src/components/SidebarFolder.vue
index fb4afad8..6a7d2e8c 100644
--- a/src/components/SidebarFolder.vue
+++ b/src/components/SidebarFolder.vue
@@ -11,7 +11,10 @@
:title="folder.title"
:active.sync="activeTab"
@close="onClose">
- <AppSidebarTab id="folder-details" :name="t('bookmarks', 'Details')" icon="icon-info">
+ <AppSidebarTab id="folder-details"
+ :name="t('bookmarks', 'Details')"
+ icon="icon-info"
+ :order="0">
<h3>{{ t('bookmarks', 'Owner') }}</h3>
<UserBubble :user="folder.userId" :display-name="folder.userId" />
<h3>{{ t('bookmarks', 'Bookmarks') }}</h3>
@@ -20,7 +23,8 @@
<AppSidebarTab v-if="isSharable"
id="folder-sharing"
:name="t('bookmarks', 'Sharing')"
- icon="icon-shared">
+ icon="icon-shared"
+ :order="1">
<div class="participant-select">
<figure :class="{'icon-user': true, 'share__avatar': true }" />
<Multiselect v-model="participant"
@@ -108,6 +112,16 @@
</div>
</div>
</AppSidebarTab>
+ <AppSidebarTab v-if="!isPublic"
+ id="bookmark-projects"
+ :name="t('bookmarks', 'Projects')"
+ icon="icon-projects"
+ :order="2">
+ <CollectionList v-if="folder"
+ :id="''+folder.id"
+ :name="folder.title"
+ type="bookmarks-folder" />
+ </AppSidebarTab>
</AppSidebar>
</template>
<script>
@@ -128,10 +142,11 @@ import { actions, mutations } from '../store/'
import EyeIcon from 'vue-material-design-icons/Eye'
import PencilIcon from 'vue-material-design-icons/Pencil'
import ShareAllIcon from 'vue-material-design-icons/ShareAll'
+import { CollectionList } from 'nextcloud-vue-collections'
export default {
name: 'SidebarFolder',
- components: { AppSidebar, AppSidebarTab, Avatar, Multiselect, ActionButton, ActionCheckbox, Actions, UserBubble, ActionSeparator, EyeIcon, PencilIcon, ShareAllIcon },
+ components: { AppSidebar, AppSidebarTab, Avatar, Multiselect, ActionButton, ActionCheckbox, Actions, UserBubble, ActionSeparator, EyeIcon, PencilIcon, ShareAllIcon, CollectionList },
data() {
return {
participantSearchResults: [],