diff --git a/src/vue-poc/app.vue b/src/vue-poc/app.vue index ce49a61..11d4dfc 100644 --- a/src/vue-poc/app.vue +++ b/src/vue-poc/app.vue @@ -160,6 +160,7 @@ {href: '/server/logs',text: 'Server logs',icon: 'dns'}, {href: '/server/users',text: 'Users',icon: 'supervisor_account'}, {href: '/server/repo',text: 'Server code repository',icon: 'local_library'}, + {href: '/server/websocket',text: 'Web socket',icon: 'swap_calls'}, {href: '/server/ping',text: 'Ping',icon: 'update'} ]}, { diff --git a/src/vue-poc/components/auth.js b/src/vue-poc/components/auth.js index 9e21250..91972e4 100644 --- a/src/vue-poc/components/auth.js +++ b/src/vue-poc/components/auth.js @@ -1,9 +1,9 @@ // Authorization Object const Auth={ - user:"guest", - permission:null, - session:null, - created:null, + user: "guest", + role: null, + session: null, + created: null, install: function(Vue){ Object.defineProperty(Vue.prototype, '$auth', { get () { return Auth } @@ -11,7 +11,7 @@ const Auth={ }, logout(){ Auth.user="guest"; - Auth.permission=null; + Auth.role=null; } }; Vue.use(Auth); diff --git a/src/vue-poc/components/vp-notifications.vue b/src/vue-poc/components/vp-notifications.vue index 0ef618f..ad6be67 100644 --- a/src/vue-poc/components/vp-notifications.vue +++ b/src/vue-poc/components/vp-notifications.vue @@ -4,7 +4,7 @@ --> @@ -37,8 +45,10 @@ props: ['entity'], data: function(){ return { - q: 'filter', - item: {}, + item: {description:null, + code: null + }, + loading: false, xml: null } @@ -46,16 +56,14 @@ methods:{ getItem(){ this.loading=true - HTTP.get("data/entity/"+this.entity,{params:this.q}) + HTTP.get("data/entity/"+this.entity) .then(r=>{ this.loading=false - //console.log(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 + this.item=Object.assign({}, this.item, r.data) }) }, 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=>{ console.log(r.data) this.xml=r.data; diff --git a/src/vue-poc/features/server/ping.vue b/src/vue-poc/features/server/ping.vue index 710751d..a89169a 100644 --- a/src/vue-poc/features/server/ping.vue +++ b/src/vue-poc/features/server/ping.vue @@ -10,11 +10,10 @@

Read or increment a database value. This measures round trip times browser-database-browser.

Counter: {{counter}}

- +
- @@ -28,10 +27,9 @@ - @@ -62,10 +60,9 @@ - diff --git a/src/vue-poc/features/tasks/model.build/rxq-model.xqm b/src/vue-poc/features/tasks/model.build/rxq-model.xqm index 19c1d68..1b8ab56 100644 --- a/src/vue-poc/features/tasks/model.build/rxq-model.xqm +++ b/src/vue-poc/features/tasks/model.build/rxq-model.xqm @@ -20,7 +20,8 @@ declare %updating 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)) }; (:~ diff --git a/src/vue-poc/features/tasks/model.build/tx-model.xq b/src/vue-poc/features/tasks/model.build/tx-model.xq index 1cdd2ff..49d4d28 100644 --- a/src/vue-poc/features/tasks/model.build/tx-model.xq +++ b/src/vue-poc/features/tasks/model.build/tx-model.xq @@ -8,13 +8,15 @@ import module namespace bf = 'quodatum.tools.buildfields' at "./../../../lib/ent : Folder containing model definitions as xml : @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 : @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";' diff --git a/src/vue-poc/features/tasks/rxq-tasks.xqm b/src/vue-poc/features/tasks/rxq-tasks.xqm index a8c83dd..6aed142 100644 --- a/src/vue-poc/features/tasks/rxq-tasks.xqm +++ b/src/vue-poc/features/tasks/rxq-tasks.xqm @@ -53,6 +53,8 @@ function vue-rest:runtask($task) let $task:=doc("taskdef.xml")/tasks/task[@name=$task] let $url:=resolve-uri($task/@url) - return query-a:run($url,query-a:params()) + return ( + query-a:run($url,query-a:params($url)), + }; \ No newline at end of file diff --git a/src/vue-poc/features/tasks/task/task.vue b/src/vue-poc/features/tasks/task/task.vue index eebc602..aab12ac 100644 --- a/src/vue-poc/features/tasks/task/task.vue +++ b/src/vue-poc/features/tasks/task/task.vue @@ -15,6 +15,10 @@ + + play_circle_outline + Run @@ -28,19 +32,6 @@ - - Clear - Reset - - - play_circle_outline - Run - Generate documentation for folder - - XQdoc to db - Generate XQdoc to save + + XQdoc rest + XQdoc... diff --git a/src/vue-poc/features/tasks/tasks.vue b/src/vue-poc/features/tasks/tasks.vue index 7829469..236efa8 100644 --- a/src/vue-poc/features/tasks/tasks.vue +++ b/src/vue-poc/features/tasks/tasks.vue @@ -18,17 +18,28 @@ clearable> - + - - -
    -
  • - -
    -
  • -
-
+ + + + + + + @@ -38,9 +49,13 @@ diff --git a/src/vue-poc/lib/query-a.xqm b/src/vue-poc/lib/query-a.xqm index ff5f22b..e41d59e 100644 --- a/src/vue-poc/lib/query-a.xqm +++ b/src/vue-poc/lib/query-a.xqm @@ -19,7 +19,8 @@ let $d:=inspect:module($mod) let $vars:=$d/variable[@external="true"] return { $d/description/string() } - { $updating } + { $updating } + { $mod } { $vars! <_ type="object"> @@ -45,46 +46,33 @@ as item() default return $val }; -(:~ - :@return map param->type -:) -declare function query-a:types($mod as xs:anyURI) + +(:~ + : @return map of request parameter names typed + :) +declare +function query-a:params($mod as xs:anyURI) as map(*) { let $vars:=inspect:module($mod)/variable[@external="true"] 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)) ) }; declare %updating 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, - function($key,$val){ - switch($types($key)=>trace("CONV")) - case "xs:anyURI" return xs:anyURI($val) - default return $val - } +{ + ( + + { xquery:invoke($query,$params)} + todo + =>update:output(), + hlog:save() ) - - return ( - xquery:invoke($query,$params)=>update:output(), - hlog:save( - - ) - ) }; declare @@ -94,23 +82,3 @@ function query-a:update($query as xs:anyURI,$params as map(*)) xquery:invoke-update($query,$params) }; -(:~ - : Maps a function over all entries of the map $map. - : Each entry ($key, $value) in the map is replaced by a new - : entry ($key, $f($key, $value)), the keys are not touched. - : - : @param $f function to be applies to all entries - : @param $map input map - : @return copy of $map where all values $value - : are replaced by $f($key, $value) - :) -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))) - ) -}; diff --git a/src/vue-poc/lib/xqdoc/html-index.xsl b/src/vue-poc/lib/xqdoc/html-index.xsl index fe0cfb8..3589782 100644 --- a/src/vue-poc/lib/xqdoc/html-index.xsl +++ b/src/vue-poc/lib/xqdoc/html-index.xsl @@ -43,7 +43,7 @@ ,id: - + RestXQ

