From ec351137d4638dc8ec3850400869eff6b91309fe Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 25 Jan 2021 21:24:02 +0100 Subject: [PATCH] search definition refactoring --- package-lock.json | 56 ++++++++--------- package.json | 4 +- src/public/app/services/date_notes.js | 2 +- ...ct_action.js => abstract_search_action.js} | 5 +- .../widgets/search_actions/delete_label.js | 4 +- .../app/widgets/search_actions/delete_note.js | 4 +- .../widgets/search_actions/delete_relation.js | 4 +- .../widgets/search_actions/execute_script.js | 4 +- .../widgets/search_actions/rename_label.js | 4 +- .../widgets/search_actions/rename_relation.js | 4 +- .../widgets/search_actions/set_label_value.js | 4 +- .../search_actions/set_relation_target.js | 4 +- src/public/app/widgets/search_definition.js | 62 +++++++++---------- .../search_options/abstract_search_option.js | 9 ++- .../widgets/search_options/search_string.js | 16 +++-- 15 files changed, 98 insertions(+), 88 deletions(-) rename src/public/app/widgets/search_actions/{abstract_action.js => abstract_search_action.js} (89%) diff --git a/package-lock.json b/package-lock.json index fcf93bb00..93ecea17e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -636,9 +636,9 @@ } }, "@types/estree": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", - "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "version": "0.0.46", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz", + "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==", "dev": true }, "@types/fs-extra": { @@ -668,9 +668,9 @@ "dev": true }, "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "@types/keyv": { @@ -1769,9 +1769,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001178", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001178.tgz", - "integrity": "sha512-VtdZLC0vsXykKni8Uztx45xynytOi71Ufx9T8kHptSw9AL4dpqailUJJHavttuzUe1KYuBYtChiWv+BAb7mPmQ==", + "version": "1.0.30001179", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz", + "integrity": "sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==", "dev": true }, "caseless": { @@ -3208,9 +3208,9 @@ } }, "electron-to-chromium": { - "version": "1.3.641", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.641.tgz", - "integrity": "sha512-b0DLhsHSHESC1I+Nx6n4w4Lr61chMd3m/av1rZQhS2IXTzaS5BMM5N+ldWdMIlni9CITMRM09m8He4+YV/92TA==", + "version": "1.3.645", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.645.tgz", + "integrity": "sha512-T7mYop3aDpRHIQaUYcmzmh6j9MAe560n6ukqjJMbVC6bVTau7dSpvB18bcsBPPtOSe10cKxhJFtlbEzLa0LL1g==", "dev": true }, "electron-window-state": { @@ -6002,9 +6002,9 @@ } }, "postcss": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.1.tgz", - "integrity": "sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA==", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", + "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", "requires": { "colorette": "^1.2.1", "nanoid": "^3.1.20", @@ -6525,9 +6525,9 @@ } }, "sanitize-html": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.0.tgz", - "integrity": "sha512-JAsbaKskfxR+ZhEnqO/T3c2dKalVDA6sXIgy/27TatIUzOPO/zWr1r8Ykzp1cwJx1j+DPMQF5ifvhniixRWYDA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.1.tgz", + "integrity": "sha512-JYziKrrtCEGhrsUAZK1mL0RdEcRxBGZ+ptgppv7ulAsan7MZVL+oVKRSPCIcYinfM1rVOMYh5dHLydMuHaQOUA==", "requires": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", @@ -6572,9 +6572,9 @@ } }, "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "escape-string-regexp": { "version": "4.0.0", @@ -7680,13 +7680,13 @@ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.16.0.tgz", - "integrity": "sha512-QOkctcjYfEGxcYg4AzPJafyAQ7ANc266/URkX881uFA7b2k31E0Dmpy1ExfppHOTp1kHDTsRh9sXojVUvgPF0g==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.17.0.tgz", + "integrity": "sha512-R+IdNEaYcYaACpXZOt7reyc8txBK7J06lOPkX1SbgmeoAnUbyBZivJIksrDBnmMA3wlTWvPcX7DubxELyPB8rA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.45", + "@types/estree": "^0.0.46", "@webassemblyjs/ast": "1.11.0", "@webassemblyjs/wasm-edit": "1.11.0", "@webassemblyjs/wasm-parser": "1.11.0", @@ -7712,9 +7712,9 @@ }, "dependencies": { "acorn": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", - "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz", + "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==", "dev": true }, "graceful-fs": { diff --git a/package.json b/package.json index aed058f80..0a8fe5050 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "request": "^2.88.2", "rimraf": "3.0.2", "sanitize-filename": "1.6.3", - "sanitize-html": "2.3.0", + "sanitize-html": "2.3.1", "sax": "1.2.4", "semver": "7.3.4", "serve-favicon": "2.5.0", @@ -86,7 +86,7 @@ "jsdoc": "3.6.6", "lorem-ipsum": "2.0.3", "rcedit": "3.0.0", - "webpack": "5.16.0", + "webpack": "5.17.0", "webpack-cli": "4.4.0" }, "optionalDependencies": { diff --git a/src/public/app/services/date_notes.js b/src/public/app/services/date_notes.js index 7b46497c7..d46d81dd4 100644 --- a/src/public/app/services/date_notes.js +++ b/src/public/app/services/date_notes.js @@ -48,7 +48,7 @@ async function createSearchNote(opts = {}) { const attrsToUpdate = [ opts.ancestor ? { type: 'relation', name: 'ancestor', value: opts.ancestorNoteId } : undefined, - opts.searchString ? { type: 'label', name: 'searchString', value: opts.searchString } : undefined + { type: 'label', name: 'searchString', value: opts.searchString } ].filter(attr => !!attr); if (attrsToUpdate.length > 0) { diff --git a/src/public/app/widgets/search_actions/abstract_action.js b/src/public/app/widgets/search_actions/abstract_search_action.js similarity index 89% rename from src/public/app/widgets/search_actions/abstract_action.js rename to src/public/app/widgets/search_actions/abstract_search_action.js index e0e0575d8..0fb7f8ef1 100644 --- a/src/public/app/widgets/search_actions/abstract_action.js +++ b/src/public/app/widgets/search_actions/abstract_search_action.js @@ -1,8 +1,11 @@ import server from "../../services/server.js"; import ws from "../../services/ws.js"; +import Component from "../component.js"; -export default class AbstractAction { +export default class AbstractSearchAction extends Component { constructor(attribute, actionDef) { + super(); + this.attribute = attribute; this.actionDef = actionDef; } diff --git a/src/public/app/widgets/search_actions/delete_label.js b/src/public/app/widgets/search_actions/delete_label.js index 1a06fa859..8914c80d0 100644 --- a/src/public/app/widgets/search_actions/delete_label.js +++ b/src/public/app/widgets/search_actions/delete_label.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -21,7 +21,7 @@ const TPL = ` `; -export default class DeleteLabelSearchAction extends AbstractAction { +export default class DeleteLabelSearchAction extends AbstractSearchAction { static get actionName() { return "deleteLabel"; } doRender() { diff --git a/src/public/app/widgets/search_actions/delete_note.js b/src/public/app/widgets/search_actions/delete_note.js index 44e16065d..bc579ec29 100644 --- a/src/public/app/widgets/search_actions/delete_note.js +++ b/src/public/app/widgets/search_actions/delete_note.js @@ -1,4 +1,4 @@ -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -12,7 +12,7 @@ const TPL = ` `; -export default class DeleteNoteSearchAction extends AbstractAction { +export default class DeleteNoteSearchAction extends AbstractSearchAction { static get actionName() { return "deleteNote"; } doRender() { diff --git a/src/public/app/widgets/search_actions/delete_relation.js b/src/public/app/widgets/search_actions/delete_relation.js index 22876f43d..6376dca22 100644 --- a/src/public/app/widgets/search_actions/delete_relation.js +++ b/src/public/app/widgets/search_actions/delete_relation.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -21,7 +21,7 @@ const TPL = ` `; -export default class DeleteRelationSearchAction extends AbstractAction { +export default class DeleteRelationSearchAction extends AbstractSearchAction { static get actionName() { return "deleteRelation"; } doRender() { diff --git a/src/public/app/widgets/search_actions/execute_script.js b/src/public/app/widgets/search_actions/execute_script.js index a0e76dadf..7e9391ce2 100644 --- a/src/public/app/widgets/search_actions/execute_script.js +++ b/src/public/app/widgets/search_actions/execute_script.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -20,7 +20,7 @@ const TPL = ` `; -export default class ExecuteScriptSearchAction extends AbstractAction { +export default class ExecuteScriptSearchAction extends AbstractSearchAction { static get actionName() { return "executeScript"; } doRender() { diff --git a/src/public/app/widgets/search_actions/rename_label.js b/src/public/app/widgets/search_actions/rename_label.js index 1c8fe10fd..6e46e2216 100644 --- a/src/public/app/widgets/search_actions/rename_label.js +++ b/src/public/app/widgets/search_actions/rename_label.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -32,7 +32,7 @@ const TPL = ` `; -export default class RenameLabelSearchAction extends AbstractAction { +export default class RenameLabelSearchAction extends AbstractSearchAction { static get actionName() { return "renameLabel"; } doRender() { diff --git a/src/public/app/widgets/search_actions/rename_relation.js b/src/public/app/widgets/search_actions/rename_relation.js index 8ec6ed41a..64a436e4a 100644 --- a/src/public/app/widgets/search_actions/rename_relation.js +++ b/src/public/app/widgets/search_actions/rename_relation.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -32,7 +32,7 @@ const TPL = ` `; -export default class RenameRelationSearchAction extends AbstractAction { +export default class RenameRelationSearchAction extends AbstractSearchAction { static get actionName() { return "renameRelation"; } doRender() { diff --git a/src/public/app/widgets/search_actions/set_label_value.js b/src/public/app/widgets/search_actions/set_label_value.js index 8f2fae2d1..25c761921 100644 --- a/src/public/app/widgets/search_actions/set_label_value.js +++ b/src/public/app/widgets/search_actions/set_label_value.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; const TPL = ` @@ -28,7 +28,7 @@ const TPL = ` `; -export default class SetLabelValueSearchAction extends AbstractAction { +export default class SetLabelValueSearchAction extends AbstractSearchAction { static get actionName() { return "setLabelValue"; } doRender() { diff --git a/src/public/app/widgets/search_actions/set_relation_target.js b/src/public/app/widgets/search_actions/set_relation_target.js index 11ca9f085..0d386b09e 100644 --- a/src/public/app/widgets/search_actions/set_relation_target.js +++ b/src/public/app/widgets/search_actions/set_relation_target.js @@ -1,5 +1,5 @@ import SpacedUpdate from "../../services/spaced_update.js"; -import AbstractAction from "./abstract_action.js"; +import AbstractSearchAction from "./abstract_search_action.js"; import noteAutocompleteService from "../../services/note_autocomplete.js"; const TPL = ` @@ -28,7 +28,7 @@ const TPL = ` `; -export default class SetRelationTargetSearchAction extends AbstractAction { +export default class SetRelationTargetSearchAction extends AbstractSearchAction { static get actionName() { return "setRelationTarget"; } doRender() { diff --git a/src/public/app/widgets/search_definition.js b/src/public/app/widgets/search_definition.js index f39c5c966..f470259a7 100644 --- a/src/public/app/widgets/search_definition.js +++ b/src/public/app/widgets/search_definition.js @@ -182,6 +182,24 @@ export default class SearchDefinitionWidget extends TabAwareWidget { this.refresh(); }); + 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-search-option-del]', async event => { async function deleteAttr(note, attrName) { for (const attr of note.getOwnedAttributes()) { @@ -204,28 +222,6 @@ export default class SearchDefinitionWidget extends TabAwareWidget { this.refresh(); }); - this.$searchOptions = this.$widget.find('.search-options'); - - 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'); @@ -236,14 +232,17 @@ export default class SearchDefinitionWidget extends TabAwareWidget { this.refresh(); }); + this.$searchOptions = this.$widget.find('.search-options'); + this.$actionOptions = this.$widget.find('.action-options'); + this.$searchButton = this.$widget.find('.search-button'); - this.$searchButton.on('click', () => this.refreshResults()); + this.$searchButton.on('click', () => this.triggerCommand('refreshResults')); this.$searchAndExecuteButton = this.$widget.find('.search-and-execute-button'); this.$searchAndExecuteButton.on('click', () => this.searchAndExecute()); } - async refreshResults() { + async refreshResultsCommand() { await treeCache.reloadNotes([this.noteId]); this.triggerEvent('searchRefreshed', {tabId: this.tabContext.tabId}); @@ -260,9 +259,10 @@ export default class SearchDefinitionWidget extends TabAwareWidget { const attr = this.note.getAttribute(attributeType, optionName); this.$widget.find(`[data-search-option-add='${optionName}'`).toggle(!attr); -console.log(optionName, attr); + if (attr) { - const searchOption = new OptionClass(attr, this.note); + const searchOption = new OptionClass(attr, this.note).setParent(this); + this.child(searchOption); this.$searchOptions.append(searchOption.render()); } @@ -290,7 +290,8 @@ console.log(optionName, attr); continue; } - const action = new ActionClass(actionAttr, actionDef); + const action = new ActionClass(actionAttr, actionDef).setParent(this); + this.child(action); this.$actionOptions.append(action.render()); } @@ -298,11 +299,6 @@ console.log(optionName, attr); this.$searchAndExecuteButton.css('visibility', actionLabels.length > 0 ? 'visible' : 'hidden'); } - focusOnSearchDefinitionEvent() { - // FIXME - this.$searchString.focus(); - } - getContent() { return ''; } @@ -310,7 +306,7 @@ console.log(optionName, attr); async searchAndExecute() { await server.post(`search-and-execute-note/${this.noteId}`); - this.refreshResults(); + this.triggerCommand('refreshResults'); toastService.showMessage('Actions have been executed.', 3000); } diff --git a/src/public/app/widgets/search_options/abstract_search_option.js b/src/public/app/widgets/search_options/abstract_search_option.js index 00cb042a5..35825a1b3 100644 --- a/src/public/app/widgets/search_options/abstract_search_option.js +++ b/src/public/app/widgets/search_options/abstract_search_option.js @@ -1,8 +1,11 @@ import server from "../../services/server.js"; import ws from "../../services/ws.js"; +import Component from "../component.js"; -export default class AbstractSearchOption { +export default class AbstractSearchOption extends Component { constructor(attribute, note) { + super(); + this.attribute = attribute; this.note = note; } @@ -13,6 +16,10 @@ export default class AbstractSearchOption { await ws.waitForMaxKnownEntityChangeId(); } + async setAttribute(type, name, value = '') { + await this.constructor.setAttribute(this.note.noteId, type, name, value); + } + render() { try { const $rendered = this.doRender(); diff --git a/src/public/app/widgets/search_options/search_string.js b/src/public/app/widgets/search_options/search_string.js index 4e7fcc624..b43075a36 100644 --- a/src/public/app/widgets/search_options/search_string.js +++ b/src/public/app/widgets/search_options/search_string.js @@ -41,17 +41,17 @@ export default class SearchString extends AbstractSearchOption { doRender() { const $option = $(TPL); - const $searchString = $option.find('.search-string'); - $searchString.on('input', () => this.spacedUpdate.scheduleUpdate()); + this.$searchString = $option.find('.search-string'); + this.$searchString.on('input', () => this.spacedUpdate.scheduleUpdate()); - utils.bindElShortcut($searchString, 'return', async () => { + utils.bindElShortcut(this.$searchString, 'return', async () => { await this.spacedUpdate.updateNowIfNecessary(); - this.refreshResults(); // FIXME!!! + this.triggerCommand('refreshResults'); }); this.spacedUpdate = new SpacedUpdate(async () => { - const searchString = $searchString.val(); + const searchString = this.$searchString.val(); await this.setAttribute('label', 'searchString', searchString); @@ -62,8 +62,12 @@ export default class SearchString extends AbstractSearchOption { } }, 1000); - $searchString.val(this.note.getLabelValue('searchString')); + this.$searchString.val(this.note.getLabelValue('searchString')); return $option; } + + focusOnSearchDefinitionEvent() { + this.$searchString.focus(); + } }