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') moment.locale('nl')
const math = create(all) const math = create(all)
math.import(formulaFunctions) math.import(formulaFunctions)
function isMultiline(input) { function isMultiline(input) {
@ -109,8 +108,8 @@ function showSearchResultsExtended(element, template, searchTool, query, input,
$lc.offset(pos) $lc.offset(pos)
} }
var templateText = he.decode(document.getElementById(template).innerHTML); let templateText = he.decode(document.getElementById(template).innerHTML);
var rendered = Mustache.render(templateText, { let rendered = Mustache.render(templateText, {
page: value.trim().replace(/\s+/g, '_'), page: value.trim().replace(/\s+/g, '_'),
results: results results: results
}, {}, ['[[', ']]']); }, {}, ['[[', ']]']);
@ -467,7 +466,7 @@ function Editor(holder, input) {
if (insideSearch) { if (insideSearch) {
let query = value.substring(start + 1, end); let query = value.substring(start + 1, end);
showSearchResults(commandSearch, query, input, value, 'command').then(results => { showSearchResults(commandSearch, query, input, value, 'command').then(results => {
if (query.length > 0 && result.length === 0) { if (query.length > 0 && results.length === 0) {
searchEnabled = false 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() $('#link-complete').off()
PrismJS.highlightAll() PrismJS.highlightAll()
mermaid.init() mermaid.init()
renderGraphs(); 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 return editor
}) })
} }
let searchInput = document.getElementById('search-input'); let searchInput = document.getElementById('search-input');
search(searchInput).then(searcher => {
_.tap(search.search(searchInput), searcher => {
let showSearch = _.debounce(function (searcher) { let showSearch = _.debounce(function (searcher) {
let query = $(searchInput).val() let query = $(searchInput).val()
if (query === '') { if (query === '') {
let autocomplete = document.getElementById('autocomplete'); $('#autocomplete').hide()
$(autocomplete).hide()
return false return false
} }
showSearchResultsExtended('#autocomplete', 'result-template', query => searcher.search(query), query, searchInput, query, 'search-result') showSearchResultsExtended('#autocomplete', 'result-template', query => searcher.search(query), query, searchInput, query, 'search-result')
return true; return true;
}, 200) }, 200)
@ -513,5 +543,4 @@ search(searchInput).then(searcher => {
}) })
}) })
export default Editor; export default Editor;

View File

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

View File

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

View File

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

View File

@ -399,8 +399,35 @@ function Store(inputData) {
return changed; 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) => { _.each(inputData, (d) => {
if (d.text.startsWith("{{query:")) {
removeLevel = d.indented;
append(d) append(d)
} else if (d.indented <= removeLevel) {
removeLevel = 9999999999;
append(d)
}
}) })
return { return {
@ -424,6 +451,7 @@ function Store(inputData) {
debug, debug,
tree, tree,
flat, flat,
replaceChildren,
hasChanged, hasChanged,
clearChanged, clearChanged,
}; };