mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-23 18:53:36 +02:00
Removed default folder concept
This commit is contained in:
parent
e1de43988d
commit
79e0bb2e65
@ -63,12 +63,12 @@ async function main() {
|
||||
// console.info('DELETING ALL DATA');
|
||||
// await db.exec('DELETE FROM notes');
|
||||
// await db.exec('DELETE FROM changes');
|
||||
// await db.exec('DELETE FROM folders WHERE is_default != 1');
|
||||
// await db.exec('DELETE FROM folders');
|
||||
// await db.exec('DELETE FROM resources');
|
||||
// await db.exec('DELETE FROM deleted_items');
|
||||
// await db.exec('DELETE FROM tags');
|
||||
// await db.exec('DELETE FROM note_tags');
|
||||
// let folder1 = await Folder.save({ title: 'test1', is_default: 1 });
|
||||
// let folder1 = await Folder.save({ title: 'test1' });
|
||||
// let folder2 = await Folder.save({ title: 'test2' });
|
||||
// await importEnex(folder1.id, '/mnt/c/Users/Laurent/Desktop/Laurent.enex');
|
||||
// return;
|
||||
@ -324,13 +324,27 @@ async function main() {
|
||||
|
||||
commands.push({
|
||||
usage: 'rm <item-title>',
|
||||
description: 'Deletes the given item. For a notebook, all the notes within that notebook will be deleted.',
|
||||
description: 'Deletes the given item. For a notebook, all the notes within that notebook will be deleted. Use `rm ../<notebook-name>` to delete a notebook.',
|
||||
action: async function(args, end) {
|
||||
let title = args['item-title'];
|
||||
let itemType = currentFolder ? BaseModel.MODEL_TYPE_NOTE : BaseModel.MODEL_TYPE_FOLDER;
|
||||
let itemType = null;
|
||||
|
||||
if (title.substr(0, 3) == '../') {
|
||||
itemType = BaseModel.MODEL_TYPE_FOLDER;
|
||||
title = title.substr(3);
|
||||
} else {
|
||||
itemType = BaseModel.MODEL_TYPE_NOTE;
|
||||
}
|
||||
|
||||
let item = await BaseItem.loadItemByField(itemType, 'title', title);
|
||||
if (!item) return commandError(this, _('No item with title "%s" found.', title), end);
|
||||
await BaseItem.deleteItem(itemType, item.id);
|
||||
|
||||
if (currentFolder && currentFolder.id == item.id) {
|
||||
let f = await Folder.defaultFolder();
|
||||
switchCurrentFolder(f);
|
||||
}
|
||||
|
||||
end();
|
||||
},
|
||||
autocomplete: autocompleteItems,
|
||||
|
@ -9,44 +9,4 @@ import { BaseModel } from 'lib/base-model.js';
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.error('Unhandled promise rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
async function thereIsOnlyOneDefaultFolder() {
|
||||
let count = 0;
|
||||
let folders = await Folder.all();
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
if (!!folders[i].is_default) count++;
|
||||
}
|
||||
return count === 1;
|
||||
}
|
||||
|
||||
describe('Folder', function() {
|
||||
|
||||
beforeEach( async (done) => {
|
||||
await setupDatabase(1);
|
||||
switchClient(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should have one default folder only', async (done) => {
|
||||
let f1 = await Folder.save({ title: 'folder1', is_default: 1 });
|
||||
let f2 = await Folder.save({ title: 'folder2' });
|
||||
let f3 = await Folder.save({ title: 'folder3' });
|
||||
|
||||
await Folder.save({ id: f2.id, is_default: 1 });
|
||||
f2 = await Folder.load(f2.id);
|
||||
|
||||
expect(f2.is_default).toBe(1);
|
||||
|
||||
let r = await thereIsOnlyOneDefaultFolder();
|
||||
expect(r).toBe(true);
|
||||
|
||||
await Folder.save({ id: f2.id, is_default: 0 });
|
||||
f2 = await Folder.load(f2.id);
|
||||
|
||||
expect(f2.is_default).toBe(1);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
@ -53,7 +53,7 @@ class SideMenuContentComponent extends Component {
|
||||
let buttons = [];
|
||||
for (let i = 0; i < this.props.folders.length; i++) {
|
||||
let f = this.props.folders[i];
|
||||
let title = f.title + (f.is_default ? ' *' : '');
|
||||
let title = f.title;
|
||||
buttons.push(
|
||||
<Button style={styles.button} title={title} onPress={() => { this.folder_press(f) }} key={f.id} />
|
||||
);
|
||||
|
@ -254,10 +254,7 @@ class BaseModel {
|
||||
static delete(id, options = null) {
|
||||
options = this.modOptions(options);
|
||||
|
||||
if (!id) {
|
||||
Log.warn('Cannot delete object without an ID');
|
||||
return;
|
||||
}
|
||||
if (!id) throw new Error('Cannot delete object without an ID');
|
||||
|
||||
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]).then(() => {
|
||||
let trackDeleted = this.trackDeleted();
|
||||
|
@ -10,8 +10,7 @@ CREATE TABLE folders (
|
||||
title TEXT NOT NULL DEFAULT "",
|
||||
created_time INT NOT NULL DEFAULT 0,
|
||||
updated_time INT NOT NULL DEFAULT 0,
|
||||
sync_time INT NOT NULL DEFAULT 0,
|
||||
is_default INT NOT NULL DEFAULT 0
|
||||
sync_time INT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE notes (
|
||||
@ -437,7 +436,7 @@ class Database {
|
||||
|
||||
let queries = this.wrapQueries(this.sqlStringToLines(structureSql));
|
||||
queries.push(this.wrapQuery('INSERT INTO settings (`key`, `value`, `type`) VALUES ("clientId", "' + uuid.create() + '", "' + Database.enumId('settings', 'string') + '")'));
|
||||
queries.push(this.wrapQuery('INSERT INTO folders (`id`, `title`, `is_default`, `created_time`) VALUES ("' + uuid.create() + '", "' + _('Notebook') + '", 1, ' + (new Date()).getTime() + ')'));
|
||||
queries.push(this.wrapQuery('INSERT INTO folders (`id`, `title`, `created_time`) VALUES ("' + uuid.create() + '", "' + _('Notebook') + '", ' + (new Date()).getTime() + ')'));
|
||||
|
||||
return this.transactionExecBatch(queries).then(() => {
|
||||
this.logger().info('Database schema created successfully');
|
||||
|
@ -43,6 +43,21 @@ class BaseItem extends BaseModel {
|
||||
});
|
||||
}
|
||||
|
||||
static loadItemByField(itemType, field, value) {
|
||||
let ItemClass = this.itemClass(itemType);
|
||||
return ItemClass.loadByField(field, value);
|
||||
}
|
||||
|
||||
static loadItem(itemType, id) {
|
||||
let ItemClass = this.itemClass(itemType);
|
||||
return ItemClass.load(id);
|
||||
}
|
||||
|
||||
static deleteItem(itemType, id) {
|
||||
let ItemClass = this.itemClass(itemType);
|
||||
return ItemClass.delete(id);
|
||||
}
|
||||
|
||||
static serialize_format(propName, propValue) {
|
||||
if (['created_time', 'updated_time'].indexOf(propName) >= 0) {
|
||||
if (!propValue) return '';
|
||||
|
@ -57,31 +57,23 @@ class Folder extends BaseItem {
|
||||
});
|
||||
}
|
||||
|
||||
static delete(folderId, options = null) {
|
||||
return this.load(folderId).then((folder) => {
|
||||
if (!folder) throw new Error('Trying to delete non-existing folder: ' + folderId);
|
||||
static async delete(folderId, options = null) {
|
||||
let folder = await Folder.load(folderId);
|
||||
if (!folder) throw new Error('Trying to delete non-existing notebook: ' + folderId);
|
||||
|
||||
if (!!folder.is_default) {
|
||||
throw new Error(_('Cannot delete the default list'));
|
||||
}
|
||||
}).then(() => {
|
||||
return this.noteIds(folderId);
|
||||
}).then((ids) => {
|
||||
let chain = [];
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
chain.push(() => {
|
||||
return Note.delete(ids[i]);
|
||||
});
|
||||
}
|
||||
let count = await Folder.count();
|
||||
if (count <= 1) throw new Error(_('Cannot delete the last notebook'));
|
||||
|
||||
return promiseChain(chain);
|
||||
}).then(() => {
|
||||
return super.delete(folderId, options);
|
||||
}).then(() => {
|
||||
this.dispatch({
|
||||
type: 'FOLDER_DELETE',
|
||||
folderId: folderId,
|
||||
});
|
||||
let noteIds = await Folder.noteIds(folderId);
|
||||
for (let i = 0; i < noteIds.length; i++) {
|
||||
await Note.delete(noteIds[i]);
|
||||
}
|
||||
|
||||
super.delete(folderId, options);
|
||||
|
||||
this.dispatch({
|
||||
type: 'FOLDER_DELETE',
|
||||
folderId: folderId,
|
||||
});
|
||||
}
|
||||
|
||||
@ -98,25 +90,12 @@ class Folder extends BaseItem {
|
||||
}
|
||||
|
||||
static async defaultFolder() {
|
||||
return this.modelSelectOne('SELECT * FROM folders WHERE is_default = 1');
|
||||
return this.modelSelectOne('SELECT * FROM folders ORDER BY created_time DESC LIMIT 1');
|
||||
}
|
||||
|
||||
static save(o, options = null) {
|
||||
return Folder.loadByField('title', o.title).then((existingFolder) => {
|
||||
if (existingFolder && existingFolder.id != o.id) throw new Error(_('A folder with title "%s" already exists', o.title));
|
||||
|
||||
if ('is_default' in o) {
|
||||
if (!o.is_default) {
|
||||
o = Object.assign({}, o);
|
||||
delete o.is_default;
|
||||
Log.warn('is_default property cannot be set to 0 directly. Instead, set the folder that should become the default to 1.');
|
||||
} else {
|
||||
options = this.modOptions(options);
|
||||
options.transactionNextQueries.push(
|
||||
{ sql: 'UPDATE folders SET is_default = 0 WHERE id != ?', params: [o.id] },
|
||||
);
|
||||
}
|
||||
}
|
||||
if (existingFolder && existingFolder.id != o.id) throw new Error(_('A notebook with title "%s" already exists', o.title));
|
||||
|
||||
return super.save(o, options).then((folder) => {
|
||||
this.dispatch({
|
||||
|
Loading…
x
Reference in New Issue
Block a user