feat: xterm + UI fixes

This commit is contained in:
Nicolas Giard 2018-08-13 00:12:44 -04:00
parent 453c1beab3
commit c4c1cf007b
11 changed files with 238 additions and 83 deletions

View File

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

View File

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

View File

@ -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;
}
span {
color: mc('blue', '300');
&.altbg {
background: mc('theme', 'primary');
span {
color: mc('blue', '300');
}
a {
color: mc('blue', '200');
}
}
}
</style>

View File

@ -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;

View File

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

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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';

View File

@ -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%",

View File

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

View File

@ -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"