vuetify 0.13.0

This commit is contained in:
Andy Bunce 2017-07-05 23:05:34 +01:00
parent 06c70e13d9
commit 8d841ad7cb
45 changed files with 1317 additions and 977 deletions

View file

@ -1,5 +1,5 @@
WARNING=DO NOT MODIFY THIS FILE IF YOU DON'T UNDERSTAND WARNING=DO NOT MODIFY THIS FILE IF YOU DON'T UNDERSTAND
defaultDestination=C\:/Program Files (x86)/basex/webapp defaultDestination=C\:/Users/andy/Desktop/basex.865b/webapp
defaultVariables= defaultVariables=
eclipse.preferences.version=1 eclipse.preferences.version=1
includeTeamPrivateFiles=false includeTeamPrivateFiles=false

View file

@ -58,8 +58,8 @@ Vue.component('nav-list', {
</v-flex> </v-flex>
</v-layout> </v-layout>
<v-list-group v-else-if="item.children" v-model="item.model" no-action> <v-list-group v-else-if="item.children" v-model="item.model" no-action>
<v-list-item slot="item">
<v-list-tile :href="item.href" router ripple> <v-list-tile slot="item" :href="item.href" router ripple>
<v-list-tile-action> <v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon> <v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action> </v-list-tile-action>
@ -74,12 +74,9 @@ Vue.component('nav-list', {
</v-list-tile-content> </v-list-tile-content>
</v-list-tile> </v-list-tile>
</v-list-item>
<v-list-item <template v-for="(child, i) in item.children">
v-for="(child, i) in item.children" <v-list-tile :key="i" :href="child.href" router ripple>
:key="i"
>
<v-list-tile :href="child.href" router ripple>
<v-list-tile-action v-if="child.icon"> <v-list-tile-action v-if="child.icon">
<v-icon>{{ child.icon }}</v-icon> <v-icon>{{ child.icon }}</v-icon>
</v-list-tile-action> </v-list-tile-action>
@ -89,10 +86,10 @@ Vue.component('nav-list', {
</v-list-tile-title> </v-list-tile-title>
</v-list-tile-content> </v-list-tile-content>
</v-list-tile> </v-list-tile>
</v-list-item> </template>
</v-list-group> </v-list-group>
<v-list-item v-else>
<v-list-tile :href="item.href" router ripple> <v-list-tile v-else :href="item.href" router ripple>
<v-list-tile-action> <v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon> <v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action> </v-list-tile-action>
@ -102,7 +99,6 @@ Vue.component('nav-list', {
</v-list-tile-title> </v-list-tile-title>
</v-list-tile-content> </v-list-tile-content>
</v-list-tile> </v-list-tile>
</v-list-item>
</template> </template>
</v-list>`, </v-list>`,
created:function(){ created:function(){
@ -178,16 +174,16 @@ const app = new Vue({
{href: 'files', text: 'File system',icon: 'folder' }, {href: 'files', text: 'File system',icon: 'folder' },
{href: 'edit',text: 'edit',icon: 'mode_edit'}, {href: 'edit',text: 'edit',icon: 'mode_edit'},
{href: 'history',text: 'history',icon: 'history'}, {href: 'history',text: 'history',icon: 'history'},
{href: 'logs',text: 'Server logs',icon: 'dns'}
]}, ]},
{ {
icon: 'directions_run', icon: 'directions_run',
text: 'Actions' , text: 'Actions' ,
model: false, model: false,
children: [ children: [
{href: 'eval',text: 'Evaluate',icon: 'cake'}, {href: 'eval',text: 'Evaluate',icon: 'play_circle_outline'},
{href: 'tasks',text: 'Tasks',icon: 'build'}, {href: 'jobs',text: 'Jobs',icon: 'dashboard'},
{href: 'jobs',text: 'Jobs',icon: 'print'}, {href: 'tasks',text: 'Tasks',icon: 'history'},
{href: 'logs',text: 'Server logs',icon: 'dns'}
]}, ]},
{ {
icon: 'more_horiz', icon: 'more_horiz',

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<template id="my-component">
<a :href="href" :target="href" > {{href}}<v-icon>link</v-icon></a>
</template>
<script>{
props: ['href'],
created:function(){
console.log("my-component");
}
}
</script>

View file

@ -0,0 +1,76 @@
<!DOCTYPE html>
<template id="nav-list">
<v-list dense>
<template v-for="(item, i) in items">
<v-layout
row
v-if="item.heading"
align-center
:key="i"
>
<v-flex xs6>
<v-subheader v-if="item.heading">
{{ item.heading }}
</v-subheader>
</v-flex>
<v-flex xs6 class="text-xs-center">
<a href="#!" class="body-2 black--text">EDIT</a>
</v-flex>
</v-layout>
<v-list-group v-else-if="item.children" v-model="item.model" no-action>
<v-list-tile :href="item.href" router ripple slot="item">
<v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-title>
{{ item.text }}
</v-list-tile-title>
<v-spacer></v-spacer>
<v-list-tile-action>
<v-icon>{{ item.model ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
</v-list-tile-content>
</v-list-tile>
<template
v-for="(child, i) in item.children"
:key="i"
>
<v-list-tile :href="child.href" router ripple>
<v-list-tile-action v-if="child.icon">
<v-icon>{{ child.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>
{{ child.text }}
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
</v-list-group>
<v-list-tile v-else :href="item.href" router ripple>
<v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>
{{ item.text }}
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
</v-list>
</template>
<script>{
props: ['items'],
created:function(){
console.log("nav-lst");
}
}
</script>

View file

@ -2,7 +2,7 @@
abbrev="vue-poc" version="0.0.3" spec="1.0"> abbrev="vue-poc" version="0.0.3" spec="1.0">
<title>vue-poc test of vue.js.</title> <title>vue-poc test of vue.js.</title>
<dependency name="ace" version="1.2.7" /> <dependency name="ace" version="1.2.7" />
<dependency name="vuetify" version="0.12.5" /> <dependency name="vuetify" version="0.13.0" />
<dependency name="vue" version="2.3.4" /> <dependency name="vue" version="2.3.4" />
<dependency name="vue-router" version="2.5.3" /> <dependency name="vue-router" version="2.5.3" />
<dependency name="google-material" version="0.0.0" /> <dependency name="google-material" version="0.0.0" />

View file

@ -0,0 +1,85 @@
(:~
: vue-poc collection api.
:
: @author Andy Bunce july-2017
:)
module namespace vue-api = 'quodatum:vue.api.collection';
import module namespace rest = "http://exquery.org/ns/restxq";
import module namespace fw="quodatum:file.walker";
import module namespace ufile = 'vue-poc/file' at "../../lib/file.xqm";
declare namespace c="http://www.w3.org/ns/xproc-step";
(:~
: history list
:)
declare
%rest:GET %rest:path("/vue-poc/api/history")
%rest:produces("application/json")
%output:method("json")
function vue-api:history( )
{
let $h:=(
'/vue-poc/vue-poc.xqm',
'/vue-poc/data/vue-poc/ch4d1.xml',
'/vue-poc/static/app-gen.js',
'/vue-poc/static/app.html',
'/vue-poc/static/app.css',
'/vue-poc/logo.svg',
'/vue-poc/static/resources/sparql.rq',
'/vue-poc/static/resources/turtle.ttl'
)
return <json type="object" >
<items type="array">
{$h!(<_ type="object"><url>{.}</url></_>)}
</items>
</json>
};
(:~
: Returns folder info.
:)
declare
%rest:path("/vue-poc/api/file")
%rest:query-param("url", "{$url}")
%rest:produces("application/json")
%output:method("json")
function vue-api:file($url as xs:string)
{
let $path := ufile:web( $url)=>trace("vue-api:web ")
return if( file:exists($path))then
let $items:=fw:directory-list($path,map{"max-depth":1,"include-info":true()})
return <json type="object" >
<folders type="array">
{for $f in $items/c:directory
order by $f/@name/lower-case(.)
return <_ type="object">
{vue-api:details($f,"folder")}
</_>
}
</folders>
<files type="array">
{for $f in $items/c:file
order by $f/@name/lower-case(.)
return <_ type="object">
{vue-api:details($f,"insert_drive_file")}
</_>
}
</files>
</json>
else
error(xs:QName('vue-api:raw'),$path)
};
declare function vue-api:details($f as element(*),$icon as xs:string)
as element(*)*
{
<name>{$f/@name/string()}</name>
,<icon>{$icon}</icon>
,<modified>{$f/@last-modified/string()}</modified>
,<size type="number">{$f/@size/string()}</size>
,<mime>unknown</mime>
};

View file

@ -3,32 +3,31 @@
<v-container fluid> <v-container fluid>
<v-card> <v-card>
<v-card-row class="green white--text"> <v-toolbar>
<v-menu bottom right> <v-menu bottom right>
<v-btn icon dark slot="activator"><v-icon >folder</v-icon></v-btn> <v-btn icon dark slot="activator"><v-icon >folder</v-icon></v-btn>
<v-list> <v-list>
<v-list-item v-for="item in crumbs" :key="item"> <template v-for="item in crumbs">
<v-list-tile> <v-list-tile :key="item">
<v-list-tile-title @click="root()">{{ item }}</v-list-tile-title> <v-list-tile-title @click="root()">{{ item }}</v-list-tile-title>
</v-list-tile> </v-list-tile>
</v-list-item> </template>
</v-list> </v-list>
</v-menu> </v-menu>
<v-toolbar-title>{{ url }}</v-toolbar-title> <v-toolbar-title>{{ url }}</v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-text-field prepend-icon="search" label="Filter..." v-model="q" type="search" <v-text-field prepend-icon="search" label="Filter..." v-model="q" type="search"
hide-details single-line dark @keyup.native.enter="filter"></v-text-field> hide-details single-line dark @keyup.native.enter="filter"></v-text-field>
<v-icon>view_module</v-icon> <v-icon>view_module</v-icon>
</v-card-row> </v-toolbar>
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear> <v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
<v-list v-if="!busy" two-line subheader> <v-list v-if="!busy" two-line subheader>
<v-subheader inset>Folders</v-subheader> <v-subheader inset>Folders</v-subheader>
<v-list-item v-for="item in folders" v-bind:key="item.name" @click="folder(item.name)"> <template v-for="item in folders">
<v-list-tile avatar > <v-list-tile v-bind:key="item.name" @click="folder(item.name)" avatar >
<v-list-tile-avatar > <v-list-tile-avatar >
<v-icon v-bind:class="[item.iconClass]">{{ item.icon }}</v-icon> <v-icon v-bind:class="[item.iconClass]">{{ item.icon }}</v-icon>
</v-list-tile-avatar> </v-list-tile-avatar>
@ -42,11 +41,12 @@
</v-btn> </v-btn>
</v-list-tile-action> </v-list-tile-action>
</v-list-tile> </v-list-tile>
</v-list-item> </template>
<v-divider inset></v-divider> <v-divider inset></v-divider>
<v-subheader inset>Files</v-subheader> <v-subheader inset>Files</v-subheader>
<v-list-item v-for="item in files" v-bind:key="item.name" @click="file(item.name)"> <template v-for="item in folders">
<v-list-tile> <v-list-tile v-bind:key="item.name" @click="file(item.name)">
<v-list-tile-avatar> <v-list-tile-avatar>
<v-icon v-bind:class="[item.iconClass]">{{ item.icon }}</v-icon> <v-icon v-bind:class="[item.iconClass]">{{ item.icon }}</v-icon>
</v-list-tile-avatar> </v-list-tile-avatar>
@ -60,10 +60,12 @@
</v-btn> </v-btn>
</v-list-tile-action> </v-list-tile-action>
</v-list-tile> </v-list-tile>
</v-list-item> </template>
</v-list> </v-list>
<v-navigation-drawer right light temporary v-model="infodraw" <v-navigation-drawer right light temporary v-model="infodraw"
>Some info here {{selected}}</v-navigation-drawer> > <v-card> <v-card-title class="green white--text">
Some info here {{selected}} </v-card-title> <v-card-text> blah blah </v-card-text> </v-card>
</v-navigation-drawer>
</v-card> </v-card>
</v-container> </v-container>
</template> </template>

View file

@ -2,20 +2,17 @@
<template id="history"> <template id="history">
<v-container fluid> <v-container fluid>
<v-list> <v-list>
<v-list-item v-for="item in items" v-bind:key="item.title" <v-list-tile v-for="item in items" v-bind:key="item.title" @click="doEdit(item.url)" avatar>
@click="doEdit(item.url)">
<v-list-tile avatar>
<v-list-tile-action> <v-list-tile-action>
<v-icon v-if="item.icon" class="pink--text">star</v-icon> <v-icon v-if="item.icon" class="pink--text">star</v-icon>
</v-list-tile-action> </v-list-tile-action>
<v-list-tile-content> <v-list-tile-content>
<v-list-tile-title v-text="item.url"></v-list-tile-title> <v-list-tile-title @click="doEdit(item.url)" v-text="item.url"></v-list-tile-title>
</v-list-tile-content> </v-list-tile-content>
<v-list-tile-avatar> <v-list-tile-avatar>
<img v-bind:src="item.avatar"/> <img v-bind:src="item.avatar"/>
</v-list-tile-avatar> </v-list-tile-avatar>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
</v-container> </v-container>
</template> </template>

View file

@ -7,15 +7,13 @@
</v-snackbar> </v-snackbar>
<v-card> <v-card>
<v-app-bar> <v-toolbar class="grey lighten-2 black--text">
<v-menu offset-y> <v-menu >
<v-btn primary icon dark slot="activator" v-tooltip:top="{ html: path.join('/') }"><v-icon >folder</v-icon></v-btn> <v-btn primary icon dark slot="activator" v-tooltip:top="{ html: path.join('/') }"><v-icon >folder</v-icon></v-btn>
<v-list> <v-list>
<v-list-item v-for="item in path" :key="item"> <v-list-tile v-for="item in path" :key="item" @click="showfiles()">
<v-list-tile> <v-list-tile-title >{{ item }}</v-list-tile-title>
<v-list-tile-title @click="showfiles()">{{ item }}</v-list-tile-title>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
</v-menu> </v-menu>
@ -66,23 +64,19 @@
<v-icon>help</v-icon> <v-icon>help</v-icon>
</v-btn> </v-btn>
<v-list> <v-list>
<v-list-item @click="acecmd('showSettingsMenu')"> <v-list-tile @click="acecmd('showSettingsMenu')" avatar >
<v-list-tile avatar >
<v-list-tile-avatar> <v-list-tile-avatar>
<v-icon >settings</v-icon> <v-icon >settings</v-icon>
</v-list-tile-avatar> </v-list-tile-avatar>
<v-list-tile-title >Show settings</v-list-tile-title> <v-list-tile-title >Show settings</v-list-tile-title>
</v-list-tile> </v-list-tile>
</v-list-item>
<v-list-item @click="acecmd('showKeyboardShortcuts')"> <v-list-tile @click="acecmd('showKeyboardShortcuts')" avatar>
<v-list-tile avatar>
<v-list-tile-avatar> <v-list-tile-avatar>
<v-icon >keyboard</v-icon> <v-icon >keyboard</v-icon>
</v-list-tile-avatar> </v-list-tile-avatar>
<v-list-tile-title >Show keyboard commands</v-list-tile-title> <v-list-tile-title >Show keyboard commands</v-list-tile-title>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
</v-menu> </v-menu>
<v-menu left transition="v-fade-transition"> <v-menu left transition="v-fade-transition">
@ -91,40 +85,34 @@
</v-btn> </v-btn>
<v-list> <v-list>
<v-list-item >
<v-list-tile> <v-list-tile>
<v-list-tile-title >unused</v-list-tile-title> <v-list-tile-title >unused</v-list-tile-title>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
</v-menu> </v-menu>
</v-toolbar-items> </v-toolbar-items>
<v-dialog v-model="clearDialog" > <v-dialog v-model="clearDialog" >
<v-card> <v-card>
<v-card-row>
<v-card-title>Clear?</v-card-title> <v-card-title>Clear?</v-card-title>
</v-card-row>
<v-card-row>
<v-card-text>clear text.</v-card-text> <v-card-text>clear text.</v-card-text>
</v-card-row> <v-card-actions>
<v-card-row actions>
<v-btn class="green--text darken-1" flat="flat" @click.native="reset(false)">Cancel</v-btn> <v-btn class="green--text darken-1" flat="flat" @click.native="reset(false)">Cancel</v-btn>
<v-btn class="green--text darken-1" flat="flat" @click.native="reset(true)">Ok</v-btn> <v-btn class="green--text darken-1" flat="flat" @click.native="reset(true)">Ok</v-btn>
</v-card-row> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
</v-app-bar> </v-toolbar>
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear> <v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
<v-card-text v-if="!busy">
<v-flex xs12 style="height:70vh" v-if="!busy" fill-height> <v-flex xs12 style="height:70vh" fill-height>
<vue-ace :content="contentA" :mode="mode" :wrap="wrap" <vue-ace :content="contentA" :mode="mode" :wrap="wrap"
v-on:change-content="changeContentA" v-on:change-content="changeContentA"
v-on:annotation="annotation"></vue-ace> v-on:annotation="annotation"></vue-ace>
</v-flex> </v-flex>
</v-card-text>
</v-card> </v-card>
</v-container> </v-container>
@ -156,7 +144,8 @@ v-on:annotation="annotation"></vue-ace>
"application/sparql-query":"sparql", "application/sparql-query":"sparql",
"text/html":"html", "text/html":"html",
"text/turtle":"turtle", "text/turtle":"turtle",
"text/css":"css" "text/css":"css",
"image/svg+xml":"svg"
} }
} }
}, },
@ -225,6 +214,7 @@ v-on:annotation="annotation"></vue-ace>
var a=this.contentA var a=this.contentA
switch(this.mode) { switch(this.mode) {
case "html": case "html":
case "svg":
case "xml": case "xml":
a=html_beautify(a, { indent_size: 3 ,indent_inner_html:true}) a=html_beautify(a, { indent_size: 3 ,indent_inner_html:true})
break; break;

View file

@ -0,0 +1,62 @@
(:~
: vue-poc api.
:
: @author Andy Bunce may-2017
:)
module namespace vue-api = 'quodatum:vue.api';
import module namespace rest = "http://exquery.org/ns/restxq";
import module namespace session = "http://basex.org/modules/session";
import module namespace ufile = 'vue-poc/file' at "../../lib/file.xqm";
import module namespace mt = 'quodatum.data.mimetype' at "../../lib/mimetype.xqm";
declare namespace c="http://www.w3.org/ns/xproc-step";
(:~
: Returns a file content.
:)
declare
%rest:GET %rest:path("/vue-poc/api/edit")
%rest:query-param("url", "{$url}")
%rest:produces("application/json")
%output:method("json")
function vue-api:edit-get($url as xs:string)
{
let $path := ufile:web( $url)=>trace("path ")
return if( file:exists($path))then
let $type:=mt:type($path)
let $fetch:=mt:fetch-fn($type("treat-as"))
return <json type="object" >
<url>{$url}</url>
<mimetype>{$type?type}</mimetype>
<data>{$fetch($path)}</data>
</json>
else
error(xs:QName('vue-api:raw'),$path)
};
(:~
: Update a file content. @TODO
:)
declare
%rest:POST %rest:path("/vue-poc/api/edit")
%rest:form-param("url", "{$url}")
%rest:form-param("data", "{$data}")
%rest:produces("application/json")
%output:method("json")
function vue-api:edit-post($url as xs:string,$data)
{
let $path := ufile:web( $url)=>trace("path ")
let $data:=trace($data)
return if( file:exists($path))then
let $type:=mt:type($path)
let $fetch:=mt:fetch-fn($type("treat-as"))
return <json type="object" >
<url>{$url}</url>
<mimetype>{$type?type}</mimetype>
<data>{$fetch($path)}</data>
</json>
else
error(xs:QName('vue-api:raw'),$path)
};

View file

@ -0,0 +1,139 @@
<!DOCTYPE html>
<template id="eval">
<v-container fluid>
<v-card class="grey lighten-1 z-depth-1 mb-5">
<v-app-bar>
<v-btn @click.native="run()">Run</v-btn>
<v-btn @click.native="submit()">
<v-icon>play_circle_outline</v-icon>
Submit</v-btn>
<v-btn-dropdown v-bind:options="dropdown_font" max-height="auto" overflow></v-btn-dropdown>
</v-app-bar>
<v-card-text >
<v-flex xs12 style="height:200px" fill-height>
<vue-ace :content="xq" mode="xquery" wrap="true"
v-on:change-content="onChange"
></vue-ace>
</v-flex>
</v-card-text>
<v-alert error v-bind:value="showError">
{{result}}
</v-alert>
<v-card-actions v-if="show" >
JobId:
<v-chip class="green white--text">{{jobId}}</v-chip>
<v-progress-circular v-if="waiting" indeterminate class="primary--text"></v-progress-circular>
Elapsed:
<v-chip class="green white--text">{{elapsed}}</v-chip>
<v-spacer></v-spacer>
<v-btn flat class="green--text darken-1">@TODO</v-btn>
</v-card-actions>
<v-card-text v-if="show">
<v-flex xs12 style="height:200px" fill-height>
<vue-ace :content="result" mode="text" wrap="true" read-only="true"
></vue-ace>
</v-flex>
</v-card-text>
</v-card>
</v-container>
</template>
<script>{
data: function(){
return {
xq: '(: type your XQuery :)\n',
result:'',
elapsed:null,
show:false,
showError:false,
jobId:null,
waiting:false,
start:null,
dropdown_font: [
{ text: 'Arial' },
{ text: 'Calibri' },
{ text: 'Courier' },
{ text: 'Verdana' }
]
}
},
methods:{
onChange(val){
if (this.xq !== val) {
this.xq = val
}
},
run(){
var data={xq:this.xq}
this.showError=this.show=false
this.start = performance.now();
HTTP.post("eval/execute",Qs.stringify(data))
.then(r=>{
this.elapsed=Math.floor(performance.now() - this.start);
this.result=r.data.result
this.jobId=null
this.show=true
})
.catch(r=> {
console.log("error",r)
this.result=r.response.data
this.showError=true;
});
localforage.setItem('eval/xq', this.xq)
},
submit(){
var data={xq:this.xq}
this.showError=this.show=false
this.start = performance.now();
HTTP.post("eval/submit",Qs.stringify(data))
.then(r=>{
this.elapsed=Math.floor(performance.now() - this.start);
this.result=this.jobId=r.data.job
this.show=true
this.pollState()
})
.catch(r=> {
console.log("error",r)
this.jobId=r.response.job
this.showError=true;
});
},
pollState(){
this.waiting=true;
HTTP.get("job/"+this.jobId)
.then(r=>{
this.waiting=r.data.state!="cached";
this.elapsed=Math.floor(performance.now() - this.start);
if(this.waiting) {
setTimeout(()=>{ this.pollState() }, 5000);
}else{
this.getResult()
}
})
},
getResult(){
HTTP.post("eval/result/"+this.jobId)
.then(r=>{
this.result=r.data.result
this.jobId=null
this.show=true
})
}
},
created:function(){
localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq});
}
}
</script>

View file

@ -41,3 +41,28 @@ function vue-api:submit($xq )
<job>{$r}</job> <job>{$r}</job>
</json> </json>
}; };
(:~
: imports
:)
declare
%rest:GET %rest:path("/vue-poc/api/eval/imports")
%output:method("json")
function vue-api:imports( )
{
let $n:='import module namespace fw="quodatum:file.walker";'
return <json type="array" >
<_>{$n}</_>
</json>
};
declare
%rest:POST %rest:path('/vue-poc/api/eval/result/{$id}')
%output:method("json")
function vue-api:result($id)
{
let $r:=jobs:result($id)
return <json type="object" >
<result>{util:display($r)}</result>
</json>
};

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<template id="home"> <v-layout class="ma-5"> <v-flex
xs4> <v-card hover raised> <v-card-title
height="200px" class="pa-5 green lighten-1">
<div class="display-1 white--text text-xs-center">VUE-POC</div>
v0.0.2 </v-card-title> </v-card> </v-flex> <v-flex xs4>
<p>
This is a experiment in using
<code>vue.js</code>
.
</p>
<ul>
<li><a href="https://vuetifyjs.com/vuetify/quick-start"
target="new">vuetifyjs</a></li>
<li><a href="https://github.com/monterail/vue-multiselect"
target="new">vue-multiselect</a></li>
<li><a href="https://github.com/sagalbot/vue-select" target="new"><s>vue-select</s></a></li>
<li><a href="https://github.com/beautify-web/js-beautify"
target="new">js-beautify</a></li>
<li><a href="/doc/#/data/app/vue-poc" target="new">doc</a></li>
<li><a href="/dba" target="new">DBA app</a></li>
</ul>
</v-flex> <v-btn floating="floating"> <v-icon>add</v-icon> </v-btn> <my-component
href="/dba">REPLACED</my-component> </v-layout> </template>
<script>
{
}
</script>

View file

@ -0,0 +1,107 @@
<!DOCTYPE html>
<template id="job">
<v-card >
<v-toolbar class="green white--text">
<v-btn
light icon
:loading="loading"
@click.native="getJobs()"
:disabled="loading"
>
<v-icon>refresh</v-icon>
</v-btn>
<v-btn
@click.native="stop()"
:disabled="noSelection"
>Stop</v-btn>
<v-spacer></v-spacer>
<v-text-field
append-icon="search"
label="Search"
single-line
hide-details
v-model="search"
></v-text-field>
</v-toolbar>
<v-data-table
:headers="headers"
:items="items"
:search="search"
v-model="selected"
select-all
class="elevation-1"
no-data-text="No Jobs currently running"
>
<template slot="items" scope="props">
<td>
<v-checkbox
primary
hide-details
v-model="props.selected"
></v-checkbox>
</td>
<td>{{ props.item.id }}</td>
<td class="text-xs-right">{{ props.item.state }}</td>
<td class="text-xs-right">{{ props.item.duration }}</td>
<td class="text-xs-right">{{ props.item.type }}</td>
<td class="text-xs-right">{{ props.item.user }}</td>
<td ><code>{{ props.item.text }}</code></td>
</template>
</v-data-table>
</v-card>
</template>
<script>{
data: function(){
return {
headers: [
{
text: 'Job id',
left: true,
value: 'id'
},
{ text: 'State', value: 'state' },
{ text: 'Duration', value: 'duration' },
{ text: 'Type', value: 'type' },
{ text: 'User', value: 'user' },
{ text: 'Query', value: 'text' }
],
items:[
],
selected:[],
search:"",
loading:false
}
},
methods:{
getJobs(){
this.loading=true;
HTTP.get("job")
.then(r=>{
this.loading=false
this.items=r.data
setTimeout(()=>{ this.getJobs() }, 10000);
})
},
stop(){
var s=this.selected.map((j)=>{return j.id}).join(",")
console.log("AAA",this.selected)
alert(s)
}
},
computed: {
// a computed getter
noSelection: function () {
// `this` points to the vm instance
return this.selected.length==0
}
},
created(){
this.getJobs()
}
}
</script>

View file

@ -0,0 +1,46 @@
module namespace j = 'quodatum.test.jobs';
(:~
: job list
:)
declare
%rest:GET %rest:path("/vue-poc/api/job")
%output:method("json")
function j:list()
as element(json)
{
let $jlist:=jobs:list()[. != jobs:current()] !jobs:list-details(.)
return <json type="array">
{for $j in reverse($jlist)
return <_ type="object">
{j:job-json($j)}
</_>
}</json>
};
(:~
: job info
:)
declare
%rest:GET %rest:path("/vue-poc/api/job/{$job}")
%output:method("json")
function j:job($job)
as element(json)
{
let $j:=jobs:list-details($job)
return <json type="object">
{j:job-json($j)}
</json>
};
declare function j:job-json($j)
as element(*)*
{
<id>{$j/@id/string()}</id>
,<type>{$j/@type/string()}</type>
,<state>{$j/@state/string()}</state>
,<user>{$j/@user/string()}</user>
,<duration>{$j/@duration/string()}</duration>
,<text>{$j/string()}</text>
};

View file

@ -2,15 +2,13 @@
<template id="login"> <template id="login">
<v-card class="grey lighten-4 elevation-0"> <v-card class="grey lighten-4 elevation-0">
<v-card-row class="green darken-1"> <v-card-title class="green darken-1">
<v-card-title>
<span class="white--text">Login</span> <span class="white--text">Login</span>
</v-card-title> </v-card-title>
</v-card-row>
<v-alert error v-bind:value="showMessage"> <v-alert error v-bind:value="showMessage">
{{message}} {{message}}
</v-alert> </v-alert>
<v-card-row> <v-card-actions>
<v-text-field <v-text-field
name="input-name" name="input-name"
label="Enter your name" label="Enter your name"
@ -18,9 +16,9 @@
v-model="name" v-model="name"
required required
></v-text-field> ></v-text-field>
</v-card-row> </v-card-actions>
<v-card-row> <v-card-actions>
<v-text-field <v-text-field
name="input-password" name="input-password"
label="Enter your password" label="Enter your password"
@ -31,13 +29,13 @@
:type="hidepass ? 'password' : 'text'" :type="hidepass ? 'password' : 'text'"
required required
></v-text-field> ></v-text-field>
</v-card-row> </v-card-actions>
<v-divider></v-divider> <v-divider></v-divider>
<v-card-row actions class="blue-grey darken-1 mt-0"> <v-card-actions class="blue-grey darken-1 mt-0">
<v-btn primary @click.native="go()">Continue</v-btn> <v-btn primary @click.native="go()">Continue</v-btn>
<v-spacer></v-spacer> <v-spacer></v-spacer>
</v-card-row> </v-card-actions>
</v-card> </v-card>
</template> </template>

View file

@ -3,20 +3,18 @@
<v-layout > <v-layout >
<v-flex xs2> <v-flex xs2>
<v-card class="blue darken-4 white--text"> <v-card class="blue darken-4 white--text">
<v-card-row height="200px"> <v-card-title height="200px">
<v-card-title>
Featured Event: <br> Featured Event: <br>
May 24, 2016 <br> May 24, 2016 <br>
7-11pm 7-11pm
</v-card-title> </v-card-title>
</v-card-row> <v-card-actions>
<v-card-row actions>
<v-btn flat class="white--text" @click.native="snackbar = true" >Add to <br>Calendar</v-btn> <v-btn flat class="white--text" @click.native="snackbar = true" >Add to <br>Calendar</v-btn>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn icon dark @click.native="snackbar = true" > <v-btn icon dark @click.native="snackbar = true" >
<v-icon>event</v-icon> <v-icon>event</v-icon>
</v-btn> </v-btn>
</v-card-row> </v-card-actions>
</v-card> </v-card>
</v-flex> </v-flex>
@ -28,7 +26,7 @@
</v-flex> </v-flex>
<v-flex xs4> <v-flex xs4>
<v-card-row img="music.jpg" height="300px"></v-card-row> <v-card-media img="music.jpg" height="300px"></v-card-media>
<v-btn block primary @click.native="snackbar = true" dark>Show Snackbar</v-btn> <v-btn block primary @click.native="snackbar = true" dark>Show Snackbar</v-btn>
<v-btn class="white--text" @click.native="snackbar = true">Snackbar?</v-btn> <v-btn class="white--text" @click.native="snackbar = true">Snackbar?</v-btn>
</v-flex> </v-flex>

View file

@ -14,10 +14,10 @@
</v-card> </v-card>
<v-layout> <v-layout>
<v-flex xs5> <v-flex xs5>
<v-card-row img="resources/music.jpg" height="300px"></v-card-row> <v-card-media src="resources/music.jpg" height="300px"></v-card-media>
</v-flex> </v-flex>
<v-flex xs1> <v-flex xs1>
<v-card-row :img="img" height="60px"></v-card-row> <v-card-media :src="img" height="60px"></v-card-media>
</v-flex> </v-flex>
</v-layout> </v-layout>
</v-container> </v-container>

View file

@ -2,12 +2,11 @@
<template id="select"> <template id="select">
<v-container fluid> <v-container fluid>
<v-card> <v-card>
<v-card-row class="green darken-1">
<v-card-title> <v-card-title class="green darken-1">
<span class="white--text">Selection</span> <span class="white--text">Selection</span>
</v-card-title> </v-card-title>
</v-card-row>
<v-card-text> <v-card-text>
<v-layout> <v-layout>

View file

@ -6,7 +6,7 @@
<v-list two-line subheader> <v-list two-line subheader>
<v-subheader>Ace editor settings</v-subheader> <v-subheader>Ace editor settings</v-subheader>
<v-list-item>
<v-list-tile avatar> <v-list-tile avatar>
<v-list-tile-action> <v-list-tile-action>
<v-checkbox v-model="ace.enableSnippets"></v-checkbox> <v-checkbox v-model="ace.enableSnippets"></v-checkbox>
@ -16,8 +16,7 @@
<v-list-tile-sub-title>Allow snippets</v-list-tile-sub-title> <v-list-tile-sub-title>Allow snippets</v-list-tile-sub-title>
</v-list-tile-content> </v-list-tile-content>
</v-list-tile> </v-list-tile>
</v-list-item>
<v-list-item>
<v-list-tile avatar> <v-list-tile avatar>
<v-list-tile-action> <v-list-tile-action>
<v-checkbox v-model="ace.enableBasicAutocompletion"></v-checkbox> <v-checkbox v-model="ace.enableBasicAutocompletion"></v-checkbox>
@ -27,8 +26,7 @@
<v-list-tile-sub-title>enableBasicAutocompletion</v-list-tile-sub-title> <v-list-tile-sub-title>enableBasicAutocompletion</v-list-tile-sub-title>
</v-list-tile-content> </v-list-tile-content>
</v-list-tile> </v-list-tile>
</v-list-item>
<v-list-item>
<v-list-tile avatar> <v-list-tile avatar>
<v-list-tile-action> <v-list-tile-action>
<v-checkbox v-model="ace.enableLiveAutocompletion"></v-checkbox> <v-checkbox v-model="ace.enableLiveAutocompletion"></v-checkbox>
@ -38,7 +36,6 @@
<v-list-tile-sub-title>enableLiveAutocompletion</v-list-tile-sub-title> <v-list-tile-sub-title>enableLiveAutocompletion</v-list-tile-sub-title>
</v-list-tile-content> </v-list-tile-content>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
</v-card> </v-card>

View file

@ -2,8 +2,7 @@
<template id="tabs"> <template id="tabs">
<v-tabs id="mobile-tabs-6" scroll-bars light> <v-tabs id="mobile-tabs-6" scroll-bars light>
<v-card class="primary white--text"> <v-card class="primary white--text">
<v-card-text> <v-card-actions>
<v-card-row>
<v-btn icon light> <v-btn icon light>
<v-icon>menu</v-icon> <v-icon>menu</v-icon>
</v-btn> </v-btn>
@ -14,8 +13,7 @@
<v-btn icon light> <v-btn icon light>
<v-icon>more_vert</v-icon> <v-icon>more_vert</v-icon>
</v-btn> </v-btn>
</v-card-row> </v-card-actions>
</v-card-text>
</v-card> </v-card>
<v-tabs-bar slot="activators"> <v-tabs-bar slot="activators">
<v-tabs-slider></v-tabs-slider> <v-tabs-slider></v-tabs-slider>

23
src/vue-poc/lib/file.xqm Normal file
View file

@ -0,0 +1,23 @@
(:~
: file Utility functions.
:
: @author Andy Bunce, 2017
:)
module namespace ufile = 'vue-poc/file';
(:~
: resolve path relative to basex webpath
: file("/fred")=>C:\Program Files (x86)\BaseX\webapp\fred
:)
declare function ufile:web($file as xs:string)
as xs:string
{
let $file:=if(starts-with($file,"/")) then
substring($file,2)
else
error(xs:QName('vue-api:badpath'),"leading slash")
let $webroot:=db:system()/globaloptions/webpath/concat(.,"/")
return file:resolve-path($file,$webroot)
};

View file

@ -15,14 +15,21 @@ import module namespace cons = 'vue-poc/cons' at 'cons.xqm';
:) :)
declare function util:query( declare function util:query(
$query as xs:string?, $query as xs:string?,
$context as item()* $context as item()*)
) as xs:string { as xs:string {
let $limit := $cons:OPTION($cons:K-MAXCHARS)
let $result := xquery:eval($query, map { '': $context }, util:query-options()) let $result := xquery:eval($query, map { '': $context }, util:query-options())
(: serialize more characters than requested, because limit represents number of bytes :) (: serialize more characters than requested, because limit represents number of bytes :)
return util:display($result)
};
declare function util:display(
$result as item()*)
as xs:string
{
let $limit := $cons:OPTION($cons:K-MAXCHARS)
(: serialize more characters than requested, because limit represents number of bytes :)
return util:chop(serialize($result, map { 'limit': $limit * 2 + 1, 'method': 'basex' }), $limit) return util:chop(serialize($result, map { 'limit': $limit * 2 + 1, 'method': 'basex' }), $limit)
}; };
(:~ (:~
: Runs an updating query. : Runs an updating query.
: @param $query query string : @param $query query string

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
<title>Vue Router Test</title> <title>Vue Router Test</title>
<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="https://unpkg.com/vuetify@0.12.7/dist/vuetify.min.css" rel="stylesheet" type="text/css"> <link href="https://unpkg.com/vuetify@0.13.0/dist/vuetify.min.css" rel="stylesheet" type="text/css">
<link href="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.css" rel="stylesheet" type="text/css"> <link href="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.css" rel="stylesheet" type="text/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">
@ -19,7 +19,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.5.3/vue-router.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.5.3/vue-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.js"></script>
<script src="https://unpkg.com/vuetify@0.12.7/dist/vuetify.min.js"></script> <script src="https://unpkg.com/vuetify@0.13.0/dist/vuetify.min.js"></script>
<script src="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.js"></script> <script src="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ace.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ext-language_tools.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ext-language_tools.js"></script>
@ -38,7 +38,7 @@
<v-app id="app" > <v-app id="app" >
<v-navigation-drawer persistent light :mini-variant.sync="mini" v-model="drawer" class="grey lighten-4 pb-0"> <v-navigation-drawer persistent light :mini-variant.sync="mini" v-model="drawer" class="grey lighten-4 pb-0">
<v-list class="pa-0"> <v-list class="pa-0">
<v-list-item>
<v-list-tile avatar tag="div"> <v-list-tile avatar tag="div">
<v-list-tile-avatar> <v-list-tile-avatar>
<img src="/vue-poc/ui/quodatum.gif" /> <img src="/vue-poc/ui/quodatum.gif" />
@ -52,7 +52,7 @@
</v-btn> </v-btn>
</v-list-tile-action> </v-list-tile-action>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
<nav-list :items="items"></nav-list> <nav-list :items="items"></nav-list>
</v-navigation-drawer> </v-navigation-drawer>
@ -69,14 +69,13 @@
</v-btn> </v-btn>
<v-list> <v-list>
<v-list-item @click="logout()">
<v-list-tile> <v-list-tile @click="logout()">
<v-list-tile-title >logout</v-list-tile-title> <v-list-tile-title >logout</v-list-tile-title>
</v-list-tile> </v-list-tile>
<v-list-tile> <v-list-tile>
<v-list-tile-title >permission: {{$auth.permission}}</v-list-tile-title> <v-list-tile-title >permission: {{$auth.permission}}</v-list-tile-title>
</v-list-tile> </v-list-tile>
</v-list-item>
</v-list> </v-list>
</v-menu> </v-menu>

View file

@ -0,0 +1 @@
42

View file

@ -0,0 +1,2 @@
declare variable $MAX:=100000;
for $i in (2 to $MAX) return if (every $j in (2 to $i - 1) satisfies $i mod $j ne 0) then $i else ()

View file

@ -0,0 +1,8 @@
(:~ create xml file list
:)
import module namespace fw="quodatum:file.walker";
declare namespace c="http://www.w3.org/ns/xproc-step";
let $opt:=map{"include-filter":".*\.xsd",
"max-depth":-1,
"include-info":true()}
return fw:directory-list("/",$opt)

View file

@ -1,109 +0,0 @@
<!DOCTYPE html>
<template id="eval">
<v-container fluid>
<v-card class="grey lighten-1 z-depth-1 mb-5">
<v-card-row>
<v-btn @click.native="run()">Run</v-btn>
<v-btn @click.native="submit()">Submit</v-btn>
</v-card-row>
<v-card-row height="200px" >
<vue-ace :content="xq" mode="xquery" wrap="true"
v-on:change-content="onChange"
></vue-ace>
</v-card-row>
</v-card>
<v-alert error v-bind:value="showError">
{{result}}
</v-alert>
<v-card v-if="show" class="grey lighten-1 z-depth-1 mb-5">
<v-card-row height="200px">
<vue-ace :content="result" mode="text" wrap="true" read-only="true"
></vue-ace>
</v-card-row>
<v-card-row actions>
<v-chip class="green white--text">
<v-avatar class="green darken-4">{{elapsed}}</v-avatar>
Elapsed:
</v-chip>
<v-chip class="green white--text">
<v-avatar class="green darken-4">{{jobId}}</v-avatar>
JobId:
</v-chip>
<v-spacer></v-spacer>
<v-btn flat class="green--text darken-1">@TODO</v-btn>
</v-card-row>
</v-card>
</v-container>
</template>
<script>{
data: function(){
return {
xq: '(: type your XQuery :)\n',
result:'',
elapsed:null,
show:false,
showError:false,
jobId:null
}
},
methods:{
onChange(val){
if (this.xq !== val) {
this.xq = val
}
},
run(){
var data={xq:this.xq}
this.showError=this.show=false
var _start = performance.now();
HTTP.post("eval/execute",Qs.stringify(data))
.then(r=>{
this.elapsed=Math.floor(performance.now() - _start);
this.result=r.data.result
this.jobId=null
this.show=true
})
.catch(r=> {
console.log("error",r)
this.result=r.response.data
this.showError=true;
});
localforage.setItem('eval/xq', this.xq)
},
submit(){
var data={xq:this.xq}
this.showError=this.show=false
var _start = performance.now();
HTTP.post("eval/submit",Qs.stringify(data))
.then(r=>{
this.elapsed=Math.floor(performance.now() - _start);
this.result=this.jobId=r.data.job
this.show=true
})
.catch(r=> {
console.log("error",r)
this.jobId=r.response.job
this.showError=true;
});
}
},
created:function(){
localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq});
}
}
</script>

View file

@ -1,31 +0,0 @@
<!DOCTYPE html>
<template id="home">
<v-layout class="ma-5">
<v-flex xs4>
<v-card hover raised>
<v-card-row height="200px" class="pa-5 green lighten-1">
<div class="display-1 white--text text-xs-center">VUE-POC</div>
v0.0.2
</v-card-row>
</v-card>
</v-flex>
<v-flex xs4>
<p>This is a experiment in using <code>vue.js</code>.</p>
<ul>
<li><a href="https://vuetifyjs.com/vuetify/quick-start" target="new">vuetifyjs</a></li>
<li><a href="https://github.com/monterail/vue-multiselect" target="new">vue-multiselect</a></li>
<li><a href="https://github.com/sagalbot/vue-select" target="new"><s>vue-select</s></a></li>
<li><a href="https://github.com/beautify-web/js-beautify" target="new">js-beautify</a></li>
<li><a href="/doc/#/data/app/vue-poc" target="new">doc</a></li>
<li><a href="/dba" target="new">DBA app</a></li>
</ul>
</v-flex>
<v-btn floating="floating">
<v-icon>add</v-icon>
</v-btn>
<my-component href="/dba">REPLACED</my-component>
</v-layout>
</template>
<script>{
}
</script>

View file

@ -1,26 +0,0 @@
<!DOCTYPE html>
<template id="job">
<v-container fluid>
<h1>JOBS</h1>
</v-container>
</template>
<script>{
data: function(){
return {
message: 'Hello Vue.js!',
jobs:[]
}
},
methods:{
getJobs(){
alert("get jobs")
}
},
created(){
this.getJobs()
}
}
</script>

View file

@ -1,25 +0,0 @@
module namespace j = 'quodatum.test.jobs';
(:~
: job list
:)
declare
%rest:GET %rest:path("/vue-poc/api/job")
%output:method("json")
function j:list()
as element(json)
{
let $jlist:=jobs:list()[. != jobs:current()] !jobs:list-details(.)
return <json type="array">
{for $j in $jlist
return <_ type="object">
<id>{$j/@id/string()}</id>
<type>{$j/@type/string()}</type>
<state>{$j/@state/string()}</state>
<user>{$j/@user/string()}</user>
<duration>{$j/@duration/string()}</duration>
</_>
}</json>
};

View file

@ -6,8 +6,8 @@
module namespace vue-api = 'quodatum:vue.api'; module namespace vue-api = 'quodatum:vue.api';
import module namespace rest = "http://exquery.org/ns/restxq"; import module namespace rest = "http://exquery.org/ns/restxq";
import module namespace session = "http://basex.org/modules/session"; import module namespace session = "http://basex.org/modules/session";
import module namespace fw="quodatum:file.walker";
import module namespace mt = 'quodatum.data.mimetype' at "lib/mimetype.xqm";
declare namespace c="http://www.w3.org/ns/xproc-step"; declare namespace c="http://www.w3.org/ns/xproc-step";
declare namespace wadl="http://wadl.dev.java.net/2009/02"; declare namespace wadl="http://wadl.dev.java.net/2009/02";
@ -51,32 +51,6 @@ return <json type="object" >
}; };
(:~
: history list
:)
declare
%rest:GET %rest:path("/vue-poc/api/history")
%rest:produces("application/json")
%output:method("json")
function vue-api:history( )
{
let $h:=(
'/vue-poc/vue-poc.xqm',
'/vue-poc/data/vue-poc/ch4d1.xml',
'/vue-poc/static/app-gen.js',
'/vue-poc/static/app.html',
'/vue-poc/static/app.css',
'/vue-poc/logo.svg',
'/vue-poc/static/resources/sparql.rq',
'/vue-poc/static/resources/turtle.ttl'
)
return <json type="object" >
<items type="array">
{$h!(<_ type="object"><url>{.}</url></_>)}
</items>
</json>
};
(:~ (:~
: Returns wadl. : Returns wadl.
@ -88,109 +62,3 @@ function vue-api:wadl()
rest:wadl() rest:wadl()
}; };
(:~
: Returns a file content.
:)
declare
%rest:GET %rest:path("/vue-poc/api/edit")
%rest:query-param("url", "{$url}")
%rest:produces("application/json")
%output:method("json")
function vue-api:edit-get($url as xs:string)
{
let $path := vue-api:web( $url)=>trace("path ")
return if( file:exists($path))then
let $type:=mt:type($path)
let $fetch:=mt:fetch-fn($type("treat-as"))
return <json type="object" >
<url>{$url}</url>
<mimetype>{$type?type}</mimetype>
<data>{$fetch($path)}</data>
</json>
else
error(xs:QName('vue-api:raw'),$path)
};
(:~
: Update a file content. @TODO
:)
declare
%rest:POST %rest:path("/vue-poc/api/edit")
%rest:form-param("url", "{$url}")
%rest:form-param("data", "{$data}")
%rest:produces("application/json")
%output:method("json")
function vue-api:edit-post($url as xs:string,$data)
{
let $path := vue-api:web( $url)=>trace("path ")
let $data:=trace($data)
return if( file:exists($path))then
let $type:=mt:type($path)
let $fetch:=mt:fetch-fn($type("treat-as"))
return <json type="object" >
<url>{$url}</url>
<mimetype>{$type?type}</mimetype>
<data>{$fetch($path)}</data>
</json>
else
error(xs:QName('vue-api:raw'),$path)
};
(:~
: Returns folder info.
:)
declare
%rest:path("/vue-poc/api/file")
%rest:query-param("url", "{$url}")
%rest:produces("application/json")
%output:method("json")
function vue-api:file($url as xs:string)
{
let $path := vue-api:web( $url)=>trace("vue-api:web ")
return if( file:exists($path))then
let $items:=fw:directory-list($path,map{"max-depth":1,"include-info":true()})
return <json type="object" >
<folders type="array">
{for $f in $items/c:directory
order by $f/@name/lower-case(.)
return <_ type="object">
<name>{$f/@name/string()}</name>
<icon>folder</icon>
<modified>{$f/@last-modified/string()}</modified>
<size type="number">{$f/@size/string()}</size>
</_>
}
</folders>
<files type="array">
{for $f in $items/c:file
order by $f/@name/lower-case(.)
return <_ type="object">
<name>{$f/@name/string()}</name>
<icon>insert_drive_file</icon>
<modified>{$f/@last-modified/string()}</modified>
<size type="number">{$f/@size/string()}</size>
</_>
}
</files>
</json>
else
error(xs:QName('vue-api:raw'),$path)
};
(:~
: resolve path relative to basex webpath
: file("/fred")=>C:\Program Files (x86)\BaseX\webapp\fred
:)
declare function vue-api:web($file as xs:string)
as xs:string
{
let $file:=if(starts-with($file,"/")) then
substring($file,2)
else
error(xs:QName('vue-api:badpath'),"leading slash")
let $webroot:=db:system()/globaloptions/webpath/concat(.,"/")
return file:resolve-path($file,$webroot)
};

View file

@ -9,28 +9,40 @@ declare namespace Element="java:ch.digitalfondue.jfiveparse.Element";
declare namespace Node="java:ch.digitalfondue.jfiveparse.Node"; declare namespace Node="java:ch.digitalfondue.jfiveparse.Node";
declare namespace functx = "http://www.functx.com"; declare namespace functx = "http://www.functx.com";
declare variable $SRC:="C:/Users/andy/git/vue-poc/src/vue-poc/templates/"; declare variable $PROJ:="C:/Users/andy/git/vue-poc/src/vue-poc/";
declare variable $CORE:="C:/Users/andy/git/vue-poc/src/vue-poc/static/core.js"; declare variable $FEATURES:="features/"=>file:resolve-path($PROJ);
declare variable $FILTERS:="C:/Users/andy/git/vue-poc/src/vue-poc/static/filters.js"; declare variable $COMPONENTS:="components/"=>file:resolve-path($PROJ);
declare variable $DEST:="C:/Users/andy/git/vue-poc/src/vue-poc/static/app-gen.js"; declare variable $CORE:="components/core.js"=>file:resolve-path($PROJ);
declare variable $FILTERS:="components/filters.js"=>file:resolve-path($PROJ);
declare variable $DEST:="static/app-gen.js"=>file:resolve-path($PROJ);
(:~ (:~
: generate javascript vue call from vue files in source folder and core.js : generate javascript vue call from vue files in source folder and core.js
:) :)
declare function local:process($doc) declare function local:feature($doc,$isComp as xs:boolean)
{ {
let $tempNode:= html5:getElementFirstByTagName($doc,"template") let $p:=local:vue-parse($doc)
let $template:= Node:getInnerHTML($tempNode) let $script:= $p?script=>substring-after("{")
let $id := Element:getAttribute($tempNode,"id")
let $name:=functx:capitalize-first($id)=>trace("ID")
let $script:= html5:getElementFirstByTagName($doc,"script") return if(empty($p?id)) then
let $script:= Node:getInnerHTML($script)=>substring-after("{") ()
let $js:= ``[const `{$name}`=Vue.extend({template:` `{$template}` `, else
``[const `{functx:capitalize-first($p?id)}`=Vue.extend({template:` `{$p?template}` `,
`{$script}` `{$script}`
); );
]`` ]``
return if(empty($id)) then () else $js };
declare function local:vue-parse($doc)
as map(*)
{
let $tempNode:= html5:getElementFirstByTagName($doc,"template")
let $template:= Node:getInnerHTML($tempNode)
let $id := Element:getAttribute($tempNode,"id")=>trace("ID")
let $script:= html5:getElementFirstByTagName($doc,"script")
let $script:= Node:getInnerHTML($script)
return map{"id":$id,"template":$template,"script":$script}
}; };
declare function functx:capitalize-first declare function functx:capitalize-first
@ -39,11 +51,16 @@ declare function functx:capitalize-first
concat(upper-case(substring($arg,1,1)), substring($arg,2)) concat(upper-case(substring($arg,1,1)), substring($arg,2))
}; };
let $files:= fw:directory-list($SRC,map{"include-filter":".*\.vue"}) let $files:= fw:directory-list($FEATURES,map{"include-filter":".*\.vue"})
//c:file/@name/resolve-uri(.,base-uri(.)) //c:file/@name/resolve-uri(.,base-uri(.))
let $docs:=$files!(fetch:text(.)=>html5:doc()=>local:process()) let $feats:=$files!(fetch:text(.)=>html5:doc()=>local:feature(false()))
let $files:= fw:directory-list($COMPONENTS,map{"include-filter":".*\.vue"})
//c:file/@name/resolve-uri(.,base-uri(.))
let $comps:=$files!(fetch:text(.)=>html5:doc()=>local:feature(true()))
let $comment:="// generated " || current-dateTime() || "&#xA;&#xD;" let $comment:="// generated " || current-dateTime() || "&#xA;&#xD;"
return file:write-text($DEST,string-join(($comment, return file:write-text($DEST,string-join(($comment,
fetch:text($FILTERS), fetch:text($FILTERS),
$docs, $feats,
fetch:text($CORE)))) fetch:text($CORE))))