crumbs
This commit is contained in:
parent
251cf23fd8
commit
07509ce03b
19 changed files with 289 additions and 183 deletions
|
@ -60,6 +60,22 @@ Vue.config.errorHandler = function (err, vm, info) {
|
|||
alert("vue error");
|
||||
};
|
||||
|
||||
//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);
|
||||
};
|
||||
};
|
||||
|
||||
// used by vue-ace
|
||||
var Events = new Vue({});
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
</v-btn>
|
||||
<v-toolbar-title>
|
||||
<v-breadcrumbs>
|
||||
<v-breadcrumbs-item v-for="item in crumbs" :key="item" :to="{ query: { url: '/' + item + '/' }}">
|
||||
{{ item }}
|
||||
<v-breadcrumbs-item v-for="item in crumbs" :key="item.path" :to="{ query: { url: item.path }}">
|
||||
{{ item.name }}
|
||||
</v-breadcrumbs-item>
|
||||
</v-breadcrumbs>
|
||||
</v-toolbar-title>
|
||||
|
@ -149,7 +149,10 @@
|
|||
return (this.protocol=="basexdb")?"developer_mode":"folder"
|
||||
},
|
||||
crumbs(){
|
||||
return this.url.split("/").filter((a)=>a.length>0)
|
||||
var parts=this.url.split("/").filter((a)=>a.length>0)
|
||||
var a=parts.map(function(v,i,a){return {name:v,
|
||||
path:"/"+a.slice(0,i+1).join("/")+"/"}})
|
||||
return a
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
|
|
|
@ -12,17 +12,15 @@
|
|||
<v-btn @click="imports()">
|
||||
<v-icon>play_circle_outline</v-icon>
|
||||
Imports</v-btn>
|
||||
<v-menu :nudge-width="100">
|
||||
<v-toolbar-title slot="activator">
|
||||
<span>{{font}}</span>
|
||||
<v-icon >arrow_drop_down</v-icon>
|
||||
</v-toolbar-title>
|
||||
<v-list>
|
||||
<v-list-tile v-for="item in dropdown_font" :key="item.text">
|
||||
<v-list-tile-title v-text="item.text" @click="font=item.text"></v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-menu offset-y>
|
||||
<v-btn icon primary dark slot="activator"> <v-icon>more_vert</v-icon></v-btn>
|
||||
<v-list>
|
||||
<v-list-tile @click="plan">Show query plan</v-list-tile>
|
||||
</v-list>
|
||||
<v-list>
|
||||
<v-list-tile @click="hitme">hit me</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-toolbar>
|
||||
|
||||
|
||||
|
@ -37,25 +35,27 @@
|
|||
{{result}}
|
||||
</v-alert>
|
||||
<v-card-actions v-if="show" >
|
||||
|
||||
JobId:
|
||||
<v-chip class="green white--text">{{jobId}}</v-chip>
|
||||
<v-progress-circular v-if="waiting" indeterminate class="primary--text"></v-progress-circular>
|
||||
|
||||
|
||||
<v-chip class="primary white--text">{{jobId}}</v-chip>
|
||||
|
||||
<v-chip label class="grey white--text">
|
||||
<v-avatar class="red"> <v-icon>lock</v-icon>W</v-avatar>
|
||||
{{ jobState.writes }}</v-chip>
|
||||
<v-chip label class="grey white--text">
|
||||
<v-avatar class="amber"> <v-icon>lock</v-icon>R</v-avatar>
|
||||
{{ jobState.reads }}</v-chip>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<v-chip class="green white--text">
|
||||
<v-progress-circular v-if="waiting" indeterminate class="primary--text"></v-progress-circular>
|
||||
<v-chip>{{ jobState.state }}</v-chip>
|
||||
<v-chip class="primary white--text">
|
||||
<v-avatar > <v-icon>timer</v-icon></v-avatar>
|
||||
{{elapsed}}ms</v-chip>
|
||||
|
||||
</v-card-actions>
|
||||
<v-card-text v-if="show">
|
||||
<v-card-text v-if="showResult">
|
||||
<v-flex xs12 style="height:200px" fill-height>
|
||||
<vue-ace :content="result" mode="text" wrap="true" read-only="true"
|
||||
<vue-ace :content="result" mode="text" wrap="false" read-only="true"
|
||||
></vue-ace>
|
||||
</v-flex>
|
||||
</v-card-text>
|
||||
|
@ -71,18 +71,12 @@
|
|||
result:'',
|
||||
elapsed: null,
|
||||
show: false,
|
||||
showError: false,
|
||||
showError: false, //unused
|
||||
showResult: false, //
|
||||
jobId: null,
|
||||
waiting: false,
|
||||
start: null,
|
||||
jobState: {},
|
||||
font: 'Courier',
|
||||
dropdown_font: [
|
||||
{ text: 'Test select' },
|
||||
{ text: 'Calibri' },
|
||||
{ text: 'Courier' },
|
||||
{ text: 'Verdana' }
|
||||
]
|
||||
jobState: {}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
@ -93,14 +87,13 @@
|
|||
},
|
||||
|
||||
run(){
|
||||
this.showError=this.show=false
|
||||
this.awaitResult(false)
|
||||
this.start = performance.now();
|
||||
HTTP.post("eval/execute",Qs.stringify({xq:this.xq}))
|
||||
.then(r=>{
|
||||
this.elapsed=Math.floor(performance.now() - this.start);
|
||||
this.result=r.data.result
|
||||
this.jobId=null
|
||||
this.show=true
|
||||
})
|
||||
.catch(r=> {
|
||||
console.log("error",r)
|
||||
|
@ -112,12 +105,12 @@
|
|||
},
|
||||
submit(){
|
||||
var data={xq:this.xq}
|
||||
this.showError=this.show=false
|
||||
this.showResult=this.show=false
|
||||
this.start = performance.now();
|
||||
HTTP.post("eval/submit",Qs.stringify(data))
|
||||
.then(r=>{
|
||||
this.elapsed=Math.floor(performance.now() - this.start);
|
||||
this.result=this.jobId=r.data.job
|
||||
this.jobId=r.data.job
|
||||
this.show=true
|
||||
this.pollState()
|
||||
|
||||
|
@ -144,15 +137,38 @@
|
|||
})
|
||||
},
|
||||
getResult(){
|
||||
this.awaitResult(true)
|
||||
HTTP.post("eval/result/"+this.jobId)
|
||||
.then(r=>{
|
||||
this.result=r.data.result
|
||||
this.jobId=null
|
||||
this.show=true
|
||||
})
|
||||
},
|
||||
hitme(){
|
||||
this.showResult=true
|
||||
setTimeout(()=>{this.result="123\n".repeat(20000); },10);
|
||||
|
||||
},
|
||||
imports(){
|
||||
alert("@TODO imports")
|
||||
},
|
||||
plan(){
|
||||
this.awaitResult(false)
|
||||
HTTP.post("eval/plan",Qs.stringify({xq:this.xq}))
|
||||
.then(r=>{
|
||||
this.result=r.data.result
|
||||
})
|
||||
.catch(r=> {
|
||||
console.log("error",r)
|
||||
this.result=r.response.data
|
||||
this.showError=true;
|
||||
|
||||
});
|
||||
},
|
||||
awaitResult(show){
|
||||
// ace slow when setting large text while hidden
|
||||
this.show=show
|
||||
this.result="(Please wait..)"
|
||||
this.showResult=true
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -24,6 +24,22 @@ function vue-api:eval($xq )
|
|||
</json>
|
||||
};
|
||||
|
||||
(:~
|
||||
: query plan
|
||||
:)
|
||||
declare
|
||||
%rest:POST %rest:path("/vue-poc/api/eval/plan")
|
||||
%rest:form-param("xq", "{$xq}")
|
||||
%output:method("json")
|
||||
function vue-api:plan($xq )
|
||||
{
|
||||
let $x:=fn:trace($xq,"task: ")
|
||||
let $r:=xquery:parse($xq,map{"compile":true(),"plan":true()})
|
||||
return <json type="object" >
|
||||
<result>{ serialize($r) }</result>
|
||||
</json>
|
||||
};
|
||||
|
||||
(:~
|
||||
: submit a simple job
|
||||
:)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<v-layout>
|
||||
<v-flex xs5>
|
||||
<pre style="overflow:auto;">{{ image.doc }}</pre>
|
||||
<a :href="meta" target="_new" >full metadata</a>
|
||||
</v-flex>
|
||||
|
||||
<v-flex xs7 >
|
||||
|
@ -40,7 +41,10 @@
|
|||
computed: {
|
||||
path(){
|
||||
return this.loaded?'/vue-poc/api/images/list/'+ this.id+ '/image':null
|
||||
}
|
||||
},
|
||||
meta(){
|
||||
return this.loaded?'/vue-poc/api/images/list/'+ this.id+ '/meta':null
|
||||
}
|
||||
},
|
||||
created:function(){
|
||||
var id=this._props.id
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
v-if="query.keyword || query.from || query.until">
|
||||
<v-icon>clear</v-icon>
|
||||
</v-btn>
|
||||
<v-chip class="primary white--text">{{ total }}</v-chip>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<span v-if="!busy">
|
||||
<v-chip class="primary white--text">{{ total }} in {{ elapsed | round(2) }} secs </v-chip>
|
||||
|
||||
Page:{{ query.page+1 }}
|
||||
<v-btn @click.stop="query.page=Math.min(0,query.page-1)" :disabled="query.page==0" icon primary>
|
||||
|
@ -25,6 +26,7 @@
|
|||
<v-btn @click.stop="query.page+=1" icon primary>
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-btn>
|
||||
</span>
|
||||
</v-toolbar>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
|
||||
<v-container v-if="!busy" fluid grid-list-md>
|
||||
|
@ -163,6 +165,7 @@
|
|||
keyword:null
|
||||
},
|
||||
total:null,
|
||||
elapsed:null,
|
||||
showFilter:false,
|
||||
busy:false,
|
||||
menu2:false,
|
||||
|
@ -184,7 +187,7 @@
|
|||
this.total=r.data.total
|
||||
this.images=r.data.items
|
||||
var t1 = performance.now();
|
||||
console.log("Time: ",t1 - t0)
|
||||
this.elapsed= 0.001 *(t1 - t0)
|
||||
})
|
||||
},
|
||||
clear(){
|
||||
|
|
|
@ -72,7 +72,7 @@ declare
|
|||
function vue-api:keywords()
|
||||
{
|
||||
let $keys:=
|
||||
collection("/vue-poc/Pictures")/image/keywords/keyword
|
||||
collection("/vue-poc/image")/image/keywords/keyword
|
||||
=>distinct-values()
|
||||
=>sort("http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive")
|
||||
return <json type="object" >
|
||||
|
@ -82,14 +82,37 @@ return <json type="object" >
|
|||
</json>
|
||||
};
|
||||
|
||||
(:~ fields for image for json :)
|
||||
(:~ full size image :)
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/images/list/{ $id }/image")
|
||||
function vue-api:rawimage($id as xs:integer)
|
||||
{
|
||||
let $image as element(image):=db:open-id("vue-poc",$id)
|
||||
let $path:=$cfg:IMAGEDIR || '../' || $vue-api:entity?access?path($image)
|
||||
return (
|
||||
web:response-header(map { 'media-type': web:content-type($path) }),
|
||||
file:read-binary($path)
|
||||
)
|
||||
};
|
||||
|
||||
(:~ image metadata :)
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/images/list/{ $id }/meta")
|
||||
function vue-api:meta($id as xs:integer)
|
||||
{
|
||||
let $image as element(image):=db:open-id("vue-poc",$id)
|
||||
let $path:="vue-poc/meta/" || $vue-api:entity?access?path($image) || "/meta.xml"
|
||||
return doc($path)
|
||||
};
|
||||
|
||||
(:~ fields for thumbnail for json :)
|
||||
declare function vue-api:get-image($image as element(image))
|
||||
as element(*)*
|
||||
{
|
||||
let $id:=$vue-api:entity?access?id($image)
|
||||
let $path:=$vue-api:entity?access?path($image)
|
||||
let $name:=$vue-api:entity?access?name($image)
|
||||
let $thumb:= $cfg:THUMBDIR || $path
|
||||
let $thumb:= $cfg:THUMBDIR || $path
|
||||
let $thumb:=if(file:exists($thumb)) then $thumb else $cfg:THUMBDIR || "missing.jpg"
|
||||
return ( <id>{$id}</id>
|
||||
,<name>{$name}</name>
|
||||
|
@ -98,16 +121,5 @@ return ( <id>{$id}</id>
|
|||
,<mime>{fetch:content-type($thumb)}</mime>)
|
||||
};
|
||||
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/images/list/{ $id }/image")
|
||||
function vue-api:rawimage($id as xs:integer)
|
||||
{
|
||||
let $image as element(image):=db:open-id("vue-poc",$id)
|
||||
let $path:=$cfg:IMAGEDIR || $vue-api:entity?access?path($image)
|
||||
return (
|
||||
web:response-header(map { 'media-type': web:content-type($path) }),
|
||||
file:read-binary($path)
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -9,15 +9,15 @@ declare namespace c="http://www.w3.org/ns/xproc-step";
|
|||
declare variable $DB:="vue-poc";
|
||||
declare variable $CHUNK:=1000;
|
||||
|
||||
let $done:=uri-collection("vue-poc/Pictures")
|
||||
let $done:=uri-collection("vue-poc/meta")
|
||||
let $files:= doc("/vue-poc/pics.xml")//c:file[ends-with(lower-case(@name),".jpg")]
|
||||
|
||||
let $relpath:= $files!( ancestor-or-self::*/@name=>string-join("/"))
|
||||
|
||||
let $todo:= $relpath[not("/vue-poc/" || .|| "/meta.xml"=$done)]
|
||||
let $todo:= $relpath[not("/vue-poc/meta/" || .|| "/meta.xml"=$done)]
|
||||
return (for $f in subsequence($todo,1, $CHUNK)
|
||||
let $spath:=$cfg:IMAGEDIR || "../" || $f
|
||||
let $dbpath:=$f || "/meta.xml"
|
||||
let $dbpath:="meta/" || $f || "/meta.xml"
|
||||
let $meta:=imgmeta:read($spath)
|
||||
return db:replace($DB,$dbpath,$meta),
|
||||
db:output($todo=>count()))
|
|
@ -4,7 +4,7 @@
|
|||
:)
|
||||
import module namespace metadata = 'expkg-zone58:image.metadata';
|
||||
import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";
|
||||
for $meta in collection("/vue-poc/Pictures")/metadata
|
||||
for $meta in collection("/vue-poc/meta")/metadata
|
||||
let $loc:=db:path($meta)=>tokenize("/")
|
||||
let $name:=$loc[count($loc)-1]
|
||||
let $path:= subsequence($loc,1,count($loc)-1)=>string-join("/")
|
||||
|
@ -14,5 +14,5 @@ for $meta in collection("/vue-poc/Pictures")/metadata
|
|||
metadata:geo($meta),
|
||||
metadata:keywords($meta)
|
||||
} </image>
|
||||
let $target:=$path || "/image.xml"
|
||||
let $target:="image/"|| $path || "/image.xml"
|
||||
return db:replace("vue-poc",$target,$image)
|
|
@ -29,7 +29,7 @@ declare %updating function local:write-binary($data,$url as xs:string)
|
|||
file:write-binary($url,$data)
|
||||
)
|
||||
};
|
||||
let $done:=uri-collection("vue-poc/Pictures")
|
||||
|
||||
let $files:= doc("/vue-poc/pics.xml")//c:file[ends-with(lower-case(@name),".jpg")]
|
||||
|
||||
let $relpath:= $files!( ancestor-or-self::*/@name=>string-join("/"))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(: set original:)
|
||||
for $i in collection("/vue-poc/Pictures")/image
|
||||
for $i in collection("/vue-poc/image")/image
|
||||
where $i[file/@path=>contains('original')]
|
||||
return insert node attribute { 'original' } { true() } into $i
|
|
@ -2,29 +2,30 @@
|
|||
<template id="jobs">
|
||||
<v-card >
|
||||
<v-toolbar light>
|
||||
<v-btn
|
||||
light icon
|
||||
:loading="loading"
|
||||
@click="getJobs()"
|
||||
:disabled="loading"
|
||||
>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
<v-btn
|
||||
@click="stop()"
|
||||
:disabled="noSelection"
|
||||
>Stop</v-btn>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<v-text-field
|
||||
<v-text-field
|
||||
append-icon="search"
|
||||
label="Filter jobs"
|
||||
single-line
|
||||
hide-details
|
||||
v-model="search"
|
||||
></v-text-field>
|
||||
|
||||
></v-text-field>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn
|
||||
light icon
|
||||
:loading="loading"
|
||||
@click="getJobs()"
|
||||
@dblclick="autorefresh = !autorefresh"
|
||||
:disabled="loading"
|
||||
>
|
||||
<v-icon>{{ autorefresh?'refresh':'arrow_downward' }}</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
|
@ -44,13 +45,13 @@
|
|||
></v-checkbox>
|
||||
</td>
|
||||
<td class="vtop"> <router-link :to="{name: 'jobShow', params: {job: props.item.id }}">{{props.item.id}}</router-link></td>
|
||||
<td class="vtop text-xs-right">{{ props.item.state }}</td>
|
||||
<td class="vtop "><div>{{ props.item.state }}</div>
|
||||
<div>{{ props.item.type }}</div> </td>
|
||||
<td class="vtop text-xs-right">{{ props.item.duration }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.type }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.writes }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.reads }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.user }}</td>
|
||||
<td class="vtop"><code>{{ props.item.text }}</code></td>
|
||||
<td class="vtop" ><code class="multiline-ellipsis">{{ props.item.text }}</code></td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card>
|
||||
|
@ -67,7 +68,6 @@
|
|||
},
|
||||
{ text: 'State', value: 'state' },
|
||||
{ text: 'Duration', value: 'duration' },
|
||||
{ text: 'Type', value: 'type' },
|
||||
{ text: 'WriteL', value: 'writes' },
|
||||
{ text: 'ReadL', value: 'reads' },
|
||||
{ text: 'User', value: 'user' },
|
||||
|
@ -75,9 +75,10 @@
|
|||
],
|
||||
items:[
|
||||
],
|
||||
selected:[],
|
||||
search:"",
|
||||
loading:false
|
||||
selected: [],
|
||||
search: "",
|
||||
loading: false,
|
||||
autorefresh: true
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
@ -87,7 +88,7 @@
|
|||
.then(r=>{
|
||||
this.loading=false
|
||||
this.items=r.data
|
||||
setTimeout(()=>{ this.getJobs() }, 10000);
|
||||
if(this.autorefresh) setTimeout(()=>{ this.getJobs() }, 10000);
|
||||
})
|
||||
|
||||
},
|
||||
|
@ -102,7 +103,7 @@
|
|||
noSelection: function () {
|
||||
// `this` points to the vm instance
|
||||
return this.selected.length==0
|
||||
}
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.getJobs()
|
||||
|
|
|
@ -25,7 +25,7 @@ declare variable $vue:DEST:="static/app-gen.js";
|
|||
declare function vue:feature($doc,$isComp as xs:boolean)
|
||||
as xs:string
|
||||
{
|
||||
let $p:=vue:parse($doc)
|
||||
let $p:=vue:parse($doc=>trace("feature: "))
|
||||
let $script:= $p?script=>substring-after("{")
|
||||
|
||||
return if(empty($p?id)) then
|
||||
|
@ -64,6 +64,20 @@ declare function vue:capitalize-first
|
|||
concat(upper-case(substring($arg,1,1)), substring($arg,2))
|
||||
};
|
||||
|
||||
declare function vue:feature-files($proj)
|
||||
as xs:string*
|
||||
{
|
||||
let $FEATURES:="features/"=>file:resolve-path($proj=>trace("proj:"))
|
||||
return fw:directory-list($FEATURES,map{"include-filter":".*\.vue"})
|
||||
//c:file/@name/resolve-uri(.,base-uri(.))
|
||||
};
|
||||
|
||||
declare function vue:feature-build($url as xs:string,$isComp as xs:boolean)
|
||||
as xs:string
|
||||
{
|
||||
fetch:text($url)=>html5:doc()=>vue:feature($isComp)
|
||||
};
|
||||
|
||||
(:~
|
||||
: compile vue code to "static/app-gen.js"
|
||||
: @param $proj root folder e.g "C:/Users/andy/git/vue-poc/src/vue-poc/"
|
||||
|
@ -76,13 +90,12 @@ let $CORE:="components/core.js"=>file:resolve-path($proj)
|
|||
let $FILTERS:="components/filters.js"=>file:resolve-path($proj)
|
||||
let $DEST:="static/app-gen.js"=>file:resolve-path($proj)
|
||||
|
||||
let $files:= fw:directory-list($FEATURES,map{"include-filter":".*\.vue"})
|
||||
//c:file/@name/resolve-uri(.,base-uri(.))
|
||||
let $feats:=$files!(fetch:text(.)=>html5:doc()=>vue:feature(false()))
|
||||
let $files:=vue:feature-files($proj)
|
||||
let $feats:=$files!vue:feature-build(.,false())
|
||||
|
||||
let $files:= fw:directory-list($COMPONENTS,map{"include-filter":".*\.vue"})
|
||||
//c:file/@name/resolve-uri(.,base-uri(.))
|
||||
let $comps:=$files!(fetch:text(.)=>html5:doc()=>vue:feature(true()))
|
||||
let $comps:=$files!vue:feature-build(.,true())
|
||||
|
||||
let $comment:="// generated " || current-dateTime() || "

"
|
||||
return file:write-text($DEST,string-join(($comment,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(: entity access maps
|
||||
: auto generated from xml files in entities folder at: 2017-08-13T22:21:05.468+01:00
|
||||
: auto generated from xml files in entities folder at: 2017-08-23T10:12:22.413+01:00
|
||||
:)
|
||||
|
||||
module namespace entity = 'quodatum.models.generated';
|
||||
|
@ -130,7 +130,7 @@ declare variable $entity:list:=map {
|
|||
} },
|
||||
|
||||
"data": function() as element(image)*
|
||||
{ collection("/vue-poc/Pictures")/image },
|
||||
{ collection("/vue-poc/image")/image },
|
||||
|
||||
"views": map{
|
||||
'filter': 'name'
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
<view name="filter">name</view>
|
||||
</views>
|
||||
<iconclass>fa fa-file</iconclass>
|
||||
<data type="element(image)">collection("/vue-poc/Pictures")/image</data>
|
||||
<data type="element(image)">collection("/vue-poc/image")/image</data>
|
||||
|
||||
</entity>
|
|
@ -1,4 +1,4 @@
|
|||
// generated 2017-08-21T11:24:21.865+01:00
|
||||
// generated 2017-08-24T18:16:31.442+01:00
|
||||
Vue.component('qd-link',{template:`
|
||||
<a :href="href" :target="href"> {{href}}<v-icon>link</v-icon></a>
|
||||
`,
|
||||
|
@ -263,8 +263,8 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
</v-btn>
|
||||
<v-toolbar-title>
|
||||
<v-breadcrumbs>
|
||||
<v-breadcrumbs-item v-for="item in crumbs" :key="item" :to="{ query: { url: '/' + item + '/' }}">
|
||||
{{ item }}
|
||||
<v-breadcrumbs-item v-for="item in crumbs" :key="item.path" :to="{ query: { url: item.path }}">
|
||||
{{ item.name }}
|
||||
</v-breadcrumbs-item>
|
||||
</v-breadcrumbs>
|
||||
</v-toolbar-title>
|
||||
|
@ -400,7 +400,10 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
return (this.protocol=="basexdb")?"developer_mode":"folder"
|
||||
},
|
||||
crumbs(){
|
||||
return this.url.split("/").filter((a)=>a.length>0)
|
||||
var parts=this.url.split("/").filter((a)=>a.length>0)
|
||||
var a=parts.map(function(v,i,a){return {name:v,
|
||||
path:"/"+a.slice(0,i+1).join("/")+"/"}})
|
||||
return a
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
|
@ -746,17 +749,15 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
<v-btn @click="imports()">
|
||||
<v-icon>play_circle_outline</v-icon>
|
||||
Imports</v-btn>
|
||||
<v-menu :nudge-width="100">
|
||||
<v-toolbar-title slot="activator">
|
||||
<span>{{font}}</span>
|
||||
<v-icon>arrow_drop_down</v-icon>
|
||||
</v-toolbar-title>
|
||||
<v-list>
|
||||
<v-list-tile v-for="item in dropdown_font" :key="item.text">
|
||||
<v-list-tile-title v-text="item.text" @click="font=item.text"></v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-menu offset-y="">
|
||||
<v-btn icon="" primary="" dark="" slot="activator"> <v-icon>more_vert</v-icon></v-btn>
|
||||
<v-list>
|
||||
<v-list-tile @click="plan">Show query plan</v-list-tile>
|
||||
</v-list>
|
||||
<v-list>
|
||||
<v-list-tile @click="hitme">hit me</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-toolbar>
|
||||
|
||||
|
||||
|
@ -769,25 +770,27 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
{{result}}
|
||||
</v-alert>
|
||||
<v-card-actions v-if="show">
|
||||
|
||||
JobId:
|
||||
<v-chip class="green white--text">{{jobId}}</v-chip>
|
||||
<v-progress-circular v-if="waiting" indeterminate="" class="primary--text"></v-progress-circular>
|
||||
|
||||
|
||||
<v-chip class="primary white--text">{{jobId}}</v-chip>
|
||||
|
||||
<v-chip label="" class="grey white--text">
|
||||
<v-avatar class="red"> <v-icon>lock</v-icon>W</v-avatar>
|
||||
{{ jobState.writes }}</v-chip>
|
||||
<v-chip label="" class="grey white--text">
|
||||
<v-avatar class="amber"> <v-icon>lock</v-icon>R</v-avatar>
|
||||
{{ jobState.reads }}</v-chip>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<v-chip class="green white--text">
|
||||
<v-progress-circular v-if="waiting" indeterminate="" class="primary--text"></v-progress-circular>
|
||||
<v-chip>{{ jobState.state }}</v-chip>
|
||||
<v-chip class="primary white--text">
|
||||
<v-avatar> <v-icon>timer</v-icon></v-avatar>
|
||||
{{elapsed}}ms</v-chip>
|
||||
|
||||
</v-card-actions>
|
||||
<v-card-text v-if="show">
|
||||
<v-card-text v-if="showResult">
|
||||
<v-flex xs12="" style="height:200px" fill-height="">
|
||||
<vue-ace :content="result" mode="text" wrap="true" read-only="true"></vue-ace>
|
||||
<vue-ace :content="result" mode="text" wrap="false" read-only="true"></vue-ace>
|
||||
</v-flex>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
@ -801,18 +804,12 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
result:'',
|
||||
elapsed: null,
|
||||
show: false,
|
||||
showError: false,
|
||||
showError: false, //unused
|
||||
showResult: false, //
|
||||
jobId: null,
|
||||
waiting: false,
|
||||
start: null,
|
||||
jobState: {},
|
||||
font: 'Courier',
|
||||
dropdown_font: [
|
||||
{ text: 'Test select' },
|
||||
{ text: 'Calibri' },
|
||||
{ text: 'Courier' },
|
||||
{ text: 'Verdana' }
|
||||
]
|
||||
jobState: {}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
@ -823,14 +820,13 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
},
|
||||
|
||||
run(){
|
||||
this.showError=this.show=false
|
||||
this.awaitResult(false)
|
||||
this.start = performance.now();
|
||||
HTTP.post("eval/execute",Qs.stringify({xq:this.xq}))
|
||||
.then(r=>{
|
||||
this.elapsed=Math.floor(performance.now() - this.start);
|
||||
this.result=r.data.result
|
||||
this.jobId=null
|
||||
this.show=true
|
||||
})
|
||||
.catch(r=> {
|
||||
console.log("error",r)
|
||||
|
@ -842,12 +838,12 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
},
|
||||
submit(){
|
||||
var data={xq:this.xq}
|
||||
this.showError=this.show=false
|
||||
this.showResult=this.show=false
|
||||
this.start = performance.now();
|
||||
HTTP.post("eval/submit",Qs.stringify(data))
|
||||
.then(r=>{
|
||||
this.elapsed=Math.floor(performance.now() - this.start);
|
||||
this.result=this.jobId=r.data.job
|
||||
this.jobId=r.data.job
|
||||
this.show=true
|
||||
this.pollState()
|
||||
|
||||
|
@ -874,15 +870,38 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
})
|
||||
},
|
||||
getResult(){
|
||||
this.awaitResult(true)
|
||||
HTTP.post("eval/result/"+this.jobId)
|
||||
.then(r=>{
|
||||
this.result=r.data.result
|
||||
this.jobId=null
|
||||
this.show=true
|
||||
})
|
||||
},
|
||||
hitme(){
|
||||
this.showResult=true
|
||||
setTimeout(()=>{this.result="123\n".repeat(20000); },10);
|
||||
|
||||
},
|
||||
imports(){
|
||||
alert("@TODO imports")
|
||||
},
|
||||
plan(){
|
||||
this.awaitResult(false)
|
||||
HTTP.post("eval/plan",Qs.stringify({xq:this.xq}))
|
||||
.then(r=>{
|
||||
this.result=r.data.result
|
||||
})
|
||||
.catch(r=> {
|
||||
console.log("error",r)
|
||||
this.result=r.response.data
|
||||
this.showError=true;
|
||||
|
||||
});
|
||||
},
|
||||
awaitResult(show){
|
||||
// ace slow when setting large text while hidden
|
||||
this.show=show
|
||||
this.result="(Please wait..)"
|
||||
this.showResult=true
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -961,6 +980,7 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
<v-layout>
|
||||
<v-flex xs5="">
|
||||
<pre style="overflow:auto;">{{ image.doc }}</pre>
|
||||
<a :href="meta" target="_new">full metadata</a>
|
||||
</v-flex>
|
||||
|
||||
<v-flex xs7="">
|
||||
|
@ -980,7 +1000,10 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
computed: {
|
||||
path(){
|
||||
return this.loaded?'/vue-poc/api/images/list/'+ this.id+ '/image':null
|
||||
}
|
||||
},
|
||||
meta(){
|
||||
return this.loaded?'/vue-poc/api/images/list/'+ this.id+ '/meta':null
|
||||
}
|
||||
},
|
||||
created:function(){
|
||||
var id=this._props.id
|
||||
|
@ -1003,9 +1026,10 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
<v-btn @click="clear" icon="" v-tooltip:top="{ html: 'Clear search' }" v-if="query.keyword || query.from || query.until">
|
||||
<v-icon>clear</v-icon>
|
||||
</v-btn>
|
||||
<v-chip class="primary white--text">{{ total }}</v-chip>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<span v-if="!busy">
|
||||
<v-chip class="primary white--text">{{ total }} in {{ elapsed | round(2) }} secs </v-chip>
|
||||
|
||||
Page:{{ query.page+1 }}
|
||||
<v-btn @click.stop="query.page=Math.min(0,query.page-1)" :disabled="query.page==0" icon="" primary="">
|
||||
|
@ -1014,6 +1038,7 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
<v-btn @click.stop="query.page+=1" icon="" primary="">
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-btn>
|
||||
</span>
|
||||
</v-toolbar>
|
||||
<v-progress-linear v-if="busy" v-bind:indeterminate="true"></v-progress-linear>
|
||||
<v-container v-if="!busy" fluid="" grid-list-md="">
|
||||
|
@ -1111,6 +1136,7 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
keyword:null
|
||||
},
|
||||
total:null,
|
||||
elapsed:null,
|
||||
showFilter:false,
|
||||
busy:false,
|
||||
menu2:false,
|
||||
|
@ -1132,7 +1158,7 @@ v0.0.3 </v-card-title> </v-card> </v-flex> <v-flex xs4="">
|
|||
this.total=r.data.total
|
||||
this.images=r.data.items
|
||||
var t1 = performance.now();
|
||||
console.log("Time: ",t1 - t0)
|
||||
this.elapsed= 0.001 *(t1 - t0)
|
||||
})
|
||||
},
|
||||
clear(){
|
||||
|
@ -1300,15 +1326,15 @@ body
|
|||
const Jobs=Vue.extend({template:`
|
||||
<v-card>
|
||||
<v-toolbar light="">
|
||||
<v-btn light="" icon="" :loading="loading" @click="getJobs()" :disabled="loading">
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
<v-btn @click="stop()" :disabled="noSelection">Stop</v-btn>
|
||||
|
||||
<v-text-field append-icon="search" label="Filter jobs" single-line="" hide-details="" v-model="search"></v-text-field>
|
||||
<v-spacer></v-spacer>
|
||||
<v-text-field append-icon="search" label="Filter jobs" single-line="" hide-details="" v-model="search"></v-text-field>
|
||||
|
||||
|
||||
<v-btn light="" icon="" :loading="loading" @click="getJobs()" @dblclick="autorefresh = !autorefresh" :disabled="loading">
|
||||
<v-icon>{{ autorefresh?'refresh':'arrow_downward' }}</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-data-table :headers="headers" :items="items" :search="search" v-model="selected" select-all="" class="elevation-1" no-data-text="No Jobs currently running">
|
||||
<template slot="items" scope="props">
|
||||
|
@ -1316,13 +1342,13 @@ body
|
|||
<v-checkbox primary="" hide-details="" v-model="props.selected"></v-checkbox>
|
||||
</td>
|
||||
<td class="vtop"> <router-link :to="{name: 'jobShow', params: {job: props.item.id }}">{{props.item.id}}</router-link></td>
|
||||
<td class="vtop text-xs-right">{{ props.item.state }}</td>
|
||||
<td class="vtop "><div>{{ props.item.state }}</div>
|
||||
<div>{{ props.item.type }}</div> </td>
|
||||
<td class="vtop text-xs-right">{{ props.item.duration }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.type }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.writes }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.reads }}</td>
|
||||
<td class="vtop text-xs-right">{{ props.item.user }}</td>
|
||||
<td class="vtop"><code>{{ props.item.text }}</code></td>
|
||||
<td class="vtop"><code class="multiline-ellipsis">{{ props.item.text }}</code></td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card>
|
||||
|
@ -1338,7 +1364,6 @@ body
|
|||
},
|
||||
{ text: 'State', value: 'state' },
|
||||
{ text: 'Duration', value: 'duration' },
|
||||
{ text: 'Type', value: 'type' },
|
||||
{ text: 'WriteL', value: 'writes' },
|
||||
{ text: 'ReadL', value: 'reads' },
|
||||
{ text: 'User', value: 'user' },
|
||||
|
@ -1346,9 +1371,10 @@ body
|
|||
],
|
||||
items:[
|
||||
],
|
||||
selected:[],
|
||||
search:"",
|
||||
loading:false
|
||||
selected: [],
|
||||
search: "",
|
||||
loading: false,
|
||||
autorefresh: true
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
@ -1358,7 +1384,7 @@ body
|
|||
.then(r=>{
|
||||
this.loading=false
|
||||
this.items=r.data
|
||||
setTimeout(()=>{ this.getJobs() }, 10000);
|
||||
if(this.autorefresh) setTimeout(()=>{ this.getJobs() }, 10000);
|
||||
})
|
||||
|
||||
},
|
||||
|
@ -1373,7 +1399,7 @@ body
|
|||
noSelection: function () {
|
||||
// `this` points to the vm instance
|
||||
return this.selected.length==0
|
||||
}
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.getJobs()
|
||||
|
@ -2362,6 +2388,22 @@ Vue.config.errorHandler = function (err, vm, info) {
|
|||
alert("vue error");
|
||||
};
|
||||
|
||||
//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);
|
||||
};
|
||||
};
|
||||
|
||||
// used by vue-ace
|
||||
var Events = new Vue({});
|
||||
|
|
|
@ -54,4 +54,14 @@ td.vtop {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.multiline-ellipsis {
|
||||
display: block;
|
||||
display: -webkit-box;
|
||||
max-height: 110px;
|
||||
margin: 0 auto;
|
||||
line-height: 1.4;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
declare namespace task="https://github.com/Quodatum/app-doc/task";
|
||||
import module namespace bf = 'quodatum.tools.buildfields' at "../lib/entity-gen.xqm";
|
||||
|
||||
let $efolder:="file:///C:/Users/andy/workspace/app-doc/src/doc/data/doc/models"
|
||||
let $target:="file:///C:/Users/andy/workspace/app-doc/src/doc/generated/models.xqm"
|
||||
return (bf:write($efolder,$target),db:output("generated C:/Users/andy/workspace/app-doc/src/doc/generated/models.xqm"))
|
||||
let $efolder:="C:/Users/andy/git/vue-poc/src/vue-poc/models"
|
||||
let $target:="C:/Users/andy/git/vue-poc/src/vue-poc/models.gen.xqm"
|
||||
return (bf:write($efolder,$target),db:output("generated " || $target))
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
(:~
|
||||
: create vue files from app.html
|
||||
:)
|
||||
import module namespace html5="text.html5" at "html5parse.xqm";
|
||||
declare namespace Document="java:ch.digitalfondue.jfiveparse.Document";
|
||||
declare namespace Element="java:ch.digitalfondue.jfiveparse.Element";
|
||||
declare namespace Node="java:ch.digitalfondue.jfiveparse.Node";
|
||||
|
||||
declare variable $DEST:="C:/Users/andy/git/vue-poc/src/vue-poc/templates/";
|
||||
declare variable $SRC:="C:/Users/andy/git/vue-poc/src/vue-poc/static/app.html";
|
||||
|
||||
|
||||
declare function local:process($node)
|
||||
{
|
||||
let $id:= Element:getAttribute($node,"id")
|
||||
let $html:=Node:getInnerHTML($node)
|
||||
let $name:=$DEST || $id || ".vue"
|
||||
let $out:=``[<!DOCTYPE html>
|
||||
<template id="`{$id}`">`{$html}`</template>
|
||||
<script>
|
||||
</script>
|
||||
]``
|
||||
return file:write-text($name,$out)
|
||||
|
||||
};
|
||||
|
||||
let $doc:=$SRC=>fetch:text()=>html5:doc()
|
||||
let $matcher:=html5:selector()
|
||||
let $nodes:= Document:getAllNodesMatching($doc,$matcher)
|
||||
return $nodes=>html5:for-each(local:process#1)
|
Loading…
Add table
Reference in a new issue