loader
This commit is contained in:
parent
0e56f4ff44
commit
2c253b93e8
19 changed files with 670 additions and 898 deletions
|
|
@ -1,12 +0,0 @@
|
||||||
let $head:="<head/>"
|
|
||||||
let $app:="<v-app/>"
|
|
||||||
return ``[
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
`{$head}`
|
|
||||||
<body>
|
|
||||||
`{$app}`
|
|
||||||
<script src="/vue-poc/ui/app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
]``
|
|
||||||
|
|
@ -2,29 +2,21 @@
|
||||||
localforage.config({
|
localforage.config({
|
||||||
name: 'vuepoc'
|
name: 'vuepoc'
|
||||||
});
|
});
|
||||||
|
const AXIOS_CONFIG={
|
||||||
|
baseURL: "/vue-poc/api/",
|
||||||
|
headers: {
|
||||||
|
'X-Custom-Header': 'vue-poc',
|
||||||
|
accept: 'application/json'
|
||||||
|
},
|
||||||
|
paramsSerializer: function(params) {
|
||||||
|
return Qs.stringify(params)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// errors displayed by interceptor
|
// errors displayed by interceptor
|
||||||
const HTTP = axios.create({
|
const HTTP = axios.create(AXIOS_CONFIG);
|
||||||
baseURL: "/vue-poc/api/",
|
|
||||||
headers: {
|
|
||||||
'X-Custom-Header': 'vue-poc',
|
|
||||||
accept: 'application/json'
|
|
||||||
},
|
|
||||||
paramsSerializer: function(params) {
|
|
||||||
return Qs.stringify(params)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// errors hidden
|
// errors hidden
|
||||||
const HTTPNE = axios.create({
|
const HTTPNE = axios.create(AXIOS_CONFIG);
|
||||||
baseURL: "/vue-poc/api/",
|
|
||||||
headers: {
|
|
||||||
'X-Custom-Header': 'vue-poc',
|
|
||||||
accept: 'application/json'
|
|
||||||
},
|
|
||||||
paramsSerializer: function(params) {
|
|
||||||
return Qs.stringify(params)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const axios_json={ headers: {accept: 'application/json'}};
|
const axios_json={ headers: {accept: 'application/json'}};
|
||||||
|
|
||||||
const Auth={
|
const Auth={
|
||||||
|
|
@ -40,13 +32,13 @@ Vue.use(Auth);
|
||||||
// read and write settings
|
// read and write settings
|
||||||
// https://vuejs.org/v2/guide/state-management.html
|
// https://vuejs.org/v2/guide/state-management.html
|
||||||
var settings = {
|
var settings = {
|
||||||
debug: true,
|
debug: false,
|
||||||
getItem (key) {
|
getItem (key) {
|
||||||
if (this.debug) console.log('getItem',key);
|
if (this.debug) console.log('getItem',key);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
localforage.getItem(key)
|
localforage.getItem(key)
|
||||||
.then((value) => {
|
.then((value) => {
|
||||||
console.log('GET setting', key,value);
|
//console.log('GET setting', key,value);
|
||||||
resolve(value)
|
resolve(value)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log('GET failed');
|
console.log('GET failed');
|
||||||
|
|
@ -59,7 +51,7 @@ var settings = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
localforage.setItem(key, value)
|
localforage.setItem(key, value)
|
||||||
.then((value) => {
|
.then((value) => {
|
||||||
console.log('SET ',key, value);
|
//console.log('SET ',key, value);
|
||||||
return new Promise((resolve, reject) => {resolve(value);})
|
return new Promise((resolve, reject) => {resolve(value);})
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log('set failed');
|
console.log('set failed');
|
||||||
|
|
@ -133,194 +125,5 @@ const Fullscreen={
|
||||||
}) }
|
}) }
|
||||||
};
|
};
|
||||||
Vue.use(Fullscreen);
|
Vue.use(Fullscreen);
|
||||||
|
|
||||||
|
|
||||||
const router = new VueRouter({
|
|
||||||
base:"/vue-poc/ui/",
|
|
||||||
mode: 'history',
|
|
||||||
routes: [
|
|
||||||
{ path: '/', component: Home, meta:{title:"Home"} },
|
|
||||||
{ path: '/session', component: Session ,meta: {title:"Session"}},
|
|
||||||
{path: '/images', redirect: '/images/item' },
|
|
||||||
{ path: '/images/item', name:'images', component: Images, meta:{title: "Images"} },
|
|
||||||
{ path: '/images/report', name:"image-reports", component: Report, props: true, meta:{title: "Image report"}},
|
|
||||||
{ path: '/images/item/:id', name:"image",component: Image, props: true, meta:{title: "Image details"}},
|
|
||||||
{ path: '/images/thumbnail', component: Thumbnail, meta:{title:"Thumbnail generator"} },
|
|
||||||
{ path: '/images/keywords', component: Keywords, meta:{title:"Image keywords"} },
|
|
||||||
{ path: '/images/dates', component: Dates, meta:{title:"Image dates"} },
|
|
||||||
{ path: '/select', component: Select, meta:{title:"Select"} },
|
|
||||||
{ path: '/search', component: Search, meta:{title:"Search"} },
|
|
||||||
{ path: '/tabs', component: Tabs,meta:{title:"tab test",requiresAuth: true} },
|
|
||||||
{ path: '/login', component: Login,meta:{title:"login"} },
|
|
||||||
{ path: '/edit', component: Edit,meta:{title:"Ace editor"} },
|
|
||||||
{ path: '/server/users', component: Users,meta:{title:"Users"} },
|
|
||||||
{ path: '/server/repo', component: Repo,meta:{title:"Repository"} },
|
|
||||||
{ path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} },
|
|
||||||
{ path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} },
|
|
||||||
{ path: '/ping', component: Ping,meta:{title:"Ping"} },
|
|
||||||
{ path: '/settings', component: Settings, meta:{title:"Settings"} },
|
|
||||||
{ path: '/acesettings', component: Acesettings, meta:{title:"Editor settings"} },
|
|
||||||
{ path: '/history', component: History, meta:{title:"File History"} },
|
|
||||||
{ path: '/puzzle', component: Puzzle, meta:{title:"Jigsaw"} },
|
|
||||||
{ path: '/eval', component: Eval, meta:{title:"Evaluate XQuery"} },
|
|
||||||
{ path: '/logs', component: Log, meta:{title:"Server logs"} },
|
|
||||||
{ path: '/tasks', component: Task, meta:{title:"Runnable tasks"} },
|
|
||||||
{ path: '/tasks/model', component: Model, meta:{title:"build model"} },
|
|
||||||
{ path: '/tasks/xqdoc', component: Xqdoc, meta:{title:"build xqdoc"} },
|
|
||||||
{ path: '/tasks/vuecompile', component: Vuecompile, meta:{title:"vue compile"} },
|
|
||||||
{ path: '/jobs', component: Jobs, meta:{title:"Jobs running"} },
|
|
||||||
{ path: '/jobs/:job', name:"jobShow", component: Job, props: true, meta:{title:"Job Status"} },
|
|
||||||
{ path: '/timeline', component: Timeline,meta:{title:"timeline"} },
|
|
||||||
{ path: '/about', component: About,meta:{title:"About Vue-poc"} },
|
|
||||||
{ path: '*', component: Notfound,meta:{title:"Page not found"} }
|
|
||||||
],
|
|
||||||
});
|
|
||||||
router.afterEach(function(route) {
|
|
||||||
document.title = (route.meta.title?route.meta.title:"") + " VUE-Poc";
|
|
||||||
});
|
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
|
||||||
if (to.matched.some(record => record.meta.requiresAuth)) {
|
|
||||||
// this route requires auth, check if logged in
|
|
||||||
// if not, redirect to login page.
|
|
||||||
if ("admin"==Auth.permission) {
|
|
||||||
next({
|
|
||||||
path: '/login',
|
|
||||||
query: { redirect: to.fullPath }
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
next() // make sure to always call next()!
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.use(Vuetify);
|
Vue.use(Vuetify);
|
||||||
|
new Vuepoc().$mount('#app')
|
||||||
const app = new Vue({
|
|
||||||
router,
|
|
||||||
data:function(){return {
|
|
||||||
q:"",
|
|
||||||
status:{},
|
|
||||||
drawer:true,
|
|
||||||
mini: false,
|
|
||||||
dark: false,
|
|
||||||
alert:{show:false,msg:"Hello"},
|
|
||||||
items:[
|
|
||||||
{href: '/',text: 'Home', icon: 'home' },
|
|
||||||
{
|
|
||||||
icon: 'folder_open',
|
|
||||||
text: 'Collections' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/database', text: 'Databases',icon: 'developer_mode' },
|
|
||||||
{href: '/files', text: 'File system',icon: 'folder' },
|
|
||||||
{href: '/edit',text: 'Edit',icon: 'mode_edit'},
|
|
||||||
{href: '/history',text: 'history',icon: 'history'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'directions_run',
|
|
||||||
text: 'Actions' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/eval',text: 'Query',icon: 'play_circle_outline'},
|
|
||||||
{href: '/tasks',text: 'Tasks',icon: 'history'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'cast_connected',
|
|
||||||
text: 'Server' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/jobs',text: 'Running jobs',icon: 'dashboard'},
|
|
||||||
{href: '/logs',text: 'Server logs',icon: 'dns'},
|
|
||||||
{href: '/server/users',text: 'Users',icon: 'supervisor_account'},
|
|
||||||
{href: '/server/repo',text: 'Server code repository',icon: 'local_library'},
|
|
||||||
{href: '/ping',text: 'Ping',icon: 'update'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'camera_roll',
|
|
||||||
text: 'Images' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/images/item',text: 'Collection',icon: 'photo_camera'},
|
|
||||||
{href: '/images/keywords',text: 'Keywords',icon: 'label'},
|
|
||||||
{href: '/images/dates',text: 'Date taken',icon: 'date_range'},
|
|
||||||
{href: '/images/thumbnail',text: 'Thumbnail',icon: 'touch_app'},
|
|
||||||
{href: '/images/report',text: 'Reports',icon: 'report'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'more_horiz',
|
|
||||||
text: 'More' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/session',text: 'Session',icon: 'person'},
|
|
||||||
{href: '/select',text: 'Select',icon: 'extension'},
|
|
||||||
{href: '/puzzle',text: 'Puzzle',icon: 'extension'},
|
|
||||||
{href: '/tabs',text: 'Tabs',icon: 'switch_camera'},
|
|
||||||
{href: '/timeline',text: 'Time line',icon: 'timelapse'}
|
|
||||||
]},
|
|
||||||
|
|
||||||
{href: '/settings',text: 'Settings',icon: 'settings' },
|
|
||||||
{href: '/about',text: 'About', icon: 'help' },
|
|
||||||
]
|
|
||||||
|
|
||||||
}},
|
|
||||||
methods: {
|
|
||||||
session(){
|
|
||||||
this.$router.push({path: '/session'})
|
|
||||||
},
|
|
||||||
search(){
|
|
||||||
this.$router.push({path: '/search',query: { q: this.q }})
|
|
||||||
},
|
|
||||||
logout(){
|
|
||||||
HTTP.get("logout").then(r=>{
|
|
||||||
alert("logout")
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showAlert(msg){
|
|
||||||
this.alert.msg=moment().format()+" "+ msg
|
|
||||||
this.alert.show=true
|
|
||||||
},
|
|
||||||
onDark(dark){
|
|
||||||
this.dark=dark
|
|
||||||
alert("theme")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
created(){
|
|
||||||
|
|
||||||
console.log("create-----------")
|
|
||||||
Vue.config.errorHandler = function (err, vm, info) {
|
|
||||||
// handle error
|
|
||||||
// `info` is a Vue-specific error info, e.g. which lifecycle hook
|
|
||||||
console.error(err, vm, info);
|
|
||||||
this.showAlert("vue error:\n"+err)
|
|
||||||
alert("vue error");
|
|
||||||
};
|
|
||||||
// Add a response interceptor
|
|
||||||
|
|
||||||
HTTP.interceptors.response.use(
|
|
||||||
(response)=> {
|
|
||||||
// Do something with response data
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
(error) =>{
|
|
||||||
// interupt restxq single
|
|
||||||
console.log("$$$$$$$$$$$",error)
|
|
||||||
if(460 != error.response.status)this.showAlert("http error:\n"+error.response.data)
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
HTTP.get("status")
|
|
||||||
.then(r=>{
|
|
||||||
console.log("status",r.data)
|
|
||||||
Object.assign(Auth,r.data)
|
|
||||||
this.$forceUpdate()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
beforeDestroy(){
|
|
||||||
console.log("destory-----------")
|
|
||||||
|
|
||||||
}
|
|
||||||
}).$mount('#app');
|
|
||||||
|
|
|
||||||
60
src/vue-poc/components/router.js
Normal file
60
src/vue-poc/components/router.js
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
const router = new VueRouter({
|
||||||
|
base:"/vue-poc/ui/",
|
||||||
|
mode: 'history',
|
||||||
|
routes: [
|
||||||
|
{ path: '/', component: Home, meta:{title:"Home"} },
|
||||||
|
{ path: '/session', component: Session ,meta: {title:"Session"}},
|
||||||
|
{path: '/images', redirect: '/images/item' },
|
||||||
|
{ path: '/images/item', name:'images', component: Images, meta:{title: "Images"} },
|
||||||
|
{ path: '/images/report', name:"image-reports", component: Report, props: true, meta:{title: "Image report"}},
|
||||||
|
{ path: '/images/item/:id', name:"image",component: Image, props: true, meta:{title: "Image details"}},
|
||||||
|
{ path: '/images/thumbnail', component: Thumbnail, meta:{title:"Thumbnail generator"} },
|
||||||
|
{ path: '/images/keywords', component: Keywords, meta:{title:"Image keywords"} },
|
||||||
|
{ path: '/images/dates', component: Dates, meta:{title:"Image dates"} },
|
||||||
|
{ path: '/select', component: Select, meta:{title:"Select"} },
|
||||||
|
{ path: '/search', component: Search, meta:{title:"Search"} },
|
||||||
|
{ path: '/tabs', component: Tabs,meta:{title:"tab test",requiresAuth: true} },
|
||||||
|
{ path: '/login', component: Login,meta:{title:"login"} },
|
||||||
|
{ path: '/edit', component: Edit,meta:{title:"Ace editor"} },
|
||||||
|
{ path: '/server/users', component: Users,meta:{title:"Users"} },
|
||||||
|
{ path: '/server/repo', component: Repo,meta:{title:"Repository"} },
|
||||||
|
{ path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} },
|
||||||
|
{ path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} },
|
||||||
|
{ path: '/ping', component: Ping,meta:{title:"Ping"} },
|
||||||
|
{ path: '/settings', component: Settings, meta:{title:"Settings"} },
|
||||||
|
{ path: '/acesettings', component: Acesettings, meta:{title:"Editor settings"} },
|
||||||
|
{ path: '/history', component: History, meta:{title:"File History"} },
|
||||||
|
{ path: '/puzzle', component: Puzzle, meta:{title:"Jigsaw"} },
|
||||||
|
{ path: '/eval', component: Eval, meta:{title:"Evaluate XQuery"} },
|
||||||
|
{ path: '/logs', component: Log, meta:{title:"Server logs"} },
|
||||||
|
{ path: '/tasks', component: Task, meta:{title:"Runnable tasks"} },
|
||||||
|
{ path: '/tasks/model', component: Model, meta:{title:"build model"} },
|
||||||
|
{ path: '/tasks/xqdoc', component: Xqdoc, meta:{title:"build xqdoc"} },
|
||||||
|
{ path: '/tasks/vuecompile', component: Vuecompile, meta:{title:"vue compile"} },
|
||||||
|
{ path: '/jobs', component: Jobs, meta:{title:"Jobs running"} },
|
||||||
|
{ path: '/jobs/:job', name:"jobShow", component: Job, props: true, meta:{title:"Job Status"} },
|
||||||
|
{ path: '/timeline', component: Timeline,meta:{title:"timeline"} },
|
||||||
|
{ path: '/about', component: About,meta:{title:"About Vue-poc"} },
|
||||||
|
{ path: '*', component: Notfound,meta:{title:"Page not found"} }
|
||||||
|
],
|
||||||
|
});
|
||||||
|
router.afterEach(function(route) {
|
||||||
|
document.title = (route.meta.title?route.meta.title:"") + " VUE-Poc";
|
||||||
|
});
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
if (to.matched.some(record => record.meta.requiresAuth)) {
|
||||||
|
// this route requires auth, check if logged in
|
||||||
|
// if not, redirect to login page.
|
||||||
|
if ("admin"==Auth.permission) {
|
||||||
|
next({
|
||||||
|
path: '/login',
|
||||||
|
query: { redirect: to.fullPath }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
next() // make sure to always call next()!
|
||||||
|
}
|
||||||
|
});
|
||||||
3
src/vue-poc/data/vue-poc/ping.xml
Normal file
3
src/vue-poc/data/vue-poc/ping.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<state>
|
||||||
|
<last-id>3</last-id>
|
||||||
|
</state>
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
<state>
|
<state>
|
||||||
|
<ping>0</ping>
|
||||||
<last-id>3</last-id>
|
<last-id>3</last-id>
|
||||||
</state>
|
</state>
|
||||||
|
|
@ -4,10 +4,26 @@
|
||||||
<v-card >
|
<v-card >
|
||||||
|
|
||||||
<v-toolbar>
|
<v-toolbar>
|
||||||
<v-btn @click="run()">Run</v-btn>
|
|
||||||
<v-btn @click="submit()">
|
|
||||||
<v-icon>play_circle_outline</v-icon>
|
<v-menu offset-y>
|
||||||
Submit</v-btn>
|
<v-btn slot="activator">
|
||||||
|
<v-icon>play_circle_outline</v-icon>
|
||||||
|
Run</v-btn>
|
||||||
|
<v-list>
|
||||||
|
<v-list-tile @click="submit">
|
||||||
|
<v-list-tile-title>Submit</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-list-tile @click="run">
|
||||||
|
<v-list-tile-title>Run</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile @click="plan">
|
||||||
|
<v-list-tile-title>Show query plan</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn @click="imports">
|
<v-btn @click="imports">
|
||||||
<v-icon>library_books</v-icon>
|
<v-icon>library_books</v-icon>
|
||||||
|
|
@ -167,7 +183,7 @@
|
||||||
},
|
},
|
||||||
plan(){
|
plan(){
|
||||||
this.awaitResult(false)
|
this.awaitResult(false)
|
||||||
HTTP.post("eval/plan",Qs.stringify({xq:this.xq}))
|
HTTPNE.post("eval/plan",Qs.stringify({xq:this.xq}))
|
||||||
.then(r=>{
|
.then(r=>{
|
||||||
this.result=r.data.result
|
this.result=r.data.result
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
module namespace ping = 'quodatum.test.ping';
|
module namespace ping = 'quodatum.test.ping';
|
||||||
declare variable $ping:db as xs:string:="doc-doc";
|
declare variable $ping:db as xs:string:="vue-poc";
|
||||||
declare variable $ping:state as element(state):=db:open($ping:db,"/state.xml")/state;
|
declare variable $ping:state as element(state):=db:open($ping:db,"/state.xml")/state;
|
||||||
|
|
||||||
(:~
|
(:~
|
||||||
|
|
@ -10,8 +10,8 @@ declare %updating
|
||||||
%output:method("text")
|
%output:method("text")
|
||||||
function ping:dopost()
|
function ping:dopost()
|
||||||
{
|
{
|
||||||
(replace value of node $ping:state/hits with 1+$ping:state/hits,
|
(replace value of node $ping:state/ping with 1+$ping:state/ping,
|
||||||
db:output(1+$ping:state/hits))
|
db:output(1+$ping:state/ping))
|
||||||
};
|
};
|
||||||
|
|
||||||
(:~
|
(:~
|
||||||
|
|
@ -22,5 +22,5 @@ declare
|
||||||
%rest:GET %rest:path("/vue-poc/api/ping")
|
%rest:GET %rest:path("/vue-poc/api/ping")
|
||||||
function ping:dostate()
|
function ping:dostate()
|
||||||
{
|
{
|
||||||
$ping:state/hits
|
$ping:state/ping
|
||||||
};
|
};
|
||||||
|
|
@ -1,224 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<template id="vuepoc">
|
|
||||||
<v-app >
|
|
||||||
<v-navigation-drawer persistent light :mini-variant.sync="mini" v-model="drawer"
|
|
||||||
:disable-route-watcher="true" height="100%" class="grey lighten-4 pb-0">
|
|
||||||
<v-list class="pa-0">
|
|
||||||
|
|
||||||
<v-list-tile avatar tag="div">
|
|
||||||
<v-list-tile-avatar >
|
|
||||||
<v-btn icon @click="session">
|
|
||||||
<img src="/vue-poc/ui/quodatum.gif" />
|
|
||||||
</v-btn>
|
|
||||||
</v-list-tile-avatar>
|
|
||||||
<v-list-tile-content>
|
|
||||||
<v-list-tile-title>Vue PoC</v-list-tile-title>
|
|
||||||
</v-list-tile-content>
|
|
||||||
<v-list-tile-action>
|
|
||||||
<v-btn icon @click.stop="mini = !mini">
|
|
||||||
<v-icon>chevron_left</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-tile-action>
|
|
||||||
</v-list-tile>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
<qd-navlist :items="items"></qd-navlist>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-toolbar class="indigo" dark >
|
|
||||||
<v-toolbar-side-icon @click.stop="drawer = !drawer" ></v-toolbar-side-icon>
|
|
||||||
<v-toolbar-title class="hidden-sm-and-down" >{{$route.meta.title}}</v-toolbar-title>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-text-field prepend-icon="search" label="Search..." v-model="q"
|
|
||||||
hide-details single-line dark @keyup.enter="search"></v-text-field>
|
|
||||||
<v-menu left transition="v-fade-transition">
|
|
||||||
<v-btn dark icon slot="activator">
|
|
||||||
{{$auth.user}}
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-list>
|
|
||||||
|
|
||||||
<v-list-tile @click="logout()">
|
|
||||||
<v-list-tile-title >logout</v-list-tile-title>
|
|
||||||
</v-list-tile>
|
|
||||||
<v-list-tile>
|
|
||||||
<v-list-tile-title >permission: {{$auth.permission}}</v-list-tile-title>
|
|
||||||
</v-list-tile>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
<v-btn icon @click="fullscreen" :disabled="!fullscreenEnabled">
|
|
||||||
<v-icon>{{ fullscreenIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<qd-fullscreen></qd-fullscreen>
|
|
||||||
</v-toolbar>
|
|
||||||
<main>
|
|
||||||
<v-alert error value="true" dismissible v-model="alert.show">
|
|
||||||
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
|
||||||
</v-alert>
|
|
||||||
<transition name="fade" mode="out-in">
|
|
||||||
<router-view class="view ma-3"></router-view>
|
|
||||||
</transition>
|
|
||||||
</main>
|
|
||||||
</v-app>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>{
|
|
||||||
// router,
|
|
||||||
data:function(){return {
|
|
||||||
q:"",
|
|
||||||
status:{},
|
|
||||||
drawer:true,
|
|
||||||
mini: false,
|
|
||||||
alert:{show:false,msg:"Hello"},
|
|
||||||
items:[
|
|
||||||
{href: '/',text: 'Home', icon: 'home' },
|
|
||||||
{
|
|
||||||
icon: 'folder_open',
|
|
||||||
text: 'Collections' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/database', text: 'Databases',icon: 'developer_mode' },
|
|
||||||
{href: '/files', text: 'File system',icon: 'folder' },
|
|
||||||
{href: '/edit',text: 'Edit',icon: 'mode_edit'},
|
|
||||||
{href: '/history',text: 'history',icon: 'history'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'directions_run',
|
|
||||||
text: 'Actions' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/eval',text: 'Query',icon: 'play_circle_outline'},
|
|
||||||
{href: '/tasks',text: 'Tasks',icon: 'history'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'cast_connected',
|
|
||||||
text: 'Server' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/jobs',text: 'Running jobs',icon: 'dashboard'},
|
|
||||||
{href: '/logs',text: 'Server logs',icon: 'dns'},
|
|
||||||
{href: '/ping',text: 'Ping',icon: 'update'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'camera_roll',
|
|
||||||
text: 'Images' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/images/item',text: 'Collection',icon: 'photo_camera'},
|
|
||||||
{href: '/images/keywords',text: 'Keywords',icon: 'label'},
|
|
||||||
{href: '/images/dates',text: 'Date taken',icon: 'date_range'},
|
|
||||||
{href: '/images/thumbnail',text: 'Thumbnail',icon: 'touch_app'},
|
|
||||||
{href: '/images/report',text: 'Reports',icon: 'report'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'more_horiz',
|
|
||||||
text: 'More' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/session',text: 'Session',icon: 'person'},
|
|
||||||
{href: '/select',text: 'Select',icon: 'extension'},
|
|
||||||
{href: '/puzzle',text: 'Puzzle',icon: 'extension'},
|
|
||||||
{href: '/tabs',text: 'Tabs',icon: 'switch_camera'},
|
|
||||||
{href: '/timeline',text: 'Time line',icon: 'timelapse'}
|
|
||||||
]},
|
|
||||||
|
|
||||||
{href: '/settings',text: 'Settings',icon: 'settings' },
|
|
||||||
{href: '/about',text: 'About', icon: 'help' },
|
|
||||||
]
|
|
||||||
|
|
||||||
}},
|
|
||||||
methods: {
|
|
||||||
session(){
|
|
||||||
this.$router.push({path: '/session'})
|
|
||||||
},
|
|
||||||
search(){
|
|
||||||
this.$router.push({path: '/search',query: { q: this.q }})
|
|
||||||
},
|
|
||||||
logout(){
|
|
||||||
HTTP.get("logout").then(r=>{
|
|
||||||
alert("logout")
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showAlert(msg){
|
|
||||||
this.alert.msg=moment().format()+" "+ msg
|
|
||||||
this.alert.show=true
|
|
||||||
},
|
|
||||||
fullscreenEnabled(){
|
|
||||||
return document.fullscreenEnabled
|
|
||||||
},
|
|
||||||
isInFullScreen(){
|
|
||||||
return (document.fullscreenElement && document.fullscreenElement !== null) ||
|
|
||||||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
|
|
||||||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
|
|
||||||
(document.msFullscreenElement && document.msFullscreenElement !== null)
|
|
||||||
},
|
|
||||||
fullscreen(){
|
|
||||||
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
|
|
||||||
var isInFullScreen = this.isInFullScreen();
|
|
||||||
alert(isInFullScreen);
|
|
||||||
var docElm = document.documentElement;
|
|
||||||
if (!isInFullScreen) {
|
|
||||||
if (docElm.requestFullscreen) {
|
|
||||||
docElm.requestFullscreen();
|
|
||||||
} else if (docElm.mozRequestFullScreen) {
|
|
||||||
docElm.mozRequestFullScreen();
|
|
||||||
} else if (docElm.webkitRequestFullScreen) {
|
|
||||||
docElm.webkitRequestFullScreen();
|
|
||||||
} else if (docElm.msRequestFullscreen) {
|
|
||||||
docElm.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (document.exitFullscreen) {
|
|
||||||
document.exitFullscreen();
|
|
||||||
} else if (document.webkitExitFullscreen) {
|
|
||||||
document.webkitExitFullscreen();
|
|
||||||
} else if (document.mozCancelFullScreen) {
|
|
||||||
document.mozCancelFullScreen();
|
|
||||||
} else if (document.msExitFullscreen) {
|
|
||||||
document.msExitFullscreen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed:{
|
|
||||||
fullscreenIcon(){ return this.isInFullScreen()?'fullscreen_exit':'fullscreen'}
|
|
||||||
},
|
|
||||||
|
|
||||||
created(){
|
|
||||||
|
|
||||||
console.log("create-----------")
|
|
||||||
Vue.config.errorHandler = function (err, vm, info) {
|
|
||||||
// handle error
|
|
||||||
// `info` is a Vue-specific error info, e.g. which lifecycle hook
|
|
||||||
console.error(err, vm, info);
|
|
||||||
this.showAlert("vue error:\n"+err)
|
|
||||||
alert("vue error");
|
|
||||||
};
|
|
||||||
// Add a response interceptor
|
|
||||||
|
|
||||||
HTTP.interceptors.response.use(
|
|
||||||
(response)=> {
|
|
||||||
// Do something with response data
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
(error) =>{
|
|
||||||
// interupt restxq single
|
|
||||||
if(460 != error.response.status)this.showAlert("http error:\n"+error.response.data)
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
HTTP.get("status")
|
|
||||||
.then(r=>{
|
|
||||||
console.log("status",r.data)
|
|
||||||
Object.assign(Auth,r.data)
|
|
||||||
this.$forceUpdate()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
beforeDestroy(){
|
|
||||||
console.log("destory-----------")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -64,12 +64,14 @@ declare function vue:capitalize-first
|
||||||
concat(upper-case(substring($arg,1,1)), substring($arg,2))
|
concat(upper-case(substring($arg,1,1)), substring($arg,2))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(: filename of features:)
|
||||||
declare function vue:feature-files($proj)
|
declare function vue:feature-files($proj)
|
||||||
as xs:string*
|
as xs:string*
|
||||||
{
|
{
|
||||||
let $FEATURES:="features/"=>file:resolve-path($proj)
|
let $FEATURES:="features/"=>file:resolve-path($proj)
|
||||||
return fw:directory-list($FEATURES,map{"include-filter":".*\.vue"})
|
let $files:= fw:directory-list($FEATURES,map{"include-filter":".*\.vue"})
|
||||||
//c:file/@name/resolve-uri(.,base-uri(.))
|
//c:file/@name/resolve-uri(.,base-uri(.))
|
||||||
|
return $files
|
||||||
};
|
};
|
||||||
|
|
||||||
declare function vue:feature-build($url as xs:string,$isComp as xs:boolean)
|
declare function vue:feature-build($url as xs:string,$isComp as xs:boolean)
|
||||||
|
|
@ -88,8 +90,9 @@ let $FEATURES:="features/"=>file:resolve-path($proj=>trace("proj:"))
|
||||||
let $COMPONENTS:="components/"=>file:resolve-path($proj)
|
let $COMPONENTS:="components/"=>file:resolve-path($proj)
|
||||||
let $CORE:="components/core.js"=>file:resolve-path($proj)
|
let $CORE:="components/core.js"=>file:resolve-path($proj)
|
||||||
let $FILTERS:="components/filters.js"=>file:resolve-path($proj)
|
let $FILTERS:="components/filters.js"=>file:resolve-path($proj)
|
||||||
|
let $ROUTER:="components/router.js"=>file:resolve-path($proj)
|
||||||
let $DEST:="static/app-gen.js"=>file:resolve-path($proj)
|
let $DEST:="static/app-gen.js"=>file:resolve-path($proj)
|
||||||
|
let $APP:="vue-poc.vue"=>file:resolve-path($proj)
|
||||||
let $files:=vue:feature-files($proj)
|
let $files:=vue:feature-files($proj)
|
||||||
let $feats:=$files!vue:feature-build(.,false())
|
let $feats:=$files!vue:feature-build(.,false())
|
||||||
|
|
||||||
|
|
@ -102,5 +105,7 @@ return file:write-text($DEST,string-join(($comment,
|
||||||
$comps,
|
$comps,
|
||||||
fetch:text($FILTERS),
|
fetch:text($FILTERS),
|
||||||
$feats,
|
$feats,
|
||||||
|
fetch:text($ROUTER),
|
||||||
|
$APP!vue:feature-build(.,false()),
|
||||||
fetch:text($CORE))))
|
fetch:text($CORE))))
|
||||||
};
|
};
|
||||||
33
src/vue-poc/models/query.xml
Normal file
33
src/vue-poc/models/query.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<entity name="query" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||||
|
<description>An replx query</description>
|
||||||
|
<namespace prefix="xqdoc" uri="http://www.xqdoc.org/1.0"/>
|
||||||
|
|
||||||
|
<fields>
|
||||||
|
<field name="id" type="xs:string">
|
||||||
|
<description>unique id</description>
|
||||||
|
<xpath>@id</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="created" type="xs:string">
|
||||||
|
<description>date</description>
|
||||||
|
<xpath>created</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="query" type="xs:string">
|
||||||
|
<description>query</description>
|
||||||
|
<xpath>query</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="result" type="xs:string">
|
||||||
|
<description>result</description>
|
||||||
|
<xpath>substring(result,0,1000)</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="resultlength" type="xs:integer">
|
||||||
|
<description>result</description>
|
||||||
|
<xpath>string-length(result)</xpath>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
<views>
|
||||||
|
<view name="filter">name description</view>
|
||||||
|
</views>
|
||||||
|
<iconclass>fa fa-file-code-o</iconclass>
|
||||||
|
<data type="element(query)">collection("replx/queries")/query
|
||||||
|
</data>
|
||||||
|
</entity>
|
||||||
23
src/vue-poc/models/search-result.xml
Normal file
23
src/vue-poc/models/search-result.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<entity name="search-result" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||||
|
<description>About a search result.</description>
|
||||||
|
<fields>
|
||||||
|
<field name="title" type="xs:string">
|
||||||
|
<description>title</description>
|
||||||
|
<xpath>title</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="type" type="xs:string">
|
||||||
|
<description>type</description>
|
||||||
|
<xpath>type</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="uri" type="xs:string">
|
||||||
|
<description>link to result</description>
|
||||||
|
<xpath>uri</xpath>
|
||||||
|
</field>
|
||||||
|
<field name="sref" type="xs:string">
|
||||||
|
<description>ui-router ui-sref data</description>
|
||||||
|
<xpath>"app.item.index({'name':'benchx'})"</xpath>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
<iconclass>fa fa-question-circle</iconclass>
|
||||||
|
<data type="element(search)"></data>
|
||||||
|
</entity>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// generated 2017-09-05T15:21:42.951+01:00
|
// generated 2017-09-07T22:40:46.775+01:00
|
||||||
Vue.component('qd-fullscreen',{template:`
|
Vue.component('qd-fullscreen',{template:`
|
||||||
<a @click="toggle()" href="javascript:void(0);" title="Fullscreen toggle">
|
<a @click="toggle()" href="javascript:void(0);" title="Fullscreen toggle">
|
||||||
<v-icon>{{ fullscreenIcon }}</v-icon>
|
<v-icon>{{ fullscreenIcon }}</v-icon>
|
||||||
|
|
@ -936,10 +936,26 @@ Vue.filter('round', function(value, decimals) {
|
||||||
<v-card>
|
<v-card>
|
||||||
|
|
||||||
<v-toolbar>
|
<v-toolbar>
|
||||||
<v-btn @click="run()">Run</v-btn>
|
|
||||||
<v-btn @click="submit()">
|
|
||||||
<v-icon>play_circle_outline</v-icon>
|
<v-menu offset-y="">
|
||||||
Submit</v-btn>
|
<v-btn slot="activator">
|
||||||
|
<v-icon>play_circle_outline</v-icon>
|
||||||
|
Run</v-btn>
|
||||||
|
<v-list>
|
||||||
|
<v-list-tile @click="submit">
|
||||||
|
<v-list-tile-title>Submit</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-list-tile @click="run">
|
||||||
|
<v-list-tile-title>Run</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile @click="plan">
|
||||||
|
<v-list-tile-title>Show query plan</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn @click="imports">
|
<v-btn @click="imports">
|
||||||
<v-icon>library_books</v-icon>
|
<v-icon>library_books</v-icon>
|
||||||
|
|
@ -1095,7 +1111,7 @@ Vue.filter('round', function(value, decimals) {
|
||||||
},
|
},
|
||||||
plan(){
|
plan(){
|
||||||
this.awaitResult(false)
|
this.awaitResult(false)
|
||||||
HTTP.post("eval/plan",Qs.stringify({xq:this.xq}))
|
HTTPNE.post("eval/plan",Qs.stringify({xq:this.xq}))
|
||||||
.then(r=>{
|
.then(r=>{
|
||||||
this.result=r.data.result
|
this.result=r.data.result
|
||||||
})
|
})
|
||||||
|
|
@ -2849,365 +2865,7 @@ users todo
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
const Vuepoc=Vue.extend({template:`
|
const router = new VueRouter({
|
||||||
<v-app>
|
|
||||||
<v-navigation-drawer persistent="" light="" :mini-variant.sync="mini" v-model="drawer" :disable-route-watcher="true" height="100%" class="grey lighten-4 pb-0">
|
|
||||||
<v-list class="pa-0">
|
|
||||||
|
|
||||||
<v-list-tile avatar="" tag="div">
|
|
||||||
<v-list-tile-avatar>
|
|
||||||
<v-btn icon="" @click="session">
|
|
||||||
<img src="/vue-poc/ui/quodatum.gif">
|
|
||||||
</v-btn>
|
|
||||||
</v-list-tile-avatar>
|
|
||||||
<v-list-tile-content>
|
|
||||||
<v-list-tile-title>Vue PoC</v-list-tile-title>
|
|
||||||
</v-list-tile-content>
|
|
||||||
<v-list-tile-action>
|
|
||||||
<v-btn icon="" @click.stop="mini = !mini">
|
|
||||||
<v-icon>chevron_left</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-tile-action>
|
|
||||||
</v-list-tile>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
<qd-navlist :items="items"></qd-navlist>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-toolbar class="indigo" dark="">
|
|
||||||
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
|
|
||||||
<v-toolbar-title class="hidden-sm-and-down">{{$route.meta.title}}</v-toolbar-title>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-text-field prepend-icon="search" label="Search..." v-model="q" hide-details="" single-line="" dark="" @keyup.enter="search"></v-text-field>
|
|
||||||
<v-menu left="" transition="v-fade-transition">
|
|
||||||
<v-btn dark="" icon="" slot="activator">
|
|
||||||
{{$auth.user}}
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-list>
|
|
||||||
|
|
||||||
<v-list-tile @click="logout()">
|
|
||||||
<v-list-tile-title>logout</v-list-tile-title>
|
|
||||||
</v-list-tile>
|
|
||||||
<v-list-tile>
|
|
||||||
<v-list-tile-title>permission: {{$auth.permission}}</v-list-tile-title>
|
|
||||||
</v-list-tile>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
<v-btn icon="" @click="fullscreen" :disabled="!fullscreenEnabled">
|
|
||||||
<v-icon>{{ fullscreenIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<qd-fullscreen></qd-fullscreen>
|
|
||||||
</v-toolbar>
|
|
||||||
<main>
|
|
||||||
<v-alert error="" value="true" dismissible="" v-model="alert.show">
|
|
||||||
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
|
||||||
</v-alert>
|
|
||||||
<transition name="fade" mode="out-in">
|
|
||||||
<router-view class="view ma-3"></router-view>
|
|
||||||
</transition>
|
|
||||||
</main>
|
|
||||||
</v-app>
|
|
||||||
|
|
||||||
`,
|
|
||||||
|
|
||||||
// router,
|
|
||||||
data:function(){return {
|
|
||||||
q:"",
|
|
||||||
status:{},
|
|
||||||
drawer:true,
|
|
||||||
mini: false,
|
|
||||||
alert:{show:false,msg:"Hello"},
|
|
||||||
items:[
|
|
||||||
{href: '/',text: 'Home', icon: 'home' },
|
|
||||||
{
|
|
||||||
icon: 'folder_open',
|
|
||||||
text: 'Collections' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/database', text: 'Databases',icon: 'developer_mode' },
|
|
||||||
{href: '/files', text: 'File system',icon: 'folder' },
|
|
||||||
{href: '/edit',text: 'Edit',icon: 'mode_edit'},
|
|
||||||
{href: '/history',text: 'history',icon: 'history'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'directions_run',
|
|
||||||
text: 'Actions' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/eval',text: 'Query',icon: 'play_circle_outline'},
|
|
||||||
{href: '/tasks',text: 'Tasks',icon: 'history'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'cast_connected',
|
|
||||||
text: 'Server' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/jobs',text: 'Running jobs',icon: 'dashboard'},
|
|
||||||
{href: '/logs',text: 'Server logs',icon: 'dns'},
|
|
||||||
{href: '/ping',text: 'Ping',icon: 'update'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'camera_roll',
|
|
||||||
text: 'Images' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/images/item',text: 'Collection',icon: 'photo_camera'},
|
|
||||||
{href: '/images/keywords',text: 'Keywords',icon: 'label'},
|
|
||||||
{href: '/images/dates',text: 'Date taken',icon: 'date_range'},
|
|
||||||
{href: '/images/thumbnail',text: 'Thumbnail',icon: 'touch_app'},
|
|
||||||
{href: '/images/report',text: 'Reports',icon: 'report'}
|
|
||||||
]},
|
|
||||||
{
|
|
||||||
icon: 'more_horiz',
|
|
||||||
text: 'More' ,
|
|
||||||
model: false,
|
|
||||||
children: [
|
|
||||||
{href: '/session',text: 'Session',icon: 'person'},
|
|
||||||
{href: '/select',text: 'Select',icon: 'extension'},
|
|
||||||
{href: '/puzzle',text: 'Puzzle',icon: 'extension'},
|
|
||||||
{href: '/tabs',text: 'Tabs',icon: 'switch_camera'},
|
|
||||||
{href: '/timeline',text: 'Time line',icon: 'timelapse'}
|
|
||||||
]},
|
|
||||||
|
|
||||||
{href: '/settings',text: 'Settings',icon: 'settings' },
|
|
||||||
{href: '/about',text: 'About', icon: 'help' },
|
|
||||||
]
|
|
||||||
|
|
||||||
}},
|
|
||||||
methods: {
|
|
||||||
session(){
|
|
||||||
this.$router.push({path: '/session'})
|
|
||||||
},
|
|
||||||
search(){
|
|
||||||
this.$router.push({path: '/search',query: { q: this.q }})
|
|
||||||
},
|
|
||||||
logout(){
|
|
||||||
HTTP.get("logout").then(r=>{
|
|
||||||
alert("logout")
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showAlert(msg){
|
|
||||||
this.alert.msg=moment().format()+" "+ msg
|
|
||||||
this.alert.show=true
|
|
||||||
},
|
|
||||||
fullscreenEnabled(){
|
|
||||||
return document.fullscreenEnabled
|
|
||||||
},
|
|
||||||
isInFullScreen(){
|
|
||||||
return (document.fullscreenElement && document.fullscreenElement !== null) ||
|
|
||||||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
|
|
||||||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
|
|
||||||
(document.msFullscreenElement && document.msFullscreenElement !== null)
|
|
||||||
},
|
|
||||||
fullscreen(){
|
|
||||||
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
|
|
||||||
var isInFullScreen = this.isInFullScreen();
|
|
||||||
alert(isInFullScreen);
|
|
||||||
var docElm = document.documentElement;
|
|
||||||
if (!isInFullScreen) {
|
|
||||||
if (docElm.requestFullscreen) {
|
|
||||||
docElm.requestFullscreen();
|
|
||||||
} else if (docElm.mozRequestFullScreen) {
|
|
||||||
docElm.mozRequestFullScreen();
|
|
||||||
} else if (docElm.webkitRequestFullScreen) {
|
|
||||||
docElm.webkitRequestFullScreen();
|
|
||||||
} else if (docElm.msRequestFullscreen) {
|
|
||||||
docElm.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (document.exitFullscreen) {
|
|
||||||
document.exitFullscreen();
|
|
||||||
} else if (document.webkitExitFullscreen) {
|
|
||||||
document.webkitExitFullscreen();
|
|
||||||
} else if (document.mozCancelFullScreen) {
|
|
||||||
document.mozCancelFullScreen();
|
|
||||||
} else if (document.msExitFullscreen) {
|
|
||||||
document.msExitFullscreen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed:{
|
|
||||||
fullscreenIcon(){ return this.isInFullScreen()?'fullscreen_exit':'fullscreen'}
|
|
||||||
},
|
|
||||||
|
|
||||||
created(){
|
|
||||||
|
|
||||||
console.log("create-----------")
|
|
||||||
Vue.config.errorHandler = function (err, vm, info) {
|
|
||||||
// handle error
|
|
||||||
// `info` is a Vue-specific error info, e.g. which lifecycle hook
|
|
||||||
console.error(err, vm, info);
|
|
||||||
this.showAlert("vue error:\n"+err)
|
|
||||||
alert("vue error");
|
|
||||||
};
|
|
||||||
// Add a response interceptor
|
|
||||||
|
|
||||||
HTTP.interceptors.response.use(
|
|
||||||
(response)=> {
|
|
||||||
// Do something with response data
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
(error) =>{
|
|
||||||
// interupt restxq single
|
|
||||||
if(460 != error.response.status)this.showAlert("http error:\n"+error.response.data)
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
HTTP.get("status")
|
|
||||||
.then(r=>{
|
|
||||||
console.log("status",r.data)
|
|
||||||
Object.assign(Auth,r.data)
|
|
||||||
this.$forceUpdate()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
beforeDestroy(){
|
|
||||||
console.log("destory-----------")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
);
|
|
||||||
// base -----------------------
|
|
||||||
localforage.config({
|
|
||||||
name: 'vuepoc'
|
|
||||||
});
|
|
||||||
|
|
||||||
// errors displayed by interceptor
|
|
||||||
const HTTP = axios.create({
|
|
||||||
baseURL: "/vue-poc/api/",
|
|
||||||
headers: {
|
|
||||||
'X-Custom-Header': 'vue-poc',
|
|
||||||
accept: 'application/json'
|
|
||||||
},
|
|
||||||
paramsSerializer: function(params) {
|
|
||||||
return Qs.stringify(params)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// errors hidden
|
|
||||||
const HTTPNE = axios.create({
|
|
||||||
baseURL: "/vue-poc/api/",
|
|
||||||
headers: {
|
|
||||||
'X-Custom-Header': 'vue-poc',
|
|
||||||
accept: 'application/json'
|
|
||||||
},
|
|
||||||
paramsSerializer: function(params) {
|
|
||||||
return Qs.stringify(params)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const axios_json={ headers: {accept: 'application/json'}};
|
|
||||||
|
|
||||||
const Auth={
|
|
||||||
user:"guest",
|
|
||||||
permission:null,
|
|
||||||
install: function(Vue){
|
|
||||||
Object.defineProperty(Vue.prototype, '$auth', {
|
|
||||||
get () { return Auth }
|
|
||||||
}) }
|
|
||||||
};
|
|
||||||
Vue.use(Auth);
|
|
||||||
|
|
||||||
// read and write settings
|
|
||||||
// https://vuejs.org/v2/guide/state-management.html
|
|
||||||
var settings = {
|
|
||||||
debug: true,
|
|
||||||
getItem (key) {
|
|
||||||
if (this.debug) console.log('getItem',key);
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
localforage.getItem(key)
|
|
||||||
.then((value) => {
|
|
||||||
console.log('GET setting', key,value);
|
|
||||||
resolve(value)
|
|
||||||
}).catch((err) => {
|
|
||||||
console.log('GET failed');
|
|
||||||
reject(err)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setItem (key,value) {
|
|
||||||
if (this.debug) console.log('setItem',key,value);
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
localforage.setItem(key, value)
|
|
||||||
.then((value) => {
|
|
||||||
console.log('SET ',key, value);
|
|
||||||
return new Promise((resolve, reject) => {resolve(value);})
|
|
||||||
}).catch((err) => {
|
|
||||||
console.log('set failed');
|
|
||||||
return new Promise((resolve, reject) => {reject(err);})
|
|
||||||
});
|
|
||||||
})
|
|
||||||
},
|
|
||||||
keys(){
|
|
||||||
return localforage.keys() // returns array of keys
|
|
||||||
|
|
||||||
},
|
|
||||||
clear(){
|
|
||||||
localforage.clear()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Returns a function, that, as long as it continues to be invoked, will not
|
|
||||||
//be triggered. The function will be called after it stops being called for
|
|
||||||
//N milliseconds. If `immediate` is passed, trigger the function on the
|
|
||||||
//leading edge, instead of the trailing. https://gist.github.com/nmsdvid/8807205
|
|
||||||
function debounce(func, wait, immediate) {
|
|
||||||
var timeout;
|
|
||||||
return function() {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(function() {
|
|
||||||
timeout = null;
|
|
||||||
if (!immediate) func.apply(context, args);
|
|
||||||
}, wait);
|
|
||||||
if (immediate && !timeout) func.apply(context, args);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
|
|
||||||
const Fullscreen={
|
|
||||||
isInFullScreen(){
|
|
||||||
return (document.fullscreenElement && document.fullscreenElement !== null) ||
|
|
||||||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
|
|
||||||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
|
|
||||||
(document.msFullscreenElement && document.msFullscreenElement !== null);
|
|
||||||
},
|
|
||||||
toggle(){
|
|
||||||
var docElm = document.documentElement;
|
|
||||||
if (!this.isInFullScreen()) {
|
|
||||||
if (docElm.requestFullscreen) {
|
|
||||||
docElm.requestFullscreen();
|
|
||||||
} else if (docElm.mozRequestFullScreen) {
|
|
||||||
docElm.mozRequestFullScreen();
|
|
||||||
} else if (docElm.webkitRequestFullScreen) {
|
|
||||||
docElm.webkitRequestFullScreen();
|
|
||||||
} else if (docElm.msRequestFullscreen) {
|
|
||||||
docElm.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (document.exitFullscreen) {
|
|
||||||
document.exitFullscreen();
|
|
||||||
} else if (document.webkitExitFullscreen) {
|
|
||||||
document.webkitExitFullscreen();
|
|
||||||
} else if (document.mozCancelFullScreen) {
|
|
||||||
document.mozCancelFullScreen();
|
|
||||||
} else if (document.msExitFullscreen) {
|
|
||||||
document.msExitFullscreen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
install: function(Vue){
|
|
||||||
Object.defineProperty(Vue.prototype, '$fullscreen', {
|
|
||||||
get () { return Fullscreen }
|
|
||||||
}) }
|
|
||||||
};
|
|
||||||
Vue.use(Fullscreen);
|
|
||||||
|
|
||||||
|
|
||||||
const router = new VueRouter({
|
|
||||||
base:"/vue-poc/ui/",
|
base:"/vue-poc/ui/",
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
routes: [
|
routes: [
|
||||||
|
|
@ -3266,11 +2924,65 @@ router.beforeEach((to, from, next) => {
|
||||||
} else {
|
} else {
|
||||||
next() // make sure to always call next()!
|
next() // make sure to always call next()!
|
||||||
}
|
}
|
||||||
});
|
});const Vuepoc=Vue.extend({template:`
|
||||||
|
<v-app id="app" :dark="dark" @theme="onDark">
|
||||||
|
<v-navigation-drawer persistent="" :mini-variant.sync="mini" v-model="drawer" :disable-route-watcher="true" class="grey lighten-4 pb-0">
|
||||||
|
<v-list class="pa-0">
|
||||||
|
|
||||||
Vue.use(Vuetify);
|
<v-list-tile avatar="" tag="div">
|
||||||
|
<v-list-tile-avatar>
|
||||||
|
<v-btn icon="" @click="session">
|
||||||
|
<img src="/vue-poc/ui/quodatum.gif">
|
||||||
|
</v-btn>
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Vue PoC</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
<v-list-tile-action>
|
||||||
|
<v-btn icon="" @click.stop="mini = !mini">
|
||||||
|
<v-icon>chevron_left</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-tile-action>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
const app = new Vue({
|
</v-list>
|
||||||
|
<qd-navlist :items="items"></qd-navlist>
|
||||||
|
</v-navigation-drawer>
|
||||||
|
|
||||||
|
<v-toolbar class="indigo" dark="">
|
||||||
|
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
|
||||||
|
<v-toolbar-title class="hidden-sm-and-down">{{$route.meta.title}}</v-toolbar-title>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-text-field prepend-icon="search" label="Search..." v-model="q" hide-details="" single-line="" dark="" @keyup.enter="search"></v-text-field>
|
||||||
|
<v-menu left="" transition="v-fade-transition">
|
||||||
|
<v-btn dark="" icon="" slot="activator">
|
||||||
|
{{$auth.user}}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-list>
|
||||||
|
|
||||||
|
<v-list-tile @click="logout()">
|
||||||
|
<v-list-tile-title>logout</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile>
|
||||||
|
<v-list-tile-title>permission: {{$auth.permission}}</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
<qd-fullscreen></qd-fullscreen>
|
||||||
|
</v-toolbar>
|
||||||
|
<main>
|
||||||
|
<v-alert error="" value="true" dismissible="" v-model="alert.show">
|
||||||
|
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
||||||
|
</v-alert>
|
||||||
|
<transition name="fade" mode="out-in">
|
||||||
|
<router-view class="view ma-3"></router-view>
|
||||||
|
</transition>
|
||||||
|
</main>
|
||||||
|
</v-app>
|
||||||
|
`,
|
||||||
|
|
||||||
router,
|
router,
|
||||||
data:function(){return {
|
data:function(){return {
|
||||||
q:"",
|
q:"",
|
||||||
|
|
@ -3395,4 +3107,137 @@ const app = new Vue({
|
||||||
console.log("destory-----------")
|
console.log("destory-----------")
|
||||||
|
|
||||||
}
|
}
|
||||||
}).$mount('#app');
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
// base -----------------------
|
||||||
|
localforage.config({
|
||||||
|
name: 'vuepoc'
|
||||||
|
});
|
||||||
|
const AXIOS_CONFIG={
|
||||||
|
baseURL: "/vue-poc/api/",
|
||||||
|
headers: {
|
||||||
|
'X-Custom-Header': 'vue-poc',
|
||||||
|
accept: 'application/json'
|
||||||
|
},
|
||||||
|
paramsSerializer: function(params) {
|
||||||
|
return Qs.stringify(params)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// errors displayed by interceptor
|
||||||
|
const HTTP = axios.create(AXIOS_CONFIG);
|
||||||
|
// errors hidden
|
||||||
|
const HTTPNE = axios.create(AXIOS_CONFIG);
|
||||||
|
const axios_json={ headers: {accept: 'application/json'}};
|
||||||
|
|
||||||
|
const Auth={
|
||||||
|
user:"guest",
|
||||||
|
permission:null,
|
||||||
|
install: function(Vue){
|
||||||
|
Object.defineProperty(Vue.prototype, '$auth', {
|
||||||
|
get () { return Auth }
|
||||||
|
}) }
|
||||||
|
};
|
||||||
|
Vue.use(Auth);
|
||||||
|
|
||||||
|
// read and write settings
|
||||||
|
// https://vuejs.org/v2/guide/state-management.html
|
||||||
|
var settings = {
|
||||||
|
debug: true,
|
||||||
|
getItem (key) {
|
||||||
|
if (this.debug) console.log('getItem',key);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
localforage.getItem(key)
|
||||||
|
.then((value) => {
|
||||||
|
console.log('GET setting', key,value);
|
||||||
|
resolve(value)
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('GET failed');
|
||||||
|
reject(err)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setItem (key,value) {
|
||||||
|
if (this.debug) console.log('setItem',key,value);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
localforage.setItem(key, value)
|
||||||
|
.then((value) => {
|
||||||
|
console.log('SET ',key, value);
|
||||||
|
return new Promise((resolve, reject) => {resolve(value);})
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('set failed');
|
||||||
|
return new Promise((resolve, reject) => {reject(err);})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
},
|
||||||
|
keys(){
|
||||||
|
return localforage.keys() // returns array of keys
|
||||||
|
|
||||||
|
},
|
||||||
|
clear(){
|
||||||
|
localforage.clear()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Returns a function, that, as long as it continues to be invoked, will not
|
||||||
|
//be triggered. The function will be called after it stops being called for
|
||||||
|
//N milliseconds. If `immediate` is passed, trigger the function on the
|
||||||
|
//leading edge, instead of the trailing. https://gist.github.com/nmsdvid/8807205
|
||||||
|
function debounce(func, wait, immediate) {
|
||||||
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) func.apply(context, args);
|
||||||
|
}, wait);
|
||||||
|
if (immediate && !timeout) func.apply(context, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
|
||||||
|
const Fullscreen={
|
||||||
|
isInFullScreen(){
|
||||||
|
return (document.fullscreenElement && document.fullscreenElement !== null) ||
|
||||||
|
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
|
||||||
|
(document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
|
||||||
|
(document.msFullscreenElement && document.msFullscreenElement !== null);
|
||||||
|
},
|
||||||
|
toggle(){
|
||||||
|
var docElm = document.documentElement;
|
||||||
|
if (!this.isInFullScreen()) {
|
||||||
|
if (docElm.requestFullscreen) {
|
||||||
|
docElm.requestFullscreen();
|
||||||
|
} else if (docElm.mozRequestFullScreen) {
|
||||||
|
docElm.mozRequestFullScreen();
|
||||||
|
} else if (docElm.webkitRequestFullScreen) {
|
||||||
|
docElm.webkitRequestFullScreen();
|
||||||
|
} else if (docElm.msRequestFullscreen) {
|
||||||
|
docElm.msRequestFullscreen();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (document.exitFullscreen) {
|
||||||
|
document.exitFullscreen();
|
||||||
|
} else if (document.webkitExitFullscreen) {
|
||||||
|
document.webkitExitFullscreen();
|
||||||
|
} else if (document.mozCancelFullScreen) {
|
||||||
|
document.mozCancelFullScreen();
|
||||||
|
} else if (document.msExitFullscreen) {
|
||||||
|
document.msExitFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
install: function(Vue){
|
||||||
|
Object.defineProperty(Vue.prototype, '$fullscreen', {
|
||||||
|
get () { return Fullscreen }
|
||||||
|
}) }
|
||||||
|
};
|
||||||
|
Vue.use(Fullscreen);
|
||||||
|
|
||||||
|
|
||||||
|
Vue.use(Vuetify);
|
||||||
|
new Vuepoc().$mount('#app')
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,57 @@
|
||||||
/* app.css */
|
/* app.css */
|
||||||
body {
|
|
||||||
overflow-y:hidden!;
|
/* http://tobiasahlin.com/spinkit/ */
|
||||||
|
.spinner {
|
||||||
|
margin: 100px auto;
|
||||||
|
width: 50px;
|
||||||
|
height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner > div {
|
||||||
|
background-color: #0000a0;
|
||||||
|
height: 100%;
|
||||||
|
width: 6px;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
|
||||||
|
animation: sk-stretchdelay 1.2s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner .rect2 {
|
||||||
|
-webkit-animation-delay: -1.1s;
|
||||||
|
animation-delay: -1.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner .rect3 {
|
||||||
|
-webkit-animation-delay: -1.0s;
|
||||||
|
animation-delay: -1.0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner .rect4 {
|
||||||
|
-webkit-animation-delay: -0.9s;
|
||||||
|
animation-delay: -0.9s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner .rect5 {
|
||||||
|
-webkit-animation-delay: -0.8s;
|
||||||
|
animation-delay: -0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes sk-stretchdelay {
|
||||||
|
0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
|
||||||
|
20% { -webkit-transform: scaleY(1.0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes sk-stretchdelay {
|
||||||
|
0%, 40%, 100% {
|
||||||
|
transform: scaleY(0.4);
|
||||||
|
-webkit-transform: scaleY(0.4);
|
||||||
|
} 20% {
|
||||||
|
transform: scaleY(1.0);
|
||||||
|
-webkit-transform: scaleY(1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.fade-enter-active, .fade-leave-active {
|
.fade-enter-active, .fade-leave-active {
|
||||||
transition-property: opacity;
|
transition-property: opacity;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,22 @@
|
||||||
<link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css">
|
<link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css">
|
||||||
<link rel="shortcut icon" href="/vue-poc/ui/icon.png"/>
|
<link rel="shortcut icon" href="/vue-poc/ui/icon.png"/>
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<div class="spinner">
|
||||||
|
<div class="rect1"></div>
|
||||||
|
<div class="rect2"></div>
|
||||||
|
<div class="rect3"></div>
|
||||||
|
<div class="rect4"></div>
|
||||||
|
<div class="rect5"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.5.3/vue-router.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.5.3/vue-router.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script>
|
||||||
|
|
@ -30,71 +46,7 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.4.3/localforage.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.4.3/localforage.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.js"></script>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
|
|
||||||
|
|
||||||
<script src="/vue-poc/ui/perf-stat.js"></script>
|
<script src="/vue-poc/ui/perf-stat.js"></script>
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<v-app id="app" :dark="dark" @theme="onDark">
|
|
||||||
<v-navigation-drawer persistent :mini-variant.sync="mini" v-model="drawer"
|
|
||||||
:disable-route-watcher="true" class="grey lighten-4 pb-0">
|
|
||||||
<v-list class="pa-0">
|
|
||||||
|
|
||||||
<v-list-tile avatar tag="div">
|
|
||||||
<v-list-tile-avatar >
|
|
||||||
<v-btn icon @click="session">
|
|
||||||
<img src="/vue-poc/ui/quodatum.gif" />
|
|
||||||
</v-btn>
|
|
||||||
</v-list-tile-avatar>
|
|
||||||
<v-list-tile-content>
|
|
||||||
<v-list-tile-title>Vue PoC</v-list-tile-title>
|
|
||||||
</v-list-tile-content>
|
|
||||||
<v-list-tile-action>
|
|
||||||
<v-btn icon @click.stop="mini = !mini">
|
|
||||||
<v-icon>chevron_left</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-tile-action>
|
|
||||||
</v-list-tile>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
<qd-navlist :items="items"></qd-navlist>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-toolbar class="indigo" dark >
|
|
||||||
<v-toolbar-side-icon @click.stop="drawer = !drawer" ></v-toolbar-side-icon>
|
|
||||||
<v-toolbar-title class="hidden-sm-and-down" >{{$route.meta.title}}</v-toolbar-title>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-text-field prepend-icon="search" label="Search..." v-model="q"
|
|
||||||
hide-details single-line dark @keyup.enter="search"></v-text-field>
|
|
||||||
<v-menu left transition="v-fade-transition">
|
|
||||||
<v-btn dark icon slot="activator">
|
|
||||||
{{$auth.user}}
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-list>
|
|
||||||
|
|
||||||
<v-list-tile @click="logout()">
|
|
||||||
<v-list-tile-title >logout</v-list-tile-title>
|
|
||||||
</v-list-tile>
|
|
||||||
<v-list-tile>
|
|
||||||
<v-list-tile-title >permission: {{$auth.permission}}</v-list-tile-title>
|
|
||||||
</v-list-tile>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
<qd-fullscreen></qd-fullscreen>
|
|
||||||
</v-toolbar>
|
|
||||||
<main>
|
|
||||||
<v-alert error value="true" dismissible v-model="alert.show">
|
|
||||||
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
|
||||||
</v-alert>
|
|
||||||
<transition name="fade" mode="out-in">
|
|
||||||
<router-view class="view ma-3"></router-view>
|
|
||||||
</transition>
|
|
||||||
</main>
|
|
||||||
</v-app>
|
|
||||||
|
|
||||||
|
|
||||||
<script src="/vue-poc/ui/app-gen.js"></script>
|
<script src="/vue-poc/ui/app-gen.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
declare namespace fw="quodatum:collection.walker";
|
declare namespace fw="quodatum:collection.walker";
|
||||||
declare namespace c="http://www.w3.org/ns/xproc-step";
|
declare namespace c="http://www.w3.org/ns/xproc-step";
|
||||||
import module namespace tree="quodatum.data.tree" at "lib/tree.xqm";
|
import module namespace tree="quodatum.data.tree" at "../lib/tree.xqm";
|
||||||
|
|
||||||
let $paths:=uri-collection("/ALO")
|
let $paths:=uri-collection("/ALO")
|
||||||
return tree:build($paths)
|
return tree:build($paths)
|
||||||
13
src/vue-poc/tasks/create-db.xq
Normal file
13
src/vue-poc/tasks/create-db.xq
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
(:~
|
||||||
|
: create vue-poc db
|
||||||
|
:)
|
||||||
|
import module namespace dbtools = 'quodatum.dbtools' at "../lib/dbtools.xqm";
|
||||||
|
|
||||||
|
declare variable $target-db:="vue-poc";
|
||||||
|
|
||||||
|
declare variable $data-uri:=resolve-uri("../data/vue-poc/");
|
||||||
|
(dbtools:sync-from-files(
|
||||||
|
$target-db
|
||||||
|
,$data-uri
|
||||||
|
,file:list($data-uri,fn:true())
|
||||||
|
,hof:id#1))
|
||||||
|
|
@ -12,7 +12,18 @@ declare namespace c="http://www.w3.org/ns/xproc-step";
|
||||||
|
|
||||||
declare namespace wadl="http://wadl.dev.java.net/2009/02";
|
declare namespace wadl="http://wadl.dev.java.net/2009/02";
|
||||||
|
|
||||||
|
(:~
|
||||||
|
: get status
|
||||||
|
:)
|
||||||
|
declare
|
||||||
|
%rest:GET %rest:path("/vue-poc/api/start")
|
||||||
|
function vue-api:start( )
|
||||||
|
{
|
||||||
|
if(db:exists("vue-poc")) then
|
||||||
|
()
|
||||||
|
else
|
||||||
|
()
|
||||||
|
};
|
||||||
|
|
||||||
(:~
|
(:~
|
||||||
: Returns a query result.
|
: Returns a query result.
|
||||||
|
|
|
||||||
190
src/vue-poc/vue-poc.vue
Normal file
190
src/vue-poc/vue-poc.vue
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<template id="vuepoc">
|
||||||
|
<v-app id="app" :dark="dark" @theme="onDark">
|
||||||
|
<v-navigation-drawer persistent :mini-variant.sync="mini" v-model="drawer"
|
||||||
|
:disable-route-watcher="true" class="grey lighten-4 pb-0">
|
||||||
|
<v-list class="pa-0">
|
||||||
|
|
||||||
|
<v-list-tile avatar tag="div">
|
||||||
|
<v-list-tile-avatar >
|
||||||
|
<v-btn icon @click="session">
|
||||||
|
<img src="/vue-poc/ui/quodatum.gif" />
|
||||||
|
</v-btn>
|
||||||
|
</v-list-tile-avatar>
|
||||||
|
<v-list-tile-content>
|
||||||
|
<v-list-tile-title>Vue PoC</v-list-tile-title>
|
||||||
|
</v-list-tile-content>
|
||||||
|
<v-list-tile-action>
|
||||||
|
<v-btn icon @click.stop="mini = !mini">
|
||||||
|
<v-icon>chevron_left</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-tile-action>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
|
</v-list>
|
||||||
|
<qd-navlist :items="items"></qd-navlist>
|
||||||
|
</v-navigation-drawer>
|
||||||
|
|
||||||
|
<v-toolbar class="indigo" dark >
|
||||||
|
<v-toolbar-side-icon @click.stop="drawer = !drawer" ></v-toolbar-side-icon>
|
||||||
|
<v-toolbar-title class="hidden-sm-and-down" >{{$route.meta.title}}</v-toolbar-title>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-text-field prepend-icon="search" label="Search..." v-model="q"
|
||||||
|
hide-details single-line dark @keyup.enter="search"></v-text-field>
|
||||||
|
<v-menu left transition="v-fade-transition">
|
||||||
|
<v-btn dark icon slot="activator">
|
||||||
|
{{$auth.user}}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-list>
|
||||||
|
|
||||||
|
<v-list-tile @click="logout()">
|
||||||
|
<v-list-tile-title >logout</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
<v-list-tile>
|
||||||
|
<v-list-tile-title >permission: {{$auth.permission}}</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
|
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
<qd-fullscreen></qd-fullscreen>
|
||||||
|
</v-toolbar>
|
||||||
|
<main>
|
||||||
|
<v-alert error value="true" dismissible v-model="alert.show">
|
||||||
|
<pre style="overflow:auto;">{{ alert.msg }}</pre>
|
||||||
|
</v-alert>
|
||||||
|
<transition name="fade" mode="out-in">
|
||||||
|
<router-view class="view ma-3"></router-view>
|
||||||
|
</transition>
|
||||||
|
</main>
|
||||||
|
</v-app>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>{
|
||||||
|
router,
|
||||||
|
data:function(){return {
|
||||||
|
q:"",
|
||||||
|
status:{},
|
||||||
|
drawer:true,
|
||||||
|
mini: false,
|
||||||
|
dark: false,
|
||||||
|
alert:{show:false,msg:"Hello"},
|
||||||
|
items:[
|
||||||
|
{href: '/',text: 'Home', icon: 'home' },
|
||||||
|
{
|
||||||
|
icon: 'folder_open',
|
||||||
|
text: 'Collections' ,
|
||||||
|
model: false,
|
||||||
|
children: [
|
||||||
|
{href: '/database', text: 'Databases',icon: 'developer_mode' },
|
||||||
|
{href: '/files', text: 'File system',icon: 'folder' },
|
||||||
|
{href: '/edit',text: 'Edit',icon: 'mode_edit'},
|
||||||
|
{href: '/history',text: 'history',icon: 'history'}
|
||||||
|
]},
|
||||||
|
{
|
||||||
|
icon: 'directions_run',
|
||||||
|
text: 'Actions' ,
|
||||||
|
model: false,
|
||||||
|
children: [
|
||||||
|
{href: '/eval',text: 'Query',icon: 'play_circle_outline'},
|
||||||
|
{href: '/tasks',text: 'Tasks',icon: 'history'}
|
||||||
|
]},
|
||||||
|
{
|
||||||
|
icon: 'cast_connected',
|
||||||
|
text: 'Server' ,
|
||||||
|
model: false,
|
||||||
|
children: [
|
||||||
|
{href: '/jobs',text: 'Running jobs',icon: 'dashboard'},
|
||||||
|
{href: '/logs',text: 'Server logs',icon: 'dns'},
|
||||||
|
{href: '/server/users',text: 'Users',icon: 'supervisor_account'},
|
||||||
|
{href: '/server/repo',text: 'Server code repository',icon: 'local_library'},
|
||||||
|
{href: '/ping',text: 'Ping',icon: 'update'}
|
||||||
|
]},
|
||||||
|
{
|
||||||
|
icon: 'camera_roll',
|
||||||
|
text: 'Images' ,
|
||||||
|
model: false,
|
||||||
|
children: [
|
||||||
|
{href: '/images/item',text: 'Collection',icon: 'photo_camera'},
|
||||||
|
{href: '/images/keywords',text: 'Keywords',icon: 'label'},
|
||||||
|
{href: '/images/dates',text: 'Date taken',icon: 'date_range'},
|
||||||
|
{href: '/images/thumbnail',text: 'Thumbnail',icon: 'touch_app'},
|
||||||
|
{href: '/images/report',text: 'Reports',icon: 'report'}
|
||||||
|
]},
|
||||||
|
{
|
||||||
|
icon: 'more_horiz',
|
||||||
|
text: 'More' ,
|
||||||
|
model: false,
|
||||||
|
children: [
|
||||||
|
{href: '/session',text: 'Session',icon: 'person'},
|
||||||
|
{href: '/select',text: 'Select',icon: 'extension'},
|
||||||
|
{href: '/puzzle',text: 'Puzzle',icon: 'extension'},
|
||||||
|
{href: '/tabs',text: 'Tabs',icon: 'switch_camera'},
|
||||||
|
{href: '/timeline',text: 'Time line',icon: 'timelapse'}
|
||||||
|
]},
|
||||||
|
|
||||||
|
{href: '/settings',text: 'Settings',icon: 'settings' },
|
||||||
|
{href: '/about',text: 'About', icon: 'help' },
|
||||||
|
]
|
||||||
|
|
||||||
|
}},
|
||||||
|
methods: {
|
||||||
|
session(){
|
||||||
|
this.$router.push({path: '/session'})
|
||||||
|
},
|
||||||
|
search(){
|
||||||
|
this.$router.push({path: '/search',query: { q: this.q }})
|
||||||
|
},
|
||||||
|
logout(){
|
||||||
|
HTTP.get("logout").then(r=>{
|
||||||
|
alert("logout")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
showAlert(msg){
|
||||||
|
this.alert.msg=moment().format()+" "+ msg
|
||||||
|
this.alert.show=true
|
||||||
|
},
|
||||||
|
onDark(dark){
|
||||||
|
this.dark=dark
|
||||||
|
alert("theme")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created(){
|
||||||
|
|
||||||
|
console.log("create-----------")
|
||||||
|
var that=this
|
||||||
|
Vue.config.errorHandler = function (err, vm, info) {
|
||||||
|
// handle error
|
||||||
|
// `info` is a Vue-specific error info, e.g. which lifecycle hook
|
||||||
|
console.error(err, vm, info);
|
||||||
|
that.showAlert("vue error:\n"+err)
|
||||||
|
alert("vue error");
|
||||||
|
};
|
||||||
|
// Add a response interceptor
|
||||||
|
|
||||||
|
HTTP.interceptors.response.use(
|
||||||
|
(response)=> {
|
||||||
|
// Do something with response data
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
(error) =>{
|
||||||
|
// interupt restxq single
|
||||||
|
console.log("$$$$$$$$$$$",error)
|
||||||
|
if(460 != error.response.status)this.showAlert("http error:\n"+error.response.data)
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
HTTP.get("status")
|
||||||
|
.then(r=>{
|
||||||
|
console.log("status",r.data)
|
||||||
|
Object.assign(Auth,r.data)
|
||||||
|
this.$forceUpdate()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy(){
|
||||||
|
console.log("destory-----------")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -40,7 +40,9 @@ function vue-poc:file(
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
(:~
|
||||||
|
:web serve $file if it exists otherwise serve $vue-poc:index
|
||||||
|
:)
|
||||||
declare function vue-poc:get-file($file)
|
declare function vue-poc:get-file($file)
|
||||||
{
|
{
|
||||||
let $path := resolve-uri( 'static/' || $file,static-base-uri())
|
let $path := resolve-uri( 'static/' || $file,static-base-uri())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue