qd-table
This commit is contained in:
parent
5d6aa4e12b
commit
a20b64c6bd
48 changed files with 1418 additions and 1263 deletions
11
README.md
11
README.md
|
|
@ -8,7 +8,9 @@ Includes:
|
|||
* localforage for persistence
|
||||
|
||||
## Icons
|
||||
* https://material.io/resources/icons/?style=baseline
|
||||
* https://vuetifyjs.com/en/customization/icons/
|
||||
|
||||
## Tests
|
||||
|
||||
### Cypress
|
||||
|
|
@ -23,7 +25,14 @@ or...
|
|||
npx cypress run
|
||||
```
|
||||
## Settings
|
||||
|
||||
Required BaseX options https://docs.basex.org/wiki/Options
|
||||
```
|
||||
CHOP = false
|
||||
LOGTRACE = false
|
||||
RESTXQERRORS = false
|
||||
GZIP = true
|
||||
```
|
||||
### Other
|
||||
Global `settings` provides `getItem(name)` and `setItem(name.value)`
|
||||
Example usage
|
||||
```
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
model: false,
|
||||
children: [
|
||||
{href: '/tasks',text: 'Task list',icon: 'assignment'},
|
||||
{href: '/history/tasks',text: 'History',icon: 'history'}
|
||||
{href: '/history/tasks',text: 'Run history',icon: 'history'}
|
||||
]},
|
||||
{
|
||||
icon: 'folder_open',
|
||||
|
|
|
|||
108
src/vue-poc/components/qd-perfstats.vue
Normal file
108
src/vue-poc/components/qd-perfstats.vue
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
perfstats
|
||||
https://adamwathan.me/renderless-components-in-vuejs/
|
||||
-->
|
||||
<template id="qd-perfstats">
|
||||
<div>
|
||||
<slot name="actions" :add="add" :repeats="repeats" :reset="reset" :clip="clip"></slot>
|
||||
<hr/>
|
||||
<slot name="table" :items="items" :headers="headers" :run="run"></slot>
|
||||
<slot name="response" :data="response" ></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>{
|
||||
props: {
|
||||
initial: {default: function(){ return []}
|
||||
}
|
||||
},
|
||||
data: function(){
|
||||
return {
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: 'Action', value: 'id'},
|
||||
{ text: 'Repeat', value: 'repeat' },
|
||||
{ text: 'Count', value: 'count', align: 'right' },
|
||||
{ text: 'Max', value: 'max' , align: 'right' },
|
||||
{ text: 'Min', value: 'min' , align: 'right'},
|
||||
{ text: 'Median', value: 'median', align: 'right' },
|
||||
{ text: 'Last', value: 'last' , align: 'right'},
|
||||
{ text: 'Average', value: 'avg' , align: 'right'}
|
||||
],
|
||||
response: null
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
add(id,method,url){
|
||||
var obj={index:this.items.length, id: id, method:method, url:url, repeat: false,
|
||||
count: 0, max: null, min: null, total:0, median:null, last:null, avg:null}
|
||||
this.items.push(obj)
|
||||
},
|
||||
run(index){
|
||||
this.update(this.items[index])
|
||||
},
|
||||
|
||||
clear(index){
|
||||
var data=this.items[index]
|
||||
data.count= data.total= 0
|
||||
data.max= data.min= data.last= data.avg= data.median= null
|
||||
},
|
||||
|
||||
update (item) {
|
||||
var _start = performance.now();
|
||||
HTTP.request(item.url, {method: item.method, headers: {accept: 'application/json'}})
|
||||
.then(r=>{
|
||||
var elapsed=Math.floor(performance.now() - _start);
|
||||
this.response=r.data
|
||||
this.log(item,elapsed)
|
||||
if(item.repeat) this.update(item);
|
||||
})
|
||||
},
|
||||
// update item stats
|
||||
log(item,val){
|
||||
item.last= val
|
||||
item.total+= val;
|
||||
item.count+= 1;
|
||||
if(item.count==1){
|
||||
item.max=val;
|
||||
item.min=val;
|
||||
item.median=val;
|
||||
}else{
|
||||
if(val<item.min)item.min=val;
|
||||
if(val>item.max)item.max=val;
|
||||
};
|
||||
//https://jeremykun.com/2012/06/14/streaming-median/
|
||||
if (item.median > val)
|
||||
item.median-= 1
|
||||
else if( item.median < val)
|
||||
item.median += 1;
|
||||
item.avg=(item.total / item.count).toFixed(2);
|
||||
},
|
||||
|
||||
repeats(b){
|
||||
this.$nextTick(() => {
|
||||
this.items.forEach(item=>item.repeat=b)
|
||||
})
|
||||
},
|
||||
|
||||
reset(){
|
||||
this.items.forEach(item=>this.clear(item.index))
|
||||
},
|
||||
|
||||
clip(){
|
||||
var txt=this.items.map(item=>item.id + ',' + item.avg).join("\n")
|
||||
navigator.clipboard.writeText(txt).then(function() {
|
||||
/* clipboard successfully set */
|
||||
}, function() {
|
||||
alert("clipboard write failed")
|
||||
});
|
||||
}
|
||||
},
|
||||
created:function(){
|
||||
console.log("qd-perfstats:",this.initial);
|
||||
this.initial.forEach(item=>this.add(item.id,item.method,item.url))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -30,12 +30,20 @@
|
|||
</v-btn>
|
||||
</template>
|
||||
<v-card >
|
||||
<v-toolbar color="cyan lighten-2">
|
||||
<v-card-title >Actions</v-card-title>
|
||||
</v-toolbar>
|
||||
<v-app-bar dense color="cyan lighten-2" >
|
||||
<v-card-title dense>Actions</v-card-title>
|
||||
</v-app-bar>
|
||||
|
||||
<v-card-text>
|
||||
<v-list dense>
|
||||
<slot name="actions"></slot>
|
||||
<v-list-item @click="copy">
|
||||
<v-list-item-avatar><v-icon>content_copy</v-icon></v-list-item-avatar>
|
||||
<v-list-item-title>Copy selection</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
|
|
@ -89,6 +97,7 @@
|
|||
class="elevation-1"
|
||||
:fixed-header="true"
|
||||
:no-data-text="noDataMsg"
|
||||
|
||||
>
|
||||
<template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope"><slot :name="slot" v-bind="scope"/></template>
|
||||
|
||||
|
|
@ -100,15 +109,22 @@
|
|||
<script>{
|
||||
props: {
|
||||
headers: {default: [ { text: 'Name', value: 'id'} ]},
|
||||
dataUri:{ default: "data/dice.entity"},
|
||||
dataUri:{ default: null},
|
||||
itemKey:{ default: "id"},
|
||||
noDataMsg:{ default: "No data found."},
|
||||
title:{ default: "" },
|
||||
entity:{ },
|
||||
query: {default: function(){return {filter:null}}},
|
||||
showSelect: { default: false },
|
||||
multiSort: { default: false }
|
||||
multiSort: { default: false },
|
||||
customFilter: {default: function(value, search, item) {
|
||||
return value != null &&
|
||||
search != null &&
|
||||
typeof value === 'string' &&
|
||||
value.toString().indexOf(search) !== -1}
|
||||
}
|
||||
},
|
||||
|
||||
data: function(){
|
||||
return {
|
||||
selected: [],
|
||||
|
|
@ -119,8 +135,10 @@
|
|||
autoRefreshL: false
|
||||
}
|
||||
},
|
||||
|
||||
methods:{
|
||||
getItems(){
|
||||
if(this.dataUri === null) return;
|
||||
this.loading=true;
|
||||
HTTP.get(this.dataUri)
|
||||
.then(r=>{
|
||||
|
|
@ -129,6 +147,20 @@
|
|||
this.items=r.data.items;
|
||||
if(this.autoRefreshL) this.timer=setTimeout(()=>{ this.getItems() }, 10000);
|
||||
})
|
||||
},
|
||||
|
||||
copy(){
|
||||
var flds=this.headers.map(h=>h.value)
|
||||
var row=function(item){return flds.map(f=>item.hasOwnProperty(f)?item[f]:'').join(",")}
|
||||
var txt=flds.join(",")
|
||||
var txt=this.selected.map(item=>row(item)).join("\n")
|
||||
txt= txt=flds.join(",") +"\n" + txt
|
||||
navigator.clipboard.writeText(txt).then(function() {
|
||||
/* clipboard successfully set */
|
||||
}, function() {
|
||||
alert("clipboard write failed")
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
-->
|
||||
<template id="vp-notifications">
|
||||
<v-card>
|
||||
<v-app-bar class="amber white--text" >
|
||||
<v-toolbar-title >Notifications </v-toolbar-title>
|
||||
{{ $notification.nextId }}
|
||||
<v-app-bar dense class="amber white--text" >
|
||||
<v-toolbar-title > {{ $notification.nextId }} Notifications </v-toolbar-title>
|
||||
<v-btn @click="refresh" icon><v-icon>refresh</v-icon></v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="set(false)" icon><v-icon>close</v-icon></v-btn>
|
||||
</v-app-bar>
|
||||
|
||||
<v-card-text>
|
||||
<v-list three-line>
|
||||
<template v-for="msg in $notification.messages" >
|
||||
|
|
|
|||
|
|
@ -8,9 +8,12 @@
|
|||
<v-toolbar color="blue lighten-3" dense>
|
||||
<v-card-title >{{ description }}</v-card-title>
|
||||
<v-spacer></v-spacer>
|
||||
<router-link :to="{name:'edit', query:{url: url}}">
|
||||
<v-icon :title="url">history</v-icon>{{ name }}
|
||||
</router-link>
|
||||
<v-btn @click="clear()" id="btn-clear"
|
||||
>Clear</v-btn>
|
||||
<v-btn @click="reset()"
|
||||
>Reset</v-btn>
|
||||
<v-btn @click="zlog()"
|
||||
>console</v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-form ref="form" lazy-validation>
|
||||
|
|
@ -43,15 +46,7 @@
|
|||
</v-form>
|
||||
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn @click="clear()" id="btn-clear"
|
||||
>Clear</v-btn>
|
||||
<v-btn @click="reset()"
|
||||
>Reset</v-btn>
|
||||
</v-card-actions>
|
||||
<v-btn @click="zlog()"
|
||||
>console</v-btn>
|
||||
</v-card-actions>
|
||||
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,20 @@ axios.interceptors.response.use(function (response) {
|
|||
|
||||
// errors displayed by interceptor
|
||||
const HTTP = axios.create(AXIOS_CONFIG);
|
||||
HTTP.interceptors.request.use((config) => {
|
||||
HTTP.interceptors.request.use(
|
||||
(config) => {
|
||||
config.qdStartTime=performance.now();
|
||||
return config;
|
||||
});
|
||||
return config;}
|
||||
);
|
||||
|
||||
HTTP.interceptors.response.use((response) => {
|
||||
HTTP.interceptors.response.use(
|
||||
(response) => {
|
||||
// Do something with response data
|
||||
if( response && response.config && response.config.qdStartTime){
|
||||
var s=Math.floor(performance.now() - response.config.qdStartTime);
|
||||
response.headers["X-response-ms"]= s // custom header
|
||||
//console.log("AXIOS H:",response.headers)
|
||||
|
||||
var c=response.config;
|
||||
var url=response.config.url + "?" + c.paramsSerializer(c.params);
|
||||
//console.log("interceptors time:",s, response.config);
|
||||
|
|
@ -40,7 +45,8 @@ HTTP.interceptors.response.use((response) => {
|
|||
Notification.add({html: b, elapsed: s});
|
||||
}
|
||||
return response;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// errors hidden
|
||||
|
|
|
|||
24
src/vue-poc/data/vue-poc/entities/basex/database.xml
Normal file
24
src/vue-poc/data/vue-poc/entities/basex/database.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<entity name="basex.database" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||
<description>BaseX databases</description>
|
||||
|
||||
<fields>
|
||||
<field name="name" type="xs:string">
|
||||
<description>database name</description>
|
||||
<xpath>.</xpath>
|
||||
</field>
|
||||
<field name="documents" type="xs:integer">
|
||||
<description>number of documents in database</description>
|
||||
<xpath>db:property(.,'documents')</xpath>
|
||||
</field>
|
||||
<field name="binaries" type="xs:integer">
|
||||
<description>non xml documents</description>
|
||||
<xpath>db:property(.,'binaries')</xpath>
|
||||
</field>
|
||||
<field name="timestamp" type="xs:string">
|
||||
<description>last update</description>
|
||||
<xpath>db:property(.,'timestamp')</xpath>
|
||||
</field>
|
||||
</fields>
|
||||
<views iconclass="library_books"/>
|
||||
<data type="xs:string">db:list()</data>
|
||||
</entity>
|
||||
3
src/vue-poc/data/vue-poc/entities/basex/readme.md
Normal file
3
src/vue-poc/data/vue-poc/entities/basex/readme.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# BaseX entities
|
||||
|
||||
Objects mapping BaseX features
|
||||
3
src/vue-poc/data/vue-poc/entities/dice/readme.md
Normal file
3
src/vue-poc/data/vue-poc/entities/dice/readme.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Dice entities
|
||||
|
||||
The entities
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<entity name="filehistory" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||
<entity name="history.file" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||
<description>vue-poc file view events </description>
|
||||
<namespace prefix="h" uri="urn:quodatum:vue-poc.history" />
|
||||
<fields>
|
||||
3
src/vue-poc/data/vue-poc/entities/history/readme.md
Normal file
3
src/vue-poc/data/vue-poc/entities/history/readme.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# History entities
|
||||
|
||||
Logs for web application
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<entity name="taskhistory" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||
<entity name="history.task" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||
<description>vue-poc task view events </description>
|
||||
<namespace prefix="h" uri="urn:quodatum:vue-poc.history" />
|
||||
<fields>
|
||||
|
|
@ -14,16 +14,24 @@
|
|||
<description>id</description>
|
||||
<xpath>@id</xpath>
|
||||
</field>
|
||||
<field name="protocol" type="xs:string">
|
||||
<description>mode eg file basexdb</description>
|
||||
<xpath>h:file/@mode</xpath>
|
||||
<field name="task" type="xs:string">
|
||||
<description>name of task</description>
|
||||
<xpath>h:task/@task</xpath>
|
||||
</field>
|
||||
|
||||
<field name="url" type="xs:string">
|
||||
<description>path</description>
|
||||
<xpath>h:file/@url</xpath>
|
||||
<xpath>h:task/@url</xpath>
|
||||
</field>
|
||||
<field name="arity" type="xs:integer">
|
||||
<description>number of parameters</description>
|
||||
<xpath>count(h:task/*:param)</xpath>
|
||||
</field>
|
||||
<field name="summary" type="xs:string">
|
||||
<description>Parameter summary</description>
|
||||
<xpath>string-join(h:task/h:param/concat(string(@name),'=',string(.)),'; ')</xpath>
|
||||
</field>
|
||||
</fields>
|
||||
<views iconclass="calendar_today"/>
|
||||
<data type="element(h:event)">doc("vue-poc/history.xml")/h:history/h:event[task]</data>
|
||||
<data type="element(h:event)">doc("vue-poc/history.xml")/h:history/h:event[h:task]</data>
|
||||
</entity>
|
||||
3
src/vue-poc/data/vue-poc/entities/quodatum/readme.md
Normal file
3
src/vue-poc/data/vue-poc/entities/quodatum/readme.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Quodatum entities
|
||||
|
||||
Logs for web application
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
<entity name="quodatum.task" xmlns="https://github.com/Quodatum/app-doc/entity">
|
||||
<description>Predefined queries with parameters, listed in taskdef.xml </description>
|
||||
<namespace prefix="t" uri="https://github.com/Quodatum/task" />
|
||||
<fields>
|
||||
<field name="to" type="xs:string">
|
||||
<description>name for task</description>
|
||||
|
|
@ -11,13 +12,13 @@
|
|||
</field>
|
||||
<field name="title" type="xs:string">
|
||||
<description>title</description>
|
||||
<xpath>title</xpath>
|
||||
<xpath>t:title</xpath>
|
||||
</field>
|
||||
<field name="description" type="xs:string">
|
||||
<description>task description</description>
|
||||
<xpath>fn:serialize(description/node())</xpath>
|
||||
<xpath>fn:serialize(t:description/node())</xpath>
|
||||
</field>
|
||||
</fields>
|
||||
<views iconclass="update"/>
|
||||
<data type="element(task)">doc("tasks/taskdef.xml")/tasks/task</data>
|
||||
<data type="element(t:task)">doc("tasks/taskdef.xml")/t:tasks/t:task</data>
|
||||
</entity>
|
||||
|
|
@ -1,38 +1,21 @@
|
|||
<history next-id="13" xmlns="urn:quodatum:vue-poc.history">
|
||||
<event id="1" user="admin" when="">
|
||||
<file mode="webfile" url="/vue-poc/app.xqm" />
|
||||
</event>
|
||||
<event id="2">
|
||||
<file mode="webfile" url="/vue-poc/data/vue-poc/samples/ch4d1.xml" />
|
||||
</event>
|
||||
<event id="3">
|
||||
<file mode="webfile" url="/vue-poc/static/app-gen.js" />
|
||||
</event>
|
||||
<event id="4">
|
||||
<file mode="webfile" url="/vue-poc/static/app.html" />
|
||||
</event>
|
||||
<event id="5">
|
||||
<file mode="webfile" url="/vue-poc/static/app.css" />
|
||||
</event>
|
||||
<event id="6">
|
||||
<file mode="webfile" url="/vue-poc/logo.svg" />
|
||||
</event>
|
||||
<event id="7">
|
||||
<file mode="webfile" url="/vue-poc/static/resources/semantic/sparql.rq" />
|
||||
</event>
|
||||
<event id="8">
|
||||
<file mode="webfile" url="/vue-poc/static/resources/semantic/turtle.ttl" />
|
||||
</event>
|
||||
<event id="9">
|
||||
<file mode="webfile" url="/vue-poc/static/resources/task.xsd" />
|
||||
</event>
|
||||
<event id="10">
|
||||
<file mode="webfile" url="/vue-poc/static/resources/schematron/ark.sch" />
|
||||
</event>
|
||||
<event id="11">
|
||||
<file mode="basexdb" url="/abide/abide.xml" />
|
||||
</event>
|
||||
<event id="12">
|
||||
<collection mode="basexdb" url="/vue-poc" />
|
||||
</event>
|
||||
<history xmlns="urn:quodatum:vue-poc.history" next-id="6">
|
||||
<hist:event xmlns:hist="urn:quodatum:vue-poc.history" id="ev-5" when="2020-10-20T22:36:42.7+01:00" user="admin">
|
||||
<task task="log.enrich" url="file:///C:/Users/andy/basex.home/webapp/vue-poc/features/tasks/task/log.enrich.xq"/>
|
||||
</hist:event>
|
||||
<hist:event xmlns:hist="urn:quodatum:vue-poc.history" id="ev-4" when="2020-10-20T22:36:16.206+01:00" user="admin">
|
||||
<task task="model" url="file:///C:/Users/andy/basex.home/webapp/vue-poc/features/tasks/model.build/tx-model.xq">
|
||||
<param name="target">C:/Users/andy/git/vue-poc/src/vue-poc/models.gen.xqm</param>
|
||||
<param name="efolder">C:/Users/andy/git/vue-poc/src/vue-poc/data/vue-poc/entities</param>
|
||||
</task>
|
||||
</hist:event>
|
||||
<hist:event xmlns:hist="urn:quodatum:vue-poc.history" id="ev-3" when="2020-10-20T22:35:57.352+01:00" user="admin">
|
||||
<task task="primes" url="file:///C:/Users/andy/basex.home/webapp/vue-poc/tasks/primes.xq">
|
||||
<param name="MAX">2020</param>
|
||||
</task>
|
||||
</hist:event>
|
||||
<hist:event xmlns:hist="urn:quodatum:vue-poc.history" id="2" when="2020-10-14T21:50:53.073+01:00" user="admin">
|
||||
<task task="primes" url="file:///C:/Users/andy/basex.home/webapp/vue-poc/tasks/primes.xq">
|
||||
<param name="MAX">1000</param>
|
||||
</task>
|
||||
</hist:event>
|
||||
</history>
|
||||
38
src/vue-poc/data/vue-poc/tasks/taskdef.xml
Normal file
38
src/vue-poc/data/vue-poc/tasks/taskdef.xml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<tasks xmlns="https://github.com/Quodatum/task">
|
||||
<task name="model" url="model.build/tx-model.xq">
|
||||
<title>Generate model.gen.xqm</title>
|
||||
<description> Generate <code>model.gen.xqm</code> from files in entity folder
|
||||
</description>
|
||||
</task>
|
||||
<task name="import2" url="task/tx-dbimport2.xq">
|
||||
<title>Import files from drive into a database</title>
|
||||
<description>Load files into database</description>
|
||||
</task>
|
||||
|
||||
<task name="log.enrich" url="task/log.enrich.xq">
|
||||
<title>log enrich</title>
|
||||
<description>Enrich log files in collection /logs database vue-poc
|
||||
by adding @start and @end attributes where calculatable</description>
|
||||
</task>
|
||||
<task name="vuecompile">
|
||||
<title>vue compile</title>
|
||||
<description>compile</description>
|
||||
</task>
|
||||
|
||||
<task name="xqdoca" url="file:///C:/Users/andy/git/xqdoca/src/main/xqdoca.xq">
|
||||
<title>Create xqDoc</title>
|
||||
<description>xquery documentation</description>
|
||||
</task>
|
||||
|
||||
<task name="primes" url="../../tasks/primes.xq">
|
||||
<title>Calculate primes</title>
|
||||
<description>performance</description>
|
||||
</task>
|
||||
<task name="newapp" url="task/tx-newapp.xq">
|
||||
<title>application template</title>
|
||||
<description>application template</description>
|
||||
<params>
|
||||
<param name="appname">Name for new application</param>
|
||||
</params>
|
||||
</task>
|
||||
</tasks>
|
||||
|
|
@ -52,7 +52,8 @@
|
|||
|
||||
<v-list-item><a href="https://material.io/tools/icons/?style=baseline"
|
||||
target="new">icons (material)</a></v-list-item>
|
||||
|
||||
<v-list-item><a href="../api"
|
||||
target="new">wadl</a></v-list-item>
|
||||
</v-list>
|
||||
</v-flex>
|
||||
<v-flex xs6>
|
||||
|
|
|
|||
|
|
@ -275,10 +275,6 @@ v-on:annotation="annotation"></vue-ace>
|
|||
var r=type.mode
|
||||
this.mode=r?r:"text"
|
||||
},
|
||||
onResize(){
|
||||
var h=window.innerHeight
|
||||
console.log("height:",h)
|
||||
},
|
||||
leaving(event) {
|
||||
event.returnValue = "event seems to need to be set";
|
||||
//debugger;
|
||||
|
|
|
|||
|
|
@ -17,14 +17,13 @@ declare namespace c="http://www.w3.org/ns/xproc-step";
|
|||
:)
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/edit")
|
||||
%rest:query-param("url", "{$url}")
|
||||
%rest:query-param("url", "{ $url }")
|
||||
%rest:query-param("protocol", "{ $protocol }")
|
||||
%rest:produces("application/json")
|
||||
%output:method("json")
|
||||
function vue-api:edit-get($url as xs:string)
|
||||
function vue-api:edit-get($url as xs:string, $protocol as xs:string)
|
||||
{
|
||||
let $a:=analyze-string($url,"^\w*:")=>trace("PROTO")
|
||||
let $protocol:=$a/fn:match/string()
|
||||
let $protocol:=if ($protocol) then $protocol else "webfile"
|
||||
|
||||
let $reader := map{
|
||||
"webfile": vue-api:get-webfile#1,
|
||||
"xmldb": vue-api:get-basexdb#1
|
||||
|
|
|
|||
|
|
@ -32,9 +32,15 @@
|
|||
:search="q"
|
||||
class="elevation-1"
|
||||
>
|
||||
<template slot="items" slot-scope="props">
|
||||
<td >AA: <router-link :to="'tasks/' + props.item.to" v-text="props.item.title"></router-link></td>
|
||||
<td >{{ props.item.description }}</td>
|
||||
<template v-slot:item.id="{ item }" >
|
||||
<router-link :to="{path: '/tasks/' + item.task + '/run', query:{ id: item.id}}">
|
||||
{{ item.id }}
|
||||
</router-link>
|
||||
</template>
|
||||
<template v-slot:item.task="{ item }" >
|
||||
<router-link :to="{path: '/tasks/' + item.task + '/run', query:{ id: item.id}}">
|
||||
{{ item.task }}
|
||||
</router-link>
|
||||
</template>
|
||||
<template slot="no-data">
|
||||
<v-alert :value="true" icon="warning">
|
||||
|
|
@ -56,17 +62,20 @@
|
|||
loading: false,
|
||||
q: null,
|
||||
headers: [
|
||||
{ text: 'Task', value: 'title' },
|
||||
{ text: 'Description', value: 'description' },
|
||||
{ text: 'Id', value: 'id' },
|
||||
{ text: 'Task', value: 'task' },
|
||||
{ text: 'Created', value: 'created' },
|
||||
{ text: 'Summary', value: 'summary' },
|
||||
{ text: 'Params', value: 'arity' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getTasks(){
|
||||
this.loading= true;
|
||||
HTTP.get("tasks")
|
||||
HTTP.get("data/history.task")
|
||||
.then(r=>{
|
||||
this.items=r.data;
|
||||
this.items=r.data.items;
|
||||
this.loading= false;
|
||||
})
|
||||
}
|
||||
|
|
@ -19,7 +19,8 @@ declare
|
|||
%perm:check('/vue-poc')
|
||||
function vue-login:check-app() {
|
||||
let $user := session:get('id')
|
||||
let $_:=trace($user,"CHECK")
|
||||
let $m:=``[path: `{ request:path() }`, user: `{ $user }`.]``
|
||||
let $_:=trace($m,"CHECK: ")
|
||||
return ()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,15 +46,17 @@
|
|||
<v-expansion-panels v-model="panel" multiple>
|
||||
<v-expansion-panel expand >
|
||||
<v-expansion-panel-header>
|
||||
<v-layout>
|
||||
<v-flex xs12>
|
||||
<v-avatar><v-icon>{{ item.iconclass }}</v-icon></v-avatar>
|
||||
<span class="font-weight-black">{{ item.name }}</span>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<v-layout>
|
||||
<v-flex xs1>
|
||||
<v-avatar color="teal" size="62"><v-icon x-large>{{ item.iconclass }}</v-icon></v-avatar>
|
||||
</v-flex>
|
||||
<v-flex xs11>
|
||||
{{item.description}}
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<pre v-if="xml"><code>{{ xml }}</code></pre>
|
||||
</v-expansion-panel-content>
|
||||
<v-expansion-panel>
|
||||
|
|
@ -109,7 +111,7 @@
|
|||
{text: "description", value: "description"},
|
||||
{text: "xpath", value: "xpath"}
|
||||
],
|
||||
panel: [1,2]
|
||||
panel: [0,1,2]
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
<v-container fluid>
|
||||
<qd-table :headers="headers" data-uri="data/namespace" entity="namespace" item-key="xmlns">
|
||||
<template v-slot:item.xmlns="{ item }" >
|
||||
<td ><router-link :to="{name:'namespace1', query:{ id: item.xmlns}}">
|
||||
<router-link :to="{name:'namespace1', query:{ id: item.xmlns}}">
|
||||
{{ item.xmlns }}
|
||||
</router-link></td>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<template slot="no-results">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ xquery version "3.1";
|
|||
: @since oct 2019
|
||||
:)
|
||||
|
||||
module namespace _ = 'quodatum.model.namespaces';
|
||||
module namespace _ = 'urn:quodatum:model.namespaces';
|
||||
|
||||
|
||||
import module namespace entity ='quodatum.models.generated' at "../../models.gen.xqm";
|
||||
|
|
|
|||
|
|
@ -2,79 +2,59 @@
|
|||
<template id="dicetest">
|
||||
<v-container fluid>
|
||||
<v-card>
|
||||
|
||||
<v-toolbar >
|
||||
<v-toolbar-title>Dice entity list</v-toolbar-title>
|
||||
<v-toolbar-title>Read json data for 1st page for entity</v-toolbar-title>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="reset()">Reset</v-btn>
|
||||
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<p>Read json data for 1st page for entity.</p>
|
||||
<v-flex xs12 sm6>
|
||||
<v-combobox
|
||||
v-model="entity"
|
||||
:items="entities" item-text="name"
|
||||
label="Select target" clearable open-on-clear>
|
||||
<template v-slot:item="{ parent, item }">
|
||||
<v-icon>{{ item.iconclass }}</v-icon>
|
||||
{{ item.name }}
|
||||
<qd-perfstats>
|
||||
<v-app-bar slot="actions" slot-scope="{ add , repeats, reset, clip }">
|
||||
<v-select v-model="selectedEntities" :items="entities" item-text="name"
|
||||
return-object label="Entities to test"
|
||||
multiple chips>
|
||||
<template v-slot:prepend-item>
|
||||
<v-list-item ripple @click="toggle" class="green lighten">
|
||||
<v-list-item-action>
|
||||
<v-icon :color="selectedEntities.length > 0 ? 'indigo darken-4' : ''">{{ icon }}</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Select All</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-divider class="mt-2"></v-divider>
|
||||
</template>
|
||||
</v-combobox>
|
||||
</v-select>
|
||||
<div v-if="selectedEntities.length">
|
||||
<v-btn @click="setSel(add)">Set</v-btn>
|
||||
<v-btn @click="repeats(false)">Repeat off</v-btn>
|
||||
<v-btn @click="repeats(true)">Repeat on</v-btn>
|
||||
<v-btn @click="reset()">Reset</v-btn>
|
||||
<v-btn @click="clip()" icon title="copy to clipboard"><v-icon>content_copy</v-icon></v-btn>
|
||||
</div>
|
||||
</v-app-bar>
|
||||
|
||||
</v-flex>
|
||||
<v-simple-table>
|
||||
<template v-slot:default>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="col in columns " class="text-left">
|
||||
{{ col.label }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{{ entity && entity.name }}
|
||||
</td>
|
||||
<td>
|
||||
<v-btn @click="get()" :disabled="!entity" >
|
||||
Read <v-icon right>compare_arrows</v-icon>
|
||||
</v-btn>
|
||||
</td>
|
||||
<td>
|
||||
<v-switch v-on:change="gchange" v-model="repeat.get"></v-switch>
|
||||
<v-data-table slot="table" slot-scope="{ headers, items, run }" :hide-default-footer="true" :disable-pagination="true"
|
||||
:headers="headers" :items="items" dense >
|
||||
<template v-slot:item.id="{ item }" >
|
||||
<v-btn @click="run(item.index)" :title="item.index">{{ item.id }}</v-btn>
|
||||
</template>
|
||||
<template v-slot:item.repeat="{ item }" >
|
||||
<v-simple-checkbox v-model="item.repeat"></v-simple-checkbox>
|
||||
</template>
|
||||
</v-data-table>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<span >{{getValues.last}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span >{{getValues.count}}</span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<span >{{getValues.avg | round(2)}}</span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<span >{{getValues.min}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span >{{getValues.max}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span >{{getValues.median}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<div slot="response" slot-scope="{ data }">
|
||||
<h3>Counter: <v-chip color="amber" text-color="white">counter</v-chip></h3>
|
||||
<pre>{{ data | pretty}}</pre>
|
||||
</div>
|
||||
</qd-perfstats>
|
||||
|
||||
|
||||
</tbody>
|
||||
</template>
|
||||
</v-simple-table>
|
||||
|
||||
<h3>Value: <v-chip color="amber" text-color="white">{{counter}}</v-chip></h3>
|
||||
<pre>{{ result | pretty}}</pre>
|
||||
</v-card-text>
|
||||
|
||||
</v-card>
|
||||
|
||||
</v-container>
|
||||
|
|
@ -83,68 +63,61 @@
|
|||
<script>{
|
||||
data: function(){
|
||||
return {
|
||||
getValues: new perfStat(),
|
||||
repeat: {get:false},
|
||||
entity: null,
|
||||
selectedEntities: [],
|
||||
counter: 0,
|
||||
result: null,
|
||||
entities: null,
|
||||
columns: [
|
||||
{label:"Entity"},
|
||||
{label:"Action"},
|
||||
{label:"Repeat"},
|
||||
{label:"Last"},
|
||||
{label:"Count"},
|
||||
{label:"Avg"},
|
||||
{label:"min"},
|
||||
{label:"max"},
|
||||
{label:"Median"}
|
||||
]
|
||||
entities: [],
|
||||
result: null
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
get(){
|
||||
var _start = performance.now();
|
||||
console.log("entity:", this.entity)
|
||||
HTTP.get(this.entity.datalink,axios_json)
|
||||
.then(r=>{
|
||||
var elapsed=Math.floor(performance.now() - _start);
|
||||
this.counter++;
|
||||
this.result=r.data;
|
||||
Object.assign(this.getValues,this.getValues.log(elapsed))
|
||||
this.$forceUpdate()
|
||||
if(this.repeat.get){
|
||||
this.get(); //does this leak??
|
||||
}
|
||||
})
|
||||
},
|
||||
gchange(v){
|
||||
if(v)this.get()
|
||||
},
|
||||
|
||||
reset(){
|
||||
Object.assign(this.getValues,this.getValues.clear());
|
||||
this.$forceUpdate()
|
||||
},
|
||||
getentities(){
|
||||
HTTP.get("data/entity",axios_json)
|
||||
.then(r=>{
|
||||
console.log("entities: ",r.data);
|
||||
//console.log("entities: ",r.data);
|
||||
this.entities=r.data.items
|
||||
})
|
||||
},
|
||||
setSel(add){
|
||||
console.log("setSel",this.selectedEntities)
|
||||
this.selectedEntities.forEach(item=>add(item.name,'GET',item.datalink))
|
||||
},
|
||||
toggle () {
|
||||
this.$nextTick(() => {
|
||||
if (this.all) {
|
||||
this.selectedEntities = []
|
||||
} else {
|
||||
this.selectedEntities = this.entities.slice()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
computed:{
|
||||
all () {
|
||||
return this.selectedEntities.length === this.entities.length
|
||||
},
|
||||
some () {
|
||||
return this.selectedEntities.length > 0 && !this.all
|
||||
},
|
||||
icon () {
|
||||
if (this.all) return 'mdi-close-box'
|
||||
if (this.some) return 'mdi-minus-box'
|
||||
return 'mdi-checkbox-blank-outline'
|
||||
}
|
||||
},
|
||||
|
||||
created(){
|
||||
console.log("GET entities: ");
|
||||
this.getentities()
|
||||
},
|
||||
|
||||
beforeRouteLeave(to, from, next){
|
||||
var on=this.repeat.get
|
||||
var on=this.some // @TODO this.repeat.get
|
||||
|
||||
if (on) {
|
||||
alert("running!") //<--undefined
|
||||
return next(false)
|
||||
return next()
|
||||
} else {
|
||||
return next()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,93 +5,29 @@
|
|||
<v-toolbar >
|
||||
<v-toolbar-title>Simple response counter</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="reset()">Reset</v-btn>
|
||||
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<p>Read or increment a database value. This measures round trip times browser-database-browser.</p>
|
||||
<h3>Value: <v-chip color="amber" text-color="white">{{counter}}</v-chip></h3>
|
||||
<table class="v-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-1">Action</th>
|
||||
<th class="col-md-1">Repeat</th>
|
||||
<th class="col-md-1 text-right">Last</th>
|
||||
<th class="col-md-1 text-right">Count</th>
|
||||
<th class="col-md-1 text-right">Avg</th>
|
||||
<th class="col-md-1 text-right">min</th>
|
||||
<th class="col-md-1 text-right">max</th>
|
||||
<th class="col-md-1 text-right">Median</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<qd-perfstats :initial="initial">
|
||||
|
||||
<div slot="actions" slot-scope="{ add , repeats, reset }">
|
||||
<v-btn @click="repeats(false)">Repeat off</v-btn>
|
||||
<v-btn @click="reset()">Reset</v-btn>
|
||||
</div>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<v-btn @click="get()" >
|
||||
Read Db<v-icon right>compare_arrows</v-icon>
|
||||
</v-btn>
|
||||
<v-data-table slot="table" slot-scope="{ headers, items, run }" :hide-default-footer="true"
|
||||
:headers="headers" :items="items" >
|
||||
<template v-slot:item.id="{ item }" >
|
||||
<v-btn @click="run(item.index)">{{ item.id }}</v-btn>
|
||||
</template>
|
||||
<template v-slot:item.repeat="{ item }" >
|
||||
<v-switch v-model="item.repeat"></v-switch>
|
||||
</template>
|
||||
</v-data-table>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<v-switch v-on:change="gchange" v-model="repeat.get"></v-switch>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-right">{{getValues.last}}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-right" >{{getValues.count}}</p>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<p class="text-right" >{{getValues.avg | round(2)}}</p>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<p class="text-right" >{{getValues.min}}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-right" >{{getValues.max}}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-right" >{{getValues.median}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<v-btn @click="update()" >
|
||||
Write Db<v-icon right>compare_arrows</v-icon>
|
||||
</v-btn>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<v-switch v-on:change="pchange" v-model="repeat.post"></v-switch>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span >{{postValues.last}}</span>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span >{{postValues.count}}</span>
|
||||
</td >
|
||||
|
||||
<td class="text-right">
|
||||
<span >{{postValues.avg | round(2)}}</span>
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
<span >{{postValues.min}}</span>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span >{{postValues.max}}</span>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span >{{postValues.median}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</qd-perfstats>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
|
@ -102,67 +38,15 @@
|
|||
export default {
|
||||
data: function(){
|
||||
return {
|
||||
nothingValues: new perfStat(),
|
||||
staticValues: new perfStat(),
|
||||
getValues: new perfStat(),
|
||||
postValues: new perfStat(),
|
||||
repeat: {get: false, post: false, staticx: false, nothing: false},
|
||||
counter: "(unread)"
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
update () {
|
||||
var _start = performance.now();
|
||||
HTTP.post("ping",axios_json)
|
||||
.then(r=>{
|
||||
var elapsed=Math.floor(performance.now() - _start);
|
||||
this.counter=r.data
|
||||
Object.assign(this.postValues,this.postValues.log(elapsed))
|
||||
if(this.repeat.post){
|
||||
this.update(); //does this leak??
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
get(){
|
||||
var _start = performance.now();
|
||||
HTTP.get("ping",axios_json)
|
||||
.then(r=>{
|
||||
var elapsed=Math.floor(performance.now() - _start);
|
||||
this.counter=r.data
|
||||
Object.assign(this.getValues,this.getValues.log(elapsed))
|
||||
this.$forceUpdate()
|
||||
if(this.repeat.get){
|
||||
this.get(); //does this leak??
|
||||
}
|
||||
})
|
||||
},
|
||||
nothing () {
|
||||
var _start = performance.now();
|
||||
HTTP.post("nothing",axios_json)
|
||||
.then(r=>{
|
||||
var elapsed=Math.floor(performance.now() - _start);
|
||||
this.counter=r.data
|
||||
Object.assign(this.nothingValues,this.nothingValues.log(elapsed))
|
||||
if(this.repeat.nothing){
|
||||
this.nothing(); //does this leak??
|
||||
}
|
||||
})
|
||||
},
|
||||
gchange(v){
|
||||
if(v)this.get()
|
||||
},
|
||||
pchange(v){
|
||||
if(v)this.update()
|
||||
},
|
||||
reset(){
|
||||
Object.assign(this.getValues,this.getValues.clear());
|
||||
Object.assign(this.postValues,this.postValues.clear());
|
||||
this.$forceUpdate()
|
||||
}
|
||||
initial:[
|
||||
{ id: 'WRITE DB', method: 'POST', url: 'performance/ping'},
|
||||
{ id: 'READ DB', method: 'GET', url: 'performance/ping'},
|
||||
{ id: 'NO DB', method: 'GET', url: 'performance/nodb'}
|
||||
],
|
||||
counter: 0}
|
||||
},
|
||||
beforeRouteLeave(to, from, next){
|
||||
var on=this.repeat.get || this.repeat.post
|
||||
var on=false // @TODO this.repeat.get || this.repeat.post
|
||||
|
||||
if (on) {
|
||||
alert("running!") //<--undefined
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ declare %basex:lazy variable $ping:state as element(state):=db:open($ping:db,"/s
|
|||
: incr counter
|
||||
:)
|
||||
declare %updating
|
||||
%rest:POST %rest:path("/vue-poc/api/ping")
|
||||
%rest:POST %rest:path("/vue-poc/api/performance/ping")
|
||||
%output:method("text")
|
||||
function ping:dopost()
|
||||
{(
|
||||
|
|
@ -23,7 +23,7 @@ function ping:dopost()
|
|||
:)
|
||||
declare
|
||||
%output:method("text")
|
||||
%rest:GET %rest:path("/vue-poc/api/ping")
|
||||
%rest:GET %rest:path("/vue-poc/api/performance/ping")
|
||||
function ping:dostate()
|
||||
{
|
||||
$ping:state/ping
|
||||
|
|
@ -34,7 +34,7 @@ function ping:dostate()
|
|||
:)
|
||||
declare
|
||||
%output:method("text")
|
||||
%rest:GET %rest:path("/vue-poc/api/nodb")
|
||||
%rest:GET %rest:path("/vue-poc/api/performance/nodb")
|
||||
function ping:nodb()
|
||||
{
|
||||
"ok"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,20 @@
|
|||
|
||||
<v-card-text>
|
||||
|
||||
<qd-table :headers="headers" data-uri="server/basexsettings2" item-key="name" >
|
||||
<template v-slot:item.name="{ item }" >
|
||||
<v-chip>{{ item.name }}</v-chip>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.changed="{ item }" >
|
||||
<v-simple-checkbox v-model="item.changed" disabled></v-simple-checkbox>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.description="{ item }" >
|
||||
<qd-link :href="'http://docs.basex.org/wiki/Options#' + item.name.toUpperCase()">BaseX doc</qd-link>
|
||||
</template>
|
||||
|
||||
</qd-table>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="filtered"
|
||||
|
|
@ -46,7 +60,7 @@
|
|||
{text: "current", value: "current"},
|
||||
{text: "changed", value: "changed"},
|
||||
{text: "default", value: "default"},
|
||||
{text: "description"}
|
||||
{text: "description", value: "description"}
|
||||
],
|
||||
pagination: {
|
||||
descending: false,
|
||||
|
|
@ -66,6 +80,13 @@
|
|||
this.items=r.data
|
||||
|
||||
})
|
||||
},
|
||||
customFilter(value, search, item) {
|
||||
return item.changed == this.changed &&
|
||||
value != null &&
|
||||
search != null &&
|
||||
typeof value === 'string' &&
|
||||
value.toString().indexOf(search) !== -1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
|||
|
|
@ -28,3 +28,27 @@ return <_ type="object">
|
|||
</json>
|
||||
};
|
||||
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/server/basexsettings2")
|
||||
%rest:produces("application/json")
|
||||
%output:method("json")
|
||||
function set:values2()
|
||||
{
|
||||
let $defaults:=doc("basexsettings-921.xml")//*[not(*)]
|
||||
let $dm:=map:merge($defaults!map:entry(name(.),string(.)))
|
||||
let $settings:=db:system()//*[not(*)]
|
||||
let $sm:=map:merge($settings!map:entry(name(.),string(.)))
|
||||
let $names:=distinct-values((map:keys( $dm),map:keys($sm)))=>sort()
|
||||
return <json type="object">
|
||||
<items type="array">
|
||||
{for $name in $names
|
||||
let $change:=$dm($name) ne $sm($name)
|
||||
return <_ type="object">
|
||||
<name>{$name}</name>
|
||||
<default>{$dm($name)}</default>
|
||||
<current>{$sm($name)}</current>
|
||||
<changed type="boolean">{ if ($change) then $change else false() }</changed>
|
||||
</_>}
|
||||
</items>
|
||||
</json>
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@
|
|||
<router-link :to="{name: 'repo1', query: {id: item.name }}">{{ item.name }} </router-link>
|
||||
</template>
|
||||
<template v-slot:actions>
|
||||
<v-btn>action here</v-btn>
|
||||
<v-list-item @click="remove">
|
||||
<v-list-item-avatar><v-icon>delete</v-icon></v-list-item-avatar>
|
||||
<v-list-item-title>Delete</v-list-item-title>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</qd-table>
|
||||
</v-container>
|
||||
|
|
@ -27,6 +30,11 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
remove(){
|
||||
alert("Not yet")
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"query":{
|
||||
handler:function(vnew,vold){
|
||||
|
|
|
|||
|
|
@ -35,11 +35,15 @@ as map(*){{
|
|||
(:~
|
||||
: generate xquery for to return field value in the format: "name":function($_){}
|
||||
:)
|
||||
declare function bf:accessfn($f as element(ent:field)) as xs:string
|
||||
declare function bf:accessfn(
|
||||
$f as element(ent:field)
|
||||
) as xs:string
|
||||
{
|
||||
let $type:=$f/@type/fn:string()
|
||||
return <field>
|
||||
"{$f/@name/fn:string()}": function($_ as element()) as {$type} {{$_/{$f/ent:xpath } }}</field>
|
||||
let $name:=$f/@name/fn:string()
|
||||
let $resulttype:=$f/@type/fn:string()
|
||||
let $srctype:=$f/ancestor::ent:entity/ent:data/@type/fn:string()
|
||||
return ``[
|
||||
'`{ $name }`': function($_ as `{ $srctype }`) as `{$resulttype}` { $_! `{ $f/ent:xpath }` }]``
|
||||
};
|
||||
|
||||
declare function bf:generate($e as element(ent:entity)) as xs:string
|
||||
|
|
@ -78,10 +82,9 @@ declare function bf:generate($e as element(ent:entity)) as xs:string
|
|||
declare function bf:entities($path as xs:string)
|
||||
as element(ent:entity)*
|
||||
{
|
||||
let $_:=fn:trace($path,"DD")
|
||||
let $p:=fn:resolve-uri($path) || "/"
|
||||
return for $f in file:list($p,fn:true())
|
||||
where not(ends-with(trace($f),file:dir-separator()))
|
||||
return for $f in file:list($p,fn:true(),"*.xml")
|
||||
where not(ends-with($f,file:dir-separator()))
|
||||
order by $f
|
||||
return fn:doc(fn:concat($p,$f))/ent:entity
|
||||
};
|
||||
|
|
@ -111,6 +114,7 @@ as xs:string
|
|||
let $opt:=fn:contains($type,"?")
|
||||
let $repeat:=fn:contains($type,"*")
|
||||
let $json-type:=bf:json-type($type)
|
||||
let $srctype:=$f/ancestor::ent:entity/ent:data/@type/fn:string()
|
||||
let $mult:=if($repeat) then "*" else "?"
|
||||
|
||||
let $at:=if($json-type ne "string")
|
||||
|
|
@ -119,7 +123,7 @@ as xs:string
|
|||
(: generate json xml :)
|
||||
let $simple:=function() as xs:string{
|
||||
<field>(: {$type} :)
|
||||
fn:data($_/{$f/ent:xpath })!element {$name} {{ {$at} .}}
|
||||
fn:data($_!{ $f/ent:xpath })!element { $name } {{ { $at } .}}
|
||||
</field>
|
||||
}
|
||||
let $array:=function() as xs:string{
|
||||
|
|
@ -138,7 +142,7 @@ as xs:string
|
|||
}
|
||||
|
||||
return <field>
|
||||
"{$name}": function($_ as element()) as element({$name}){$mult} {{
|
||||
"{$name}": function($_ as { $srctype }) as element({ $name }){ $mult } {{
|
||||
{if($repeat)then
|
||||
$array()
|
||||
else if($type="element()") then
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
(:~
|
||||
: Update `generated/models.xqm` from files in `data/models`
|
||||
: using file:///C:/Users/andy/workspace/app-doc/src/doc/data/doc/models
|
||||
: $efolder:="file:///C:/Users/andy/workspace/app-doc/src/doc/data/doc/models"
|
||||
: $target:="file:///C:/Users/andy/workspace/app-doc/src/doc/generated/models.xqm"
|
||||
:)
|
||||
module namespace vue-api = 'quodatum:vue.api';
|
||||
|
||||
import module namespace bf = 'quodatum.tools.buildfields' at "entity-gen.xqm";
|
||||
import module namespace query-a = 'vue-poc/query-a' at "../../../lib/query-a.xqm";
|
||||
|
||||
declare variable $vue-api:query:="tx-model.xq";
|
||||
(:~
|
||||
: Returns a file content.
|
||||
:)
|
||||
declare
|
||||
%rest:POST %rest:path("/vue-poc/api/tasks/model")
|
||||
%rest:produces("application/json")
|
||||
%output:method("json")
|
||||
%updating
|
||||
function vue-api:model( )
|
||||
{
|
||||
let $u:=resolve-uri($vue-api:query)
|
||||
return query-a:update($u,query-a:params($u))
|
||||
};
|
||||
|
||||
(:~
|
||||
: model settings.
|
||||
:)
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/tasks/model")
|
||||
%rest:produces("application/json")
|
||||
%output:method("json")
|
||||
function vue-api:settings()
|
||||
{
|
||||
let $xq:=resolve-uri($vue-api:query)
|
||||
return query-a:inspect($xq)
|
||||
};
|
||||
|
|
@ -23,7 +23,7 @@ let $config:='import module namespace cfg = "quodatum:media.image.configure" at
|
|||
|
||||
let $src:=bf:module(bf:entities($efolder),$config)
|
||||
return (
|
||||
prof:variables(),
|
||||
(: prof:variables(), :)
|
||||
file:write-text($target,$src),
|
||||
update:output(<json type="object"><msg>Updated: {$target}</msg></json>)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
<v-card-text>
|
||||
<v-container fluid>
|
||||
<vp-paramform v-if="!loading" ref="params" :endpoint="'tasks/'+task"></vp-paramform>
|
||||
<vp-paramform v-if="!loading" ref="params" :endpoint="endpoint"></vp-paramform>
|
||||
</v-container>
|
||||
</v-card-text>
|
||||
<v-snackbar v-model="snackbar.show"
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
this.loading= false
|
||||
this.id=r.data.id;
|
||||
this.snackbar= {show:true,
|
||||
msg: r.data && r.data.msg,
|
||||
msg: r.result,
|
||||
context:"success"
|
||||
};
|
||||
console.log(r)
|
||||
|
|
@ -79,16 +79,14 @@
|
|||
});
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
endpoint(){
|
||||
return 'tasks/'+this.task + (this.id? "?id=" + this.id:'')
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
id(v){
|
||||
this.$router.push({ query: { id: this.id }})
|
||||
},
|
||||
|
||||
$route(vnew,vold){
|
||||
console.log("ROUTE",vnew,vold)
|
||||
var id=this.$route.query.id
|
||||
this.id=id?id:null;
|
||||
if(vnew.query.url != vold.query.url) alert("gg")
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
module namespace vue-rest = 'quodatum:vue.tasks';
|
||||
import module namespace query-a = 'vue-poc/query-a' at "../../lib/query-a.xqm";
|
||||
import module namespace hlog = 'quodatum.data.history' at '../../lib/history.xqm';
|
||||
declare namespace hist="urn:quodatum:vue-poc.history";
|
||||
|
||||
(:~
|
||||
: list tasks
|
||||
:)
|
||||
|
|
@ -30,14 +32,23 @@ function vue-rest:tasks()
|
|||
:)
|
||||
declare
|
||||
%rest:GET %rest:path("/vue-poc/api/tasks/{$task}")
|
||||
%rest:query-param("id", "{ $id }")
|
||||
%rest:produces("application/json")
|
||||
%output:method("json")
|
||||
function vue-rest:task($task)
|
||||
function vue-rest:task($task,$id)
|
||||
{
|
||||
let $taskdef:=doc("taskdef.xml")/tasks/task[@name=$task]
|
||||
let $url:=resolve-uri($taskdef/@url)
|
||||
let $info:=query-a:inspect($url)
|
||||
return $info
|
||||
|
||||
let $h:=if($id) then hlog:get($id) else ()
|
||||
return if($h) then (: use old values :)
|
||||
let $v:=<values type="object">{
|
||||
$h/hist:task/hist:param!element{@name}{string(.)}
|
||||
}</values> =>trace("O/P")
|
||||
return $info transform with {replace node ./values with $v}
|
||||
else
|
||||
$info
|
||||
};
|
||||
|
||||
(:~
|
||||
|
|
@ -51,14 +62,20 @@ declare
|
|||
function vue-rest:runtask($task)
|
||||
{
|
||||
let $taskdef:=doc("taskdef.xml")/tasks/task[@name=$task]
|
||||
let $url:=resolve-uri($taskdef/@url)
|
||||
let $url:=resolve-uri($taskdef/@url)=>trace("RUNTASK")
|
||||
let $params:=query-a:params($url)
|
||||
let $log:=<task task="{ $task }" url="{ $url }">
|
||||
{ map:keys($params)!<param name="{.}">{map:get($params,.)}</param> }
|
||||
</task>
|
||||
return (
|
||||
query-a:run($url, $params, map{}),
|
||||
hlog:save($log)
|
||||
hlog:save($log),
|
||||
let $a:=update:cache(true())
|
||||
let $r:=<json type="object">
|
||||
<result>{$a[1]}</result>
|
||||
<id>{$a[2]}</id>
|
||||
</json>
|
||||
return update:output($r)
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -1,14 +1,9 @@
|
|||
<tasks>
|
||||
<tasks >
|
||||
<task name="model" url="model.build/tx-model.xq">
|
||||
<title>Generate model.gen.xqm</title>
|
||||
<description> Generate <code>model.gen.xqm</code> from files in entity folder
|
||||
</description>
|
||||
</task>
|
||||
<task name="model2" url="model.build/tx-model.xq">
|
||||
<title>Generate model.gen.xqm</title>
|
||||
<description> Generate <code>model.gen.xqm</code> from files in entity folder
|
||||
</description>
|
||||
</task>
|
||||
<task name="import2" url="task/tx-dbimport2.xq">
|
||||
<title>Import files from drive into a database</title>
|
||||
<description>Load files into database</description>
|
||||
|
|
|
|||
|
|
@ -7,15 +7,23 @@ declare namespace hist="urn:quodatum:vue-poc.history";
|
|||
declare variable $hlog:doc as element(hist:history):=db:open("vue-poc","/history.xml")/hist:history;
|
||||
|
||||
(:~
|
||||
wrap $item in <hist:event id=".." when=".." > node and insert in /history.xml in database vue-poc
|
||||
: write history event /history.xml in database vue-poc
|
||||
: wrap $item in <hist:event id=".." when=".." > node and insert as first
|
||||
:)
|
||||
declare
|
||||
%updating
|
||||
function hlog:save($item as element(*))
|
||||
{
|
||||
let $id:=$hlog:doc/@next-id/string(.)
|
||||
let $n:=<hist:event id="{$id}" when="{fn:current-dateTime()}" user="admin">{$item}</hist:event>
|
||||
let $id:=$hlog:doc/@next-id/string()=>trace("Saving: ")
|
||||
let $n:=<hist:event id="ev-{$id}" when="{fn:current-dateTime()}" user="admin">{$item}</hist:event>
|
||||
return (insert node $n as first into $hlog:doc,
|
||||
replace value of node $hlog:doc/@next-id with number($id)+1
|
||||
replace value of node $hlog:doc/@next-id with number($id)+1,
|
||||
update:output("ev-" || $id)
|
||||
)
|
||||
};
|
||||
|
||||
(:~ get history record for id :)
|
||||
declare function hlog:get($id as xs:string) as element(hist:event)?
|
||||
{
|
||||
$hlog:doc/hist:event[@id=$id]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
module namespace query-a = 'vue-poc/query-a';
|
||||
|
||||
import module namespace request = "http://exquery.org/ns/request";
|
||||
import module namespace xquery = "http://basex.org/modules/xquery";
|
||||
|
||||
|
||||
(:~
|
||||
|
|
@ -78,7 +79,7 @@ function query-a:run($query as xs:string,
|
|||
$options as map(*)
|
||||
)
|
||||
{
|
||||
let $query := xs:anyURI($query)
|
||||
let $query := xs:anyURI($query) =>trace("query-a:run")
|
||||
let $updating:=xquery:parse-uri($query)/@updating/boolean(.)
|
||||
return if($updating) then
|
||||
xquery:eval-update($query, $bindings, $options)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,7 @@
|
|||
"description": "App framework experiments, Frontend vuetify, backend: basex",
|
||||
"dependencies": {
|
||||
"ace-builds": "1.4.12",
|
||||
"vuetify": "2.3.13",
|
||||
"vuetify": "2.3.14",
|
||||
"vue": "2.6.11",
|
||||
"vuex": "3.1.0",
|
||||
"vue-router": "3.1.6",
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
Vue-poc
|
||||
|
||||
Min BaseX: 9.3+ https://docs.basex.org/wiki/Update_Module#Changelog
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ const router = new VueRouter({
|
|||
},
|
||||
{ path: '/history', component: { template: '<router-view/>' }
|
||||
,children: [
|
||||
{ path: 'files', component: Filehistory, meta:{title: "File History"} }
|
||||
{ path: 'files', component: Filehistory, meta:{title: "File History"} },
|
||||
{ path: 'tasks', name: "taskhistory", component: Taskhistory, meta:{title: "Task History"} }
|
||||
]
|
||||
},
|
||||
{ path: '/labs', component: { template: '<router-view/>' }
|
||||
|
|
@ -158,7 +159,6 @@ const router = new VueRouter({
|
|||
|
||||
{ path: '/tasks', component: { template: '<router-view/>' } , children:[
|
||||
{ path: '', component: Tasks, meta:{title:"Runnable tasks"} },
|
||||
{ path: 'model', component: Model, meta:{title:"build model"} },
|
||||
{ path: 'vuecompile', component: Vuecompile, meta:{title:"vue compile"} },
|
||||
{ path: ':task', props: true, component: { template: '<router-view/>' },
|
||||
children:[
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -10,7 +10,7 @@
|
|||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"/>
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"/>
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" >
|
||||
<link rel="stylesheet" href="//unpkg.com/vuetify@2.3.13/dist/vuetify.min.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="//unpkg.com/vuetify@2.3.14/dist/vuetify.min.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="//unpkg.com/@riophae/vue-treeselect@0.0.29/dist/vue-treeselect.min.css"/>
|
||||
<link rel="stylesheet" href="/vue-poc/ui/prism/prism.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="//unpkg.com/leaflet@1.6.0/dist/leaflet.css"/>
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
<script src="//cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.js" crossorigin="anonymous"></script>
|
||||
<script src="//unpkg.com/vuex@3.1.0/dist/vuex.js" crossorigin="anonymous"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.js" crossorigin="anonymous" ></script>
|
||||
<script src="//unpkg.com/vuetify@2.3.13/dist/vuetify.min.js" crossorigin="anonymous"></script>
|
||||
<script src="//unpkg.com/vuetify@2.3.14/dist/vuetify.min.js" crossorigin="anonymous"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" crossorigin="anonymous"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ext-language_tools.js" crossorigin="anonymous"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ext-linking.js" crossorigin="anonymous" charset="utf-8"></script>
|
||||
|
|
@ -65,7 +65,6 @@
|
|||
<script src="//unpkg.com/vue-native-websocket@2.0.8/dist/build.js" crossorigin="anonymous"></script>
|
||||
<script src="/vue-poc/ui/svg/d3-svg.js"></script>
|
||||
<script src="/vue-poc/ui/state.js"></script>
|
||||
<script src="/vue-poc/ui/perf-stat.js"></script>
|
||||
<script src="/vue-poc/ui/app-gen.js"></script>
|
||||
<script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
// performance monitoring. of value stream
|
||||
// var t=new perfStat()
|
||||
// t.log(newValue)
|
||||
// stores max min etc
|
||||
function perfStat() {
|
||||
this.data={count:0,max:null,min:null,total:0,median:0,last:null,avg:null};
|
||||
// add a value return updated stats
|
||||
this.log=function(val){
|
||||
var data=this.data
|
||||
data.last=val;
|
||||
data.total+=val;
|
||||
data.count+=1;
|
||||
if(data.count==1){
|
||||
data.max=val;
|
||||
data.min=val;
|
||||
data.median=val;
|
||||
}else{
|
||||
if(val<data.min)data.min=val;
|
||||
if(val>data.max)data.max=val;
|
||||
};
|
||||
//https://jeremykun.com/2012/06/14/streaming-median/
|
||||
if (data.median > val)
|
||||
data.median-= 1
|
||||
else if( data.median < val)
|
||||
data.median += 1;
|
||||
|
||||
data.avg=data.total / data.count;
|
||||
// console.log("stats",data);
|
||||
return data;
|
||||
};
|
||||
// clear stats
|
||||
this.clear=function(){
|
||||
this.data={count:0,max:null,min:null,total:0,median:0,last:null,avg:null};
|
||||
return this.data
|
||||
};
|
||||
// return values
|
||||
this.values=function(){
|
||||
return this.data;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue