refactor: moved server content to /server
This commit is contained in:
74
server/views/auth/login.pug
Normal file
74
server/views/auth/login.pug
Normal file
@@ -0,0 +1,74 @@
|
||||
doctype html
|
||||
html(data-logic='login')
|
||||
head
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(charset='UTF-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||
meta(name='theme-color', content='#009688')
|
||||
meta(name='msapplication-TileColor', content='#009688')
|
||||
meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
|
||||
title= appconfig.title
|
||||
|
||||
// Favicon
|
||||
each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
|
||||
link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png')
|
||||
each favsize in [32, 96, 16]
|
||||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='manifest', href='/manifest.json')
|
||||
|
||||
// JS / CSS
|
||||
script(type='text/javascript', src='/js/bundle.min.js')
|
||||
|
||||
body
|
||||
#bg
|
||||
each bg in _.sampleSize([1, 2, 3],3)
|
||||
div(style='background-image:url(/images/bg_' + bg + '.jpg);')
|
||||
#root
|
||||
h1= appconfig.title
|
||||
h2 Login required
|
||||
if appflash.length > 0
|
||||
h3
|
||||
i.icon-warning-outline
|
||||
= appflash[0].title
|
||||
h4= appflash[0].message
|
||||
if appconfig.auth.local.enabled
|
||||
form(method='post', action='/login')
|
||||
input#login-user(type='text', name='email', placeholder='Email / Username')
|
||||
input#login-pass(type='password', name='password', placeholder='Password')
|
||||
button(type='submit') Log In
|
||||
if appconfig.authStrategies.socialEnabled
|
||||
#social
|
||||
if appconfig.auth.local.enabled
|
||||
span Or, log in using...
|
||||
else
|
||||
span Log in using...
|
||||
if appconfig.auth.microsoft && appconfig.auth.microsoft.enabled
|
||||
button.ms(onclick='window.location.assign("/login/ms")')
|
||||
i.icon-windows2
|
||||
span Microsoft Account
|
||||
if appconfig.auth.azure && appconfig.auth.azure.enabled
|
||||
button.ms(onclick='window.location.assign("/login/azure")')
|
||||
i.icon-windows2
|
||||
span Azure AD
|
||||
if appconfig.auth.google && appconfig.auth.google.enabled
|
||||
button.google(onclick='window.location.assign("/login/google")')
|
||||
i.icon-google
|
||||
span Google ID
|
||||
if appconfig.auth.facebook && appconfig.auth.facebook.enabled
|
||||
button.facebook(onclick='window.location.assign("/login/facebook")')
|
||||
i.icon-facebook
|
||||
span Facebook
|
||||
if appconfig.auth.github && appconfig.auth.github.enabled
|
||||
button.github(onclick='window.location.assign("/login/github")')
|
||||
i.icon-github
|
||||
span GitHub
|
||||
if appconfig.auth.slack && appconfig.auth.slack.enabled
|
||||
button.slack(onclick='window.location.assign("/login/slack")')
|
||||
i.icon-slack
|
||||
span Slack
|
||||
#copyright
|
||||
= t('footer.poweredby') + ' '
|
||||
a.icon(href='https://github.com/Requarks/wiki')
|
||||
i.icon-github
|
||||
a(href='https://wiki.requarks.io/') Wiki.js
|
||||
14
server/views/common/alerts.pug
Normal file
14
server/views/common/alerts.pug
Normal file
@@ -0,0 +1,14 @@
|
||||
#alerts
|
||||
ul
|
||||
template(v-for='aItem in children', track-by='_uid')
|
||||
li(v-bind:class='aItem.class')
|
||||
button(v-on:click='acknowledge(aItem._uid)')
|
||||
strong {{ aItem.title }}
|
||||
span {{ aItem.message }}
|
||||
|
||||
if appflash.length > 0
|
||||
script(type='text/javascript').
|
||||
var alertsData = !{JSON.stringify(appflash)};
|
||||
else
|
||||
script(type='text/javascript').
|
||||
var alertsData = [];
|
||||
8
server/views/common/footer.pug
Normal file
8
server/views/common/footer.pug
Normal file
@@ -0,0 +1,8 @@
|
||||
footer.footer
|
||||
span
|
||||
= t('footer.poweredby') + ' '
|
||||
a(href='https://github.com/Requarks/wiki') Wiki.js
|
||||
| .
|
||||
ul
|
||||
li: a(href='/')= t('footer.home')
|
||||
li: a(href='#root')= t('footer.top')
|
||||
34
server/views/common/header.pug
Normal file
34
server/views/common/header.pug
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
#header-container
|
||||
nav.nav.stickyscroll#header
|
||||
.nav-left
|
||||
block rootNavLeft
|
||||
a.nav-item(href='/')
|
||||
h1
|
||||
i.icon-layers
|
||||
= appconfig.title
|
||||
.nav-center
|
||||
block rootNavCenter
|
||||
.nav-item
|
||||
p.control(v-bind:class='{ "is-loading": searchload > 0 }')
|
||||
input.input#search-input(type='text', v-model='searchq', @keyup.esc='closeSearch', @keyup.down='moveDownSearch', @keyup.up='moveUpSearch', @keyup.enter='moveSelectSearch', debounce='400', placeholder='Search...')
|
||||
span.nav-toggle
|
||||
span
|
||||
span
|
||||
span
|
||||
.nav-right
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
|
||||
transition(name='searchresults-anim', enter-active-class='slideInDown', leave-active-class='fadeOutUp')
|
||||
.searchresults.animated(v-show='searchactive', v-cloak, style={'display':'none'})
|
||||
p.searchresults-label Search Results
|
||||
ul.searchresults-list
|
||||
li(v-if='searchres.length === 0')
|
||||
a: em No results matching your query
|
||||
li(v-for='sres in searchres', v-bind:class='{ "is-active": searchmovekey === "res." + sres.entryPath }')
|
||||
a(v-bind:href='"/" + sres.entryPath') {{ sres.title }}
|
||||
p.searchresults-label(v-if='searchsuggest.length > 0') Did you mean...?
|
||||
ul.searchresults-list(v-if='searchsuggest.length > 0')
|
||||
li(v-for='sug in searchsuggest', v-bind:class='{ "is-active": searchmovekey === "sug." + sug }')
|
||||
a(v-on:click='useSuggestion(sug)') {{ sug }}
|
||||
0
server/views/common/mixins.pug
Normal file
0
server/views/common/mixins.pug
Normal file
383
server/views/configure/index.pug
Normal file
383
server/views/configure/index.pug
Normal file
@@ -0,0 +1,383 @@
|
||||
doctype html
|
||||
html(data-logic='configure')
|
||||
head
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(charset='UTF-8')
|
||||
title Wiki.js | Configure
|
||||
|
||||
// Favicon
|
||||
each favsize in [32, 96, 16]
|
||||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
|
||||
|
||||
// JS / CSS
|
||||
script(type='text/javascript').
|
||||
var appconfig = !{JSON.stringify(conf)};
|
||||
script(type='text/javascript', src='/js/configure.min.js')
|
||||
|
||||
body
|
||||
#root
|
||||
#header-container
|
||||
nav.nav#header
|
||||
.nav-left
|
||||
a.nav-item
|
||||
h1
|
||||
i.icon-layers
|
||||
| Wiki.js
|
||||
main
|
||||
.container
|
||||
transition(name='tst-welcome')
|
||||
.welcome(v-if='state === "welcome" || state === "restart"')
|
||||
img(src='/images/logo.png', alt='Wiki.js')
|
||||
h2 A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown
|
||||
.content(v-cloak)
|
||||
|
||||
//- ==============================================
|
||||
//- WELCOME
|
||||
//- ==============================================
|
||||
|
||||
template(v-if='state === "welcome"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Welcome!
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p This installation wizard will guide you through the steps needed to get your wiki up and running in no time!
|
||||
p Detailed information about installation and usage can be found on the #[a(href='https://docs.wiki.requarks.io/') official documentation site]. #[br] Should you have any question or would like to report something that doesn't look right, feel free to create a new issue on the #[a(href='https://github.com/Requarks/wiki/issues') GitHub project].
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Start
|
||||
|
||||
//- ==============================================
|
||||
//- SYSTEM CHECK
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "syscheck"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span System Check
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Checking your system for compatibility...
|
||||
p(v-if='!loading && syscheck.ok')
|
||||
ul
|
||||
li(v-for='rs in syscheck.results') #[i.icon-check] {{rs}}
|
||||
p(v-if='!loading && syscheck.ok')
|
||||
i.icon-check
|
||||
strong Looks good! No issues so far.
|
||||
p(v-if='!loading && !syscheck.ok') #[i.icon-square-cross] Error: {{ syscheck.error }}
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back
|
||||
button.button.is-teal(v-on:click='proceedToSyscheck', v-if='!loading && !syscheck.ok') Check Again
|
||||
button.button.is-light-blue(v-on:click='proceedToGeneral', v-if='loading || syscheck.ok', v-bind:disabled='loading') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- GENERAL
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "general"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span General
|
||||
i(v-if='loading')
|
||||
.panel-content.form-sections
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
label.label Site Title
|
||||
input(type='text', placeholder='e.g. Wiki', v-model='conf.title', data-vv-scope='general', name='ipt-title', v-validate='{ required: true, min: 2 }')
|
||||
span.desc The site title will appear in the top left corner on every page and within the window title bar.
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
label.label Host
|
||||
input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, url: true }')
|
||||
span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are not supported.
|
||||
section
|
||||
p.control
|
||||
label.label Port
|
||||
input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true, numeric: true, min_value: 0, max_value: 65535 }')
|
||||
span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>0</strong> to use $PORT system environment variable.
|
||||
section
|
||||
p.control
|
||||
label.label Site UI Language
|
||||
select(v-model='conf.lang')
|
||||
each lg in langs
|
||||
option(value=lg.id)= lg.name
|
||||
span.desc The language in which navigation, help and other UI elements will be displayed.
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
input#ipt-public(type='checkbox', v-model='conf.public', data-vv-scope='general', name='ipt-public')
|
||||
label.label(for='ipt-public') Public Access
|
||||
span.desc Should the site be accessible (read only) without login.
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back
|
||||
button.button.is-light-blue(v-on:click='proceedToConsiderations', v-bind:disabled='loading || errors.any("general")') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- CONSIDERATIONS
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "considerations"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Important Considerations
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
h3 Is Wiki.js going to be behind a web server (e.g. nginx / apache / IIS) or proxy?
|
||||
p
|
||||
ul
|
||||
li - Make sure the upload limit is sufficient. Most web servers have a low limit (e.g. 2 MB) by default.
|
||||
li - Make sure your web server is configured to allow web sockets. Wiki.js will fallback to standard XHR queries if not available.
|
||||
li - Do not rewrite URLs after the domain. This can cause unexpected issues in Wiki.js navigation.
|
||||
li - Do not remove or alter the client IP when proxying the requests. This can cause the authentication brute force protection to engage unexpectedly.
|
||||
template(v-if='considerations.https')
|
||||
h3 The site will not be using HTTPS? #[i.icon-warning-outline.animated.fadeOut.infinite]
|
||||
p The host URL you specified is not HTTPS. It is highly recommended to use HTTPS. You must use a web server / proxy (e.g. nginx / apache / IIS) in front of Wiki.js to use HTTPS. Wiki.js does not provide HTTPS handling by itself.
|
||||
template(v-if='considerations.port')
|
||||
h3 You are using a non-standard port.
|
||||
p If you are not planning on using a web server / proxy in front of Wiki.js, be aware that users will need to specify the port when accessing the wiki. Make sure this is the intended behavior. Otherwise set a standard HTTP port such as 80.
|
||||
template(v-if='considerations.localhost')
|
||||
h3 Are you sure you want to use localhost as the host base URL? #[i.icon-warning-outline.animated.fadeOut.infinite]
|
||||
p The host URL you specified is localhost. Unless you are a developer running Wiki.js locally on your machine, this is not recommended!
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back
|
||||
button.button.is-light-blue(v-on:click='proceedToDb', v-bind:disabled='loading') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- DATABASE
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "db"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Database
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p Wiki.js stores administrative data such as users, permissions and assets metadata in a MongoDB database. Article contents and uploads are <u>not</u> stored in the DB. Instead, they are stored on-disk and synced automatically with a remote git repository of your choice.
|
||||
.panel-content.form-sections
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
label.label MongoDB Connection String
|
||||
input(type='text', placeholder='e.g. mongodb://localhost:27017/wiki', v-model='conf.db', data-vv-scope='db', name='ipt-db', v-validate='{ required: true, min: 3 }')
|
||||
span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.<br />You can also specify an environment variable as the connection string (e.g. $MONGO_URI).
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back
|
||||
button.button.is-light-blue(v-on:click='proceedToDbcheck', v-bind:disabled='loading || errors.any("db")') Connect
|
||||
|
||||
//- ==============================================
|
||||
//- DATABASE CHECK
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "dbcheck"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Database Check
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Testing the connection to MongoDB...
|
||||
p(v-if='!loading && dbcheck.ok')
|
||||
i.icon-check
|
||||
strong Connected successfully!
|
||||
p(v-if='!loading && !dbcheck.ok') #[i.icon-square-cross] Error: {{ dbcheck.error }}
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back
|
||||
button.button.is-teal(v-on:click='proceedToDbcheck', v-if='!loading && !dbcheck.ok') Try Again
|
||||
button.button.is-light-blue(v-on:click='proceedToPaths', v-if='loading || dbcheck.ok', v-bind:disabled='loading') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- PATHS
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "paths"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Paths
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p It is recommended to leave the default values.
|
||||
.panel-content.form-sections
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
label.label Local Data Path
|
||||
input(type='text', placeholder='e.g. ./data', v-model='conf.pathData', data-vv-scope='paths', name='ipt-datapath', v-validate='{ required: true, min: 2 }')
|
||||
span.desc The path where cache (processed content, thumbnails, search index, etc.) will be stored on disk.
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
label.label Local Repository Path
|
||||
input(type='text', placeholder='e.g. ./repo', v-model='conf.pathRepo', data-vv-scope='paths', name='ipt-repopath', v-validate='{ required: true, min: 2 }')
|
||||
span.desc The path where the local git repository will be created, used to store content in markdown files and uploads.
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToDb', v-bind:disabled='loading') Back
|
||||
button.button.is-light-blue(v-on:click='proceedToGit', v-bind:disabled='loading || errors.any("paths")') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- GIT
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "git"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Git Repository
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p Wiki.js stores article content and uploads locally on disk. All content is then regularly kept in sync with a remote git repository. This acts a backup protection and provides history / revert features. While optional, it is <strong>HIGHLY</strong> recommended to setup the remote git repository connection.
|
||||
.panel-content.form-sections
|
||||
section.columns
|
||||
.column.is-two-thirds
|
||||
p.control.is-fullwidth
|
||||
label.label Repository URL
|
||||
input(type='text', placeholder='e.g. git@github.com/org/repo.git or https://github.com/org/repo', v-model='conf.gitUrl', data-vv-scope='git', name='ipt-giturl', v-validate='{ required: true, min: 5 }')
|
||||
span.desc The full git repository URL to connect to.
|
||||
.column
|
||||
p.control.is-fullwidth
|
||||
label.label Branch
|
||||
input(type='text', placeholder='e.g. master', v-model='conf.gitBranch', data-vv-scope='git', name='ipt-gitbranch', v-validate='{ required: true, min: 2 }')
|
||||
span.desc The git branch to use when synchronizing changes.
|
||||
section.columns
|
||||
.column.is-one-third
|
||||
p.control.is-fullwidth
|
||||
label.label Authentication
|
||||
select(v-model='conf.gitAuthType')
|
||||
option(value='ssh') SSH (recommended)
|
||||
option(value='basic') Basic
|
||||
span.desc The authentication method used to connect to your remote Git repository.
|
||||
p.control.is-fullwidth
|
||||
input#ipt-git-verify-ssl(type='checkbox', v-model='conf.gitAuthSSL')
|
||||
label.label(for='ipt-git-verify-ssl') Verify SSL
|
||||
.column(v-show='conf.gitAuthType === "basic"')
|
||||
p.control.is-fullwidth
|
||||
label.label Username
|
||||
input(type='text', v-model='conf.gitAuthUser')
|
||||
span.desc The username for the remote git connection.
|
||||
.column(v-show='conf.gitAuthType === "basic"')
|
||||
p.control.is-fullwidth
|
||||
label.label Password
|
||||
input(type='password', v-model='conf.gitAuthPass')
|
||||
span.desc The password for the remote git connection.
|
||||
.column(v-show='conf.gitAuthType === "ssh"')
|
||||
p.control.is-fullwidth
|
||||
label.label Private Key location
|
||||
input(type='text', placeholder='e.g. /etc/wiki/keys/git.pem', v-model='conf.gitAuthSSHKey')
|
||||
span.desc The full path to the private key on disk.
|
||||
section.columns
|
||||
.column
|
||||
p.control.is-fullwidth
|
||||
label.label Sync User Name
|
||||
input(type='text', placeholder='e.g. John Smith', v-model.number='conf.gitSignatureName', data-vv-scope='git', name='ipt-gitsigname', v-validate='{ required: true }')
|
||||
span.desc The name to use when pushing commits to the git repository.
|
||||
.column
|
||||
p.control.is-fullwidth
|
||||
label.label Sync User Email
|
||||
input(type='text', placeholder='e.g. user@example.com', v-model.number='conf.gitSignatureEmail', data-vv-scope='git', name='ipt-gitsigemail', v-validate='{ required: true, email: true }')
|
||||
span.desc The email to use when pushing commits to the git repository.
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToPaths', v-bind:disabled='loading') Back
|
||||
button.button.is-light-blue.is-outlined(v-on:click='conf.gitUseRemote = false; proceedToGitCheck()', v-bind:disabled='loading') Skip this step
|
||||
button.button.is-light-blue(v-on:click='conf.gitUseRemote = true; proceedToGitCheck()', v-bind:disabled='loading || errors.any("git")') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- GIT CHECK
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "gitcheck"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Git Repository Check
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Verifying Git repository settings...
|
||||
p(v-if='!loading && gitcheck.ok')
|
||||
ul
|
||||
li(v-for='rs in gitcheck.results') #[i.icon-check] {{rs}}
|
||||
p(v-if='!loading && gitcheck.ok')
|
||||
i.icon-check
|
||||
strong Git settings are correct!
|
||||
p(v-if='!loading && !gitcheck.ok') #[i.icon-square-cross] Error: {{ gitcheck.error }}
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back
|
||||
button.button.is-teal(v-on:click='proceedToGitCheck', v-if='!loading && !gitcheck.ok') Try Again
|
||||
button.button.is-light-blue(v-on:click='proceedToAdmin', v-if='loading || gitcheck.ok', v-bind:disabled='loading') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- ADMINISTRATOR ACCOUNT
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "admin"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Administrator Account
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p An administrator account will be created for local authentication. From this account, you can create or authorize more users.
|
||||
.panel-content.form-sections
|
||||
section
|
||||
p.control.is-fullwidth
|
||||
label.label Administrator Email
|
||||
input(type='text', placeholder='e.g. admin@example.com', v-model='conf.adminEmail', data-vv-scope='admin', name='ipt-adminemail', v-validate='{ required: true, email: true }')
|
||||
span.desc The email address of the administrator account
|
||||
section.columns
|
||||
.column
|
||||
p.control.is-fullwidth
|
||||
label.label Password
|
||||
input(type='password', v-model='conf.adminPassword', data-vv-scope='admin', name='ipt-adminpwd', v-validate='{ required: true, min: 8 }')
|
||||
span.desc At least 8 characters long.
|
||||
.column
|
||||
p.control.is-fullwidth
|
||||
label.label Confirm Password
|
||||
input(type='password', v-model='conf.adminPasswordConfirm', data-vv-scope='admin', name='ipt-adminpwd2', v-validate='{ required: true, confirmed: "ipt-adminpwd" }')
|
||||
span.desc Verify your password again.
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToGit', v-bind:disabled='loading') Back
|
||||
button.button.is-light-blue(v-on:click='proceedToFinal', v-bind:disabled='loading || errors.any("admin")') Continue
|
||||
|
||||
//- ==============================================
|
||||
//- FINAL
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "final"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Finalizing
|
||||
i(v-if='loading')
|
||||
.panel-content.is-text
|
||||
p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Finalizing your installation...
|
||||
p(v-if='!loading && final.ok')
|
||||
i.icon-check
|
||||
strong Wiki.js was configured successfully and is now ready for use.
|
||||
p(v-if='!loading && final.ok')
|
||||
| Click the <strong>Start</strong> button below to start the Wiki.js server.
|
||||
p(v-if='!loading && !final.ok') #[i.icon-square-cross] Error: {{ final.error }}
|
||||
.panel-footer
|
||||
.progress-bar: div(v-bind:style='{width: currentProgress}')
|
||||
button.button.is-light-blue.is-outlined(v-on:click='proceedToAdmin', v-bind:disabled='loading') Back
|
||||
button.button.is-teal(v-on:click='proceedToFinal', v-if='!loading && !final.ok') Try Again
|
||||
button.button.is-green(v-on:click='finish', v-if='loading || final.ok', v-bind:disabled='loading') Start
|
||||
|
||||
//- ==============================================
|
||||
//- RESTART
|
||||
//- ==============================================
|
||||
|
||||
template(v-else-if='state === "restart"')
|
||||
.panel
|
||||
h2.panel-title.is-featured
|
||||
span Restarting...
|
||||
i
|
||||
.panel-content.is-text
|
||||
p #[i.icon-loader.animated.rotateIn.infinite] Restarting Wiki.js in normal mode...
|
||||
p You'll automatically be redirected to the homepage when ready. This usually takes about 30 seconds.
|
||||
.panel-footer
|
||||
button.button.is-green(disabled='disabled') Start
|
||||
|
||||
footer.footer
|
||||
span
|
||||
| Powered by
|
||||
a(href='https://github.com/Requarks/wiki') Wiki.js
|
||||
| .
|
||||
block outside
|
||||
29
server/views/error-forbidden.pug
Normal file
29
server/views/error-forbidden.pug
Normal file
@@ -0,0 +1,29 @@
|
||||
doctype html
|
||||
html(data-logic='error')
|
||||
head
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(charset='UTF-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||
meta(name='theme-color', content='#009688')
|
||||
meta(name='msapplication-TileColor', content='#009688')
|
||||
meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
|
||||
title= appconfig.title
|
||||
|
||||
// Favicon
|
||||
each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
|
||||
link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png')
|
||||
each favsize in [32, 96, 16]
|
||||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='manifest', href='/manifest.json')
|
||||
|
||||
// JS / CSS
|
||||
script(type='text/javascript', src='/js/bundle.min.js')
|
||||
|
||||
body(class='is-forbidden')
|
||||
.container
|
||||
a(href='/'): img(src='/favicons/android-icon-96x96.png')
|
||||
h1 Forbidden
|
||||
h2 Sorry, you don't have the necessary permissions to access this page.
|
||||
a.button.is-amber.is-inverted(href='/') Go Home
|
||||
a.button.is-amber.is-inverted(href='/login') Login as...
|
||||
29
server/views/error-notexist.pug
Normal file
29
server/views/error-notexist.pug
Normal file
@@ -0,0 +1,29 @@
|
||||
doctype html
|
||||
html(data-logic='error')
|
||||
head
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(charset='UTF-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||
meta(name='theme-color', content='#009688')
|
||||
meta(name='msapplication-TileColor', content='#009688')
|
||||
meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
|
||||
title= appconfig.title
|
||||
|
||||
// Favicon
|
||||
each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
|
||||
link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png')
|
||||
each favsize in [32, 96, 16]
|
||||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='manifest', href='/manifest.json')
|
||||
|
||||
// JS / CSS
|
||||
script(type='text/javascript', src='/js/bundle.min.js')
|
||||
|
||||
body(class='is-notexist')
|
||||
.container
|
||||
a(href='/'): img(src='/favicons/android-icon-96x96.png')
|
||||
h1= message
|
||||
h2 Would you like to create this entry?
|
||||
a.button.is-amber.is-inverted.is-featured(href='/create/' + newpath) Create
|
||||
a.button.is-amber.is-inverted(href='/') Go Home
|
||||
32
server/views/error.pug
Normal file
32
server/views/error.pug
Normal file
@@ -0,0 +1,32 @@
|
||||
doctype html
|
||||
html(data-logic='error')
|
||||
head
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(charset='UTF-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||
meta(name='theme-color', content='#009688')
|
||||
meta(name='msapplication-TileColor', content='#009688')
|
||||
meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
|
||||
title= appconfig.title
|
||||
|
||||
// Favicon
|
||||
each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
|
||||
link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png')
|
||||
each favsize in [32, 96, 16]
|
||||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='manifest', href='/manifest.json')
|
||||
|
||||
// JS / CSS
|
||||
script(type='text/javascript', src='/js/bundle.min.js')
|
||||
|
||||
body(class='is-error')
|
||||
.container
|
||||
a(href='/'): img(src='/favicons/android-icon-96x96.png')
|
||||
h1= message
|
||||
h2 Oops, something went wrong
|
||||
a.button.is-amber.is-inverted.is-featured(href='/') Go Home
|
||||
|
||||
if error.stack
|
||||
h3 Detailed debug trail:
|
||||
pre: code #{error.stack}
|
||||
33
server/views/layout.pug
Normal file
33
server/views/layout.pug
Normal file
@@ -0,0 +1,33 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(charset='UTF-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1')
|
||||
meta(name='theme-color', content='#009688')
|
||||
meta(name='msapplication-TileColor', content='#009688')
|
||||
meta(name='msapplication-TileImage', content='/favicons/ms-icon-144x144.png')
|
||||
title= appconfig.title
|
||||
|
||||
// Favicon
|
||||
each favsize in [57, 60, 72, 76, 114, 120, 144, 152, 180]
|
||||
link(rel='apple-touch-icon', sizes=favsize + 'x' + favsize, href='/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='icon', type='image/png', sizes='192x192', href='/favicons/android-icon-192x192.png')
|
||||
each favsize in [32, 96, 16]
|
||||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
|
||||
link(rel='manifest', href='/manifest.json')
|
||||
|
||||
// JS / CSS
|
||||
script(type='text/javascript', src='/js/bundle.min.js')
|
||||
|
||||
block head
|
||||
|
||||
body
|
||||
#root.has-stickynav
|
||||
include ./common/header.pug
|
||||
include ./common/alerts.pug
|
||||
main
|
||||
block content
|
||||
include ./common/footer.pug
|
||||
|
||||
block outside
|
||||
39
server/views/modals/admin-createuser.pug
Normal file
39
server/views/modals/admin-createuser.pug
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
.modal#modal-admin-users-create
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-blue
|
||||
span Create / Authorize User
|
||||
p.modal-notify(v-bind:class='{ "is-active": loading }'): i
|
||||
section
|
||||
label.label Email address:
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='e.g. john.doe@company.com', v-model='email')
|
||||
section
|
||||
label.label Provider:
|
||||
p.control.is-fullwidth
|
||||
select(v-model='provider')
|
||||
option(value='local') Local Database
|
||||
if appconfig.auth.microsoft.enabled
|
||||
option(value='windowslive') Microsoft Account
|
||||
if appconfig.auth.google.enabled
|
||||
option(value='google') Google ID
|
||||
if appconfig.auth.facebook.enabled
|
||||
option(value='facebook') Facebook
|
||||
if appconfig.auth.github.enabled
|
||||
option(value='github') GitHub
|
||||
if appconfig.auth.slack.enabled
|
||||
option(value='slack') Slack
|
||||
section(v-if='provider=="local"')
|
||||
label.label Password:
|
||||
p.control.is-fullwidth
|
||||
input.input(type='password', placeholder='', v-model='password')
|
||||
section(v-if='provider=="local"')
|
||||
label.label Full Name:
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='e.g. John Doe', v-model='name')
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard
|
||||
a.button(v-on:click='create', v-if='provider=="local"', v-bind:disabled='loading', v-bind:class='{ "is-disabled": loading, "is-blue": !loading }') Create User
|
||||
a.button(v-on:click='create', v-if='provider!="local"', v-bind:disabled='loading', v-bind:class='{ "is-disabled": loading, "is-blue": !loading }') Authorize User
|
||||
12
server/views/modals/admin-deleteuser.pug
Normal file
12
server/views/modals/admin-deleteuser.pug
Normal file
@@ -0,0 +1,12 @@
|
||||
.modal#modal-admin-users-delete
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-red
|
||||
span Delete User Account?
|
||||
p.modal-notify(v-bind:class='{ "is-active": loading }'): i
|
||||
section
|
||||
span Are you sure you want to delete this user account? This action cannot be undone!
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='cancel') Abort
|
||||
a.button.is-red(v-on:click='deleteUser') Delete
|
||||
25
server/views/modals/admin-upgrade.pug
Normal file
25
server/views/modals/admin-upgrade.pug
Normal file
@@ -0,0 +1,25 @@
|
||||
.modal(v-bind:class='{ "is-active": upgradeModal.state }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
template(v-if='upgradeModal.step === "running"')
|
||||
header.is-blue Install
|
||||
section.modal-loading
|
||||
i
|
||||
span Wiki.js {{ upgradeModal.mode }} in progress...
|
||||
em Please wait
|
||||
template(v-if='upgradeModal.step === "error"')
|
||||
header.is-red Installation Error
|
||||
section.modal-loading
|
||||
span {{ upgradeModal.error }}
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='upgradeCancel') Abort
|
||||
a.button.is-deep-orange(v-on:click='upgradeStart') Try Again
|
||||
template(v-if='upgradeModal.step === "confirm"')
|
||||
header.is-deep-orange Are you sure?
|
||||
section
|
||||
label.label You are about to {{ upgradeModal.mode }} Wiki.js.
|
||||
span.note You will not be able to access your wiki during the operation. Content will not be affected. However, it is your responsability to ensure you have a backup in the unexpected event content gets lost or corrupted.
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='upgradeCancel') Abort
|
||||
a.button.is-deep-orange(v-on:click='upgradeStart') Start
|
||||
10
server/views/modals/create-discard.pug
Normal file
10
server/views/modals/create-discard.pug
Normal file
@@ -0,0 +1,10 @@
|
||||
.modal#modal-create-discard
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-orange Discard?
|
||||
section
|
||||
span Are you sure you want to leave this page and loose anything you wrote so far?
|
||||
footer
|
||||
a.button.is-grey.is-outlined.btn-create-discard Stay on page
|
||||
a.button.is-orange(href='/') Discard
|
||||
14
server/views/modals/create.pug
Normal file
14
server/views/modals/create.pug
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
.modal#modal-create-prompt
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-light-blue Create New Document
|
||||
section
|
||||
label.label Enter the new document path:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-create-prompt(type='text', placeholder='page-name')
|
||||
span.help.is-danger.is-hidden This document path is invalid!
|
||||
footer
|
||||
a.button.is-grey.is-outlined.btn-create-prompt Discard
|
||||
a.button.is-light-blue.btn-create-go Create
|
||||
11
server/views/modals/edit-discard.pug
Normal file
11
server/views/modals/edit-discard.pug
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
.modal#modal-edit-discard
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-orange Discard?
|
||||
section
|
||||
span Are you sure you want to leave this page and loose any modifications?
|
||||
footer
|
||||
a.button.is-grey.is-outlined.btn-edit-discard Stay on page
|
||||
a.button.is-orange(href='/' + pageData.meta.path) Discard
|
||||
23
server/views/modals/editor-codeblock.pug
Normal file
23
server/views/modals/editor-codeblock.pug
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
.modal#modal-editor-codeblock
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content.is-expanded
|
||||
|
||||
header.is-green
|
||||
span Insert Code Block
|
||||
|
||||
section.is-gapless
|
||||
.columns.is-stretched
|
||||
.column.is-one-quarter.modal-sidebar.is-green(style={'max-width':'350px'})
|
||||
.model-sidebar-header Language
|
||||
.model-sidebar-content
|
||||
p.control.is-fullwidth
|
||||
select(v-model='modeSelected')
|
||||
option(v-for='mode in modes', v-bind:value='mode.name') {{ mode.caption }}
|
||||
.column.ace-container
|
||||
#codeblock-editor
|
||||
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard
|
||||
a.button.is-green(v-on:click='insertCode') Insert Code Block
|
||||
80
server/views/modals/editor-file.pug
Normal file
80
server/views/modals/editor-file.pug
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
.modal#modal-editor-file
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content.is-expanded
|
||||
|
||||
header.is-green
|
||||
span Insert File
|
||||
p.modal-notify(v-bind:class='{ "is-active": isLoading }')
|
||||
span {{ isLoadingText }}
|
||||
i
|
||||
.modal-toolbar.is-green
|
||||
a.button(v-on:click='newFolder')
|
||||
i.fa.fa-folder
|
||||
span New Folder
|
||||
a.button#btn-editor-file-upload
|
||||
i.fa.fa-upload
|
||||
span Upload File
|
||||
label
|
||||
input(type='file', multiple)
|
||||
section.is-gapless
|
||||
.columns.is-stretched
|
||||
.column.is-one-quarter.modal-sidebar.is-green(style={'max-width':'350px'})
|
||||
.model-sidebar-header Folders
|
||||
ul.model-sidebar-list
|
||||
li(v-for='fld in folders')
|
||||
a(v-on:click='selectFolder(fld)', v-bind:class='{ "is-active": currentFolder === fld }')
|
||||
i.icon-folder2
|
||||
span / {{ fld }}
|
||||
.column.editor-modal-file-choices
|
||||
figure(v-for='fl in files', v-bind:class='{ "is-active": currentFile === fl._id }', v-on:click='selectFile(fl._id)', v-bind:data-uid='fl._id')
|
||||
i(class='icon-file')
|
||||
span: strong {{ fl.filename }}
|
||||
span {{ fl.mime }}
|
||||
span {{ fl.filesize | filesize }}
|
||||
em(v-show='files.length < 1')
|
||||
i.icon-marquee-minus
|
||||
| This folder is empty.
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard
|
||||
a.button.is-green(v-on:click='insertFileLink') Insert Link to File
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": newFolderShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-light-blue New Folder
|
||||
section
|
||||
label.label Enter the new folder name:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-editor-file-newfoldername(type='text', placeholder='folder name', v-model='newFolderName', v-on:keyup.enter='newFolderCreate', v-on:keyup.esc='newFolderDiscard')
|
||||
span.help.is-danger(v-show='newFolderError') This folder name is invalid!
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='newFolderDiscard') Discard
|
||||
a.button.is-light-blue(v-on:click='newFolderCreate') Create
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": renameFileShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-indigo Rename File
|
||||
section
|
||||
label.label Enter the new filename (without the extension) of the file:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-editor-file-rename(type='text', placeholder='filename', v-model='renameFileFilename')
|
||||
span.help.is-danger.is-hidden This filename is invalid!
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='renameFileDiscard') Discard
|
||||
a.button.is-light-blue(v-on:click='renameFileGo') Rename
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": deleteFileShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-red Delete file?
|
||||
section
|
||||
span Are you sure you want to delete #[strong {{deleteFileFilename}}]?
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='deleteFileWarn(false)') Discard
|
||||
a.button.is-red(v-on:click='deleteFileGo') Delete
|
||||
104
server/views/modals/editor-image.pug
Normal file
104
server/views/modals/editor-image.pug
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
.modal#modal-editor-image
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content.is-expanded
|
||||
|
||||
header.is-green
|
||||
span Insert Image
|
||||
p.modal-notify(v-bind:class='{ "is-active": isLoading }')
|
||||
span {{ isLoadingText }}
|
||||
i
|
||||
.modal-toolbar.is-green
|
||||
a.button(v-on:click='newFolder')
|
||||
i.fa.fa-folder
|
||||
span New Folder
|
||||
a.button#btn-editor-image-upload
|
||||
i.fa.fa-upload
|
||||
span Upload Image
|
||||
label
|
||||
input(type='file', multiple)
|
||||
a.button(v-on:click='fetchFromUrl')
|
||||
i.fa.fa-download
|
||||
span Fetch from URL
|
||||
section.is-gapless
|
||||
.columns.is-stretched
|
||||
.column.is-one-quarter.modal-sidebar.is-green(style={'max-width':'350px'})
|
||||
.model-sidebar-header Folders
|
||||
ul.model-sidebar-list
|
||||
li(v-for='fld in folders')
|
||||
a(v-on:click='selectFolder(fld)', v-bind:class='{ "is-active": currentFolder === fld }')
|
||||
i.icon-folder2
|
||||
span / {{ fld }}
|
||||
.model-sidebar-header Alignment
|
||||
.model-sidebar-content
|
||||
p.control.is-fullwidth
|
||||
select(v-model='currentAlign')
|
||||
option(value='left') Left (default)
|
||||
option(value='center') Centered
|
||||
option(value='right') Right
|
||||
option(value='logo') Page Logo
|
||||
.column.editor-modal-image-choices
|
||||
figure(v-for='img in images', v-bind:class='{ "is-active": currentImage === img._id }', v-on:click='selectImage(img._id)', v-bind:data-uid='img._id')
|
||||
img(v-bind:src='"/uploads/t/" + img._id + ".png"')
|
||||
span: strong {{ img.basename }}
|
||||
span {{ img.filesize | filesize }}
|
||||
em(v-show='images.length < 1')
|
||||
i.icon-marquee-minus
|
||||
| This folder is empty.
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard
|
||||
a.button.is-green(v-on:click='insertImage') Insert Image
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": newFolderShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-light-blue New Folder
|
||||
section
|
||||
label.label Enter the new folder name:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-editor-image-newfoldername(type='text', placeholder='folder name', v-model='newFolderName', v-on:keyup.enter='newFolderCreate', v-on:keyup.esc='newFolderDiscard')
|
||||
span.help.is-danger(v-show='newFolderError') This folder name is invalid!
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='newFolderDiscard') Discard
|
||||
a.button.is-light-blue(v-on:click='newFolderCreate') Create
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": fetchFromUrlShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-light-blue Fetch Image from URL
|
||||
section
|
||||
label.label Enter full URL path to the image:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-editor-image-fetchurl(type='text', placeholder='http://www.example.com/some-image.png', v-model='fetchFromUrlURL')
|
||||
span.help.is-danger.is-hidden This URL path is invalid!
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='fetchFromUrlDiscard') Discard
|
||||
a.button.is-light-blue(v-on:click='fetchFromUrlGo') Fetch
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": renameImageShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-indigo Rename Image
|
||||
section
|
||||
label.label Enter the new filename (without the extension) of the image:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-editor-image-rename(type='text', placeholder='filename', v-model='renameImageFilename')
|
||||
span.help.is-danger.is-hidden This filename is invalid!
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='renameImageDiscard') Discard
|
||||
a.button.is-light-blue(v-on:click='renameImageGo') Rename
|
||||
|
||||
.modal.is-superimposed(v-bind:class='{ "is-active": deleteImageShow }')
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-red Delete image?
|
||||
section
|
||||
span Are you sure you want to delete #[strong {{deleteImageFilename}}]?
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='deleteImageWarn(false)') Discard
|
||||
a.button.is-red(v-on:click='deleteImageGo') Delete
|
||||
33
server/views/modals/editor-link.pug
Normal file
33
server/views/modals/editor-link.pug
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
//.modallayer#modal-editor-link
|
||||
.modallayer-content
|
||||
.tabs.is-boxed
|
||||
ul
|
||||
li
|
||||
a
|
||||
span.icon.is-small
|
||||
i.fa.fa-file-text-o
|
||||
span Internal Document Link
|
||||
li.is-active
|
||||
a
|
||||
span.icon.is-small
|
||||
i.fa.fa-external-link
|
||||
span External Link
|
||||
.columns.is-hidden
|
||||
.column
|
||||
label.label Text to display
|
||||
p.control
|
||||
input.input(type='text', placeholder='Text input')
|
||||
.column
|
||||
label.label Link
|
||||
p.control
|
||||
input.input(type='text', placeholder='http://')
|
||||
.columns
|
||||
.column
|
||||
label.label Text to display
|
||||
p.control
|
||||
input.input(type='text', placeholder='Text input')
|
||||
.column
|
||||
label.label Link
|
||||
p.control
|
||||
input.input(type='text', placeholder='http://')
|
||||
28
server/views/modals/editor-video.pug
Normal file
28
server/views/modals/editor-video.pug
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
.modal#modal-editor-video
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-green Insert Video Player
|
||||
section
|
||||
label.label Enter the link to the video to be embedded:
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='https://www.youtube.com/watch?v=xxxxxxxxxxx', v-model='link')
|
||||
span.help.is-red.is-hidden This URL is invalid or not supported!
|
||||
.note The following are supported:
|
||||
ul
|
||||
li
|
||||
i.icon-youtube-play
|
||||
span Youtube
|
||||
li
|
||||
i.icon-vimeo
|
||||
span Vimeo
|
||||
li
|
||||
i.icon-film
|
||||
span Dailymotion
|
||||
li
|
||||
i.icon-video
|
||||
span Any standard MP4 file
|
||||
footer
|
||||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard
|
||||
a.button.is-green(v-on:click='insertVideo') Insert Video
|
||||
15
server/views/modals/move.pug
Normal file
15
server/views/modals/move.pug
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
.modal#modal-move-prompt
|
||||
.modal-background
|
||||
.modal-container
|
||||
.modal-content
|
||||
header.is-indigo Move document
|
||||
section
|
||||
label.label Enter the new document path:
|
||||
p.control.is-fullwidth
|
||||
input.input#txt-move-prompt(type='text', placeholder='page-name')
|
||||
span.help.is-red.is-hidden This document path is invalid or not allowed!
|
||||
span.note Note that moving or renaming documents can lead to broken links. Make sure to edit any page that links to this document afterwards!
|
||||
footer
|
||||
a.button.is-grey.is-outlined.btn-move-prompt Discard
|
||||
a.button.is-indigo.btn-move-go Move
|
||||
57
server/views/pages/admin/_layout.pug
Normal file
57
server/views/pages/admin/_layout.pug
Normal file
@@ -0,0 +1,57 @@
|
||||
extends ../../layout.pug
|
||||
|
||||
block rootNavCenter
|
||||
h2.nav-item Account
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
.nav-item
|
||||
a.button.btn-edit-discard(href='/')
|
||||
i.icon-home
|
||||
span Home
|
||||
|
||||
block content
|
||||
|
||||
#page-type-account
|
||||
.container.is-fluid
|
||||
.columns.is-gapless
|
||||
|
||||
.column.is-narrow.is-hidden-touch.sidebar
|
||||
|
||||
aside
|
||||
.sidebar-label
|
||||
span Navigation
|
||||
ul.sidebar-menu
|
||||
li
|
||||
a(href='/')
|
||||
i.icon-home
|
||||
span Home
|
||||
|
||||
aside
|
||||
.sidebar-label
|
||||
span Account
|
||||
ul.sidebar-menu
|
||||
li
|
||||
a(href='/admin/profile')
|
||||
i.icon-user
|
||||
span My Profile
|
||||
li
|
||||
a(href='/admin/stats')
|
||||
i.icon-bar-graph-2
|
||||
span Stats
|
||||
if rights.manage
|
||||
li
|
||||
a(href='/admin/users')
|
||||
i.icon-users
|
||||
span Users
|
||||
li
|
||||
a(href='/admin/settings')
|
||||
i.icon-cog
|
||||
span System Settings
|
||||
li
|
||||
a(href='/logout')
|
||||
i.icon-delete2
|
||||
span Logout
|
||||
|
||||
.column
|
||||
block adminContent
|
||||
53
server/views/pages/admin/profile.pug
Normal file
53
server/views/pages/admin/profile.pug
Normal file
@@ -0,0 +1,53 @@
|
||||
extends ./_layout.pug
|
||||
|
||||
block adminContent
|
||||
#page-type-admin-profile
|
||||
.hero
|
||||
h1.title#title My Profile
|
||||
h2.subtitle Profile and authentication info
|
||||
.form-sections
|
||||
.columns.is-gapless
|
||||
.column.is-two-thirds
|
||||
section
|
||||
label.label Email
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='Email', value=user.email, disabled)
|
||||
if user.provider === 'local'
|
||||
section
|
||||
label.label Password
|
||||
p.control.is-fullwidth
|
||||
input.input(type='password', placeholder='Password', value='********', v-model='password')
|
||||
section
|
||||
label.label Verify Password
|
||||
p.control.is-fullwidth
|
||||
input.input(type='password', placeholder='Password', value='********', v-model='passwordVerify')
|
||||
section
|
||||
label.label Display Name
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='John Smith', v-model='name')
|
||||
section
|
||||
button.button.is-green(v-on:click='saveUser')
|
||||
i.icon-check
|
||||
span Save Changes
|
||||
.column
|
||||
.panel-aside
|
||||
label.label Provider
|
||||
p.control.account-profile-provider
|
||||
case user.provider
|
||||
when 'local': i.icon-server
|
||||
when 'windowslive': i.icon-windows2.is-blue
|
||||
when 'azure': i.icon-windows2.is-blue
|
||||
when 'google': i.icon-google.is-blue
|
||||
when 'facebook': i.icon-facebook.is-indigo
|
||||
when 'github': i.icon-github.is-grey
|
||||
when 'slack': i.icon-slack.is-purple
|
||||
when 'ldap': i.icon-arrow-repeat-outline
|
||||
default: i.icon-warning
|
||||
= t('auth:providers.' + user.provider)
|
||||
label.label Member since
|
||||
p.control= userMoment(user.createdAt).format('LL')
|
||||
label.label Last Profile Update
|
||||
p.control= userMoment(user.updatedAt).format('LL')
|
||||
|
||||
script(type='text/javascript').
|
||||
var usrDataName = "!{user.name}";
|
||||
39
server/views/pages/admin/settings.pug
Normal file
39
server/views/pages/admin/settings.pug
Normal file
@@ -0,0 +1,39 @@
|
||||
extends ./_layout.pug
|
||||
|
||||
block adminContent
|
||||
#page-type-admin-settings
|
||||
.hero
|
||||
h1.title#title System Settings
|
||||
h2.subtitle Manage site configuration
|
||||
.form-sections
|
||||
section
|
||||
label.label System Version
|
||||
.section-block
|
||||
p Current Version: #[strong= sysversion.current]
|
||||
if sysversion.latest
|
||||
p Latest Version: #[strong= sysversion.latest] #[em (Published #{userMoment(sysversion.latestPublishedAt).fromNow()})]
|
||||
p
|
||||
if sysversion.current !== sysversion.latest
|
||||
button.button.is-deep-orange(v-on:click='upgrade') Upgrade
|
||||
else
|
||||
button.button.is-disabled Upgrade
|
||||
button.button.is-deep-orange.is-outlined(v-on:click='reinstall') Re-install current version
|
||||
else
|
||||
p: em Unable to query latest version. Try again later.
|
||||
section
|
||||
label.label Administrative Tools
|
||||
.section-block
|
||||
h6 Flush cache and rebuild indexes:
|
||||
p.is-small If content or search results seems out-of-date or do not include latest content, flushing the cache can help resolve these issues.
|
||||
p: button.button.is-teal.is-outlined(v-on:click='flushcache') Flush and Rebuild
|
||||
h6 Reset the root administrator and guest accounts to defaults:
|
||||
p.is-small
|
||||
| The root administrator account will be reset to the email address in the configuration file and the password will be reinitialized to #[strong admin123].
|
||||
br
|
||||
| The guest account will be recreated with its access rights set to defaults.
|
||||
p: button.button.is-teal.is-outlined(v-on:click='resetaccounts') Reset System Accounts
|
||||
h6 Flush all active user sessions:
|
||||
p.is-small All users will be logged out and forced to login again. Your current session will also be affected!
|
||||
p: button.button.is-teal.is-outlined(v-on:click='flushsessions') Flush Sessions
|
||||
|
||||
include ../../modals/admin-upgrade.pug
|
||||
14
server/views/pages/admin/stats.pug
Normal file
14
server/views/pages/admin/stats.pug
Normal file
@@ -0,0 +1,14 @@
|
||||
extends ./_layout.pug
|
||||
|
||||
block adminContent
|
||||
.hero
|
||||
h1.title#title Stats
|
||||
h2.subtitle General site-wide statistics
|
||||
.form-sections
|
||||
section
|
||||
label.label Entries
|
||||
p.control= totalEntries
|
||||
label.label Uploads
|
||||
p.control= totalUploads
|
||||
label.label Users
|
||||
p.control= totalUsers
|
||||
138
server/views/pages/admin/users-edit.pug
Normal file
138
server/views/pages/admin/users-edit.pug
Normal file
@@ -0,0 +1,138 @@
|
||||
extends ./_layout.pug
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
.nav-item
|
||||
a.button(href='/admin/users')
|
||||
i.icon-reply
|
||||
span Return to Users
|
||||
|
||||
block adminContent
|
||||
#page-type-admin-users-edit
|
||||
.hero
|
||||
h1.title#title Edit User
|
||||
h2.subtitle= usr.email
|
||||
table.table
|
||||
thead
|
||||
tr
|
||||
th Unique ID
|
||||
th Provider
|
||||
th Created On
|
||||
th Updated On
|
||||
tbody
|
||||
tr
|
||||
td.is-centered= usr._id
|
||||
td.is-centered.has-icons
|
||||
case usr.provider
|
||||
when 'local'
|
||||
i.icon-server.is-deep-orange
|
||||
| Local Database
|
||||
when 'windowslive'
|
||||
i.icon-windows2.is-blue
|
||||
| Microsoft Account
|
||||
when 'azure'
|
||||
i.icon-windows2.is-blue
|
||||
| Azure Active Directory
|
||||
when 'google'
|
||||
i.icon-google.is-blue
|
||||
| Google ID
|
||||
when 'facebook'
|
||||
i.icon-facebook.is-indigo
|
||||
| Facebook
|
||||
when 'github'
|
||||
i.icon-github.is-blue-grey
|
||||
| GitHub
|
||||
when 'slack'
|
||||
i.icon-slack.is-purple
|
||||
| Slack
|
||||
when 'ldap'
|
||||
i.icon-arrow-repeat-outline
|
||||
| LDAP / Active Directory
|
||||
default: i.icon-warning
|
||||
td.is-centered= userMoment(usr.createdAt).format('lll')
|
||||
td.is-centered= userMoment(usr.updatedAt).format('lll')
|
||||
.form-sections
|
||||
section
|
||||
label.label Email Address
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='john.smith@example.com', v-model='email', disabled=!usrOpts.canChangeEmail)
|
||||
section
|
||||
label.label Display Name
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='John Smith', v-model='name', disabled=!usrOpts.canChangeName)
|
||||
if usrOpts.canChangePassword
|
||||
section
|
||||
label.label Password
|
||||
p.control.is-fullwidth
|
||||
input.input(type='password', placeholder='Password', v-model='password', value='********')
|
||||
section
|
||||
label.label Access Rights
|
||||
table.table
|
||||
thead.is-teal
|
||||
tr
|
||||
th
|
||||
th(style={width: '200px'}) Permission(s)
|
||||
th Path
|
||||
th(style={width: '150px'}) Access
|
||||
th(style={width: '50px'})
|
||||
tbody
|
||||
tr(v-for='(right, idx) in rights', v-cloak)
|
||||
td.is-icon
|
||||
i.icon-marquee-plus.is-green(v-if='right.deny === false || right.deny === "false"')
|
||||
i.icon-marquee-minus.is-red(v-if='right.deny === true || right.deny === "true"')
|
||||
td
|
||||
p.control.is-fullwidth
|
||||
select(v-model='right.role')
|
||||
option(value='write') Read and Write
|
||||
option(value='read') Read Only
|
||||
td
|
||||
.columns
|
||||
.column.is-narrow
|
||||
p.control
|
||||
select(v-model='right.exact')
|
||||
option(value='false') Path starts with:
|
||||
option(value='true') Path match exactly:
|
||||
.column
|
||||
p.control.is-fullwidth
|
||||
input.input(type='text', placeholder='/', v-model='right.path')
|
||||
td
|
||||
p.control.is-fullwidth
|
||||
select(v-model='right.deny')
|
||||
option(value='false') Allow
|
||||
option(value='true') Deny
|
||||
td.is-centered.has-action-icons
|
||||
i.icon-delete.is-red(v-on:click='removeRightsRow(idx)')
|
||||
tr(v-if='rights.length < 1', v-cloak)
|
||||
td.is-icon
|
||||
td.is-centered(colspan='3'): em No additional access rights
|
||||
td.is-centered.has-action-icons
|
||||
.table-actions
|
||||
button.button.is-blue(v-on:click='addRightsRow')
|
||||
i.icon-plus
|
||||
span Add New Row
|
||||
section
|
||||
label.label Role Override
|
||||
p.control.is-fullwidth
|
||||
select(v-model='roleoverride', disabled=!usrOpts.canChangeRole)
|
||||
option(value='none') None
|
||||
option(value='admin') Global Administrator
|
||||
.columns.is-gapless
|
||||
.column
|
||||
section
|
||||
button.button.is-green(v-on:click='saveUser')
|
||||
i.icon-check
|
||||
span Save Changes
|
||||
a.button.button.is-grey.is-outlined(href='/admin/users')
|
||||
i.icon-cancel
|
||||
span Discard
|
||||
.column.is-narrow
|
||||
section
|
||||
if usrOpts.canBeDeleted
|
||||
button.button.is-red.btn-deluser-prompt
|
||||
i.icon-trash2
|
||||
span Delete Account
|
||||
|
||||
include ../../modals/admin-deleteuser.pug
|
||||
|
||||
script(type='text/javascript').
|
||||
var usrData = !{JSON.stringify(usr)};
|
||||
62
server/views/pages/admin/users.pug
Normal file
62
server/views/pages/admin/users.pug
Normal file
@@ -0,0 +1,62 @@
|
||||
extends ./_layout.pug
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
.nav-item
|
||||
a.button.btn-create-prompt
|
||||
i.icon-plus
|
||||
span Create / Authorize User
|
||||
|
||||
block adminContent
|
||||
#page-type-admin-users
|
||||
.hero
|
||||
h1.title#title Users
|
||||
h2.subtitle Manage users and access rights
|
||||
table.table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th Name
|
||||
th Email
|
||||
th Provider
|
||||
th Created On
|
||||
th Updated On
|
||||
tbody
|
||||
each usr in usrs
|
||||
tr
|
||||
td.is-icon
|
||||
i.icon-user.is-grey
|
||||
td
|
||||
a(href='/admin/users/' + usr._id)= usr.name
|
||||
td= usr.email
|
||||
td.is-centered.has-icons
|
||||
case usr.provider
|
||||
when 'local'
|
||||
i.icon-server.is-deep-orange
|
||||
| Local Database
|
||||
when 'windowslive'
|
||||
i.icon-windows2.is-blue
|
||||
| Microsoft Account
|
||||
when 'azure'
|
||||
i.icon-windows2.is-blue
|
||||
| Azure Active Directory
|
||||
when 'google'
|
||||
i.icon-google.is-blue
|
||||
| Google ID
|
||||
when 'facebook'
|
||||
i.icon-facebook.is-purple
|
||||
| Facebook
|
||||
when 'github'
|
||||
i.icon-github.is-blue-grey
|
||||
| GitHub
|
||||
when 'slack'
|
||||
i.icon-slack.is-purple
|
||||
| Slack
|
||||
when 'ldap'
|
||||
i.icon-arrow-repeat-outline
|
||||
| LDAP / Active Directory
|
||||
default: i.icon-warning
|
||||
td.is-centered= userMoment(usr.createdAt).format('lll')
|
||||
td.is-centered= userMoment(usr.updatedAt).format('lll')
|
||||
|
||||
include ../../modals/admin-createuser.pug
|
||||
40
server/views/pages/all.pug
Normal file
40
server/views/pages/all.pug
Normal file
@@ -0,0 +1,40 @@
|
||||
extends ../layout.pug
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
|
||||
block content
|
||||
|
||||
#page-type-all
|
||||
.container.is-fluid.has-collapsable-nav
|
||||
.sidebar.is-collapsed
|
||||
aside
|
||||
.sidebar-label
|
||||
span NAV
|
||||
ul.sidebar-menu
|
||||
li
|
||||
a(href='/')
|
||||
i.icon-home
|
||||
span Home
|
||||
if !isGuest
|
||||
li
|
||||
a(href='/admin')
|
||||
i.icon-head
|
||||
span Account
|
||||
else
|
||||
li
|
||||
a(href='/login')
|
||||
i.icon-unlock
|
||||
span Login
|
||||
ul.collapsable-nav(v-for='treeItem in tree', :class='{ "has-children": treeItem.hasChildren }', v-cloak)
|
||||
li(v-for='page in treeItem.pages', :class='{ "is-active": page.isActive }')
|
||||
a(v-on:click='mainAction(page)')
|
||||
template(v-if='page._id !== "home"')
|
||||
i(:class='{ "icon-folder2": page.isDirectory, "icon-file-text-o": !page.isDirectory }')
|
||||
span {{ page.title }}
|
||||
template(v-else)
|
||||
i.icon-home
|
||||
span Home
|
||||
a.is-pagelink(v-if='page.isDirectory && page.isEntry', v-on:click='goto(page._id)')
|
||||
i.icon-file-text-o
|
||||
i.icon-arrow-right2
|
||||
32
server/views/pages/create.pug
Normal file
32
server/views/pages/create.pug
Normal file
@@ -0,0 +1,32 @@
|
||||
extends ../layout.pug
|
||||
|
||||
block rootNavCenter
|
||||
h2.nav-item Create New Document
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
span.nav-item
|
||||
a.button.is-outlined.btn-create-discard
|
||||
i.icon-cross
|
||||
span Discard
|
||||
a.button.btn-create-save
|
||||
i.icon-check
|
||||
span Save Document
|
||||
|
||||
block content
|
||||
|
||||
#page-type-create(data-entrypath=pageData.meta.path)
|
||||
.editor-area
|
||||
textarea#mk-editor= pageData.markdown
|
||||
|
||||
include ../modals/create-discard.pug
|
||||
include ../modals/editor-link.pug
|
||||
include ../modals/editor-image.pug
|
||||
include ../modals/editor-file.pug
|
||||
include ../modals/editor-video.pug
|
||||
include ../modals/editor-codeblock.pug
|
||||
|
||||
block outside
|
||||
#page-loader
|
||||
i
|
||||
span Loading editor...
|
||||
32
server/views/pages/edit.pug
Normal file
32
server/views/pages/edit.pug
Normal file
@@ -0,0 +1,32 @@
|
||||
extends ../layout.pug
|
||||
|
||||
block rootNavCenter
|
||||
h2.nav-item= pageData.meta.title
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
span.nav-item
|
||||
a.button.is-outlined.btn-edit-discard
|
||||
i.icon-cross
|
||||
span Discard
|
||||
a.button.btn-edit-save
|
||||
i.icon-check
|
||||
span Save Changes
|
||||
|
||||
block content
|
||||
|
||||
#page-type-edit(data-entrypath=pageData.meta.path)
|
||||
.editor-area
|
||||
textarea#mk-editor= pageData.markdown
|
||||
|
||||
include ../modals/edit-discard.pug
|
||||
include ../modals/editor-link.pug
|
||||
include ../modals/editor-image.pug
|
||||
include ../modals/editor-file.pug
|
||||
include ../modals/editor-video.pug
|
||||
include ../modals/editor-codeblock.pug
|
||||
|
||||
block outside
|
||||
#page-loader
|
||||
i
|
||||
span Loading editor...
|
||||
36
server/views/pages/source.pug
Normal file
36
server/views/pages/source.pug
Normal file
@@ -0,0 +1,36 @@
|
||||
extends ../layout.pug
|
||||
|
||||
block rootNavCenter
|
||||
h2.nav-item= pageData.meta.title
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
span.nav-item
|
||||
if rights.write
|
||||
a.button.is-outlined.btn-move-prompt.is-hidden
|
||||
i.icon-shuffle
|
||||
span Move
|
||||
a.button.is-outlined(href='/' + pageData.meta.path)
|
||||
i.icon-loader
|
||||
span Normal View
|
||||
if rights.write
|
||||
a.button.is-orange(href='/edit/' + pageData.meta.path)
|
||||
i.fa.fa-edit
|
||||
span Edit
|
||||
a.button.is-blue.btn-create-prompt
|
||||
i.fa.fa-plus
|
||||
span Create
|
||||
|
||||
block content
|
||||
|
||||
#page-type-source(data-entrypath=pageData.meta.path)
|
||||
.ace-container
|
||||
#source-display= pageData.markdown
|
||||
|
||||
include ../modals/create.pug
|
||||
include ../modals/move.pug
|
||||
|
||||
block outside
|
||||
#page-loader
|
||||
i
|
||||
span Loading source...
|
||||
81
server/views/pages/view.pug
Normal file
81
server/views/pages/view.pug
Normal file
@@ -0,0 +1,81 @@
|
||||
extends ../layout.pug
|
||||
|
||||
mixin tocMenu(ti)
|
||||
each node in ti
|
||||
li
|
||||
a(href='#' + node.anchor, title=node.content)= node.content
|
||||
if node.nodes.length > 0
|
||||
ul
|
||||
+tocMenu(node.nodes)
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
.nav-item
|
||||
if rights.write
|
||||
a.button.is-outlined.btn-move-prompt.is-hidden
|
||||
i.icon-shuffle
|
||||
span Move
|
||||
a.button.is-outlined(href='/source/' + pageData.meta.path)
|
||||
i.icon-loader
|
||||
span Source
|
||||
if rights.write
|
||||
a.button(href='/edit/' + pageData.meta.path)
|
||||
i.icon-document-text
|
||||
span Edit
|
||||
a.button.btn-create-prompt
|
||||
i.icon-plus
|
||||
span Create
|
||||
|
||||
block content
|
||||
|
||||
#page-type-view.page-type-container(data-entrypath=pageData.meta.path)
|
||||
.container.is-fluid.has-mkcontent
|
||||
.columns.is-gapless
|
||||
|
||||
.column.is-narrow.is-hidden-touch.sidebar
|
||||
|
||||
aside
|
||||
.sidebar-label
|
||||
span Navigation
|
||||
ul.sidebar-menu
|
||||
li
|
||||
a(href='/')
|
||||
i.icon-home
|
||||
span Home
|
||||
li
|
||||
a(href='/all')
|
||||
i.icon-paper
|
||||
span All Pages
|
||||
if pageData.parent
|
||||
li
|
||||
a(href='/' + pageData.parent.path)
|
||||
i.icon-reply
|
||||
span= pageData.parent.title
|
||||
if !isGuest
|
||||
li
|
||||
a(href='/admin')
|
||||
i.icon-head
|
||||
span Account
|
||||
else
|
||||
li
|
||||
a(href='/login')
|
||||
i.icon-unlock
|
||||
span Login
|
||||
aside.stickyscroll(data-margin-top=15)
|
||||
.sidebar-label
|
||||
span Page Contents
|
||||
ul.sidebar-menu
|
||||
li: a(href='#root', title='Top of Page') Top of Page
|
||||
+tocMenu(pageData.tree)
|
||||
|
||||
.column
|
||||
|
||||
.hero
|
||||
h1.title#title= pageData.meta.title
|
||||
if pageData.meta.subtitle
|
||||
h2.subtitle= pageData.meta.subtitle
|
||||
.content.mkcontent
|
||||
!= pageData.html
|
||||
|
||||
include ../modals/create.pug
|
||||
include ../modals/move.pug
|
||||
16
server/views/pages/welcome.pug
Normal file
16
server/views/pages/welcome.pug
Normal file
@@ -0,0 +1,16 @@
|
||||
extends ../layout.pug
|
||||
|
||||
block rootNavCenter
|
||||
|
||||
block rootNavRight
|
||||
i.nav-item#notifload
|
||||
|
||||
block content
|
||||
|
||||
#page-type-welcome
|
||||
.container
|
||||
.welcome
|
||||
img(src='/images/logo.png', alt='Wiki.js')
|
||||
h1 Welcome to your wiki!
|
||||
h2 Let's get started and create the home page.
|
||||
a.button.is-indigo(href='/create/home') Create Home Page
|
||||
Reference in New Issue
Block a user