Add search queries inside the tree
This commit is contained in:
parent
5e1422f684
commit
5006e1095a
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
8
file.go
8
file.go
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user