vuetify 1.1.11

This commit is contained in:
Andy Bunce 2018-08-15 18:06:33 +01:00
parent ac9cb9ff8d
commit b00fa46bf5
30 changed files with 633 additions and 400 deletions

View file

@ -160,6 +160,7 @@
{href: '/server/logs',text: 'Server logs',icon: 'dns'}, {href: '/server/logs',text: 'Server logs',icon: 'dns'},
{href: '/server/users',text: 'Users',icon: 'supervisor_account'}, {href: '/server/users',text: 'Users',icon: 'supervisor_account'},
{href: '/server/repo',text: 'Server code repository',icon: 'local_library'}, {href: '/server/repo',text: 'Server code repository',icon: 'local_library'},
{href: '/server/websocket',text: 'Web socket',icon: 'swap_calls'},
{href: '/server/ping',text: 'Ping',icon: 'update'} {href: '/server/ping',text: 'Ping',icon: 'update'}
]}, ]},
{ {

View file

@ -1,9 +1,9 @@
// Authorization Object // Authorization Object
const Auth={ const Auth={
user:"guest", user: "guest",
permission:null, role: null,
session:null, session: null,
created:null, created: null,
install: function(Vue){ install: function(Vue){
Object.defineProperty(Vue.prototype, '$auth', { Object.defineProperty(Vue.prototype, '$auth', {
get () { return Auth } get () { return Auth }
@ -11,7 +11,7 @@ const Auth={
}, },
logout(){ logout(){
Auth.user="guest"; Auth.user="guest";
Auth.permission=null; Auth.role=null;
} }
}; };
Vue.use(Auth); Vue.use(Auth);

View file

@ -4,7 +4,7 @@
--> -->
<template id="vp-notifications"> <template id="vp-notifications">
<v-card> <v-card>
<v-toolbar class="amber white--text" scroll-toolbar-off-screen> <v-toolbar class="amber white--text" scroll-off-screen>
<v-toolbar-title >Notifications </v-toolbar-title> <v-toolbar-title >Notifications </v-toolbar-title>
{{ $notification.nextId }} {{ $notification.nextId }}
<v-btn @click="refresh" icon><v-icon>refresh</v-icon></v-btn> <v-btn @click="refresh" icon><v-icon>refresh</v-icon></v-btn>

View file

@ -1,29 +1,45 @@
<!DOCTYPE html> <!DOCTYPE html>
<!-- <!--
manage parameters for query manage parameters for query
including funtion to submit form
--> -->
<template id="vp-paramform"> <template id="vp-paramform">
<v-form ref="form" lazy-validation> <v-form ref="form" lazy-validation>
<div class="title">{{ description }}</div> <div class="title">{{ description }}</div>
<v-flex v-for="field in fields" :key="field.model"> <div :title="url">{{ updating }}</div>
<v-layout row>
<v-text-field v-if="field.type === 'xs:anyURI'" xs10 <v-layout column xs10>
<v-flex v-for="field in fields" :key="field.model" >
<v-text-field v-if="field.type === 'xs:anyURI'" :full-width="true"
v-model="params[field.model]" :label="field.label" v-model="params[field.model]" :label="field.label"
clearable :rules="fieldrules(field)" box clearable :rules="fieldrules(field)" box
append-outer-icon="send" @click:append-outer="source(field)" append-outer-icon="send" @click:append-outer="source(field)"
></v-text-field> ></v-text-field>
<v-switch v-else-if="field.type === 'xs:boolean'" xs10 :label="field.label" v-model="params[field.model]"> <v-switch v-else-if="field.type === 'xs:boolean'" :full-width="true"
:label="field.label" v-model="params[field.model]">
</v-switch> </v-switch>
<v-text-field v-else xs10 amber <v-text-field v-else :full-width="true" amber
v-model="params[field.model]" :label="field.type" v-model="params[field.model]" :label="field.type"
clearable box clearable box ></v-text-field>
></v-text-field>
</v-flex> </v-flex>
<v-flex>
</v-flex>
</v-layout>
<v-layout align-center justify-center column fill-height xs2 amber lighten-5>
<v-btn @click="clear()"
>Clear</v-btn>
<v-btn @click="reset()"
>Reset</v-btn>
</v-layout>
</v-layout>
</v-form> </v-form>
</template> </template>
@ -34,6 +50,8 @@
fields: [], fields: [],
params: null, params: null,
description: null, description: null,
updating: false,
url: null,
rules: { rules: {
required: value => !!value || 'Required.' required: value => !!value || 'Required.'
} }
@ -43,8 +61,10 @@
reset(){ reset(){
HTTP.get(this.endpoint) HTTP.get(this.endpoint)
.then(r=>{ .then(r=>{
this.fields=r.data.fields; this.fields= r.data.fields;
this.description=r.data.description; this.description= r.data.description;
this.updating= r.data.updating;
this.url= r.data.url;
this.params = Object.assign({}, this.params, r.data.values); this.params = Object.assign({}, this.params, r.data.values);
}) })
}, },

View file

@ -173,6 +173,9 @@ function install (Vue) {
Vue.component('vue-form-json-schema', VueFormJsonSchema); Vue.component('vue-form-json-schema', VueFormJsonSchema);
}; };
Vue.use({ install: install }); Vue.use({ install: install });
var sockhost=('https:'==window.location.protocol?'wss:':'ws:')+'//'+ window.location.host +'/ws';
Vue.use(VueNativeSock.default, sockhost);
console.log("SOCK UP",VueNativeSock,sockhost);
//leaflet //leaflet
//Vue.component('v-map', Vue2Leaflet.Map); //Vue.component('v-map', Vue2Leaflet.Map);

View file

@ -5,7 +5,7 @@
<v-card class="grey lighten-4 elevation-0"> <v-card class="grey lighten-4 elevation-0">
<v-card-title class="amber "> <v-card-title class="amber ">
<span class="white--text">Please login as user with permission is required</span> <span class="white--text">The current identity is not permissioned to access this page, please login again</span>
</v-card-title> </v-card-title>
<v-alert color="error" v-bind:value="showMessage"> <v-alert color="error" v-bind:value="showMessage">
{{message}} {{message}}
@ -33,7 +33,6 @@
></v-text-field> ></v-text-field>
</v-card-actions> </v-card-actions>
<v-divider></v-divider>
<v-card-actions > <v-card-actions >
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn color="primary" @click="go()">Continue</v-btn> <v-btn color="primary" @click="go()">Continue</v-btn>

View file

@ -82,7 +82,7 @@
methods:{ methods:{
getItems(){ getItems(){
this.loading=true this.loading=true
HTTP.get("data/entity",{params:this.q}) HTTP.get("data/entity",{params:{q:this.q}})
.then(r=>{ .then(r=>{
this.loading=false this.loading=false
//console.log(r.data) //console.log(r.data)

View file

@ -9,7 +9,12 @@
</v-breadcrumbs-item> </v-breadcrumbs-item>
<v-breadcrumbs-item > <v-breadcrumbs-item >
<v-chip>
<v-avatar>
<v-icon>{{ item.iconclass }}</v-icon>
</v-avatar>
{{ entity }} {{ entity }}
</v-chip>
</v-breadcrumbs-item> </v-breadcrumbs-item>
</v-breadcrumbs> </v-breadcrumbs>
</v-toolbar-title> </v-toolbar-title>
@ -26,9 +31,12 @@
</v-toolbar> </v-toolbar>
<v-container fluid grid-list-md> <v-container fluid grid-list-md>
<div v-if="item">
<div>{{item.description}}</div>
<code>{{item.code}}</code>
</div>
<pre>{{ xml }}</pre> <pre>{{ xml }}</pre>
</v-container> </v-container>
</v-card> </v-card>
</template> </template>
@ -37,8 +45,10 @@
props: ['entity'], props: ['entity'],
data: function(){ data: function(){
return { return {
q: 'filter', item: {description:null,
item: {}, code: null
},
loading: false, loading: false,
xml: null xml: null
} }
@ -46,16 +56,14 @@
methods:{ methods:{
getItem(){ getItem(){
this.loading=true this.loading=true
HTTP.get("data/entity/"+this.entity,{params:this.q}) HTTP.get("data/entity/"+this.entity)
.then(r=>{ .then(r=>{
this.loading=false this.loading=false
//console.log(r.data) this.item=Object.assign({}, this.item, r.data)
//var items=r.data.items.filter(item=>{return item.text!="[GET] http://localhost:8984/vue-poc/api/log"})
this.item=r.data.items
}) })
}, },
getxml(){ getxml(){
HTTP.get("data/entity/"+this.entity,{params:this.q, headers: {Accept: "text/xml"}}) HTTP.get("data/entity/"+this.entity,{ headers: {Accept: "text/xml"}})
.then(r=>{ .then(r=>{
console.log(r.data) console.log(r.data)
this.xml=r.data; this.xml=r.data;

View file

@ -10,11 +10,10 @@
<v-card-text> <v-card-text>
<p>Read or increment a database value. This measures round trip times browser-database-browser.</p> <p>Read or increment a database value. This measures round trip times browser-database-browser.</p>
<h3>Counter: <v-chip color="amber" text-color="white">{{counter}}</v-chip></h3> <h3>Counter: <v-chip color="amber" text-color="white">{{counter}}</v-chip></h3>
<table > <table class="v-table">
<thead> <thead>
<tr> <tr>
<th xs1>Action</th> <th xs1>Action</th>
<th xs1>Once</th>
<th xs1>Repeat</th> <th xs1>Repeat</th>
<th xs1>Last</th> <th xs1>Last</th>
<th xs1>Count</th> <th xs1>Count</th>
@ -28,10 +27,9 @@
<tr> <tr>
<td>Get</td>
<td> <td>
<v-btn @click="get()" icon > <v-btn @click="get()" >
<v-icon>radio_button_checked</v-icon> Read <v-icon>compare_arrows</v-icon>
</v-btn> </v-btn>
</td> </td>
@ -62,10 +60,9 @@
</tr> </tr>
<tr> <tr>
<td>Update</td>
<td> <td>
<v-btn @click="update()" icon > <v-btn @click="update()" >
<v-icon>radio_button_checked</v-icon> Write <v-icon>compare_arrows</v-icon>
</v-btn> </v-btn>
</td> </td>

View file

@ -20,7 +20,8 @@ declare
%updating %updating
function vue-api:model( ) function vue-api:model( )
{ {
resolve-uri($vue-api:query)=>query-a:update(query-a:params()) let $u:=resolve-uri($vue-api:query)
return query-a:update($u,query-a:params($u))
}; };
(:~ (:~

View file

@ -8,13 +8,15 @@ import module namespace bf = 'quodatum.tools.buildfields' at "./../../../lib/ent
: Folder containing model definitions as xml : Folder containing model definitions as xml
: @default C:/Users/andy/git/vue-poc/src/vue-poc/models/entities : @default C:/Users/andy/git/vue-poc/src/vue-poc/models/entities
:) :)
declare variable $efolder as xs:anyURI external :="C:/Users/andy/git/vue-poc/src/vue-poc/models/entities"; declare variable $efolder as xs:anyURI external
:=xs:anyURI("C:/Users/andy/git/vue-poc/src/vue-poc/models/entities");
(:~ (:~
: Path to xqm file to generate : Path to xqm file to generate
: @default C:/Users/andy/git/vue-poc/src/vue-poc/models.gen.xqm : @default C:/Users/andy/git/vue-poc/src/vue-poc/models.gen.xqm
:) :)
declare variable $target as xs:anyURI external :="C:/Users/andy/git/vue-poc/src/vue-poc/models.gen.xqm"; declare variable $target as xs:anyURI external
:=xs:anyURI("C:/Users/andy/git/vue-poc/src/vue-poc/models.gen.xqm");
let $config:='import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";' let $config:='import module namespace cfg = "quodatum:media.image.configure" at "config.xqm";'

View file

@ -53,6 +53,8 @@ function vue-rest:runtask($task)
let $task:=doc("taskdef.xml")/tasks/task[@name=$task] let $task:=doc("taskdef.xml")/tasks/task[@name=$task]
let $url:=resolve-uri($task/@url) let $url:=resolve-uri($task/@url)
return query-a:run($url,query-a:params()) return (
query-a:run($url,query-a:params($url)),
}; };

View file

@ -15,6 +15,10 @@
</v-breadcrumbs> </v-breadcrumbs>
</v-toolbar-title> </v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn color="primary" @click="submit()" :loading="loading"
:disabled="loading">
<v-icon>play_circle_outline</v-icon>
Run</v-btn>
</v-toolbar> </v-toolbar>
<v-card-text> <v-card-text>
@ -28,19 +32,6 @@
</v-container> </v-container>
</v-card-text> </v-card-text>
<v-toolbar>
<v-btn @click="$refs.params.clear()" :loading="loading"
:disabled="loading"
>Clear</v-btn>
<v-btn @click="$refs.params.reset()" :loading="loading"
:disabled="loading"
>Reset</v-btn>
<v-spacer></v-spacer>
<v-btn color="primary" @click="submit()" :loading="loading"
:disabled="loading">
<v-icon>play_circle_outline</v-icon>
Run</v-btn>
</v-toolbar>
<v-snackbar v-model="snackbar.show" <v-snackbar v-model="snackbar.show"
:timeout="6000" :timeout="6000"
:success="snackbar.context === 'success'" :success="snackbar.context === 'success'"

View file

@ -15,9 +15,9 @@
<description>Generate documentation for folder</description> <description>Generate documentation for folder</description>
</task> </task>
<task name="xqdocdb"> <task name="xqdoc-rest" url="xqdoc/tx-xqdoc2.xq">
<title>XQdoc to db</title> <title>XQdoc rest</title>
<description>Generate XQdoc to save</description> <description>XQdoc...</description>
</task> </task>
<task name="vuecompile"> <task name="vuecompile">

View file

@ -18,16 +18,27 @@
clearable></v-text-field> clearable></v-text-field>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<vp-entitylink entity="namespace"></vp-entitylink> <vp-entitylink entity="task"></vp-entitylink>
</v-toolbar> </v-toolbar>
<v-card-text> <v-card-text>
<ul> <v-data-table
<li v-for="task in tasks" :key="task.to"> :headers="headers"
<router-link :to="'tasks/' + task.to" v-text="task.title"></router-link> :items="items"
<div v-html="task.description"></div> hide-actions
</li> :search="q"
</ul> class="elevation-1"
>
<template slot="items" slot-scope="props">
<td ><router-link :to="'tasks/' + props.item.to" v-text="props.item.title"></router-link></td>
<td >{{ props.item.description }}</td>
</template>
<template slot="no-data">
<v-alert :value="true" icon="warning">
No matching items.
</v-alert>
</template>
</v-data-table>
</v-card-text> </v-card-text>
</v-card> </v-card>
@ -38,9 +49,13 @@
<script>{ <script>{
data(){ data(){
return { return {
tasks: [], items: [],
loading: false, loading: false,
q: null q: null,
headers: [
{ text: 'Task', value: 'title' },
{ text: 'Description', value: 'description' },
]
} }
}, },
methods:{ methods:{
@ -48,7 +63,7 @@
this.loading= true; this.loading= true;
HTTP.get("tasks") HTTP.get("tasks")
.then(r=>{ .then(r=>{
this.tasks=r.data; this.items=r.data;
this.loading= false; this.loading= false;
}) })
} }

View file

@ -0,0 +1,162 @@
<!DOCTYPE html>
<ul>
<li>
<a>/vue-poc</a>
</li>
<li>
<a>/vue-poc/api</a>
</li>
<li>
<a>/vue-poc/api/collection</a>
</li>
<li>
<a>/vue-poc/api/components/tree</a>
</li>
<li>
<a>/vue-poc/api/data/users</a>
</li>
<li>
<a>/vue-poc/api/data/{$entity}</a>
</li>
<li>
<a>/vue-poc/api/edit</a>
</li>
<li>
<a>/vue-poc/api/eval/execute</a>
</li>
<li>
<a>/vue-poc/api/eval/imports</a>
</li>
<li>
<a>/vue-poc/api/eval/invoke</a>
</li>
<li>
<a>/vue-poc/api/eval/plan</a>
</li>
<li>
<a>/vue-poc/api/eval/result/{$id}</a>
</li>
<li>
<a>/vue-poc/api/eval/submit</a>
</li>
<li>
<a>/vue-poc/api/get</a>
</li>
<li>
<a>/vue-poc/api/get2</a>
</li>
<li>
<a>/vue-poc/api/history</a>
</li>
<li>
<a>/vue-poc/api/images/datetaken</a>
</li>
<li>
<a>/vue-poc/api/images/keywords2</a>
</li>
<li>
<a>/vue-poc/api/images/list</a>
</li>
<li>
<a>/vue-poc/api/images/list/{ $id }/image</a>
</li>
<li>
<a>/vue-poc/api/images/list/{ $id }/meta</a>
</li>
<li>
<a>/vue-poc/api/images/list/{$id}</a>
</li>
<li>
<a>/vue-poc/api/images/report</a>
</li>
<li>
<a>/vue-poc/api/job</a>
</li>
<li>
<a>/vue-poc/api/job/{$job}</a>
</li>
<li>
<a>/vue-poc/api/log</a>
</li>
<li>
<a>/vue-poc/api/log/add</a>
</li>
<li>
<a>/vue-poc/api/login-check</a>
</li>
<li>
<a>/vue-poc/api/logout</a>
</li>
<li>
<a>/vue-poc/api/ping</a>
</li>
<li>
<a>/vue-poc/api/repo</a>
</li>
<li>
<a>/vue-poc/api/search</a>
</li>
<li>
<a>/vue-poc/api/start</a>
</li>
<li>
<a>/vue-poc/api/status</a>
</li>
<li>
<a>/vue-poc/api/tasks</a>
</li>
<li>
<a>/vue-poc/api/tasks/model</a>
</li>
<li>
<a>/vue-poc/api/tasks/task</a>
</li>
<li>
<a>/vue-poc/api/tasks/vue-compile</a>
</li>
<li>
<a>/vue-poc/api/tasks/xqdoc</a>
</li>
<li>
<a>/vue-poc/api/tasks/{$task}</a>
</li>
<li>
<a>/vue-poc/api/test-select</a>
</li>
<li>
<a>/vue-poc/api/thumbnail</a>
</li>
<li>
<a>/vue-poc/api/thumbnail/images</a>
</li>
<li>
<a>/vue-poc/api/thumbnail/validate</a>
</li>
<li>
<a>/vue-poc/api/user</a>
</li>
<li>
<a>/vue-poc/api/validate</a>
</li>
<li>
<a>/vue-poc/api/xqdoc</a>
</li>
<li>
<a>/vue-poc/api/xslt</a>
</li>
<li>
<a>/vue-poc/ui</a>
</li>
<li>
<a>/vue-poc/ui/{$file=.+}</a>
</li>
<li>
<a>vue-poc/api/data/entity</a>
</li>
<li>
<a>vue-poc/api/data/entity/{$entity}</a>
</li>
<li>
<a>vue-poc/api/data/entity/{$entity}/field</a>
</li>
</ul>

View file

@ -0,0 +1,69 @@
(:~
: XQDoc: generate restxq.html from resources located at $target
:)
import module namespace xqd = 'quodatum:build.xqdoc' at "../../../lib/xqdoc/xqdoc-proj.xqm";
declare namespace c="http://www.w3.org/ns/xproc-step";
declare namespace xqdoc="http://www.xqdoc.org/1.0";
(:~ URL of the doc source
: @default C:/tmp/xqdoc/
:)
declare variable $target as xs:anyURI external :=
"C:/tmp/xqdoc/" cast as xs:anyURI;
declare variable $files :=doc(resolve-uri("files.xml",$target));
declare function local:foo($a,$k){
if($a) then map{"k":$k,"d":$a} else ()
};
let $base:=$files/*/@xml:base/string()
let $files:= $files//c:file
let $names:= $files!string-join(ancestor-or-self::*/@name,"/")
let $xqdocs:=$files!doc(resolve-uri(``[F`{ position() }`/xqdoc.xml]``,$target))
let $paths:= $xqdocs!local:foo(xqd:rxq(*),position())
let $items:=
for $annots in $paths
let $uri:=$annots?d/string()
group by $uri
order by $uri
return <li>
<h3>{ $uri }</h3>
<ol>{
for $annot in $annots
let $fun:=$annot?d/../..
let $funname:=concat($fun/xqdoc:name/string(),'#',$fun/@arity/string())
let $href:="F12/index.html#field-list"
return <li><a href="{$href}">{$funname}</a>{$annot?k}</li>
}</ol>
<a>{ $uri }</a>
</li>
return <div>
<nav id="toc">
<div>
<a href="index.html">
Index
</a>
</div>
<h2>
<a id="contents"></a>
<span class="namespace">
RestXQ
</span>
</h2>
<ol class="toc">
<li>
<a href="#main">
<span class="secno">1 </span>
<span class="content">Introduction</span>
</a>
</li>
</ol>
</nav>
<a href="index.html">index: { $base }</a>
<ul>{ $items }</ul>
</div>
=>xqd:page(map{"resources":"resources/"})
=>xqd:store(resolve-uri("restxq.html",$target),$xqd:HTML5)

View file

@ -9,17 +9,7 @@
><v-icon>play_circle_outline</v-icon>validate</v-btn> ><v-icon>play_circle_outline</v-icon>validate</v-btn>
<span v-text="elapsed">?</span>ms. <span v-text="elapsed">?</span>ms.
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn @click="$refs.params.clear()" :loading="loading"
:disabled="loading"
>Clear</v-btn>
<v-btn @click="$refs.params.reset()" :loading="loading"
:disabled="loading"
>Reset</v-btn>
<v-btn :loading="loading"
:disabled="loading"
>is ok?</v-btn>
<v-menu offset-y left> <v-menu offset-y left>
<v-btn icon slot="activator"><v-icon>settings</v-icon></v-btn> <v-btn icon slot="activator"><v-icon>settings</v-icon></v-btn>
<v-card > <v-card >

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<template id="websocket">
<v-container fluid>
<v-card>
<v-toolbar >
<v-toolbar-title>Web socket <a href="https://github.com/nathantsoi/vue-native-websocket">Git</a></v-toolbar-title>
<v-spacer></v-spacer>
<v-btn @click="send">Sent</v-btn>
</v-toolbar>
<v-card-text>
<p>web socket</p>
</v-card-text>
</v-card>
</v-container>
</template>
<script>{
data: function(){
return {
reply: null
}
},
methods:{
send(){
this.$socket.send('some data');
}
},
mounted: function(){
//this.$connect();
this.$options.sockets.onmessage = (data) => this.reply=data;
}
}</script>

View file

@ -20,6 +20,7 @@ let $vars:=$d/variable[@external="true"]
return <json type="object"> return <json type="object">
<description>{ $d/description/string() }</description> <description>{ $d/description/string() }</description>
<updating type="boolean" >{ $updating }</updating> <updating type="boolean" >{ $updating }</updating>
<url >{ $mod }</url>
<fields type="array">{ <fields type="array">{
$vars! $vars!
<_ type="object"> <_ type="object">
@ -45,24 +46,19 @@ as item()
default return $val default return $val
}; };
(:~ (:~
:@return map param->type : @return map of request parameter names typed
:) :)
declare function query-a:types($mod as xs:anyURI) declare
function query-a:params($mod as xs:anyURI)
as map(*) as map(*)
{ {
let $vars:=inspect:module($mod)/variable[@external="true"] let $vars:=inspect:module($mod)/variable[@external="true"]
return map:merge( return map:merge(
$vars!map:entry(@name/string(),@type/string()) $vars[@name=request:parameter-names()]!
) map:entry(@name,query-a:cast(request:parameter(@name/string()),@type))
};
declare
function query-a:params()
as map(*)
{
map:merge(
for $p in request:parameter-names() return map:entry($p,request:parameter($p))
) )
}; };
@ -70,20 +66,12 @@ declare
%updating %updating
function query-a:run($query as xs:anyURI,$params as map(*)) function query-a:run($query as xs:anyURI,$params as map(*))
{ {
let $types:=query-a:types($query) (
let $params:=query-a:map-with-key($params, <json type="object">
function($key,$val){ <res>{ xquery:invoke($query,$params)}</res>
switch($types($key)=>trace("CONV")) <params>todo</params>
case "xs:anyURI" return xs:anyURI($val) </json>=>update:output(),
default return $val hlog:save(<task url="{ $query }"/>)
}
)
return (
xquery:invoke($query,$params)=>update:output(),
hlog:save(<task url="{ $query }">
<params/>
</task>)
) )
}; };
@ -94,23 +82,3 @@ function query-a:update($query as xs:anyURI,$params as map(*))
xquery:invoke-update($query,$params) xquery:invoke-update($query,$params)
}; };
(:~
: Maps a function over all entries of the map <code>$map</code>.
: Each entry <code>($key, $value)</code> in the map is replaced by a new
: entry <code>($key, $f($key, $value))</code>, the keys are not touched.
:
: @param $f function to be applies to all entries
: @param $map input map
: @return copy of <code>$map</code> where all values <code>$value</code>
: are replaced by <code>$f($key, $value)</code>
:)
declare function query-a:map-with-key(
$map as map(*),
$f as function(item(), item()*) as item()*
) as map(*)
{
map:merge(
for $key in map:keys($map)
return map:entry($key, $f($key, $map($key)))
)
};

View file

@ -43,7 +43,7 @@
<xsl:value-of select="$project" /> ,id: <xsl:value-of select="$id" /> <xsl:value-of select="$project" /> ,id: <xsl:value-of select="$id" />
</h1> </h1>
<xsl:call-template name="toc" /> <xsl:call-template name="toc" />
<a href="restxq.html">RestXQ</a>
<div id="file"> <div id="file">
<h1>Files</h1> <h1>Files</h1>
<ul> <ul>

View file

@ -484,7 +484,7 @@
<xsl:sort select="lower-case(doc:name)" /> <xsl:sort select="lower-case(doc:name)" />
<xsl:variable name="id" select="current-grouping-key()" /> <xsl:variable name="id" select="current-grouping-key()" />
<li> <li>
<a href="#{$id}"> <a href="#{$id}#0">
<span class="secno"> <span class="secno">
<xsl:value-of select="concat('3.',position())" /> <xsl:value-of select="concat('3.',position())" />
</span> </span>

View file

@ -67,7 +67,9 @@ declare function xqd:gendoc(
) )
}; };
(:~ save, create fdolder if missing) :) (:~
:save $data to $url , create fdolder if missing)
:)
declare function xqd:store($data,$url as xs:string,$params as map(*)) declare function xqd:store($data,$url as xs:string,$params as map(*))
{ {
let $p:=file:parent($url) let $p:=file:parent($url)
@ -111,8 +113,55 @@ as document-node()
xslt:transform($files,$xqd:index-xslt,$params) xslt:transform($files,$xqd:index-xslt,$params)
}; };
(:~ export :) (:~ save runtime support files to $target :)
declare function xqd:export-resources($target as xs:string) declare function xqd:export-resources($target as xs:string)
{ {
archive:extract-to($target, file:read-binary(resolve-uri('resources.zip'))) archive:extract-to($target, file:read-binary(resolve-uri('resources.zip')))
}; };
(:~
: return all rest:path annotations
:)
declare function xqd:rxq($xqdoc as element(xqdoc:xqdoc))
as element(xqdoc:annotation)*
{
let $restxq:=$xqdoc//xqdoc:namespace[@uri='http://exquery.org/ns/restxq']/@prefix/string()
return $xqdoc//xqdoc:annotations/xqdoc:annotation[@name=(for $p in $restxq return concat($p,':path'))]
};
(:~
: generate standard page wrapper
:)
declare function xqd:page($body,$opts as map(*))
as element(html)
{
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Generator" content="xqdoc-r - https://github.com/quodatum/xqdoc-r" />
<title>
RestXQ - xqDoc
</title>
<link rel="shortcut icon" type="image/x-icon" href="{$opts?resources}xqdoc.png" />
<link rel="stylesheet" type="text/css" href="{$opts?resources}page.css" />
<link rel="stylesheet" type="text/css" href="{$opts?resources}query.css" />
<link rel="stylesheet" type="text/css" href="{$opts?resources}base.css" />
<link rel="stylesheet" type="text/css" href="{$opts?resources}prettify.css" />
<script src="{$opts?resources}prettify.js" type="text/javascript">&#160;</script>
<script src="{$opts?resources}lang-xq.js" type="text/javascript">&#160;</script>
</head>
<body class="home" id="top">
<div id="main">
{$body}
</div>
<div class="footer">
<p style="text-align:right">generated at {current-dateTime()}</p>
</div>
</body>
</html>
};

View file

@ -1,5 +1,5 @@
(: entity access maps (: entity access maps
: auto generated from xml files in entities folder at: 2018-07-31T22:46:52.921+01:00 : auto generated from xml files in entities folder at: 2018-08-14T21:11:56.357+01:00
:) :)
module namespace entity = 'quodatum.models.generated'; module namespace entity = 'quodatum.models.generated';

View file

@ -56,7 +56,7 @@
</field> </field>
--> -->
</fields> </fields>
<views iconclass="place"> <views iconclass="redeem">
<view name="filter">name description</view> <view name="filter">name description</view>
</views> </views>
<data type="element(ent:entity)">collection("vue-poc")//ent:entity</data> <data type="element(ent:entity)">collection("vue-poc")//ent:entity</data>

View file

@ -0,0 +1,23 @@
<entity name="task" xmlns="https://github.com/Quodatum/app-doc/entity">
<description>predefined queries with parameters </description>
<fields>
<field name="to" type="xs:string">
<description>name for task</description>
<xpath>@name</xpath>
</field>
<field name="url" type="xs:string">
<description>user</description>
<xpath>@url</xpath>
</field>
<field name="title" type="xs:string">
<description>title</description>
<xpath>title</xpath>
</field>
<field name="description" type="xs:string">
<description>task description</description>
<xpath>fn:serialize(description/node()</xpath>
</field>
</fields>
<views iconclass="update"/>
<data type="element(task)">doc("tasks/taskdef.xml")/tasks/task</data>
</entity>

View file

@ -82,7 +82,8 @@ const router = new VueRouter({
{ path: 'jobs', name:"jobs", component: Jobs, meta:{title:"Jobs running"} }, { path: 'jobs', name:"jobs", component: Jobs, meta:{title:"Jobs running"} },
{ path: 'jobs/:job', name:"jobShow", component: Job, props: true, meta:{title:"Job Status"} }, { path: 'jobs/:job', name:"jobShow", component: Job, props: true, meta:{title:"Job Status"} },
{ path: 'ping', component: Ping,meta:{title:"Ping"} } { path: 'ping', component: Ping,meta:{title:"Ping"} },
{ path: 'websocket', component: Websocket,meta:{title:"Web socket"} }
] ]
}, },
@ -128,7 +129,7 @@ router.beforeEach((to, from, next) => {
// this route requires auth, check if logged in // this route requires auth, check if logged in
// if not, redirect to login page. // if not, redirect to login page.
console.log("matched: ",Auth) console.log("matched: ",Auth)
if ("admin"!=Auth.permission) { if ("admin"!=Auth.role) {
next({ next({
path: '/login', path: '/login',
query: { redirect: to.fullPath } query: { redirect: to.fullPath }

View file

@ -1,4 +1,4 @@
// generated 2018-07-31T23:44:22.364+01:00 // generated 2018-08-15T17:56:05.102+01:00
// src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/qd-autoheight.vue // src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/qd-autoheight.vue
Vue.component('qd-autoheight',{template:` Vue.component('qd-autoheight',{template:`
@ -482,7 +482,7 @@ Vue.component('vp-job',{template:`
// src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/vp-notifications.vue // src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/vp-notifications.vue
Vue.component('vp-notifications',{template:` Vue.component('vp-notifications',{template:`
<v-card> <v-card>
<v-toolbar class="amber white--text" scroll-toolbar-off-screen=""> <v-toolbar class="amber white--text" scroll-off-screen="">
<v-toolbar-title>Notifications </v-toolbar-title> <v-toolbar-title>Notifications </v-toolbar-title>
{{ $notification.nextId }} {{ $notification.nextId }}
<v-btn @click="refresh" icon=""><v-icon>refresh</v-icon></v-btn> <v-btn @click="refresh" icon=""><v-icon>refresh</v-icon></v-btn>
@ -547,17 +547,31 @@ Vue.component('vp-notifications',{template:`
Vue.component('vp-paramform',{template:` Vue.component('vp-paramform',{template:`
<v-form ref="form" lazy-validation=""> <v-form ref="form" lazy-validation="">
<div class="title">{{ description }}</div> <div class="title">{{ description }}</div>
<div :title="url">{{ updating }}</div>
<v-layout row="">
<v-layout column="" xs10="">
<v-flex v-for="field in fields" :key="field.model"> <v-flex v-for="field in fields" :key="field.model">
<v-text-field v-if="field.type === 'xs:anyURI'" xs10="" v-model="params[field.model]" :label="field.label" clearable="" :rules="fieldrules(field)" box="" append-outer-icon="send" @click:append-outer="source(field)"></v-text-field> <v-text-field v-if="field.type === 'xs:anyURI'" :full-width="true" v-model="params[field.model]" :label="field.label" clearable="" :rules="fieldrules(field)" box="" append-outer-icon="send" @click:append-outer="source(field)"></v-text-field>
<v-switch v-else-if="field.type === 'xs:boolean'" xs10="" :label="field.label" v-model="params[field.model]"> <v-switch v-else-if="field.type === 'xs:boolean'" :full-width="true" :label="field.label" v-model="params[field.model]">
</v-switch> </v-switch>
<v-text-field v-else="" xs10="" amber="" v-model="params[field.model]" :label="field.type" clearable="" box=""></v-text-field> <v-text-field v-else="" :full-width="true" amber="" v-model="params[field.model]" :label="field.type" clearable="" box=""></v-text-field>
</v-flex>
</v-flex>
<v-flex>
</v-flex>
</v-layout>
<v-layout align-center="" justify-center="" column="" fill-height="" xs2="" amber="" lighten-5="">
<v-btn @click="clear()">Clear</v-btn>
<v-btn @click="reset()">Reset</v-btn>
</v-layout>
</v-layout>
</v-form> </v-form>
`, `,
@ -567,6 +581,8 @@ Vue.component('vp-paramform',{template:`
fields: [], fields: [],
params: null, params: null,
description: null, description: null,
updating: false,
url: null,
rules: { rules: {
required: value => !!value || 'Required.' required: value => !!value || 'Required.'
} }
@ -576,8 +592,10 @@ Vue.component('vp-paramform',{template:`
reset(){ reset(){
HTTP.get(this.endpoint) HTTP.get(this.endpoint)
.then(r=>{ .then(r=>{
this.fields=r.data.fields; this.fields= r.data.fields;
this.description=r.data.description; this.description= r.data.description;
this.updating= r.data.updating;
this.url= r.data.url;
this.params = Object.assign({}, this.params, r.data.values); this.params = Object.assign({}, this.params, r.data.values);
}) })
}, },
@ -861,10 +879,10 @@ Vue.component('vue-ace',{template:`
// src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/auth.js // src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/auth.js
// Authorization Object // Authorization Object
const Auth={ const Auth={
user:"guest", user: "guest",
permission:null, role: null,
session:null, session: null,
created:null, created: null,
install: function(Vue){ install: function(Vue){
Object.defineProperty(Vue.prototype, '$auth', { Object.defineProperty(Vue.prototype, '$auth', {
get () { return Auth } get () { return Auth }
@ -872,7 +890,7 @@ const Auth={
}, },
logout(){ logout(){
Auth.user="guest"; Auth.user="guest";
Auth.permission=null; Auth.role=null;
} }
}; };
Vue.use(Auth); Vue.use(Auth);
@ -3931,7 +3949,7 @@ const Login=Vue.extend({template:`
<v-card class="grey lighten-4 elevation-0"> <v-card class="grey lighten-4 elevation-0">
<v-card-title class="amber "> <v-card-title class="amber ">
<span class="white--text">Please login as user with permission is required</span> <span class="white--text">The current identity is not permissioned to access this page, please login again</span>
</v-card-title> </v-card-title>
<v-alert color="error" v-bind:value="showMessage"> <v-alert color="error" v-bind:value="showMessage">
{{message}} {{message}}
@ -3944,7 +3962,6 @@ const Login=Vue.extend({template:`
<v-text-field name="input-password" label="Password" hint="Enter your password" v-model="password" :append-icon="hidepass ? 'visibility' : 'visibility_off'" @click:append="() => (hidepass = !hidepass)" :type="hidepass ? 'password' : 'text'" required=""></v-text-field> <v-text-field name="input-password" label="Password" hint="Enter your password" v-model="password" :append-icon="hidepass ? 'visibility' : 'visibility_off'" @click:append="() => (hidepass = !hidepass)" :type="hidepass ? 'password' : 'text'" required=""></v-text-field>
</v-card-actions> </v-card-actions>
<v-divider></v-divider>
<v-card-actions> <v-card-actions>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn color="primary" @click="go()">Continue</v-btn> <v-btn color="primary" @click="go()">Continue</v-btn>
@ -4098,7 +4115,7 @@ const Entity=Vue.extend({template:`
methods:{ methods:{
getItems(){ getItems(){
this.loading=true this.loading=true
HTTP.get("data/entity",{params:this.q}) HTTP.get("data/entity",{params:{q:this.q}})
.then(r=>{ .then(r=>{
this.loading=false this.loading=false
//console.log(r.data) //console.log(r.data)
@ -4131,7 +4148,12 @@ const Entity1=Vue.extend({template:`
</v-breadcrumbs-item> </v-breadcrumbs-item>
<v-breadcrumbs-item> <v-breadcrumbs-item>
<v-chip>
<v-avatar>
<v-icon>{{ item.iconclass }}</v-icon>
</v-avatar>
{{ entity }} {{ entity }}
</v-chip>
</v-breadcrumbs-item> </v-breadcrumbs-item>
</v-breadcrumbs> </v-breadcrumbs>
</v-toolbar-title> </v-toolbar-title>
@ -4142,9 +4164,12 @@ const Entity1=Vue.extend({template:`
</v-toolbar> </v-toolbar>
<v-container fluid="" grid-list-md=""> <v-container fluid="" grid-list-md="">
<div v-if="item">
<div>{{item.description}}</div>
<code>{{item.code}}</code>
</div>
<pre>{{ xml }}</pre> <pre>{{ xml }}</pre>
</v-container> </v-container>
</v-card> </v-card>
`, `,
@ -4152,8 +4177,10 @@ const Entity1=Vue.extend({template:`
props: ['entity'], props: ['entity'],
data: function(){ data: function(){
return { return {
q: 'filter', item: {description:null,
item: {}, code: null
},
loading: false, loading: false,
xml: null xml: null
} }
@ -4161,16 +4188,14 @@ const Entity1=Vue.extend({template:`
methods:{ methods:{
getItem(){ getItem(){
this.loading=true this.loading=true
HTTP.get("data/entity/"+this.entity,{params:this.q}) HTTP.get("data/entity/"+this.entity)
.then(r=>{ .then(r=>{
this.loading=false this.loading=false
//console.log(r.data) this.item=Object.assign({}, this.item, r.data)
//var items=r.data.items.filter(item=>{return item.text!="[GET] http://localhost:8984/vue-poc/api/log"})
this.item=r.data.items
}) })
}, },
getxml(){ getxml(){
HTTP.get("data/entity/"+this.entity,{params:this.q, headers: {Accept: "text/xml"}}) HTTP.get("data/entity/"+this.entity,{ headers: {Accept: "text/xml"}})
.then(r=>{ .then(r=>{
console.log(r.data) console.log(r.data)
this.xml=r.data; this.xml=r.data;
@ -4672,11 +4697,10 @@ const Ping=Vue.extend({template:`
<v-card-text> <v-card-text>
<p>Read or increment a database value. This measures round trip times browser-database-browser.</p> <p>Read or increment a database value. This measures round trip times browser-database-browser.</p>
<h3>Counter: <v-chip color="amber" text-color="white">{{counter}}</v-chip></h3> <h3>Counter: <v-chip color="amber" text-color="white">{{counter}}</v-chip></h3>
<table> <table class="v-table">
<thead> <thead>
<tr> <tr>
<th xs1="">Action</th> <th xs1="">Action</th>
<th xs1="">Once</th>
<th xs1="">Repeat</th> <th xs1="">Repeat</th>
<th xs1="">Last</th> <th xs1="">Last</th>
<th xs1="">Count</th> <th xs1="">Count</th>
@ -4690,10 +4714,9 @@ const Ping=Vue.extend({template:`
<tr> <tr>
<td>Get</td>
<td> <td>
<v-btn @click="get()" icon=""> <v-btn @click="get()">
<v-icon>radio_button_checked</v-icon> Read <v-icon>compare_arrows</v-icon>
</v-btn> </v-btn>
</td> </td>
@ -4724,10 +4747,9 @@ const Ping=Vue.extend({template:`
</tr> </tr>
<tr> <tr>
<td>Update</td>
<td> <td>
<v-btn @click="update()" icon=""> <v-btn @click="update()">
<v-icon>radio_button_checked</v-icon> Write <v-icon>compare_arrows</v-icon>
</v-btn> </v-btn>
</td> </td>
@ -5212,6 +5234,9 @@ const Runtask=Vue.extend({template:`
</v-breadcrumbs> </v-breadcrumbs>
</v-toolbar-title> </v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn color="primary" @click="submit()" :loading="loading" :disabled="loading">
<v-icon>play_circle_outline</v-icon>
Run</v-btn>
</v-toolbar> </v-toolbar>
<v-card-text> <v-card-text>
@ -5225,14 +5250,6 @@ const Runtask=Vue.extend({template:`
</v-container> </v-container>
</v-card-text> </v-card-text>
<v-toolbar>
<v-btn @click="$refs.params.clear()" :loading="loading" :disabled="loading">Clear</v-btn>
<v-btn @click="$refs.params.reset()" :loading="loading" :disabled="loading">Reset</v-btn>
<v-spacer></v-spacer>
<v-btn color="primary" @click="submit()" :loading="loading" :disabled="loading">
<v-icon>play_circle_outline</v-icon>
Run</v-btn>
</v-toolbar>
<v-snackbar v-model="snackbar.show" :timeout="6000" :success="snackbar.context === 'success'" :error="snackbar.context === 'error'"> <v-snackbar v-model="snackbar.show" :timeout="6000" :success="snackbar.context === 'success'" :error="snackbar.context === 'error'">
{{ snackbar.msg }} {{ snackbar.msg }}
<v-btn dark="" flat="" @click="snackbar.show = false">Close</v-btn> <v-btn dark="" flat="" @click="snackbar.show = false">Close</v-btn>
@ -5288,16 +5305,21 @@ const Task=Vue.extend({template:`
<v-text-field prepend-icon="filter_list" label="Filter..." v-model="q" type="search" hide-details="" single-line="" @keyup.enter="setfilter" clearable=""></v-text-field> <v-text-field prepend-icon="filter_list" label="Filter..." v-model="q" type="search" hide-details="" single-line="" @keyup.enter="setfilter" clearable=""></v-text-field>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<vp-entitylink entity="namespace"></vp-entitylink> <vp-entitylink entity="task"></vp-entitylink>
</v-toolbar> </v-toolbar>
<v-card-text> <v-card-text>
<ul> <v-data-table :headers="headers" :items="items" hide-actions="" :search="q" class="elevation-1">
<li v-for="task in tasks" :key="task.to"> <template slot="items" slot-scope="props">
<router-link :to="'tasks/' + task.to" v-text="task.title"></router-link> <td><router-link :to="'tasks/' + props.item.to" v-text="props.item.title"></router-link></td>
<div v-html="task.description"></div> <td>{{ props.item.description }}</td>
</li> </template>
</ul> <template slot="no-data">
<v-alert :value="true" icon="warning">
No matching items.
</v-alert>
</template>
</v-data-table>
</v-card-text> </v-card-text>
</v-card> </v-card>
@ -5307,9 +5329,13 @@ const Task=Vue.extend({template:`
data(){ data(){
return { return {
tasks: [], items: [],
loading: false, loading: false,
q: null q: null,
headers: [
{ text: 'Task', value: 'title' },
{ text: 'Description', value: 'description' },
]
} }
}, },
methods:{ methods:{
@ -5317,7 +5343,7 @@ const Task=Vue.extend({template:`
this.loading= true; this.loading= true;
HTTP.get("tasks") HTTP.get("tasks")
.then(r=>{ .then(r=>{
this.tasks=r.data; this.items=r.data;
this.loading= false; this.loading= false;
}) })
} }
@ -5647,11 +5673,7 @@ const Validate=Vue.extend({template:`
<v-btn @click="submit" :loading="loading" :disabled="false"><v-icon>play_circle_outline</v-icon>validate</v-btn> <v-btn @click="submit" :loading="loading" :disabled="false"><v-icon>play_circle_outline</v-icon>validate</v-btn>
<span v-text="elapsed">?</span>ms. <span v-text="elapsed">?</span>ms.
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn @click="$refs.params.clear()" :loading="loading" :disabled="loading">Clear</v-btn>
<v-btn @click="$refs.params.reset()" :loading="loading" :disabled="loading">Reset</v-btn>
<v-btn :loading="loading" :disabled="loading">is ok?</v-btn>
<v-menu offset-y="" left=""> <v-menu offset-y="" left="">
<v-btn icon="" slot="activator"><v-icon>settings</v-icon></v-btn> <v-btn icon="" slot="activator"><v-icon>settings</v-icon></v-btn>
<v-card> <v-card>
@ -5735,6 +5757,43 @@ const Validate=Vue.extend({template:`
); );
// src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/features/websocket/websocket.vue
const Websocket=Vue.extend({template:`
<v-container fluid="">
<v-card>
<v-toolbar>
<v-toolbar-title>Web socket <a href="https://github.com/nathantsoi/vue-native-websocket">Git</a></v-toolbar-title>
<v-spacer></v-spacer>
<v-btn @click="send">Sent</v-btn>
</v-toolbar>
<v-card-text>
<p>web socket</p>
</v-card-text>
</v-card>
</v-container>
`,
data: function(){
return {
reply: null
}
},
methods:{
send(){
this.$socket.send('some data');
}
},
mounted: function(){
//this.$connect();
this.$options.sockets.onmessage = (data) => this.reply=data;
}
}
);
// src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/features/xqdoc/xqdoc.vue // src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/features/xqdoc/xqdoc.vue
const Xqdoc2=Vue.extend({template:` const Xqdoc2=Vue.extend({template:`
<v-container fluid="" v-resize="onResize"> <v-container fluid="" v-resize="onResize">
@ -6009,7 +6068,8 @@ const router = new VueRouter({
{ path: 'jobs', name:"jobs", component: Jobs, meta:{title:"Jobs running"} }, { path: 'jobs', name:"jobs", component: Jobs, meta:{title:"Jobs running"} },
{ path: 'jobs/:job', name:"jobShow", component: Job, props: true, meta:{title:"Job Status"} }, { path: 'jobs/:job', name:"jobShow", component: Job, props: true, meta:{title:"Job Status"} },
{ path: 'ping', component: Ping,meta:{title:"Ping"} } { path: 'ping', component: Ping,meta:{title:"Ping"} },
{ path: 'websocket', component: Websocket,meta:{title:"Web socket"} }
] ]
}, },
@ -6055,7 +6115,7 @@ router.beforeEach((to, from, next) => {
// this route requires auth, check if logged in // this route requires auth, check if logged in
// if not, redirect to login page. // if not, redirect to login page.
console.log("matched: ",Auth) console.log("matched: ",Auth)
if ("admin"!=Auth.permission) { if ("admin"!=Auth.role) {
next({ next({
path: '/login', path: '/login',
query: { redirect: to.fullPath } query: { redirect: to.fullPath }
@ -6221,6 +6281,7 @@ const Vuepoc=Vue.extend({template:`
{href: '/server/logs',text: 'Server logs',icon: 'dns'}, {href: '/server/logs',text: 'Server logs',icon: 'dns'},
{href: '/server/users',text: 'Users',icon: 'supervisor_account'}, {href: '/server/users',text: 'Users',icon: 'supervisor_account'},
{href: '/server/repo',text: 'Server code repository',icon: 'local_library'}, {href: '/server/repo',text: 'Server code repository',icon: 'local_library'},
{href: '/server/websocket',text: 'Web socket',icon: 'swap_calls'},
{href: '/server/ping',text: 'Ping',icon: 'update'} {href: '/server/ping',text: 'Ping',icon: 'update'}
]}, ]},
{ {
@ -6524,6 +6585,9 @@ function install (Vue) {
Vue.component('vue-form-json-schema', VueFormJsonSchema); Vue.component('vue-form-json-schema', VueFormJsonSchema);
}; };
Vue.use({ install: install }); Vue.use({ install: install });
var sockhost=('https:'==window.location.protocol?'wss:':'ws:')+'//'+ window.location.host +'/ws';
Vue.use(VueNativeSock.default, sockhost);
console.log("SOCK UP",VueNativeSock,sockhost);
//leaflet //leaflet
//Vue.component('v-map', Vue2Leaflet.Map); //Vue.component('v-map', Vue2Leaflet.Map);

View file

@ -11,7 +11,7 @@
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"/> <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="//fonts.googleapis.com/icon?family=Material+Icons"/>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"/> <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
<link href="//unpkg.com/vuetify@1.1.9/dist/vuetify.min.css" rel="stylesheet" type="text/css"/> <link href="//unpkg.com/vuetify@1.1.12/dist/vuetify.min.css" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="//unpkg.com/@riophae/vue-treeselect@0.0.29/dist/vue-treeselect.min.css"> <link rel="stylesheet" href="//unpkg.com/@riophae/vue-treeselect@0.0.29/dist/vue-treeselect.min.css">
<link rel="stylesheet" href="//unpkg.com/vue-form-generator@2.2.2/dist/vfg-core.css"/> <link rel="stylesheet" href="//unpkg.com/vue-form-generator@2.2.2/dist/vfg-core.css"/>
<link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css"/> <link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css"/>
@ -38,10 +38,10 @@
<script src="//cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.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@1.1.9/dist/vuetify.min.js" crossorigin="anonymous"></script> <script src="//unpkg.com/vuetify@1.1.12/dist/vuetify.min.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ace.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ext-language_tools.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ext-language_tools.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ext-linking.js" type="text/javascript" charset="utf-8"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ext-linking.js" type="text/javascript" charset="utf-8"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify-css.js" crossorigin="anonymous"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.12/beautify-css.js" crossorigin="anonymous"></script>
@ -56,7 +56,7 @@
<script src="//unpkg.com/vue-form-generator@2.2.2/dist/vfg-core.js" crossorigin="anonymous"></script> <script src="//unpkg.com/vue-form-generator@2.2.2/dist/vfg-core.js" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue-json-schema@1.1.1/dist/vue-json-schema.js" crossorigin="anonymous"></script> <script src="//unpkg.com/vue-json-schema@1.1.1/dist/vue-json-schema.js" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue-form-json-schema@1.15.3/dist/vue-form-json-schema.umd.js" crossorigin="anonymous"></script> <script src="//unpkg.com/vue-form-json-schema@1.15.3/dist/vue-form-json-schema.umd.js" crossorigin="anonymous"></script>
<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/svg/d3-svg.js"></script>
<script src="/vue-poc/ui/perf-stat.js"></script> <script src="/vue-poc/ui/perf-stat.js"></script>
<script src="/vue-poc/ui/app-gen.js"></script> <script src="/vue-poc/ui/app-gen.js"></script>

View file

@ -1,204 +1,36 @@
"use strict"; "use strict";
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.2.0/workbox-sw.js'); importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js');
if (workbox) { if (workbox) {
console.log(`Yay! Workbox is loaded 🎉`); console.log(`Yay! Workbox is loaded 🎉`);
workbox.setConfig({
debug: false
});
//Shows logs, warnings and errors.
workbox.core.setLogLevel(workbox.core.LOG_LEVELS.log);
workbox.core.setCacheNameDetails({
prefix: 'vue-poc',
suffix: 'v1',
precache: 'install-time',
runtime: 'run-time',
googleAnalytics: 'ga',
});
workbox.routing.registerRoute(
new RegExp('/vue-poc/api/'),
workbox.strategies.networkOnly()
);
workbox.routing.registerRoute(
new RegExp('.*'),
workbox.strategies.staleWhileRevalidate()
);
} else { } else {
console.log(`Boo! Workbox didn't load 😬`); console.log(`Boo! Workbox didn't load 😬`);
}; };
console.log('WORKER: executing.');
/* A version number is useful when updating the worker logic,
allowing you to remove outdated cache entries during the update.
*/
var version = 'v0:4:';
/* These resources will be downloaded and cached by the service worker
during the installation process. If any resource fails to be downloaded,
then the service worker won't be installed either.
*/
var offlineFundamentals = [
'prof-stat.js',
'//cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js'
];
/* The install event fires when the service worker is first installed.
You can use this event to prepare the service worker to be able to serve
files while visitors are offline.
*/
self.addEventListener("install", function(event) {
console.log('WORKER: install event in progress.');
/* Using event.waitUntil(p) blocks the installation process on the provided
promise. If the promise is rejected, the service worker won't be installed.
*/
event.waitUntil(
/* The caches built-in is a promise-based API that helps you cache responses,
as well as finding and deleting them.
*/
caches
/* You can open a cache by name, and this method returns a promise. We use
a versioned cache name here so that we can remove old cache entries in
one fell swoop later, when phasing out an older service worker.
*/
.open(version + 'fundamentals')
.then(function(cache) {
/* After the cache is opened, we can fill it with the offline fundamentals.
The method below will add all resources in `offlineFundamentals` to the
cache, after making requests for them.
*/
return cache.addAll(offlineFundamentals);
})
.then(function() {
console.log('WORKER: install completed');
})
);
});
/* The fetch event fires whenever a page controlled by this service worker requests
a resource. This isn't limited to `fetch` or even XMLHttpRequest. Instead, it
comprehends even the request for the HTML page on first load, as well as JS and
CSS resources, fonts, any images, etc.
*/
self.addEventListener("fetch", function(event) {
console.log('WORKER: fetch event in progress.');
/* We should only cache GET requests, and deal with the rest of method in the
client-side, by handling failed POST,PUT,PATCH,etc. requests.
*/
if (event.request.method !== 'GET') {
/* If we don't block the event as shown below, then the request will go to
the network as usual.
*/
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
/* Similar to event.waitUntil in that it blocks the fetch event on a promise.
Fulfillment result will be used as the response, and rejection will end in a
HTTP response indicating failure.
*/
event.respondWith(
caches
/* This method returns a promise that resolves to a cache entry matching
the request. Once the promise is settled, we can then provide a response
to the fetch request.
*/
.match(event.request)
.then(function(cached) {
/* Even if the response is in our cache, we go to the network as well.
This pattern is known for producing "eventually fresh" responses,
where we return cached responses immediately, and meanwhile pull
a network response and store that in the cache.
Read more:
https://ponyfoo.com/articles/progressive-networking-serviceworker
*/
var networked = fetch(event.request)
// We handle the network request with success and failure scenarios.
.then(fetchedFromNetwork, unableToResolve)
// We should catch errors on the fetchedFromNetwork handler as well.
.catch(unableToResolve);
/* We return the cached response immediately if there is one, and fall
back to waiting on the network as usual.
*/
console.log('WORKER: fetch event', cached ? '(cached)' : '(network)', event.request.url);
return cached || networked;
function fetchedFromNetwork(response) {
/* We copy the response before replying to the network request.
This is the response that will be stored on the ServiceWorker cache.
*/
var cacheCopy = response.clone();
console.log('WORKER: fetch response from network.', event.request.url);
caches
// We open a cache to store the response for this request.
.open(version + 'pages')
.then(function add(cache) {
/* We store the response for this request. It'll later become
available to caches.match(event.request) calls, when looking
for cached responses.
*/
return cache.put(event.request, cacheCopy);
})
.then(function() {
console.log('WORKER: fetch response stored in cache.', event.request.url);
});
// Return the response so that the promise is settled in fulfillment.
return response;
}
/* When this method is called, it means we were unable to produce a response
from either the cache or the network. This is our opportunity to produce
a meaningful response even when all else fails. It's the last chance, so
you probably want to display a "Service Unavailable" view or a generic
error response.
*/
function unableToResolve () {
/* There's a couple of things we can do here.
- Test the Accept header and then return one of the `offlineFundamentals`
e.g: `return caches.match('/some/cached/image.png')`
- You should also consider the origin. It's easier to decide what
"unavailable" means for requests against your origins than for requests
against a third party, such as an ad provider.
- Generate a Response programmaticaly, as shown below, and return that.
*/
console.log('WORKER: fetch request failed in both cache and network.');
/* Here we're creating a response programmatically. The first parameter is the
response body, and the second one defines the options for the response.
*/
return new Response('<h1>Service Unavailable</h1>', {
status: 503,
statusText: 'Service Unavailable',
headers: new Headers({
'Content-Type': 'text/html'
})
});
}
})
);
});
/* The activate event fires after a service worker has been successfully installed.
It is most useful when phasing out an older version of a service worker, as at
this point you know that the new worker was installed correctly. In this example,
we delete old caches that don't match the version in the worker we just finished
installing.
*/
self.addEventListener("activate", function(event) {
/* Just like with the install event, event.waitUntil blocks activate on a promise.
Activation will fail unless the promise is fulfilled.
*/
console.log('WORKER: activate event in progress.');
event.waitUntil(
caches
/* This method returns a promise which will resolve to an array of available
cache keys.
*/
.keys()
.then(function (keys) {
// We return a promise that settles when all outdated caches are deleted.
return Promise.all(
keys
.filter(function (key) {
// Filter by keys that don't start with the latest version prefix.
return !key.startsWith(version);
})
.map(function (key) {
/* Return a promise that's fulfilled
when each outdated cache is deleted.
*/
return caches.delete(key);
})
);
})
.then(function() {
console.log('WORKER: activate completed.');
})
);
});