zeus
4 years ago
21 changed files with 210 additions and 2104 deletions
@ -1 +1 @@ |
|||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="/css/app.10423c10.css" rel="preload" as="style"><link href="/css/chunk-vendors.e469b508.css" rel="preload" as="style"><link href="/js/app.de882020.js" rel="preload" as="script"><link href="/js/chunk-vendors.d8d18fe6.js" rel="preload" as="script"><link href="/css/chunk-vendors.e469b508.css" rel="stylesheet"><link href="/css/app.10423c10.css" rel="stylesheet"></head><body><div id="app"></div><script src="/js/chunk-vendors.d8d18fe6.js"></script><script src="/js/app.de882020.js"></script></body></html> |
|||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="/css/app.10423c10.css" rel="preload" as="style"><link href="/css/chunk-vendors.e469b508.css" rel="preload" as="style"><link href="/js/app.4e119b7b.js" rel="preload" as="script"><link href="/js/chunk-vendors.d8d18fe6.js" rel="preload" as="script"><link href="/css/chunk-vendors.e469b508.css" rel="stylesheet"><link href="/css/app.10423c10.css" rel="stylesheet"></head><body><div id="app"></div><script src="/js/chunk-vendors.d8d18fe6.js"></script><script src="/js/app.4e119b7b.js"></script></body></html> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,588 +0,0 @@ |
|||
<template> |
|||
<card class="card-user" style="max-height:100%"> |
|||
|
|||
<div class="author"> |
|||
<img class="avatar border-white" src="@/assets/img/academy.png" alt="..." |
|||
v-if="datadir" |
|||
> |
|||
<img class="avatar border-white" src="@/assets/img/library.png" alt="..." |
|||
v-else |
|||
> |
|||
</div> |
|||
|
|||
<v-wait for="myRunInstancetutor1"> |
|||
<template slot="waiting"> |
|||
<div> |
|||
<img src="@/assets/loading.gif" /> |
|||
Enter Lab_room... |
|||
</div> |
|||
</template> |
|||
</v-wait> |
|||
|
|||
<b-container fluid class="bv-example-row" |
|||
v-show="datadir" |
|||
> |
|||
<div class="list-group myscrool" |
|||
> |
|||
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start" |
|||
v-for="(course, i) in courses" |
|||
@click="viewllo(course,i)" |
|||
:class="{ active: i === activeItem}" |
|||
> |
|||
<div class="d-flex w-100 justify-content-between"> |
|||
<h5 class="mb-1">{{course.title}}</h5> |
|||
|
|||
<small |
|||
:class="checkClass(course)" |
|||
> {{ course.type }} |
|||
<small class="ti-shortcode" |
|||
v-if="course.type=='asciinema'" |
|||
> </small> |
|||
<small class="ti-video-camera" |
|||
v-if="course.type=='video'" |
|||
> </small> |
|||
<small class="ti-book" |
|||
v-if="course.type=='asciidoc'" |
|||
> </small> |
|||
<small class="ti-help-alt text-exercise" |
|||
v-if="course.type=='exercise'" |
|||
> </small> |
|||
</small> |
|||
|
|||
</div> |
|||
<!-- |
|||
<p class="mb-1">{{ course.subtitle }}</p> |
|||
--> |
|||
<small>{{ course.desc}}</small> |
|||
</a> |
|||
|
|||
</div> |
|||
</b-container> |
|||
<br> |
|||
|
|||
|
|||
|
|||
<b-container fluid class="bv-example-row"> |
|||
<div class="progress" |
|||
v-show="datadir" |
|||
> |
|||
<div class="progress-bar progress-bar-striped bg-secondary" role="progressbar" :style="getprogress(datadir)" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">{{ progress }}</div> |
|||
</div> |
|||
|
|||
<div class="input-group input-group-sm sm-3"> |
|||
|
|||
<input type="text" |
|||
class="form-control" |
|||
aria-label="Small" aria-describedby="inputGroup-sizing-sm" |
|||
placeholder="Search by Name" |
|||
v-model="searchFor" |
|||
@keyup.enter="setFilter" |
|||
> |
|||
|
|||
<div class="input-group-prepend"> |
|||
<select |
|||
class="custom-select custom-select-sm" v-model="searchcourselevel"> |
|||
<option value="0" selected>Level...</option> |
|||
<option value="1">Elementary</option> |
|||
<option value="2">Intermediate</option> |
|||
<option value="3">Advanced</option> |
|||
<option value="4">Expert</option> |
|||
<option value="5">Guru</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<div class="input-group-append"> |
|||
<button |
|||
class="btn btn-outline-primary" |
|||
round |
|||
type="button" |
|||
@click="setFilter"> |
|||
Go</button> |
|||
</div> |
|||
|
|||
<div class="input-group-append"> |
|||
<button class="btn btn-outline-secondary" |
|||
round |
|||
type="button" |
|||
@click="resetFilter"> |
|||
Reset</button> |
|||
</div> |
|||
</div> |
|||
<div class="white h-100 flex-fixed-width-item" |
|||
<vuetable |
|||
ref="vuetable" |
|||
:key="vuetablekey" |
|||
:api-url='apiurl' |
|||
:api-mode="true" |
|||
:http-options="httpOptions" |
|||
:fields="fields" |
|||
:item-actions="itemActions" |
|||
:sort-order="sortOrder" |
|||
:show-sort-icons="true" |
|||
:multi-sort="multiSort" |
|||
:per-page="perpage" |
|||
pagination-path="links.pagination" |
|||
:pagination-component="paginationComponent" |
|||
:append-params="moreParams" |
|||
wrapper-class="vuetable-wrapper" |
|||
loading-class="loading" |
|||
detail-row-id="id" |
|||
@vuetable:pagination-data="onPaginationData" |
|||
@vuetable:load-success="loadsuccess" |
|||
@vuetable:load-error="onLoadError" |
|||
:css="css.table" |
|||
> |
|||
|
|||
<div slot="actions" slot-scope="props"> |
|||
<button |
|||
v-if="actionrowindex == props.rowIndex" |
|||
class="ti-more-alt btn btn-secondary btn-sm" |
|||
title="View Course Details" |
|||
round |
|||
@click="onAction('run-more', props.rowData, props.rowIndex)"> |
|||
</button> |
|||
<button |
|||
v-else |
|||
class="ti-more btn btn-outline-secondary btn-sm" |
|||
title="View Course Details" |
|||
round |
|||
@click="onAction('run-more', props.rowData, props.rowIndex)"> |
|||
</button> |
|||
<button |
|||
class="ti-info btn btn-outline-secondary btn-sm" |
|||
title="View Course Info" |
|||
round |
|||
@click="onAction('run-info', props.rowData, props.rowIndex)"> |
|||
</button> |
|||
</div> |
|||
</vuetable> |
|||
<div class="vuetable-pagination ui basic segment grid"> |
|||
<vuetable-pagination-info |
|||
ref="paginationInfo" |
|||
:css="css.paginationInfo" |
|||
> |
|||
</vuetable-pagination-info> |
|||
<vuetable-pagination |
|||
:css="css.pagination" |
|||
ref="pagination" |
|||
@vuetable-pagination:change-page="onChangePage" |
|||
> |
|||
</vuetable-pagination> |
|||
</div> |
|||
</div> |
|||
</b-container> |
|||
</card> |
|||
</template> |
|||
<script> |
|||
import store from '@/store/index' |
|||
import {mapState, mapGetters, mapActions,dispatch} from 'vuex' |
|||
import Vue from 'vue' |
|||
import {Vuetable, VuetablePaginationDropdown} from 'vuetable-2' |
|||
import VuetablePaginationInfo from 'vuetable-2/src/components/VuetablePaginationInfo' |
|||
import VuetablePagination from 'vuetable-2/src/components/VuetablePagination' |
|||
import CssConfig from 'vuetable-2/src/components/VuetableCssConfig.js' |
|||
import card from '@/components/Card.vue' |
|||
import {ApiConfig} from "@/config/index"; |
|||
export default { |
|||
components: { |
|||
card, |
|||
Vuetable, |
|||
VuetablePagination, |
|||
VuetablePaginationInfo, |
|||
VuetablePaginationDropdown |
|||
}, |
|||
props: { |
|||
}, |
|||
data() { |
|||
return{ |
|||
actionrowindex:'', |
|||
activeItem: null, |
|||
playbookInfo: {}, |
|||
token: '', |
|||
playbook: { |
|||
'title':'', |
|||
'name':'', |
|||
'description':'' |
|||
}, |
|||
datadir:'', |
|||
progress:0, |
|||
searchcourselevel:0, |
|||
courses:[], |
|||
courseshow:false, |
|||
container:{ |
|||
name:'', |
|||
view:0 |
|||
}, |
|||
pipeline:{}, |
|||
selected: 'hybrid', |
|||
options: [ |
|||
{ text: 'Packages', value: 'packages' }, |
|||
{ text: 'Images', value: 'images' }, |
|||
{ text: 'Scripts', value: 'scripts' } |
|||
], |
|||
showModal: false, |
|||
visibility: [], |
|||
active:false, |
|||
vuetablekey:0, |
|||
fielddata:{}, |
|||
fields: [ |
|||
{ |
|||
name: 'title', |
|||
title: '<span class="orange"></span>Name', |
|||
sortField: 'title', |
|||
visible:true, |
|||
dataClass: 'text-left text-wrap text-break break-word', |
|||
width: '20%' |
|||
}, |
|||
{ |
|||
name: 'subtitle', |
|||
title: '<span class="orange"></span>Course', |
|||
sortField: 'subtitle', |
|||
visible:true, |
|||
dataClass: 'left aligned w-25', |
|||
width: '25%' |
|||
}, |
|||
{ |
|||
name: '_id', |
|||
title: '<span class="orange"></span>mongo', |
|||
visible:false |
|||
}, |
|||
{ |
|||
name: 'desc', |
|||
title: '<span class="orange"></span>Description', |
|||
sortField: 'desc', |
|||
titleClass: 'center aligned', |
|||
visible:true, |
|||
width: '40%' |
|||
}, |
|||
{ |
|||
name: 'ID', |
|||
sortField: 'ID', |
|||
titleClass: 'center aligned', |
|||
dataClass: 'left aligned w-25', |
|||
visible:false, |
|||
width: '15%' |
|||
}, |
|||
{ |
|||
name: '__slot:actions', // <---- |
|||
title: '<span class="d-flex justify-content-center">Actions</span>', |
|||
titleClass: 'center aligned', |
|||
dataClass: 'text-center', |
|||
width: '15%' |
|||
} |
|||
], |
|||
apiurl:ApiConfig.url_80+"/get_llo", |
|||
//apiurl:ApiConfig.swarmlab_url_80+"/swarmlabhybridservices", |
|||
css: CssConfig, |
|||
perpage: 5, |
|||
searchFor: '', |
|||
sortOrder: [{ |
|||
field: 'pipelinename', |
|||
direction: 'asc' |
|||
}], |
|||
multiSort: true, |
|||
paginationComponent: 'vuetable-pagination', |
|||
itemActions: [ |
|||
{ name: 'view-item', label: '', icon: 'glyphicon glyphicon-zoom-in', class: 'btn btn-info', extra: {'title': 'View', 'data-toggle':"tooltip", 'data-placement': "left"} }, |
|||
{ name: 'edit-item', label: '', icon: 'glyphicon glyphicon-pencil', class: 'btn btn-warning', extra: {title: 'Edit', 'data-toggle':"tooltip", 'data-placement': "top"} }, |
|||
{ name: 'delete-item', label: '', icon: 'glyphicon glyphicon-remove', class: 'btn btn-danger', extra: {title: 'Delete', 'data-toggle':"tooltip", 'data-placement': "right" } } |
|||
], |
|||
moreParams: { |
|||
'filter': '', |
|||
'level': '', |
|||
'type': 'scripts', |
|||
'tutor': 'yes' |
|||
}, |
|||
|
|||
} |
|||
}, |
|||
mounted() { |
|||
this.$root.$on('hybrid_refresh_dockerservices', () => { |
|||
Vue.nextTick( () => this.$refs.vuetable.refresh()) |
|||
}) |
|||
//refresh from socket mytable |
|||
this.$root.$on('hybrid_refresh_table', (v) => { |
|||
this.$nextTick(function () { |
|||
Vue.nextTick( () => this.$refs.vuetable.refresh()) |
|||
this.viewhybridoptions = false |
|||
}) |
|||
}) |
|||
}, |
|||
created() { |
|||
var url_string = window.location.href |
|||
var url = new URL(url_string); |
|||
this.token = url.searchParams.get("token"); |
|||
console.log("token "+ this.token); |
|||
|
|||
}, |
|||
beforeDestroy () { |
|||
this.$root.$off('hybrid_refresh_dockerservices') |
|||
this.$root.$off('hybrid_refresh_table') |
|||
}, |
|||
computed: { |
|||
httpOptions() { |
|||
var token = this.token |
|||
var p="headers: {Authorization: token}}"; //table props -> :http-options="httpOptions" |
|||
return {headers: {Authorization: 'Bearer ' + token}} //table props -> :http-options="httpOptions" |
|||
}, |
|||
|
|||
}, |
|||
|
|||
methods: { |
|||
async getprogress(course){ |
|||
console.log('course '+course) |
|||
var value1 = {} |
|||
value1.course = this.datadir |
|||
var llo = await store.dispatch('pipelineLLO/get_progress', value1) |
|||
console.log('asciidoc '+JSON.stringify(llo)) |
|||
this.progress = 35 |
|||
return `width: ${this.progress}%;` |
|||
}, |
|||
checkClass(course){ |
|||
if(course.type == 'video'){ |
|||
return 'text-primary' |
|||
} else if(course.type == 'asciidoc'){ |
|||
return 'text-success' |
|||
} else if(course.type == 'asciinema'){ |
|||
return 'text-info' |
|||
} else if(course.type == 'exercise'){ |
|||
return 'text-warning' |
|||
}else{ |
|||
return 'text-secondary' |
|||
} |
|||
}, |
|||
onError (type,description) { |
|||
var winfo=description |
|||
var info='<h5>Bootstrap '+type+'</h5>' |
|||
this.$swal({ |
|||
type: type, |
|||
html: info+winfo, |
|||
showCloseButton: true, |
|||
showLoaderOnConfirm: false, |
|||
allowOutsideClick: false, |
|||
cancelButtonText: 'No, cancel!', |
|||
showCancelButton: false, |
|||
showLoaderOnConfirm: false, |
|||
reverseButtons: true, |
|||
focusCancel: true, |
|||
confirmButtonText: 'Ok!' |
|||
}) |
|||
}, |
|||
|
|||
|
|||
setFilter () { |
|||
this.moreParams = { |
|||
'filter': this.searchFor, |
|||
'level': this.searchcourselevel, |
|||
'type': this.selected |
|||
} |
|||
Vue.nextTick( () => this.$refs.vuetable.refresh()) |
|||
}, |
|||
resetFilter () { |
|||
this.moreParams = {} |
|||
this.searchFor = '' |
|||
Vue.nextTick( () => this.$refs.vuetable.refresh()) |
|||
}, |
|||
onPaginationData (paginationData) { |
|||
this.$refs.pagination.setPaginationData(paginationData) |
|||
this.$refs.paginationInfo.setPaginationData(paginationData) |
|||
}, |
|||
onChangePage (page) { |
|||
this.$refs.vuetable.changePage(page) |
|||
}, |
|||
editRow(rowData) { |
|||
alert("You clicked edit on"+ JSON.stringify(rowData)); |
|||
}, |
|||
async viewllo (course,i) { |
|||
|
|||
console.log(JSON.stringify(i)) |
|||
this.courseshow = true |
|||
if(course.type == 'video' ){ |
|||
console.log(JSON.stringify(course)) |
|||
var value = {} |
|||
value.type = course.type |
|||
value.course = course.file |
|||
value.llo = this.datadir |
|||
this.$root.$emit('hybrid_llo_viecourse',value) |
|||
}else if(course.type == 'asciidoc' ){ |
|||
var value1 = {} |
|||
value1.dir = this.datadir |
|||
value1.file = course.file |
|||
//console.log('asciidoc '+JSON.stringify(value1)) |
|||
var llo = await store.dispatch('pipelineLLO/get_llo_course_ascii', value1) |
|||
console.log('asciidoc '+JSON.stringify(llo)) |
|||
//this.courses = JSON.parse(llo.data) |
|||
var value = {} |
|||
value.type = course.type |
|||
value.code = llo.data.data |
|||
value.course = course.file |
|||
value.llo = this.datadir |
|||
this.$root.$emit('hybrid_llo_viecourse',value) |
|||
}else if(course.type == 'asciinema' ){ |
|||
console.log(JSON.stringify(course)) |
|||
var value = {} |
|||
value.type = course.type |
|||
value.course = course.file |
|||
value.llo = this.datadir |
|||
this.$root.$emit('hybrid_llo_viecourse',value) |
|||
} |
|||
this.activeItem = i; |
|||
}, |
|||
async onAction (action, data, index) { |
|||
//console.log('index '+this.actionrowindex) |
|||
if(action == 'run-more' ){ |
|||
this.actionrowindex = index |
|||
this.datadir = data.dir |
|||
var llo = await store.dispatch('pipelineLLO/get_llo_course', data.dir) |
|||
this.courses = llo.data |
|||
//this.courses = JSON.parse(llo.data) |
|||
//console.log(JSON.stringify(llo.data)) |
|||
//console.log(JSON.stringify(this.courses[0].type)) |
|||
}else if(action == 'run-info' ){ |
|||
console.log(JSON.stringify(data)) |
|||
// {"title":"linux","subtitle":"Basics","level":"Intermediate","desc":"description","dir":"hybrid-linux"} |
|||
var info = ` |
|||
<table class="table table-hover table-sm text-left"> |
|||
<tbody> |
|||
<tr> |
|||
<th ><b>Title</b></th> |
|||
<td>${data.title}</td> |
|||
</tr> |
|||
<tr> |
|||
<td><b>Subtitle</b></td> |
|||
<td>${data.subtitle}</td> |
|||
</tr> |
|||
<tr> |
|||
<th ><b>Level</b></th> |
|||
<td>${data.level}</td> |
|||
</tr> |
|||
<tr> |
|||
<td ><b>Description</b></td> |
|||
<td>${data.desc}</td> |
|||
</tr> |
|||
</tbody> |
|||
</table>` |
|||
this.$swal({ |
|||
type: 'Info', |
|||
title: 'Course Info!', |
|||
icon:'info', |
|||
html: info, |
|||
showCloseButton: true, |
|||
showLoaderOnConfirm: false, |
|||
allowOutsideClick: false, |
|||
cancelButtonText: 'No, cancel!', |
|||
showCancelButton: false, |
|||
showLoaderOnConfirm: false, |
|||
reverseButtons: true, |
|||
focusCancel: true, |
|||
confirmButtonText: 'Ok!' |
|||
}) |
|||
} |
|||
}, |
|||
refreshVuetable() { |
|||
this.$nextTick(()=>{ |
|||
this.vuetablekey += 1 |
|||
}) |
|||
}, |
|||
playbookinfoShow(value) { |
|||
return this.visibility[value]=true |
|||
}, |
|||
playbookinfo(value) { |
|||
return this.playbookInfo=value |
|||
}, |
|||
rowClicked(row, event) { |
|||
return { |
|||
html: true, |
|||
title: () => { return 'Hello <b>Popover:</b> ' + (++this.counter) }, |
|||
content: () => { return 'The date is:<br><em>' + new Date() + '</em>' } |
|||
} |
|||
}, |
|||
loadsuccess(response) { |
|||
var data = response.data.data |
|||
this.fielddata=data |
|||
var n = data.length |
|||
n=n-1 |
|||
}, |
|||
onLoadError(payload) { |
|||
/* |
|||
//error2 "invalid_token" join-service.vue:684 |
|||
//error2 "The access token provided has expired" join-service.vue:685 |
|||
//error2 "Unauthorized" join-service.vue:686 |
|||
//error2 401 |
|||
console.log('error2 '+JSON.stringify(payload.response.data.error)) |
|||
console.log('error2 '+JSON.stringify(payload.response.data.error_description)) |
|||
console.log('error2 '+JSON.stringify(payload.response.statusText)) |
|||
console.log('error2 '+JSON.stringify(payload.response.status)) |
|||
*/ |
|||
if(payload.response.status == '401'){ |
|||
window.location.href = 'https://api-login.swarmlab.io:8089'; |
|||
Vue.nextTick( () => window.location.href = 'https://api-login.swarmlab.io:8089') |
|||
} |
|||
} |
|||
|
|||
|
|||
}, |
|||
|
|||
|
|||
actions: { |
|||
|
|||
|
|||
} |
|||
|
|||
}; |
|||
</script> |
|||
<style> |
|||
.flex-fixed-width-item { |
|||
flex: 0 0 100px; |
|||
} |
|||
.modalinfo { |
|||
z-index: 10000000 !important; |
|||
position:fixed; |
|||
} |
|||
/* a container with flex-direction column */ |
|||
|
|||
.vue-notifyjs.notifications{ |
|||
.alert{ |
|||
z-index: 100; |
|||
} |
|||
.list-move { |
|||
transition: transform 0.3s, opacity 0.4s; |
|||
} |
|||
.list-item { |
|||
display: inline-block; |
|||
margin-right: 10px; |
|||
|
|||
} |
|||
.list-enter-active { |
|||
transition: transform 0.2s ease-in, opacity 0.4s ease-in; |
|||
} |
|||
.list-leave-active { |
|||
transition: transform 1s ease-out, opacity 0.4s ease-out; |
|||
} |
|||
|
|||
.list-enter { |
|||
opacity: 0; |
|||
transform: scale(1.1); |
|||
|
|||
} |
|||
.list-leave-to { |
|||
opacity: 0; |
|||
transform: scale(1.2, 0.7); |
|||
} |
|||
} |
|||
|
|||
.myscrool { |
|||
height: 280px; |
|||
max-height: 280px; |
|||
overflow-y: auto; |
|||
//margin-bottom: 10px; |
|||
-webkit-overflow-scrolling: touch; |
|||
} |
|||
pre { |
|||
//background-color: rgb(255, 247, 229); |
|||
background-color: #eff0f1; |
|||
border: 1px solid blue; |
|||
//white-space: pre-line; |
|||
} |
|||
|
|||
</style> |
File diff suppressed because it is too large
Loading…
Reference in new issue