New setup screen for blog installation.

fixes #3072
- Change router to handle /ember/setup/
- Adjust doSignup to also handle setup
- Adjust tests and add new where necessary
- Add setup controller, setup validation, setup route
- Adjust casper emberSetup to handle new setup
This commit is contained in:
Fabian Becker 2014-06-25 14:12:48 +02:00
parent b71e99a333
commit b359d4122b
8 changed files with 133 additions and 84 deletions

View File

@ -1,6 +1,6 @@
var ApplicationController = Ember.Controller.extend({
isSignedIn: Ember.computed.bool('user.isSignedIn'),
hideNav: Ember.computed.match('currentPath', /(signin|signup|forgotten|reset)/),
hideNav: Ember.computed.match('currentPath', /(signin|signup|setup|forgotten|reset)/),
actions: {
toggleMenu: function () {

View File

@ -0,0 +1,54 @@
import ajax from 'ghost/utils/ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';
var SetupController = Ember.ObjectController.extend(ValidationEngine, {
blogTitle: null,
name: null,
email: null,
password: null,
submitting: false,
// ValidationEngine settings
validationType: 'setup',
actions: {
setup: function () {
var self = this;
// @TODO This should call closePassive() to only close passive notifications
self.notifications.closeAll();
this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
ajax({
url: self.get('ghostPaths').adminUrl('setup'),
type: 'POST',
headers: {
'X-CSRF-Token': self.get('csrf')
},
data: self.getProperties('blogTitle', 'name', 'email', 'password')
}).then(function (resp) {
self.toggleProperty('submitting');
if (resp && resp.userData) {
self.store.pushPayload({ users: [resp.userData]});
self.store.find('user', resp.userData.id).then(function (user) {
self.send('signedIn', user);
self.notifications.clear();
self.transitionToRoute('posts');
});
} else {
self.transitionToRoute('setup');
}
}, function (resp) {
self.toggleProperty('submitting');
self.notifications.showAPIError(resp);
});
}, function (errors) {
self.toggleProperty('submitting');
self.notifications.showErrors(errors);
});
}
}
});
export default SetupController;

View File

@ -1,83 +0,0 @@
<!doctype html>
<!--[if (IE 8)&!(IEMobile)]><html class="no-js lt-ie9" lang="en"><![endif]-->
<!--[if (gte IE 9)| IEMobile |!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Ghost Admin</title>
<meta name="HandheldFriendly" content="True" />
<meta name="MobileOptimized" content="320" />
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1, minimal-ui" />
<meta http-equiv="cleartype" content="on" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="Ghost" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon-precomposed" href="/ghost/img/touch-icon-iphone.png?v=f0332a6f54" />
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="/ghost/img/touch-icon-ipad.png?v=f0332a6f54" />
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="/ghost/img/small.png?v=f0332a6f54" />
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="/ghost/img/medium.png?v=f0332a6f54" />
<meta name="application-name" content="Ghost" />
<meta name="msapplication-TileColor" content="#ffffff" />
<meta name="msapplication-square70x70logo" content="/ghost/img/small.png?v=f0332a6f54" />
<meta name="msapplication-square150x150logo" content="/ghost/img/medium.png?v=f0332a6f54" />
<meta name="msapplication-square310x310logo" content="/ghost/img/large.png?v=f0332a6f54" />
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,700" />
<link rel="stylesheet" href="/Users/John/Sites/Ghost-UI/dist/css/ghost-ui.css" />
</head>
<body class="ghost-setup">
<main role="main" id="main">
<aside id="notifications" class="notifications">
</aside>
<section class="setup-box js-setup-box">
<div class="vertical">
<form id="setup" class="setup-form" method="post" novalidate="novalidate">
<header>
<h1>Welcome to your new Ghost blog</h1>
<h2>Let's get a few things set up so you can get started.</h2>
</header>
<div class="form-group">
<label for="blog-title">Blog Title</label>
<input id="blog-title" type="text">
<p>What would you like to call your blog?</p>
</div>
<div class="form-group">
<label for="blog-title">Full Name</label>
<input id="blog-title" type="text">
<p>The name that you will sign your posts with</p>
</div>
<div class="form-group">
<label for="blog-title">Email Address</label>
<input id="blog-title" type="email">
<p>Used for important notifications</p>
</div>
<div class="form-group">
<label for="blog-title">Password</label>
<input id="blog-title" type="password">
<p>Must be at least 8 characters</p>
</div>
<footer>
<button class="button-add large">Ok, Let's Do This</button>
</footer>
</form>
</div>
</section>
</main>
<div id="modal-container"></div>
<div class="modal-background fade"></div>
<script src="https://newstartuptest.ghost.io/ghost/scripts/ghost.min.js"></script>
</body>
</html>

View File

@ -2,6 +2,7 @@ import { getRequestErrorMessage } from 'ghost/utils/ajax';
import ValidatorExtensions from 'ghost/utils/validator-extensions';
import PostValidator from 'ghost/validators/post';
import SetupValidator from 'ghost/validators/setup';
import SignupValidator from 'ghost/validators/signup';
import SigninValidator from 'ghost/validators/signin';
import ForgotValidator from 'ghost/validators/forgotten';
@ -12,6 +13,7 @@ ValidatorExtensions.init();
var ValidationEngine = Ember.Mixin.create({
validators: {
post: PostValidator,
setup: SetupValidator,
signup: SignupValidator,
signin: SigninValidator,
forgotten: ForgotValidator,

View File

@ -16,6 +16,7 @@ Router.reopen({
});
Router.map(function () {
this.route('setup');
this.route('signin');
this.route('signout');
this.route('signup');

View File

@ -0,0 +1,8 @@
import styleBody from 'ghost/mixins/style-body';
import loadingIndicator from 'ghost/mixins/loading-indicator';
var SetupRoute = Ember.Route.extend(styleBody, loadingIndicator, {
classNames: ['ghost-setup']
});
export default SetupRoute;

View File

@ -0,0 +1,33 @@
<section class="setup-box js-setup-box">
<div class="vertical">
<form id="setup" class="setup-form" method="post" novalidate="novalidate">
<header>
<h1>Welcome to your new Ghost blog</h1>
<h2>Let's get a few things set up so you can get started.</h2>
</header>
<div class="form-group">
<label for="blog-title">Blog Title</label>
{{input type="text" name="blog-title" autofocus="autofocus" autocorrect="off" value=blogTitle }}
<p>What would you like to call your blog?</p>
</div>
<div class="form-group">
<label for="name">Full Name</label>
{{input type="text" name="name" autofocus="autofocus" autocorrect="off" value=name }}
<p>The name that you will sign your posts with</p>
</div>
<div class="form-group">
<label for="email">Email Address</label>
{{input type="email" name="email" autofocus="autofocus" autocorrect="off" value=email }}
<p>Used for important notifications</p>
</div>
<div class="form-group">
<label for="password">Password</label>
{{input type="password" name="password" autofocus="autofocus" autocorrect="off" value=password }}
<p>Must be at least 8 characters</p>
</div>
<footer>
<button class="button-add large" {{action "setup"}} {{bind-attr disabled=submitting}}>Ok, Let's Do This</button>
</footer>
</form>
</div>
</section>

View File

@ -0,0 +1,34 @@
var SetupValidator = Ember.Object.create({
validate: function (model) {
var data = model.getProperties('blogTitle', 'name', 'email', 'password'),
validationErrors = [];
if (!validator.isLength(data.blogTitle || '', 1)) {
validationErrors.push({
message: 'Please enter a blog title.'
});
}
if (!validator.isLength(data.name || '', 1)) {
validationErrors.push({
message: 'Please enter a name.'
});
}
if (!validator.isEmail(data.email)) {
validationErrors.push({
message: 'Invalid Email.'
});
}
if (!validator.isLength(data.password || '', 1)) {
validationErrors.push({
message: 'Please enter a password.'
});
}
return validationErrors;
}
});
export default SetupValidator;