Get rid of example-movies-full package

This commit is contained in:
SachaG 2017-03-28 18:24:46 +09:00
parent 64da012d7f
commit dfe6e314a3
27 changed files with 0 additions and 734 deletions

View file

@ -1,11 +0,0 @@
import React, { PropTypes, Component } from 'react';
const PicsImage = ({imageUrl, onClick}) =>
<div className="pics-image" onClick={onClick}>
<img src={imageUrl}/>
</div>
export default PicsImage;

View file

@ -1,10 +0,0 @@
import { addCallback } from 'meteor/vulcan:core';
function sortByCreatedAt (parameters, terms) {
return {
selector: parameters.selector,
options: {...parameters.options, sort: {createdAt: -1}}
};
}
addCallback('pics.parameters', sortByCreatedAt);

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
Vulcan demo package.

View file

@ -1 +0,0 @@
import '../modules/index.js';

View file

@ -1,34 +0,0 @@
/*
A component that shows a detailed view of a single movie.
Wrapped with the "withDocument" container.
*/
import React, { PropTypes, Component } from 'react';
import Movies from '../../modules/movies/collection.js';
import { withDocument, registerComponent } from 'meteor/vulcan:core';
const MoviesDetails = props => {
const movie = props.document;
if (props.loading) {
return <p>Loading</p>
} else {
return (
<div>
<h2>{movie.name} ({movie.year})</h2>
<p>Reviewed by <strong>{movie.user && movie.user.displayName}</strong> on {movie.createdAt}</p>
<p>{movie.review}</p>
{movie.privateComments ? <p><strong>PRIVATE</strong>: {movie.privateComments}</p>: null}
</div>
)
}
}
const options = {
collection: Movies,
queryName: 'moviesSingleQuery',
fragmentName: 'MoviesDetailsFragment',
};
registerComponent('MoviesDetails', MoviesDetails, withDocument(options));

View file

@ -1,23 +0,0 @@
/*
A component to configure the "edit movie" form.
Wrapped with the "withDocument" container.
*/
import React, { PropTypes, Component } from 'react';
import { Components, registerComponent, getFragment } from "meteor/vulcan:core";
import Movies from '../../modules/movies/collection.js';
const MoviesEditForm = props =>
<Components.SmartForm
collection={Movies}
documentId={props.documentId}
mutationFragment={getFragment('MoviesDetailsFragment')}
showRemove={true}
successCallback={document => {
props.closeModal();
}}
/>
registerComponent('MoviesEditForm', MoviesEditForm);

View file

@ -1,61 +0,0 @@
/*
An item in the movies list.
Wrapped with the "withCurrentUser" container.
*/
import React, { PropTypes, Component } from 'react';
import { Button } from 'react-bootstrap';
import { Components, registerComponent, ModalTrigger } from 'meteor/vulcan:core';
import Movies from '../../modules/movies/collection.js';
class MoviesItem extends Component {
renderDetails() {
const movie = this.props.movie;
return (
<div style={{display: 'inline-block', marginRight: '5px'}}>
<ModalTrigger label="View Details">
<Components.MoviesDetails documentId={movie._id}/>
</ModalTrigger>
</div>
)
}
renderEdit() {
const movie = this.props.movie;
return (
<div style={{display: 'inline-block', marginRight: '5px'}}>
<ModalTrigger label="Edit Movie" >
<Components.MoviesEditForm currentUser={this.props.currentUser} documentId={movie._id} />
</ModalTrigger>
</div>
)
}
render() {
const movie = this.props.movie;
return (
<div key={movie.name} style={{paddingBottom: "15px",marginBottom: "15px", borderBottom: "1px solid #ccc"}}>
<h2>{movie.name} ({movie.year})</h2>
<p>By <strong>{movie.user && movie.user.displayName}</strong></p>
<div className="item-actions">
{this.renderDetails()}
&nbsp;|&nbsp;
{Movies.options.mutations.edit.check(this.props.currentUser, movie) ? this.renderEdit() : null}
</div>
</div>
)
}
}
registerComponent('MoviesItem', MoviesItem);

View file

