updated README.md

code cleanup
This commit is contained in:
Marvin Zhang
2019-04-03 19:58:21 +08:00
parent 2895aebc01
commit 563ecea96f
92 changed files with 38 additions and 7829 deletions

View File

@@ -1,228 +0,0 @@
<template>
<div class="wscn-http404-container">
<div class="wscn-http404">
<div class="pic-404">
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
</div>
<div class="bullshit">
<div class="bullshit__oops">OOPS!</div>
<div class="bullshit__info">版权所有
<a class="link-type" href="https://wallstreetcn.com" target="_blank">华尔街见闻</a>
</div>
<div class="bullshit__headline">{{ message }}</div>
<div class="bullshit__info">请检查您输入的网址是否正确请点击以下按钮返回主页或者发送错误报告</div>
<a href="" class="bullshit__return-home">返回首页</a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Page404',
computed: {
message () {
return '网管说这个页面你不能进......'
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.wscn-http404-container{
transform: translate(-50%,-50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #222;
font-weight: bold;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>

View File

@@ -1,32 +0,0 @@
<template>
<div class="dashboard-container">
<div class="dashboard-text">name:{{ name }}</div>
<div class="dashboard-text">roles:<span v-for="role in roles" :key="role">{{ role }}</span></div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'Dashboard',
computed: {
...mapGetters([
'name',
'roles'
])
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard {
&-container {
margin: 30px;
}
&-text {
font-size: 30px;
line-height: 46px;
}
}
</style>

View File

@@ -1,32 +0,0 @@
<template>
<div class="dashboard-container">
<div class="dashboard-text">name:{{ name }}</div>
<div class="dashboard-text">roles:<span v-for="role in roles" :key="role">{{ role }}</span></div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'Dashboard',
computed: {
...mapGetters([
'name',
'roles'
])
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard {
&-container {
margin: 30px;
}
&-text {
font-size: 30px;
line-height: 46px;
}
}
</style>

View File

@@ -1,15 +0,0 @@
<template>
<div class="">
NodeDetail
</div>
</template>
<script>
export default {
name: 'NodeDetail'
}
</script>
<style scoped>
</style>

View File

@@ -1,84 +0,0 @@
<template>
<div class="app-container">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"/>
<el-option label="Zone two" value="beijing"/>
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;"/>
</el-col>
<el-col :span="2" class="line">-</el-col>
<el-col :span="11">
<el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;"/>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery"/>
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type"/>
<el-checkbox label="Promotion activities" name="type"/>
<el-checkbox label="Offline activities" name="type"/>
<el-checkbox label="Simple brand exposure" name="type"/>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor"/>
<el-radio label="Venue"/>
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input v-model="form.desc" type="textarea"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button @click="onCancel">Cancel</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data () {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
onSubmit () {
this.$message('submit!')
},
onCancel () {
this.$message({
message: 'cancel!',
type: 'warning'
})
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -1,84 +0,0 @@
<template>
<div class="app-container">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"/>
<el-option label="Zone two" value="beijing"/>
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;"/>
</el-col>
<el-col :span="2" class="line">-</el-col>
<el-col :span="11">
<el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;"/>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery"/>
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type"/>
<el-checkbox label="Promotion activities" name="type"/>
<el-checkbox label="Offline activities" name="type"/>
<el-checkbox label="Simple brand exposure" name="type"/>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor"/>
<el-radio label="Venue"/>
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input v-model="form.desc" type="textarea"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button @click="onCancel">Cancel</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data () {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
onSubmit () {
this.$message('submit!')
},
onCancel () {
this.$message({
message: 'cancel!',
type: 'warning'
})
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -1,160 +0,0 @@
<template>
<div class="app-container">
<el-row>
<ul class="metric-list">
<li class="metric-item" v-for="m in metrics" @click="onClickMetric(m)" :key="m.name">
<el-card class="metric-card" shadow="hover">
<el-col :span="6" class="icon-col">
<i :class="m.icon" :style="{color:m.color}"></i>
</el-col>
<el-col :span="18" class="text-col">
<el-row>
<label class="label">{{$t(m.label)}}</label>
</el-row>
<el-row>
<div class="value">{{overviewStats[m.name]}}</div>
</el-row>
</el-col>
</el-card>
</li>
</ul>
</el-row>
<el-row>
<el-card shadow="hover">
<h4 class="title">{{$t('Daily New Tasks')}}</h4>
<div id="echarts-daily-tasks" class="echarts-box"></div>
</el-card>
</el-row>
</div>
</template>
<script>
import request from '../../api/request'
import echarts from 'echarts'
export default {
name: 'Home',
data () {
return {
echarts: {},
overviewStats: {},
dailyTasks: [],
metrics: [
{ name: 'task_count', label: 'Total Tasks', icon: 'fa fa-play', color: '#f56c6c', path: 'tasks' },
{ name: 'spider_count', label: 'Spiders', icon: 'fa fa-bug', color: '#67c23a', path: 'spiders' },
{ name: 'node_count', label: 'Active Nodes', icon: 'fa fa-server', color: '#409EFF', path: 'nodes' },
{ name: 'deploy_count', label: 'Total Deploys', icon: 'fa fa-cloud', color: '#409EFF', path: 'deploys' }
]
}
},
methods: {
initEchartsDailyTasks () {
const option = {
xAxis: {
type: 'category',
data: this.dailyTasks.map(d => d.date)
},
yAxis: {
type: 'value'
},
series: [{
data: this.dailyTasks.map(d => d.count),
type: 'line',
areaStyle: {},
smooth: true
}],
tooltip: {
trigger: 'axis',
show: true
}
}
this.echarts.dailyTasks = echarts.init(this.$el.querySelector('#echarts-daily-tasks'))
this.echarts.dailyTasks.setOption(option)
},
onClickMetric (m) {
this.$router.push(`/${m.path}`)
}
},
created () {
request.get('/stats/get_home_stats')
.then(response => {
// overview stats
this.overviewStats = response.data.overview_stats
// daily tasks
this.dailyTasks = response.data.daily_tasks
this.initEchartsDailyTasks()
})
}
}
</script>
<style scoped lang="scss">
.metric-list {
margin-top: 0;
padding-left: 0;
list-style: none;
display: flex;
font-size: 16px;
.metric-item:last-child .metric-card {
margin-right: 0;
}
.metric-item {
flex-basis: 25%;
.metric-card:hover {
}
.metric-card {
margin-right: 30px;
cursor: pointer;
.icon-col {
text-align: right;
i {
margin-bottom: 15px;
font-size: 56px;
}
}
.text-col {
padding-left: 20px;
height: 76px;
text-align: center;
.label {
cursor: pointer;
font-size: 16px;
display: block;
height: 24px;
color: grey;
font-weight: 900;
}
.value {
font-size: 24px;
display: block;
height: 32px;
}
}
}
}
}
.title {
padding: 0;
margin: 0;
}
#echarts-daily-tasks {
height: 360px;
width: 100%;
}
.el-card {
/*border: 1px solid lightgrey;*/
}
</style>

View File

@@ -1,79 +0,0 @@
<template>
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"></div>
<sidebar class="sidebar-container"/>
<div class="main-container">
<navbar/>
<!--<tags-view/>-->
<app-main/>
</div>
</div>
</template>
<script>
import {
Navbar,
Sidebar,
AppMain
// TagsView
} from './components'
import ResizeMixin from './mixin/ResizeHandler'
export default {
name: 'Layout',
components: {
Navbar,
Sidebar,
// TagsView,
AppMain
},
mixins: [ResizeMixin],
computed: {
sidebar () {
return this.$store.state.app.sidebar
},
device () {
return this.$store.state.app.device
},
classObj () {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
},
methods: {
handleClickOutside () {
this.$store.dispatch('CloseSideBar', { withoutAnimation: false })
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "../../../src/styles/mixin.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
&.mobile.openSidebar {
position: fixed;
top: 0;
}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
</style>

View File

@@ -1,29 +0,0 @@
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<!-- or name="fade" -->
<router-view :key="key"></router-view>
<!--<router-view/>-->
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
key () {
return this.$route.name !== undefined ? this.$route.name + +new Date() : this.$route + +new Date()
}
}
}
</script>
<style scoped>
.app-main {
/*50 = navbar */
min-height: calc(100vh - 50px);
position: relative;
overflow: hidden;
}
</style>

View File

@@ -1,34 +0,0 @@
<script>
export default {
name: 'MenuItem',
functional: true,
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
}
},
render (h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
// vnodes.push(<svg-icon icon-class={icon}/>)
const style = {
'margin-right': '5px',
'z-index': 999
}
vnodes.push(<span class={icon} style={style}/>)
}
if (title) {
vnodes.push(<span class="title" slot='title'>{(title)}</span>)
}
return vnodes
}
}
</script>

View File

@@ -1,41 +0,0 @@
import store from '@/store'
const { body } = document
const WIDTH = 1024
const RATIO = 3
export default {
watch: {
$route (route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('CloseSideBar', { withoutAnimation: false })
}
}
},
beforeMount () {
window.addEventListener('resize', this.resizeHandler)
},
mounted () {
const isMobile = this.isMobile()
if (isMobile) {
store.dispatch('ToggleDevice', 'mobile')
store.dispatch('CloseSideBar', { withoutAnimation: true })
}
},
methods: {
isMobile () {
const rect = body.getBoundingClientRect()
return rect.width - RATIO < WIDTH
},
resizeHandler () {
if (!document.hidden) {
const isMobile = this.isMobile()
store.dispatch('ToggleDevice', isMobile ? 'mobile' : 'desktop')
if (isMobile) {
store.dispatch('CloseSideBar', { withoutAnimation: true })
}
}
}
}
}

View File

@@ -1,209 +0,0 @@
<template>
<div class="login-container">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<h3 class="title">Crawlab</h3>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user"/>
</span>
<el-input v-model="loginForm.username" name="username" type="text" auto-complete="on"
placeholder="username"/>
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password"/>
</span>
<el-input
:type="pwdType"
v-model="loginForm.password"
name="password"
auto-complete="on"
placeholder="password"
@keyup.enter.native="handleLogin"/>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="pwdType === 'password' ? 'eye' : 'eye-open'"/>
</span>
</el-form-item>
<el-form-item>
<el-button :loading="loading" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
Sign in
</el-button>
</el-form-item>
<div class="tips">
<span style="margin-right:20px;">username: admin</span>
<span> password: admin</span>
</div>
</el-form>
</div>
</template>
<script>
import { isvalidUsername } from '@/utils/validate'
export default {
name: 'Login',
data () {
const validateUsername = (rule, value, callback) => {
if (!isvalidUsername(value)) {
callback(new Error('请输入正确的用户名'))
} else {
callback()
}
}
const validatePass = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error('密码不能小于5位'))
} else {
callback()
}
}
return {
loginForm: {
username: 'admin',
password: 'admin'
},
loginRules: {
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePass }]
},
loading: false,
pwdType: 'password',
redirect: undefined
}
},
watch: {
// $route: {
// handler: function (route) {
// this.redirect = route.query && route.query.redirect
// },
// immediate: true
// }
},
methods: {
showPwd () {
if (this.pwdType === 'password') {
this.pwdType = ''
} else {
this.pwdType = 'password'
}
},
handleLogin () {
this.$router.push('/')
// this.$refs.loginForm.validate(valid => {
// if (valid) {
// this.loading = true
// this.$store.dispatch('Login', this.loginForm).then(() => {
// this.loading = false
// this.$router.push({ path: this.redirect || '/' })
// }).catch(() => {
// this.loading = false
// })
// } else {
// console.log('error submit!!')
// return false
// }
// })
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
$bg: #2d3a4b;
$light_gray: #eee;
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
&:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: #fff !important;
}
}
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
position: fixed;
height: 100%;
width: 100%;
background-color: $bg;
.login-form {
position: absolute;
left: 0;
right: 0;
width: 520px;
max-width: 100%;
padding: 35px 35px 15px 35px;
margin: 120px auto;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title {
font-size: 26px;
font-weight: 400;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
}
</style>

View File

@@ -1,7 +0,0 @@
<template >
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1">
<router-view />
</el-alert>
</div>
</template>

View File

@@ -1,7 +0,0 @@
<template >
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1">
<router-view />
</el-alert>
</div>
</template>

View File

@@ -1,7 +0,0 @@
<template >
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-1" type="success">
<router-view />
</el-alert>
</div>
</template>

View File

@@ -1,7 +0,0 @@
<template >
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-1" type="success">
<router-view />
</el-alert>
</div>
</template>

View File

@@ -1,7 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2" type="success">
<router-view />
</el-alert>
</div>
</template>

View File

@@ -1,7 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2" type="success">
<router-view />
</el-alert>
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-1" type="warning" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-1" type="warning" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-2" type="warning" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-2" type="warning" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-3" type="success" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-3" type="success" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 2" />
</div>
</template>

View File

@@ -1,5 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 2" />
</div>
</template>

View File

@@ -1,98 +0,0 @@
<template>
<div class="app-container">
<!--selector-->
<div class="selector">
<label class="label">{{$t('Node')}}: </label>
<el-select v-model="nodeForm._id" @change="onNodeChange">
<el-option v-for="op in nodeList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
</div>
<!--tabs-->
<el-tabs v-model="activeTabName" @tab-click="onTabClick" type="card">
<el-tab-pane :label="$t('Overview')" name="overview">
<node-overview></node-overview>
</el-tab-pane>
<el-tab-pane :label="$t('Deployed Spiders')" name="spiders" v-if="false">
{{$t('Deployed Spiders')}}
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
import NodeOverview from '../../components/Overview/NodeOverview'
export default {
name: 'NodeDetail',
components: {
NodeOverview
},
data () {
return {
activeTabName: 'overview'
}
},
computed: {
...mapState('node', [
'nodeList',
'nodeForm'
])
},
methods: {
onTabClick () {
},
onNodeChange (id) {
this.$router.push(`/nodes/${id}`)
}
},
created () {
// get list of nodes
this.$store.dispatch('node/getNodeList')
// get node basic info
this.$store.dispatch('node/getNodeData', this.$route.params.id)
// get node deploy list
this.$store.dispatch('node/getDeployList', this.$route.params.id)
// get node task list
this.$store.dispatch('node/getTaskList', this.$route.params.id)
}
}
</script>
<style scoped>
.selector {
display: flex;
align-items: center;
position: absolute;
right: 20px;
margin-top: -7px;
/*float: right;*/
z-index: 999;
}
.selector .el-select {
padding-left: 10px;
}
.label {
width: 100px;
text-align: right;
}
</style>
<style lang="scss">
.selector {
.el-select {
.el-input {
.el-input_inner {
height: 26px;
}
}
}
}
</style>

View File

@@ -1,95 +0,0 @@
<template>
<div class="app-container">
<!--selector-->
<div class="selector">
<label class="label">Spider: </label>
<el-select v-model="spiderForm._id" @change="onSpiderChange">
<el-option v-for="op in spiderList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
</div>
<!--tabs-->
<el-tabs v-model="activeTabName" @tab-click="onTabClick" type="card">
<el-tab-pane label="Overview" name="overview">
<spider-overview/>
</el-tab-pane>
<el-tab-pane label="Files" name="files">
<file-list/>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
import FileList from '../../components/FileList/FileList'
import SpiderOverview from '../../components/Overview/SpiderOverview'
export default {
name: 'NodeDetail',
components: {
FileList,
SpiderOverview
},
data () {
return {
activeTabName: 'overview'
}
},
computed: {
...mapState('spider', [
'spiderList',
'spiderForm'
]),
...mapState('file', [
'currentPath'
]),
...mapState('deploy', [
'deployList'
])
},
methods: {
onTabClick () {
},
onSpiderChange (id) {
this.$router.push(`/spiders/${id}`)
}
},
created () {
// get the list of the spiders
this.$store.dispatch('spider/getSpiderList')
// get spider basic info
this.$store.dispatch('spider/getSpiderData', this.$route.params.id)
.then(() => {
// get spider file info
this.$store.dispatch('file/getFileList', this.spiderForm.src)
})
// get spider deploys
this.$store.dispatch('spider/getDeployList', this.$route.params.id)
// get spider tasks
this.$store.dispatch('spider/getTaskList', this.$route.params.id)
}
}
</script>
<style scoped>
.selector {
display: flex;
align-items: center;
position: absolute;
right: 20px;
/*float: right;*/
z-index: 999;
margin-top: -7px;
}
.selector .el-select {
padding-left: 10px;
}
</style>

View File

@@ -1,15 +0,0 @@
<template>
<div class="app-container">
Schedule List
</div>
</template>
<script>
export default {
name: 'ScheduleList'
}
</script>
<style scoped>
</style>

View File

@@ -1,99 +0,0 @@
<template>
<div class="app-container">
<!--selector-->
<div class="selector">
<label class="label">{{$t('Spider')}}: </label>
<el-select v-model="spiderForm._id" @change="onSpiderChange">
<el-option v-for="op in spiderList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
</div>
<!--tabs-->
<el-tabs v-model="activeTabName" @tab-click="onTabClick" type="card">
<el-tab-pane :label="$t('Overview')" name="overview">
<spider-overview/>
</el-tab-pane>
<el-tab-pane :label="$t('Files')" name="files">
<file-list/>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
import FileList from '../../components/FileList/FileList'
import SpiderOverview from '../../components/Overview/SpiderOverview'
export default {
name: 'NodeDetail',
components: {
FileList,
SpiderOverview
},
data () {
return {
activeTabName: 'overview'
}
},
computed: {
...mapState('spider', [
'spiderList',
'spiderForm'
]),
...mapState('file', [
'currentPath'
]),
...mapState('deploy', [
'deployList'
])
},
methods: {
onTabClick () {
},
onSpiderChange (id) {
this.$router.push(`/spiders/${id}`)
}
},
created () {
// get the list of the spiders
this.$store.dispatch('spider/getSpiderList')
// get spider basic info
this.$store.dispatch('spider/getSpiderData', this.$route.params.id)
.then(() => {
// get spider file info
this.$store.dispatch('file/getFileList', this.spiderForm.src)
})
// get spider deploys
this.$store.dispatch('spider/getDeployList', this.$route.params.id)
// get spider tasks
this.$store.dispatch('spider/getTaskList', this.$route.params.id)
}
}
</script>
<style scoped>
.selector {
display: flex;
align-items: center;
position: absolute;
right: 20px;
/*float: right;*/
z-index: 999;
margin-top: -7px;
}
.selector .el-select {
padding-left: 10px;
}
.label {
text-align: right;
width: 80px;
}
</style>

View File

@@ -1,78 +0,0 @@
<template>
<div class="app-container">
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row>
<el-table-column align="center" label="ID" width="95">
<template slot-scope="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="Title">
<template slot-scope="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column label="Author" width="110" align="center">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
</template>
</el-table-column>
<el-table-column label="Pageviews" width="110" align="center">
<template slot-scope="scope">
{{ scope.row.pageviews }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="Display_time" width="200">
<template slot-scope="scope">
<i class="el-icon-time"/>
<span>{{ scope.row.display_time }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getList } from '@/api/table'
export default {
filters: {
statusFilter (status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
data () {
return {
list: null,
listLoading: true
}
},
created () {
this.fetchData()
},
methods: {
fetchData () {
this.listLoading = true
getList(this.listQuery).then(response => {
this.list = response.data.items
this.listLoading = false
})
}
}
}
</script>

View File

@@ -1,78 +0,0 @@
<template>
<div class="app-container">
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row>
<el-table-column align="center" label="ID" width="95">
<template slot-scope="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="Title">
<template slot-scope="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column label="Author" width="110" align="center">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
</template>
</el-table-column>
<el-table-column label="Pageviews" width="110" align="center">
<template slot-scope="scope">
{{ scope.row.pageviews }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="Display_time" width="200">
<template slot-scope="scope">
<i class="el-icon-time"/>
<span>{{ scope.row.display_time }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getList } from '@/api/table'
export default {
filters: {
statusFilter (status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
data () {
return {
list: null,
listLoading: true
}
},
created () {
this.fetchData()
},
methods: {
fetchData () {
this.listLoading = true
getList(this.listQuery).then(response => {
this.list = response.data.items
this.listLoading = false
})
}
}
}
</script>

View File

@@ -1,104 +0,0 @@
<template>
<div class="app-container">
<!--tabs-->
<el-tabs v-model="activeTabName" @tab-click="onTabClick" type="card">
<el-tab-pane :label="$t('Overview')" name="overview">
<task-overview/>
</el-tab-pane>
<el-tab-pane :label="$t('Log')" name="log">
<div class="log-view">
<pre>
{{taskLog}}
</pre>
</div>
</el-tab-pane>
<el-tab-pane :label="$t('Results')" name="results">
<general-table-view :data="taskResultsData"
:columns="taskResultsColumns"
:page-num="resultsPageNum"
:page-size="resultsPageSize"
:total="taskResultsTotalCount"/>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
import TaskOverview from '../../components/Overview/TaskOverview'
import GeneralTableView from '../../components/TableView/GeneralTableView'
export default {
name: 'TaskDetail',
components: {
GeneralTableView,
TaskOverview
},
data () {
return {
activeTabName: 'overview'
}
},
computed: {
...mapState('task', [
'taskLog',
'taskResultsData',
'taskResultsColumns',
'taskResultsTotalCount'
]),
...mapState('file', [
'currentPath'
]),
...mapState('deploy', [
'deployList'
]),
resultsPageNum: {
get () {
return this.$store.state.task.resultsPageNum
},
set (value) {
this.$store.commit('task/SET_RESULTS_PAGE_NUM', value)
}
},
resultsPageSize: {
get () {
return this.$store.state.task.resultsPageSize
},
set (value) {
this.$store.commit('task/SET_RESULTS_PAGE_SIZE', value)
}
}
},
methods: {
onTabClick () {
},
onSpiderChange (id) {
this.$router.push(`/spiders/${id}`)
}
},
created () {
this.$store.dispatch('task/getTaskData', this.$route.params.id)
this.$store.dispatch('task/getTaskLog', this.$route.params.id)
this.$store.dispatch('task/getTaskResults', this.$route.params.id)
}
}
</script>
<style scoped>
.selector {
display: flex;
align-items: center;
position: absolute;
right: 20px;
/*float: right;*/
z-index: 999;
margin-top: -7px;
}
.selector .el-select {
padding-left: 10px;
}
</style>

View File

@@ -1,77 +0,0 @@
<template>
<div class="app-container">
<el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;"/>
<el-tree
ref="tree2"
:data="data2"
:props="defaultProps"
:filter-node-method="filterNode"
class="filter-tree"
default-expand-all
/>
</div>
</template>
<script>
export default {
data () {
return {
filterText: '',
data2: [{
id: 1,
label: 'Level one 1',
children: [{
id: 4,
label: 'Level two 1-1',
children: [{
id: 9,
label: 'Level three 1-1-1'
}, {
id: 10,
label: 'Level three 1-1-2'
}]
}]
}, {
id: 2,
label: 'Level one 2',
children: [{
id: 5,
label: 'Level two 2-1'
}, {
id: 6,
label: 'Level two 2-2'
}]
}, {
id: 3,
label: 'Level one 3',
children: [{
id: 7,
label: 'Level two 3-1'
}, {
id: 8,
label: 'Level two 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
filterText (val) {
this.$refs.tree2.filter(val)
}
},
methods: {
filterNode (value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
}
}
</script>

View File

@@ -1,77 +0,0 @@
<template>
<div class="app-container">
<el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;"/>
<el-tree
ref="tree2"
:data="data2"
:props="defaultProps"
:filter-node-method="filterNode"
class="filter-tree"
default-expand-all
/>
</div>
</template>
<script>
export default {
data () {
return {
filterText: '',
data2: [{
id: 1,
label: 'Level one 1',
children: [{
id: 4,
label: 'Level two 1-1',
children: [{
id: 9,
label: 'Level three 1-1-1'
}, {
id: 10,
label: 'Level three 1-1-2'
}]
}]
}, {
id: 2,
label: 'Level one 2',
children: [{
id: 5,
label: 'Level two 2-1'
}, {
id: 6,
label: 'Level two 2-2'
}]
}, {
id: 3,
label: 'Level one 3',
children: [{
id: 7,
label: 'Level two 3-1'
}, {
id: 8,
label: 'Level two 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
filterText (val) {
this.$refs.tree2.filter(val)
}
},
methods: {
filterNode (value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
}
}
</script>