Browse Source

feat(invite): more progress on invited / sigup view, #2353

Torkel Ödegaard 10 years ago
parent
commit
d75f96fdd5

+ 4 - 1
pkg/api/api.go

@@ -22,7 +22,7 @@ func Register(r *macaron.Macaron) {
 	r.Post("/login", bind(dtos.LoginCommand{}), wrap(LoginPost))
 	r.Get("/login/:name", OAuthLogin)
 	r.Get("/login", LoginView)
-	r.Get("/signup/invited", Index)
+	r.Get("/invite", Index)
 
 	// authed views
 	r.Get("/profile/", reqSignedIn, Index)
@@ -43,6 +43,9 @@ func Register(r *macaron.Macaron) {
 	r.Get("/signup", Index)
 	r.Post("/api/user/signup", bind(m.CreateUserCommand{}), wrap(SignUp))
 
+	// invited
+	r.Get("/api/user/invite/:code", wrap(GetInviteInfoByCode))
+
 	// reset password
 	r.Get("/user/password/send-reset-email", Index)
 	r.Get("/user/password/reset", Index)

+ 6 - 0
pkg/api/dtos/invite.go

@@ -8,3 +8,9 @@ type AddInviteForm struct {
 	Role       m.RoleType `json:"role" binding:"Required"`
 	SkipEmails bool       `json:"skipEmails"`
 }
+
+type InviteInfo struct {
+	Email    string `json:"email"`
+	Name     string `json:"name"`
+	Username string `json:"username"`
+}

+ 19 - 0
pkg/api/org_invite.go

@@ -96,3 +96,22 @@ func RevokeInvite(c *middleware.Context) Response {
 
 	return ApiSuccess("Invite revoked")
 }
+
+func GetInviteInfoByCode(c *middleware.Context) Response {
+	query := m.GetTempUsersByCodeQuery{Code: c.Params(":code")}
+
+	if err := bus.Dispatch(&query); err != nil {
+		if err == m.ErrTempUserNotFound {
+			return ApiError(404, "Invite not found", nil)
+		}
+		return ApiError(500, "Failed to get invite", err)
+	}
+
+	info := dtos.InviteInfo{
+		Email:    query.Result.Email,
+		Name:     query.Result.Name,
+		Username: query.Result.Email,
+	}
+
+	return Json(200, &info)
+}

+ 6 - 0
pkg/models/temp_user.go

@@ -68,6 +68,12 @@ type GetTempUsersForOrgQuery struct {
 	Result []*TempUserDTO
 }
 
+type GetTempUsersByCodeQuery struct {
+	Code string
+
+	Result *TempUser
+}
+
 type TempUserDTO struct {
 	Id          int64     `json:"id"`
 	Name        string    `json:"name"`

+ 15 - 0
pkg/services/sqlstore/temp_user.go

@@ -12,6 +12,7 @@ func init() {
 	bus.AddHandler("sql", CreateTempUser)
 	bus.AddHandler("sql", GetTempUsersForOrg)
 	bus.AddHandler("sql", UpdateTempUserStatus)
+	bus.AddHandler("sql", GetTempUsersByCode)
 }
 
 func UpdateTempUserStatus(cmd *m.UpdateTempUserStatusCommand) error {
@@ -68,3 +69,17 @@ func GetTempUsersForOrg(query *m.GetTempUsersForOrgQuery) error {
 	err := sess.Find(&query.Result)
 	return err
 }
+
+func GetTempUsersByCode(query *m.GetTempUsersByCodeQuery) error {
+	var user m.TempUser
+	has, err := x.Table("temp_user").Where("code=?", query.Code).Get(&user)
+
+	if err != nil {
+		return err
+	} else if has == false {
+		return m.ErrTempUserNotFound
+	}
+
+	query.Result = &user
+	return err
+}

+ 14 - 1
public/app/controllers/invitedCtrl.js

@@ -6,11 +6,24 @@ function (angular) {
 
   var module = angular.module('grafana.controllers');
 
-  module.controller('InvitedCtrl', function($scope, contextSrv) {
+  module.controller('InvitedCtrl', function($scope, $routeParams, contextSrv, backendSrv) {
 
     contextSrv.sidemenu = false;
 
+    $scope.user = {};
+
     $scope.init = function() {
+      backendSrv.get('/api/user/invite/' + $routeParams.code).then(function(invite) {
+        $scope.user.name = invite.name;
+        $scope.user.email = invite.email;
+        $scope.user.username = invite.email;
+        $scope.user.inviteId =  invite.id;
+
+        $scope.greeting = invite.name || invite.email;
+      });
+    };
+
+    $scope.submit = function() {
     };
 
     $scope.init();

+ 41 - 23
public/app/partials/signup_invited.html

@@ -9,65 +9,83 @@
 			<img src="img/logo_transparent_200x75.png">
 		</div>
 
-    <div class="login-inner-box">
+    <div class="invite-box">
+			<h3>
+				Hi, {{greeting}}, Welcome to Grafana party.
+			</h3>
 
-      <form name="loginForm" class="login-form">
+			<div class="modal-tagline">
+				Beer and wine in the fridge, food out back - <br>
+				but first introduce yourself.
+			</div>
+
+      <form name="inviteForm" class="login-form">
 				<div class="tight-from-container">
-					<div class="tight-form" ng-if="loginMode">
+					<div class="tight-form">
 						<ul class="tight-form-list">
-							<li class="tight-form-item" style="width: 78px">
-								<strong>User</strong>
+							<li class="tight-form-item" style="width: 128px">
+								Email
 							</li>
 							<li>
-								<input type="text" name="username" class="tight-form-input last" required ng-model='formModel.user' placeholder="email or username" style="width: 253px">
+								<input type="email" name="email" class="tight-form-input last" required ng-model='user.email' placeholder="Email" style="width: 253px">
 							</li>
 						</ul>
 						<div class="clearfix"></div>
 					</div>
-					<div class="tight-form" ng-if="loginMode">
+					<div class="tight-form">
 						<ul class="tight-form-list">
-							<li class="tight-form-item" style="width: 78px">
-								<strong>Password</strong>
+							<li class="tight-form-item" style="width: 128px">
+								Name
 							</li>
 							<li>
-								<input type="password" name="password" class="tight-form-input last" required ng-model="formModel.password" id="inputPassword" style="width: 253px" placeholder="password">
+								<input type="text" name="name" class="tight-form-input last" ng-model='user.name' placeholder="Name (optional)" style="width: 253px">
 							</li>
 						</ul>
 						<div class="clearfix"></div>
 					</div>
-
-					<div class="tight-form" ng-if="!loginMode">
+					<div class="tight-form">
 						<ul class="tight-form-list">
-							<li class="tight-form-item" style="width: 79px">
-								<strong>Email</strong>
+							<li class="tight-form-item" style="width: 128px">
+								Username
 							</li>
 							<li>
-								<input type="email" class="tight-form-input last" required ng-model='formModel.email' placeholder="email" style="width: 253px">
+								<input type="text" name="username" class="tight-form-input last" required ng-model='user.username' placeholder="Username" style="width: 253px">
 							</li>
 						</ul>
 						<div class="clearfix"></div>
 					</div>
 
-					<div class="tight-form" ng-if="!loginMode">
+					<div class="tight-form">
+						<ul class="tight-form-list">
+							<li class="tight-form-item" style="width: 128px">
+								Password
+							</li>
+							<li>
+								<input type="password" name="password" class="tight-form-input last" required ng-model="user.password" id="inputPassword" style="width: 253px" placeholder="password">
+							</li>
+						</ul>
+						<div class="clearfix"></div>
+					</div>
+					<div class="tight-form">
 						<ul class="tight-form-list">
-							<li class="tight-form-item" style="width: 79px">
-								<strong>Password</strong>
+							<li class="tight-form-item" style="width: 128px">
+								Confirm Password
 							</li>
 							<li>
-								<input type="password" class="tight-form-input last" watch-change="formModel.password = inputValue;" ng-minlength="4" required ng-model='formModel.password' placeholder="password" style="width: 253px">
+								<input type="password" name="confirmPassword" class="tight-form-input last" required ng-model="user.confirmPassword" id="confirmPassword" style="width: 253px" placeholder="confirm password">
 							</li>
 						</ul>
 						<div class="clearfix"></div>
 					</div>
 				</div>
 
-				<div ng-if="!loginMode" style="margin-left: 97px; width: 254px;">
-					<password-strength password="formModel.password"></password-strength>
+				<div style="margin-left: 147px; width: 254px;">
+					<password-strength password="user.password"></password-strength>
 				</div>
 
 				<div class="login-submit-button-row">
-					<button type="submit" class="btn" ng-click="submit();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
-						{{submitBtnText}}
+					<button type="submit" class="btn" ng-click="submit();" ng-class="{'btn-inverse': !inviteForm.$valid, 'btn-primary': inviteForm.$valid}">
+						Continue
 					</button>
 				</div>
 			</form>

+ 31 - 0
public/css/less/login.less

@@ -105,3 +105,34 @@
   opacity: 0.15;
   z-index: -1;
 }
+
+.invite-box {
+  text-align: center;
+  border: 1px solid @grafanaTargetFuncBackground;
+	background-color: @grafanaPanelBackground;
+	position: fixed;
+  max-width: 800px;
+  left: 0;
+  right: 0;
+  margin-left: auto;
+  margin-right: auto;
+  top: 20%;
+
+  .tight-form {
+    text-align: left;
+  }
+
+  h3 {
+    margin-top: 30px;
+  }
+
+  .modal-close {
+    float: right;
+    font-size: 140%;
+    padding: 10px;
+  }
+
+  .modal-tagline {
+    font-size: 16px;
+  }
+}