@ -1,61 +0,0 @@
/*
List of movies.
Wrapped with the "withList" and "withCurrentUser" containers.
*/
import React, { PropTypes, Component } from 'react';
import { Button } from 'react-bootstrap';
import Movies from '../../modules/movies/collection.js';
import { Components, registerComponent, ModalTrigger, withList, withCurrentUser } from 'meteor/vulcan: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>
class MoviesList extends Component {
renderNew() {
const component = (
<div className="add-movie">
<ModalTrigger
title="Add Movie"
component={<Button bsStyle="primary">Add Movie</Button>}
>
<Components.MoviesNewForm />
</ModalTrigger>
<hr/>
</div>
)
return !!this.props.currentUser ? component : null;
}
render() {
const canCreateNewMovie = Movies.options.mutations.new.check(this.props.currentUser);
if (this.props.loading) {
return <Components.Loading />
} else {
const hasMore = this.props.totalCount > this.props.results.length;
return (
<div className="movies">
{canCreateNewMovie ? this.renderNew() : null}
{this.props.results.map(movie => <Components.MoviesItem key={movie._id} movie={movie} currentUser={this.props.currentUser} />)}
{hasMore ? <LoadMore {...this.props}/> : <p>No more movies</p>}
</div>
)
}
}
}
const options = {
collection: Movies,
queryName: 'moviesListQuery',
fragmentName: 'MoviesItemFragment',
limit: 5,
};
registerComponent('MoviesList', MoviesList, withList(options), withCurrentUser);

View file

@ -1,20 +0,0 @@
/*
A component to configure the "new movie" form.
*/
import React, { PropTypes, Component } from 'react';
import Movies from '../../modules/movies/collection.js';
import { Components, registerComponent, withMessages, getFragment } from 'meteor/vulcan:core';
const MoviesNewForm = props =>
<Components.SmartForm
collection={Movies}
mutationFragment={getFragment('MoviesItemFragment')}
successCallback={document => {
props.closeModal();
}}
/>
registerComponent('MoviesNewForm', MoviesNewForm, withMessages);

View file

@ -1,23 +0,0 @@
/*
Wrapper for the Movies components
*/
import React, { PropTypes, Component } from 'react';
import { Components, registerComponent } from 'meteor/vulcan:core';
const MoviesWrapper = () =>
<div className="wrapper framework-demo" style={{maxWidth: '500px', margin: 'auto'}}>
<div className="header" style={{padding: '20px 0', marginBottom: '20px', borderBottom: '1px solid #ccc'}}>
<Components.AccountsLoginForm />
</div>
<div className="main">
<Components.MoviesList />
</div>
</div>
registerComponent('MoviesWrapper', MoviesWrapper);

View file

@ -1,6 +0,0 @@
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';

View file

@ -1,12 +0,0 @@
/*
Add strings for internationalization.
*/
import { addStrings } from 'meteor/vulcan:core';
addStrings('en', {
'movies.delete': "Delete Movie",
'movies.delete_confirm': "Delete Movie?"
});

View file

@ -1,15 +0,0 @@
// The main Movies collection
import MoviesImport from './movies/collection.js';
// Text strings used in the UI
import './i18n.js';
// React components
import './components.js';
// Routes
import './routes.js';
// Add Movies collection to global Meteor namespace (optional)
Movies = MoviesImport;

View file

@ -1,35 +0,0 @@
/*
The main Movies collection definition file.
*/
import { createCollection } from 'meteor/vulcan:core';
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',
typeName: 'Movie',
schema,
resolvers,
mutations,
});
export default Movies;

View file

@ -1,35 +0,0 @@
/*
Register the two GraphQL fragments used to query for data
*/
import { registerFragment } from 'meteor/vulcan:core';
registerFragment(`
fragment MoviesItemFragment on Movie {
_id
name
year
createdAt
userId
user {
displayName
}
}
`);
registerFragment(`
fragment MoviesDetailsFragment on Movie {
_id
name
createdAt
year
review
privateComments
userId
user {
displayName
}
}
`);

View file

