file selection

This commit is contained in:
Andy Bunce 2017-09-17 17:25:44 +01:00
parent 4c65218cba
commit 7081c4446c
10 changed files with 1865 additions and 1820 deletions

View File

@ -19,7 +19,7 @@ const router = new VueRouter({
{ path: '/server/users', component: Users,meta:{title:"Users"} },
{ path: '/server/repo', component: Repo,meta:{title:"Repository"} },
{ path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} },
{ path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} },
{ path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"xmldb"} },
{ path: '/ping', component: Ping,meta:{title:"Ping"} },
{ path: '/settings', component: Settings, meta:{title:"Settings"} },
{ path: '/acesettings', component: Acesettings, meta:{title:"Editor settings"} },

View File

@ -41,7 +41,7 @@ as element(json)
{
let $reader:=map{
"webfile":ufile:webfile#1,
"basexdb":ufile:basexdb#1
"xmldb":ufile:xmldb#1
}
let $items:=$reader($protocol)($url)
return vue-api:items($items)
@ -53,32 +53,25 @@ declare function vue-api:items($items)
as element(json)
{
<json type="object" >
<folders type="array">
{for $f in $items/c:directory
<items type="array">
{for $f in $items/*
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>
</items>
</json>
};
declare function vue-api:details($f as element(*),$icon as xs:string)
declare function vue-api:details($f as element(*),$type as xs:string)
as element(*)*
{
<name>{$f/@name/string()}</name>
,<icon>{$icon}</icon>
,<type>{if(local-name($f)="file" )then "file" else "folder"}</type>
,<modified>{$f/@last-modified/string()}</modified>
,<size type="number">{$f/@size/string()}</size>
,<selected type="boolean">false</selected>
,<mime>unknown</mime>
};

View File

@ -4,7 +4,7 @@
<v-card>
<v-toolbar >
<v-toolbar dense >
<v-btn icon :to="{query: { url: '/' }}">
<v-icon >{{icon}}</v-icon>
</v-btn>
@ -15,24 +15,27 @@
</v-breadcrumbs-item>
</v-breadcrumbs>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items v-if="!selected">
<v-text-field prepend-icon="search" label="Filter..." v-model="q" type="search"
<v-btn v-if="selCount" @click="selectNone">Sel:{{selCount}}</v-btn>
<v-text-field v-if="!selCount" prepend-icon="search" label="Filter..." v-model="q" type="search"
hide-details single-line @keyup.enter="setfilter"></v-text-field>
<v-toolbar-items v-if="!selCount">
<v-btn icon v-for="b in buttons" :key="b.icon" @click="action(b)">
<v-avatar>
<v-icon v-text="b.icon"></v-icon>
</v-avatar>
</v-btn>
</v-toolbar-items>
<v-toolbar-items v-if="selected">
<v-toolbar-items v-if="selCount">
<v-btn icon v-for="b in selopts" :key="b.icon" @click="action(b)">
<v-icon v-text="b.icon"></v-icon>
</v-btn>
</v-toolbar-items>
<v-menu offset-y>
<v-menu offset-y v-if="selCount">
<v-btn icon slot="activator">
<v-icon>more_vert</v-icon>
</v-btn>
@ -49,20 +52,18 @@
</v-list-tile>
</v-list>
</v-menu>
</v-toolbar>
<v-progress-linear v-if="busy" v-bind:indeterminate="true" ></v-progress-linear>
<v-layout>
<v-layout v-if="!busy">
<v-flex>
<v-list v-if="!busy" two-line subheader>
<v-list two-line subheader>
<v-subheader inset >
<span >Folders ({{ folders.length }})</span>
<span >Folders ({{ xfolders.length }})</span>
</v-subheader>
<v-list-tile v-for="item in folders" v-bind:key="item.name" @click="folder(item)" avatar >
<v-list-tile v-for="item in xfolders" v-bind:key="item.name" @click="folder(item)" avatar >
<v-list-tile-avatar >
<v-icon v-bind:class="[item.iconClass]">{{ item.icon }}</v-icon>
<v-icon v-bind:class="[item.iconClass]">{{ itemIcon(item) }}</v-icon>
</v-list-tile-avatar>
<v-list-tile-content >
<v-list-tile-title>{{ item.name }}</v-list-tile-title>
@ -77,11 +78,11 @@
<v-divider inset></v-divider>
<v-subheader inset>
<span >Files ({{ files.length }})</span>
<span >Files ({{ xfiles.length }})</span>
</v-subheader>
<v-list-tile v-for="item in files" v-bind:key="item.name" >
<v-list-tile-avatar>
<v-icon v-bind:class="[item.iconClass]">{{ item.icon }}</v-icon>
<v-list-tile v-for="item in xfiles" v-bind:key="item.name" >
<v-list-tile-avatar avatar @click.prevent.stop="item.selected =! item.selected ">
<v-icon v-bind:class="[item.iconClass]">{{ itemIcon(item) }}</v-icon>
</v-list-tile-avatar>
<v-list-tile-content @click="file(item.name)">
<v-list-tile-title >{{ item.name }}</v-list-tile-title>
@ -113,6 +114,7 @@
</v-navigation-drawer>
</v-card>
<v-progress-linear v-if="busy" v-bind:indeterminate="true" height="2"></v-progress-linear>
</v-container>
</template>
@ -122,18 +124,17 @@
data(){
return {
url: "",
folders: [],
files: [],
items: [],
q: "",
busy: false,
showInfo: false,
selected: null,
selected: [],
buttons: [
{method: this.todo, icon: "view_quilt"},
{method: this.add, icon: "add"},
{method: this.todo, icon: "refresh"},
{method: this.load, icon: "refresh"},
{method: this.todo, icon: "sort"},
{method: this.todo, icon: "select_all"}
{method: this.selectAll, icon: "select_all"}
],
selopts: [
{method: this.todo, icon: "delete"},
@ -153,12 +154,12 @@ selopts: [
folder (item) {
this.url=this.url+item.name+"/"
},
load(url){
load(){
var url=this.url
this.busy=true
HTTP.get("collection",{params:{url:url,protocol:this.protocol}})
.then(r=>{
this.folders=r.data.folders
this.files=r.data.files
this.items=r.data.items
this.busy=false
})
.catch(error=> {
@ -169,8 +170,7 @@ selopts: [
},
action(b){
alert(b.icon)
b.method()
b.method(b.icon)
},
add(){
alert("add")
@ -191,14 +191,29 @@ selopts: [
this.$router.push({ name: 'jobShow', params: {job:job }})
})
},
todo(){
alert("todo")
todo(icon){
alert("todo: " + icon)
},
itemIcon(item){
return item.selected?"check_circle":"folder"
},
selectAll(){
this.items.forEach(item=>{item.selected=true})
},
selectNone(){
this.items.forEach(item=>{item.selected=false})
}
},
computed: {
icon(){
return (this.protocol=="basexdb")?"developer_mode":"folder"
return (this.protocol=="xmldb")?"developer_mode":"folder"
},
xfiles(){
return this.items.filter(item=>{return item.type!="folder"})
},
xfolders(){
return this.items.filter(item=>{return item.type=="folder"})
},
// array of {name:"that", path:"/this/that/"} for url
crumbs(){
var parts=this.url.split("/").filter((a)=>a.length>0)
@ -206,6 +221,9 @@ selopts: [
function(v,i,a){return {name:v, path:"/"+a.slice(0,i+1).join("/")+"/"}}
)
return a
},
selCount(){
return this.items.reduce((acc,item)=>{return acc+(item.selected?1:0)},0)
}
},
watch:{
@ -216,14 +234,14 @@ selopts: [
//console.log("ROUTE",vnew,vold)
var url=this.$route.query.url
this.url=url?url:"/";
if(vnew.query.url != vold.query.url) this.load(this.url)
if(vnew.query.url != vold.query.url) this.load()
}
},
created:function(){
var url=this.$route.query.url
this.url=url?url:"/";
this.q=this.$route.query.q || this.q
this.load(this.url)
this.load()
}
}
</script>

View File

@ -221,7 +221,7 @@ v-on:annotation="annotation"></vue-ace>
})
},
showfiles(){
var target=this.protocol="basexdb"?"database":"files";
var target=this.protocol="xmldb"?"database":"files";
router.push({ path: target, query: { url: this.path.join("/"),protocol:this.protocol }})
},
beautify(){
@ -267,7 +267,7 @@ v-on:annotation="annotation"></vue-ace>
},
computed:{
icon(){
return (this.protocol=="basexdb")?"account_balance":"folder"
return (this.protocol=="xmldb")?"account_balance":"folder"
}
},
created(){

View File

@ -25,7 +25,7 @@ function vue-api:edit-get($url as xs:string,$protocol as xs:string)
{
let $reader := map{
"webfile":vue-api:get-webfile#1,
"basexdb":vue-api:get-basexdb#1
"xmldb":vue-api:get-basexdb#1
}
return $reader($protocol)($url)
};

View File

@ -2,6 +2,13 @@
<template id="task">
<v-container fluid>
<h3>Available Tasks</h3>
<v-snackbar
:bottom="true"
v-model="snackbar"
>
got tasks, currently ignoring
<v-btn flat class="pink--text" @click.native="snackbar = false">Close</v-btn>
</v-snackbar>
<ul>
<li v-for="task in tasks" :key="task.to">
<router-link :to="task.to" v-text="task.text"></router-link>
@ -17,14 +24,15 @@
{to: "tasks/model", text: "model"},
{to: "tasks/xqdoc", text: "xqdoc"},
{to: "tasks/vuecompile", text: "vue compile"}
]
],
snackbar: false
}
},
methods:{
getTasks(){
HTTP.get("tasks/list")
.then(r=>{
alert("tasks http")
this.snackbar=true
})
}
},

View File

@ -32,10 +32,10 @@ as element(c:directory)
error(xs:QName('ufile:badpath'),$path)
};
declare function ufile:basexdb($url as xs:string)
declare function ufile:xmldb($url as xs:string)
as element(c:directory)
{
<c:directory name="" xml:base="basexdb:/" last-modified="2017-07-01T13:39:38.98691Z" size="4096">{
<c:directory name="" xml:base="xmldb:/" last-modified="2017-07-01T13:39:38.98691Z" size="4096">{
if($url="/") then
db:list()!
<c:directory name="{db:property(.,'name')}"

View File

@ -1,5 +1,5 @@
(: entity access maps
: auto generated from xml files in entities folder at: 2017-09-08T12:06:30.901+01:00
: auto generated from xml files in entities folder at: 2017-09-17T13:41:02.538+01:00
:)
module namespace entity = 'quodatum.models.generated';

File diff suppressed because it is too large Load Diff

View File

@ -22,17 +22,20 @@
</head>
<body>
<div id="app">
<h3><code>vue-poc</code> <small>(v0.1)</small> </h3>
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
<span>loading...</span>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.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/vue/2.4.4/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.7.0/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/qs/6.4.0/qs.js"></script>
<script src="https://unpkg.com/vuetify@0.15.7/dist/vuetify.min.js"></script>