diff --git a/appinfo/routes.php b/appinfo/routes.php index 9bcbcf8a60..6fda232732 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -502,7 +502,7 @@ ], [ 'name' => 'snippet#getShares', - 'url' => '/api/snippets/share/shares', + 'url' => '/api/snippets/share/shares/{id}', 'verb' => 'GET', ], [ @@ -517,7 +517,7 @@ ], [ 'name' => 'snippet#delete', - 'url' => '/api/snippets', + 'url' => '/api/snippets/{id}', 'verb' => 'DELETE', ], [ diff --git a/lib/Controller/SnippetController.php b/lib/Controller/SnippetController.php index c9c6ec64c2..79805db79b 100644 --- a/lib/Controller/SnippetController.php +++ b/lib/Controller/SnippetController.php @@ -29,8 +29,6 @@ public function __construct( private SnippetService $snippetService, ) { parent::__construct(Application::APP_ID, $request); - - $this->snippetService = $snippetService; $this->uid = $userId; } @@ -77,29 +75,29 @@ public function create(string $title, string $content): JsonResponse { /** * @NoAdminRequired - * @param int $snippetId + * @param int $id * @param string $title * @param string $content * * @return JsonResponse */ #[TrapError] - public function update(int $snippetId, string $title, string $content): JsonResponse { + public function update(int $id, string $title, string $content): JsonResponse { - $snippet = $this->snippetService->find($snippetId, $this->uid); + $snippet = $this->snippetService->find($id, $this->uid); if ($snippet === null) { return JsonResponse::error('Snippet not found', Http::STATUS_NOT_FOUND); } - $this->snippetService->update($snippetId, $this->uid, $title, $content); + $this->snippetService->update($id, $this->uid, $title, $content); return JsonResponse::success($snippet, Http::STATUS_OK); } - public function delete($snippetId): JsonResponse { + public function delete(int $id): JsonResponse { try { - $this->snippetService->delete($snippetId, $this->uid); + $this->snippetService->delete($id, $this->uid); return JsonResponse::success(); } catch (DoesNotExistException $e) { return JsonResponse::fail('Snippet not found', Http::STATUS_NOT_FOUND); @@ -135,14 +133,14 @@ public function share(int $snippetId, string $shareWith, string $type): JsonResp } - public function getShares($id): JsonResponse { - $snippet = $this->snippetService->find($snippetId, $this->uid); + public function getShares(int $id): JsonResponse { + $snippet = $this->snippetService->find($id, $this->uid); if ($snippet === null) { return JsonResponse::error('Snippet not found', Http::STATUS_NOT_FOUND); } - $shares = $this->snippetService->getShares($this->uid, $snippetId); + $shares = $this->snippetService->getShares($this->uid, $id); return JsonResponse::success($shares); } diff --git a/lib/Db/Snippet.php b/lib/Db/Snippet.php index 0b9f7fdeec..b06f63f7e0 100644 --- a/lib/Db/Snippet.php +++ b/lib/Db/Snippet.php @@ -16,7 +16,7 @@ /** * @method string getOwner() * @method void setOwner(string $owner) - * @method string geTitle() + * @method string getTitle() * @method void setTitle(string $title) * @method string getContent() * @method void setContent(string $content) @@ -37,7 +37,7 @@ public function jsonSerialize() { return [ 'id' => $this->getId(), 'owner' => $this->getOwner(), - 'title' => $this->geTitle(), + 'title' => $this->getTitle(), 'content' => $this->getContent(), ]; } diff --git a/lib/Db/SnippetMapper.php b/lib/Db/SnippetMapper.php index 5eff3a7bba..5265d1ad94 100644 --- a/lib/Db/SnippetMapper.php +++ b/lib/Db/SnippetMapper.php @@ -66,15 +66,15 @@ public function findSharedWithMe(string $userId, array $groups): array { $qb = $this->db->getQueryBuilder(); $qb->select('s.*') ->from($this->getTableName(), 's') - ->join('s', 'mail_snippets_shares', 'share', $qb->expr()->eq('s.id', 'sshare.snippet_id')) + ->join('s', 'mail_snippets_shares', 'share', $qb->expr()->eq('s.id', 'share.snippet_id')) ->where($qb->expr()->andX( - $qb->expr()->eq('sshare.share_with', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), - $qb->expr()->in('sshare.type', $qb->createNamedParameter('user', IQueryBuilder::PARAM_STR)) + $qb->expr()->eq('share.share_with', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), + $qb->expr()->eq('share.type', $qb->createNamedParameter('user', IQueryBuilder::PARAM_STR)) )) ->orWhere( $qb->expr()->andX( - $qb->expr()->in('sshare.share_with', $qb->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY)), - $qb->expr()->in('sshare.type', $qb->createNamedParameter('group', IQueryBuilder::PARAM_STR)) + $qb->expr()->in('share.share_with', $qb->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY)), + $qb->expr()->eq('share.type', $qb->createNamedParameter('group', IQueryBuilder::PARAM_STR)) ) ); return $this->findEntities($qb); diff --git a/lib/Db/SnippetShareMapper.php b/lib/Db/SnippetShareMapper.php index 3386a0326b..a9c6b109af 100644 --- a/lib/Db/SnippetShareMapper.php +++ b/lib/Db/SnippetShareMapper.php @@ -82,15 +82,12 @@ public function findAllShares(string $owner): array { * * @return SnippetShare[] */ - public function findSnippetShares(string $owner, int $snippetId): array { + public function findSnippetShares(int $snippetId): array { $qb = $this->db->getQueryBuilder(); - $qb->select('sshare.*') - ->from($this->getTableName(), 'sshare') + $qb->select('*') + ->from($this->getTableName()) ->where( - $qb->expr()->eq('s.owner', $qb->createNamedParameter($owner, IQueryBuilder::PARAM_STR)) - ) - ->andWhere( - $qb->expr()->eq('sshare.snippet_id', $qb->createNamedParameter($snippetId, IQueryBuilder::PARAM_INT)) + $qb->expr()->eq('snippet_id', $qb->createNamedParameter($snippetId, IQueryBuilder::PARAM_INT)) ); return $this->findEntities($qb); diff --git a/lib/Service/SnippetService.php b/lib/Service/SnippetService.php index d791c88207..7b860ea634 100644 --- a/lib/Service/SnippetService.php +++ b/lib/Service/SnippetService.php @@ -32,11 +32,11 @@ class SnippetService { /** @var IGroupManager */ private $groupManager; - public function __construct(SnippetMapper $snippetMapper, SnippetShareMapper $snippetShareMapper, IUserManager $userManager, IGroupManager $groupManager) { + public function __construct(SnippetMapper $snippetMapper, SnippetShareMapper $snippetShareMapper, IGroupManager $groupManager, IUserManager $userManager) { $this->snippetMapper = $snippetMapper; $this->snippetShareMapper = $snippetShareMapper; $this->userManager = $userManager; - $this->$groupManager = $groupManager; + $this->groupManager = $groupManager; } /** @@ -52,7 +52,8 @@ public function findAll(string $userId): array { * @return Snippet[] */ public function findAllSharedWithMe(string $userId): array { - $groups = $this->groupManager->getUserGroupIds($userId); + $user = $this->userManager->get($userId); + $groups = $this->groupManager->getUserGroupIds($user); return $this->snippetMapper->findSharedWithMe($userId, $groups); } /** @@ -128,7 +129,7 @@ public function share(int $snippetId, string $shareWith): void { } public function getShares(string $uid, int $snippetId): array { - return $this->snippetShareMapper->findSnippetShares($uid, $snippetId); + return $this->snippetShareMapper->findSnippetShares($snippetId); } /** diff --git a/src/components/AppSettingsMenu.vue b/src/components/AppSettingsMenu.vue index 8e31368674..8eecbfd067 100755 --- a/src/components/AppSettingsMenu.vue +++ b/src/components/AppSettingsMenu.vue @@ -292,12 +292,26 @@ + + {{ t('mail', 'Create new snippet') }} +
{{ t('mail','My snippets') }}
- +
{{ t('mail','Shared with me') }}
-
+ + + + @@ -307,7 +321,7 @@ import { generateUrl } from '@nextcloud/router' import { showError } from '@nextcloud/dialogs' import CompactMode from 'vue-material-design-icons/ReorderHorizontal.vue' -import { NcAppSettingsSection, NcAppSettingsDialog, NcButton, NcLoadingIcon as IconLoading, NcCheckboxRadioSwitch } from '@nextcloud/vue' +import { NcAppSettingsSection, NcAppSettingsDialog, NcButton, NcLoadingIcon as IconLoading, NcCheckboxRadioSwitch, NcDialog, NcInputField, NcTextArea } from '@nextcloud/vue' import IconAdd from 'vue-material-design-icons/Plus.vue' import IconEmail from 'vue-material-design-icons/Email.vue' @@ -321,6 +335,8 @@ import InternalAddress from './InternalAddress.vue' import isMobile from '@nextcloud/vue/dist/Mixins/isMobile.js' import { mapGetters } from 'vuex' import List from './snippets/List.vue' +import IconCancel from '@mdi/svg/svg/cancel.svg?raw' +import IconCheck from '@mdi/svg/svg/check.svg?raw' export default { name: 'AppSettingsMenu', @@ -340,6 +356,9 @@ export default { VerticalSplit, HorizontalSplit, List, + NcDialog, + NcInputField, + NcTextArea, }, mixins: [isMobile], props: { @@ -372,6 +391,32 @@ export default { showMailSettings: true, selectedAccount: null, mailvelopeIsAvailable: false, + snippetDialogOpen: false, + localSnippet: { + title: '', + content: '', + }, + snippetButtons: [ + { + label: 'Cancel', + icon: IconCancel, + callback: () => { + this.snippetDialogOpen = false + this.localSnippet = { + title: '', + content: '', + } + }, + }, + { + label: 'Ok', + type: 'primary', + icon: IconCheck, + callback: () => { + this.$store.dispatch('createSnippet', { ...this.localSnippet }) + }, + }, + ], } }, computed: { @@ -409,10 +454,10 @@ export default { return this.$store.getters.getPreference('layout-mode', 'vertical-split') }, mySnippets() { - return this.$store.getters.getSnippets() + return this.$store.getters.getMySnippets }, - shareSnippet() { - return this.$store.getters.getSharedSnippets() + sharedSnippet() { + return this.$store.getters.getSharedSnippets }, }, watch: { @@ -430,6 +475,10 @@ export default { mounted() { this.sortOrder = this.$store.getters.getPreference('sort-order', 'newest') document.addEventListener.call(window, 'mailvelope', () => this.checkMailvelope()) + if (!this.$store.getters.areSnippetsFetched) { + this.$store.dispatch('fetchMySnippets') + this.$store.dispatch('fetchSharedSnippets') + } }, updated() { this.checkMailvelope() diff --git a/src/components/Composer.vue b/src/components/Composer.vue index edd76170aa..a1aad57f4e 100644 --- a/src/components/Composer.vue +++ b/src/components/Composer.vue @@ -993,7 +993,7 @@ export default { if (this.sendAt && this.isSendAtCustom) { this.selectedDate = new Date(this.sendAt) } - if (this.snippets.length === 0) { + if (!this.$store.getters.areSnippetsFetched) { this.$store.dispatch('fetchSharedSnippets') this.$store.dispatch('fetchMySnippets') } diff --git a/src/components/snippets/ListItem.vue b/src/components/snippets/ListItem.vue index de478b0e51..daf0509f52 100644 --- a/src/components/snippets/ListItem.vue +++ b/src/components/snippets/ListItem.vue @@ -8,19 +8,22 @@ {{ snippet.title }}

- {{ snippet.preview }} + {{ snippet.content }}

+ @option:selecting="shareSnippet" + @option:deselecting="removeShare" /> - + {{ t('mail','Delete {title}', { title: snippet.title }) }} - + {{ t('mail','Edit {title}', { title: snippet.title }) }} @@ -29,15 +32,19 @@ :is-form="true" :buttons="buttons" size="normal"> - - + +