refactor: moved server content to /server

This commit is contained in:
NGPixel
2017-04-28 17:58:38 -04:00
parent 86eb7a427d
commit d4b73be1e7
97 changed files with 7452 additions and 73 deletions

View 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

View 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 = [];

View 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')

View 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 }}

View File

View 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

View 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...

View 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
View 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
View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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://')

View 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

View 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

View 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

View 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}";

View 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

View 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

View 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)};

View 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

View 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

View 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...

View 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...

View 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...

View 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

View 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