Add search queries inside the tree

This commit is contained in:
Peter Stuifzand 2020-10-28 20:01:25 +01:00
parent 5e1422f684
commit 5006e1095a
5 changed files with 132 additions and 42 deletions

View File

@ -27,7 +27,6 @@ import formulaFunctions from './formula'
moment.locale('nl')
const math = create(all)
math.import(formulaFunctions)
function isMultiline(input) {
@ -109,8 +108,8 @@ function showSearchResultsExtended(element, template, searchTool, query, input,
$lc.offset(pos)
}
var templateText = he.decode(document.getElementById(template).innerHTML);
var rendered = Mustache.render(templateText, {
let templateText = he.decode(document.getElementById(template).innerHTML);
let rendered = Mustache.render(templateText, {
page: value.trim().replace(/\s+/g, '_'),
results: results
}, {}, ['[[', ']]']);
@ -467,7 +466,7 @@ function Editor(holder, input) {
if (insideSearch) {
let query = value.substring(start + 1, end);
showSearchResults(commandSearch, query, input, value, 'command').then(results => {
if (query.length > 0 && result.length === 0) {
if (query.length > 0 && results.length === 0) {
searchEnabled = false
}
})
@ -481,27 +480,58 @@ function Editor(holder, input) {
}
})
})
editor.on('stop-editing', function (input) {
$(input).parents('.list-item').removeClass('active');
editor.on('stop-editing', function (input, id) {
let $input = $(input);
$input.parents('.list-item').removeClass('active');
$('#link-complete').off()
PrismJS.highlightAll()
mermaid.init()
renderGraphs();
})
if ($input.val()) {
let query = $input.val();
let res = query.match(/{{query: ([^}]+)}}/)
if (res) {
search.startQuery(res[1])
.then(hits => {
let results = _.flatMap(hits, hit => {
return [
{
text: "[[" + hit.title + "]]",
indented: 0,
fold: 'open',
hidden: false,
fleeting: true
},
{
text: hit.line,
indented: 1,
fold: 'open',
hidden: false,
fleeting: true
}
]
})
editor.replaceChildren(id, results)
}).then(function () {
editor.render()
})
}
}
});
return editor
})
}
let searchInput = document.getElementById('search-input');
search(searchInput).then(searcher => {
_.tap(search.search(searchInput), searcher => {
let showSearch = _.debounce(function (searcher) {
let query = $(searchInput).val()
if (query === '') {
let autocomplete = document.getElementById('autocomplete');
$(autocomplete).hide()
$('#autocomplete').hide()
return false
}
showSearchResultsExtended('#autocomplete', 'result-template', query => searcher.search(query), query, searchInput, query, 'search-result')
return true;
}, 200)
@ -513,5 +543,4 @@ search(searchInput).then(searcher => {
})
})
export default Editor;

View File

@ -2,29 +2,37 @@ import $ from 'jquery'
import qs from 'querystring';
function search(element) {
return new Promise(function (resolve, reject) {
resolve({
element: element,
search(query) {
element.classList.add('is-loading')
return fetch('/search/?' + qs.encode({q:query}))
.then(res => res.json())
.then(data => {
let actualResult = [];
$.each(data.hits, (key, value) => {
actualResult.push({
ref: value.fields.page,
title: value.fields.title,
text: value.fragments.text[0]
})
})
element.classList.remove('is-loading')
console.log(actualResult)
return actualResult
})
}
})
})
return {
element: element,
search(query) {
element.classList.add('is-loading')
return startQuery(query)
.then(res => {
element.classList.remove('is-loading')
return res
})
}
}
}
export default search;
function startQuery(query) {
return fetch('/search/?' + qs.encode({q: query}))
.then(res => res.json())
.then(data => {
let actualResult = [];
$.each(data.hits, (key, value) => {
actualResult.push({
ref: value.fields.page,
title: value.fields.title,
line: value.fields.text,
text: value.fragments.text[0]
})
})
return actualResult
})
}
export default {
search,
startQuery
};

View File

@ -85,6 +85,7 @@ func (v2 ListItemV2) ListItem() ListItem {
v2.ID.StrID,
v2.Indented,
v2.Text,
false,
}
}
@ -93,6 +94,7 @@ type ListItem struct {
ID string
Indented int
Text string
Fleeting bool `json:"fleeting,omitempty"`
}
type ActualListItem struct {
@ -101,6 +103,7 @@ type ActualListItem struct {
Text string `json:"text"`
Fold string `json:"fold"`
Hidden bool `json:"hidden"`
Fleeting bool `json:"fleeting,omitempty"`
}
type FilePages struct {
@ -313,6 +316,7 @@ func saveBlocksFromPage(dirname string, page Page) error {
var listItems []ListItem
err := json.NewDecoder(strings.NewReader(page.Content)).Decode(&listItems)
if err != nil {
log.Println("decoding default failed: %w", err)
var listItemsV2 []ListItemV2
err = json.NewDecoder(strings.NewReader(page.Content)).Decode(&listItemsV2)
listItems, err = saveWithNewIDs(dirname, listItemsV2, page.Name)
@ -353,6 +357,10 @@ func saveBlocksFromPage(dirname string, page Page) error {
var prev = &parent
for i, item := range listItems {
if item.Fleeting {
continue
}
prevList[item.ID] = item
if item.Indented > prev.Indented {
parent = *prev

View File

@ -13,6 +13,7 @@ function editor(root, inputData, options) {
let cursor = createCursor()
let selection = createSelection()
let store = createStore(inputData);
let drake = null;
function createStore(inputData) {
let data = [
@ -93,6 +94,19 @@ function editor(root, inputData, options) {
startEditing(root, store, cursor)
}
function replaceChildren(id, children)
{
store.replaceChildren(id, children)
}
function renderUpdate()
{
disableDragging(drake)
render(root, store);
drake = enableDragging(root)
}
let EDITOR = {
on,
save,
@ -101,7 +115,9 @@ function editor(root, inputData, options) {
update,
start,
zoomin,
treeForId
treeForId,
replaceChildren,
render: renderUpdate
};
root.classList.add('root')
@ -115,7 +131,6 @@ function editor(root, inputData, options) {
options = _.merge(defaults, options)
let drake = null;
let events = {
change: [],
@ -293,7 +308,8 @@ function editor(root, inputData, options) {
}
let text = element.val()
$(element).closest('.list-item').removeClass('editor');
element.closest('.list-item').removeClass('editor');
let id = element.data('id')
store.update(element.data('id'), (value) => {
return _.merge(value, {
text: text
@ -306,9 +322,9 @@ function editor(root, inputData, options) {
}
let $span = $('<div class="content">');
options.transform(text, $span, element.attr('data-id'), EDITOR)
options.transform(text, $span, id, EDITOR)
element.replaceWith($span);
trigger('stop-editing', currentEditor[0])
trigger('stop-editing', currentEditor[0], id)
editing = false
currentEditor = null
@ -460,6 +476,7 @@ function editor(root, inputData, options) {
stopEditing(root, store, currentEditor);
}
}
if (event.key === 'Enter') {
startEditing(root, store, cursor);
return false

View File

@ -399,8 +399,35 @@ function Store(inputData) {
return changed;
}
function replaceChildren(id, newChildren) {
let first = index(id)
let firstVal = value(id)
if (firstVal.fleeting) {
return
}
let last = lastHigherIndented(first)
first++
let ids = []
_.each(newChildren, item => {
item.indented += 1 + firstVal.indented
if (!item.id) {
item.id = ID()
}
ids.push(item.id)
values[item.id] = item
})
idList.splice(first, last - first, ...ids)
}
let removeLevel = 9999999999;
_.each(inputData, (d) => {
append(d)
if (d.text.startsWith("{{query:")) {
removeLevel = d.indented;
append(d)
} else if (d.indented <= removeLevel) {
removeLevel = 9999999999;
append(d)
}
})
return {
@ -424,6 +451,7 @@ function Store(inputData) {
debug,
tree,
flat,
replaceChildren,
hasChanged,
clearChanged,
};