From 63772629cfd014718a37e2bc79bc3a36128c63ad Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Mon, 17 Jul 2017 19:19:01 +0000 Subject: [PATCH] mv folder in cli --- CliClient/app/app.js | 9 +++++++ CliClient/app/command-mkbook.js | 5 +--- CliClient/app/command-mv.js | 26 +++++++++++++------ .../lib/components/screens/folder.js | 5 +--- ReactNativeClient/lib/models/folder.js | 22 +++++++++++++--- 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/CliClient/app/app.js b/CliClient/app/app.js index 58d6217d6..8fd9d36eb 100644 --- a/CliClient/app/app.js +++ b/CliClient/app/app.js @@ -66,6 +66,15 @@ class Application { this.updatePrompt(); } + async guessTypeAndLoadItem(pattern, options = null) { + let type = BaseModel.TYPE_NOTE; + if (pattern.indexOf('/') === 0) { + type = BaseModel.TYPE_FOLDER; + pattern = pattern.substr(1); + } + return this.loadItem(type, pattern, options); + } + async loadItem(type, pattern, options = null) { let output = await this.loadItems(type, pattern, options); return output.length ? output[0] : null; diff --git a/CliClient/app/command-mkbook.js b/CliClient/app/command-mkbook.js index ae04534c4..5dbaf4866 100644 --- a/CliClient/app/command-mkbook.js +++ b/CliClient/app/command-mkbook.js @@ -18,10 +18,7 @@ class Command extends BaseCommand { } async action(args) { - let folder = await Folder.save({ title: args['notebook'] }, { - duplicateCheck: true, - reservedTitleCheck: true, - }); + let folder = await Folder.save({ title: args['notebook'] }, { userSideValidation: true }); app().switchCurrentFolder(folder); } diff --git a/CliClient/app/command-mv.js b/CliClient/app/command-mv.js index de94e2339..467f6eac1 100644 --- a/CliClient/app/command-mv.js +++ b/CliClient/app/command-mv.js @@ -9,11 +9,11 @@ import { autocompleteItems } from './autocomplete.js'; class Command extends BaseCommand { usage() { - return 'mv '; + return 'mv '; } description() { - return 'Moves the notes matching to .'; + return 'Moves the notes matching to . If is a note, it will be moved to the notebook . If is a notebook, it will be renamed to .'; } autocomplete() { @@ -22,15 +22,25 @@ class Command extends BaseCommand { async action(args) { const pattern = args['pattern']; + const destination = args['destination']; - const folder = await Folder.loadByField('title', args['notebook']); - if (!folder) throw new Error(_('No notebook "%s"', args['notebook'])); + const item = await app().guessTypeAndLoadItem(pattern); - const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern); - if (!notes.length) throw new Error(_('No note matches this pattern: "%s"', pattern)); + if (!item) throw new Error(_('No item matches pattern "%s"', pattern)); - for (let i = 0; i < notes.length; i++) { - await Note.moveToFolder(notes[i].id, folder.id); + if (item.type_ == BaseModel.TYPE_FOLDER) { + await Folder.save({ id: item.id, title: destination }, { userSideValidation: true }); + await app().refreshCurrentFolder(); + } else { // TYPE_NOTE + const folder = await Folder.loadByField('title', destination); + if (!folder) throw new Error(_('No notebook "%s"', destination)); + + const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern); + if (!notes.length) throw new Error(_('No note matches this pattern: "%s"', pattern)); + + for (let i = 0; i < notes.length; i++) { + await Note.moveToFolder(notes[i].id, folder.id); + } } } diff --git a/ReactNativeClient/lib/components/screens/folder.js b/ReactNativeClient/lib/components/screens/folder.js index 9ed97dc1f..d06bc4c15 100644 --- a/ReactNativeClient/lib/components/screens/folder.js +++ b/ReactNativeClient/lib/components/screens/folder.js @@ -66,10 +66,7 @@ class FolderScreenComponent extends BaseScreenComponent { let folder = Object.assign({}, this.state.folder); try { - folder = await Folder.save(folder, { - duplicateCheck: true, - reservedTitleCheck: true, - }); + folder = await Folder.save(folder, { userSideValidation: true }); reg.scheduleSync(); } catch (error) { diff --git a/ReactNativeClient/lib/models/folder.js b/ReactNativeClient/lib/models/folder.js index 866a8d918..be9dfafe9 100644 --- a/ReactNativeClient/lib/models/folder.js +++ b/ReactNativeClient/lib/models/folder.js @@ -114,15 +114,29 @@ class Folder extends BaseItem { // These "duplicateCheck" and "reservedTitleCheck" should only be done when a user is // manually creating a folder. They shouldn't be done for example when the folders - // are being synced to avoid any strange side-effect. Technically it's possible to - // have folders and notes with duplicate titles (or no title), or with reserved words, + // are being synced to avoid any strange side-effects. Technically it's possible to + // have folders and notes with duplicate titles (or no title), or with reserved words. static async save(o, options = null) { - if (options && options.duplicateCheck === true && o.title) { + if (!options) options = {}; + + if (options.userSideValidation === true) { + if (!('duplicateCheck' in options)) options.duplicateCheck = true; + if (!('reservedTitleCheck' in options)) options.reservedTitleCheck = true; + if (!('stripLeftSlashes' in options)) options.stripLeftSlashes = true; + } + + if (options.stripLeftSlashes === true && o.title) { + while (o.title.length && (o.title[0] == '/' || o.title[0] == "\\")) { + o.title = o.title.substr(1); + } + } + + if (options.duplicateCheck === true && o.title) { let existingFolder = await Folder.loadByTitle(o.title); if (existingFolder && existingFolder.id != o.id) throw new Error(_('A notebook with this title already exists: "%s"', o.title)); } - if (options && options.reservedTitleCheck === true && o.title) { + if (options.reservedTitleCheck === true && o.title) { if (o.title == Folder.conflictFolderTitle()) throw new Error(_('Notebooks cannot be named "%s", which is a reserved title.', o.title)); }