Начальная реализация паттернов

This commit is contained in:
saber-nyan 2019-05-11 03:35:37 +03:00
parent 04839c3a26
commit cf548de895
No known key found for this signature in database
GPG Key ID: 7B069E9C295E6B4A
4 changed files with 111 additions and 30 deletions

View File

@ -0,0 +1,16 @@
<template>
<div class="dropdown-item" :style="'color:' + color">
{{name}}: {{value}}
</div>
</template>
<script>
export default {
name: "FlagPattern",
props: ['name', 'value', 'color',],
}
</script>
<style scoped>
</style>

View File

@ -1,6 +1,27 @@
<template>
<nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow navbar-expand-lg navbar-expand">
<router-link to="/" class="navbar-brand col-sm-3 col-md-2 mr-0">Packmate</router-link>
<!-- <router-link to="/" class="navbar-brand col-sm-3 col-md-2 mr-0">Packmate</router-link>-->
<div class="dropdown">
<button class="btn btn-dark dropdown-toggle" type="button" data-toggle="dropdown">
Паттерны
</button>
<div class="dropdown-menu">
<div class="input-group">
<input type="text" class="form-control" placeholder="Name" v-model="newPattern.name">
<input type="text" class="form-control" placeholder="Value" v-model="newPattern.value">
<input type="text" class="form-control" placeholder="#Color" v-model="newPattern.color">
<div class="input-group-append">
<button @click.prevent="createPattern()" class="btn btn-outline-primary" type="button">+</button>
</div>
</div>
<FlagPattern v-for="pattern in patterns"
:key="pattern.id"
:name="pattern.name"
:value="pattern.value"
:color="pattern.color"></FlagPattern>
</div>
</div>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
@ -40,12 +61,20 @@
<script>
import CtfService from "@/components/CtfService.vue";
import axios from "axios";
import $ from "jquery";
import FlagPattern from "@/components/FlagPattern.vue";
export default {
name: "Navbar",
data: function () {
return {
ctfServices: [],
patterns: [],
newPattern: {
name: '',
value: '',
color: '',
},
}
},
methods: {
@ -65,11 +94,59 @@ export default {
.then(response => (this.ctfServices = response.data))
.catch(error => console.error('Failed to load CTF services!', error))
},
getPatterns() {
const instance = axios.create({
baseURL: this.$store.state.apiUrl,
auth: {
username: this.$store.state.apiLogin,
password: this.$store.state.apiPassword,
},
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
instance.get('/pattern/')
.then(response => (this.patterns = response.data))
.catch(error => console.error('Failed to load patterns!', error));
},
createPattern() {
const instance = axios.create({
baseURL: this.$store.state.apiUrl,
auth: {
username: this.$store.state.apiLogin,
password: this.$store.state.apiPassword,
},
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
instance.post('/pattern/', this.newPattern)
.then(response => {
console.debug('got r', response.data);
this.getPatterns();
})
.catch(error => console.error('failed to create pattern', error));
},
},
mounted() {
this.getCtfServices();
this.getPatterns();
const dropdown = $('.dropdown');
dropdown.on('show.bs.dropdown', function () {
$(this).find('.dropdown-menu').first().stop(true, true).slideDown();
});
dropdown.on('hide.bs.dropdown', function () {
$(this).find('.dropdown-menu').first().stop(true, true).slideUp();
});
$('.dropdown-menu').on("click.bs.dropdown", function (e) {
e.stopPropagation();
e.preventDefault();
});
},
components: {CtfService,},
components: {FlagPattern, CtfService,},
}
</script>
@ -77,30 +154,6 @@ export default {
li {
margin-left: 10px;
}
.navbar-brand {
padding-top: .75rem;
padding-bottom: .75rem;
font-size: 1rem;
background-color: rgba(0, 0, 0, .25);
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
}
.navbar .form-control {
padding: .75rem 1rem;
border-width: 0;
border-radius: 0;
}
.form-control-dark {
color: #fff;
background-color: rgba(255, 255, 255, .1);
border-color: rgba(255, 255, 255, .1);
}
.form-control-dark:focus {
border-color: transparent;
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
}
svg {
position: absolute;
@ -108,4 +161,14 @@ export default {
bottom: 50%;
transform: translate(-50%, -50%);
}
.dropdown-menu {
min-width: 300px;
}
.input-group {
padding-left: 10px;
padding-right: 10px;
padding-bottom: 5px;
}
</style>

View File

@ -91,7 +91,7 @@ export default {
bottom: 0;
left: 0;
z-index: 100; /* Behind the navbar */
padding: 48px 0 0; /* Height of navbar */
padding: 48px 0 0 !important; /* Height of navbar */
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
}
@ -99,7 +99,7 @@ export default {
position: relative;
top: 0;
height: calc(100vh - 48px);
padding-top: .5rem;
/*padding-top: .5rem;*/
overflow-x: hidden;
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
}

View File

@ -4,6 +4,7 @@
<div class="container-fluid">
<div class="row">
<Sidebar ref="sidebar" :servicePort="servicePort" :streamId="streamId"></Sidebar>
<!--suppress HtmlDeprecatedTag -->
<Content :servicePort="servicePort" :streamId="streamId"></Content>
</div>
</div>
@ -40,6 +41,7 @@ export default {
methods: {
reloadNavbar() {
this.$refs.navbar.getCtfServices();
this.$refs.navbar.getPatterns();
},
connectWs() {
const wsUrl = this.$store.state.apiUrl + '/ws';
@ -52,7 +54,7 @@ export default {
};
this.socket.onclose = function (ev) {
console.debug('WS disconnected', ev.code, ev.reason);
if (ev.code === 1008) {
if (ev.code === 1008) { // FIXME: выключить security timeout (This connection was established under an authenticated HTTP session that has ended.)
console.info('Security timeout, reconnecting...');
this.connectWs();
}
@ -74,7 +76,7 @@ export default {
},
mounted() {
this.connectWs();
this.navbarTimer = setInterval(this.reloadNavbar, 4000); // TODO: некрасиво, лучше ловить через WS
this.navbarTimer = setInterval(this.reloadNavbar, 5000); // TODO: некрасиво, лучше ловить через WS
},
beforeDestroy() {
this.socket.close();