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
You need to sign in or sign up before continuing.
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