Browse Source

refactor: views consolidation + css fixes

pull/621/head
Nicolas Giard 6 years ago
parent
commit
453c1beab3
47 changed files with 189 additions and 1055 deletions
  1. 4
      client/app.js
  2. 10
      client/components/admin.vue
  3. 2
      client/components/admin/admin-theme.vue
  4. 29
      client/components/common/nav-footer.vue
  5. 36
      client/components/login.vue
  6. 9
      client/scss/app.scss
  7. 67
      client/scss/base/base.scss
  8. 39
      client/scss/base/icons.scss
  9. 25
      client/scss/base/variables.scss
  10. 317
      client/scss/components/login.scss
  11. 0
      client/scss/components/v-btn.scss
  12. 0
      client/scss/components/v-data-table.scss
  13. 0
      client/scss/components/v-dialog.scss
  14. 27
      client/scss/components/vue-tree-navigation.scss
  15. 7
      client/scss/global.scss
  16. 2
      client/store/site.js
  17. 81
      client/themes/default/components/app.vue
  18. 2
      package.json
  19. 2
      server/controllers/auth.js
  20. 10
      server/controllers/common.js
  21. 5
      server/views/admin.pug
  22. 65
      server/views/admin/_layout.pug
  23. 62
      server/views/admin/profile.pug
  24. 9
      server/views/admin/settings.pug
  25. 15
      server/views/admin/stats.pug
  26. 47
      server/views/admin/system.pug
  27. 32
      server/views/admin/theme.pug
  28. 122
      server/views/admin/users-edit.pug
  29. 47
      server/views/admin/users.pug
  30. 14
      server/views/common/alerts.pug
  31. 8
      server/views/common/footer.pug
  32. 19
      server/views/common/header.pug
  33. 0
      server/views/common/mixins.pug
  34. 4
      server/views/editor.pug
  35. 4
      server/views/error.pug
  36. 30
      server/views/errors/error-forbidden.pug
  37. 30
      server/views/errors/error-notexist.pug
  38. 11
      server/views/layout.pug
  39. 5
      server/views/login.pug
  40. 5
      server/views/main/admin.pug
  41. 5
      server/views/main/login.pug
  42. 5
      server/views/main/profile.pug
  43. 4
      server/views/page.pug
  44. 5
      server/views/profile.pug
  45. 4
      server/views/setup.pug
  46. 4
      server/views/welcome.pug
  47. 14
      yarn.lock

4
client/app.js

