many improvements!
This commit is contained in:
1 parent
da7cacb57e
commit
dda4e0b6ae
13 files changed
+245
-31
No files matched your search
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bitbucket.org/damyot/vulture/shared"
|
"bitbucket.org/damyot/vulture/shared"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"labix.org/v2/mgo"
|
"labix.org/v2/mgo"
|
||||||
@@ -17,6 +18,7 @@ type VultureBackend struct {
|
|||||||
|
|
||||||
func GetVultureBackend(req *http.Request) (*VultureBackend, error) {
|
func GetVultureBackend(req *http.Request) (*VultureBackend, error) {
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
|
|
||||||
serverURL, ok := vars["server"]
|
serverURL, ok := vars["server"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("server field not specified")
|
return nil, errors.New("server field not specified")
|
||||||
@@ -83,13 +85,13 @@ func (this *VultureBackend) getMetaData(query *mgo.Query) (map[string]interface{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VultureBackend) GetDocumentByIndex(index int) (map[string]interface{}, error) {
|
func (this *VultureBackend) GetDocumentByIndex(index int, query interface{}) (map[string]interface{}, error) {
|
||||||
doc := make(map[string]interface{})
|
doc := make(map[string]interface{})
|
||||||
query := this.Collection.Find(nil)
|
queryResult := this.Collection.Find(query)
|
||||||
if err := query.Skip(index).One(&doc); err != nil {
|
if err := queryResult.Skip(index).One(&doc); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return this.wrapDocumentWithMetadata(doc, query)
|
return this.wrapDocumentWithMetadata(doc, queryResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VultureBackend) wrapDocumentWithMetadata(doc map[string]interface{}, query *mgo.Query) (map[string]interface{}, error) {
|
func (this *VultureBackend) wrapDocumentWithMetadata(doc map[string]interface{}, query *mgo.Query) (map[string]interface{}, error) {
|
||||||
@@ -136,5 +138,30 @@ func getDocumentByIndex(w http.ResponseWriter, request *http.Request) (interface
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("index field is not an inteder ( " + indexAsString + ")")
|
return nil, errors.New("index field is not an inteder ( " + indexAsString + ")")
|
||||||
}
|
}
|
||||||
return vb.GetDocumentByIndex(index)
|
return vb.GetDocumentByIndex(index, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDocumentByQueryAndIndex(w http.ResponseWriter, request *http.Request) (interface{}, error) {
|
||||||
|
vb, err := GetVultureBackend(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vars := mux.Vars(request)
|
||||||
|
indexAsString, ok := vars["index"]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("index field not specified")
|
||||||
|
}
|
||||||
|
index, err := strconv.Atoi(indexAsString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("index field is not an inteder ( " + indexAsString + ")")
|
||||||
|
}
|
||||||
|
queryString, ok := vars["query"]
|
||||||
|
if !ok || queryString == "" {
|
||||||
|
return vb.GetDocumentByIndex(index, nil)
|
||||||
|
}
|
||||||
|
query := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal([]byte(queryString), &query); err != nil {
|
||||||
|
return nil, errors.New("invalid json")
|
||||||
|
}
|
||||||
|
return vb.GetDocumentByIndex(index, query)
|
||||||
}
|
}
|
||||||
+3
-1
@@ -16,6 +16,8 @@
|
|||||||
"angular-local-storage": "~0.0.1",
|
"angular-local-storage": "~0.0.1",
|
||||||
"qunit": "~1.14.0",
|
"qunit": "~1.14.0",
|
||||||
"zepto": "~1.1.3",
|
"zepto": "~1.1.3",
|
||||||
"fontawesome": "~4.0.3"
|
"fontawesome": "~4.0.3",
|
||||||
|
"angular-leaflet-directive": "~0.7.7",
|
||||||
|
"leaflet": "~0.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,112 @@
|
|||||||
root = this;
|
root = this;
|
||||||
|
|
||||||
|
mongoJsToMongoJSON = (queryString) ->
|
||||||
|
ObjectId = (id) ->
|
||||||
|
return {"$oid": id}
|
||||||
|
|
||||||
|
DBRef = (name, id) ->
|
||||||
|
return {"$ref": name, "$id": id}
|
||||||
|
|
||||||
|
Timestamp = (t, i) ->
|
||||||
|
return {"t": t, "i": i}
|
||||||
|
NumberLong = (number) ->
|
||||||
|
return { "$numberLong": String(number)}
|
||||||
|
MaxKey = { "$maxKey": 1 }
|
||||||
|
MinKey = { "$minKey": 1 }
|
||||||
|
|
||||||
|
query = ""
|
||||||
|
eval("query = " + queryString)
|
||||||
|
fixQuery = (query) ->
|
||||||
|
if _.isArray(query)
|
||||||
|
for v, i in query
|
||||||
|
query[i] = fixQuery(v)
|
||||||
|
return query
|
||||||
|
if _.isRegExp(query)
|
||||||
|
options = ""
|
||||||
|
for k, option of {multiline: "m", global: "g", ignoreCase: "i"}
|
||||||
|
if query[k]
|
||||||
|
options += option
|
||||||
|
return { "$regex": query.source, "$options": options }
|
||||||
|
if _.isDate(query)
|
||||||
|
return { "$date": query.getTime()}
|
||||||
|
if query == undefined
|
||||||
|
return { "$undefined": true }
|
||||||
|
if _.isObject(query)
|
||||||
|
for k, v of query
|
||||||
|
query[k] = fixQuery(v)
|
||||||
|
return query
|
||||||
|
return query
|
||||||
|
|
||||||
|
return fixQuery(query)
|
||||||
|
|
||||||
|
testmongoJsToMongoJSON = () ->
|
||||||
|
assertEqual = (a, b) ->
|
||||||
|
if not _.isEqual(a, b)
|
||||||
|
console.log("error! ", a, " != ", b)
|
||||||
|
s = """{a: 89}"""
|
||||||
|
assertEqual(mongoJsToMongoJSON(s), {a : 89})
|
||||||
|
s = """{a: [1,3,{reg: /allo/gim}]}"""
|
||||||
|
assertEqual(mongoJsToMongoJSON(s), {a: [1,3, {reg: { "$regex":"allo", "$options": "mgi" }}]})
|
||||||
|
s = """{a: [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
{reg:
|
||||||
|
[/allo/gim,
|
||||||
|
new Date("2014-05-08T21:52:24.320Z")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}"""
|
||||||
|
assertEqual(mongoJsToMongoJSON(s), {a: [1,3, {reg: [{ "$regex":"allo", "$options": "mgi" }, {"$date": 1399585944320}]}]})
|
||||||
|
|
||||||
|
|
||||||
|
testmongoJsToMongoJSON()
|
||||||
|
|
||||||
root.controllers.controller('documentCtrl', ['$scope', '$routeParams', '$http', ($scope, $routeParams, $http) ->
|
root.controllers.controller('documentCtrl', ['$scope', '$routeParams', '$http', ($scope, $routeParams, $http) ->
|
||||||
$scope.idx = $routeParams.idx
|
$scope.idx = $routeParams.idx
|
||||||
$scope.doc = {}
|
$scope.doc = {}
|
||||||
$scope.idx = Number($routeParams.idx)
|
$scope.idx = Number($routeParams.idx)
|
||||||
$scope.meta = {}
|
$scope.meta = {}
|
||||||
$http.get("/api/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$routeParams.idx - 1}").then((res) ->
|
$scope.newQuery = $routeParams.query or ""
|
||||||
|
|
||||||
|
url = "/api/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }"
|
||||||
|
if $routeParams.query
|
||||||
|
url = "#{url}/query/#{$routeParams.query}"
|
||||||
|
url = "#{ url }/idx/#{$routeParams.idx - 1}"
|
||||||
|
|
||||||
|
$http.get(url).then((res) ->
|
||||||
$scope.doc = res.data.document
|
$scope.doc = res.data.document
|
||||||
$scope.meta = res.data.meta
|
$scope.meta = res.data.meta
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$scope.parseQueryToJSON = (query) ->
|
||||||
|
try
|
||||||
|
ret = JSON.stringify(mongoJsToMongoJSON(query))
|
||||||
|
$scope.error = ""
|
||||||
|
return ret
|
||||||
|
catch error
|
||||||
|
$scope.error
|
||||||
|
return ""
|
||||||
|
|
||||||
|
$scope.getQueryPath = ()->
|
||||||
|
query = $scope.parseQueryToJSON($scope.newQuery)
|
||||||
|
if query == ""
|
||||||
|
return ""
|
||||||
|
return "#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/1/query/#{query}"
|
||||||
|
|
||||||
$scope.previousDocumentUrl = () ->
|
$scope.previousDocumentUrl = () ->
|
||||||
"#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$scope.idx - 1}"
|
url = "#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$scope.idx - 1}"
|
||||||
|
if $routeParams.query
|
||||||
|
url = "/query/#{$routeParams.query}"
|
||||||
|
return url
|
||||||
|
|
||||||
$scope.nextDocumentUrl = () ->
|
$scope.nextDocumentUrl = () ->
|
||||||
"#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$scope.idx + 1}"
|
url = "#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$scope.idx + 1}"
|
||||||
|
if $routeParams.query
|
||||||
|
url = "/query/#{$routeParams.query}"
|
||||||
|
return url
|
||||||
|
|
||||||
$scope.hasPreviousDocument = () ->
|
$scope.hasPreviousDocument = () ->
|
||||||
$scope.idx > 1
|
$scope.idx > 1
|
||||||
|
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
root = this;
|
||||||
|
|
||||||
|
|
||||||
|
root.controllers.controller('geojsonmapCtrl', ['$scope', '$routeParams', '$http', ($scope, $routeParams, $http) ->
|
||||||
|
$scope.geojson = {}
|
||||||
|
$scope.geojsonData = {}
|
||||||
|
$scope.idx = Number($routeParams.idx)
|
||||||
|
$scope.center = # experimental point around Québec
|
||||||
|
lat: 46.1227
|
||||||
|
lng: -72.6169
|
||||||
|
zoom: 7
|
||||||
|
|
||||||
|
|
||||||
|
$http.get("/api/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$routeParams.idx - 1}").then((res) ->
|
||||||
|
$scope.geojson = res.data.document[$routeParams.key]
|
||||||
|
if not $scope.geojson.properties
|
||||||
|
$scope.geojson.properties = {}
|
||||||
|
$scope.geojson.properties["_vulture_url_link"] = ""
|
||||||
|
$scope.meta = res.data.meta
|
||||||
|
$scope.geojsonData =
|
||||||
|
data: $scope.geojson
|
||||||
|
style: undefined
|
||||||
|
resetStyleOnMouseout: true
|
||||||
|
)
|
||||||
|
|
||||||
|
$scope.previousDocumentUrl = () ->
|
||||||
|
"#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$scope.idx - 1}/geojson/#{$routeParams.key}"
|
||||||
|
|
||||||
|
$scope.nextDocumentUrl = () ->
|
||||||
|
"#/#{ $routeParams.server }/#{ $routeParams.database }/#{ $routeParams.collection }/idx/#{$scope.idx + 1}/geojson/#{$routeParams.key}"
|
||||||
|
|
||||||
|
$scope.hasPreviousDocument = () ->
|
||||||
|
$scope.idx > 1
|
||||||
|
|
||||||
|
$scope.$on "leafletDirectiveMap.geojsonClick", (ev, featureSelected, leafletEvent) ->
|
||||||
|
a = 90
|
||||||
|
b = 89
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
@@ -3,9 +3,11 @@ root = this;
|
|||||||
root.controllers.controller('topBarCtrl', ['$scope', '$location', ($scope, $location) ->
|
root.controllers.controller('topBarCtrl', ['$scope', '$location', ($scope, $location) ->
|
||||||
$scope.$on('$routeChangeSuccess', (next, current) ->
|
$scope.$on('$routeChangeSuccess', (next, current) ->
|
||||||
$scope.path = _.filter($location.path().split("/"), (s) -> s)
|
$scope.path = _.filter($location.path().split("/"), (s) -> s)
|
||||||
|
if $scope.path[5] == "query"
|
||||||
|
$scope.path = $scope.path[0...-1]
|
||||||
$scope.getHistoryUrl = (idx) ->
|
$scope.getHistoryUrl = (idx) ->
|
||||||
ret = "#/" + ($scope.path[i] for i in [0...idx]).join("/")
|
ret = "#/" + ($scope.path[i] for i in [0...idx]).join("/")
|
||||||
if $scope.path[idx] == "idx"
|
if _.indexOf(["idx", "geojson"], $scope.path[idx]) != -1
|
||||||
return ""
|
return ""
|
||||||
if idx == 0
|
if idx == 0
|
||||||
ret += "servers"
|
ret += "servers"
|
||||||
@@ -13,6 +15,8 @@ root.controllers.controller('topBarCtrl', ['$scope', '$location', ($scope, $loca
|
|||||||
ret += "/databases"
|
ret += "/databases"
|
||||||
else if idx == 2
|
else if idx == 2
|
||||||
ret += "/collections"
|
ret += "/collections"
|
||||||
|
else if idx == 4
|
||||||
|
ret += "/#{ $scope.path[4] }"
|
||||||
return ret
|
return ret
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
@@ -1,4 +1,20 @@
|
|||||||
|
|
||||||
|
hasIndex = (keyName, indexes) ->
|
||||||
|
for index in indexes
|
||||||
|
if _.indexOf(index.keys, keyName) != -1
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
hasIndexAsc = (keyName, indexes) ->
|
||||||
|
hasIndex(keyName, indexes)
|
||||||
|
|
||||||
|
hasIndexDesc = (keyName, indexes) ->
|
||||||
|
hasIndex("-#{keyName}", indexes)
|
||||||
|
|
||||||
|
|
||||||
|
has2dIndex = (keyName, indexes) ->
|
||||||
|
hasIndex("$2dsphere:#{keyName}", indexes)
|
||||||
|
|
||||||
directive = () ->
|
directive = () ->
|
||||||
directive =
|
directive =
|
||||||
templateUrl: "/partials/directives/key.html"
|
templateUrl: "/partials/directives/key.html"
|
||||||
@@ -6,12 +22,17 @@ directive = () ->
|
|||||||
transclude: false,
|
transclude: false,
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope:
|
scope:
|
||||||
value: "="
|
keyName: "="
|
||||||
controller:["$scope", ($scope) ->
|
indexes: "="
|
||||||
$scope.hasIndexDown = false
|
controller:["$scope", "$routeParams", ($scope, $routeParams) ->
|
||||||
$scope.hasIndexUp = false
|
$scope.hasIndexDesc = hasIndexDesc($scope.keyName, $scope.indexes)
|
||||||
$scope.hasIndex = false
|
$scope.hasIndexAsc = hasIndexAsc($scope.keyName, $scope.indexes)
|
||||||
$scope.has2DIndexUp = false
|
$scope.has2DIndex = has2dIndex($scope.keyName, $scope.indexes)
|
||||||
|
$scope.showTools = false
|
||||||
|
$scope.hasIndex = $scope.hasIndexDown or $scope.hasIndexUp or $scope.has2DIndex
|
||||||
|
$scope.getGeoJsonUrl = () ->
|
||||||
|
r = $routeParams
|
||||||
|
return "#" + "/#{r.server}/#{r.database}/#{r.collection}/idx/#{r.idx}/geojson/#{$scope.keyName}"
|
||||||
]
|
]
|
||||||
return directive
|
return directive
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ root = this;
|
|||||||
|
|
||||||
angular.module('vulture', [
|
angular.module('vulture', [
|
||||||
'ngRoute'
|
'ngRoute'
|
||||||
|
'leaflet-directive'
|
||||||
'vulture.filters'
|
'vulture.filters'
|
||||||
'vulture.services'
|
'vulture.services'
|
||||||
'vulture.directives'
|
'vulture.directives'
|
||||||
@@ -14,6 +15,8 @@ config(['$routeProvider', ($routeProvider) ->
|
|||||||
$routeProvider.when('/:server/databases', {templateUrl: 'partials/databases.html', controller: 'databasesCtrl'})
|
$routeProvider.when('/:server/databases', {templateUrl: 'partials/databases.html', controller: 'databasesCtrl'})
|
||||||
$routeProvider.when('/:server/:database/collections', {templateUrl: 'partials/collections.html', controller: 'collectionsCtrl'})
|
$routeProvider.when('/:server/:database/collections', {templateUrl: 'partials/collections.html', controller: 'collectionsCtrl'})
|
||||||
$routeProvider.when('/:server/:database/:collection/idx/:idx', {templateUrl: 'partials/document.html', controller: 'documentCtrl'})
|
$routeProvider.when('/:server/:database/:collection/idx/:idx', {templateUrl: 'partials/document.html', controller: 'documentCtrl'})
|
||||||
|
$routeProvider.when('/:server/:database/:collection/idx/:idx/query/:query', {templateUrl: 'partials/document.html', controller: 'documentCtrl'})
|
||||||
|
$routeProvider.when('/:server/:database/:collection/idx/:idx/geojson/:key', {templateUrl: 'partials/geojsonmap.html', controller: 'geojsonmapCtrl'})
|
||||||
|
|
||||||
$routeProvider.otherwise({redirectTo: '/servers'})
|
$routeProvider.otherwise({redirectTo: '/servers'})
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<link rel="stylesheet" href="bower_components/foundation/css/foundation.css">
|
<link rel="stylesheet" href="bower_components/foundation/css/foundation.css">
|
||||||
<link rel="stylesheet" href="bower_components/foundation/css/normalize.css">
|
<link rel="stylesheet" href="bower_components/foundation/css/normalize.css">
|
||||||
<link rel="stylesheet" href="bower_components/fontawesome/css/font-awesome.css">
|
<link rel="stylesheet" href="bower_components/fontawesome/css/font-awesome.css">
|
||||||
|
<link rel="stylesheet" href="bower_components/leaflet-dist/leaflet.css">
|
||||||
|
|
||||||
|
|
||||||
<!-- If you are using the gem version, you need this only -->
|
<!-- If you are using the gem version, you need this only -->
|
||||||
@@ -37,10 +38,13 @@
|
|||||||
|
|
||||||
<div ng-view></div>
|
<div ng-view></div>
|
||||||
|
|
||||||
|
<script src="bower_components/leaflet-dist/leaflet.js"></script>
|
||||||
<script src="bower_components/underscore/underscore.js"></script>
|
<script src="bower_components/underscore/underscore.js"></script>
|
||||||
<script src="bower_components/jquery/dist/jquery.js"></script>
|
<script src="bower_components/jquery/dist/jquery.js"></script>
|
||||||
<script src="bower_components/foundation/js/foundation.js"></script>
|
<script src="bower_components/foundation/js/foundation.js"></script>
|
||||||
<script src="bower_components/angular-route/angular-route.js"></script>
|
<script src="bower_components/angular-route/angular-route.js"></script>
|
||||||
|
<script src="bower_components/angular-leaflet-directive/dist/angular-leaflet-directive.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script src="js/vultureApp.js"></script>
|
<script src="js/vultureApp.js"></script>
|
||||||
<script src="js/filters.js"></script>
|
<script src="js/filters.js"></script>
|
||||||
@@ -49,6 +53,7 @@
|
|||||||
<script src="js/controllers/databasesCtrl.js"></script>
|
<script src="js/controllers/databasesCtrl.js"></script>
|
||||||
<script src="js/controllers/collectionsCtrl.js"></script>
|
<script src="js/controllers/collectionsCtrl.js"></script>
|
||||||
<script src="js/controllers/documentCtrl.js"></script>
|
<script src="js/controllers/documentCtrl.js"></script>
|
||||||
|
<script src="js/controllers/geojsonmapCtrl.js"></script>
|
||||||
|
|
||||||
<script src="js/directives/key.js"></script>
|
<script src="js/directives/key.js"></script>
|
||||||
<script src="js/directives/value.js"></script>
|
<script src="js/directives/value.js"></script>
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<span>
|
<span ng-mouseenter="showTools=true" ng-mouseleave="showTools=false">
|
||||||
{{value}}
|
{{keyName}}
|
||||||
<span class="right" style="color:magenta">
|
|
||||||
<i class="fa fa-bolt" ng-show="hasIndex"></i>
|
<span ng-style="{visibility: showTools ? 'inline': 'hidden'}">
|
||||||
<i class="fa fa-sort-numeric-asc" ng-show="hasIndexDown"></i>
|
<!-- place to but some hoover information-->
|
||||||
<i class="fa fa-sort-numeric-desc" ng-show="hasIndexUp"></i>
|
</span>
|
||||||
<i class="fa fa-map-marker" ng-show="has2DIndexUp"></i>
|
<span class="right" style="color:#008CBA;">
|
||||||
|
<i class="fa fa-sort-numeric-asc" ng-show="hasIndexAsc"></i>
|
||||||
|
<i class="fa fa-sort-numeric-desc" ng-show="hasIndexDesc"></i>
|
||||||
|
<a class="fa fa-globe" ng-show="has2DIndex" ng-href="{{ getGeoJsonUrl() }}" target="_blank"></a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-9 columns">
|
<div class="large-9 columns">
|
||||||
<input type="text">
|
<input type="text" ng-model="newQuery">
|
||||||
</div>
|
</div>
|
||||||
<div class="large-3 columns right">
|
<div class="large-3 columns right">
|
||||||
<ul class="button-group">
|
<ul class="button-group">
|
||||||
<li><a class="button tiny">Query</a></li>
|
<li><a class="button tiny" ng-href="{{ getQueryPath() }}">Query</a></li>
|
||||||
<li><a class="button tiny">Clear</a></li>
|
<li><a class="button tiny">Clear</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-12 columns" style="text-align: center;">
|
<div class="large-12 columns" style="text-align: center;">
|
||||||
<a class="fa fa-angle-left" ng-href="{{ previousDocumentUrl() }}" ng-show="{{ hasPreviousDocument() }}"></a>
|
<a class="fa fa-angle-left" ng-href="{{ previousDocumentUrl() }}" ng-show="{{ hasPreviousDocument() }}"></a>
|
||||||
<kbd>{{idx}} / {{ meta.count}}</kbd>
|
<kbd>{{idx}} / {{ meta.count | number | replaceAllCommasBySpaces }}</kbd>
|
||||||
<a class="fa fa-angle-right" ng-href="{{ nextDocumentUrl() }}"></a>
|
<a class="fa fa-angle-right" ng-href="{{ nextDocumentUrl() }}"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -29,8 +29,12 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="(key, value) in doc">
|
<tr ng-repeat="(key, value) in doc">
|
||||||
<td style="vertical-align: top;"><vul-key value="key"></vul-key></td>
|
<td style="vertical-align: top;">
|
||||||
<td><vul-value value="value"></vul-value></td>
|
<vul-key key-name="key" indexes="meta.indexes" ></vul-key>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<vul-value value="value"></vul-value>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="row">
|
||||||
|
<div class="large-12 columns" style="text-align: center;">
|
||||||
|
<a class="fa fa-angle-left" ng-href="{{ previousDocumentUrl() }}" ng-show="{{ hasPreviousDocument() }}"></a>
|
||||||
|
<kbd>{{idx}} / {{ meta.count}}</kbd>
|
||||||
|
<a class="fa fa-angle-right" ng-href="{{ nextDocumentUrl() }}"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns large-12">
|
||||||
|
<leaflet width="100%" height="500px" geojson="geojsonData" center="center"></leaflet>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ type ApiHandler func(w http.ResponseWriter, request *http.Request) (interface{},
|
|||||||
func (this ApiHandler) ServeHTTP(w http.ResponseWriter, request *http.Request) {
|
func (this ApiHandler) ServeHTTP(w http.ResponseWriter, request *http.Request) {
|
||||||
ret, err := this(w, request)
|
ret, err := this(w, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
ret = &errorWrapper{err}
|
ret = &errorWrapper{err}
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func serveApi(router *mux.Router) {
|
|||||||
router.Handle("/{server}/databases", ApiHandler(getAvailableDataBases))
|
router.Handle("/{server}/databases", ApiHandler(getAvailableDataBases))
|
||||||
router.Handle("/{server}/{database}/collections", ApiHandler(getAvailableCollections))
|
router.Handle("/{server}/{database}/collections", ApiHandler(getAvailableCollections))
|
||||||
router.Handle("/{server}/{database}/{collection}/idx/{index:[0-9]+}", ApiHandler(getDocumentByIndex))
|
router.Handle("/{server}/{database}/{collection}/idx/{index:[0-9]+}", ApiHandler(getDocumentByIndex))
|
||||||
|
router.Handle("/{server}/{database}/{collection}/query/{query}/idx/{index:[0-9]+}", ApiHandler(getDocumentByQueryAndIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMuxRouter() http.Handler {
|
func createMuxRouter() http.Handler {
|
||||||
|
|||||||
Reference in new issue
Block a user