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
d2a18eca
Unverified
Commit
d2a18eca
authored
Apr 02, 2023
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: welcome overlay + editor improvements
parent
b979e508
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
492 additions
and
294 deletions
+492
-294
app-init.sh
.devcontainer/app-init.sh
+2
-0
settings.json
.vscode/settings.json
+5
-1
package.json
server/package.json
+1
-1
package-lock.json
ux/package-lock.json
+0
-0
package.json
ux/package.json
+47
-46
quasar.config.js
ux/quasar.config.js
+1
-1
App.vue
ux/src/App.vue
+2
-0
EditorMarkdown.vue
ux/src/components/EditorMarkdown.vue
+0
-0
MainOverlayDialog.vue
ux/src/components/MainOverlayDialog.vue
+4
-0
PageActionsCol.vue
ux/src/components/PageActionsCol.vue
+210
-0
SideDialog.vue
ux/src/components/SideDialog.vue
+128
-0
WelcomeOverlay.vue
ux/src/components/WelcomeOverlay.vue
+70
-10
app.scss
ux/src/css/app.scss
+1
-0
en.json
ux/src/i18n/locales/en.json
+0
-0
Index.vue
ux/src/pages/Index.vue
+15
-227
routes.js
ux/src/router/routes.js
+2
-6
page.js
ux/src/stores/page.js
+2
-2
site.js
ux/src/stores/site.js
+2
-0
No files found.
.devcontainer/app-init.sh
View file @
d2a18eca
...
...
@@ -9,6 +9,8 @@ git config oh-my-zsh.hide-info 1
echo
"Waiting for DB container to come online..."
/usr/local/bin/wait-for localhost:5432
--
echo
"DB ready"
npm
install
-g
npm-check-updates
echo
"Installing dependencies..."
cd
server
npm
install
...
...
.vscode/settings.json
View file @
d2a18eca
...
...
@@ -13,5 +13,9 @@
"i18n-ally.localesPaths"
:
[
"ux/src/i18n/locales"
],
"i18n-ally.keystyle"
:
"flat"
"i18n-ally.keystyle"
:
"flat"
,
"i18n-ally.sortKeys"
:
true
,
"i18n-ally.enabledFrameworks"
:
[
"vue"
]
}
server/package.json
View file @
d2a18eca
...
...
@@ -198,7 +198,7 @@
},
"ext"
:
"js,json,graphql,gql"
,
"watch"
:
[
"
./
"
"
server
"
]
}
}
ux/package-lock.json
View file @
d2a18eca
B
{
...
...
ux/package.json
View file @
d2a18eca
...
...
@@ -11,41 +11,42 @@
"lint"
:
"eslint --ext .js,.vue ./"
},
"dependencies"
:
{
"@apollo/client"
:
"3.7.
7
"
,
"@apollo/client"
:
"3.7.
11
"
,
"@lezer/common"
:
"1.0.2"
,
"@quasar/extras"
:
"1.15.10"
,
"@tiptap/core"
:
"2.0.0-beta.212"
,
"@tiptap/extension-code-block"
:
"2.0.0-beta.212"
,
"@tiptap/extension-code-block-lowlight"
:
"2.0.0-beta.212"
,
"@tiptap/extension-color"
:
"2.0.0-beta.212"
,
"@tiptap/extension-dropcursor"
:
"2.0.0-beta.212"
,
"@tiptap/extension-font-family"
:
"2.0.0-beta.212"
,
"@tiptap/extension-gapcursor"
:
"2.0.0-beta.212"
,
"@tiptap/extension-hard-break"
:
"2.0.0-beta.212"
,
"@tiptap/extension-highlight"
:
"2.0.0-beta.212"
,
"@tiptap/extension-history"
:
"2.0.0-beta.212"
,
"@tiptap/extension-image"
:
"2.0.0-beta.212"
,
"@tiptap/extension-mention"
:
"2.0.0-beta.212"
,
"@tiptap/extension-placeholder"
:
"2.0.0-beta.212"
,
"@tiptap/extension-table"
:
"2.0.0-beta.212"
,
"@tiptap/extension-table-cell"
:
"2.0.0-beta.212"
,
"@tiptap/extension-table-header"
:
"2.0.0-beta.212"
,
"@tiptap/extension-table-row"
:
"2.0.0-beta.212"
,
"@tiptap/extension-task-item"
:
"2.0.0-beta.212"
,
"@tiptap/extension-task-list"
:
"2.0.0-beta.212"
,
"@tiptap/extension-text-align"
:
"2.0.0-beta.212"
,
"@tiptap/extension-text-style"
:
"2.0.0-beta.212"
,
"@tiptap/extension-typography"
:
"2.0.0-beta.212"
,
"@tiptap/pm"
:
"2.0.0-beta.212"
,
"@tiptap/starter-kit"
:
"2.0.0-beta.212"
,
"@tiptap/vue-3"
:
"2.0.0-beta.212"
,
"@mdi/font"
:
"7.2.96"
,
"@quasar/extras"
:
"1.16.1"
,
"@tiptap/core"
:
"2.0.1"
,
"@tiptap/extension-code-block"
:
"2.0.1"
,
"@tiptap/extension-code-block-lowlight"
:
"2.0.1"
,
"@tiptap/extension-color"
:
"2.0.1"
,
"@tiptap/extension-dropcursor"
:
"2.0.1"
,
"@tiptap/extension-font-family"
:
"2.0.1"
,
"@tiptap/extension-gapcursor"
:
"2.0.1"
,
"@tiptap/extension-hard-break"
:
"2.0.1"
,
"@tiptap/extension-highlight"
:
"2.0.1"
,
"@tiptap/extension-history"
:
"2.0.1"
,
"@tiptap/extension-image"
:
"2.0.1"
,
"@tiptap/extension-mention"
:
"2.0.1"
,
"@tiptap/extension-placeholder"
:
"2.0.1"
,
"@tiptap/extension-table"
:
"2.0.1"
,
"@tiptap/extension-table-cell"
:
"2.0.1"
,
"@tiptap/extension-table-header"
:
"2.0.1"
,
"@tiptap/extension-table-row"
:
"2.0.1"
,
"@tiptap/extension-task-item"
:
"2.0.1"
,
"@tiptap/extension-task-list"
:
"2.0.1"
,
"@tiptap/extension-text-align"
:
"2.0.1"
,
"@tiptap/extension-text-style"
:
"2.0.1"
,
"@tiptap/extension-typography"
:
"2.0.1"
,
"@tiptap/pm"
:
"2.0.1"
,
"@tiptap/starter-kit"
:
"2.0.1"
,
"@tiptap/vue-3"
:
"2.0.1"
,
"apollo-upload-client"
:
"17.0.0"
,
"browser-fs-access"
:
"0.3
1.2
"
,
"browser-fs-access"
:
"0.3
3.0
"
,
"clipboard"
:
"2.0.11"
,
"codemirror"
:
"5.65.11"
,
"codemirror-asciidoc"
:
"1.0.4"
,
"dependency-graph"
:
"0.11.0"
,
"filesize"
:
"10.0.
6
"
,
"filesize"
:
"10.0.
7
"
,
"filesize-parser"
:
"1.5.0"
,
"fuse.js"
:
"6.6.2"
,
"graphql"
:
"16.6.0"
,
...
...
@@ -54,45 +55,45 @@
"jwt-decode"
:
"3.1.2"
,
"lodash-es"
:
"4.17.21"
,
"lowlight"
:
"2.8.1"
,
"luxon"
:
"3.
2.1
"
,
"pinia"
:
"2.0.3
0
"
,
"prosemirror-commands"
:
"1.5.
0
"
,
"luxon"
:
"3.
3.0
"
,
"pinia"
:
"2.0.3
3
"
,
"prosemirror-commands"
:
"1.5.
1
"
,
"prosemirror-history"
:
"1.3.0"
,
"prosemirror-keymap"
:
"1.2.
0
"
,
"prosemirror-keymap"
:
"1.2.
1
"
,
"prosemirror-model"
:
"1.19.0"
,
"prosemirror-schema-list"
:
"1.2.2"
,
"prosemirror-state"
:
"1.4.2"
,
"prosemirror-transform"
:
"1.7.1"
,
"prosemirror-view"
:
"1.30.
1
"
,
"prosemirror-view"
:
"1.30.
2
"
,
"pug"
:
"3.0.2"
,
"quasar"
:
"2.11.
5
"
,
"slugify"
:
"1.6.
5
"
,
"socket.io-client"
:
"4.
5.4
"
,
"quasar"
:
"2.11.
9
"
,
"slugify"
:
"1.6.
6
"
,
"socket.io-client"
:
"4.
6.1
"
,
"tabulator-tables"
:
"5.4.4"
,
"tippy.js"
:
"6.3.7"
,
"uuid"
:
"9.0.0"
,
"v-network-graph"
:
"0.
8
.1"
,
"v-network-graph"
:
"0.
9
.1"
,
"vue"
:
"3.2.47"
,
"vue-i18n"
:
"9.2.2"
,
"vue-router"
:
"4.1.6"
,
"vue3-otp-input"
:
"0.
3.6
"
,
"vue3-otp-input"
:
"0.
4.1
"
,
"vuedraggable"
:
"4.1.0"
,
"xterm"
:
"5.1.0"
,
"zxcvbn"
:
"4.4.2"
},
"devDependencies"
:
{
"@intlify/unplugin-vue-i18n"
:
"0.
8.1
"
,
"@quasar/app-vite"
:
"1.2.
0
"
,
"@types/lodash"
:
"4.14.19
1
"
,
"@volar/vue-language-plugin-pug"
:
"1.
0.24
"
,
"@intlify/unplugin-vue-i18n"
:
"0.
10.0
"
,
"@quasar/app-vite"
:
"1.2.
1
"
,
"@types/lodash"
:
"4.14.19
2
"
,
"@volar/vue-language-plugin-pug"
:
"1.
2.0
"
,
"autoprefixer"
:
"10.4.14"
,
"browserlist"
:
"latest"
,
"eslint"
:
"8.3
3
.0"
,
"eslint"
:
"8.3
7
.0"
,
"eslint-config-standard"
:
"17.0.0"
,
"eslint-plugin-import"
:
"2.27.5"
,
"eslint-plugin-n"
:
"15.
6.1
"
,
"eslint-plugin-n"
:
"15.
7.0
"
,
"eslint-plugin-promise"
:
"6.1.1"
,
"eslint-plugin-vue"
:
"9.
9
.0"
"eslint-plugin-vue"
:
"9.
10
.0"
},
"engines"
:
{
"node"
:
">= 18.0"
,
...
...
ux/quasar.config.js
View file @
d2a18eca
...
...
@@ -50,7 +50,7 @@ module.exports = configure(function (/* ctx */) {
extras
:
[
// 'ionicons-v4',
// 'mdi-v5',
'mdi-v7'
,
//
'mdi-v7',
// 'fontawesome-v6',
// 'eva-icons',
// 'themify',
...
...
ux/src/App.vue
View file @
d2a18eca
...
...
@@ -10,6 +10,8 @@ import { useSiteStore } from 'src/stores/site'
import
{
useUserStore
}
from
'src/stores/user'
import
{
setCssVar
,
useQuasar
}
from
'quasar'
import
'@mdi/font/css/materialdesignicons.css'
/* global siteConfig */
// QUASAR
...
...
ux/src/components/EditorMarkdown.vue
View file @
d2a18eca
This diff is collapsed.
Click to expand it.
ux/src/components/MainOverlayDialog.vue
View file @
d2a18eca
...
...
@@ -26,6 +26,10 @@ const overlays = {
TableEditor
:
defineAsyncComponent
({
loader
:
()
=>
import
(
'./TableEditorOverlay.vue'
),
loadingComponent
:
LoadingGeneric
}),
Welcome
:
defineAsyncComponent
({
loader
:
()
=>
import
(
'./WelcomeOverlay.vue'
),
loadingComponent
:
LoadingGeneric
})
}
...
...
ux/src/components/PageActionsCol.vue
0 → 100644
View file @
d2a18eca
<
template
lang=
"pug"
>
.page-actions.column.items-stretch.order-last(:class='editorStore.isActive ? `is-editor` : ``')
q-btn.q-py-md(
flat
icon='las la-pen-nib'
:color='editorStore.isActive ? `white` : `deep-orange-9`'
aria-label='Page Properties'
@click='togglePageProperties'
)
q-tooltip(anchor='center left' self='center right') Page Properties
q-btn.q-py-md(
flat
icon='las la-project-diagram'
:color='editorStore.isActive ? `white` : `deep-orange-9`'
aria-label='Page Data'
@click='togglePageData'
disable
v-if='flagsStore.experimental'
)
q-tooltip(anchor='center left' self='center right') Page Data
template(v-if='!(editorStore.isActive && editorStore.mode === `create`)')
q-separator.q-my-sm(inset)
q-btn.q-py-sm(
flat
icon='las la-ellipsis-h'
:color='editorStore.isActive ? `deep-orange-2` : `grey`'
aria-label='Page Actions'
)
q-tooltip(anchor='center left' self='center right') Page Actions
q-menu(
anchor='top left'
self='top right'
auto-close
transition-show='jump-left'
)
q-list(padding, style='min-width: 225px;')
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-history', size='sm')
q-item-section
q-item-label View History
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-code', size='sm')
q-item-section
q-item-label View Source
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-atom', size='sm')
q-item-section
q-item-label Convert Page
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-magic', size='sm')
q-item-section
q-item-label Re-render Page
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-sun', size='sm')
q-item-section
q-item-label View Backlinks
q-space
template(v-if='!(editorStore.isActive && editorStore.mode === `create`)')
q-btn.q-py-sm(
flat
icon='las la-copy'
:color='editorStore.isActive ? `deep-orange-2` : `grey`'
aria-label='Duplicate Page'
@click='duplicatePage'
)
q-tooltip(anchor='center left' self='center right') Duplicate Page
q-btn.q-py-sm(
flat
icon='las la-share'
:color='editorStore.isActive ? `deep-orange-2` : `grey`'
aria-label='Rename / Move Page'
@click='renamePage'
)
q-tooltip(anchor='center left' self='center right') Rename / Move Page
q-btn.q-py-sm(
flat
icon='las la-trash'
:color='editorStore.isActive ? `deep-orange-2` : `grey`'
aria-label='Delete Page'
@click='deletePage'
:class='editorStore.isActive ? `q-pb-md` : ``'
)
q-tooltip(anchor='center left' self='center right') Delete Page
span.page-actions-mode(v-else)
{{
t
(
'common.actions.newPage'
)
}}
</
template
>
<
script
setup
>
import
{
useQuasar
}
from
'quasar'
import
{
computed
,
defineAsyncComponent
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
useRouter
,
useRoute
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
useEditorStore
}
from
'src/stores/editor'
import
{
useFlagsStore
}
from
'src/stores/flags'
import
{
usePageStore
}
from
'src/stores/page'
import
{
useSiteStore
}
from
'src/stores/site'
// QUASAR
const
$q
=
useQuasar
()
// STORES
const
editorStore
=
useEditorStore
()
const
flagsStore
=
useFlagsStore
()
const
pageStore
=
usePageStore
()
const
siteStore
=
useSiteStore
()
// ROUTER
const
router
=
useRouter
()
const
route
=
useRoute
()
// I18N
const
{
t
}
=
useI18n
()
// METHODS
function
togglePageProperties
()
{
siteStore
.
$patch
({
sideDialogComponent
:
'PagePropertiesDialog'
,
sideDialogShown
:
true
})
}
function
togglePageData
()
{
siteStore
.
$patch
({
sideDialogComponent
:
'PageDataDialog'
,
sideDialogShown
:
true
})
}
function
duplicatePage
()
{
$q
.
dialog
({
component
:
defineAsyncComponent
(()
=>
import
(
'../components/TreeBrowserDialog.vue'
)),
componentProps
:
{
mode
:
'duplicatePage'
,
folderPath
:
''
,
itemId
:
pageStore
.
id
,
itemTitle
:
pageStore
.
title
,
itemFileName
:
pageStore
.
path
}
}).
onOk
(()
=>
{
// TODO: change route to new location
})
}
function
renamePage
()
{
$q
.
dialog
({
component
:
defineAsyncComponent
(()
=>
import
(
'../components/TreeBrowserDialog.vue'
)),
componentProps
:
{
mode
:
'renamePage'
,
folderPath
:
''
,
itemId
:
pageStore
.
id
,
itemTitle
:
pageStore
.
title
,
itemFileName
:
pageStore
.
path
}
}).
onOk
(()
=>
{
// TODO: change route to new location
})
}
function
deletePage
()
{
$q
.
dialog
({
component
:
defineAsyncComponent
(()
=>
import
(
'../components/PageDeleteDialog.vue'
)),
componentProps
:
{
pageId
:
pageStore
.
id
,
pageName
:
pageStore
.
title
}
}).
onOk
(()
=>
{
router
.
replace
(
'/'
)
})
}
</
script
>
<
style
lang=
"scss"
>
.page-actions
{
flex
:
0
0
56px
;
@at-root
.body--light
&
{
background-color
:
$grey-3
;
}
@at-root
.body--dark
&
{
background-color
:
$dark-4
;
}
&
.is-editor
{
@at-root
.body--light
&
{
background-color
:
$deep-orange-9
;
}
@at-root
.body--dark
&
{
background-color
:
$deep-orange-9
;
}
}
&
-mode
{
writing-mode
:
vertical-rl
;
text-orientation
:
mixed
;
padding
:
1
.75rem
1rem
1
.75rem
0
;
color
:
$deep-orange-3
;
font-weight
:
500
;
}
}
</
style
>
ux/src/components/SideDialog.vue
0 → 100644
View file @
d2a18eca
<
template
lang=
"pug"
>
q-dialog(
v-model='siteStore.sideDialogShown'
position='right'
full-height
transition-show='jump-left'
transition-hide='jump-right'
class='floating-sidepanel'
no-shake
)
component(:is='sideDialogs[siteStore.sideDialogComponent]')
</
template
>
<
script
setup
>
import
{
useQuasar
}
from
'quasar'
import
{
computed
,
defineAsyncComponent
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
useRouter
,
useRoute
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
useEditorStore
}
from
'src/stores/editor'
import
{
useFlagsStore
}
from
'src/stores/flags'
import
{
usePageStore
}
from
'src/stores/page'
import
{
useSiteStore
}
from
'src/stores/site'
// COMPONENTS
import
LoadingGeneric
from
'src/components/LoadingGeneric.vue'
const
sideDialogs
=
{
PageDataDialog
:
defineAsyncComponent
({
loader
:
()
=>
import
(
'src/components/PageDataDialog.vue'
),
loadingComponent
:
LoadingGeneric
}),
PagePropertiesDialog
:
defineAsyncComponent
({
loader
:
()
=>
import
(
'src/components/PagePropertiesDialog.vue'
),
loadingComponent
:
LoadingGeneric
})
}
// QUASAR
const
$q
=
useQuasar
()
// STORES
const
editorStore
=
useEditorStore
()
const
flagsStore
=
useFlagsStore
()
const
pageStore
=
usePageStore
()
const
siteStore
=
useSiteStore
()
// ROUTER
const
router
=
useRouter
()
const
route
=
useRoute
()
// I18N
const
{
t
}
=
useI18n
()
// DATA
const
state
=
reactive
({
showSideDialog
:
false
,
sideDialogComponent
:
null
,
showGlobalDialog
:
false
,
globalDialogComponent
:
null
,
showTagsEditBtn
:
false
,
tagEditMode
:
false
,
tocExpanded
:
[
'h1-0'
,
'h1-1'
],
tocSelected
:
[],
currentRating
:
3
})
</
script
>
<
style
lang=
"scss"
>
.floating-sidepanel
{
.q-dialog__inner
{
right
:
24px
;
.q-card
{
border-radius
:
4px
!
important
;
min-width
:
450px
;
.q-card__section
{
border-radius
:
0
;
}
}
}
.alt-card
{
@at-root
.body--light
&
{
background-color
:
$grey-2
;
border-top
:
1px
solid
$grey-4
;
box-shadow
:
inset
0
1px
0
0
#FFF
,
inset
0
-1px
0
0
#FFF
;
border-bottom
:
1px
solid
$grey-4
;
}
@at-root
.body--dark
&
{
background-color
:
$dark-4
;
border-top
:
1px
solid
lighten
(
$dark-3
,
8%
);
box-shadow
:
inset
0
1px
0
0
$dark-6
,
inset
0
-1px
0
0
$dark-6
;
border-bottom
:
1px
solid
lighten
(
$dark-3
,
8%
);
}
}
&
-quickaccess
{
width
:
40px
;
border-radius
:
4px
!
important
;
background-color
:
rgba
(
0
,
0
,
0
,.
75
);
backdrop-filter
:
blur
(
5px
);
color
:
#FFF
;
position
:
fixed
;
right
:
486px
;
top
:
74px
;
z-index
:
-1
;
display
:
flex
;
flex-direction
:
column
;
box-shadow
:
0
0
5px
0
rgba
(
0
,
0
,
0
,.
5
)
!
important
;
@at-root
.q-transition--jump-left-enter-active
&
{
display
:
none
!
important
;
}
@at-root
.q-transition--jump-right-leave-active
&
{
display
:
none
!
important
;
}
}
}
</
style
>
ux/src/
pages/Welcome
.vue
→
ux/src/
components/WelcomeOverlay
.vue
View file @
d2a18eca
...
...
@@ -13,22 +13,68 @@
:label='t(`welcome.createHome`)'
icon='las la-plus'
no-caps
href='/_edit'
)
)
q-menu.translucent-menu(
auto-close
anchor='top left'
self='bottom left'
)
q-list(padding)
q-item(
clickable
@click='createHomePage(`wysiwyg`)'
v-if='siteStore.editors.wysiwyg'
)
blueprint-icon(icon='google-presentation')
q-item-section.q-pr-sm Using the Visual Editor
q-item-section(side): q-icon(name='mdi-chevron-right')
q-item(
clickable
@click='createHomePage(`markdown`)'
v-if='siteStore.editors.markdown'
)
blueprint-icon(icon='markdown')
q-item-section.q-pr-sm Using the Markdown Editor
q-item-section(side): q-icon(name='mdi-chevron-right')
q-item(
clickable
@click='createHomePage(`asciidoc`)'
v-if='siteStore.editors.asciidoc'
)
blueprint-icon(icon='asciidoc')
q-item-section.q-pr-sm Using the AsciiDoc Editor
q-item-section(side): q-icon(name='mdi-chevron-right')
q-btn(
push
color='primary'
:label='t(`welcome.admin`)'
icon='las la-cog'
no-caps
to='/_a
dmin'
@click='loadA
dmin'
)
</
template
>
<
script
setup
>
import
{
useI18n
}
from
'vue-i18n'
import
{
useMeta
}
from
'quasar'
import
{
useRouter
}
from
'vue-router'
import
{
useMeta
,
useQuasar
}
from
'quasar'
import
{
useSiteStore
}
from
'src/stores/site'
import
{
usePageStore
}
from
'src/stores/page'
// QUASAR
const
$q
=
useQuasar
()
// STORES
const
pageStore
=
usePageStore
()
const
siteStore
=
useSiteStore
()
// ROUTER
const
router
=
useRouter
()
// I18N
...
...
@@ -40,13 +86,27 @@ useMeta({
title
:
t
(
'welcome.title'
)
})
// METHODS
function
createHomePage
(
editor
)
{
siteStore
.
overlay
=
''
pageStore
.
pageCreate
({
editor
,
locale
:
'en'
,
path
:
''
})
}
function
loadAdmin
()
{
siteStore
.
overlay
=
''
router
.
push
(
'/_admin'
)
}
</
script
>
<
style
lang=
"scss"
>
.welcome
{
background
:
$dark-6
radial-gradient
(
ellipse
,
$dark-4
,
$dark-6
);
color
:
#FFF
;
background
:
#FFF
radial-gradient
(
ellipse
,
#FFF
,
#DDD
);
color
:
$grey-9
;
height
:
100vh
;
border
:
10px
solid
#EEE
;
border-radius
:
25px
!
important
;
&
-bg
{
position
:
absolute
;
...
...
@@ -54,10 +114,10 @@ useMeta({
left
:
50%
;
width
:
320px
;
height
:
320px
;
background
:
linear-gradient
(
0
,
$purple-6
50%
,
$blue-9
50%
);
background
:
linear-gradient
(
0
,
#FFF
50%
,
$blue-5
50%
);
border-radius
:
50%
;
filter
:
blur
(
8
0px
);
transform
:
translate
(
-50%
,
-5
0
%
);
filter
:
blur
(
10
0px
);
transform
:
translate
(
-50%
,
-5
5
%
);
}
&
-content
{
...
...
@@ -96,7 +156,7 @@ useMeta({
&
-subtitle
{
font-size
:
1
.2rem
;
font-weight
:
500
;
color
:
$
purple-2
;
color
:
$
blue-7
;
line-height
:
1
.2rem
;
margin-top
:
1rem
;
}
...
...
ux/src/css/app.scss
View file @
d2a18eca
...
...
@@ -202,6 +202,7 @@ body::-webkit-scrollbar-thumb {
@at-root
.body--dark
&
{
background-color
:
rgba
(
$dark
,.
7
);
}
backdrop-filter
:
blur
(
10px
);
>
.q-card
{
...
...
ux/src/i18n/locales/en.json
View file @
d2a18eca
This diff is collapsed.
Click to expand it.
ux/src/pages/Index.vue
View file @
d2a18eca
...
...
@@ -149,105 +149,13 @@ q-page.column
icon='las la-thumbs-up'
color='secondary'
)
.page-actions.column.items-stretch.order-last
q-btn.q-py-md(
flat
icon='las la-pen-nib'
color='deep-orange-9'
aria-label='Page Properties'
@click='togglePageProperties'
)
q-tooltip(anchor='center left' self='center right') Page Properties
q-btn.q-py-md(
flat
icon='las la-project-diagram'
color='deep-orange-9'
aria-label='Page Data'
@click='togglePageData'
disable
v-if='flagsStore.experimental'
)
q-tooltip(anchor='center left' self='center right') Page Data
q-separator.q-my-sm(inset)
q-btn.q-py-sm(
flat
icon='las la-ellipsis-h'
color='grey'
aria-label='Page Actions'
)
q-tooltip(anchor='center left' self='center right') Page Actions
q-menu(
anchor='top left'
self='top right'
auto-close
transition-show='jump-left'
)
q-list(padding, style='min-width: 225px;')
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-history', size='sm')
q-item-section
q-item-label View History
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-code', size='sm')
q-item-section
q-item-label View Source
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-atom', size='sm')
q-item-section
q-item-label Convert Page
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-magic', size='sm')
q-item-section
q-item-label Re-render Page
q-item(clickable)
q-item-section.items-center(avatar)
q-icon(color='deep-orange-9', name='las la-sun', size='sm')
q-item-section
q-item-label View Backlinks
q-space
q-btn.q-py-sm(
flat
icon='las la-copy'
color='grey'
aria-label='Duplicate Page'
@click='duplicatePage'
)
q-tooltip(anchor='center left' self='center right') Duplicate Page
q-btn.q-py-sm(
flat
icon='las la-share'
color='grey'
aria-label='Rename / Move Page'
@click='renamePage'
)
q-tooltip(anchor='center left' self='center right') Rename / Move Page
q-btn.q-py-sm(
flat
icon='las la-trash'
color='grey'
aria-label='Delete Page'
@click='deletePage'
)
q-tooltip(anchor='center left' self='center right') Delete Page
q-dialog(
v-model='state.showSideDialog'
position='right'
full-height
transition-show='jump-left'
transition-hide='jump-right'
class='floating-sidepanel'
no-shake
)
component(:is='sideDialogs[state.sideDialogComponent]')
page-actions-col
side-dialog
</
template
>
<
script
setup
>
import
{
useMeta
,
useQuasar
,
setCssVar
}
from
'quasar'
import
{
useMeta
,
useQuasar
}
from
'quasar'
import
{
computed
,
defineAsyncComponent
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
useRouter
,
useRoute
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
...
...
@@ -261,19 +169,10 @@ import { useSiteStore } from 'src/stores/site'
// COMPONENTS
import
LoadingGeneric
from
'src/components/LoadingGeneric.vue'
import
PageActionsCol
from
'src/components/PageActionsCol.vue'
import
PageHeader
from
'src/components/PageHeader.vue'
import
PageTags
from
'../components/PageTags.vue'
const
sideDialogs
=
{
PageDataDialog
:
defineAsyncComponent
({
loader
:
()
=>
import
(
'../components/PageDataDialog.vue'
),
loadingComponent
:
LoadingGeneric
}),
PagePropertiesDialog
:
defineAsyncComponent
({
loader
:
()
=>
import
(
'../components/PagePropertiesDialog.vue'
),
loadingComponent
:
LoadingGeneric
})
}
import
PageTags
from
'src/components/PageTags.vue'
import
SideDialog
from
'src/components/SideDialog.vue'
const
editorComponents
=
{
markdown
:
defineAsyncComponent
({
...
...
@@ -364,10 +263,14 @@ watch(() => route.path, async (newValue) => {
await
pageStore
.
pageLoad
({
path
:
newValue
})
}
catch
(
err
)
{
if
(
err
.
message
===
'ERR_PAGE_NOT_FOUND'
)
{
$q
.
notify
({
type
:
'negative'
,
message
:
'This page does not exist (yet)!'
})
if
(
newValue
===
'/'
)
{
siteStore
.
overlay
=
'Welcome'
}
else
{
$q
.
notify
({
type
:
'negative'
,
message
:
'This page does not exist (yet)!'
})
}
}
else
{
$q
.
notify
({
type
:
'negative'
,
...
...
@@ -382,58 +285,6 @@ watch(() => pageStore.tocDepth, () => { refreshTocExpanded() })
// METHODS
function
togglePageProperties
()
{
state
.
sideDialogComponent
=
'PagePropertiesDialog'
state
.
showSideDialog
=
true
}
function
togglePageData
()
{
state
.
sideDialogComponent
=
'PageDataDialog'
state
.
showSideDialog
=
true
}
function
duplicatePage
()
{
$q
.
dialog
({
component
:
defineAsyncComponent
(()
=>
import
(
'../components/TreeBrowserDialog.vue'
)),
componentProps
:
{
mode
:
'duplicatePage'
,
folderPath
:
''
,
itemId
:
pageStore
.
id
,
itemTitle
:
pageStore
.
title
,
itemFileName
:
pageStore
.
path
}
}).
onOk
(()
=>
{
// TODO: change route to new location
})
}
function
renamePage
()
{
$q
.
dialog
({
component
:
defineAsyncComponent
(()
=>
import
(
'../components/TreeBrowserDialog.vue'
)),
componentProps
:
{
mode
:
'renamePage'
,
folderPath
:
''
,
itemId
:
pageStore
.
id
,
itemTitle
:
pageStore
.
title
,
itemFileName
:
pageStore
.
path
}
}).
onOk
(()
=>
{
// TODO: change route to new location
})
}
function
deletePage
()
{
$q
.
dialog
({
component
:
defineAsyncComponent
(()
=>
import
(
'../components/PageDeleteDialog.vue'
)),
componentProps
:
{
pageId
:
pageStore
.
id
,
pageName
:
pageStore
.
title
}
}).
onOk
(()
=>
{
router
.
replace
(
'/'
)
})
}
function
refreshTocExpanded
(
baseToc
,
lvl
)
{
const
toExpand
=
[]
let
isRootNode
=
false
...
...
@@ -538,16 +389,6 @@ function refreshTocExpanded (baseToc, lvl) {
}
}
}
.page-actions
{
flex
:
0
0
56px
;
@at-root
.body--light
&
{
background-color
:
$grey-3
;
}
@at-root
.body--dark
&
{
background-color
:
$dark-4
;
}
}
.floating-syncpanel
{
.q-dialog__inner
{
...
...
@@ -570,59 +411,6 @@ function refreshTocExpanded (baseToc, lvl) {
}
}
.floating-sidepanel
{
.q-dialog__inner
{
right
:
24px
;
.q-card
{
border-radius
:
4px
!
important
;
min-width
:
450px
;
.q-card__section
{
border-radius
:
0
;
}
}
}
.alt-card
{
@at-root
.body--light
&
{
background-color
:
$grey-2
;
border-top
:
1px
solid
$grey-4
;
box-shadow
:
inset
0
1px
0
0
#FFF
,
inset
0
-1px
0
0
#FFF
;
border-bottom
:
1px
solid
$grey-4
;
}
@at-root
.body--dark
&
{
background-color
:
$dark-4
;
border-top
:
1px
solid
lighten
(
$dark-3
,
8%
);
box-shadow
:
inset
0
1px
0
0
$dark-6
,
inset
0
-1px
0
0
$dark-6
;
border-bottom
:
1px
solid
lighten
(
$dark-3
,
8%
);
}
}
&
-quickaccess
{
width
:
40px
;
border-radius
:
4px
!
important
;
background-color
:
rgba
(
0
,
0
,
0
,.
75
);
backdrop-filter
:
blur
(
5px
);
color
:
#FFF
;
position
:
fixed
;
right
:
486px
;
top
:
74px
;
z-index
:
-1
;
display
:
flex
;
flex-direction
:
column
;
box-shadow
:
0
0
5px
0
rgba
(
0
,
0
,
0
,.
5
)
!
important
;
@at-root
.q-transition--jump-left-enter-active
&
{
display
:
none
!
important
;
}
@at-root
.q-transition--jump-right-leave-active
&
{
display
:
none
!
important
;
}
}
}
.q-card
{
@at-root
.body--light
&
{
background-color
:
#FFF
;
...
...
ux/src/router/routes.js
View file @
d2a18eca
...
...
@@ -4,8 +4,8 @@ const routes = [
path
:
'/'
,
component
:
()
=>
import
(
'../layouts/MainLayout.vue'
),
children
:
[
{
path
:
''
,
component
:
()
=>
import
(
'../pages/Index.vue'
)
}
// { path: 'n
/:editor?', component: () => import('../pages/Index.vue') }
{
path
:
''
,
component
:
()
=>
import
(
'../pages/Index.vue'
)
}
,
{
path
:
'_create
/:editor?'
,
component
:
()
=>
import
(
'../pages/Index.vue'
)
}
]
},
{
...
...
@@ -62,10 +62,6 @@ const routes = [
]
},
{
path
:
'/_welcome'
,
component
:
()
=>
import
(
'pages/Welcome.vue'
)
},
{
path
:
'/_error/:action?'
,
component
:
()
=>
import
(
'pages/ErrorGeneric.vue'
)
},
...
...
ux/src/stores/page.js
View file @
d2a18eca
...
...
@@ -191,7 +191,7 @@ export const usePageStore = defineStore('page', {
// -> Page Data
this
.
id
=
0
this
.
locale
=
locale
||
this
.
locale
if
(
path
)
{
if
(
path
||
path
===
''
)
{
this
.
path
=
path
}
else
{
this
.
path
=
this
.
path
.
length
<
2
?
'new-page'
:
`
${
this
.
path
}
/new-page`
...
...
@@ -199,7 +199,7 @@ export const usePageStore = defineStore('page', {
this
.
title
=
''
this
.
description
=
''
this
.
icon
=
'las la-file-alt'
this
.
isPublished
=
false
this
.
publishState
=
'published'
this
.
relations
=
[]
this
.
tags
=
[]
...
...
ux/src/stores/site.js
View file @
d2a18eca
...
...
@@ -60,6 +60,8 @@ export const useSiteStore = defineStore('site', {
width
:
'9px'
,
opacity
:
1
},
sideDialogShown
:
false
,
sideDialogComponent
:
''
,
docsBase
:
'https://next.js.wiki/docs'
}),
getters
:
{
...
...
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