Holger Knublauch

Tree now uses SPIN templates

......@@ -515,36 +515,42 @@ app:ClassFormBody
]
] .
app:ClassTreeDataProvider
rdf:type app:QueryTreeDataProvider ;
rdfs:comment "A data provider for a class tree starting at rdfs:Resource."^^xsd:string ;
rdfs:label "Class tree data provider"^^xsd:string ;
arg:childrenQuery
app:ClassTreeChildren
rdf:type spin:SelectTemplate ;
rdfs:comment "A template that delivers all (named) subclasses of a given parent class, using rdfs:subClassOf."^^xsd:string ;
rdfs:label "Class tree children"^^xsd:string ;
rdfs:subClassOf app:TreeChildrenTemplates ;
spin:body
[ rdf:type sp:Select ;
sp:orderBy ([ sp:varName "label"^^xsd:string
]) ;
sp:resultVariables ([ sp:varName "child"^^xsd:string
sp:resultVariables ([ sp:varName "node"^^xsd:string
] [ sp:varName "label"^^xsd:string
] [ sp:varName "leaf"^^xsd:string
] [ sp:varName "icon"^^xsd:string
] [ sp:varName "type"^^xsd:string
]) ;
sp:where ([ sp:object
[ sp:varName "parent"^^xsd:string
] ;
sp:predicate rdfs:subClassOf ;
sp:subject
[ sp:varName "child"^^xsd:string
[ sp:varName "node"^^xsd:string
]
] [ rdf:type sp:Filter ;
sp:expression
[ rdf:type sp:isIRI ;
sp:arg1 [ sp:varName "node"^^xsd:string
]
]
] [ rdf:type sp:Bind ;
sp:expression
[ rdf:type sp:notExists ;
sp:elements ([ sp:object
[ sp:varName "child"^^xsd:string
[ sp:varName "node"^^xsd:string
] ;
sp:predicate rdfs:subClassOf ;
sp:subject
[ sp:varName "grandChild"^^xsd:string
[ sp:varName "child"^^xsd:string
]
])
] ;
......@@ -554,7 +560,7 @@ app:ClassTreeDataProvider
] [ rdf:type sp:Bind ;
sp:expression
[ rdf:type ui:label ;
sp:arg1 [ sp:varName "child"^^xsd:string
sp:arg1 [ sp:varName "node"^^xsd:string
]
] ;
sp:variable
......@@ -565,39 +571,60 @@ app:ClassTreeDataProvider
sp:variable
[ sp:varName "icon"^^xsd:string
]
] [ rdf:type sp:Bind ;
sp:expression
[ rdf:type spl:object ;
sp:arg1 [ sp:varName "child"^^xsd:string
] ;
sp:arg2 rdf:type
] ;
sp:variable
[ sp:varName "type"^^xsd:string
]
])
] ;
arg:id [ sp:varName "id"^^xsd:string
] ;
arg:rootsQuery
] .
app:ClassTreeDataProvider
rdf:type app:TreeDataProvider ;
rdfs:comment "A data provider for a class tree starting at rdfs:Resource."^^xsd:string ;
rdfs:label "Class tree data provider"^^xsd:string ;
arg:treeChildrenTemplate
app:ClassTreeChildren ;
arg:treeRootsTemplate
app:ClassTreeRoots .
app:ClassTreeRoots
rdf:type spin:SelectTemplate ;
rdfs:label "Class tree roots"^^xsd:string ;
rdfs:subClassOf app:TreeRootsTemplates ;
spin:body
[ rdf:type sp:Select ;
sp:resultVariables ([ sp:varName "child"^^xsd:string
sp:resultVariables ([ sp:varName "node"^^xsd:string
] [ sp:varName "label"^^xsd:string
] [ sp:varName "leaf"^^xsd:string
] [ sp:varName "icon"^^xsd:string
]) ;
sp:where ([ rdf:type sp:Bind ;
sp:expression rdfs:Resource ;
sp:expression
[ rdf:type sp:coalesce ;
sp:arg1 [ sp:varName "root"^^xsd:string
] ;
sp:arg2 rdfs:Resource
] ;
sp:variable
[ sp:varName "child"^^xsd:string
[ sp:varName "node"^^xsd:string
]
] [ rdf:type sp:Bind ;
sp:expression "Resource" ;
sp:expression
[ rdf:type ui:label ;
sp:arg1 [ sp:varName "node"^^xsd:string
]
] ;
sp:variable
[ sp:varName "label"^^xsd:string
]
] [ rdf:type sp:Bind ;
sp:expression "false"^^xsd:boolean ;
sp:expression
[ rdf:type sp:notExists ;
sp:elements ([ sp:object
[ sp:varName "node"^^xsd:string
] ;
sp:predicate rdfs:subClassOf ;
sp:subject
[ sp:varName "child"^^xsd:string
]
])
] ;
sp:variable
[ sp:varName "leaf"^^xsd:string
]
......@@ -3619,86 +3646,6 @@ app:PropertyLabel
]
] .
app:QueryTreeDataProvider
rdf:type ui:NodeClass ;
rdfs:comment "A TreeDataProvider backed by two SELECT queries - one to get the roots, and one to get the children of a given node."^^xsd:string ;
rdfs:label "Query tree data provider"^^xsd:string ;
rdfs:subClassOf app:TreeDataProvider ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The query to get the children."^^xsd:string ;
spl:predicate arg:childrenQuery ;
spl:valueType sp:Select
] ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The query to get the roots of the tree."^^xsd:string ;
spl:predicate arg:rootsQuery ;
spl:valueType sp:Select
] ;
ui:prototype
[ rdf:type ui:group ;
ui:child
[ rdf:type ui:if ;
ui:child
[ rdf:type app:QueryTreeDataProviderHelper ;
ui:childIndex 0 ;
ui:resultSet
[ sp:varName "rootsQuery"^^xsd:string
]
] ;
ui:childIndex 0 ;
ui:condition
[ rdf:type sp:or ;
sp:arg1 [ rdf:type sp:eq ;
sp:arg1 [ sp:varName "id"^^xsd:string
] ;
sp:arg2 "1"
] ;
sp:arg2 [ rdf:type sp:not ;
sp:arg1 [ rdf:type sp:bound ;
sp:arg1 [ sp:varName "id"^^xsd:string
]
]
]
]
] ;
ui:child
[ rdf:type ui:else ;
ui:child
[ rdf:type ui:group ;
let:parent
[ rdf:type ui:decodeNode ;
sp:arg1 [ rdf:type app:removeUniqueId ;
sp:arg1 [ sp:varName "id"^^xsd:string
]
]
] ;
ui:child
[ rdf:type app:QueryTreeDataProviderHelper ;
ui:childIndex 0 ;
ui:resultSet
[ sp:varName "childrenQuery"^^xsd:string
]
] ;
ui:childIndex 0
] ;
ui:childIndex 1
]
] .
app:QueryTreeDataProviderHelper
rdf:type ui:NodeClass ;
rdfs:label "Query tree data provider helper"^^xsd:string ;
rdfs:subClassOf app:TreeElements ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The query to execute."^^xsd:string ;
spl:predicate ui:resultSet ;
spl:valueType sp:Select
] ;
ui:prototype <http://appschema.org/imports/queryTreeDataProviderHelper.uispin.html> .
app:ResourceEnumDropDownEditor
rdf:type app:ObjectEditorClass ;
rdfs:label "Resource enum drop down editor"^^xsd:string ;
......@@ -5509,11 +5456,30 @@ app:Tree
spl:predicate arg:onSelect ;
spl:valueType xsd:string
] ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "A root node that can overload the default root of the data provider. For example, app:ClassTreeDataProvider starts at rdfs:Resource by default - set arg:root to owl:Thing to start there instead."^^xsd:string ;
spl:optional "true"^^xsd:boolean ;
spl:predicate arg:root ;
spl:valueType rdfs:Resource
] ;
ui:prototype <http://appschema.org/imports/tree.uispin.html> .
app:TreeChildrenTemplates
rdf:type spin:SelectTemplate ;
rdfs:label "Tree children templates"^^xsd:string ;
rdfs:subClassOf app:TreeTemplates ;
spin:abstract "true"^^xsd:boolean ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The parent node to get the children of."^^xsd:string ;
spl:predicate arg:parent ;
spl:valueType rdfs:Resource
] .
app:TreeDataProvider
rdf:type ui:NodeClass ;
rdfs:comment "Base class for various kinds of data providers implementing Ajax call-backs to app:Tree components."^^xsd:string ;
rdfs:comment "A TreeDataProvider is backed by two SELECT queries - one to get the roots, and one to get the children of a given node."^^xsd:string ;
rdfs:label "Tree data provider"^^xsd:string ;
rdfs:subClassOf app:TreeElements ;
spin:constraint
......@@ -5522,13 +5488,135 @@ app:TreeDataProvider
spl:predicate arg:id ;
spl:valueType xsd:string
] ;
ui:abstract "true"^^xsd:boolean .
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The root resource. If none is specified, then the system will use compute the root(s) from the roots template."^^xsd:string ;
spl:optional "true"^^xsd:boolean ;
spl:predicate arg:root ;
spl:valueType rdfs:Resource
] ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The subclass of app:TreeChildrenTemplates that delivers the children of a given parent node."^^xsd:string ;
spl:predicate arg:treeChildrenTemplate ;
spl:valueType spin:Template
] ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "A subclass of app:TreeRootsTemplates that delivers the roots of the tree. Will be bypassed if the tree itself defined an arg:rootResource."^^xsd:string ;
spl:optional "true"^^xsd:boolean ;
spl:predicate arg:treeRootsTemplate ;
spl:valueType spin:Template
] ;
ui:prototype
[ rdf:type ui:group ;
ui:child
[ rdf:type ui:if ;
ui:child
[ rdf:type ui:call ;
arg:root
[ sp:varName "root"^^xsd:string
] ;
ui:child
[ rdf:type app:TreeDataProviderHelper ;
ui:childIndex 0 ;
ui:resultSet
[ sp:varName "rs"^^xsd:string
]
] ;
ui:childIndex 0 ;
ui:template
[ sp:varName "treeRootsTemplate"^^xsd:string
]
] ;
ui:childIndex 0 ;
ui:condition
[ rdf:type sp:or ;
sp:arg1 [ rdf:type sp:eq ;
sp:arg1 [ sp:varName "id"^^xsd:string
] ;
sp:arg2 "1"
] ;
sp:arg2 [ rdf:type sp:not ;
sp:arg1 [ rdf:type sp:bound ;
sp:arg1 [ sp:varName "id"^^xsd:string
]
]
]
]
] ;
ui:child
[ rdf:type ui:else ;
ui:child
[ rdf:type ui:call ;
arg:parent
[ rdf:type ui:decodeNode ;
sp:arg1 [ rdf:type app:removeUniqueId ;
sp:arg1 [ sp:varName "id"^^xsd:string
]
]
] ;
ui:child
[ rdf:type app:TreeDataProviderHelper ;
ui:childIndex 0 ;
ui:resultSet
[ sp:varName "rs"^^xsd:string
]
] ;
ui:childIndex 0 ;
ui:template
[ sp:varName "treeChildrenTemplate"^^xsd:string
]
] ;
ui:childIndex 1
]
] .
app:TreeDataProviderHelper
rdf:type ui:NodeClass ;
rdfs:label "Tree data provider helper"^^xsd:string ;
rdfs:subClassOf app:TreeElements ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The query to execute."^^xsd:string ;
spl:predicate ui:resultSet ;
spl:valueType sp:Select
] ;
ui:prototype <http://appschema.org/imports/treeDataProviderHelper.uispin.html> .
app:TreeElements
rdf:type ui:NodeClass ;
rdfs:label "Tree elements"^^xsd:string ;
rdfs:subClassOf app:Elements .
app:TreeRootsTemplates
rdf:type spin:SelectTemplate ;
rdfs:comment "Abstract superclass for queries that can deliver the roots of a tree."^^xsd:string ;
rdfs:label "Tree roots templates"^^xsd:string ;
rdfs:subClassOf app:TreeTemplates ;
spin:constraint
[ rdf:type spl:Argument ;
rdfs:comment "The node to return as single root - this is bound by the tree if the tree has a dedicated arg:root. Otherwise the node is created by the WHERE clause."^^xsd:string ;
spl:optional "true"^^xsd:boolean ;
spl:predicate arg:root ;
spl:valueType rdfs:Resource
] .
app:TreeTemplates
rdf:type spin:SelectTemplate ;
rdfs:comment """Base class for SELECT templates that are used to populate trees. There are two kinds of queries:
a) to find all root nodes
b) to find the children of a given parent node.
All SELECT queries in subclass of this must return the following result variables:
SELECT ?node ?label ?leaf ?icon
- ?node: the resource behind the node, e.g. an owl:Class or skos:Concept
- ?label (optional): the label for the resource - if not used, the system will call ui:label(?node)
- ?leaf: true means no children, i.e. the node cannot be expanded
- ?icon (optional): CSS class for the icon"""^^xsd:string ;
rdfs:label "Tree templates"^^xsd:string ;
rdfs:subClassOf spin:SelectTemplates .
app:URIResourceEditor
rdf:type app:ObjectEditorClass ;
rdfs:comment "The default Editor for resources, consisting of a combo-box with auto-complete."^^xsd:string ;
......@@ -7052,6 +7140,11 @@ app:weight
rdfs:range xsd:integer ;
rdfs:subPropertyOf app:systemProperty .
arg:child
rdf:type rdf:Property ;
rdfs:label "child"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:childrenQuery
rdf:type rdf:Property ;
rdfs:label "children query"^^xsd:string ;
......@@ -7162,6 +7255,11 @@ arg:params
rdfs:label "params"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:parent
rdf:type rdf:Property ;
rdfs:label "parent"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:predicates
rdf:type rdf:Property ;
rdfs:label "predicates"^^xsd:string ;
......@@ -7192,6 +7290,11 @@ arg:resultsId
rdfs:label "results id"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:root
rdf:type rdf:Property ;
rdfs:label "root"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:rootsQuery
rdf:type rdf:Property ;
rdfs:label "roots query"^^xsd:string ;
......@@ -7252,6 +7355,16 @@ arg:topHeight
rdfs:label "top height"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:treeChildrenTemplate
rdf:type rdf:Property ;
rdfs:label "tree children template"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:treeRootsTemplate
rdf:type rdf:Property ;
rdfs:label "tree roots template"^^xsd:string ;
rdfs:subPropertyOf sp:arg .
arg:type
rdf:type rdf:Property ;
rdfs:label "type"^^xsd:string ;
......
......@@ -2,7 +2,8 @@
ui:format="json"
ui:sendQueryGraph="true"
ui:snippet="true"
ui:view="{= ?dataProvider }">
ui:view="{= ?dataProvider }"
arg:root="{= ?root }">
<!-- The div that will be turned into a jsTree below -->
<div id="{= ?id }" />
......
<ui:group xmlns:ui="http://uispin.org/ui#">
[
<ui:if ui:condition="{= spr:rowCount(?resultSet) &gt; 0 }">
<ui:forEach ui:indexVar="index" ui:resultSet="{= ?resultSet }">
<ui:if ui:condition="{= ?index &gt; 0 }">,</ui:if>
<ui:forEach ui:indexVar="index" ui:resultSet="{= ?resultSet }" ui:separator=",">
{
"data" : {
"title" : "{= IF(bound(?label), ?label, ui:label(?child)) }"
"title" : "{= COALESCE(?label, ui:label(?node)) }"
<ui:if ui:condition="{= bound(?icon) }">,
"icon" : "{= ?icon }"
</ui:if>
},
"attr" : {
"id": "{= ui:encodeNode(?child) }::{= ui:uniqueId() }",
"resource" : "{= IRI(?child) }"
"id": "{= ui:encodeNode(?node) }::{= ui:uniqueId() }",
"resource" : "{= IRI(?node) }"
},
<ui:if ui:condition="{= ?leaf }">
"children" : []
......@@ -20,7 +18,7 @@
<ui:else>
"state" : "closed"
</ui:else>
}</ui:forEach>
</ui:if>
}
</ui:forEach>
]
</ui:group>
\ No newline at end of file
......
......@@ -48,9 +48,10 @@ log:LogBrowser
html:class "ui-layout-content"^^xsd:string ;
ui:child
[ rdf:type app:Tree ;
arg:dataProvider log:LogEventClassTreeDataProvider ;
arg:dataProvider app:ClassTreeDataProvider ;
arg:id "classTree"^^xsd:string ;
arg:onSelect "appLoadWithResource('form', 'resourceType', resource)"^^xsd:string ;
arg:root "log:LogEvent"^^xsd:string ;
ui:childIndex 0
] ;
ui:childIndex 1
......