Files

ActionOnce Repeat Last Count
Get - - radio_button_checked + + Read compare_arrows
Update - - radio_button_checked + + Write compare_arrows
+
- @@ -4690,10 +4714,9 @@ const Ping=Vue.extend({template:` - @@ -4724,10 +4747,9 @@ const Ping=Vue.extend({template:` - @@ -5212,6 +5234,9 @@ const Runtask=Vue.extend({template:` + + play_circle_outline + Run @@ -5225,14 +5250,6 @@ const Runtask=Vue.extend({template:` - - Clear - Reset - - - play_circle_outline - Run - {{ snackbar.msg }} Close @@ -5288,17 +5305,22 @@ const Task=Vue.extend({template:` - + - - -
    -
  • - -
    -
  • -
-
+ + + + + + + @@ -5307,9 +5329,13 @@ const Task=Vue.extend({template:` data(){ return { - tasks: [], + items: [], loading: false, - q: null + q: null, + headers: [ + { text: 'Task', value: 'title' }, + { text: 'Description', value: 'description' }, + ] } }, methods:{ @@ -5317,7 +5343,7 @@ const Task=Vue.extend({template:` this.loading= true; HTTP.get("tasks") .then(r=>{ - this.tasks=r.data; + this.items=r.data; this.loading= false; }) } @@ -5647,11 +5673,7 @@ const Validate=Vue.extend({template:` play_circle_outlinevalidate ?ms. - Clear - Reset - - - is ok? + settings @@ -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:` + + + + Web socket
Git + + Sent + + +

web socket

+
+ + + + `, + + 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 const Xqdoc2=Vue.extend({template:` @@ -6009,7 +6068,8 @@ const router = new VueRouter({ { path: 'jobs', name:"jobs", component: Jobs, meta:{title:"Jobs running"} }, { 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 // if not, redirect to login page. console.log("matched: ",Auth) - if ("admin"!=Auth.permission) { + if ("admin"!=Auth.role) { next({ path: '/login', query: { redirect: to.fullPath } @@ -6221,6 +6281,7 @@ const Vuepoc=Vue.extend({template:` {href: '/server/logs',text: 'Server logs',icon: 'dns'}, {href: '/server/users',text: 'Users',icon: 'supervisor_account'}, {href: '/server/repo',text: 'Server code repository',icon: 'local_library'}, + {href: '/server/websocket',text: 'Web socket',icon: 'swap_calls'}, {href: '/server/ping',text: 'Ping',icon: 'update'} ]}, { @@ -6524,6 +6585,9 @@ function install (Vue) { Vue.component('vue-form-json-schema', VueFormJsonSchema); }; 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 //Vue.component('v-map', Vue2Leaflet.Map); diff --git a/src/vue-poc/static/app.html b/src/vue-poc/static/app.html index 270e52e..86ee8e2 100644 --- a/src/vue-poc/static/app.html +++ b/src/vue-poc/static/app.html @@ -11,7 +11,7 @@ - + @@ -38,10 +38,10 @@ - - - - + + + + @@ -56,7 +56,7 @@ - + diff --git a/src/vue-poc/static/serviceworker.js b/src/vue-poc/static/serviceworker.js index 74a4433..253dd76 100644 --- a/src/vue-poc/static/serviceworker.js +++ b/src/vue-poc/static/serviceworker.js @@ -1,204 +1,36 @@ "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) { 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 { 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('

Service Unavailable

', { - 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.'); - }) - ); -});
ActionOnce Repeat Last Count
Get - - radio_button_checked + + Read compare_arrows
Update - - radio_button_checked + + Write compare_arrows