From 420389cded4a1dd6ed7cfe8c7cdb7538b975e640 Mon Sep 17 00:00:00 2001 From: GretaD Date: Mon, 15 Jun 2020 18:28:57 +0200 Subject: [PATCH] Add rename mailbox option Signed-off-by: GretaD --- lib/IMAP/FolderMapper.php | 13 + src/components/NavigationFolder.vue | 331 +++++++++++++++++++++++++ src/service/FolderService.js | 51 ++++ src/store/actions.js | 7 + src/store/mutations.js | 15 ++ src/tests/unit/store/mutations.spec.js | 51 ++++ 6 files changed, 468 insertions(+) create mode 100644 src/components/NavigationFolder.vue create mode 100644 src/service/FolderService.js diff --git a/lib/IMAP/FolderMapper.php b/lib/IMAP/FolderMapper.php index 7f3f2795ef..b40d5abeba 100644 --- a/lib/IMAP/FolderMapper.php +++ b/lib/IMAP/FolderMapper.php @@ -139,6 +139,19 @@ public function getFoldersStatusAsObject(Horde_Imap_Client_Socket $client, ); } + /** + * @param Horde_Imap_Client_Socket $client + * @param string $oldName + * @param string $newName + * + * @throws Horde_Imap_Client_Exception + */ + public function renameFolder(Horde_Imap_Client_Socket $client, + string $oldName, + string $newName): void { + $client->renameMailbox($oldName, $newName); + } + /** * @param Folder[] $folders * diff --git a/src/components/NavigationFolder.vue b/src/components/NavigationFolder.vue new file mode 100644 index 0000000000..932689a5ce --- /dev/null +++ b/src/components/NavigationFolder.vue @@ -0,0 +1,331 @@ + + + + + diff --git a/src/service/FolderService.js b/src/service/FolderService.js new file mode 100644 index 0000000000..3a3289f931 --- /dev/null +++ b/src/service/FolderService.js @@ -0,0 +1,51 @@ +import {generateUrl} from '@nextcloud/router' +import Axios from '@nextcloud/axios' + +export function fetchAll(accountId) { + const url = generateUrl('/apps/mail/api/accounts/{accountId}/folders', { + accountId, + }) + + // FIXME: this return format is weird and should be avoided + // TODO: respect `resp.data.delimiter` value + return Axios.get(url).then((resp) => resp.data.folders) +} + +export function create(accountId, name) { + const url = generateUrl('/apps/mail/api/accounts/{accountId}/folders', { + accountId, + }) + + const data = { + name, + } + return Axios.post(url, data).then((resp) => resp.data) +} + +export function getFolderStats(accountId, folderId) { + const url = generateUrl('/apps/mail/api/accounts/{accountId}/folders/{folderId}/stats', { + accountId, + folderId, + }) + + return Axios.get(url).then((resp) => resp.data) +} + +export function markFolderRead(accountId, folderId) { + const url = generateUrl('/apps/mail/api/accounts/{accountId}/folders/{folderId}/read', { + accountId, + folderId, + }) + + return Axios.post(url).then((resp) => resp.data) +} + +export async function patchFolder(accountId, folderId, data) { + const url = generateUrl('/apps/mail/api/accounts/{accountId}/folders/{folderId}', { + accountId, + folderId, + }) + + const response = await Axios.patch(url, data) + return response.data.data +} diff --git a/src/store/actions.js b/src/store/actions.js index d0a62e26eb..659e0b9463 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -669,5 +669,12 @@ export default { async deleteAlias({ commit }, { account, aliasToDelete }) { await deleteAlias(account, aliasToDelete) commit('deleteAlias', { account, alias: aliasToDelete }) + async renameFolder({commit}, {account, folder, newName}) { + await patchFolder(account.id, folder.id, { + name: newName, + }) + + console.debug(`folder ${folder.id} renamed to ${newName}`, {folder}) + commit('renameFolder', {accountId: account.id, folder, newName}) }, } diff --git a/src/store/mutations.js b/src/store/mutations.js index 64e57b3031..38d764a915 100644 --- a/src/store/mutations.js +++ b/src/store/mutations.js @@ -218,4 +218,19 @@ export default { deleteAlias(state, { account, alias }) { account.aliases.splice(account.aliases.indexOf(alias), 1) }, + renameFolder(state, { accountId, folder, newName }) { + const oldId = folder.id + + // Remove the old entry + Vue.delete(state.folders, normalizedFolderId(accountId, oldId)) + // Update the ID + folder.id = btoa(newName) + // Set the new entry + Vue.set(state.folders, normalizedFolderId(accountId, folder.id), folder) + + // Update the reference + const oldNormalized = normalizedFolderId(accountId, oldId) + state.accounts[accountId].folders = state.accounts[accountId].folders.filter(id => id !== oldNormalized) + state.accounts[accountId].folders.push(normalizedFolderId(accountId, folder.id)) + }, } diff --git a/src/tests/unit/store/mutations.spec.js b/src/tests/unit/store/mutations.spec.js index 6099c9cac3..a3519bc192 100644 --- a/src/tests/unit/store/mutations.spec.js +++ b/src/tests/unit/store/mutations.spec.js @@ -27,6 +27,57 @@ import { } from '../../../store/constants' describe('Vuex store mutations', () => { + it('renames a folder', () => { + const oldId = btoa('Old') + const newId = btoa('New') + const state = { + accounts: { + 123: { + accountId: 123, + id: 123, + folders: [ + '123-' + oldId + ], + }, + }, + envelopes: {}, + folders: { + ['123-' + oldId]: { + id: oldId, + envelopeLists: {}, + }, + }, + } + + mutations.renameFolder(state, { + accountId: 123, + folder: { + id: oldId, + envelopeLists: {}, + }, + newName: 'New' + }) + + expect(state).to.deep.equal({ + accounts: { + 123: { + accountId: 123, + id: 123, + folders: [ + '123-' + newId + ], + }, + }, + envelopes: {}, + folders: { + ['123-' + newId]: { + id: newId, + envelopeLists: {}, + }, + }, + }) + }) + it('adds envelopes', () => { const state = { accounts: {