@ -19,6 +19,7 @@ import Hammer from 'hammerjs'
import moment from 'moment'
import VueMoment from 'vue-moment'
import VueTour from 'vue-tour'
import VueTreeNavigation from 'vue-tree-navigation'
import store from './store'
// ====================================
@ -100,6 +101,7 @@ Vue.use(VeeValidate, { events: '' })
Vue.use(Vuetify)
Vue.use(VueMoment, { moment })
Vue.use(VueTour)
Vue.use(VueTreeNavigation)
Vue.prototype.Velocity = Velocity
@ -136,7 +138,7 @@ let bootstrap = () => {
const i18n = localization.init()
window.WIKI = new Vue({
el: '#app',
el: '#root',
components: {},
mixins: [helpers],
provide: apolloProvider.provide(),

10
client/components/admin.vue

@ -80,12 +80,7 @@
<script>
import VueRouter from 'vue-router'
import adminStore from '@/store/admin'
/* global WIKI */
WIKI.$store.registerModule('admin', adminStore)
import { get } from 'vuex-pathify'
const router = new VueRouter({
mode: 'history',
@ -121,6 +116,9 @@ export default {
adminDrawerShown: true
}
},
computed: {
darkMode: get('site/dark')
},
router
}
</script>

2
client/components/admin/admin-theme.vue

@ -108,7 +108,7 @@ export default {
}
},
computed: {
darkMode: sync('admin/theme@dark')
darkMode: sync('site/dark')
},
mounted() {
this.darkModeInitial = this.darkMode

29
client/components/common/nav-footer.vue

@ -1,5 +1,5 @@
<template lang="pug">
v-footer.justify-center(:color='darkMode ? "" : "grey lighten-3"', inset)
v-footer.justify-center(:color='color', inset)
.caption.grey--text.text--darken-1
span(v-if='company && company.length > 0') {{ $t('common:footer.copyright', { company: company, year: currentYear }) }} |&nbsp;
span {{ $t('common:footer.poweredBy') }} Wiki.js
@ -20,6 +20,12 @@
import { get, sync } from 'vuex-pathify'
export default {
props: {
altbg: {
type: Boolean,
default: false
}
},
data() {
return {
currentYear: (new Date()).getFullYear()
@ -29,7 +35,26 @@ export default {
company: get('site/company'),
notification: get('notification'),
darkMode: get('site/dark'),
notificationState: sync('notification@isActive')
notificationState: sync('notification@isActive'),
color() {
if (this.altbg) {
return 'altbg'
} else if (!this.darkMode) {
return 'grey lighten-3'
} else {
return ''
}
}
}
}
</script>
<style lang="scss">
.v-footer.altbg {
background: mc('theme', 'primary');
span {
color: mc('blue', '300');
}
}
</style>

36
client/components/login.vue

@ -1,6 +1,5 @@
<template lang="pug">
v-app
nav-header
.login
.login-container(:class='{ "is-expanded": strategies.length > 1, "is-loading": isLoading }')
.login-mascot
@ -35,20 +34,7 @@
input(type='text', ref='iptTFA', v-model='securityCode', :placeholder='$t("auth:tfa.placeholder")', @keyup.enter='verifySecurityCode')
button.button.is-blue.is-fullwidth(@click='verifySecurityCode')
span {{ $t('auth:tfa.verifyToken') }}
.login-copyright
span {{ $t('common:footer.poweredBy') }}
a(href='https://wiki.js.org', rel='external', title='Wiki.js') Wiki.js
v-snackbar(
:color='notification.style'
bottom,
right,
multi-line,
v-model='notificationState'
)
.text-xs-left
v-icon.mr-3(dark) {{ notification.icon }}
span {{ notification.message }}
nav-footer(altbg)
</template>
<script>
@ -145,7 +131,7 @@ export default {
})
} else {
this.$store.commit('showNotification', {
message: 'Login successful!',
message: 'Login Successful! Redirecting...',
style: 'success',
icon: 'check'
})
@ -259,23 +245,22 @@ export default {
&::before {
content: '';
position: absolute;
background-image: url('../static/svg/login-bg.svg');
background-position: center bottom;
background-color: #0d47a1;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox='0 0 1600 800'%3E%3Cg %3E%3Cpath fill='%231356b1' d='M486 705.8c-109.3-21.8-223.4-32.2-335.3-19.4C99.5 692.1 49 703 0 719.8V800h843.8c-115.9-33.2-230.8-68.1-347.6-92.2C492.8 707.1 489.4 706.5 486 705.8z'/%3E%3Cpath fill='%231866c1' d='M1600 0H0v719.8c49-16.8 99.5-27.8 150.7-33.5c111.9-12.7 226-2.4 335.3 19.4c3.4 0.7 6.8 1.4 10.2 2c116.8 24 231.7 59 347.6 92.2H1600V0z'/%3E%3Cpath fill='%231c75d2' d='M478.4 581c3.2 0.8 6.4 1.7 9.5 2.5c196.2 52.5 388.7 133.5 593.5 176.6c174.2 36.6 349.5 29.2 518.6-10.2V0H0v574.9c52.3-17.6 106.5-27.7 161.1-30.9C268.4 537.4 375.7 554.2 478.4 581z'/%3E%3Cpath fill='%231f86e2' d='M0 0v429.4c55.6-18.4 113.5-27.3 171.4-27.7c102.8-0.8 203.2 22.7 299.3 54.5c3 1 5.9 2 8.9 3c183.6 62 365.7 146.1 562.4 192.1c186.7 43.7 376.3 34.4 557.9-12.6V0H0z'/%3E%3Cpath fill='%232196f3' d='M181.8 259.4c98.2 6 191.9 35.2 281.3 72.1c2.8 1.1 5.5 2.3 8.3 3.4c171 71.6 342.7 158.5 531.3 207.7c198.8 51.8 403.4 40.8 597.3-14.8V0H0v283.2C59 263.6 120.6 255.7 181.8 259.4z'/%3E%3Cpath fill='%2355a4f5' d='M1600 0H0v136.3c62.3-20.9 127.7-27.5 192.2-19.2c93.6 12.1 180.5 47.7 263.3 89.6c2.6 1.3 5.1 2.6 7.7 3.9c158.4 81.1 319.7 170.9 500.3 223.2c210.5 61 430.8 49 636.6-16.6V0z'/%3E%3Cpath fill='%2374b2f7' d='M454.9 86.3C600.7 177 751.6 269.3 924.1 325c208.6 67.4 431.3 60.8 637.9-5.3c12.8-4.1 25.4-8.4 38.1-12.9V0H288.1c56 21.3 108.7 50.6 159.7 82C450.2 83.4 452.5 84.9 454.9 86.3z'/%3E%3Cpath fill='%238ec0f8' d='M1600 0H498c118.1 85.8 243.5 164.5 386.8 216.2c191.8 69.2 400 74.7 595 21.1c40.8-11.2 81.1-25.2 120.3-41.7V0z'/%3E%3Cpath fill='%23a5cffa' d='M1397.5 154.8c47.2-10.6 93.6-25.3 138.6-43.8c21.7-8.9 43-18.8 63.9-29.5V0H643.4c62.9 41.7 129.7 78.2 202.1 107.4C1020.4 178.1 1214.2 196.1 1397.5 154.8z'/%3E%3Cpath fill='%23bbdefb' d='M1315.3 72.4c75.3-12.6 148.9-37.1 216.8-72.4h-723C966.8 71 1144.7 101 1315.3 72.4z'/%3E%3C/g%3E%3C/svg%3E");
background-attachment: fixed;
background-size: cover;
/* background by SVGBackgrounds.com */
opacity: .5;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
@include until($tablet) {
display: none;
}
}
&::after {
content: '';
position: absolute;
background-image: linear-gradient(to bottom, rgba(mc('blue', '800'), 1) 0%, rgba(mc('blue', '800'), 0) 100%);
background-image: linear-gradient(to bottom, rgba(mc('blue', '800'), .9) 0%, rgba(mc('blue', '800'), 0) 100%);
top: 0;
left: 0;
width: 100vw;
@ -332,11 +317,11 @@ export default {
}
@include until($tablet) {
width: 100%;
width: 95vw;
border-radius: 0;
&.is-expanded {
width: 100%;
width: 95vw;
}
}
}
@ -365,7 +350,6 @@ export default {
// border-top: 1px solid rgba(mc('light-blue', '900'), .5);
background: linear-gradient(to right, rgba(0,0,0, .5), rgba(0,0,0, .7));
border-top: 1px solid rgba(0,0,0, .2);
font-family: $core-font-standard;
font-weight: 600;
text-align: left;
min-height: 40px;

9
client/scss/app.scss

@ -1,18 +1,19 @@
@import "global";
@import "base/base";
@import 'base/icons';
@import "../libs/animate/animate";
@import 'components/markdown-content';
@import 'components/btn';
@import 'components/data-table';
@import 'components/dialog';
@import 'components/v-btn';
@import 'components/v-data-table';
@import 'components/v-dialog';
@import 'components/vue-tree-navigation';
// @import '../libs/twemoji/twemoji-awesome';
@import '../libs/prism/prism.css';
@import '~vue-tour/dist/vue-tour.css';
@import '~vue-status-indicator/styles.css';
// @import 'node_modules/diff2html/dist/diff2html.min';
@import 'pages/welcome';

67
client/scss/base/base.scss

@ -1,6 +1,5 @@
html {
box-sizing: border-box;
font-family: $core-font-standard;
height: 100%;
}
*, *:before, *:after {
@ -11,7 +10,7 @@ html {
display: none;
}
#app {
#root {
position: relative;
min-height: 100%;
@ -19,67 +18,3 @@ html {
height: 100vh;
}
}
// Container
.container {
position: relative;
}
.content {
padding: 20px;
}
.datatable {
th, td {
vertical-align: middle;
}
}
// Visibility
.is-hidden {
display: none !important;
}
.is-hidden-mobile {
@include mobile {
display: none !important;
}
}
.is-hidden-tablet {
@include tablet {
display: none !important;
}
}
.is-hidden-tablet-only {
@include tablet-only {
display: none !important;
}
}
.is-hidden-touch {
@include touch {
display: none !important;
}
}
.is-hidden-desktop {
@include desktop {
display: none !important;
}
}
.is-hidden-desktop-only {
@include desktop-only {
display: none !important;
}
}
.is-hidden-widescreen {
@include widescreen {
display: none !important;
}
}

39
client/scss/base/icons.scss

@ -1,39 +0,0 @@
.icons {
display: inline-block;
color: mc('grey', '800');
&.is-text {
display: inline-block;
width: 1em;
height: 1em;
vertical-align: middle;
position: relative;
top: -0.0625em;
stroke: none;
fill: none;
}
@each $size in 16,18,20,24,32,48,64,96,128 {
&.is-#{$size} {
width: #{$size}px;
height: #{$size}px;
}
}
&.has-right-pad {
margin-right: .5rem;
}
&.is-outlined {
stroke-width: 2px;
use {
fill: inherit;
stroke: mc('grey', '800');
}
}
}
.material-design-icon {
display: inline-flex;
}

25
client/scss/base/variables.scss

@ -1,25 +0,0 @@
// --------------------------------------
// FONTS
// --------------------------------------
$core-font-standard: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
$core-font-monospace: Consolas, "Liberation Mono", Menlo, Courier, monospace;
// --------------------------------------
// LAYOUT
// --------------------------------------
$tablet: 769px !default;
$desktop: 980px !default;
$widescreen: 1180px !default;
// --------------------------------------
// COLORS
// --------------------------------------
$color-text: mc('grey', '800');
$color-link: mc('blue', '500');
$color-link-hover: mc('blue', '700');
$color-link-active: mc('purple', '500');
$color-bg: #F4F5F9;

317
client/scss/components/login.scss

@ -1,317 +0,0 @@
.login {
background-color: mc('blue', '800');
background-image: url('../svg/login-bg-motif.svg');
background-repeat: repeat;
background-size: 200px;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
animation: loginBgReveal 20s linear infinite;
@include keyframes(loginBgReveal) {
0% {
background-position-y: 0;
}
100% {
background-position-y: -800px;
}
}
&::before {
content: '';
position: absolute;
background-image: url('../svg/login-bg.svg');
background-position: center bottom;
background-size: cover;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
@include until($tablet) {
display: none;
}
}
&::after {
content: '';
position: absolute;
background-image: linear-gradient(to bottom, rgba(mc('blue', '800'), 1) 0%, rgba(mc('blue', '800'), 0) 100%);
top: 0;
left: 0;
width: 100vw;
height: 25vh;
}
&-container {
position: relative;
display: flex;
width: 400px;
align-items: stretch;
box-shadow: 0 14px 28px rgba(0,0,0,0.2);
border-radius: 6px;
animation: zoomIn .5s ease;
&::after {
position: absolute;
top: 1rem;
right: 1rem;
content: " ";
@include spinner(mc('blue', '500'),0.5s,16px);
display: none;
}
&.is-expanded {
width: 650px;
.login-frame {
border-radius: 0 6px 6px 0;
border-left: none;
@include until($tablet) {
border-radius: 0;
}
}
}
&.is-loading::after {
display: block;
}
@include until($tablet) {
width: 100%;
border-radius: 0;
&.is-expanded {
width: 100%;
}
}
}
&-providers {
display: flex;
flex-direction: column;
width: 250px;
border-right: none;
border-radius: 6px 0 0 6px;
z-index: 1;
overflow: hidden;
@include until($tablet) {
width: 50px;
border-radius: 0;
}
button {
flex: 0 1 50px;
padding: 5px 15px;
border: none;
color: #FFF;
// background: linear-gradient(to right, rgba(mc('light-blue', '800'), .7), rgba(mc('light-blue', '800'), 1));
// border-top: 1px solid rgba(mc('light-blue', '900'), .5);
background: linear-gradient(to right, rgba(0,0,0, .5), rgba(0,0,0, .7));
border-top: 1px solid rgba(0,0,0, .2);
font-family: $core-font-standard;
font-weight: 600;
text-align: left;
min-height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
transition: all .4s ease;
&:focus {
outline: none;
}
@include until($tablet) {
justify-content: center;
}
&:hover {
background-color: rgba(0,0,0, .4);
}
&:first-child {
border-top: none;
&.is-active {
border-top: 1px solid rgba(255,255,255, .5);
}
}
&.is-active {
background-image: linear-gradient(to right, rgba(255,255,255,1) 0%,rgba(255,255,255,.77) 100%);
color: mc('grey', '800');
cursor: default;
&:hover {
background-color: transparent;
}
svg path {
fill: mc('grey', '800');
}
}
i {
margin-right: 10px;
font-size: 16px;
@include until($tablet) {
margin-right: 0;
font-size: 20px;
}
}
svg {
margin-right: 10px;
width: auto;
height: 20px;
max-width: 18px;
max-height: 20px;
path {
fill: #FFF;
}
@include until($tablet) {
margin-right: 0;
font-size: 20px;
}
}
span {
font-weight: 600;
@include until($tablet) {
display: none;
}
}
}
&-fill {
flex: 1 1 0;
background: linear-gradient(to right, rgba(mc('light-blue', '800'), .7), rgba(mc('light-blue', '800'), 1));
}
}
&-frame {
background-image: radial-gradient(circle at top center, rgba(255,255,255,1) 5%,rgba(255,255,255,.6) 100%);
border: 1px solid rgba(255,255,255, .5);
border-radius: 6px;
width: 400px;
padding: 1rem;
color: mc('grey', '700');
display: flex;
justify-content: center;
flex-direction: column;
text-align: center;
@include until($tablet) {
width: 100%;
border-radius: 0;
border: none;
}
h1 {
font-size: 2rem;
font-weight: 600;
color: mc('light-blue', '700');
text-shadow: 1px 1px 0 #FFF;
padding: 0;
margin: 0;
}
h2 {
font-size: 1.5rem;
font-weight: 300;
color: mc('grey', '700');
text-shadow: 1px 1px 0 #FFF;
padding: 0;
margin: 0 0 25px 0;
}
form {
display: flex;
flex-direction: column;
}
input[type=text], input[type=password] {
width: 100%;
border: 1px solid rgba(mc('blue-grey','500'), .5);
border-radius: 3px;
background-color: rgba(255,255,255,.9);
box-shadow: inset 0 0 0 3px rgba(255,255,255, .25);
padding: 0 15px;
height: 40px;
margin: 0 0 10px 0;
color: mc('grey', '700');
font-weight: 600;
font-size: .8rem;
transition: all 0.4s ease;
text-align: center;
&:focus {
outline: none;
border-color: mc('light-blue','500');
background-color: rgba(255,255,255,1);
box-shadow: inset 0 0 8px rgba(mc('light-blue','500'), .5);
color: mc('light-blue', '800');
}
}
.button {
background-image: linear-gradient(to bottom, mc('blue', '400') 0%, mc('blue', '600') 50%, mc('blue', '700') 100%);
background-repeat: no-repeat;
background-size: 100% 200%;
&:hover {
background-position-y: 100%;
}
}
}
&-tfa {
position: relative;
display: flex;
width: 400px;
align-items: stretch;
box-shadow: 0 14px 28px rgba(0,0,0,0.2);
border-radius: 6px;
animation: zoomIn .5s ease;
}
&-copyright {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
left: 0;
bottom: 10vh;
width: 100%;
z-index: 2;
color: mc('grey', '500');
font-weight: 400;
a {
font-weight: 600;
color: mc('blue', '500');
margin-left: .25rem;
@include until($tablet) {
color: mc('blue', '200');
}
}
@include until($tablet) {
color: mc('blue', '50');
}
}
}

client/scss/components/_btn.scss → client/scss/components/v-btn.scss

client/scss/components/_data-table.scss → client/scss/components/v-data-table.scss

client/scss/components/_dialog.scss → client/scss/components/v-dialog.scss

27
client/scss/components/vue-tree-navigation.scss

@ -0,0 +1,27 @@
.TreeNavigation.treenav {
font-size: 13px;
li {
padding-left: 24px;
}
a {
text-decoration: none;
color: mc('grey', '800');
}
.NavigationLevel__parent {
// font-weight: 600;
}
.NavigationItem {
padding: 3px 0;
}
.NavigationItem--active {
color: #42b883;
}
.NavigationToggle__icon {
border-color: mc('blue', '600');
}
}

7
client/scss/global.scss

@ -1,7 +1,8 @@
@charset "utf-8";
$primary: 'indigo';
@import "base/variables";
@import "base/material";
@import "base/mixins";
$tablet: 769px !default;
$desktop: 980px !default;
$widescreen: 1180px !default;

2
client/store/site.js

@ -4,7 +4,7 @@ import { make } from 'vuex-pathify'
const state = {
company: '',
dark: false,
dark: siteConfig.darkMode,
mascot: true,
title: siteConfig.title
}

81
client/themes/default/components/app.vue

@ -37,7 +37,8 @@
v-breadcrumbs-item Galaxy
v-breadcrumbs-item Solar System
v-breadcrumbs-item Planet Earth
v-spacer
status-indicator(active, pulse)
v-divider
v-layout(row)
v-flex(xs12, lg9, xl10)
@ -45,6 +46,7 @@
div
.headline.grey--text.text--darken-3 {{title}}
.caption.grey--text.text--darken-1 {{description}}
v-divider
.contents
slot(name='contents')
v-flex(lg3, xl2, fill-height, v-if='$vuetify.breakpoint.lgAndUp')
@ -58,33 +60,41 @@
v-btn(icon, slot='activator')
v-icon(color='grey') edit
span Edit Page
v-list.grey.lighten-3(dense)
v-subheader.pl-4 Table of contents
v-list-tile
v-list-tile-avatar: v-icon chevron_right
v-list-tile-title Introduction
v-divider
v-list.grey.lighten-3.pb-3(dense)
v-subheader.pl-4.primary--text Table of contents
vue-tree-navigation.treenav(:items='toc', :defaultOpenLevel='1')
v-divider
v-list.grey.lighten-4(dense)
v-subheader.pl-4.teal--text Tags
v-list-tile
v-list-tile-avatar: v-icon chevron_right
v-list-tile-title Cities
v-list-tile(inset)
v-list-tile-avatar: v-icon chevron_right
v-list-tile-title New York
v-divider.my-2
v-subheader.pl-4 Metadata
v-list-tile-avatar: v-icon(color='teal') label
v-list-tile-title Astrophysics
v-divider(inset)
v-list-tile
v-list-tile-avatar: v-icon chevron_right
v-list-tile-title Test
v-list-tile-avatar: v-icon(color='teal') label
v-list-tile-title Space
v-divider(inset)
v-list-tile
v-list-tile-avatar: v-icon chevron_right
v-list-tile-title Test
v-list-tile
v-list-tile-avatar: v-icon chevron_right
v-list-tile-title Test
v-list-tile-avatar: v-icon(color='teal') label
v-list-tile-title Planets
v-divider
v-toolbar(color='grey lighten-3', flat, dense)
v-spacer
v-btn(icon): v-icon(color='grey') bookmark
v-btn(icon): v-icon(color='grey') share
v-btn(icon): v-icon(color='grey') print
v-spacer
nav-footer
</template>
<script>
import { StatusIndicator } from 'vue-status-indicator'
export default {
components: {
StatusIndicator
},
props: {
title: {
type: String,
@ -97,7 +107,36 @@ export default {
},
data() {
return {
navOpen: false
navOpen: false,
toc: [
{
name: 'Introduction',
element: 'introduction'
},
{
name: 'Cities',
element: 'cities',
children: [
{
name: 'New York',
element: 'contact',
children: [
{ name: 'E-mail', element: 'email' },
{ name: 'Phone', element: 'phone' }
]
},
{
name: 'Chicago',
element: 'contact',
children: [
{ name: 'E-mail', element: 'email' },
{ name: 'Phone', element: 'phone' }
]
}
]
},
{ name: 'Population', external: 'https://github.com' }
]
}
},
computed: {

2
package.json

@ -238,8 +238,10 @@
"vue-moment": "4.0.0",
"vue-router": "3.0.1",
"vue-simple-breakpoints": "1.0.3",
"vue-status-indicator": "1.1.0",
"vue-template-compiler": "2.5.17",
"vue-tour": "1.0.1",
"vue-tree-navigation": "3.0.1",
"vuedraggable": "2.16.0",
"vuetify": "1.1.10",
"vuex": "3.0.1",

2
server/controllers/auth.js

@ -34,7 +34,7 @@ const bruteforce = new ExpressBrute(EBstore, {
* Login form
*/
router.get('/login', function (req, res, next) {
res.render('main/login')
res.render('login')
})
router.post('/login', bruteforce.prevent, function (req, res, next) {

10
server/controllers/common.js

@ -5,35 +5,35 @@ const router = express.Router()
* Create/Edit document
*/
router.get(['/e', '/e/*'], (req, res, next) => {
res.render('main/editor')
res.render('editor')
})
/**
* Administration
*/
router.get(['/a', '/a/*'], (req, res, next) => {
res.render('main/admin')
res.render('admin')
})
/**
* Profile
*/
router.get(['/p', '/p/*'], (req, res, next) => {
res.render('main/profile')
res.render('profile')
})
/**
* View document
*/
router.get('/', (req, res, next) => {
res.render('main/welcome')
res.render('welcome')
})
/**
* View document
*/
router.get('/*', (req, res, next) => {
res.render('main/page')
res.render('page')
})
module.exports = router

5
server/views/admin.pug

@ -0,0 +1,5 @@
extends master.pug
block body
#root
admin

65
server/views/admin/_layout.pug

@ -1,65 +0,0 @@
extends ../../layout.pug
block rootNavCenter
h2.nav-item= t('nav.settings')
block rootNavRight
loading-spinner
.nav-item
a.button.btn-edit-discard(href='/')
i.nc-icon-outline.ui-1_home-minimal
span= t('nav.root')
block content
#page-type-account
.container.is-fluid
.columns.is-gapless
.column.is-narrow.is-hidden-touch.sidebar
aside
.sidebar-label
span= t('sidebar.navigation')
ul.sidebar-menu
li
a(href='/')
i.nc-icon-outline.ui-1_home-minimal
span= t('nav.root')
aside
.sidebar-label
span= t('nav.account')
ul.sidebar-menu
li
a(href='/admin/profile')
i.nc-icon-outline.business_business-contact-86
span= t('nav.myprofile')
li
a(href='/admin/stats')
i.nc-icon-outline.ui-3_chart-bars
span= t('nav.stats')
if rights.manage
li
a(href='/admin/users')
i.nc-icon-outline.users_multiple-19
span= t('nav.users')
li
a(href='/admin/theme')
i.nc-icon-outline.ui-1_drop
span= t('nav.theme')
//-li
a(href='/admin/settings')
i.nc-icon-outline.ui-1_settings-gear-63
span= t('nav.syssettings')
li
a(href='/admin/system')
i.nc-icon-outline.objects_planet
span= t('nav.sysinfo')
li
a(href='/logout')
i.nc-icon-outline.arrows-1_log-out
span= t('nav.logout')
.column
block adminContent

62
server/views/admin/profile.pug

@ -1,62 +0,0 @@
extends ./_layout.pug
block adminContent
.hero
h1.title#title= t('nav.myprofile')
h2.subtitle= t('admin:profile.subtitle')
i.pageicon.nc-icon-outline.business_business-contact-86
.form-sections
.columns.is-gapless
.column.is-two-thirds
admin-profile(inline-template, email=user.email, name=user.name, provider=user.provider)
div
section
label.label= t('admin:profile.email')
p.control.is-fullwidth
input.input(type='text', placeholder=t('admin:profile.email'), value=user.email, disabled)
if user.provider === 'local'
section
label.label= t('admin:profile.password')
p.control.is-fullwidth
input.input(type='password', placeholder=t('admin:profile.password'), value='********', v-model='password')
section
label.label= t('admin:profile.passwordverify')
p.control.is-fullwidth
input.input(type='password', placeholder=t('admin:profile.password'), value='********', v-model='passwordVerify')
section
label.label= t('admin:profile.displayname')
p.control.is-fullwidth
input.input(type='text', placeholder=t('admin:profile.displaynameexample'), v-model='name')
//-section
label.label #{t('admin:profile.tfa')}: #[strong.is-red(v-cloak) {{ tfaStatus }}]
button.button.is-blue(@click='$store.dispatch("modalProfile2fa/open")', :disabled='tfaIsActive')
i.nc-icon-outline.ui-1_circle-add
span= t('admin:profile.tfaenable')
button.button.is-blue(@click='saveUser', :disabled='!tfaIsActive')
i.nc-icon-outline.ui-1_circle-delete
span= t('admin:profile.tfadisable')
section
button.button.is-green(@click='saveUser')
i.nc-icon-outline.ui-1_check
span= t('admin:profile.savechanges')
.column
.panel-aside
label.label= t('admin:profile.provider')
p.control.account-profile-provider
case user.provider
when 'local': i.nc-icon-outline.ui-1_database
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= t('admin:profile.membersince')
p.control= moment(user.createdAt).format('LL')
label.label= t('admin:profile.lastprofileupdate')
p.control= moment(user.updatedAt).format('LL')
//-modal-profile-2fa

9
server/views/admin/settings.pug

@ -1,9 +0,0 @@
extends ./_layout.pug
block adminContent
.hero
h1.title#title= t('nav.syssettings')
h2.subtitle= t('admin:settings.subtitle')
i.pageicon.nc-icon-outline.ui-1_settings-gear-63
.form-sections
section Coming soon

15
server/views/admin/stats.pug

@ -1,15 +0,0 @@
extends ./_layout.pug
block adminContent
.hero
h1.title#title= t('nav.stats')
h2.subtitle= t('admin:stats.subtitle')
i.pageicon.nc-icon-outline.ui-3_chart-bars
.form-sections
section
label.label= t('admin:stats.entries')
p.control= totalEntries
label.label= t('admin:stats.uploads')
p.control= totalUploads
label.label= t('admin:stats.users')
p.control= totalUsers

47
server/views/admin/system.pug

@ -1,47 +0,0 @@
extends ./_layout.pug
block adminContent
.hero
h1.title#title= t('nav.sysinfo')
h2.subtitle= t('admin:system.subtitle')
i.pageicon.nc-icon-outline.objects_planet
admin-settings(inline-template)
.form-sections
section
img(src='/images/logo.png', style={width:'200px', float:'right'})
label.label= t('admin:system.systemversion')
.section-block
p #{t('admin:system.currentversion')}: #[strong= sysversion.current]
if sysversion.latest
p #{t('admin:system.latestversion')}: #[strong= sysversion.latest] #[em (Published #{moment(sysversion.latestPublishedAt).fromNow()})]
p
if sysversion.current !== sysversion.latest
button.button.is-deep-orange(@click='$store.dispatch("modalUpgradeSystem/open", { mode: "upgrade"})')= t('admin:system.upgrade')
else
button.button.is-disabled= t('admin:system.upgrade')
button.button.is-deep-orange.is-outlined(@click='$store.dispatch("modalUpgradeSystem/open", { mode: "reinstall"})')= t('admin:system.reinstall')
else
p: em= t('admin:system.versioncheckfailed')
section
label.label= t('admin:system.hostinfo')
.section-block
p #{t('admin:system.os')}: #[strong= hostInfo.os]
p #{t('admin:system.nodeversion')}: #[strong= hostInfo.nodeversion]
p #{t('admin:system.hostname')}: #[strong= hostInfo.hostname]
p #{t('admin:system.cores')}: #[strong= hostInfo.cpus.length]
p #{t('admin:system.totalmem')}: #[strong= hostInfo.totalmem]
p #{t('admin:system.cwd')}: #[strong= hostInfo.cwd]
section
label.label= t('admin:system.administrativetools')
.section-block
h6 #{t('admin:system.flushcache')}:
p.is-small= t('admin:system.flushcachetext')
p: button.button.is-teal.is-outlined(v-on:click='flushcache')= t('admin:system.flushcachebtn')
h6 #{t('admin:system.resetaccounts')}:
p.is-small= t('admin:system.resetaccountstext')
p: button.button.is-teal.is-outlined(v-on:click='resetaccounts')= t('admin:system.resetaccountsbtn')
h6 #{t('admin:system.flushsessions')}:
p.is-small= t('admin:system.flushsessionstext')
p: button.button.is-teal.is-outlined(v-on:click='flushsessions')= t('admin:system.flushsessionsbtn')
modal-upgrade-system

32
server/views/admin/theme.pug

@ -1,32 +0,0 @@
extends ./_layout.pug
block adminContent
.hero
h1.title#title= t('nav.theme')
h2.subtitle= t('admin:theme.subtitle')
i.pageicon.nc-icon-outline.ui-1_drop
admin-theme(inline-template, themedata=JSON.stringify(appconfig.theme))
.form-sections
section
label.label= t('admin:theme.primarycolor')
color-picker(v-model='primary')
span.desc= t('admin:theme.primarycolordesc')
section
label.label= t('admin:theme.altcolor')
color-picker(v-model='alt')
span.desc= t('admin:theme.altcolordesc')
section
label.label= t('admin:theme.footercolor')
color-picker(v-model='footer')
span.desc= t('admin:theme.footercolordesc')
section
label.label= t('admin:theme.codeblock.title')
toggle(v-model='codedark', desc=t('admin:theme.codeblock.dark'))
toggle(v-model='codecolorize', desc=t('admin:theme.codeblock.colorize'))
section
button.button.is-grey(@click='resetTheme')
i.nc-icon-outline.design_paint-37
span= t('admin:theme.reset')
button.button.is-green(@click='saveTheme')
i.nc-icon-outline.ui-1_check
span= t('admin:theme.savechanges')

122
server/views/admin/users-edit.pug

@ -1,122 +0,0 @@
extends ./_layout.pug
block rootNavRight
loading-spinner
.nav-item
a.button(href='/admin/users')
i.nc-icon-outline.arrows-2_corner-left-round
span= t('admin:users.returntousers')
block adminContent
admin-edit-user(inline-template, usrdata=JSON.stringify(usr))
div
.hero
h1.title= t('admin:users.edituser')
h2.subtitle= usr.email
i.pageicon.nc-icon-outline.users_single-05
table.table
thead
tr
th= t('admin:users.uniqueid')
th= t('admin:users.provider')
th= t('admin:users.createdon')
th= t('admin:users.updatedon')
tbody
tr
td.is-centered= usr._id
td.is-centered.has-icons
case usr.provider
when 'local': i.nc-icon-outline.ui-1_database
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.' + usr.provider)
td.is-centered= moment(usr.createdAt).format('lll')
td.is-centered= moment(usr.updatedAt).format('lll')
.form-sections
section
label.label= t('admin:profile.email')
p.control.is-fullwidth
input.input(type='text', placeholder='john.smith@example.com', v-model='email', disabled=!usrOpts.canChangeEmail)
section
label.label= t('admin:profile.displayname')
p.control.is-fullwidth
input.input(type='text', placeholder=t('admin:profile.displaynameexample'), v-model='name', disabled=!usrOpts.canChangeName)
if usrOpts.canChangePassword
section
label.label= t('admin:profile.password')
p.control.is-fullwidth
input.input(type='password', placeholder=t('admin:profile.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.nc-icon-outline.ui-2_square-add-08.is-green(v-if='right.deny === false || right.deny === "false"')
i.nc-icon-outline.ui-2_square-delete-10.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.nc-icon-outline.ui-1_simple-add
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.nc-icon-outline.ui-1_check
span Save Changes
a.button.button.is-grey.is-outlined(href='/admin/users')
i.nc-icon-outline.ui-1_simple-remove
span Discard
.column.is-narrow
section
if usrOpts.canBeDeleted
button.button.is-red(v-on:click='$store.dispatch("modalDeleteUser/open")')
i.nc-icon-outline.ui-1_trash
span Delete Account
modal-delete-user(current-user=usr._id)

47
server/views/admin/users.pug

@ -1,47 +0,0 @@
extends ./_layout.pug
block rootNavRight
loading-spinner
.nav-item
a.button(v-on:click='$store.dispatch("modalCreateUser/open")')
i.nc-icon-outline.ui-1_simple-add
span= t('admin:users.createauthorize')
block adminContent
.hero
h1.title#title= t('nav.users')
h2.subtitle= t('admin:users.subtitle')
i.pageicon.nc-icon-outline.users_multiple-19
table.table
thead
tr
th
th= t('admin:users.name')
th= t('admin:users.email')
th= t('admin:users.provider')
th= t('admin:users.createdon')
th= t('admin:users.updatedon')
tbody
each usr in usrs
tr
td.is-icon
i.nc-icon-outline.users_single-05.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.nc-icon-outline.ui-1_database
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.' + usr.provider)
td.is-centered= moment(usr.createdAt).format('lll')
td.is-centered= moment(usr.updatedAt).format('lll')
modal-create-user

14
server/views/common/alerts.pug

@ -1,14 +0,0 @@
#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

@ -1,8 +0,0 @@
footer.footer(class=['is-' + appconfig.theme.footer], ref='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')

19
server/views/common/header.pug

@ -1,19 +0,0 @@
#header-container
nav.nav#header(class=['is-' + appconfig.theme.primary], ref='header')
.nav-left
block rootNavLeft
a.nav-item(href='/')
h1
i.nc-icon-outline.ui-2_layers
= appconfig.title
.nav-center
block rootNavCenter
search
span.nav-toggle
span
span
span
.nav-right
block rootNavRight
loading-spinner

0
server/views/common/mixins.pug

server/views/main/editor.pug → server/views/editor.pug

@ -1,6 +1,6 @@
extends ../master.pug
extends master.pug
block body
#app
#root
v-app
editor

4
server/views/error.pug

@ -1,7 +1,7 @@
extends ./master.pug
extends master.pug
block body
#app.is-fullscreen
#root.is-fullscreen
v-app(dark)
.app-error
v-container

30
server/views/errors/error-forbidden.pug

@ -1,30 +0,0 @@
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=appconfig.host + '/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=appconfig.host + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
link(rel='icon', type='image/png', sizes='192x192', href=appconfig.host + '/favicons/android-icon-192x192.png')
each favsize in [32, 96, 16]
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/favicon-' + favsize + 'x' + favsize + '.png')
link(rel='manifest', href=appconfig.host + '/manifest.json')
// JS / CSS
script(type='text/javascript', src=appconfig.host + '/js/vendor.js')
script(type='text/javascript', src=appconfig.host + '/js/app.js')
body(class='is-forbidden')
.container
a(href='/'): img(src=appconfig.host + '/images/logo.png')
h1= t('errors:forbidden')
h2= t('errors:forbiddendetail')
a.button.is-amber.is-inverted(href=appconfig.host + '/')= t('errors:actions.gohome')
a.button.is-amber.is-inverted(href=appconfig.host + '/login')= t('errors:actions.loginas')

30
server/views/errors/error-notexist.pug

@ -1,30 +0,0 @@
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=appconfig.host + '/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=appconfig.host + '/favicons/apple-icon-' + favsize + 'x' + favsize + '.png')
link(rel='icon', type='image/png', sizes='192x192', href=appconfig.host + '/favicons/android-icon-192x192.png')
each favsize in [32, 96, 16]
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href=appconfig.host + '/favicons/favicon-' + favsize + 'x' + favsize + '.png')
link(rel='manifest', href=appconfig.host + '/manifest.json')
// JS / CSS
script(type='text/javascript', src=appconfig.host + '/js/vendor.js')
script(type='text/javascript', src=appconfig.host + '/js/app.js')
body(class='is-notexist')
.container
a(href='/'): img(src=appconfig.host + '/images/logo.png')
h1 !{message}
h2= t('errors:notexistdetail')
a.button.is-amber.is-inverted.is-featured(href=appconfig.host + '/create/' + newpath)= t('errors:actions.create')
a.button.is-amber.is-inverted(href=appconfig.host + '/')= t('errors:actions.gohome')

11
server/views/layout.pug

@ -1,11 +0,0 @@
extends ./master.pug
block body
body
#app
navigator
main
block content
footer
block outside

5
server/views/login.pug

@ -0,0 +1,5 @@
extends master.pug
block body
#root.is-fullscreen
login

5
server/views/main/admin.pug

@ -1,5 +0,0 @@
extends ../master.pug
block body
#app
admin

5
server/views/main/login.pug

@ -1,5 +0,0 @@
extends ../master.pug
block body
#app.is-fullscreen
login

5
server/views/main/profile.pug

@ -1,5 +0,0 @@
extends ../master.pug
block body
#app
profile

server/views/main/page.pug → server/views/page.pug

@ -1,9 +1,9 @@
extends ../master.pug
extends master.pug
block head
block body
#app
#root
page(title='Planet Earth', description='The 3rd planet of the solar system')
template(slot='contents')
p Earth is the third planet from the Sun and the only astronomical object known to harbor life. According to radiometric dating and other sources of evidence, Earth formed over 4.5 billion years ago.[24][25][26] Earth's gravity interacts with other objects in space, especially the Sun and the Moon, Earth's only natural satellite. Earth revolves around the Sun in 365.26 days, a period known as an Earth year. During this time, Earth rotates about its axis about 366.26 times.[n 5]

5
server/views/profile.pug

@ -0,0 +1,5 @@
extends master.pug
block body
#root
profile

server/views/main/setup.pug → server/views/setup.pug

@ -1,5 +1,5 @@
extends ../master.pug
extends master.pug
block body
#app
#root
setup(telemetry-id=telemetryClientID, wiki-version=packageObj.version)

server/views/main/welcome.pug → server/views/welcome.pug

@ -1,7 +1,7 @@
extends ../master.pug
extends master.pug
block body
#app.is-fullscreen
#root.is-fullscreen
v-app
.onboarding
img.animated.fadeIn(src='/svg/logo-wikijs.svg', alt='Wiki.js')

14
yarn.lock

@ -12524,6 +12524,12 @@ vue-simple-breakpoints@1.0.3:
dependencies:
simple-breakpoints "^1.1.1"
vue-status-indicator@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/vue-status-indicator/-/vue-status-indicator-1.1.0.tgz#53f69fe62950f0291e00331ae63379221e6f1c8e"
dependencies:
vue "^2.5.11"
vue-style-loader@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.0.tgz#7588bd778e2c9f8d87bfc3c5a4a039638da7a863"
@ -12550,11 +12556,17 @@ vue-tour@1.0.1:
popper.js "^1.12.9"
vue "^2.5.13"
vue-tree-navigation@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/vue-tree-navigation/-/vue-tree-navigation-3.0.1.tgz#1225f10ad7725ad03aeb8414116aa92e589dc720"
dependencies:
vue "^2.5.11"
vue@2.5.16, vue@^2.5.13:
version "2.5.16"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
vue@2.5.17:
vue@2.5.17, vue@^2.5.11:
version "2.5.17"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"

Loading…
Cancel
Save