diff --git a/src/public/app/widgets/search_definition.js b/src/public/app/widgets/search_definition.js index 76d067716..b85405ee4 100644 --- a/src/public/app/widgets/search_definition.js +++ b/src/public/app/widgets/search_definition.js @@ -87,17 +87,23 @@ const TPL = ` + + + + + + + +
+ + + +
+ + + `; +const ACTION_TPLS = { + deleteNote: ` + + + + + Delete matched note + + + + +`, + deleteAttribute: ` + + + Delete attribute: + + +
+
Attribute name:
+ + +
+ + + + +` +}; + export default class SearchDefinitionWidget extends TabAwareWidget { static getType() { return "search"; } @@ -306,14 +334,40 @@ export default class SearchDefinitionWidget extends TabAwareWidget { await this.setAttribute('label', 'orderDirection', orderDirection); }); + + this.$actionOptions = this.$widget.find('.action-options'); + + this.$widget.on('click', '[data-action-add]', async event => { + const actionName = $(event.target).attr('data-action-add'); + + await server.post(`notes/${this.noteId}/attributes`, { + type: 'label', + name: 'action', + value: JSON.stringify({ + name: actionName + }) + }); + + this.$widget.find('.action-add-toggle').dropdown('toggle'); + + await ws.waitForMaxKnownEntityChangeId(); + + this.refresh(); + }); + + this.$widget.on('click', '[data-action-conf-del]', async event => { + const attributeId = $(event.target).closest('[data-attribute-id]').attr('data-attribute-id'); + + await server.remove(`notes/${this.noteId}/attributes/${attributeId}`); + + await ws.waitForMaxKnownEntityChangeId(); + + this.refresh(); + }); } async setAttribute(type, name, value = '') { - await server.put(`notes/${this.noteId}/set-attribute`, { - type, - name, - value - }); + await server.put(`notes/${this.noteId}/set-attribute`, { type, name, value }); await ws.waitForMaxKnownEntityChangeId(); } @@ -340,12 +394,30 @@ export default class SearchDefinitionWidget extends TabAwareWidget { .val(descendantOfNote ? descendantOfNote.title : "") .setSelectedNotePath(descendantOfNoteId); - if (note.hasLabel('orderBy')) { this.$orderBy.val(note.getLabelValue('orderBy')); this.$orderDirection.val(note.getLabelValue('orderDirection') || 'asc'); } + this.$actionOptions.empty(); + + for (const actionAttr of this.note.getLabels('action')) { + let actionDef; + + try { + actionDef = JSON.parse(actionAttr.value); + } + catch (e) { + console.log(`Parsing of attribute: '${actionAttr.value}' failed with error: ${e.message}`); + continue; + } + + const $actionConf = $(ACTION_TPLS[actionDef.name]); + $actionConf.attr('data-attribute-id', actionAttr.attributeId); + + this.$actionOptions.append($actionConf); + } + this.refreshResults(); // important specifically when this search note was not yet refreshed } diff --git a/src/routes/api/attributes.js b/src/routes/api/attributes.js index ffbd6696b..31f7025aa 100644 --- a/src/routes/api/attributes.js +++ b/src/routes/api/attributes.js @@ -86,6 +86,16 @@ function setNoteAttribute(req) { attr.save(); } +function addNoteAttribute(req) { + const noteId = req.params.noteId; + const body = req.body; + + const attr = new Attribute(body); + attr.noteId = noteId; + + attr.save(); +} + function deleteNoteAttribute(req) { const noteId = req.params.noteId; const attributeId = req.params.attributeId; @@ -220,6 +230,7 @@ module.exports = { updateNoteAttributes, updateNoteAttribute, setNoteAttribute, + addNoteAttribute, deleteNoteAttribute, getAttributeNames, getValuesForAttribute, diff --git a/src/routes/routes.js b/src/routes/routes.js index 1b88ddf3b..850428f5c 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -176,6 +176,7 @@ function register(app) { apiRoute(POST, '/api/notes/:noteId/saveToTmpDir', filesRoute.saveToTmpDir); apiRoute(GET, '/api/notes/:noteId/attributes', attributesRoute.getEffectiveNoteAttributes); + apiRoute(POST, '/api/notes/:noteId/attributes', attributesRoute.addNoteAttribute); apiRoute(PUT, '/api/notes/:noteId/attributes', attributesRoute.updateNoteAttributes); apiRoute(PUT, '/api/notes/:noteId/attribute', attributesRoute.updateNoteAttribute); apiRoute(PUT, '/api/notes/:noteId/set-attribute', attributesRoute.setNoteAttribute);