Allow search query results in tables
This commit is contained in:
parent
f3737f96bd
commit
8513e4b96c
|
@ -142,6 +142,37 @@ function showSearchResultsExtended(element, template, searchTool, query, input,
|
|||
})
|
||||
}
|
||||
|
||||
function formatLineResult(hit) {
|
||||
return [
|
||||
{
|
||||
text: "[[" + hit.title + "]]",
|
||||
indented: 0,
|
||||
fold: 'open',
|
||||
hidden: false,
|
||||
fleeting: true
|
||||
},
|
||||
{
|
||||
text: hit.line,
|
||||
indented: 1,
|
||||
fold: 'open',
|
||||
hidden: false,
|
||||
fleeting: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function formatTitleResult(hit) {
|
||||
return [
|
||||
{
|
||||
text: "[[" + hit.title + "]]",
|
||||
indented: 0,
|
||||
fold: 'open',
|
||||
hidden: false,
|
||||
fleeting: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function renderGraphs() {
|
||||
$('code.language-dot').each(function (i, code) {
|
||||
if (!code.innerText) {
|
||||
|
@ -163,11 +194,23 @@ function renderGraphs() {
|
|||
function el(tag, children = []) {
|
||||
let el = document.createElement(tag)
|
||||
_.each(children, item => {
|
||||
el.appendChild(item)
|
||||
if (item !== undefined) el.appendChild(item)
|
||||
})
|
||||
return el
|
||||
}
|
||||
|
||||
function mflatten(rowData) {
|
||||
return Promise.all(rowData.reduce(function (a, b) {
|
||||
return a.concat(b);
|
||||
}, []));
|
||||
}
|
||||
|
||||
function flatten(rowData) {
|
||||
return rowData.reduce(function (a, b) {
|
||||
return a.concat(b);
|
||||
}, []);
|
||||
}
|
||||
|
||||
function Editor(holder, input) {
|
||||
function renderInline(cellText) {
|
||||
if (!cellText) return document.createTextNode('')
|
||||
|
@ -179,38 +222,57 @@ function Editor(holder, input) {
|
|||
return span[0];
|
||||
}
|
||||
|
||||
function promiseMapAll(p, f) {
|
||||
return p.then(all => Promise.all(_.map(all, f)))
|
||||
}
|
||||
|
||||
function transformTable(editor, id, element) {
|
||||
editor.treeForId(id).then(tree => {
|
||||
let header = _.find(tree[0].children, c => c.text === 'headers') || []
|
||||
let rows = _.find(tree[0].children, c => c.text === 'rows') || []
|
||||
editor.treeForId(id)
|
||||
.then(tree => {
|
||||
let header = _.find(tree[0].children, c => c.text === 'headers') || []
|
||||
let rows = _.find(tree[0].children, c => c.text === 'rows') || []
|
||||
|
||||
let rowData = _.map(rows.children, row => {
|
||||
// FIXME: Use a real parse link function
|
||||
let page = row.text.substring(2).substring(0, row.text.length - 4)
|
||||
return fetch('/' + page + '?format=metakv')
|
||||
.then(res => res.json())
|
||||
.then(res => res.meta)
|
||||
.then(rowData => {
|
||||
return el("tr", [
|
||||
el("td", [renderInline(row.text)]),
|
||||
..._.map(header.children, col => {
|
||||
let td = el("td")
|
||||
let value = rowData[_.snakeCase(_.trim(col.text))];
|
||||
if (col.children && col.children.length > 0) {
|
||||
value = col.children[0].text
|
||||
}
|
||||
transform(value ? value.replace(/^:/, '=') : '', $(td), id, editor, rowData)
|
||||
return td
|
||||
})
|
||||
])
|
||||
let collection = _.map(rows.children, child => {
|
||||
let res = child.text.match(/{{query(!?):\s*([^}]+)}}/)
|
||||
if (res && res[1] === '!') {
|
||||
return search.startQuery(res[2])
|
||||
.then(hits => _.uniqBy(_.flatMap(hits, formatTitleResult), _.property('text')))
|
||||
}
|
||||
return Promise.resolve().then(() => [child])
|
||||
});
|
||||
|
||||
Promise.all(collection)
|
||||
.then(_.flatten)
|
||||
.then(_.partialRight(_.map, _.property('text')))
|
||||
.then(_.uniq)
|
||||
.then(rowTexts => {
|
||||
return _.map(rowTexts, rowText => {
|
||||
let page = rowText.substring(2).substring(0, rowText.length - 4)
|
||||
return fetch('/' + page + '?format=metakv')
|
||||
.then(res => res.ok ? res.json() : {meta: {}})
|
||||
.then(res => res.meta)
|
||||
.then(rowData => {
|
||||
rowData.title = rowData.title || rowText
|
||||
return el("tr", [
|
||||
el("td", [renderInline(rowText)]),
|
||||
..._.map(header.children, col => {
|
||||
let td = el("td")
|
||||
let value = rowData[_.snakeCase(_.trim(col.text))];
|
||||
if (col.children && col.children.length > 0) {
|
||||
value = col.children[0].text
|
||||
}
|
||||
transform(value ? value.replace(/^:/, '=') : '', $(td), id, editor, rowData)
|
||||
return td
|
||||
})
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Promise.all(rowData)
|
||||
.then(trs => {
|
||||
return el("table", [
|
||||
el("thead", [
|
||||
el("tr", [
|
||||
.then(mflatten)
|
||||
.then(trs => {
|
||||
return el("table", [
|
||||
el("thead", [
|
||||
el("tr", [
|
||||
el("th", [
|
||||
document.createTextNode("Title")
|
||||
]),
|
||||
|
@ -219,13 +281,21 @@ function Editor(holder, input) {
|
|||
document.createTextNode(col.text)
|
||||
])
|
||||
})
|
||||
]
|
||||
),
|
||||
]),
|
||||
el("tbody", trs)
|
||||
])
|
||||
}).then(table => element.html(table))
|
||||
})
|
||||
]),
|
||||
]),
|
||||
el("tbody", trs)
|
||||
])
|
||||
})
|
||||
.then(table => {
|
||||
table.classList.add('table')
|
||||
table.classList.add('wiki-table')
|
||||
|
||||
let div = el('div', [table])
|
||||
div.classList.add('table-wrapper')
|
||||
|
||||
return element.html(div);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function transformMathExpression(converted, scope) {
|
||||
|
@ -242,7 +312,7 @@ function Editor(holder, input) {
|
|||
if (parsedExpr.isAssignmentNode) {
|
||||
converted = parsedExpr.object.name + " = <i>" + evaluated.toString() + "</i>"
|
||||
} else {
|
||||
converted = expr + " = <i>" + evaluated.toString() + "</i>"
|
||||
converted = "<span class='expression'>" + expr + " = </span><i>" + evaluated.toString() + "</i>"
|
||||
}
|
||||
} catch (e) {
|
||||
converted = converted + ' <span style="background: red; color: white;">' + e.message + '</span>';
|
||||
|
@ -331,11 +401,11 @@ function Editor(holder, input) {
|
|||
).save().then(() => indicator.done())
|
||||
})
|
||||
|
||||
// editor.on('rendered', function () {
|
||||
// PrismJS.highlightAll()
|
||||
// mermaid.init()
|
||||
// renderGraphs();
|
||||
// })
|
||||
// editor.on('rendered', function () {
|
||||
// PrismJS.highlightAll()
|
||||
// mermaid.init()
|
||||
// renderGraphs();
|
||||
// })
|
||||
|
||||
menu.connectContextMenu(editor)
|
||||
|
||||
|
@ -522,47 +592,45 @@ function Editor(holder, input) {
|
|||
|
||||
editor.on('stop-editing', function (input, id) {
|
||||
let $input = $(input);
|
||||
$input.parents('.list-item').removeClass('active');
|
||||
$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()
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!$input.val()) return
|
||||
|
||||
let query = $input.val()
|
||||
|
||||
Promise.any([
|
||||
match(query, /{{query(!?):\s*([^}]+)}}/)
|
||||
])
|
||||
.then(res => {
|
||||
if (res[1] === '!') {
|
||||
return search.startQuery(res[2])
|
||||
.then(hits => _.uniqBy(_.flatMap(hits, formatTitleResult), _.property('text')))
|
||||
.then(results => editor.replaceChildren(id, results))
|
||||
.finally(() => editor.render())
|
||||
} else {
|
||||
return search.startQuery(res[2])
|
||||
.then(hits => _.flatMap(hits, formatLineResult))
|
||||
.then(results => editor.replaceChildren(id, results))
|
||||
.finally(() => editor.render())
|
||||
}
|
||||
})
|
||||
.catch(() => console.log('match error'))
|
||||
});
|
||||
return editor
|
||||
})
|
||||
}
|
||||
|
||||
function match(s, re) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let res = s.match(re)
|
||||
if (res) resolve(res)
|
||||
else reject()
|
||||
});
|
||||
}
|
||||
|
||||
let searchInput = document.getElementById('search-input');
|
||||
|
||||
_.tap(search.search(searchInput), searcher => {
|
||||
|
|
|
@ -457,6 +457,9 @@ input.input-line, input.input-line:active {
|
|||
width: 400px;
|
||||
}
|
||||
}
|
||||
.wiki-table .expression {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.todo--todo {
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user