@ -1,104 +0,0 @@
/*
Define the three default mutations:
- new (e.g.: moviesNew(document: moviesInput) : Movie )
- edit (e.g.: moviesEdit(documentId: String, set: moviesInput, unset: moviesUnset) : Movie )
- remove (e.g.: moviesRemove(documentId: String) : Movie )
Each mutation has:
- A name
- A check function that takes the current user and (optionally) the document affected
- The actual mutation
*/
import { newMutation, editMutation, removeMutation, Utils } from 'meteor/vulcan:core';
import Users from 'meteor/vulcan:users';
const performCheck = (mutation, user, document) => {
if (!mutation.check(user, document)) throw new Error(Utils.encodeIntlError({id: `app.mutation_not_allowed`, value: `"${mutation.name}" on _id "${document._id}"`}));
}
const mutations = {
new: {
name: 'moviesNew',
check(user) {
if (!user) return false;
return Users.canDo(user, 'movies.new');
},
mutation(root, {document}, context) {
performCheck(this, context.currentUser, document);
return newMutation({
collection: context.Movies,
document: document,
currentUser: context.currentUser,
validate: true,
context,
});
},
},
edit: {
name: 'moviesEdit',
check(user, document) {
if (!user || !document) return false;
return Users.owns(user, document) ? Users.canDo(user, 'movies.edit.own') : Users.canDo(user, `movies.edit.all`);
},
mutation(root, {documentId, set, unset}, context) {
const document = context.Movies.findOne(documentId);
performCheck(this, context.currentUser, document);
return editMutation({
collection: context.Movies,
documentId: documentId,
set: set,
unset: unset,
currentUser: context.currentUser,
validate: true,
context,
});
},
},
remove: {
name: 'moviesRemove',
check(user, document) {
if (!user || !document) return false;
return Users.owns(user, document) ? Users.canDo(user, 'movies.remove.own') : Users.canDo(user, `movies.remove.all`);
},
mutation(root, {documentId}, context) {
const document = context.Movies.findOne(documentId);
performCheck(this, context.currentUser, document);
return removeMutation({
collection: context.Movies,
documentId: documentId,
currentUser: context.currentUser,
validate: true,
context,
});
},
},
};
export default mutations;

View file

@ -1,19 +0,0 @@
/*
Add a new parameter callback that sorts movies by 'createdAt' property.
We use a callback instead of defining the sort in the resolver so that
the same sort can be used on the client, too.
*/
import { addCallback } from 'meteor/vulcan:core';
function sortByCreatedAt (parameters, terms) {
return {
selector: parameters.selector,
options: {...parameters.options, sort: {createdAt: -1}}
};
}
addCallback("movies.parameters", sortByCreatedAt);

View file

@ -1,14 +0,0 @@
import Users from 'meteor/vulcan:users';
const membersActions = [
'movies.new',
'movies.edit.own',
'movies.remove.own',
];
Users.groups.members.can(membersActions);
const adminActions = [
'movies.edit.all',
'movies.remove.all'
];
Users.groups.admins.can(adminActions);

View file

@ -1,62 +0,0 @@
/*
Three resolvers are defined:
- list (e.g.: moviesList(terms: JSON, offset: Int, limit: Int) )
- single (e.g.: moviesSingle(_id: String) )
- listTotal (e.g.: moviesTotal )
*/
import { GraphQLSchema } from 'meteor/vulcan:core';
// add the "user" resolver for the Movie type separately
const movieResolver = {
Movie: {
user(movie, args, context) {
return context.Users.findOne({ _id: movie.userId }, { fields: context.getViewableFields(context.currentUser, context.Users) });
},
},
};
GraphQLSchema.addResolvers(movieResolver);
// basic list, single, and total query resolvers
const resolvers = {
list: {
name: 'moviesList',
resolver(root, {terms = {}}, context, info) {
let {selector, options} = context.Movies.getParameters(terms);
options.limit = (terms.limit < 1 || terms.limit > 100) ? 100 : terms.limit;
options.fields = context.getViewableFields(context.currentUser, context.Movies);
return context.Movies.find(selector, options).fetch();
},
},
single: {
name: 'moviesSingle',
resolver(root, {documentId}, context) {
const document = context.Movies.findOne({_id: documentId});
return _.pick(document, _.keys(context.getViewableFields(context.currentUser, context.Movies, document)));
},
},
total: {
name: 'moviesTotal',
resolver(root, {terms = {}}, context) {
let {selector, options} = context.Movies.getParameters(terms);
return context.Movies.find(selector, options).count();
},
}
};
export default resolvers;

