started new web client
This commit is contained in:
1 parent
1b3d0ea70b
commit
fcff74109a
33 files changed
+230
-2583
No files matched your search
@@ -4,7 +4,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/didiercrunch/doormanserver/logpublisher"
|
"github.com/didiercrunch/doormanserver/logpublisher"
|
||||||
"github.com/didiercrunch/doormanserver/nanomsgpublisher"
|
|
||||||
"github.com/didiercrunch/doormanserver/nsqpublisher"
|
"github.com/didiercrunch/doormanserver/nsqpublisher"
|
||||||
"github.com/didiercrunch/doormanserver/shared"
|
"github.com/didiercrunch/doormanserver/shared"
|
||||||
"gopkg.in/mgo.v2/bson"
|
"gopkg.in/mgo.v2/bson"
|
||||||
@@ -25,21 +24,10 @@ func initNSQPublisher() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initNanoMsgPublisher() {
|
|
||||||
publisher = new(nanomsgpublisher.NanoMsgPublisher)
|
|
||||||
if err := publisher.Init(); err != nil {
|
|
||||||
log.Panic(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func initPublisher(params *shared.Params) {
|
func initPublisher(params *shared.Params) {
|
||||||
if params.UseNSQ() {
|
if params.UseNSQ() {
|
||||||
initNSQPublisher()
|
initNSQPublisher()
|
||||||
log.Println("using nsq as message queue")
|
log.Println("using nsq as message queue")
|
||||||
} else if params.UseNanomsg() {
|
|
||||||
initNanoMsgPublisher()
|
|
||||||
log.Println("using nanomsg as message queue")
|
|
||||||
} else {
|
} else {
|
||||||
publisher = &logpublisher.LogPublisher{log.Println}
|
publisher = &logpublisher.LogPublisher{log.Println}
|
||||||
log.Println("using stdout as message queue")
|
log.Println("using stdout as message queue")
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package nanomsgpublisher
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/didiercrunch/doormanserver/shared"
|
|
||||||
"github.com/go-mangos/mangos"
|
|
||||||
"github.com/go-mangos/mangos/protocol/pub"
|
|
||||||
"github.com/go-mangos/mangos/transport/ipc"
|
|
||||||
"github.com/go-mangos/mangos/transport/tcp"
|
|
||||||
"gopkg.in/mgo.v2/bson"
|
|
||||||
)
|
|
||||||
|
|
||||||
type NanoMsgPublisher struct {
|
|
||||||
Url string
|
|
||||||
sock mangos.Socket
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *NanoMsgPublisher) Init() error {
|
|
||||||
var err error
|
|
||||||
if p.sock, err = pub.NewSocket(); err != nil {
|
|
||||||
return errors.New("can't listen on pub socket:" + err.Error())
|
|
||||||
}
|
|
||||||
p.sock.AddTransport(ipc.NewTransport())
|
|
||||||
p.sock.AddTransport(tcp.NewTransport())
|
|
||||||
if err = p.sock.Listen(shared.GetParams().NanoMsg.NanoMsgUrl); err != nil {
|
|
||||||
return errors.New("can't listen on pub socket: %s" + err.Error())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *NanoMsgPublisher) Emit(doormanId bson.ObjectId, doorman shared.AsDoormanUpdatePayloader) error {
|
|
||||||
log.Println("Emit for ", doormanId.Hex())
|
|
||||||
if d, err := doorman.AsDoormanUpdatePayload(); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
return p.sock.Send(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"directory": "app/bower_components"
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
logs/*
|
|
||||||
!.gitkeep
|
|
||||||
node_modules/
|
|
||||||
bower_components/
|
|
||||||
tmp
|
|
||||||
.DS_Store
|
|
||||||
.idea
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "angular-requirejs-seed",
|
|
||||||
"description": "AngularJS seed project modified for requireJS support.",
|
|
||||||
"version": "0.2.0",
|
|
||||||
"homepage": "https://github.com/tnajdek/angular-requirejs-seed",
|
|
||||||
"license": "MIT",
|
|
||||||
"ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"node_modules",
|
|
||||||
"bower_components",
|
|
||||||
"test",
|
|
||||||
"tests"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"angular": "~1.2.1",
|
|
||||||
"angular-route": "~1.2.1",
|
|
||||||
"angular-scenario": "~1.2.1",
|
|
||||||
"angular-mocks": "~1.2.1",
|
|
||||||
"requirejs": "~2.1.9",
|
|
||||||
"requirejs-text": "~2.0.10",
|
|
||||||
"html5-boilerplate": "~4.3.0",
|
|
||||||
"angularAMD": "~0.2.1",
|
|
||||||
"angular-foundation": "~0.5.1",
|
|
||||||
"lodash": "~3.9.3",
|
|
||||||
"font-awesome": "~4.3.0",
|
|
||||||
"bourbon": "~4.2.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
|
|
||||||
define [
|
|
||||||
"angularAMD"
|
|
||||||
"lodash"
|
|
||||||
"angular-route"
|
|
||||||
"foundation"
|
|
||||||
|
|
||||||
], (angularAMD, _) ->
|
|
||||||
app = angular.module("webapp", ["ngRoute", "mm.foundation"])
|
|
||||||
app.config ($routeProvider) ->
|
|
||||||
$routeProvider.when("/", angularAMD.route(
|
|
||||||
templateUrl: "partials/home.html"
|
|
||||||
controller: "HomeCtrl"
|
|
||||||
controllerUrl: "controllers/homeCtrl"
|
|
||||||
)).when("/serverspec", angularAMD.route(
|
|
||||||
templateUrl: "partials/serverspec.html"
|
|
||||||
controller: "ServerspecCtrl"
|
|
||||||
controllerUrl: "controllers/serverspecCtrl"
|
|
||||||
)).when("/apispec", angularAMD.route(
|
|
||||||
templateUrl: "partials/apispec.html"
|
|
||||||
controller: "ApispecCtrl"
|
|
||||||
controllerUrl: "controllers/apispecCtrl"
|
|
||||||
)).when("/newdoorman", angularAMD.route(
|
|
||||||
templateUrl: "partials/newdoorman.html"
|
|
||||||
controller: "NewDoormanCtrl"
|
|
||||||
controllerUrl: "controllers/newdoormanCtrl"
|
|
||||||
)).when("/doormen", angularAMD.route(
|
|
||||||
templateUrl: "partials/doormen.html"
|
|
||||||
controller: "DoormenCtrl"
|
|
||||||
controllerUrl: "controllers/doormenCtrl"
|
|
||||||
)).when("/doormen/error/:error/:id", angularAMD.route(
|
|
||||||
templateUrl: "partials/doormanError.html"
|
|
||||||
controller: "DoormanErrorCtrl"
|
|
||||||
controllerUrl: "controllers/doormanErrorCtrl"
|
|
||||||
)).when("/doormen/:id", angularAMD.route(
|
|
||||||
templateUrl: "partials/doorman.html"
|
|
||||||
controller: "DoormanCtrl"
|
|
||||||
controllerUrl: "controllers/doormanCtrl"
|
|
||||||
)).otherwise({redirectTo: "/"})
|
|
||||||
|
|
||||||
document.getElementsByTagName("body")[0].style.visibility = ""
|
|
||||||
return
|
|
||||||
|
|
||||||
app.controller "topbarCtrl", ["$scope", "$rootScope", "$location", ($scope, $rootScope, $location) ->
|
|
||||||
|
|
||||||
$scope.init = () ->
|
|
||||||
$scope.email = localStorage.getItem("email")
|
|
||||||
$scope.loggedIn = !!$scope.email
|
|
||||||
if !$scope.loggedIn
|
|
||||||
$location.path('/').replace()
|
|
||||||
|
|
||||||
$scope.logout = () ->
|
|
||||||
localStorage.setItem("email", "")
|
|
||||||
$scope.email = ""
|
|
||||||
$scope.loggedIn = false
|
|
||||||
$scope.$emit("logout")
|
|
||||||
|
|
||||||
$scope.init()
|
|
||||||
$rootScope.$on('login', $scope.init)
|
|
||||||
return
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
angularAMD.bootstrap(app)
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
define ["app", "angularAMD"], (app, angularAMD) ->
|
|
||||||
app.controller "ApispecCtrl",['$scope', '$http', ($scope, $http) ->
|
|
||||||
$http.get("/api/documentation").then (res)->
|
|
||||||
$scope.endpoints = res.data.endpoints
|
|
||||||
|
|
||||||
$scope.methods =
|
|
||||||
get: "GET"
|
|
||||||
post: "POST"
|
|
||||||
]
|
|
||||||
|
|
||||||
angularAMD.directive "wabMethod", () ->
|
|
||||||
directive =
|
|
||||||
restrict: 'E',
|
|
||||||
scope:
|
|
||||||
method: '@'
|
|
||||||
link: (scope, element) ->
|
|
||||||
scope.methods =
|
|
||||||
get: "GET"
|
|
||||||
put: "PUT"
|
|
||||||
delete: "DELETE"
|
|
||||||
post: "POST"
|
|
||||||
|
|
||||||
template: '<code style="width:5em; display: block; text-align: center;">{{ methods[method] }}</code>'
|
|
||||||
return directive
|
|
||||||
|
|
||||||
angularAMD.directive "wabApi", () ->
|
|
||||||
directive =
|
|
||||||
restrict: 'E',
|
|
||||||
scope:
|
|
||||||
endpoint: '@'
|
|
||||||
template: '<a>/api{{ endpoint }}</a>'
|
|
||||||
return directive
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
define ["app", "lodash", "directives/ratinput"], (app, _, ratinput) ->
|
|
||||||
|
|
||||||
app.controller "DoormanCtrl", ["$scope", "$http","$routeParams","$location", "$timeout", ($scope, $http, $routeParams, $location, $timeout) ->
|
|
||||||
$scope.doorman = {values: []}
|
|
||||||
$scope.somevalue = "2/6"
|
|
||||||
$scope.apiurl = "/api/doormen/#{$routeParams.id}"
|
|
||||||
$scope.user = localStorage.getItem("email")
|
|
||||||
$scope.doormanChanged = false
|
|
||||||
|
|
||||||
$http.get($scope.apiurl).then((res) ->
|
|
||||||
$scope.doorman = res.data
|
|
||||||
$scope.isAdmin = _.contains($scope.doorman.emails, $scope.user)
|
|
||||||
$scope.initEmails()
|
|
||||||
|
|
||||||
).catch((res) ->
|
|
||||||
if res.status == 404
|
|
||||||
$location.path("/doormen/error/#{res.status}/#{$routeParams.id}")
|
|
||||||
)
|
|
||||||
|
|
||||||
$scope.deleteDoorman = () ->
|
|
||||||
console.log("not yet implemented")
|
|
||||||
|
|
||||||
$scope.initEmails = () ->
|
|
||||||
[$scope.leftEmailColumns, $scope.rightEmailColumns] = _.chunk($scope.doorman.emails, 2)
|
|
||||||
|
|
||||||
$scope.rationalToFloat = (rat) ->
|
|
||||||
if _.contains(rat, "/")
|
|
||||||
num = Number(rat.substr(0, rat.indexOf("/")))
|
|
||||||
denum = Number(rat.substr(rat.indexOf("/") + 1))
|
|
||||||
return num / denum
|
|
||||||
Number(rat)
|
|
||||||
|
|
||||||
|
|
||||||
$scope.validate = ()->
|
|
||||||
ret = 0
|
|
||||||
for val in $scope.doorman.values
|
|
||||||
ret += $scope.rationalToFloat(val.probability)
|
|
||||||
return Math.abs(ret - 1.0) < 0.000001
|
|
||||||
|
|
||||||
$scope.addNewAuthorEmail = () ->
|
|
||||||
if not $scope.canAddNewEmail()
|
|
||||||
return
|
|
||||||
$scope.doorman.emails.push($scope.newEmail)
|
|
||||||
$scope.updateDoorman()
|
|
||||||
$scope.newEmail = ""
|
|
||||||
$scope.initEmails()
|
|
||||||
|
|
||||||
$scope.removeEmail = (email) ->
|
|
||||||
$scope.doorman.emails = _.reject($scope.doorman.emails , (email_) -> email_ == email)
|
|
||||||
$scope.initEmails()
|
|
||||||
$scope.updateDoorman()
|
|
||||||
|
|
||||||
$scope.canAddNewEmail = ()->
|
|
||||||
if !$scope.newEmail or $scope.newEmail.length < 5
|
|
||||||
return false
|
|
||||||
not _.contains($scope.doorman.emails, $scope.newEmail)
|
|
||||||
|
|
||||||
|
|
||||||
$scope.updateDoorman = () ->
|
|
||||||
if !$scope.validate()
|
|
||||||
return
|
|
||||||
params = {params: {user: $scope.user}}
|
|
||||||
$http.put($scope.apiurl, $scope.doorman, params).then((ret)->
|
|
||||||
console.log "update"
|
|
||||||
).then((res) ->
|
|
||||||
$scope.doormanChanged = true
|
|
||||||
$timeout(() ->
|
|
||||||
$scope.doormanChanged = false
|
|
||||||
, 3000)
|
|
||||||
).catch((res) ->
|
|
||||||
$scope.error =
|
|
||||||
message: res.data
|
|
||||||
status : res.status
|
|
||||||
)
|
|
||||||
]
|
|
||||||
return
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
define ["app"], (app) ->
|
|
||||||
app.controller "DoormanErrorCtrl", ["$scope","$routeParams", ($scope, $routeParams) ->
|
|
||||||
$scope.id = $routeParams.id
|
|
||||||
$scope.error = Number($routeParams.error)
|
|
||||||
]
|
|
||||||
return
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
define ["app"], (app) ->
|
|
||||||
app.controller "DoormenCtrl",[ "$scope", "$http", ($scope, $http) ->
|
|
||||||
$scope.doormen = []
|
|
||||||
$http.get("/api/doormen").then (res) ->
|
|
||||||
$scope.doormen = res.data.doormen
|
|
||||||
return
|
|
||||||
]
|
|
||||||
|
|
||||||
return
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
define ["app"], (app) ->
|
|
||||||
app.controller "HomeCtrl", ['$scope', '$rootScope', ($scope, $rootScope) ->
|
|
||||||
$scope.init = () ->
|
|
||||||
$scope.loggedEmail = localStorage.getItem("email")
|
|
||||||
|
|
||||||
$scope.login = () ->
|
|
||||||
if $scope.email
|
|
||||||
localStorage.setItem("email", $scope.email)
|
|
||||||
$scope.loggedEmail = $scope.email
|
|
||||||
$scope.email = ""
|
|
||||||
$scope.$emit("login")
|
|
||||||
|
|
||||||
$scope.init()
|
|
||||||
$rootScope.$on('logout', $scope.init)
|
|
||||||
]
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
epsilon = 0.0001
|
|
||||||
|
|
||||||
define ["app", "lodash", "../filters", "directives/ratinput"], (app, _, filters, ratinput) ->
|
|
||||||
app.controller "NewDoormanCtrl", ["$scope", "$http", "$location", "rationals", ($scope, $http, $location, rationals) ->
|
|
||||||
$scope.error = ""
|
|
||||||
$scope.user = localStorage.getItem("email")
|
|
||||||
$scope.value = {probability: "1", name: ""}
|
|
||||||
$scope.payload =
|
|
||||||
name: ""
|
|
||||||
values: []
|
|
||||||
emails: [$scope.user]
|
|
||||||
|
|
||||||
$scope.isValidValue = () ->
|
|
||||||
return $scope.value.name
|
|
||||||
|
|
||||||
$scope.addNewValue = () ->
|
|
||||||
if !$scope.isValidValue()
|
|
||||||
return
|
|
||||||
$scope.payload.values.push($scope.value)
|
|
||||||
$scope.value =
|
|
||||||
name: ""
|
|
||||||
probability: $scope.getProbabilityRemaining()
|
|
||||||
|
|
||||||
$scope.removeValue = (idx) ->
|
|
||||||
$scope.payload.values.splice(idx, 1);
|
|
||||||
|
|
||||||
$scope.getProbabilityRemaining = () ->
|
|
||||||
sum = rationals.sum(_.pluck($scope.payload.values, "probability")...)
|
|
||||||
return rationals.minus("1", sum)
|
|
||||||
|
|
||||||
|
|
||||||
$scope.redirectToDoorman = (doormanLocation) ->
|
|
||||||
$http.get(doormanLocation).then (res) ->
|
|
||||||
id = res.data.id
|
|
||||||
return $location.url("/doormen/#{id}")
|
|
||||||
|
|
||||||
$scope.getPayload = () ->
|
|
||||||
payload = _.cloneDeep($scope.payload)
|
|
||||||
for value in payload.values
|
|
||||||
value.probability = value.probability
|
|
||||||
return payload
|
|
||||||
|
|
||||||
$scope.createDoorman = () ->
|
|
||||||
if not $scope.isDoormanValid()
|
|
||||||
return
|
|
||||||
params = {params: {user: $scope.user}}
|
|
||||||
$http.post("/api/doormen", $scope.getPayload(), params).
|
|
||||||
then((res, s) ->
|
|
||||||
$scope.redirectToDoorman(res.headers("location"))
|
|
||||||
).catch((res) ->
|
|
||||||
$scope.error = res.data
|
|
||||||
)
|
|
||||||
|
|
||||||
$scope.isDoormanValid = () ->
|
|
||||||
if not $scope.payload.name
|
|
||||||
return false
|
|
||||||
if $scope.payload.values.length < 2
|
|
||||||
return false
|
|
||||||
rationals.equal($scope.getProbabilityRemaining(), "0" )
|
|
||||||
|
|
||||||
|
|
||||||
$scope.addEmail = () ->
|
|
||||||
if not $scope.newEmail
|
|
||||||
return
|
|
||||||
$scope.payload.emails.push($scope.newEmail)
|
|
||||||
$scope.newEmail = ""
|
|
||||||
|
|
||||||
$scope.removeEmail = (idx) ->
|
|
||||||
if $scope.payload.emails[idx] == $scope.user
|
|
||||||
return
|
|
||||||
$scope.payload.emails.splice(idx, 1);
|
|
||||||
|
|
||||||
$scope.getSum = () ->
|
|
||||||
probs = _.pluck($scope.payload.values, "probability")
|
|
||||||
return rationals.pp(rationals.sum(probs...))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return
|
|
||||||
]
|
|
||||||
|
|
||||||
return
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
define ["app"], (app) ->
|
|
||||||
app.controller "ServerspecCtrl",["$scope", "$http", ($scope, $http) ->
|
|
||||||
$scope.server = {}
|
|
||||||
$http.get("/api/server").then (res) -> $scope.server = res.data
|
|
||||||
return
|
|
||||||
]
|
|
||||||
return
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
define ["app"], (app) ->
|
|
||||||
app.controller "sideBarCtrl", ($scope) ->
|
|
||||||
$scope.message = "Message from MyCtrl1"
|
|
||||||
return
|
|
||||||
|
|
||||||
return
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
template = """
|
|
||||||
<div class="row rat-input">
|
|
||||||
<div class="row" ng-show="!edit" >
|
|
||||||
<div class="columns large-12" style="text-align: center;">
|
|
||||||
<span class="fraction-box" ng-click="enableEdit()">
|
|
||||||
<span ng-bind="nominator"></span> ⁄ <span ng-bind="denominator" ></span>
|
|
||||||
<i class="fa fa-pencil-square-o" ng-show="!ngDisabled"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div ng-show="edit" class="edit">
|
|
||||||
<form ng-submit="edit=false">
|
|
||||||
<div class="large-12 columns" style="text-align: center;">
|
|
||||||
<input ng-model="nominator" type="text" ng-change="changeModel()" ng-disabled="ngDisabled">
|
|
||||||
<span style="text-align: center;">⁄<span>
|
|
||||||
<input ng-model="denominator" type="text" ng-change="changeModel()" ng-disabled="ngDisabled">
|
|
||||||
<i class="fa fa-check" ng-click="edit=false"></i>
|
|
||||||
<input type="submit" style="display:none;">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
define ["app", "angularAMD", "lodash", "services/rationals"], (app, angularAMD, _, rationals) ->
|
|
||||||
|
|
||||||
angularAMD.directive "ratInput", () ->
|
|
||||||
directive =
|
|
||||||
restrict: 'E',
|
|
||||||
template: template
|
|
||||||
scope:
|
|
||||||
ngModel: "="
|
|
||||||
ngDisabled: "="
|
|
||||||
controller: [ '$scope', "rationals", ($scope, rationals) ->
|
|
||||||
|
|
||||||
$scope.getNominator = ()->
|
|
||||||
if _.contains($scope.ngModel, "/")
|
|
||||||
return Number($scope.ngModel.substr(0, $scope.ngModel.indexOf("/")))
|
|
||||||
Number($scope.ngModel)
|
|
||||||
|
|
||||||
$scope.getDenominator = () ->
|
|
||||||
if _.contains($scope.ngModel, "/")
|
|
||||||
return Number($scope.ngModel.substr($scope.ngModel.indexOf("/") + 1))
|
|
||||||
1
|
|
||||||
|
|
||||||
$scope.changeModel = ()->
|
|
||||||
$scope.ngModel = rationals.newRat($scope.nominator, $scope.denominator)
|
|
||||||
|
|
||||||
$scope.enableEdit = () ->
|
|
||||||
if not $scope.ngDisabled
|
|
||||||
$scope.edit = true
|
|
||||||
|
|
||||||
$scope.init = () ->
|
|
||||||
$scope.nominator = rationals.getNominator($scope.ngModel)
|
|
||||||
$scope.denominator = $scope.getDenominator()
|
|
||||||
|
|
||||||
$scope.$watch 'ngModel', () ->
|
|
||||||
$scope.init()
|
|
||||||
|
|
||||||
$scope.init()
|
|
||||||
|
|
||||||
]
|
|
||||||
return directive
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
define ['angularAMD', 'app'], (angular, app) ->
|
|
||||||
app.filter 'reverse', ->
|
|
||||||
(items) ->
|
|
||||||
if !Array.isArray(items)
|
|
||||||
return false
|
|
||||||
items.slice().reverse()
|
|
||||||
return
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
require.config
|
|
||||||
baseUrl: "js"
|
|
||||||
|
|
||||||
# alias libraries paths. Must set 'angular'
|
|
||||||
paths:
|
|
||||||
"angular" : "/bower_components/angular/angular.min"
|
|
||||||
"angular-route": "/bower_components/angular-route/angular-route.min"
|
|
||||||
"angularAMD" : "/bower_components/angularAMD/angularAMD.min"
|
|
||||||
"foundation" : "/bower_components/angular-foundation/mm-foundation-tpls"
|
|
||||||
"lodash" : "/bower_components/lodash/lodash.min"
|
|
||||||
|
|
||||||
|
|
||||||
# Add angular modules that does not support AMD out of the box, put it in a shim
|
|
||||||
shim:
|
|
||||||
"angularAMD": ["angular"]
|
|
||||||
"angular-route": ["angular"]
|
|
||||||
"foundation" : ["angular"]
|
|
||||||
|
|
||||||
|
|
||||||
# kick start application
|
|
||||||
deps: ["app"]
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
define ["app", "angularAMD", "lodash"], (app, angularAMD, _) ->
|
|
||||||
|
|
||||||
app.service "rationals", () ->
|
|
||||||
service =
|
|
||||||
getNominator: (rat) ->
|
|
||||||
if _.contains(rat, "/")
|
|
||||||
return Number(rat.substr(0, rat.indexOf("/")))
|
|
||||||
Number(rat)
|
|
||||||
|
|
||||||
getDenominator: (rat) ->
|
|
||||||
if _.contains(rat, "/")
|
|
||||||
return Number(rat.substr(rat.indexOf("/") + 1))
|
|
||||||
1
|
|
||||||
|
|
||||||
getNomDenom: (rat) ->
|
|
||||||
return [service.getNominator(rat), service.getDenominator(rat)]
|
|
||||||
|
|
||||||
gcd: (a, b) ->
|
|
||||||
if b == 0
|
|
||||||
return a
|
|
||||||
return service.gcd(b, a % b)
|
|
||||||
|
|
||||||
lcm: (a, b) ->
|
|
||||||
return a * b / service.gcd(a, b)
|
|
||||||
|
|
||||||
changeDenominator: (rat, newDenom) ->
|
|
||||||
[nom, denom] = service.getNomDenom(rat)
|
|
||||||
return service.newRat( nom * newDenom / denom, newDenom)
|
|
||||||
|
|
||||||
add: (rat1, rat2) ->
|
|
||||||
[nom, denom] = service.getNomDenom(rat2)
|
|
||||||
[nNom, nDenom] = service.getNomDenom(rat1)
|
|
||||||
gcd = service.gcd(nDenom, denom)
|
|
||||||
|
|
||||||
rNom = nom*nDenom + nNom * denom
|
|
||||||
rDenom = denom * nDenom
|
|
||||||
return service.newRat(rNom/gcd , rDenom/gcd)
|
|
||||||
|
|
||||||
minus: (rat1, rat2) ->
|
|
||||||
return service.add(rat1, service.opposite(rat2))
|
|
||||||
|
|
||||||
reduce: (rat) ->
|
|
||||||
[nom, denom] = service.getNomDenom(rat)
|
|
||||||
gcd = service.gcd(nom, denom)
|
|
||||||
return service.newRat(nom/gcd, denom/gcd)
|
|
||||||
|
|
||||||
opposite: (rat) ->
|
|
||||||
[nom, denom] = service.getNomDenom(rat)
|
|
||||||
return service.newRat(-nom, denom)
|
|
||||||
|
|
||||||
|
|
||||||
sum: (rats...) ->
|
|
||||||
ret = "0/1"
|
|
||||||
for rat in rats
|
|
||||||
ret = service.add(ret, rat)
|
|
||||||
return service.reduce(ret)
|
|
||||||
|
|
||||||
equal: (rat1, rat2) ->
|
|
||||||
[nom1, denom1] = service.getNomDenom(rat1)
|
|
||||||
[nom2, denom2] = service.getNomDenom(rat2)
|
|
||||||
return nom1 * denom2 == nom2 * denom1
|
|
||||||
|
|
||||||
pp: (x) ->
|
|
||||||
[num, denum] = service.getNomDenom(service.reduce(x))
|
|
||||||
if denum == 1
|
|
||||||
return num
|
|
||||||
return "#{num}/#{denum}"
|
|
||||||
|
|
||||||
|
|
||||||
newRat: (nom , denom) ->
|
|
||||||
if nom * denom >= 0
|
|
||||||
return "#{Math.abs(nom)}/#{Math.abs(denom)}"
|
|
||||||
return "#{-Math.abs(nom)}/#{Math.abs(denom)}"
|
|
||||||
|
|
||||||
return service
|
|
||||||
|
|
||||||
app.filter "ratpp", ["rationals", (rationals) ->
|
|
||||||
filter = (n) ->
|
|
||||||
return rationals.pp(n)
|
|
||||||
]
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
var bower = require('gulp-bower');
|
|
||||||
var gulp = require('gulp');
|
|
||||||
var coffee = require('gulp-coffee');
|
|
||||||
var help = require('gulp-task-listing');
|
|
||||||
var clean = require('gulp-clean');
|
|
||||||
var sass = require('gulp-sass');
|
|
||||||
var rjs = require("gulp-rjs");
|
|
||||||
var gutil = require('gulp-util');
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task('help', help);
|
|
||||||
|
|
||||||
gulp.task('bower', function() {
|
|
||||||
return bower()
|
|
||||||
.pipe(gulp.dest('bower_components/'))
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('sass', ['bower'], function () {
|
|
||||||
return gulp.src('./scss/*.scss')
|
|
||||||
.pipe(sass({includePaths: ['bower_components/foundation/scss', 'bower_components/bourbon/app/assets/stylesheets']}))
|
|
||||||
.pipe(gulp.dest('./css'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('coffee', ['bower'], function() {
|
|
||||||
return gulp.src('coffee/**/*.coffee')
|
|
||||||
.pipe(coffee({bare: true}).on('error', gutil.log))
|
|
||||||
.pipe(gulp.dest('js/'))
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('clean', function(){
|
|
||||||
return gulp.src(["js/", "bower_components/", "css/"], {read: false})
|
|
||||||
.pipe(clean())
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task('rjs', ['coffee'], function(){
|
|
||||||
return gulp.src('coffee/**/*.coffee')
|
|
||||||
.pipe(coffee())
|
|
||||||
.pipe(gulp.dest('./dist'))
|
|
||||||
.pipe(rjs({baseUrl:'.'}))
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task('default', ['bower', 'sass', 'coffee']);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task('dev', ['bower', 'sass', 'coffee'], function(){
|
|
||||||
gulp.watch('coffee/**/*.coffee', ['coffee']);
|
|
||||||
gulp.watch('./scss/*.scss', ['sass']);
|
|
||||||
});
|
|
||||||
Whitespace-only changes.
+15
-40
@@ -1,47 +1,22 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>doorman</title>
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css">
|
|
||||||
<script data-main="/js/main" src="/bower_components/requirejs/require.js"></script>
|
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
|
||||||
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/mithril/mithril.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
<body >
|
||||||
<body style="visibility:hidden;">
|
<section class="section">
|
||||||
<div ng-controller="topbarCtrl">
|
<div class="container">
|
||||||
<top-bar>
|
<div id="mithril"></div>
|
||||||
<ul class="title-area">
|
|
||||||
<li class="name">
|
|
||||||
<h1><a href="#/">Doorman</a></h1>
|
|
||||||
</li>
|
|
||||||
<li toggle-top-bar class="menu-icon"><a >Menu</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<top-bar-section>
|
|
||||||
<ul class="left show-for-large-up">
|
|
||||||
<li>
|
|
||||||
<a ng-bind="email" href="#"></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="right">
|
|
||||||
<li has-dropdown>
|
|
||||||
<a >Dropdown</a>
|
|
||||||
<ul top-bar-dropdown ng-show="loggedIn">
|
|
||||||
<li><a href="#/doormen">doormen</a></li>
|
|
||||||
<li><a href="#/newdoorman">new doorman</a></li>
|
|
||||||
<li><a href="#/apispec">api specification</a></li>
|
|
||||||
<li><a href="#/serverspec">server specification</a></li>
|
|
||||||
<li ng-click="logout()"><a href="#/">logout</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</top-bar-section>
|
|
||||||
</top-bar>
|
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
<div class="large-12 small-12 columns" ng-view></div>
|
<script src="index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
+215
@@ -0,0 +1,215 @@
|
|||||||
|
(function(){
|
||||||
|
const Ratio = (n, d) => ({
|
||||||
|
type: 'Ratio',
|
||||||
|
'n': n, // numerator
|
||||||
|
'd': d // denominator
|
||||||
|
});
|
||||||
|
|
||||||
|
const approxRatio = eps => n => {
|
||||||
|
const
|
||||||
|
gcde = (e, x, y) => {
|
||||||
|
const _gcd = (a, b) => (b < e ? a : _gcd(b, a % b));
|
||||||
|
return _gcd(Math.abs(x), Math.abs(y));
|
||||||
|
},
|
||||||
|
c = gcde(Boolean(eps) ? eps : (1 / 10000), 1, n);
|
||||||
|
return Ratio(
|
||||||
|
Math.floor(n / c), // numerator
|
||||||
|
Math.floor(1 / c) // denominator
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
var topBar = {}
|
||||||
|
|
||||||
|
function fontawesome(){
|
||||||
|
const classes = _.map(arguments, x => "." + x).reduce((s, n) => s + n);
|
||||||
|
return m('i' + classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
var TopBar = {
|
||||||
|
view: function(){
|
||||||
|
return m('nav.navbar', [
|
||||||
|
m('div.navbar-brand',
|
||||||
|
m('a.navbar-item', {href: "#!/"}, "Doorman ", fontawesome('fas', 'fa-door-open'))),
|
||||||
|
m('div.navbar-menu', [
|
||||||
|
m('div.navbar-end', [
|
||||||
|
m('a.navbar-item', {href: "#!/server"}, "Server"),
|
||||||
|
m('a.navbar-item', {href: "#!/new-doorman"}, "New Doorman"),
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var Home = {};
|
||||||
|
|
||||||
|
Home.doormen = [];
|
||||||
|
|
||||||
|
Home.oninit = function(){
|
||||||
|
m.request({method: "GET", url: "/api/doormen"}).then(data => Home.doormen = data.doormen);
|
||||||
|
}
|
||||||
|
|
||||||
|
Home.doorman = function(doorman, idx){
|
||||||
|
const link = "#!/doorman/" + doorman.id
|
||||||
|
return m('li', m('a', {href: link}, doorman.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Home.view = function() {
|
||||||
|
return m("main", [
|
||||||
|
m(TopBar),
|
||||||
|
m("h1", {class: "title"}, "Home"),
|
||||||
|
m('div.content',
|
||||||
|
m('ul', _.map(Home.doormen, Home.doorman)))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var NewDoorman = {}
|
||||||
|
|
||||||
|
|
||||||
|
NewDoorman.oninit = function(){
|
||||||
|
NewDoorman.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.setToPayload = function(field){
|
||||||
|
return function(e){
|
||||||
|
_.set(NewDoorman.payload, field, e.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.nameField = function(){
|
||||||
|
const fields = {
|
||||||
|
type: 'text',
|
||||||
|
placeholder: 'Background Colour dsds',
|
||||||
|
onchange: NewDoorman.setToPayload('foo')};
|
||||||
|
return m('label.label', 'Name',
|
||||||
|
m('input.input', fields));
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.ownerField = function(email, idx){
|
||||||
|
const label = 'Owner ' + (idx + 1);
|
||||||
|
const fields = {
|
||||||
|
type: 'text',
|
||||||
|
value: email,
|
||||||
|
onchange: NewDoorman.setToPayload(['OwnerEmails', idx])}
|
||||||
|
return m('label.label', label,
|
||||||
|
m('input.input', fields));
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.putEmptyOwnerFields = function(){
|
||||||
|
NewDoorman.payload.OwnerEmails = _(NewDoorman.payload.OwnerEmails)
|
||||||
|
.filter(x => !_.isEmpty(x))
|
||||||
|
.concat('')
|
||||||
|
.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.ownerFields = function(){
|
||||||
|
return m('fieldset', {onchange: NewDoorman.putEmptyOwnerFields()},
|
||||||
|
m('legend', 'Owners'),
|
||||||
|
_.map(NewDoorman.payload.OwnerEmails, NewDoorman.ownerField));
|
||||||
|
}
|
||||||
|
NewDoorman.valueField = function(value, idx){
|
||||||
|
const nameField = m('div.field',
|
||||||
|
m('label', 'name',
|
||||||
|
m('input.input', {type: 'text', value: value.name, onchange: NewDoorman.setToPayload(['Values', idx, 'name'])})));
|
||||||
|
const valueField = m('div.field', m('label', 'value', m('input.input', {type: 'number', value: value.value, onchange: NewDoorman.setToPayload(['Values', idx, 'value'])})));
|
||||||
|
|
||||||
|
return m('div.columns',
|
||||||
|
m('div.column', nameField),
|
||||||
|
m('div.column', valueField));
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.putEmptyValueFields = function() {
|
||||||
|
const hasEmptyNames = _(NewDoorman.payload.Values).map('name').filter(_.isEmpty).value().length;
|
||||||
|
const hasEmptyValues = _(NewDoorman.payload.Values).map('value').filter(_.isEmpty).value().length;
|
||||||
|
const sum = _(NewDoorman.payload.Values).map('value').map(x => parseInt(x)).sum();
|
||||||
|
if(sum >= 100 || hasEmptyNames || hasEmptyValues){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NewDoorman.payload.Values.push({name: '', value: 100 - sum});
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.valueFields = function(){
|
||||||
|
return m('fieldset', {onchange: NewDoorman.putEmptyValueFields}, m('legend', 'Values'),
|
||||||
|
_.map(NewDoorman.payload.Values, NewDoorman.valueField));
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.clear = function(){
|
||||||
|
NewDoorman.payload = {
|
||||||
|
OwnerEmails: [],
|
||||||
|
Values: [{}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.buttons = function(){
|
||||||
|
return m('div.buttons', [
|
||||||
|
m('button.button.is-primary.is-light', 'Create'),
|
||||||
|
m('button.button.is-danger.is-light', {onclick: NewDoorman.clear}, 'Clear')
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDoorman.view = function(){
|
||||||
|
return m('div',
|
||||||
|
m(TopBar),
|
||||||
|
m('form', [
|
||||||
|
NewDoorman.nameField(),
|
||||||
|
m('br'),
|
||||||
|
NewDoorman.ownerFields(),
|
||||||
|
m('br'),
|
||||||
|
NewDoorman.valueFields(),
|
||||||
|
m('br'),
|
||||||
|
NewDoorman.buttons()
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
var Server = {}
|
||||||
|
|
||||||
|
Server.data = {};
|
||||||
|
|
||||||
|
Server.oninit= function(){
|
||||||
|
m.request({method: "GET", url: "/api/server"})
|
||||||
|
.then(function(data) {
|
||||||
|
Server.data = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Server.renderRow = function(value, key){
|
||||||
|
return m('tr', [
|
||||||
|
m('td', key),
|
||||||
|
m('td', _.isObject(value) ? JSON.stringify(value) : value)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Server.renderTable = function(serverData){
|
||||||
|
const rows = _.map(serverData, Server.renderRow);
|
||||||
|
return m('table.table.is-bordered.is-striped.is-hoverable', rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
Server.view = function() {
|
||||||
|
return m("div", [
|
||||||
|
m(TopBar),
|
||||||
|
m("h1", {class: "title"}, "Server"),
|
||||||
|
Server.renderTable(Server.data)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var Doorman = {};
|
||||||
|
Doorman.doorman = {}
|
||||||
|
|
||||||
|
Doorman.oninit = function(vnode){
|
||||||
|
m.request({method: "GET", url: "/api/doormen"})
|
||||||
|
.then(data => _(data.doormen).filter(x => x.id == vnode.attrs.doormanId).map('url').first())
|
||||||
|
.then(url => m.request({method: "GET", url: url}))
|
||||||
|
.then(data => Doorman.doorman = data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Doorman.view = function(vnode){
|
||||||
|
return m('div', [m(TopBar),'blah' + JSON.stringify(Doorman.doorman)])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
m.route(document.getElementById('mithril'), "/", {
|
||||||
|
"/": Home,
|
||||||
|
"/server": Server,
|
||||||
|
"/new-doorman": NewDoorman,
|
||||||
|
"/doorman/:doormanId": Doorman,
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"gulp": "~3.8.9",
|
|
||||||
"gulp-bower": "0.0.7",
|
|
||||||
"gulp-clean": "~0.3.1",
|
|
||||||
"gulp-coffee": "~2.2.0",
|
|
||||||
"gulp-sass": "^1.2.4",
|
|
||||||
"gulp-task-listing": "~0.3.0",
|
|
||||||
"gulp-util": "^3.0.3",
|
|
||||||
"node-sass": "~1.2.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"gulp-rjs": "^0.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>Api specification</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h3>End points</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row wab-apispect">
|
|
||||||
<table class="columns large-12">
|
|
||||||
<thead>
|
|
||||||
<tr >
|
|
||||||
<th >api endpoint</th>
|
|
||||||
<th>method</th>
|
|
||||||
<th >description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr ng-repeat="endpoint in endpoints">
|
|
||||||
<td><wab-api endpoint="{{ endpoint.pattern }}"></wab-api></td>
|
|
||||||
<td>
|
|
||||||
<code style="width:5em; display: block; text-align: center;">{{ endpoint.method }}</code>
|
|
||||||
</td>
|
|
||||||
<td >{{ endpoint.description }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h3>Authentication</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<p>
|
|
||||||
All calls that change an asset requires authentication.
|
|
||||||
Authentication is done by adding a <code class="light">
|
|
||||||
user={user_name}</code> parameter to the endpoint. For example, to
|
|
||||||
authenticate to <code class="light">/api/doormen/zST8_FWcPDT2-14wDQAAAQ==</code>
|
|
||||||
with a user called "bob", the url becomes
|
|
||||||
<code class="light">/api/doormen/zST8_FWcPDT2-14wDQAAAQ==?user=bob</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>{{ doorman.name }} </h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<span>doorman id: <code>{{ doorman.id }}</code></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-repeat="value in doorman.values">
|
|
||||||
<div class="columns large-8 small-10">
|
|
||||||
<div class="row">
|
|
||||||
<div class="large-2 columns">
|
|
||||||
<a class="button prefix disabled" ng-bind="$index"> </a>
|
|
||||||
</div>
|
|
||||||
<div class="large-10 columns">
|
|
||||||
<input type="text" placeholder="value name" ng-value="value.name" disabled>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-4 small-2">
|
|
||||||
<label >
|
|
||||||
probability
|
|
||||||
<rat-input ng-model="value.probability" ng-disabled="!isAdmin"></rat-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="large-4 columns">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="email in leftEmailColumns">
|
|
||||||
<span ng-bind="email"></span>
|
|
||||||
<i class="fa fa-times right"
|
|
||||||
ng-click="removeEmail(email)"
|
|
||||||
style="cursor: pointer;"
|
|
||||||
ng-show="doorman.emails.length > 1 && isAdmin && email != user"
|
|
||||||
|
|
||||||
></i>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="large-4 columns">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="email in rightEmailColumns">
|
|
||||||
<span ng-bind="email"></span>
|
|
||||||
<i class="fa fa-times right"></i>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="large-4 columns">
|
|
||||||
<div>
|
|
||||||
<label>
|
|
||||||
new admin
|
|
||||||
<div class="row collapse">
|
|
||||||
<div class="columns large-10 small-10">
|
|
||||||
|
|
||||||
<input type="text" ng-model="newEmail"/>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-2 small-2">
|
|
||||||
|
|
||||||
<a class="button postfix" ng-click="addNewAuthorEmail()" ng-class=" canAddNewEmail() ? '' : 'disabled' " >+</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-show="error">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<code style="width:100%; height:100%; display:block; margin-bottom: 1em;">
|
|
||||||
<b>{{ error.status }}</b><br> {{ error.message }}
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-show="isAdmin">
|
|
||||||
<div class="large-12 small-12 columns">
|
|
||||||
<ul class="button-group">
|
|
||||||
<li><a ng-click="updateDoorman()" class="small button" ng-class="{disabled: !validate()}">Update</a></li>
|
|
||||||
</ul>
|
|
||||||
<span ng-show="doormanChanged">
|
|
||||||
doorman changed
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>error page</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<span>Error {{ error }} getting doorman {{ id }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>doormen</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="doorman in doormen"> <a href="#/doormen/{{ doorman.id }}"> {{ doorman.name }} </a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>Welcome to the world best a/b testing library</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<form ng-submit="login()" >
|
|
||||||
<fieldset>
|
|
||||||
<legend>Login</legend>
|
|
||||||
<div class="large-12 columns">
|
|
||||||
<div class="row collapse">
|
|
||||||
<div class="small-10 columns">
|
|
||||||
<input type="text" placeholder="email" ng-model="email">
|
|
||||||
</div>
|
|
||||||
<div class="small-2 columns">
|
|
||||||
<button type="submit" class="button postfix" >Login!</input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-show="loggedEmail">
|
|
||||||
<div class="large-12 columns">
|
|
||||||
You are currently logged in as <code ng-bind="loggedEmail"></code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>new doorman</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<label >name<input type="text" placeholder="unique doorman name" ng-model="payload.name"></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<fieldset>
|
|
||||||
<legend>doorman state</legend>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-8">
|
|
||||||
<label >name<input type="text" placeholder="value name" ng-model="value.name"></label>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-3">
|
|
||||||
<label >probability
|
|
||||||
<rat-input ng-model="value.probability"></rat-input>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="columns large-1">
|
|
||||||
<br>
|
|
||||||
<a class="button round tiny" ng-class="{disabled: !isValidValue()}" ng-click="addNewValue()">
|
|
||||||
<i class="fa fa-plus"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-repeat="value in payload.values | reverse">
|
|
||||||
<div class="columns large-8">
|
|
||||||
<label >value<input type="text" placeholder="value name" ng-model="value.name"></label>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-3">
|
|
||||||
<label >probability
|
|
||||||
<rat-input ng-model="value.probability"></rat-input>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-1">
|
|
||||||
<br>
|
|
||||||
<a class="button round tiny" ng-click="removeValue( payload.values.length - $index - 1 )">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<fieldset>
|
|
||||||
<legend>administrator</legend>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns large-11">
|
|
||||||
<label>admin email <input type="text" placeholder="admin email" ng-model="newEmail"></label>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-1">
|
|
||||||
<br><a class="button round tiny" ng-click="addEmail()" ng-class="{disabled: !newEmail}">
|
|
||||||
<i class="fa fa-plus"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-repeat="email in payload.emails | reverse">
|
|
||||||
<div class="columns large-11">
|
|
||||||
<label>admin email <input type="text" ng-disabled="email==user" placeholder="wild cards are allow here" ng-model="email"></label>
|
|
||||||
</div>
|
|
||||||
<div class="columns large-1">
|
|
||||||
<br><a class="button round tiny" ng-click="removeEmail(payload.emails.length - $index -1)" ng-disabled="email==user? 'disabled' : ''">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-show="error">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<code style="width:100%; height:100%; display:block; margin-bottom: 1em;">{{ error }}</code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="large-9 columns">
|
|
||||||
<button ng-click="createDoorman()" ng-class="{disabled: !isDoormanValid()}">create</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="large-3 columns">
|
|
||||||
<span >propability remaning: {{ getProbabilityRemaining() | ratpp}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h1>server specification</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-show="server.message_queue == 'nanomsg'">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h3>general</h3>
|
|
||||||
<table style="width:100%;">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th >value</th>
|
|
||||||
<th>key</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>hostname</td>
|
|
||||||
<td><code>{{server.hostname}}</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>port</td>
|
|
||||||
<td><code>{{server.port}}</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>go version</td>
|
|
||||||
<td><code>{{server.go_version}}</code></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row" ng-show="server.message_queue == 'nanomsg'">
|
|
||||||
<div class="columns large-12">
|
|
||||||
<h3>nano msg</h3>
|
|
||||||
<table style="width:100%;">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th >value</th>
|
|
||||||
<th>key</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>url</td>
|
|
||||||
<td><code>{{server.nano_msg.url}}</code></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
@import "settings";
|
|
||||||
@import "bourbon";
|
|
||||||
|
|
||||||
// @import url(http://fonts.googleapis.com/css?family=Orbitron:400,900,500,700);
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Orbitron';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Orbitron-Light'), local('Orbitron-Regular'), url(/scss/font/orbitron/HmnHiRzvcnQr8CjBje6GQvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'), url(/scss/font/orbitron/94ug0rEgQO_WuI_xKJMFc_esZW2xOQ-xsNqO47m55DA.woff) format('woff');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
h1, h2{
|
|
||||||
font-family: 'Orbitron', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.wab-sidebar{
|
|
||||||
background: $ghost;
|
|
||||||
|
|
||||||
h1{
|
|
||||||
text-align: center;
|
|
||||||
color: $primary-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.wab-apispect{
|
|
||||||
h2{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rat-input{
|
|
||||||
.fraction-box{
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 1.3em;
|
|
||||||
border: 2px;
|
|
||||||
padding: 0.3em;
|
|
||||||
box-shadow: 2px 2px 1px #888;
|
|
||||||
@include border-top-radius(5px);
|
|
||||||
@include border-bottom-radius(5px);
|
|
||||||
|
|
||||||
i{
|
|
||||||
font-size: 1em;
|
|
||||||
margin-left: 0.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fraction-box:hover{
|
|
||||||
border: 2px;
|
|
||||||
padding: 0.3em;
|
|
||||||
box-shadow: 2px 2px 1px red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit{
|
|
||||||
input{
|
|
||||||
width: 4em;
|
|
||||||
height: 2em;
|
|
||||||
display: inline;
|
|
||||||
padding: 0px;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.light{
|
|
||||||
border-style: none;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,41 +0,0 @@
|
|||||||
@import "settings";
|
|
||||||
@import "foundation";
|
|
||||||
@import "doorman";
|
|
||||||
|
|
||||||
// Or selectively include components
|
|
||||||
// @import
|
|
||||||
// "foundation/components/accordion",
|
|
||||||
// "foundation/components/alert-boxes",
|
|
||||||
// "foundation/components/block-grid",
|
|
||||||
// "foundation/components/breadcrumbs",
|
|
||||||
// "foundation/components/button-groups",
|
|
||||||
// "foundation/components/buttons",
|
|
||||||
// "foundation/components/clearing",
|
|
||||||
// "foundation/components/dropdown",
|
|
||||||
// "foundation/components/dropdown-buttons",
|
|
||||||
// "foundation/components/flex-video",
|
|
||||||
// "foundation/components/forms",
|
|
||||||
// "foundation/components/grid",
|
|
||||||
// "foundation/components/inline-lists",
|
|
||||||
// "foundation/components/joyride",
|
|
||||||
// "foundation/components/keystrokes",
|
|
||||||
// "foundation/components/labels",
|
|
||||||
// "foundation/components/magellan",
|
|
||||||
// "foundation/components/orbit",
|
|
||||||
// "foundation/components/pagination",
|
|
||||||
// "foundation/components/panels",
|
|
||||||
// "foundation/components/pricing-tables",
|
|
||||||
// "foundation/components/progress-bars",
|
|
||||||
// "foundation/components/reveal",
|
|
||||||
// "foundation/components/side-nav",
|
|
||||||
// "foundation/components/split-buttons",
|
|
||||||
// "foundation/components/sub-nav",
|
|
||||||
// "foundation/components/switch",
|
|
||||||
// "foundation/components/tables",
|
|
||||||
// "foundation/components/tabs",
|
|
||||||
// "foundation/components/thumbs",
|
|
||||||
// "foundation/components/tooltips",
|
|
||||||
// "foundation/components/top-bar",
|
|
||||||
// "foundation/components/type",
|
|
||||||
// "foundation/components/offcanvas",
|
|
||||||
// "foundation/components/visibility";
|
|
||||||
Reference in new issue
Block a user