mirror of
https://github.com/taobataoma/meanTorrent.git
synced 2026-05-06 15:56:20 +02:00
0.3RC
Express 4 Support New naming convention Glob patterns CSS Linting Uglify CSS Min Environmental Asset Management DI Menu System
This commit is contained in:
15
.csslintrc
Normal file
15
.csslintrc
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"adjoining-classes": false,
|
||||
"box-model": false,
|
||||
"box-sizing": false,
|
||||
"floats": false,
|
||||
"font-sizes": false,
|
||||
"important": false,
|
||||
"known-properties": false,
|
||||
"overqualified-elements": false,
|
||||
"qualified-headings": false,
|
||||
"regex-selectors": false,
|
||||
"unique-headings": false,
|
||||
"universal-selector": false,
|
||||
"unqualified-attributes": false
|
||||
}
|
||||
@@ -68,6 +68,13 @@ var UserSchema = new Schema({
|
||||
},
|
||||
providerData: {},
|
||||
additionalProvidersData: {},
|
||||
roles: {
|
||||
type: [{
|
||||
type: String,
|
||||
enum: ['user', 'admin']
|
||||
}],
|
||||
default: ['user']
|
||||
},
|
||||
updated: {
|
||||
type: Date
|
||||
},
|
||||
@@ -114,8 +121,10 @@ UserSchema.statics.findUniqueUsername = function(username, suffix, callback) {
|
||||
var _this = this;
|
||||
var possibleUsername = username + (suffix || '');
|
||||
|
||||
_this.findOne({username: possibleUsername}, function(err, user) {
|
||||
if(!err) {
|
||||
_this.findOne({
|
||||
username: possibleUsername
|
||||
}, function(err, user) {
|
||||
if (!err) {
|
||||
if (!user) {
|
||||
callback(possibleUsername);
|
||||
} else {
|
||||
@@ -3,8 +3,8 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
var users = require('../../app/controllers/users'),
|
||||
articles = require('../../app/controllers/articles');
|
||||
var users = require('../../app/controllers/users.server.controller'),
|
||||
articles = require('../../app/controllers/articles.server.controller');
|
||||
|
||||
module.exports = function(app) {
|
||||
// Article Routes
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
module.exports = function(app) {
|
||||
// Root routing
|
||||
var core = require('../../app/controllers/core');
|
||||
var core = require('../../app/controllers/core.server.controller');
|
||||
app.get('/', core.index);
|
||||
};
|
||||
@@ -7,7 +7,7 @@ var passport = require('passport');
|
||||
|
||||
module.exports = function(app) {
|
||||
// User Routes
|
||||
var users = require('../../app/controllers/users');
|
||||
var users = require('../../app/controllers/users.server.controller');
|
||||
app.get('/users/me', users.me);
|
||||
app.put('/users', users.update);
|
||||
app.post('/users/password', users.changePassword);
|
||||
@@ -30,18 +30,11 @@
|
||||
<meta name="twitter:image" content="/img/brand/logo.png">
|
||||
|
||||
<!-- Fav Icon -->
|
||||
<link href="/img/brand/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
||||
<link href="/modules/core/img/brand/favicon.ico" rel="shortcut icon" type="image/x-icon">
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.css">
|
||||
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap-theme.css">
|
||||
|
||||
<!-- Application CSS -->
|
||||
<link rel="stylesheet" href="/css/common.css">
|
||||
|
||||
<!--Application Modules CSS-->
|
||||
{% for modulesCSSFile in modulesCSSFiles %}
|
||||
<link rel="stylesheet" href="{{modulesCSSFile}}">{% endfor %}
|
||||
<!--Application CSS Files-->
|
||||
{% for cssFile in cssFiles %}<link rel="stylesheet" href="{{cssFile}}">
|
||||
{% endfor %}
|
||||
|
||||
<!-- HTML5 Shim -->
|
||||
<!--[if lt IE 9]>
|
||||
@@ -62,29 +55,13 @@
|
||||
var user = {{ user | json | safe }};
|
||||
</script>
|
||||
|
||||
<!--AngularJS-->
|
||||
<script type="text/javascript" src="/lib/angular/angular.js"></script>
|
||||
<script type="text/javascript" src="/lib/angular-resource/angular-resource.js"></script>
|
||||
<script type="text/javascript" src="/lib/angular-cookies/angular-cookies.js"></script>
|
||||
<script type="text/javascript" src="/lib/angular-animate/angular-animate.js"></script>
|
||||
|
||||
<!--Angular UI-->
|
||||
<script type="text/javascript" src="/lib/angular-bootstrap/ui-bootstrap.js"></script>
|
||||
<script type="text/javascript" src="/lib/angular-ui-utils/ui-utils.js"></script>
|
||||
<script type="text/javascript" src="/lib/angular-ui-router/release/angular-ui-router.js"></script>
|
||||
|
||||
<!--AngularJS Application Init-->
|
||||
<script type="text/javascript" src="/js/config.js"></script>
|
||||
<script type="text/javascript" src="/js/application.js"></script>
|
||||
|
||||
<!--Application Modules-->
|
||||
{% for modulesJSFile in modulesJSFiles %}
|
||||
<script type="text/javascript" src="{{modulesJSFile}}"></script>
|
||||
<!--Application JavaScript Files-->
|
||||
{% for jsFile in jsFiles %}<script type="text/javascript" src="{{jsFile}}"></script>
|
||||
{% endfor %}
|
||||
|
||||
{% if process.env.NODE_ENV === 'development' %}
|
||||
<!--Livereload script rendered -->
|
||||
<script type="text/javascript" src="http://localhost:35729/livereload.js"></script>
|
||||
<!--Livereload script rendered -->
|
||||
<script type="text/javascript" src="http://localhost:35729/livereload.js"></script>
|
||||
{% endif %}
|
||||
</body>
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"dependencies": {
|
||||
"bootstrap": "~3",
|
||||
"angular": "~1.2",
|
||||
"angular-cookies": "~1.2",
|
||||
"angular-resource": "~1.2",
|
||||
"angular-animate": "~1.2",
|
||||
"angular-mocks": "~1.2",
|
||||
|
||||
@@ -1,15 +1,74 @@
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash'),
|
||||
utilities = require('./utilities');
|
||||
glob = require('glob');
|
||||
|
||||
// Look for a valid NODE_ENV variable and if one cannot be found load the development NODE_ENV
|
||||
process.env.NODE_ENV = ~utilities.walk('./config/env', /(.*)\.js$/).map(function(file) {
|
||||
return file.split('/').pop().slice(0, -3);
|
||||
}).indexOf(process.env.NODE_ENV) ? process.env.NODE_ENV : 'development';
|
||||
/**
|
||||
* Before we begin, lets set the envrionment variable
|
||||
* We'll Look for a valid NODE_ENV variable and if one cannot be found load the development NODE_ENV
|
||||
*/
|
||||
glob('./config/env/' + process.env.NODE_ENV + '.js', {
|
||||
sync: true
|
||||
}, function(err, environmentFiles) {
|
||||
process.env.NODE_ENV = environmentFiles.length ? process.env.NODE_ENV : 'development';
|
||||
});
|
||||
|
||||
// Load app configurations
|
||||
module.exports = _.extend(
|
||||
require('./env/all'),
|
||||
require('./env/' + process.env.NODE_ENV) || {}
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
* Get the modules JavaScript files
|
||||
*/
|
||||
module.exports.getGlobbedFiles = function(globPatterns, removeRoot) {
|
||||
// For context switching
|
||||
var _this = this;
|
||||
|
||||
// The output array
|
||||
var output = [];
|
||||
|
||||
// If glob pattern is array so we use each pattern in a recursive way, otherwise we use glob
|
||||
if (_.isArray(globPatterns)) {
|
||||
globPatterns.forEach(function(globPattern) {
|
||||
output = _.union(output, _this.getGlobbedFiles(globPattern, removeRoot));
|
||||
});
|
||||
} else if (_.isString(globPatterns)) {
|
||||
glob(globPatterns, {
|
||||
sync: true
|
||||
}, function(err, files) {
|
||||
if (removeRoot) {
|
||||
files = files.map(function(file) {
|
||||
return file.replace(removeRoot, '');
|
||||
});
|
||||
}
|
||||
|
||||
output = _.union(output, files);
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the modules JavaScript files
|
||||
*/
|
||||
module.exports.getJavaScriptAssets = function(includeTests) {
|
||||
var output = this.getGlobbedFiles(this.assets.js, 'public/');
|
||||
|
||||
// To include tests
|
||||
if (includeTests) {
|
||||
output = _.union(output, this.getGlobbedFiles(this.assets.tests));
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the modules CSS files
|
||||
*/
|
||||
module.exports.getCSSAssets = function() {
|
||||
var output = this.getGlobbedFiles(this.assets.css, 'public/');
|
||||
return output;
|
||||
};
|
||||
25
config/env/all.js
vendored
25
config/env/all.js
vendored
@@ -13,5 +13,28 @@ module.exports = {
|
||||
port: process.env.PORT || 3000,
|
||||
templateEngine: 'swig',
|
||||
sessionSecret: 'MEAN',
|
||||
sessionCollection: 'sessions'
|
||||
sessionCollection: 'sessions',
|
||||
assets: {
|
||||
css: [
|
||||
'public/lib/bootstrap/dist/css/bootstrap.css',
|
||||
'public/lib/bootstrap/dist/css/bootstrap-theme.css',
|
||||
'public/modules/**/css/*.css'
|
||||
],
|
||||
js: [
|
||||
'public/lib/angular/angular.js',
|
||||
'public/lib/angular-resource/angular-resource.js',
|
||||
'public/lib/angular-animate/angular-animate.js',
|
||||
'public/lib/angular-ui-router/release/angular-ui-router.js',
|
||||
'public/lib/angular-ui-utils/ui-utils.js',
|
||||
'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
|
||||
'public/config.js',
|
||||
'public/application.js',
|
||||
'public/modules/*/*.js',
|
||||
'public/modules/*/*[!tests]*/*.js'
|
||||
],
|
||||
tests: [
|
||||
'public/lib/angular-mocks/angular-mocks.js',
|
||||
'public/modules/*/tests/*.js'
|
||||
]
|
||||
}
|
||||
};
|
||||
6
config/env/production.js
vendored
6
config/env/production.js
vendored
@@ -1,7 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean',
|
||||
db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean',
|
||||
assets: {
|
||||
css: 'public/dist/application.min.css',
|
||||
js: 'public/dist/application.min.js'
|
||||
},
|
||||
facebook: {
|
||||
clientID: 'APP_ID',
|
||||
clientSecret: 'APP_SECRET',
|
||||
|
||||
@@ -9,15 +9,14 @@ var express = require('express'),
|
||||
flash = require('connect-flash'),
|
||||
config = require('./config'),
|
||||
consolidate = require('consolidate'),
|
||||
path = require('path'),
|
||||
utilities = require('./utilities');
|
||||
path = require('path');
|
||||
|
||||
module.exports = function(db) {
|
||||
// Initialize express app
|
||||
var app = express();
|
||||
|
||||
// Initialize models
|
||||
utilities.walk('./app/models').forEach(function(modelPath) {
|
||||
// Globbing model files
|
||||
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
|
||||
require(path.resolve(modelPath));
|
||||
});
|
||||
|
||||
@@ -27,8 +26,8 @@ module.exports = function(db) {
|
||||
description: config.app.description,
|
||||
keywords: config.app.keywords,
|
||||
facebookAppId: config.facebook.clientID,
|
||||
modulesJSFiles: utilities.walk('./public/modules', /(.*)\.(js)/, /(.*)\.(spec.js)/, './public'),
|
||||
modulesCSSFiles: utilities.walk('./public/modules', /(.*)\.(css)/, null, './public')
|
||||
jsFiles: config.getJavaScriptAssets(),
|
||||
cssFiles: config.getCSSAssets()
|
||||
});
|
||||
|
||||
// Passing the request url to environment locals
|
||||
@@ -104,8 +103,8 @@ module.exports = function(db) {
|
||||
// Setting the app router and static folder
|
||||
app.use(express.static(config.root + '/public'));
|
||||
|
||||
// Load Routes
|
||||
utilities.walk('./app/routes').forEach(function(routePath) {
|
||||
// Globbing routing files
|
||||
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
|
||||
require(path.resolve(routePath))(app);
|
||||
});
|
||||
|
||||
@@ -132,4 +131,4 @@ module.exports = function(db) {
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
var passport = require('passport'),
|
||||
User = require('mongoose').model('User'),
|
||||
path = require('path'),
|
||||
utilities = require('./utilities');
|
||||
config = require('./config');
|
||||
|
||||
module.exports = function() {
|
||||
// Serialize sessions
|
||||
@@ -21,7 +21,7 @@ module.exports = function() {
|
||||
});
|
||||
|
||||
// Initialize strategies
|
||||
utilities.walk('./config/strategies').forEach(function(strategyPath) {
|
||||
require(path.resolve(strategyPath))();
|
||||
config.getGlobbedFiles('./config/strategies/**/*.js').forEach(function(strategy) {
|
||||
require(path.resolve(strategy))();
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
var passport = require('passport'),
|
||||
FacebookStrategy = require('passport-facebook').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
users = require('../../app/controllers/users.server.controller');
|
||||
|
||||
module.exports = function() {
|
||||
// Use facebook strategy
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var passport = require('passport'),
|
||||
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
users = require('../../app/controllers/users.server.controller');
|
||||
|
||||
module.exports = function() {
|
||||
// Use google strategy
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var passport = require('passport'),
|
||||
LinkedInStrategy = require('passport-linkedin').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
users = require('../../app/controllers/users.server.controller');
|
||||
|
||||
module.exports = function() {
|
||||
// Use linkedin strategy
|
||||
|
||||
@@ -4,7 +4,6 @@ var passport = require('passport'),
|
||||
LocalStrategy = require('passport-local').Strategy,
|
||||
User = require('mongoose').model('User');
|
||||
|
||||
|
||||
module.exports = function() {
|
||||
// Use local strategy
|
||||
passport.use(new LocalStrategy({
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var passport = require('passport'),
|
||||
TwitterStrategy = require('passport-twitter').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
users = require('../../app/controllers/users.server.controller');
|
||||
|
||||
module.exports = function() {
|
||||
// Use twitter strategy
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
var fs = require('fs');
|
||||
|
||||
// Walk function to recursively get files
|
||||
var _walk = function(root, includeRegex, excludeRegex, removePath) {
|
||||
var output = [];
|
||||
var directories = [];
|
||||
includeRegex = includeRegex || /(.*)\.(js|coffee)$/;
|
||||
|
||||
// First read through files
|
||||
fs.readdirSync(root).forEach(function(file) {
|
||||
var newPath = root + '/' + file;
|
||||
var stat = fs.statSync(newPath);
|
||||
|
||||
if (stat.isFile()) {
|
||||
if (includeRegex.test(file) && (!excludeRegex || !excludeRegex.test(file))) {
|
||||
output.push(newPath.replace(removePath, ''));
|
||||
}
|
||||
} else if (stat.isDirectory()) {
|
||||
directories.push(newPath);
|
||||
}
|
||||
});
|
||||
|
||||
// Then recursively add directories
|
||||
directories.forEach(function(directory) {
|
||||
output = output.concat(_walk(directory, includeRegex, excludeRegex, removePath));
|
||||
});
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Exposing the walk function
|
||||
*/
|
||||
exports.walk = _walk;
|
||||
44
gruntfile.js
44
gruntfile.js
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('./config/config');
|
||||
|
||||
module.exports = function(grunt) {
|
||||
// Project Configuration
|
||||
grunt.initConfig({
|
||||
@@ -33,6 +35,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
clientCSS: {
|
||||
files: ['public/**/css/*.css'],
|
||||
tasks: ['csslint'],
|
||||
options: {
|
||||
livereload: true,
|
||||
}
|
||||
@@ -46,6 +49,31 @@ module.exports = function(grunt) {
|
||||
}
|
||||
}
|
||||
},
|
||||
csslint: {
|
||||
options: {
|
||||
csslintrc: '.csslintrc',
|
||||
},
|
||||
all: {
|
||||
src: ['public/modules/**/css/*.css']
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
production: {
|
||||
options: {
|
||||
mangle: false
|
||||
},
|
||||
files: {
|
||||
'public/dist/application.min.js': config.assets.js
|
||||
}
|
||||
}
|
||||
},
|
||||
cssmin: {
|
||||
combine: {
|
||||
files: {
|
||||
'public/dist/application.min.css': config.assets.css
|
||||
}
|
||||
}
|
||||
},
|
||||
nodemon: {
|
||||
dev: {
|
||||
script: 'server.js',
|
||||
@@ -80,19 +108,19 @@ module.exports = function(grunt) {
|
||||
});
|
||||
|
||||
//Load NPM tasks
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-mocha-test');
|
||||
grunt.loadNpmTasks('grunt-karma');
|
||||
grunt.loadNpmTasks('grunt-nodemon');
|
||||
grunt.loadNpmTasks('grunt-concurrent');
|
||||
grunt.loadNpmTasks('grunt-env');
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
//Making grunt default to force in order not to break the project.
|
||||
grunt.option('force', true);
|
||||
|
||||
//Default task(s).
|
||||
grunt.registerTask('default', ['jshint', 'concurrent']);
|
||||
grunt.registerTask('default', ['jshint', 'csslint', 'concurrent']);
|
||||
|
||||
//Lint task(s).
|
||||
grunt.registerTask('lint', ['jshint', 'csslint']);
|
||||
|
||||
//Build task(s).
|
||||
grunt.registerTask('build', ['jshint', 'csslint', 'uglify', 'cssmin']);
|
||||
|
||||
//Test task.
|
||||
grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
var utilities = require('./config/utilities');
|
||||
|
||||
// Grabbing module files using the walk function
|
||||
var modulesJSFiles = utilities.walk('./public/modules', /(.*)\.js$/);
|
||||
var applicationConfiguration = require('./config/config');
|
||||
|
||||
// Karma configuration
|
||||
module.exports = function(config) {
|
||||
@@ -15,18 +12,7 @@ module.exports = function(config) {
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
// List of files / patterns to load in the browser
|
||||
files: [
|
||||
'public/lib/angular/angular.js',
|
||||
'public/lib/angular-animate/angular-animate.js',
|
||||
'public/lib/angular-mocks/angular-mocks.js',
|
||||
'public/lib/angular-cookies/angular-cookies.js',
|
||||
'public/lib/angular-resource/angular-resource.js',
|
||||
'public/lib/angular-bootstrap/ui-bootstrap.js',
|
||||
'public/lib/angular-ui-utils/ui-utils.js',
|
||||
'public/lib/angular-ui-router/release/angular-ui-router.js',
|
||||
'public/js/config.js',
|
||||
'public/js/application.js',
|
||||
].concat(modulesJSFiles),
|
||||
files: applicationConfiguration.assets.js.concat(applicationConfiguration.assets.tests),
|
||||
|
||||
// Test results reporter to use
|
||||
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "meanjs",
|
||||
"description": "Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js.",
|
||||
"version": "0.2.3",
|
||||
"version": "0.3.0",
|
||||
"private": false,
|
||||
"author": "https://github.com/meanjs/mean/graphs/contributors",
|
||||
"repository": {
|
||||
@@ -33,7 +33,8 @@
|
||||
"lodash": "~2.4.1",
|
||||
"forever": "~0.11.00",
|
||||
"bower": "~1.3.1",
|
||||
"grunt-cli": "~0.1.13"
|
||||
"grunt-cli": "~0.1.13",
|
||||
"glob": "~3.2.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"supertest": "~0.10.0",
|
||||
@@ -42,10 +43,14 @@
|
||||
"grunt-node-inspector": "~0.1.3",
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-contrib-csslint": "^0.2.0",
|
||||
"grunt-contrib-uglify": "~0.4.0",
|
||||
"grunt-contrib-cssmin": "~0.9.0",
|
||||
"grunt-nodemon": "~0.2.0",
|
||||
"grunt-concurrent": "~0.5.0",
|
||||
"grunt-mocha-test": "~0.10.0",
|
||||
"grunt-karma": "~0.8.2",
|
||||
"load-grunt-tasks": "~0.4.0",
|
||||
"karma": "~0.12.0",
|
||||
"karma-jasmine": "~0.2.1",
|
||||
"karma-coverage": "~0.2.0",
|
||||
|
||||
16
public/config.js
Normal file
16
public/config.js
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
// Init the application configuration object for AngularJS application
|
||||
var ApplicationConfiguration = (function() {
|
||||
return {
|
||||
applicationModuleName: 'mean',
|
||||
applicationModuleVendorDependencies: ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils'],
|
||||
registerModule: function(moduleName) {
|
||||
// Create angular module
|
||||
angular.module(moduleName, []);
|
||||
|
||||
// Add the module to the AngularJS configuration file
|
||||
angular.module(this.applicationModuleName).requires.push(moduleName);
|
||||
}
|
||||
};
|
||||
})();
|
||||
9
public/dist/application.min.css
vendored
Normal file
9
public/dist/application.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
12
public/dist/application.min.js
vendored
Normal file
12
public/dist/application.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
0
public/img/.gitignore
vendored
0
public/img/.gitignore
vendored
@@ -1,23 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Init the application configuration module for AngularJS application
|
||||
var ApplicationConfiguration = (function() {
|
||||
// Init module configuration options
|
||||
var applicationModuleName = 'mean';
|
||||
var applicationModuleVendorDependencies = ['ngResource', 'ngCookies', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils'];
|
||||
|
||||
// Add a new vertical module
|
||||
var registerModule = function(moduleName) {
|
||||
// Create angular module
|
||||
angular.module(moduleName, []);
|
||||
|
||||
// Add the module to the AngularJS configuration file
|
||||
angular.module(applicationModuleName).requires.push(moduleName);
|
||||
};
|
||||
|
||||
return {
|
||||
applicationModuleName: applicationModuleName,
|
||||
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
|
||||
registerModule: registerModule
|
||||
};
|
||||
})();
|
||||
10
public/modules/articles/config/articles.config.js
Normal file
10
public/modules/articles/config/articles.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
// Configuring the Articles module
|
||||
angular.module('articles').run(['Menus',
|
||||
function(Menus) {
|
||||
// Set top bar menu items
|
||||
Menus.addMenuItem('topbar', 'Articles', 'articles');
|
||||
Menus.addMenuItem('topbar', 'New Article', 'articles/create');
|
||||
}
|
||||
]);
|
||||
62
public/modules/articles/controllers/articles.controller.js
Normal file
62
public/modules/articles/controllers/articles.controller.js
Normal file
@@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
|
||||
function($scope, $stateParams, $location, Authentication, Articles) {
|
||||
$scope.authentication = Authentication;
|
||||
|
||||
$scope.create = function() {
|
||||
var article = new Articles({
|
||||
title: this.title,
|
||||
content: this.content
|
||||
});
|
||||
article.$save(function(response) {
|
||||
$location.path('articles/' + response._id);
|
||||
});
|
||||
|
||||
this.title = '';
|
||||
this.content = '';
|
||||
};
|
||||
|
||||
$scope.remove = function(article) {
|
||||
if (article) {
|
||||
article.$remove();
|
||||
|
||||
for (var i in $scope.articles) {
|
||||
if ($scope.articles[i] === article) {
|
||||
$scope.articles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$scope.article.$remove(function() {
|
||||
$location.path('articles');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
var article = $scope.article;
|
||||
if (!article.updated) {
|
||||
article.updated = [];
|
||||
}
|
||||
article.updated.push(new Date().getTime());
|
||||
|
||||
article.$update(function() {
|
||||
$location.path('articles/' + article._id);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.find = function() {
|
||||
Articles.query(function(articles) {
|
||||
$scope.articles = articles;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.findOne = function() {
|
||||
Articles.get({
|
||||
articleId: $stateParams.articleId
|
||||
}, function(article) {
|
||||
$scope.article = article;
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
@@ -1,62 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
|
||||
function($scope, $stateParams, $location, Authentication, Articles) {
|
||||
$scope.authentication = Authentication;
|
||||
|
||||
$scope.create = function() {
|
||||
var article = new Articles({
|
||||
title: this.title,
|
||||
content: this.content
|
||||
});
|
||||
article.$save(function(response) {
|
||||
$location.path('articles/' + response._id);
|
||||
});
|
||||
|
||||
this.title = '';
|
||||
this.content = '';
|
||||
};
|
||||
|
||||
$scope.remove = function(article) {
|
||||
if (article) {
|
||||
article.$remove();
|
||||
|
||||
for (var i in $scope.articles) {
|
||||
if ($scope.articles[i] === article) {
|
||||
$scope.articles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$scope.article.$remove(function() {
|
||||
$location.path('articles');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
var article = $scope.article;
|
||||
if (!article.updated) {
|
||||
article.updated = [];
|
||||
}
|
||||
article.updated.push(new Date().getTime());
|
||||
|
||||
article.$update(function() {
|
||||
$location.path('articles/' + article._id);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.find = function() {
|
||||
Articles.query(function(articles) {
|
||||
$scope.articles = articles;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.findOne = function() {
|
||||
Articles.get({
|
||||
articleId: $stateParams.articleId
|
||||
}, function(article) {
|
||||
$scope.article = article;
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
@@ -1,19 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('core').controller('HeaderController', ['$scope', 'Authentication',
|
||||
function($scope, Authentication) {
|
||||
angular.module('core').controller('HeaderController', ['$scope', 'Authentication', 'Menus',
|
||||
function($scope, Authentication, Menus) {
|
||||
$scope.authentication = Authentication;
|
||||
$scope.isCollapsed = false;
|
||||
|
||||
$scope.menu = [{
|
||||
title: 'Articles',
|
||||
link: 'articles',
|
||||
uiRoute: '/articles'
|
||||
}, {
|
||||
title: 'New Article',
|
||||
link: 'articles/create',
|
||||
uiRoute: '/articles/create'
|
||||
}];
|
||||
$scope.menu = Menus.getMenu('topbar');
|
||||
|
||||
$scope.toggleCollapsibleMenu = function() {
|
||||
$scope.isCollapsed = !$scope.isCollapsed;
|
||||
@@ -1,7 +1,7 @@
|
||||
.content {
|
||||
margin-top: 50px;
|
||||
}
|
||||
a.undecorated-link:hover {
|
||||
.undecorated-link:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
114
public/modules/core/services/menus.service.js
Normal file
114
public/modules/core/services/menus.service.js
Normal file
@@ -0,0 +1,114 @@
|
||||
'use strict';
|
||||
|
||||
//Menu service used for managing menus
|
||||
angular.module('core').service('Menus', [
|
||||
function() {
|
||||
// Define a set of default roles
|
||||
this.defaultRoles = ['user'];
|
||||
|
||||
// Define the menus object
|
||||
this.menus = {};
|
||||
|
||||
// A private function for rendering decision
|
||||
var shouldRender = function(user) {
|
||||
if(user) {
|
||||
for (var userRoleIndex in user.roles) {
|
||||
for (var roleIndex in this.roles) {
|
||||
if(this.roles[roleIndex] === user.roles[userRoleIndex]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return !this.requiresAuthentication;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Validate menu existance
|
||||
this.validateMenuExistance = function(menuId) {
|
||||
if (menuId && menuId.length) {
|
||||
if (this.menus[menuId]) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error('Menu does not exists');
|
||||
}
|
||||
} else {
|
||||
throw new Error('MenuId was not provided');
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Get the menu object by menu id
|
||||
this.getMenu = function(menuId) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
// Add new menu object by menu id
|
||||
this.addMenu = function(menuId, requiresAuthentication, roles) {
|
||||
// Create the new menu
|
||||
this.menus[menuId] = {
|
||||
requiresAuthentication: requiresAuthentication || true,
|
||||
roles: roles || this.defaultRoles,
|
||||
items: [],
|
||||
shouldRender: shouldRender
|
||||
};
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
// Remove existing menu object by menu id
|
||||
this.removeMenu = function(menuId) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Return the menu object
|
||||
delete this.menus[menuId];
|
||||
};
|
||||
|
||||
// Add menu item object
|
||||
this.addMenuItem = function(menuId, menuItemTitle, menuItemURL, menuItemUIRoute, requiresAuthentication, roles) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Push new menu item
|
||||
this.menus[menuId].items.push({
|
||||
title: menuItemTitle,
|
||||
link: menuItemURL,
|
||||
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
|
||||
requiresAuthentication: requiresAuthentication || false,
|
||||
roles: roles || this.defaultRoles,
|
||||
shouldRender: shouldRender
|
||||
});
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
// Remove existing menu object by menu id
|
||||
this.removeMenuItem = function(menuId, menuItemURL) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Search for menu item to remove
|
||||
for (var itemIndex in this.menus[menuId].items) {
|
||||
if (this.menus[menuId].items[itemIndex].menuItemURL === menuItemURL) {
|
||||
this.menus[menuId].items.splice(itemIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
//Adding the topbar menu
|
||||
this.addMenu('topbar');
|
||||
}
|
||||
]);
|
||||
@@ -9,8 +9,8 @@
|
||||
<a href="/#!/" class="navbar-brand">MEAN.JS</a>
|
||||
</div>
|
||||
<nav class="collapse navbar-collapse" collapse="!isCollapsed" role="navigation">
|
||||
<ul class="nav navbar-nav" data-ng-show="authentication.user">
|
||||
<li data-ng-repeat="item in menu" data-ng-show="authentication.user" ui-route="{{item.uiRoute}}" ng-class="{active: $uiRoute}">
|
||||
<ul class="nav navbar-nav" data-ng-if="menu.shouldRender(authentication.user);">
|
||||
<li data-ng-repeat="item in menu.items" data-ng-if="item.shouldRender(authentication.user);" ui-route="{{item.uiRoute}}" ng-class="{active: $uiRoute}">
|
||||
<a href="/#!/{{item.link}}">{{item.title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -10,6 +9,7 @@ var config = require('./config/config'),
|
||||
* Main application entry file.
|
||||
* Please note that the order of loading is important.
|
||||
*/
|
||||
|
||||
// Bootstrap db connection
|
||||
var db = mongoose.connect(config.db);
|
||||
|
||||
@@ -26,4 +26,5 @@ app.listen(config.port);
|
||||
exports = module.exports = app;
|
||||
|
||||
// Logging initialization
|
||||
console.log('Express app started on port ' + config.port);
|
||||
console.log('Using the "' + process.env.NODE_ENV + '" envrionment file');
|
||||
console.log('MEAN.JS application started on port ' + config.port);
|
||||
|
||||
Reference in New Issue
Block a user