View file

@ -1,63 +0,0 @@
/*
A SimpleSchema-compatible JSON schema
*/
import Users from 'meteor/vulcan:users';
// define schema
const schema = {
_id: {
type: String,
optional: true,
viewableBy: ['guests'],
},
name: {
label: 'Name',
type: String,
viewableBy: ['guests'],
insertableBy: ['members'],
editableBy: ['members'],
},
createdAt: {
type: Date,
viewableBy: ['guests'],
autoValue: (documentOrModifier) => {
if (documentOrModifier && !documentOrModifier.$set) return new Date() // if this is an insert, set createdAt to current timestamp
}
},
year: {
label: 'Year',
type: String,
optional: true,
viewableBy: ['guests'],
insertableBy: ['members'],
editableBy: ['members'],
},
review: {
label: 'Review',
type: String,
control: 'textarea',
viewableBy: ['guests'],
insertableBy: ['members'],
editableBy: ['members']
},
privateComments: {
label: 'Private Comments',
type: String,
optional: true,
control: 'textarea',
viewableBy: Users.owns,
insertableBy: ['members'],
editableBy: ['members']
},
userId: {
type: String,
optional: true,
viewableBy: ['guests'],
resolveAs: 'user: User',
}
};
export default schema;

View file

@ -1,4 +0,0 @@
import { addRoute, getComponent } from 'meteor/vulcan:core';
// add new "/movies" route that loads the MoviesWrapper component
addRoute({ name: 'movies', path: '/', componentName: 'MoviesWrapper' });

View file

@ -1,2 +0,0 @@
import '../modules/index.js';
import './seed.js';

View file

@ -1,80 +0,0 @@
/*
Seed the database with some dummy content.
*/
import Movies from '../modules/movies/collection.js';
import Users from 'meteor/vulcan:users';
import { newMutation } from 'meteor/vulcan:core';
const seedData = [
{
name: 'Star Wars',
year: '1973',
review: `A classic.`,
privateComments: `Actually, I don't really like Star Wars…`
},
{
name: 'Die Hard',
year: '1987',
review: `A must-see if you like action movies.`,
privateComments: `I love Bruce Willis so much!`
},
{
name: 'Terminator',
year: '1983',
review: `Once again, Schwarzenegger shows why he's the boss.`,
privateComments: `Terminator is my favorite movie ever. `
},
{
name: 'Jaws',
year: '1971',
review: 'The original blockbuster.',
privateComments: `I'm scared of sharks…`
},
{
name: 'Die Hard II',
year: '1991',
review: `Another classic.`
},
{
name: 'Rush Hour',
year: '1993',
review: `Jackie Chan at his best.`,
},
{
name: 'Citizen Kane',
year: '1943',
review: `A disappointing lack of action sequences.`,
},
{
name: 'Commando',
year: '1983',
review: 'A good contender for highest kill count ever.',
},
];
Meteor.startup(function () {
if (Users.find().fetch().length === 0) {
Accounts.createUser({
username: 'DemoUser',
email: 'dummyuser@telescopeapp.org',
profile: {
isDummy: true
}
});
}
const currentUser = Users.findOne();
if (Movies.find().fetch().length === 0) {
seedData.forEach(document => {
newMutation({
action: 'movies.new',
collection: Movies,
document: document,
currentUser: currentUser,
validate: false
});
});
}
});

File diff suppressed because one or more lines are too long

View file

@ -1,23 +0,0 @@
Package.describe({
name: 'example-movies-full',
});
Package.onUse(function (api) {
api.use([
'vulcan:core',
'vulcan:forms',
'vulcan:routing',
'vulcan:accounts',
]);
api.addFiles('lib/stylesheets/bootstrap.min.css', 'client');
api.mainModule('lib/server/main.js', 'server');
api.mainModule('lib/client/main.js', 'client');
api.export([
'Movies',
], ['client', 'server']);
});

View file

@ -1,7 +1,6 @@
/*
A component to configure the "edit movie" form.
Wrapped with the "withDocument" container.
*/