Add new actions for todo's and sorting to contextmenu
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Peter Stuifzand 2020-11-11 22:16:07 +01:00
parent 37a8482a87
commit 75209250c3
5 changed files with 227 additions and 10 deletions

93
editor/src/actions.js Normal file
View File

@ -0,0 +1,93 @@
function hasCheckbox(id) {
let found = false
let todo = false
this.update(id, function (item, prev, next) {
let res = item.text.match(/^#\[\[(TODO|DONE)\]\]/)
if (res) {
found = true
todo = res[1] === 'TODO'
}
return item
});
return [found, todo]
}
function addCheckbox(id) {
this.update(id, function (item, prev, next) {
if (item.text.match(/^#\[\[TODO\]\]/)) {
return item
} else if (item.text.match(/^#\[\[|DONE\]\]/)) {
item.text = item.text.replace(/^#\[\[DONE\]\]/, '#[[TODO]]')
} else {
item.text = '#[[TODO]] ' + item.text
}
return item
});
}
function removeCheckbox(id) {
this.update(id, function (item, prev, next) {
if (item.text.match(/^#\[\[(TODO|DONE)\]\]/)) {
item.text = item.text.replace(/#\[\[(TODO|DONE)\]\]\s*/, '')
}
return item
});
}
function markDone(id) {
this.update(id, function (item, prev, next) {
if (item.text.match(/^#\[\[(TODO)\]\]/)) {
item.text = item.text.replace(/#\[\[(TODO)\]\]\s*/, '#[[DONE]]')
}
return item
});
}
function markTodo(id) {
this.update(id, function (item, prev, next) {
if (item.text.match(/^#\[\[(DONE)\]\]/)) {
item.text = item.text.replace(/#\[\[(DONE)\]\]\s*/, '#[[TODO]]')
}
return item
});
}
function sort(id, property, direction) {
let children = this.getChildren(id)
if (property === 'todo') {
children = _.orderBy(children, item => {
let res = item.text.match(/^#\[\[(TODO|DONE)/)
if (!res) return "C";
if (res[1] === 'TODO') return direction === 'asc' ? "A" : "B";
if (res[1] === 'DONE') return direction === 'asc' ? "B" : "A";
return "D";
}, direction)
} else {
children = _.orderBy(children, property, direction)
}
this.replaceChildren(id, children)
}
function removeCompleted(id) {
let children = this.getChildren(id)
let newChildren = _.filter(children, item => {
let res = item.text.match(/^#\[\[(TODO|DONE)\]\]/)
let found = false, todo = false
if (res) {
found = true
todo = res[1] === 'TODO'
}
return !found || todo
})
this.replaceChildren(id, newChildren)
}
export default {
hasCheckbox,
addCheckbox,
removeCheckbox,
markTodo,
markDone,
sort,
removeCompleted
}

View File

@ -23,6 +23,7 @@ import MD from './markdown'
import he from 'he'
import {all, create} from 'mathjs'
import formulaFunctions from './formula'
import actions from './actions'
moment.locale('nl')
@ -375,6 +376,7 @@ function Editor(holder, input) {
let editor = listEditor(holder, inputData, options);
holder.$listEditor = editor
editor.scope = {}
editor.actions = actions
$(holder).on('click', '.content input[type="checkbox"]', function (event) {
let that = this

View File

@ -49,35 +49,135 @@ function connectContextMenu(editor) {
name: 'Zoom in',
callback: function (key, opt) {
editor.zoomin(this).then(id => {
location.href = '/edit/'+id;
location.href = '/edit/' + id;
})
}
},
debug: {
name: 'Debug block',
callback: function (key, opt) {
editor.copy(this, {recursive:true}).then(console.log)
editor.copy(this, {recursive: true}).then(console.log)
}
},
addCheckbox: {
name: 'Add checkbox',
visible: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
let [found] = editor.actions.hasCheckbox.call(editor, id)
return !found
},
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.addCheckbox.call(editor, id)
}
},
removeCheckbox: {
name: 'Remove checkbox',
visible: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
let [found] = editor.actions.hasCheckbox.call(editor, id)
return found
},
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.removeCheckbox.call(editor, id)
}
},
markTodo: {
name: 'Mark To Do',
visible: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
let [found, todo] = editor.actions.hasCheckbox.call(editor, id)
return found && !todo
},
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.markTodo.call(editor, id)
}
},
markDone: {
name: 'Mark Done',
visible: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
let [found, todo] = editor.actions.hasCheckbox.call(editor, id)
return found && todo
},
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.markDone.call(editor, id)
}
},
sort: {
name: 'Sort',
items: [
{
name: 'Title (A-Z)',
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.sort.call(editor, id, 'text', 'asc')
editor.render()
}
},
{
name: 'Title (Z-A)',
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.sort.call(editor, id, 'text', 'desc')
editor.render()
}
},
{
name: 'Checked first',
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.sort.call(editor, id, 'todo', 'desc')
editor.render()
}
},
{
name: 'Unchecked first',
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.sort.call(editor, id, 'todo', 'asc')
editor.render()
}
}
]
},
removeCompleted: {
name: 'Remove completed',
callback: function (key, opt) {
let item = $(this).parents('.list-item')
let id = item.attr('data-id')
editor.actions.removeCompleted.call(editor, id)
editor.render()
}
}
// TODO
// - Sort
// - Title (A-Z)
// - Title (Z-A)
// - Date (on item) (new-old)
// - Date (on item) (old-new)
// - Unchecked first
// - Checked first
// - Updated (new to old)
// - Updated (old to new)
// - Created (new to old)
// - Created (old to new)
// - Reverse
// - Zoom in (should work in the same document)
// - Move To
// - Indent
// - Add checkboxes
// - Remove checkboxes
}
});
}

View File

@ -136,11 +136,13 @@ function editor(root, inputData, options) {
startEditing(root, store, cursor)
}
function getChildren(id ) {
return store.children(id )
}
function replaceChildren(id, children) {
store.replaceChildren(id, children)
}
function renderUpdate() {
disableDragging(drake)
render(root, store);
@ -148,6 +150,9 @@ function editor(root, inputData, options) {
}
let EDITOR = {
normalKeymap,
editorKeymap,
on,
save,
saveTree,
@ -156,6 +161,7 @@ function editor(root, inputData, options) {
start,
zoomin,
treeForId,
getChildren,
replaceChildren,
render: renderUpdate,

View File

@ -417,6 +417,21 @@ function Store(inputData) {
return changed;
}
function children(id) {
let first = index(id)
let firstVal = value(id)
if (firstVal.fleeting) {
return []
}
let last = lastHigherIndented(first)
first++
return _.map(idList.slice(first, last), function (id) {
return _.tap(_.clone(value(id)), c => {
c.indented -= firstVal.indented + 1
})
})
}
function replaceChildren(id, newChildren) {
let first = index(id)
let firstVal = value(id)
@ -470,6 +485,7 @@ function Store(inputData) {
debug,
tree,
flat,
children,
replaceChildren,
hasChanged,
clearChanged,