mirror of
https://github.com/vale981/Vulcan
synced 2025-03-05 09:31:43 -05:00
Move store rest logic to nova:accounts; get rid of AccountsForm component
This commit is contained in:
parent
f5e4bd5ba1
commit
2f0775a7b8
27 changed files with 75 additions and 147 deletions
|
@ -43,5 +43,5 @@ accounts-password@1.3.4
|
|||
############ Your Packages ############
|
||||
|
||||
example-movies
|
||||
# example-movies-full
|
||||
# example-movies-full
|
||||
# example-customization
|
||||
|
|
|
@ -13,7 +13,6 @@ boilerplate-generator@1.0.11
|
|||
caching-compiler@1.1.9
|
||||
callback-hook@1.0.10
|
||||
check@1.2.5
|
||||
coffeescript@1.11.1_4
|
||||
ddp@1.2.5
|
||||
ddp-client@1.3.3
|
||||
ddp-common@1.2.8
|
||||
|
@ -51,6 +50,7 @@ modules@0.7.9
|
|||
modules-runtime@0.7.9
|
||||
mongo@1.1.16
|
||||
mongo-id@1.0.6
|
||||
nova:accounts@1.2.0
|
||||
nova:core@1.2.0
|
||||
nova:forms@1.2.0
|
||||
nova:i18n-en-us@1.2.0
|
||||
|
@ -75,14 +75,12 @@ service-configuration@1.0.11
|
|||
session@1.1.7
|
||||
sha@1.0.9
|
||||
shell-server@0.2.3
|
||||
softwarerero:accounts-t9n@1.3.9
|
||||
spacebars@1.0.13
|
||||
spacebars-compiler@1.0.13
|
||||
srp@1.0.10
|
||||
standard-minifier-css@1.3.4
|
||||
standard-minifier-js@1.2.3
|
||||
standard-minifiers@1.0.6
|
||||
std:accounts-ui@1.2.19
|
||||
tmeasday:check-npm-versions@0.3.1
|
||||
tracker@1.1.2
|
||||
ui@1.0.12
|
||||
|
|
|
@ -3,8 +3,9 @@ import ReactDOM from 'react-dom';
|
|||
import Tracker from 'tracker-component';
|
||||
import { Accounts } from 'meteor/accounts-base';
|
||||
import { KEY_PREFIX } from '../../login_session.js';
|
||||
import { Components, registerComponent } from 'meteor/nova:core';
|
||||
import { FormattedMessage, intlShape } from 'react-intl';
|
||||
import { Components, registerComponent, withCurrentUser } from 'meteor/nova:core';
|
||||
import { intlShape } from 'react-intl';
|
||||
import { withApollo } from 'react-apollo';
|
||||
|
||||
import {
|
||||
STATES,
|
||||
|
@ -28,19 +29,25 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
console.warn('Do not force the state to SIGN_IN on Accounts.ui.LoginForm, it will make it impossible to reset password in your app, this state is also the default state if logged out, so no need to force it.');
|
||||
}
|
||||
|
||||
const user = typeof props.user !== 'undefined'
|
||||
? props.user : Accounts.user();
|
||||
const currentUser = props.currentUser;
|
||||
|
||||
const resetStoreAndThen = hook => {
|
||||
return () => {
|
||||
props.client.resetStore();
|
||||
hook();
|
||||
}
|
||||
}
|
||||
|
||||
// Set inital state.
|
||||
this.state = {
|
||||
messages: [],
|
||||
waiting: true,
|
||||
formState: props.formState ? props.formState : (user ? STATES.PROFILE : STATES.SIGN_IN),
|
||||
formState: props.formState ? props.formState : (currentUser ? STATES.PROFILE : STATES.SIGN_IN),
|
||||
onSubmitHook: props.onSubmitHook || Accounts.ui._options.onSubmitHook,
|
||||
onSignedInHook: props.onSignedInHook || Accounts.ui._options.onSignedInHook,
|
||||
onSignedOutHook: props.onSignedOutHook || Accounts.ui._options.onSignedOutHook,
|
||||
onSignedInHook: resetStoreAndThen(props.onSignedInHook || Accounts.ui._options.onSignedInHook),
|
||||
onSignedOutHook: resetStoreAndThen(props.onSignedOutHook || Accounts.ui._options.onSignedOutHook),
|
||||
onPreSignUpHook: props.onPreSignUpHook || Accounts.ui._options.onPreSignUpHook,
|
||||
onPostSignUpHook: props.onPostSignUpHook || Accounts.ui._options.onPostSignUpHook,
|
||||
onPostSignUpHook: resetStoreAndThen(props.onPostSignUpHook || Accounts.ui._options.onPostSignUpHook),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -79,7 +86,7 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
// Add the services list to the user.
|
||||
this.subscribe('servicesList');
|
||||
this.setState({
|
||||
user: Accounts.user(),
|
||||
currentUser: Accounts.user(),
|
||||
waiting: !Accounts.loginServicesConfigured()
|
||||
});
|
||||
|
||||
|
@ -96,17 +103,17 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (typeof this.props.user !== 'undefined') {
|
||||
if (!prevProps.user !== !this.props.user) {
|
||||
if (typeof this.props.currentUser !== 'undefined') {
|
||||
if (!prevProps.currentUser !== !this.props.currentUser) {
|
||||
this.setState({
|
||||
formState: this.props.user ? STATES.PROFILE : STATES.SIGN_IN
|
||||
formState: this.props.currentUser ? STATES.PROFILE : STATES.SIGN_IN
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.formState == STATES.PROFILE) {
|
||||
if (!this.props.user && this.state.messages.length === 0) {
|
||||
if (!this.props.currentUser && this.state.messages.length === 0) {
|
||||
this.showMessage(loggingInMessage);
|
||||
} else if (this.props.user &&
|
||||
} else if (this.props.currentUser &&
|
||||
this.state.messages.find(({ message }) => message === loggingInMessage)) {
|
||||
this.clearMessage(loggingInMessage);
|
||||
}
|
||||
|
@ -115,9 +122,9 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
this.clearMessage(loggingInMessage);
|
||||
}
|
||||
} else {
|
||||
if (!prevState.user !== !this.state.user) {
|
||||
if (!prevState.currentUser !== !this.state.currentUser) {
|
||||
this.setState({
|
||||
formState: this.state.user ? STATES.PROFILE : STATES.SIGN_IN
|
||||
formState: this.state.currentUser ? STATES.PROFILE : STATES.SIGN_IN
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +158,7 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
hint: this.context.intl.formatMessage({id: 'accounts.enter_username_or_email'}),
|
||||
label: this.context.intl.formatMessage({id: 'accounts.username_or_email'}),
|
||||
required: true,
|
||||
defaultValue: this.state.username || "",
|
||||
defaultValue: this.state.currentUsername || "",
|
||||
onChange: this.handleChange.bind(this, 'usernameOrEmail'),
|
||||
message: this.getMessageForField('usernameOrEmail'),
|
||||
};
|
||||
|
@ -163,7 +170,7 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
hint: this.context.intl.formatMessage({id: 'accounts.enter_username'}),
|
||||
label: this.context.intl.formatMessage({id: 'accounts.username'}),
|
||||
required: true,
|
||||
defaultValue: this.state.username || "",
|
||||
defaultValue: this.state.currentUsername || "",
|
||||
onChange: this.handleChange.bind(this, 'username'),
|
||||
message: this.getMessageForField('username'),
|
||||
};
|
||||
|
@ -313,10 +320,10 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
} = this.props;
|
||||
const { formState, waiting } = this.state;
|
||||
let loginButtons = [];
|
||||
const user = typeof this.props.user !== 'undefined'
|
||||
? this.props.user : this.state.user;
|
||||
const currentUser = typeof this.props.currentUser !== 'undefined'
|
||||
? this.props.currentUser : this.state.currentUser;
|
||||
|
||||
if (user && formState == STATES.PROFILE) {
|
||||
if (currentUser && formState == STATES.PROFILE) {
|
||||
loginButtons.push({
|
||||
id: 'signOut',
|
||||
label: this.context.intl.formatMessage({id: 'accounts.sign_out'}),
|
||||
|
@ -355,9 +362,9 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
});
|
||||
}
|
||||
|
||||
if (user
|
||||
if (currentUser
|
||||
&& formState == STATES.PROFILE
|
||||
&& (user.services && 'password' in user.services)) {
|
||||
&& (currentUser.services && 'password' in currentUser.services)) {
|
||||
loginButtons.push({
|
||||
id: 'switchToChangePassword',
|
||||
label: this.context.intl.formatMessage({id: 'accounts.change_password'}),
|
||||
|
@ -651,7 +658,7 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
}
|
||||
|
||||
oauthSignIn(serviceName) {
|
||||
const { formState, waiting, user, onSubmitHook } = this.state;
|
||||
const { formState, waiting, currentUser, onSubmitHook } = this.state;
|
||||
//Thanks Josh Owens for this one.
|
||||
function capitalService() {
|
||||
return serviceName.charAt(0).toUpperCase() + serviceName.slice(1);
|
||||
|
@ -751,8 +758,8 @@ export class AccountsLoginForm extends Tracker.Component {
|
|||
else {
|
||||
onSubmitHook(null, formState);
|
||||
this.setState({ formState: STATES.PROFILE, password: null });
|
||||
let user = Accounts.user();
|
||||
loginResultCallback(this.state.onPostSignUpHook.bind(this, _options, user));
|
||||
let currentUser = Accounts.user();
|
||||
loginResultCallback(this.state.onPostSignUpHook.bind(this, _options, currentUser));
|
||||
this.clearDefaultFieldValues();
|
||||
}
|
||||
|
||||
|
@ -924,4 +931,4 @@ AccountsLoginForm.contextTypes = {
|
|||
intl: intlShape
|
||||
}
|
||||
|
||||
registerComponent('AccountsLoginForm', AccountsLoginForm);
|
||||
registerComponent('AccountsLoginForm', AccountsLoginForm, withCurrentUser, withApollo);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Package.describe({
|
||||
name: 'std:accounts-ui',
|
||||
version: '1.2.19',
|
||||
name: 'nova:accounts',
|
||||
version: '1.2.0',
|
||||
summary: 'Accounts UI for React in Meteor 1.3+',
|
||||
git: 'https://github.com/studiointeract/accounts-ui',
|
||||
documentation: 'README.md'
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import { Button, FormControl } from 'react-bootstrap';
|
||||
import { Accounts } from 'meteor/std:accounts-ui';
|
||||
import { withApollo } from 'react-apollo';
|
||||
import { registerComponent, withCurrentUser } from 'meteor/nova:core';
|
||||
|
||||
Accounts.ui.config({
|
||||
passwordSignupFields: 'USERNAME_AND_EMAIL',
|
||||
});
|
||||
|
||||
const AccountsForm = ({client, currentUser}) => {
|
||||
return (
|
||||
<div>
|
||||
<Accounts.ui.LoginForm
|
||||
user={currentUser}
|
||||
onPostSignUpHook={() => client.resetStore()}
|
||||
onSignedInHook={() => client.resetStore()}
|
||||
onSignedOutHook={() => client.resetStore()}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
class AccountsButton extends Accounts.ui.Button {
|
||||
render () {
|
||||
const {label, href, type, disabled, className, onClick} = this.props;
|
||||
if (type === 'link') {
|
||||
return <a href={ href } className={ className } onClick={ onClick }>{ label }</a>;
|
||||
}
|
||||
return <Button
|
||||
bsStyle="primary"
|
||||
className={ className }
|
||||
type={ type }
|
||||
disabled={ disabled }
|
||||
onClick={ onClick }>{ label }
|
||||
</Button>;
|
||||
}
|
||||
}
|
||||
|
||||
class AccountsField extends Accounts.ui.Field {
|
||||
|
||||
render() {
|
||||
const { id, hint, /* label, */ type = 'text', onChange, className = "field", defaultValue = "", message } = this.props;
|
||||
const { mount = true } = this.state;
|
||||
return mount ? (
|
||||
<div className={ className }>
|
||||
<FormControl id={ id } type={ type } inputRef={ref => { this.input = ref; }} onChange={ onChange } placeholder={ hint } defaultValue={ defaultValue } />
|
||||
{message && (
|
||||
<span className={['message', message.type].join(' ').trim()}>
|
||||
{message.message}</span>
|
||||
)}
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
Accounts.ui.Button = AccountsButton;
|
||||
Accounts.ui.Field = AccountsField;
|
||||
|
||||
registerComponent('AccountsForm', AccountsForm, withCurrentUser, withApollo);
|
|
@ -6,7 +6,7 @@ Wrapped with the "withDocument" container.
|
|||
*/
|
||||
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import Movies from '../modules/collection.js';
|
||||
import Movies from '../../modules/movies/collection.js';
|
||||
import { withDocument, registerComponent } from 'meteor/nova:core';
|
||||
|
||||
const MoviesDetails = props => {
|
|
@ -7,7 +7,7 @@ Wrapped with the "withDocument" container.
|
|||
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { Components, registerComponent, getFragment } from "meteor/nova:core";
|
||||
import Movies from '../modules/collection.js';
|
||||
import Movies from '../../modules/movies/collection.js';
|
||||
|
||||
const MoviesEditForm = props =>
|
||||
<Components.SmartForm
|
|
@ -8,7 +8,7 @@ Wrapped with the "withCurrentUser" container.
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { Components, registerComponent, ModalTrigger } from 'meteor/nova:core';
|
||||
import Movies from '../modules/collection.js';
|
||||
import Movies from '../../modules/movies/collection.js';
|
||||
|
||||
class MoviesItem extends Component {
|
||||
|
|
@ -7,7 +7,7 @@ Wrapped with the "withList" and "withCurrentUser" containers.
|
|||
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import Movies from '../modules/collection.js';
|
||||
import Movies from '../../modules/movies/collection.js';
|
||||
import { Components, registerComponent, ModalTrigger, withList, withCurrentUser } from 'meteor/nova:core';
|
||||
|
||||
const LoadMore = props => <a href="#" className="load-more button button--primary" onClick={e => {e.preventDefault(); props.loadMore();}}>Load More ({props.count}/{props.totalCount})</a>
|
|
@ -5,7 +5,7 @@ A component to configure the "new movie" form.
|
|||
*/
|
||||
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import Movies from '../modules/collection.js';
|
||||
import Movies from '../../modules/movies/collection.js';
|
||||
import { Components, registerComponent, withMessages, getFragment } from 'meteor/nova:core';
|
||||
|
||||
const MoviesNewForm = props =>
|
|
@ -11,7 +11,7 @@ const MoviesWrapper = () =>
|
|||
<div className="wrapper framework-demo">
|
||||
|
||||
<div className="header">
|
||||
<Components.AccountsForm />
|
||||
<Components.AccountsLoginForm />
|
||||
</div>
|
||||
|
||||
<div className="main">
|
|
@ -1,7 +1,7 @@
|
|||
import '../components/AccountsForm.jsx';
|
||||
import '../components/MoviesDetails.jsx';
|
||||
import '../components/MoviesEditForm.jsx';
|
||||
import '../components/MoviesItem.jsx';
|
||||
import '../components/MoviesList.jsx';
|
||||
import '../components/MoviesNewForm.jsx';
|
||||
import '../components/MoviesWrapper.jsx';
|
||||
import '../components/movies/MoviesDetails.jsx';
|
||||
import '../components/movies/MoviesEditForm.jsx';
|
||||
import '../components/movies/MoviesItem.jsx';
|
||||
import '../components/movies/MoviesList.jsx';
|
||||
import '../components/movies/MoviesNewForm.jsx';
|
||||
import '../components/movies/MoviesWrapper.jsx';
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
// The main Movies collection
|
||||
import MoviesImport from './collection.js';
|
||||
import MoviesImport from './movies/collection.js';
|
||||
|
||||
// Text strings used in the UI
|
||||
import './i18n.js';
|
||||
|
||||
// Groups & user permissions
|
||||
import './permissions.js';
|
||||
|
||||
// GraphQL fragments used to query for data
|
||||
import './fragments.js';
|
||||
|
||||
// React components
|
||||
import './components.js';
|
||||
|
@ -16,8 +11,5 @@ import './components.js';
|
|||
// Routes
|
||||
import './routes.js';
|
||||
|
||||
// Sorting & filtering parameters
|
||||
import './parameters.js';
|
||||
|
||||
// Add Movies collection to global Meteor namespace (optional)
|
||||
Movies = MoviesImport;
|
|
@ -9,6 +9,15 @@ import schema from './schema.js';
|
|||
import resolvers from './resolvers.js';
|
||||
import mutations from './mutations.js';
|
||||
|
||||
// Groups & user permissions
|
||||
import './permissions.js';
|
||||
|
||||
// GraphQL fragments used to query for data
|
||||
import './fragments.js';
|
||||
|
||||
// Sorting & filtering parameters
|
||||
import './parameters.js';
|
||||
|
||||
const Movies = createCollection({
|
||||
|
||||
collectionName: 'movies',
|
|
@ -1,4 +1,4 @@
|
|||
import { addRoute, getComponent } from 'meteor/nova:core';
|
||||
|
||||
// add new "/movies" route that loads the MoviesWrapper component
|
||||
addRoute({ name: 'movies', path: 'movies', componentName: 'MoviesWrapper' });
|
||||
addRoute({ name: 'movies', path: '/', componentName: 'MoviesWrapper' });
|
||||
|
|
|
@ -4,7 +4,7 @@ Seed the database with some dummy content.
|
|||
|
||||
*/
|
||||
|
||||
import Movies from '../modules/collection.js';
|
||||
import Movies from '../modules/movies/collection.js';
|
||||
import Users from 'meteor/nova:users';
|
||||
import { newMutation } from 'meteor/nova:core';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Package.describe({
|
||||
name: 'framework-demo',
|
||||
name: 'example-movies-full',
|
||||
});
|
||||
|
||||
Package.onUse(function (api) {
|
||||
|
@ -9,10 +9,10 @@ Package.onUse(function (api) {
|
|||
'nova:forms',
|
||||
'nova:routing',
|
||||
|
||||
'std:accounts-ui@1.2.19',
|
||||
'nova:accounts',
|
||||
]);
|
||||
|
||||
api.addFiles('lib/stylesheets/bootstrap.css', 'client');
|
||||
api.addFiles('lib/stylesheets/bootstrap.min.css', 'client');
|
||||
|
||||
api.mainModule('lib/server/main.js', 'server');
|
||||
api.mainModule('lib/client/main.js', 'client');
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import { Accounts } from 'meteor/std:accounts-ui';
|
||||
import { withApollo } from 'react-apollo';
|
||||
import { Components, registerComponent } from 'meteor/nova:core';
|
||||
|
||||
Accounts.ui.config({
|
||||
passwordSignupFields: 'USERNAME_AND_EMAIL',
|
||||
});
|
||||
|
||||
const AccountsForm = ({client}) => {
|
||||
return (
|
||||
<div style={{padding: '20px 0', marginBottom: '20px', borderBottom: '1px solid #ccc'}} >
|
||||
<Components.AccountsLoginForm
|
||||
onPostSignUpHook={() => client.resetStore()}
|
||||
onSignedInHook={() => client.resetStore()}
|
||||
onSignedOutHook={() => client.resetStore()}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default withApollo(AccountsForm);
|
|
@ -6,20 +6,23 @@ Wrapped with the "withList" and "withCurrentUser" containers.
|
|||
*/
|
||||
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { withList, withCurrentUser, Loading } from 'meteor/nova:core';
|
||||
import { Components, withList, withCurrentUser, Loading } from 'meteor/nova:core';
|
||||
|
||||
import Movies from '../../modules/movies/collection.js';
|
||||
import MoviesItem from './MoviesItem.jsx';
|
||||
import MoviesNewForm from './MoviesNewForm.jsx';
|
||||
import AccountsForm from '../AccountsForm.jsx';
|
||||
|
||||
const MoviesList = ({results, currentUser, loading, loadMore, count, totalCount}) =>
|
||||
const MoviesList = ({results = [], currentUser, loading, loadMore, count, totalCount}) =>
|
||||
|
||||
<div style={{maxWidth: '500px', margin: 'auto'}}>
|
||||
|
||||
{/* user accounts */}
|
||||
|
||||
<AccountsForm />
|
||||
<div style={{padding: '20px 0', marginBottom: '20px', borderBottom: '1px solid #ccc'}}>
|
||||
|
||||
<Components.AccountsLoginForm />
|
||||
|
||||
</div>
|
||||
|
||||
{loading ?
|
||||
|
||||
|
@ -50,6 +53,7 @@ const MoviesList = ({results, currentUser, loading, loadMore, count, totalCount}
|
|||
const options = {
|
||||
collection: Movies,
|
||||
fragmentName: 'MoviesItemFragment',
|
||||
limit: 5
|
||||
};
|
||||
|
||||
export default withList(options)(withCurrentUser(MoviesList))
|
|
@ -2,4 +2,4 @@ import { addRoute } from 'meteor/nova:core';
|
|||
|
||||
import MoviesList from '../components/movies/MoviesList.jsx';
|
||||
|
||||
addRoute({ name: 'movies', path: 'movies', component: MoviesList });
|
||||
addRoute({ name: 'movies', path: '/', component: MoviesList });
|
||||
|
|
|
@ -9,7 +9,7 @@ Package.onUse(function (api) {
|
|||
'nova:forms',
|
||||
'nova:routing',
|
||||
|
||||
'std:accounts-ui@1.2.19',
|
||||
'nova:accounts',
|
||||
]);
|
||||
|
||||
api.addFiles('lib/stylesheets/bootstrap.min.css');
|
||||
|
|
Loading…
Add table
Reference in a new issue