Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
76ade8df
Commit
76ade8df
authored
Apr 11, 2020
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: link autocomplete + insert link modal (markdown)
parent
245104c6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
134 additions
and
8 deletions
+134
-8
page-selector.vue
client/components/common/page-selector.vue
+1
-0
editor-markdown.vue
client/components/editor/editor-markdown.vue
+113
-4
engine.js
server/modules/search/db/engine.js
+2
-0
engine.js
server/modules/search/postgres/engine.js
+18
-4
No files found.
client/components/common/page-selector.vue
View file @
76ade8df
...
...
@@ -10,6 +10,7 @@
v-icon.mr-3(color='white') mdi-page-next-outline
.body-1(v-if='mode === `create`') Select New Page Location
.body-1(v-else-if='mode === `move`') Move / Rename Page Location
.body-1(v-else-if='mode === `select`') Select Page
v-spacer
v-progress-circular(
indeterminate
...
...
client/components/editor/editor-markdown.vue
View file @
76ade8df
...
...
@@ -109,7 +109,7 @@
.
editor
-
markdown
-
sidebar
v
-
tooltip
(
right
,
color
=
'teal'
)
template
(
v
-
slot
:
activator
=
'{ on
}
'
)
v
-
btn
.
animated
.
fadeInLeft
(
icon
,
tile
,
v
-
on
=
'on'
,
dark
,
disabled
).
mx
-
0
v
-
btn
.
animated
.
fadeInLeft
(
icon
,
tile
,
v
-
on
=
'on'
,
dark
,
@
click
=
'insertLink'
).
mx
-
0
v
-
icon
mdi
-
link
-
plus
span
{{
$t
(
'editor:markup.insertLink'
)
}}
v
-
tooltip
(
right
,
color
=
'teal'
)
...
...
@@ -130,7 +130,7 @@
v
-
tooltip
(
right
,
color
=
'teal'
)
template
(
v
-
slot
:
activator
=
'{ on
}
'
)
v
-
btn
.
mt
-
3
.
animated
.
fadeInLeft
.
wait
-
p4s
(
icon
,
tile
,
v
-
on
=
'on'
,
dark
,
disabled
).
mx
-
0
v
-
icon
mdi
-
library
-
video
v
-
icon
mdi
-
movie
span
{{
$t
(
'editor:markup.insertVideoAudio'
)
}}
v
-
tooltip
(
right
,
color
=
'teal'
)
template
(
v
-
slot
:
activator
=
'{ on
}
'
)
...
...
@@ -176,14 +176,16 @@
.
caption
Ln
{{
cursorPos
.
line
+
1
}}
,
Col
{{
cursorPos
.
ch
+
1
}}
markdown
-
help
(
v
-
if
=
'helpShown'
)
page
-
selector
(
mode
=
'select'
,
v
-
model
=
'insertLinkDialog'
,
:
open
-
handler
=
'insertLinkHandler'
,
:
path
=
'path'
,
:
locale
=
'locale'
)
<
/template
>
<
script
>
import
_
from
'lodash'
import
{
get
,
sync
}
from
'vuex-pathify'
import
markdownHelp
from
'./markdown/help.vue'
import
gql
from
'graphql-tag'
/* global siteConfig */
/* global siteConfig
, siteLangs
*/
// ========================================
// IMPORTS
...
...
@@ -202,6 +204,7 @@ import 'codemirror/addon/display/fullscreen.js'
import
'codemirror/addon/display/fullscreen.css'
import
'codemirror/addon/selection/mark-selection.js'
import
'codemirror/addon/search/searchcursor.js'
import
'codemirror/addon/hint/show-hint.js'
// Markdown-it
import
MarkdownIt
from
'markdown-it'
...
...
@@ -353,7 +356,8 @@ export default {
cursorPos
:
{
ch
:
0
,
line
:
1
}
,
previewShown
:
true
,
previewHTML
:
''
,
helpShown
:
false
helpShown
:
false
,
insertLinkDialog
:
false
}
}
,
computed
:
{
...
...
@@ -544,6 +548,72 @@ export default {
mmElm.innerHTML = `
<
div
id
=
"mermaid-id-${mermaidId
}
"
>
$
{
mermaid
.
render
(
`mermaid-id-${mermaidId
}
`
,
mermaidDef
)
}
<
/div>
`
elm
.
parentElement
.
replaceWith
(
mmElm
)
}
)
}
,
autocomplete
(
cm
,
change
)
{
if
(
cm
.
getModeAt
(
cm
.
getCursor
()).
name
!==
'markdown'
)
{
return
}
// Links
if
(
change
.
text
[
0
]
===
'('
)
{
const
curLine
=
cm
.
getLine
(
change
.
from
.
line
).
substring
(
0
,
change
.
from
.
ch
)
if
(
curLine
[
curLine
.
length
-
1
]
===
']'
)
{
cm
.
showHint
({
hint
:
async
(
cm
,
options
)
=>
{
const
cur
=
cm
.
getCursor
()
const
token
=
cm
.
getTokenAt
(
cur
)
try
{
const
respRaw
=
await
this
.
$apollo
.
query
({
query
:
gql
`
query ($query: String!, $locale: String) {
pages {
search(query:$query, locale:$locale) {
results {
title
path
locale
}
totalHits
}
}
}
`
,
variables
:
{
query
:
token
.
string
,
locale
:
this
.
locale
}
,
fetchPolicy
:
'cache-first'
}
)
const
resp
=
_
.
get
(
respRaw
,
'data.pages.search'
,
{
}
)
if
(
resp
&&
resp
.
totalHits
>
0
)
{
return
{
list
:
resp
.
results
.
map
(
r
=>
({
text
:
(
siteLangs
.
length
>
0
?
`/${r.locale
}
/${r.path
}
`
:
`/${r.path
}
`
)
+
')'
,
displayText
:
siteLangs
.
length
>
0
?
`/${r.locale
}
/${r.path
}
- ${r.title
}
`
:
`/${r.path
}
- ${r.title
}
`
}
)),
from
:
CodeMirror
.
Pos
(
cur
.
line
,
token
.
start
),
to
:
CodeMirror
.
Pos
(
cur
.
line
,
token
.
end
)
}
}
}
catch
(
err
)
{
}
return
{
list
:
[],
from
:
CodeMirror
.
Pos
(
cur
.
line
,
token
.
start
),
to
:
CodeMirror
.
Pos
(
cur
.
line
,
token
.
end
)
}
}
}
)
}
}
}
,
insertLink
()
{
this
.
insertLinkDialog
=
true
}
,
insertLinkHandler
({
locale
,
path
}
)
{
const
lastPart
=
_
.
last
(
path
.
split
(
'/'
))
this
.
insertAtCursor
({
content
:
siteLangs
.
length
>
0
?
`[${lastPart
}
](/${locale
}
/${path
}
)`
:
`[${lastPart
}
](/${path
}
)`
}
)
}
}
,
mounted
()
{
...
...
@@ -624,6 +694,8 @@ export default {
}
)
this
.
cm
.
setOption
(
'extraKeys'
,
keyBindings
)
this
.
cm
.
on
(
'inputRead'
,
this
.
autocomplete
)
// Handle cursor movement
this
.
cm
.
on
(
'cursorActivity'
,
c
=>
{
...
...
@@ -921,6 +993,43 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
text
-
decoration
:
underline
;
color
:
white
!
important
;
}
}
// HINT DROPDOWN
.
CodeMirror
-
hints
{
position
:
absolute
;
z
-
index
:
10
;
overflow
:
hidden
;
list
-
style
:
none
;
margin
:
0
;
padding
:
1
px
;
box
-
shadow
:
2
px
3
px
5
px
rgba
(
0
,
0
,
0
,.
2
);
border
:
1
px
solid
mc
(
'grey'
,
'700'
);
background
:
mc
(
'grey'
,
'900'
);
font
-
family
:
'Roboto Mono'
,
monospace
;
font
-
size
:
.
9
rem
;
max
-
height
:
150
px
;
overflow
-
y
:
auto
;
min
-
width
:
250
px
;
max
-
width
:
80
vw
;
}
.
CodeMirror
-
hint
{
margin
:
0
;
padding
:
0
4
px
;
white
-
space
:
pre
;
color
:
#
FFF
;
cursor
:
pointer
;
}
li
.
CodeMirror
-
hint
-
active
{
background
:
mc
(
'blue'
,
'500'
);
color
:
#
FFF
;
}
<
/style
>
server/modules/search/db/engine.js
View file @
76ade8df
...
...
@@ -34,9 +34,11 @@ module.exports = {
if
(
WIKI
.
config
.
db
.
type
===
'postgres'
)
{
builderSub
.
where
(
'title'
,
'ILIKE'
,
`%
${
q
}
%`
)
builderSub
.
orWhere
(
'description'
,
'ILIKE'
,
`%
${
q
}
%`
)
builderSub
.
orWhere
(
'path'
,
'ILIKE'
,
`%
${
q
.
toLowerCase
()}
%`
)
}
else
{
builderSub
.
where
(
'title'
,
'LIKE'
,
`%
${
q
}
%`
)
builderSub
.
orWhere
(
'description'
,
'LIKE'
,
`%
${
q
}
%`
)
builderSub
.
orWhere
(
'path'
,
'LIKE'
,
`%
${
q
.
toLowerCase
()}
%`
)
}
})
})
...
...
server/modules/search/postgres/engine.js
View file @
76ade8df
...
...
@@ -60,12 +60,26 @@ module.exports = {
async
query
(
q
,
opts
)
{
try
{
let
suggestions
=
[]
const
results
=
await
WIKI
.
models
.
knex
.
raw
(
`
let
qry
=
`
SELECT id, path, locale, title, description
FROM "pagesVector", to_tsquery(?,?) query
WHERE query @@ "tokens"
ORDER BY ts_rank(tokens, query) DESC
`
,
[
this
.
config
.
dictLanguage
,
tsquery
(
q
)])
WHERE (query @@ "tokens" OR path ILIKE ?)
`
let
qryEnd
=
`ORDER BY ts_rank(tokens, query) DESC`
let
qryParams
=
[
this
.
config
.
dictLanguage
,
tsquery
(
q
),
`%
${
q
.
toLowerCase
()}
%`
]
if
(
opts
.
locale
)
{
qry
=
`
${
qry
}
AND locale = ?`
qryParams
.
push
(
opts
.
locale
)
}
if
(
opts
.
path
)
{
qry
=
`
${
qry
}
AND path ILIKE ?`
qryParams
.
push
(
`%
${
opts
.
path
}
`
)
}
const
results
=
await
WIKI
.
models
.
knex
.
raw
(
`
${
qry
}
${
qryEnd
}
`
,
qryParams
)
if
(
results
.
rows
.
length
<
5
)
{
const
suggestResults
=
await
WIKI
.
models
.
knex
.
raw
(
`SELECT word, word <-> ? AS rank FROM "pagesWords" WHERE similarity(word, ?) > 0.2 ORDER BY rank LIMIT 5;`
,
[
q
,
q
])
suggestions
=
suggestResults
.
rows
.
map
(
r
=>
r
.
word
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment