Browse Source

feat: xterm + UI fixes

Nicolas Giard 6 years ago
parent
commit
c4c1cf007b

+ 83 - 0
client/components/admin/admin-logging-console.vue

@@ -0,0 +1,83 @@
+<template lang='pug'>
+  v-dialog(v-model='isShown', width='90vw', max-width='1200')
+    .dialog-header
+      span Live Console
+      v-spacer
+      .caption.blue--text.text--lighten-3.mr-3 Streaming...
+      v-progress-circular(
+        indeterminate
+        color='blue lighten-3'
+        :size='20'
+        :width='2'
+        )
+    .consoleTerm(ref='consoleContainer')
+    v-toolbar(flat, color='grey darken-3', dark)
+      v-spacer
+      v-btn(outline, @click='clear')
+        v-icon(left) cancel_presentation
+        span Clear
+      v-btn(outline, @click='close')
+        v-icon(left) close
+        span Close
+</template>
+
+<script>
+import _ from 'lodash'
+import { Terminal } from 'xterm'
+import * as fit from 'xterm/lib/addons/fit/fit'
+
+Terminal.applyAddon(fit)
+
+export default {
+  term: null,
+  props: {
+    value: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    isShown: {
+      get() { return this.value },
+      set(val) { this.$emit('input', val) }
+    }
+  },
+  watch: {
+    value(newValue, oldValue) {
+      if (newValue) {
+        _.delay(() => {
+          this.term = new Terminal()
+          this.term.open(this.$refs.consoleContainer)
+          this.term.writeln('Connecting to \x1B[1;3;31mconsole output\x1B[0m...')
+        }, 100)
+      } else {
+        this.term.dispose()
+        this.term = null
+      }
+    }
+  },
+  mounted() {
+    this.term = new Terminal()
+    this.term.open(this.$refs.consoleContainer)
+  },
+  methods: {
+    clear() {
+      this.term.clear()
+    },
+    close() {
+      this.isShown = false
+    }
+  }
+}
+</script>
+
+<style lang='scss'>
+
+.consoleTerm {
+  background-color: #000;
+  padding: 16px;
+  width: 100%;
+  height: 415px;
+}
+
+</style>

+ 11 - 8
client/components/admin/admin-logging.vue

@@ -25,7 +25,7 @@
             v-btn(color='primary')
               v-icon(left) chevron_right
               | Set Services
-            v-btn(color='black', dark)
+            v-btn(color='black', dark, @click='toggleConsole')
               v-icon(left) keyboard
               | View Console
             v-btn(color='black', dark)
@@ -45,21 +45,21 @@
               v-icon(left) chevron_right
               | Save Configuration
 
-    v-snackbar(
-      color='success'
-      top
-      v-model='refreshCompleted'
-    )
-      v-icon.mr-3(dark) cached
-      | List of logging services has been refreshed.
+    logging-console(v-model='showConsole')
 </template>
 
 <script>
 import _ from 'lodash'
 
+import LoggingConsole from './admin-logging-console.vue'
+
 export default {
+  components: {
+    LoggingConsole
+  },
   data() {
     return {
+      showConsole: false,
       services: [],
       selectedServices: ['console'],
       refreshCompleted: false
@@ -80,6 +80,9 @@ export default {
     async refresh() {
       await this.$apollo.queries.services.refetch()
       this.refreshCompleted = true
+    },
+    toggleConsole () {
+      this.showConsole = !this.showConsole
     }
   }
 }

+ 16 - 6
client/components/common/nav-footer.vue

@@ -1,8 +1,8 @@
 <template lang="pug">
   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
+      span(v-if='company && company.length > 0') {{ $t('common:footer.copyright', { company: company, year: currentYear, interpolation: { escapeValue: false } }) }} |&nbsp;
+      span {{ $t('common:footer.poweredBy') }} #[a(href='https://wiki.js.org', ref='nofollow') Wiki.js]
 
     v-snackbar(
       :color='notification.style'
@@ -50,11 +50,21 @@ export default {
 </script>
 
 <style lang="scss">
-  .v-footer.altbg {
-    background: mc('theme', 'primary');
+  .v-footer {
+    a {
+      text-decoration: none;
+    }
+
+    &.altbg {
+      background: mc('theme', 'primary');
 
-    span {
-      color: mc('blue', '300');
+      span {
+        color: mc('blue', '300');
+      }
+
+      a {
+        color: mc('blue', '200');
+      }
     }
   }
 </style>

+ 49 - 5
client/components/common/nav-header.vue

@@ -1,5 +1,21 @@
 <template lang='pug'>
-  v-toolbar(color='black', dark, app, clipped-left, fixed, flat)
+  v-toolbar.nav-header(color='black', dark, app, clipped-left, fixed, flat, :extended='searchIsShown && $vuetify.breakpoint.smAndDown')
+    v-toolbar(color='deep-purple', flat, slot='extension', v-if='searchIsShown && $vuetify.breakpoint.smAndDown')
+      v-text-field(
+        ref='searchFieldMobile',
+        v-model='search',
+        clearable,
+        background-color='deep-purple'
+        color='white',
+        label='Search...',
+        single-line,
+        solo
+        flat
+        hide-details,
+        prepend-inner-icon='search',
+        :loading='searchIsLoading',
+        @keyup.enter='searchEnter'
+      )
     v-menu(open-on-hover, offset-y, bottom, left, min-width='250')
       v-toolbar-side-icon(slot='activator')
         v-icon view_module
@@ -32,9 +48,9 @@
         v-list-tile(avatar, @click='')
           v-list-tile-avatar: v-icon(color='blue-grey') burst_mode
           v-list-tile-content Images &amp; Files
-    v-toolbar-title.ml-2
+    v-toolbar-title(:class='{ "ml-2": $vuetify.breakpoint.mdAndUp, "ml-0": $vuetify.breakpoint.smAndDown }')
       span.subheading {{title}}
-    v-spacer
+    v-spacer(v-if='searchIsShown && $vuetify.breakpoint.mdAndUp')
     transition(name='navHeaderSearch')
       v-text-field(
         ref='searchField',
@@ -61,7 +77,11 @@
     .navHeaderLoading.mr-3
       v-progress-circular(indeterminate, color='blue', :size='22', :width='2' v-show='isLoading')
     slot(name='actions')
-    v-btn(v-if='searchIsShown && $vuetify.breakpoint.smAndDown', icon)
+    v-btn(
+      v-if='!hideSearch && $vuetify.breakpoint.smAndDown'
+      @click='searchToggle'
+      icon
+      )
       v-icon(color='grey') search
     v-tooltip(bottom)
       v-btn(icon, href='/a', slot='activator')
@@ -90,6 +110,7 @@
 
 <script>
 import { get } from 'vuex-pathify'
+import _ from 'lodash'
 
 export default {
   props: {
@@ -115,11 +136,19 @@ export default {
     title: get('site/title')
   },
   created() {
-    if (this.hideSearch || this.dense) {
+    if (this.hideSearch || this.dense || this.$vuetify.breakpoint.smAndDown) {
       this.searchIsShown = false
     }
   },
   methods: {
+    searchToggle() {
+      this.searchIsShown = !this.searchIsShown
+      if (this.searchIsShown) {
+        _.delay(() => {
+          this.$refs.searchFieldMobile.focus()
+        }, 200)
+      }
+    },
     searchEnter() {
       this.searchIsLoading = true
     },
@@ -146,6 +175,21 @@ export default {
 </script>
 
 <style lang='scss'>
+
+.nav-header {
+  .v-toolbar__extension {
+    padding: 0;
+
+    .v-toolbar__content {
+      padding: 0;
+    }
+    .v-text-field .v-input__prepend-inner {
+      padding: 0 14px 0 5px;
+      padding-right: 14px;
+    }
+  }
+}
+
 .navHeaderSearch {
   &-enter-active, &-leave-active {
     transition: opacity .25s ease, transform .25s ease;

+ 23 - 10
client/components/editor.vue

@@ -2,16 +2,29 @@
   .editor
     nav-header(dense)
       template(slot='actions')
-        v-btn(outline, color='green', @click.native.stop='save')
-          v-icon(color='green', left) check
-          span.white--text(v-if='mode === "create"') {{ $t('common:actions.create') }}
-          span.white--text(v-else) {{ $t('common:actions.save') }}
-        v-btn(outline, color='red').mx-0
-          v-icon(color='red', left) close
-          span.white--text {{ $t('common:actions.discard') }}
-        v-btn(outline, color='blue', @click.native.stop='openModal(`properties`)', dark)
-          v-icon(left) sort_by_alpha
-          span.white--text {{ $t('editor:page') }}
+        v-btn(
+          outline
+          color='green'
+          @click.native.stop='save'
+          :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'
+          )
+          v-icon(color='green', :left='$vuetify.breakpoint.lgAndUp') check
+          span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ mode === 'create' ? $t('common:actions.create') : $t('common:actions.save') }}
+        v-btn.mx-0(
+          outline
+          color='red'
+          :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'
+          )
+          v-icon(color='red', :left='$vuetify.breakpoint.lgAndUp') close
+          span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('common:actions.discard') }}
+        v-btn(
+          outline
+          color='blue'
+          @click.native.stop='openModal(`properties`)'
+          :class='{ "is-icon": $vuetify.breakpoint.mdAndDown }'
+          )
+          v-icon(color='blue', :left='$vuetify.breakpoint.lgAndUp') sort_by_alpha
+          span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:page') }}
     v-content
       editor-code
       component(:is='currentModal')

+ 46 - 52
client/components/editor/editor-code.vue

@@ -1,58 +1,54 @@
 <template lang='pug'>
   .editor-code
     v-toolbar.editor-code-toolbar(dense, color='primary', dark)
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Bold
-          use(xlink:href='#fa-bold')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Italic
-          use(xlink:href='#fa-italic')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Strikethrough
-          use(xlink:href='#fa-strikethrough')
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon format_bold
+        span Bold
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon format_italic
+        span Italic
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon format_strikethrough
+        span Strikethrough
       v-menu(offset-y, open-on-hover)
         v-btn(icon, slot='activator').mx-0
-          svg.icons.is-18(role='img')
-            title Heading
-            use(xlink:href='#fa-heading')
+          v-icon font_download
         v-list
           v-list-tile(v-for='(n, idx) in 6', @click='', :key='idx')
             v-list-tile-action
-              svg.icons.is-18(role='img')
-                title Heading {{n}}
-                use(xlink:href='#fa-heading')
+              v-icon font_download
             v-list-tile-title Heading {{n}}
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Blockquote
-          use(xlink:href='#fa-quote-left')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Unordered List
-          use(xlink:href='#fa-list-ul')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Ordered List
-          use(xlink:href='#fa-list-ol')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Link
-          use(xlink:href='#fa-link')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Inline Code
-          use(xlink:href='#fa-terminal')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Code Block
-          use(xlink:href='#fa-code')
-      v-btn(icon).mx-0
-        svg.icons.is-18(role='img')
-          title Horizontal Bar
-          use(xlink:href='#fa-minus')
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon format_quote
+        span Blockquote
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon format_list_bulleted
+        span Unordered List
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon format_list_numbered
+        span Ordered List
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon insert_link
+        span Link
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon space_bar
+        span Inline Code
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon code
+        span Code Block
+      v-tooltip(top)
+        v-btn(icon, slot='activator').mx-0
+          v-icon remove
+        span Horizontal Bar
 
     .editor-code-main
       .editor-code-editor
@@ -361,13 +357,11 @@ export default {
     background-image: linear-gradient(to bottom, mc('blue', '700') 0%, mc('blue','800') 100%);
     color: #FFF;
 
-    @include until($tablet) {
-      justify-content: center;
-    }
+    .v-toolbar__content {
+      padding-left: 16px;
 
-    svg {
-      use {
-        color: #FFF;
+      @include until($tablet) {
+        padding-left: 8px;
       }
     }
   }

+ 2 - 0
client/components/login.vue

@@ -265,6 +265,7 @@ export default {
       left: 0;
       width: 100vw;
       height: 25vh;
+      z-index: 1;
     }
 
     &-mascot {
@@ -289,6 +290,7 @@ export default {
       box-shadow: 0 14px 28px rgba(0,0,0,0.2);
       border-radius: 6px;
       animation: zoomIn .5s ease;
+      z-index: 2;
 
       &::after {
         position: absolute;

+ 1 - 0
client/scss/app.scss

@@ -14,6 +14,7 @@
 @import '../libs/prism/prism.css';
 @import '~vue-tour/dist/vue-tour.css';
 @import '~vue-status-indicator/styles.css';
+@import '~xterm/dist/xterm.css';
 // @import 'node_modules/diff2html/dist/diff2html.min';
 
 @import 'pages/welcome';

+ 2 - 1
package.json

@@ -254,7 +254,8 @@
     "webpack-hot-middleware": "2.22.3",
     "webpack-merge": "4.1.4",
     "whatwg-fetch": "2.0.4",
-    "write-file-webpack-plugin": "4.3.2"
+    "write-file-webpack-plugin": "4.3.2",
+    "xterm": "3.6.0"
   },
   "browserslist": [
     "> 1%",

+ 1 - 1
server/modules/authentication/cas/definition.yml

@@ -3,7 +3,7 @@ title: CAS
 description: The Central Authentication Service (CAS) is a single sign-on protocol for the web.
 author: requarks.io
 logo: https://static.requarks.io/logo/cas.svg
-website: https://wiki.js.org
+website: https://apereo.github.io/cas/
 useForm: false
 props:
   ssoBaseURL: String

+ 4 - 0
yarn.lock

@@ -12983,6 +12983,10 @@ xtend@^4.0.0, xtend@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
 
+xterm@3.6.0:
+  version "3.6.0"
+  resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.6.0.tgz#9b95cd23a338e5842343aec1a104f094c5153e7c"
+
 y18n@^3.2.1:
   version "3.2.1"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"