|
@@ -1,5 +1,5 @@
|
|
import define from '../../utils/define.js';
|
|
import define from '../../utils/define.js';
|
|
-import { globalBus } from '../../utils/events.js';
|
|
|
|
|
|
+import {globalBus} from '../../utils/events.js';
|
|
|
|
|
|
// Components
|
|
// Components
|
|
import result from '../molecules/result.js';
|
|
import result from '../molecules/result.js';
|
|
@@ -17,6 +17,8 @@ export default define('results', class extends HTMLElement {
|
|
constructor() {
|
|
constructor() {
|
|
super();
|
|
super();
|
|
this.results = null;
|
|
this.results = null;
|
|
|
|
+ this.oldIndex = null;
|
|
|
|
+ this.curating = false;
|
|
this.__setup();
|
|
this.__setup();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -31,7 +33,7 @@ export default define('results', class extends HTMLElement {
|
|
this.results.innerHTML = '';
|
|
this.results.innerHTML = '';
|
|
let resultsHTML = '';
|
|
let resultsHTML = '';
|
|
if (!e.detail.error) {
|
|
if (!e.detail.error) {
|
|
- // If there is no details the input is empty
|
|
|
|
|
|
+ // If there is no details the input is empty
|
|
if (!e.detail.results) {
|
|
if (!e.detail.results) {
|
|
resultsHTML = /*html*/`
|
|
resultsHTML = /*html*/`
|
|
<li is='${home}'></li>
|
|
<li is='${home}'></li>
|
|
@@ -42,7 +44,7 @@ export default define('results', class extends HTMLElement {
|
|
for(const resultData of e.detail.results) {
|
|
for(const resultData of e.detail.results) {
|
|
resultsHTML += /*html*/`
|
|
resultsHTML += /*html*/`
|
|
<li
|
|
<li
|
|
- is='${result}'
|
|
|
|
|
|
+ is='${result}'
|
|
data-url='${escapeString(resultData.url)}'
|
|
data-url='${escapeString(resultData.url)}'
|
|
data-title='${escapeString(JSON.stringify(resultData.title))}'
|
|
data-title='${escapeString(JSON.stringify(resultData.title))}'
|
|
data-extract='${escapeString(JSON.stringify(resultData.extract))}'
|
|
data-extract='${escapeString(JSON.stringify(resultData.extract))}'
|
|
@@ -65,11 +67,167 @@ export default define('results', class extends HTMLElement {
|
|
}
|
|
}
|
|
// Bind HTML to the DOM
|
|
// Bind HTML to the DOM
|
|
this.results.innerHTML = resultsHTML;
|
|
this.results.innerHTML = resultsHTML;
|
|
|
|
+
|
|
|
|
+ // Allow the user to re-order search results
|
|
|
|
+ $(".results").sortable({
|
|
|
|
+ "activate": this.__sortableActivate.bind(this),
|
|
|
|
+ "deactivate": this.__sortableDeactivate.bind(this),
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.curating = false;
|
|
});
|
|
});
|
|
|
|
|
|
// Focus first element when coming from the search bar
|
|
// Focus first element when coming from the search bar
|
|
globalBus.on('focus-result', () => {
|
|
globalBus.on('focus-result', () => {
|
|
this.results.firstElementChild.firstElementChild.focus();
|
|
this.results.firstElementChild.firstElementChild.focus();
|
|
- })
|
|
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ globalBus.on('curate-delete-result', (e) => {
|
|
|
|
+ console.log("Curate delete result event", e);
|
|
|
|
+ this.__beginCurating.bind(this)();
|
|
|
|
+
|
|
|
|
+ const children = this.results.getElementsByClassName('result');
|
|
|
|
+ let deleteIndex = e.detail.data.delete_index;
|
|
|
|
+ const child = children[deleteIndex];
|
|
|
|
+ this.results.removeChild(child);
|
|
|
|
+ const newResults = this.__getResults();
|
|
|
|
+
|
|
|
|
+ const curationSaveEvent = new CustomEvent('save-curation', {
|
|
|
|
+ detail: {
|
|
|
|
+ type: 'delete',
|
|
|
|
+ data: {
|
|
|
|
+ url: document.location.href,
|
|
|
|
+ results: newResults,
|
|
|
|
+ curation: {
|
|
|
|
+ delete_index: deleteIndex
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ globalBus.dispatch(curationSaveEvent);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ globalBus.on('curate-validate-result', (e) => {
|
|
|
|
+ console.log("Curate validate result event", e);
|
|
|
|
+ this.__beginCurating.bind(this)();
|
|
|
|
+
|
|
|
|
+ const children = this.results.getElementsByClassName('result');
|
|
|
|
+ const validateChild = children[e.detail.data.validate_index];
|
|
|
|
+ validateChild.querySelector('.curate-approve').toggleValidate();
|
|
|
|
+
|
|
|
|
+ const newResults = this.__getResults();
|
|
|
|
+
|
|
|
|
+ const curationStartEvent = new CustomEvent('save-curation', {
|
|
|
|
+ detail: {
|
|
|
|
+ type: 'validate',
|
|
|
|
+ data: {
|
|
|
|
+ url: document.location.href,
|
|
|
|
+ results: newResults,
|
|
|
|
+ curation: e.detail.data
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ globalBus.dispatch(curationStartEvent);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ globalBus.on('begin-curating-results', (e) => {
|
|
|
|
+ // We might not be online, or logged in, so save the curation in local storage in case:
|
|
|
|
+ console.log("Begin curation event", e);
|
|
|
|
+ this.__beginCurating.bind(this)();
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ globalBus.on('curate-add-result', (e) => {
|
|
|
|
+ console.log("Add result", e);
|
|
|
|
+ this.__beginCurating();
|
|
|
|
+ const resultData = e.detail;
|
|
|
|
+ const resultHTML = /*html*/`
|
|
|
|
+ <li
|
|
|
|
+ is='${result}'
|
|
|
|
+ data-url='${escapeString(resultData.url)}'
|
|
|
|
+ data-title='${escapeString(JSON.stringify(resultData.title))}'
|
|
|
|
+ data-extract='${escapeString(JSON.stringify(resultData.extract))}'
|
|
|
|
+ ></li>
|
|
|
|
+ `;
|
|
|
|
+ this.results.insertAdjacentHTML('afterbegin', resultHTML);
|
|
|
|
+
|
|
|
|
+ const newResults = this.__getResults();
|
|
|
|
+
|
|
|
|
+ const curationSaveEvent = new CustomEvent('save-curation', {
|
|
|
|
+ detail: {
|
|
|
|
+ type: 'add',
|
|
|
|
+ data: {
|
|
|
|
+ url: document.location.href,
|
|
|
|
+ results: newResults,
|
|
|
|
+ curation: {
|
|
|
|
+ insert_index: 0,
|
|
|
|
+ url: e.detail.url
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ globalBus.dispatch(curationSaveEvent);
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ __sortableActivate(event, ui) {
|
|
|
|
+ console.log("Sortable activate", ui);
|
|
|
|
+ this.__beginCurating();
|
|
|
|
+ this.oldIndex = ui.item.index();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ __beginCurating() {
|
|
|
|
+ if (!this.curating) {
|
|
|
|
+ const results = this.__getResults();
|
|
|
|
+ const curationStartEvent = new CustomEvent('save-curation', {
|
|
|
|
+ detail: {
|
|
|
|
+ type: 'begin',
|
|
|
|
+ data: {
|
|
|
|
+ url: document.location.href,
|
|
|
|
+ results: results
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ globalBus.dispatch(curationStartEvent);
|
|
|
|
+ this.curating = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ __getResults() {
|
|
|
|
+ const resultsElements = document.querySelectorAll('.results .result:not(.ui-sortable-placeholder)');
|
|
|
|
+ const results = [];
|
|
|
|
+ for (let resultElement of resultsElements) {
|
|
|
|
+ const result = {
|
|
|
|
+ url: resultElement.querySelector('a').href,
|
|
|
|
+ title: resultElement.querySelector('.title').innerText,
|
|
|
|
+ extract: resultElement.querySelector('.extract').innerText,
|
|
|
|
+ curated: resultElement.querySelector('.curate-approve').isValidated()
|
|
|
|
+ }
|
|
|
|
+ results.push(result);
|
|
|
|
+ }
|
|
|
|
+ console.log("Results", results);
|
|
|
|
+ return results;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ __sortableDeactivate(event, ui) {
|
|
|
|
+ const newIndex = ui.item.index();
|
|
|
|
+ console.log('Sortable deactivate', ui, this.oldIndex, newIndex);
|
|
|
|
+
|
|
|
|
+ const newResults = this.__getResults();
|
|
|
|
+
|
|
|
|
+ const curationMoveEvent = new CustomEvent('save-curation', {
|
|
|
|
+ detail: {
|
|
|
|
+ type: 'move',
|
|
|
|
+ data: {
|
|
|
|
+ url: document.location.href,
|
|
|
|
+ results: newResults,
|
|
|
|
+ curation: {
|
|
|
|
+ old_index: this.oldIndex,
|
|
|
|
+ new_index: newIndex,
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ globalBus.dispatch(curationMoveEvent);
|
|
}
|
|
}
|
|
});
|
|
});
|