diff --git a/.gitignore b/.gitignore index 5bcaf95..b34967f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,50 @@ +# Logs +logs +*.log +npm-debug.log* -dist/public/js/loopback-admin.resources.js +# Runtime data +pids +*.pid +*.seed +*.pid.lock -dist/public/js/loopback-admin.config.js +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov -dist/public/config.json +# Coverage directory used by tools like istanbul +coverage -dist/package.json +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +.idea +.DS_Store diff --git a/Gruntfile.coffee b/Gruntfile.coffee deleted file mode 100644 index 4c0ed5c..0000000 --- a/Gruntfile.coffee +++ /dev/null @@ -1,96 +0,0 @@ -{ normalize } = require 'path' - -module.exports = (grunt) -> - require('load-grunt-tasks') grunt - - grunt.initConfig - config: - dist: normalize "#{__dirname}/dist" - - concat: - js: - src: [ - 'src/client/vendor/js/**/*.js' - 'src/client/vendor/js/**' - ] - dest: 'dist/public/js/loopback-admin.vendor.js' - - css: - src: [ - 'src/client/vendor/css/**/*.css' - 'src/client/vendor/css/**' - ] - dest: 'dist/public/css/loopback-admin.vendor.css' - - copy: - dist: - src: ['package.json'] - dest: normalize "#{__dirname}/dist" - expand: true - main: - files: [ - { expand: true, cwd: 'src/client/assets/', src: ['**'], dest: 'dist/public' } - ] - - clean: - dist: src: [ '<%= config.dist %>/*.js', '<%= config.dist %>/public/js/*.js', '<%= config.dist %>/public/{css,images,index.html,!config.json}', '!<%= config.dist %>/public/js/{loopback-admin.resources,loopback-admin.config}.js' ] - - coffee: - app: - options: - bare: true - join: true - files: 'dist/public/js/loopback-admin.js': ['src/client/app.coffee', 'src/client/components/*.coffee', 'src/client/components/**/**.coffee'] - main: - options: - bare: true - join: true - expand: true - cwd: 'src/component' - src: [ '**/*.coffee' ] - dest: 'dist/' - ext: '.js' - - # https://www.npmjs.com/package/grunt-angular-templates - ngtemplates: - material: - options: - standalone: true - module: 'loopback-admin.theme' - cwd: 'src/client' - src: ['templates/**/*.html'] - dest: 'dist/public/js/loopback-admin.templates.js' - - watch: - less: files: ['src/client/styles/*.less', 'src/client/styles/**/*.less'], tasks: ['less'], options: livereload: true - ngtemplates: files: ['src/client/**/*/**.html'], tasks: ['ngtemplates', 'concat' ], options: livereload: true - coffee: files: ['src/client/*.coffee', 'src/client/**/**.coffee'], tasks: ['coffee', 'ngAnnotate', 'ngtemplates', 'concat'], options: livereload: true - vendor_js: files: ['src/client/vendor/js/**'], tasks: ['ngtemplates', 'concat:js'], options: livereload: true - vendor_css: files: ['src/client/vendor/css/**'], tasks: ['concat:css'], options: livereload: true - copy: files: ['src/client/assets/**'], tasks: ['copy'], options: livereload: true - - # https://www.npmjs.com/package/grunt-express - express: all: options: - port: 4000 - hostname: 'localhost' - bases: [ __dirname + '/dist/public' ] - livereload: true - - open: all: path: 'http://localhost:<%= express.all.options.port%>' - - # https://www.npmjs.com/package/grunt-ng-annotate - ngAnnotate: - dist: - files: 'dist/public/js/loopback-admin.js': [ 'dist/public/js/loopback-admin.js' ] - - less: - build: - files: 'dist/public/css/loopback-admin.css': 'src/client/styles/layout.less' - - grunt.event.on 'watch', (action, filepath, target) -> - grunt.log.writeln target + ': ' + filepath + ' has ' + action - return - - grunt.registerTask 'server', ['default', 'express', 'open', 'watch'] - grunt.registerTask 'default', [ 'clean', 'coffee', 'ngtemplates', 'ngAnnotate', 'concat', 'copy:dist', 'copy:main', 'less' ] - grunt.registerTask 'dev', [ 'default', 'watch' ] \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..913db2e --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,144 @@ +var normalize; + +normalize = require('path').normalize; + +module.exports = function (grunt) { + require('load-grunt-tasks')(grunt); + grunt.initConfig({ + config: { + dist: normalize(__dirname + "/dist") + }, + concat: { + main: { + src: ['src/client/app.js', 'src/client/components/*.js', 'src/client/components/**/**.js'], + dest: 'dist/public/js/loopback-admin.js' + + }, + js: { + src: ['src/client/vendor/js/**/*.js', 'src/client/vendor/js/**'], + dest: 'dist/public/js/loopback-admin.vendor.js' + }, + css: { + src: ['src/client/vendor/css/**/*.css', 'src/client/vendor/css/**'], + dest: 'dist/public/css/loopback-admin.vendor.css' + } + }, + copy: { + dist: { + src: ['package.json'], + dest: normalize(__dirname + "/dist"), + expand: true + }, + component: { + files: [ + { + expand: true, + cwd: 'src/component/', + src: ['*.js'], + dest: 'dist' + } + ] + }, + main: { + files: [ + { + expand: true, + cwd: 'src/client/assets/', + src: ['**'], + dest: 'dist/public' + } + ] + } + }, + clean: { + dist: { + src: ['<%= config.dist %>/*.js', '<%= config.dist %>/public/js/*.js', '<%= config.dist %>/public/{css,images,index.html,!config.json}', '!<%= config.dist %>/public/js/{loopback-admin.resources,loopback-admin.config}.js'] + } + }, + ngtemplates: { + material: { + options: { + standalone: true, + module: 'loopback-admin.theme' + }, + cwd: 'src/client', + src: ['templates/**/*.html'], + dest: 'dist/public/js/loopback-admin.templates.js' + } + }, + watch: { + less: { + files: ['src/client/styles/*.less', 'src/client/styles/**/*.less'], + tasks: ['less'], + options: { + livereload: true + } + }, + ngtemplates: { + files: ['src/client/**/*/**.html'], + tasks: ['ngtemplates', 'concat'], + options: { + livereload: true + } + }, + vendor_js: { + files: ['src/client/vendor/js/**'], + tasks: ['ngtemplates', 'concat:js'], + options: { + livereload: true + } + }, + vendor_css: { + files: ['src/client/vendor/css/**'], + tasks: ['concat:css'], + options: { + livereload: true + } + }, + copy: { + files: ['src/client/assets/**'], + tasks: ['copy'], + options: { + livereload: true + } + } + }, + express: { + all: { + options: { + port: 4000, + hostname: 'localhost', + bases: [__dirname + '/dist/public'], + livereload: true + } + } + }, + open: { + all: { + path: 'http://localhost:<%= express.all.options.port%>' + } + }, + ngAnnotate: { + dist: { + files: { + 'dist/public/js/loopback-admin.js': ['dist/public/js/loopback-admin.js'] + } + } + }, + less: { + build: { + files: { + 'dist/public/css/loopback-admin.css': 'src/client/styles/layout.less' + } + } + } + }); + + grunt.event.on('watch', function (action, filepath, target) { + grunt.log.writeln(target + ': ' + filepath + ' has ' + action); + }); + + grunt.registerTask('server', ['default', 'express', 'open', 'watch']); + grunt.registerTask('default', ['clean', 'concat', 'ngtemplates', 'ngAnnotate', 'copy:dist', 'copy:main', 'copy:component', 'less']); + return grunt.registerTask('dev', ['default', 'watch']); +}; diff --git a/dist/admin-spec.js b/dist/admin-spec.js index 11b1240..e3a6a54 100644 --- a/dist/admin-spec.js +++ b/dist/admin-spec.js @@ -9,75 +9,75 @@ services = require('loopback-sdk-angular').services; path = require('path'); -formatProperties = function(properties) { - var key, result; - result = {}; - for (key in properties) { - result[key] = clone(properties[key]); - if (Array.isArray(properties[key].type)) { - result[key].type = 'Array'; - result[key].subtype = properties[key].type[0]; - } else { - result[key].type = properties[key].type.name; +formatProperties = function (properties) { + var key, result; + result = {}; + for (key in properties) { + result[key] = clone(properties[key]); + if (Array.isArray(properties[key].type)) { + result[key].type = 'Array'; + result[key].subtype = properties[key].type[0]; + } else { + result[key].type = properties[key].type.name; + } } - } - return result; + return result; }; _models = {}; -getModelInfo = function(loopbackApplication, modelName) { - var baseModel, baseProperties, keys, model, properties, result; - if (_models[modelName]) { - return _models[modelName]; - } - model = loopbackApplication.models[modelName]; - baseModel = void 0; - baseProperties = void 0; - if (model.definition.base) { - baseModel = getModelInfo(loopbackApplication, model.definition.base); - baseProperties = formatProperties(baseModel.definition.properties); - } - properties = formatProperties(model.definition.properties); - result = { - name: model.definition.name, - properties: extend(properties, baseProperties) - }; - keys = ['description', 'plural', 'idInjection', 'persistUndefinedAsNull', 'strict', 'hidden', 'validations', 'relations', 'acls', 'methods', 'mixins']; - keys.forEach(function(key) { - var ref1, ref2; - result[key] = (ref1 = model.definition) != null ? (ref2 = ref1.settings) != null ? ref2[key] : void 0 : void 0; - }); - _models[modelName] = result; - return result; +getModelInfo = function (loopbackApplication, modelName) { + var baseModel, baseProperties, keys, model, properties, result; + if (_models[modelName]) { + return _models[modelName]; + } + model = loopbackApplication.models[modelName]; + baseModel = void 0; + baseProperties = void 0; + if (model.definition.base) { + baseModel = getModelInfo(loopbackApplication, model.definition.base); + baseProperties = formatProperties(baseModel.definition.properties); + } + properties = formatProperties(model.definition.properties); + result = { + name: model.definition.name, + properties: extend(properties, baseProperties) + }; + keys = ['description', 'plural', 'idInjection', 'persistUndefinedAsNull', 'strict', 'hidden', 'validations', 'relations', 'acls', 'methods', 'mixins']; + keys.forEach(function (key) { + var ref1, ref2; + result[key] = (ref1 = model.definition) != null ? (ref2 = ref1.settings) != null ? ref2[key] : void 0 : void 0; + }); + _models[modelName] = result; + return result; }; -module.exports = function(loopbackApplication, options, callback) { - var api, handler, host, models, mountPath, port, sdkFile, sdkFilePath, url; - mountPath = options.mountPath; - host = loopbackApplication.get('host'); - port = loopbackApplication.get('port'); - api = loopbackApplication.get('restApiRoot'); - url = options.url || 'http://' + host + ':' + port + api; - sdkFile = services(loopbackApplication, 'loopback-admin.services', url); - sdkFilePath = path.join(__dirname, 'public/js/loopback-admin.resources.js'); - fs.writeFileSync(sdkFilePath, sdkFile, 'utf-8'); - handler = loopbackApplication.handler('rest'); - models = []; - process.nextTick(function() { - var config, configFile, configJSON; - handler.adapter.getClasses().forEach(function(modelClass) { - if (modelClass.ctor) { - return models.push(getModelInfo(loopbackApplication, modelClass.name)); - } +module.exports = function (loopbackApplication, options, callback) { + var api, handler, host, models, mountPath, port, sdkFile, sdkFilePath, url; + mountPath = options.mountPath; + host = loopbackApplication.get('host'); + port = loopbackApplication.get('port'); + api = loopbackApplication.get('restApiRoot'); + url = options.url || 'http://' + host + ':' + port + api; + sdkFile = services(loopbackApplication, 'loopback-admin.services', url); + sdkFilePath = path.join(__dirname, 'public/js/loopback-admin.resources.js'); + fs.writeFileSync(sdkFilePath, sdkFile, 'utf-8'); + handler = loopbackApplication.handler('rest'); + models = []; + process.nextTick(function () { + var config, configFile, configJSON; + handler.adapter.getClasses().forEach(function (modelClass) { + if (modelClass.ctor) { + return models.push(getModelInfo(loopbackApplication, modelClass.name)); + } + }); + config = { + options: options, + models: models.sort() + }; + configFile = path.join(__dirname, 'public/config.json'); + configJSON = JSON.stringify(config); + fs.writeFileSync(configFile, configJSON, 'utf-8'); + callback(configJSON); }); - config = { - options: options, - models: models.sort() - }; - configFile = path.join(__dirname, 'public/config.json'); - configJSON = JSON.stringify(config); - fs.writeFileSync(configFile, configJSON, 'utf-8'); - callback(configJSON); - }); -}; +}; \ No newline at end of file diff --git a/dist/create-user.js b/dist/create-user.js index a5fa0c2..31973ea 100644 --- a/dist/create-user.js +++ b/dist/create-user.js @@ -1,96 +1,96 @@ var createAdminRole, createDefaultAdmin; -module.exports = function(loopbackApplication, options) { - var ACL, Role, RoleMapping, User; - ACL = loopbackApplication.models.ACL; - Role = loopbackApplication.models.Role; - RoleMapping = loopbackApplication.models.RoleMapping; - User = loopbackApplication.models[options.userModel]; - if (!User) { - User = loopbackApplication.models.User; - } - User.count(function(error, count) { - if (error) { - console.log('Error setting up default admin.'); - console.dir(error); - return; +module.exports = function (loopbackApplication, options) { + var ACL, Role, RoleMapping, User; + ACL = loopbackApplication.models.ACL; + Role = loopbackApplication.models.Role; + RoleMapping = loopbackApplication.models.RoleMapping; + User = loopbackApplication.models[options.userModel]; + if (!User) { + User = loopbackApplication.models.User; } - if (count === 0) { - Role.findOne({ - where: { - name: 'admin' - } - }, function(error, result) { + User.count(function (error, count) { if (error) { - console.log('Error setting up default admin role.'); - console.dir(error); - return; + console.log('Error setting up default admin.'); + console.dir(error); + return; } - if (!result) { - createAdminRole(Role, function(error, role) { - if (error) { - console.log('Error creating admin role.'); - console.dir(error); - return; - } - createDefaultAdmin(User, RoleMapping, ACL, role.id); - }); - } else { - createDefaultAdmin(User, RoleMapping, ACL, result.id); + if (count === 0) { + Role.findOne({ + where: { + name: 'admin' + } + }, function (error, result) { + if (error) { + console.log('Error setting up default admin role.'); + console.dir(error); + return; + } + if (!result) { + createAdminRole(Role, function (error, role) { + if (error) { + console.log('Error creating admin role.'); + console.dir(error); + return; + } + createDefaultAdmin(User, RoleMapping, ACL, role.id); + }); + } else { + createDefaultAdmin(User, RoleMapping, ACL, result.id); + } + }); } - }); - } - }); + }); }; -createAdminRole = function(Role, callback) { - var role; - role = { - name: 'admin', - description: 'admin' - }; - Role.create(role, callback); +createAdminRole = function (Role, callback) { + var role; + role = { + name: 'admin', + description: 'admin' + }; + Role.create(role, callback); }; -createDefaultAdmin = function(User, RoleMapping, ACL, roleId) { - User.create({ - email: 'admin@example.com', - username: 'admin', - password: 'password', - created: new Date - }, function(error, user) { - if (error) { - console.log('Error creating \'admin\' user.'); - console.dir(error); - return; - } - RoleMapping.create({ - principalType: 'USER', - principalId: user.getId(), - roleId: roleId - }, function(error, result) { - if (error) { - console.log('Error creating \'admin\' role mapping.'); - console.dir(error); - return; - } - console.log('Created default \'admin\' user with password \'password\'.'); - }); - ACL.create({ - model: User.definition.name, - property: '*', - accessType: '*', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: 'admin' - }); - ACL.create({ - model: 'AccessToken', - property: '*', - accessType: '*', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: 'admin' +createDefaultAdmin = function (User, RoleMapping, ACL, roleId) { + User.create({ + email: 'admin@example.com', + username: 'admin', + password: 'password', + created: new Date + }, function (error, user) { + if (error) { + console.log('Error creating \'admin\' user.'); + console.dir(error); + return; + } + RoleMapping.create({ + principalType: 'USER', + principalId: user.getId(), + roleId: roleId + }, function (error, result) { + if (error) { + console.log('Error creating \'admin\' role mapping.'); + console.dir(error); + return; + } + console.log('Created default \'admin\' user with password \'password\'.'); + }); + ACL.create({ + model: User.definition.name, + property: '*', + accessType: '*', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: 'admin' + }); + ACL.create({ + model: 'AccessToken', + property: '*', + accessType: '*', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: 'admin' + }); }); - }); }; diff --git a/dist/index.js b/dist/index.js index 446af1c..15dac9c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -17,90 +17,90 @@ generateAdminSpec = require('./admin-spec'); STATIC_ROOT = path.join(__dirname, 'public'); -attachXTotalCount = function(loopbackApplication) { - var remotes; - remotes = loopbackApplication.remotes(); - remotes.after('*.find', function(ctx, next) { - var filter; - filter = void 0; - if (ctx.args && ctx.args.filter) { - if (typeof ctx.args.filter === 'object') { - filter = ctx.args.filter.where; - } else { - filter = JSON.parse(ctx.args.filter).where; - } - } - if (!ctx.res._headerSent) { - this.count(filter, function(err, count) { - ctx.res.set('Access-Control-Expose-Headers', 'X-Total-Count'); - ctx.res.set('X-Total-Count', count); - next(); - }); - } else { - next(); - } - }); +attachXTotalCount = function (loopbackApplication) { + var remotes; + remotes = loopbackApplication.remotes(); + remotes.after('*.find', function (ctx, next) { + var filter; + filter = void 0; + if (ctx.args && ctx.args.filter) { + if (typeof ctx.args.filter === 'object') { + filter = ctx.args.filter.where; + } else { + filter = JSON.parse(ctx.args.filter).where; + } + } + if (!ctx.res._headerSent) { + this.count(filter, function (err, count) { + ctx.res.set('Access-Control-Expose-Headers', 'X-Total-Count'); + ctx.res.set('X-Total-Count', count); + next(); + }); + } else { + next(); + } + }); }; -writeConfig = function(config) { - var configJS, configJSON; - configJSON = JSON.stringify(config); - configJS = "angular.module('loopback-admin')\n\n.config([\"LoopBackAdminConfigurationProvider\", function(LoopBackAdminConfigurationProvider) {\n LoopBackAdminConfigurationProvider.setConfig(" + configJSON + ");\n}]);"; - fs.writeFileSync(path.join(__dirname, 'public/js/loopback-admin.config.js'), configJS, 'utf-8'); +writeConfig = function (config) { + var configJS, configJSON; + configJSON = JSON.stringify(config); + configJS = "angular.module('loopback-admin')\n\n.config([\"LoopBackAdminConfigurationProvider\", function(LoopBackAdminConfigurationProvider) {\n LoopBackAdminConfigurationProvider.setConfig(" + configJSON + ");\n}]);"; + fs.writeFileSync(path.join(__dirname, 'public/js/loopback-admin.config.js'), configJS, 'utf-8'); }; -mountAdmin = function(loopbackApplication, adminApp, opts) { - return generateAdminSpec(loopbackApplication, opts, function(adminObject) { - var remotes, resourcePath; - resourcePath = opts.resourcePath; - if (resourcePath[0] !== '/') { - resourcePath = '/' + resourcePath; - } - remotes = loopbackApplication.remotes(); - setupCors(adminApp, remotes); - adminApp.get(resourcePath, function(req, res) { - res.status(200).send(adminObject); +mountAdmin = function (loopbackApplication, adminApp, opts) { + return generateAdminSpec(loopbackApplication, opts, function (adminObject) { + var remotes, resourcePath; + resourcePath = opts.resourcePath; + if (resourcePath[0] !== '/') { + resourcePath = '/' + resourcePath; + } + remotes = loopbackApplication.remotes(); + setupCors(adminApp, remotes); + adminApp.get(resourcePath, function (req, res) { + res.status(200).send(adminObject); + }); }); - }); }; -setupCors = function(adminApp, remotes) { - var corsOptions; - corsOptions = remotes.options && remotes.options.cors || { - origin: true, - credentials: true - }; - adminApp.use(cors(corsOptions)); +setupCors = function (adminApp, remotes) { + var corsOptions; + corsOptions = remotes.options && remotes.options.cors || { + origin: true, + credentials: true + }; + adminApp.use(cors(corsOptions)); }; -routes = function(loopbackApplication, options) { - var loopback, router; - loopback = loopbackApplication.loopback; - options = defaults({}, options, { - resourcePath: 'config.json', - mountPath: '/admin', - userModel: 'User', - userLoginField: 'username', - apiInfo: loopbackApplication.get('apiInfo') || {} - }); - router = new loopback.Router(); - attachXTotalCount(loopbackApplication); - mountAdmin(loopbackApplication, router, options); - writeConfig(options); - router.use(loopback["static"](STATIC_ROOT)); - return router; +routes = function (loopbackApplication, options) { + var loopback, router; + loopback = loopbackApplication.loopback; + options = defaults({}, options, { + resourcePath: 'config.json', + mountPath: '/admin', + userModel: 'User', + userLoginField: 'username', + apiInfo: loopbackApplication.get('apiInfo') || {} + }); + router = new loopback.Router(); + attachXTotalCount(loopbackApplication); + mountAdmin(loopbackApplication, router, options); + writeConfig(options); + router.use(loopback["static"](STATIC_ROOT)); + return router; }; -module.exports = function(loopbackApplication, options) { - options = defaults({}, options, { - mountPath: '/admin' - }); - loopbackApplication.use(options.mountPath, routes(loopbackApplication, options)); - loopbackApplication.set('loopback-component-admin', options); - loopbackApplication.once('started', function() { - var adminPath, baseUrl; - baseUrl = loopbackApplication.get('url').replace(/\/$/, ''); - adminPath = options.mountPath || options.route; - return console.log('Browse your Admin UI at %s%s', baseUrl, adminPath); - }); +module.exports = function (loopbackApplication, options) { + options = defaults({}, options, { + mountPath: '/admin' + }); + loopbackApplication.use(options.mountPath, routes(loopbackApplication, options)); + loopbackApplication.set('loopback-component-admin', options); + loopbackApplication.once('started', function () { + var adminPath, baseUrl; + baseUrl = loopbackApplication.get('url').replace(/\/$/, ''); + adminPath = options.mountPath || options.route; + return console.log('Browse your Admin UI at %s%s', baseUrl, adminPath); + }); }; diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 0000000..d2e2ed3 --- /dev/null +++ b/dist/package.json @@ -0,0 +1,36 @@ +{ + "name": "loopback-component-admin", + "version": "0.2.0", + "main": "dist/index.js", + "author": { + "name": "BoLaMN", + "url": "https://github.com/BoLaMN" + }, + "repository": { + "type": "git", + "url": "https://github.com/aitoraznar/loopback-component-admin" + }, + "license": "MIT", + "scripts": {}, + "devDependencies": { + "grunt": "^0.4.5", + "grunt-angular-templates": "^0.5.7", + "grunt-contrib-clean": "~0.6.0", + "grunt-contrib-coffee": "~0.13.0", + "grunt-contrib-concat": "^0.5.1", + "grunt-contrib-copy": "~0.8.1", + "grunt-contrib-sass": "^*", + "grunt-contrib-watch": "^0.6.1", + "grunt-ng-annotate": "^1.0.1", + "load-grunt-tasks": "^3.2.0", + "grunt-contrib-less": "^1.1.0", + "grunt-contrib-watch": "^0.6.1", + "grunt-express": "^1.4.1", + "grunt-open": "^0.2.3", + "grunt-parallel": "^0.4.1" + }, + "dependencies": { + "loopback": "^2.26.0", + "loopback-sdk-angular": "^1.6.0" + } +} diff --git a/dist/public/js/loopback-admin.js b/dist/public/js/loopback-admin.js index 64da0f6..00a6be7 100644 --- a/dist/public/js/loopback-admin.js +++ b/dist/public/js/loopback-admin.js @@ -1,1367 +1,1390 @@ -var hasProp = {}.hasOwnProperty, - extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - -angular.module('loopback-admin', ['ui.router', 'md.data.table', 'ngSanitize', 'ngAnimate', 'ngAria', 'ngMaterial', 'angularFileUpload', 'loopback-admin.services', 'loopback-admin.theme']).config(["$urlRouterProvider", "$mdThemingProvider", "$mdIconProvider", "$compileProvider", function($urlRouterProvider, $mdThemingProvider, $mdIconProvider, $compileProvider) { - var dark; - $compileProvider.debugInfoEnabled(true); - $mdThemingProvider.theme('default').primaryPalette('blue'); - dark = $mdThemingProvider.extendPalette('grey', { - contrastDefaultColor: 'light' - }); - $mdThemingProvider.definePalette('dark', dark); - $mdThemingProvider.theme('black').primaryPalette('dark', { - "default": '900' - }); - $urlRouterProvider.when('', '/landing').when('/', '/landing').otherwise(function($injector, $location) { - var state; - state = $injector.get('$state'); - state.go('error'); - return $location.path(); - }); - $mdIconProvider.defaultFontSet('material-icons'); -}]); +angular.module('loopback-admin', ['ui.router', 'md.data.table', 'ngSanitize', 'ngAnimate', 'ngAria', 'ngMaterial', + 'angularFileUpload', 'loopback-admin.services', + 'loopback-admin.theme']) + .config(["$urlRouterProvider", "$mdThemingProvider", "$mdIconProvider", "$compileProvider", function ($urlRouterProvider, $mdThemingProvider, $mdIconProvider, $compileProvider) { -'use strict'; + var dark; -angular.module('loopback-admin').controller('AccountSettingsController', ["$upload", "$rootScope", "activeTab", "LoopBackAuth", "LoopBackAdminConfiguration", function($upload, $rootScope, activeTab, LoopBackAuth, LoopBackAdminConfiguration) { - var User, vm; - vm = this; - User = LoopBackAdminConfiguration.userModel; - vm.auth = LoopBackAuth; - vm.activeTab = activeTab; - vm.changePassword = function(passwords) { - User.changePassword(passwords).$promise.then((function(_this) { - return function(data) { - $rootScope.showToast(data); - $rootScope.closeModal(); - }; - })(this)); - }; - vm.getUsernameForCurrentUser = function() { - if (!this.current || !this.current.email) { - return; - } - if (this.current.username) { - return this.current.username; - } - return this.current.email.split('@')[0]; - }; - vm.updateAccountSettings = function(settings, id) { - var payload, userId; - payload = settings || this.auth.currentUserData; - userId = id || this.auth.currentUserId; - return User.update({ - where: { - id: userId - } - }, payload).$promise.then((function(_this) { - return function(data) { - if (!settings) { - $rootScope.showToast('profileUpdateSuccess', true); - $rootScope.closeModal(); - _this.current = data; - } - }; - })(this)); - }; - vm.removeAvatar = function() { - return $http["delete"](LoopBackAdminConfiguration.urlBase + '/employees/' + this.current.id + '/avatar').success(function(data) { - this.current.avatar_url = ''; - $rootScope.showToast(data); - }); - }; - vm.upload = function(files) { - var file; - if (!files.length) { - return; - } - file = files[0]; - return $upload.upload({ - url: LoopBackAdminConfiguration.urlBase + '/employees/' + id + '/avatar', - file: file - }).success(function(data) { - return LoopBackAuth.currentUserData.avatar_url = data; - }).error(function(data, code) { - if (code === 422) { - return showToast(data.file[0]); - } - }); - }; -}]).directive('cmsCurrentUser', function() { - return { - replace: true, - templateUrl: 'templates/common/current-user.html', - controllerAs: 'ctrl', - controller: ["$state", "LoopBackAuth", "$mdDialog", "$upload", function($state, LoopBackAuth, $mdDialog, $upload) { - var vm; - vm = this; - vm.auth = LoopBackAuth; - vm.state = $state; - vm.openMenu = function($mdOpenMenu, ev) { - return $mdOpenMenu(ev); - }; - vm.showAccountSettingsModal = function($event, fieldToFocus) { - var options; - options = { - templateUrl: 'templates/modals/account-settings.html', - targetEvent: $event, - locals: { - activeTab: 'settings' - }, - clickOutsideToClose: true, - controllerAs: 'modal', - controller: 'AccountSettingsController' - }; - if (fieldToFocus === 'avatar') { - options.locals.activeTab = 'avatar'; - } - $mdDialog.show(options); - }; - }] - }; -}).directive('cmsToolbar', function() { - return { - replace: true, - scope: { - title: '=' - }, - templateUrl: 'templates/common/toolbar.html' - }; + $compileProvider.debugInfoEnabled(true); + $mdThemingProvider.theme('default').primaryPalette('blue'); + dark = $mdThemingProvider.extendPalette('grey', { + contrastDefaultColor: 'light' + }); + $mdThemingProvider.definePalette('dark', dark); + $mdThemingProvider.theme('black').primaryPalette('dark', { + "default": '900' + }); + $urlRouterProvider.when('', '/landing').when('/', '/landing').otherwise(function ($injector, $location) { + var state; + state = $injector.get('$state'); + state.go('error'); + return $location.path(); + }); + $mdIconProvider.defaultFontSet('material-icons'); + }]); + +'use strict'; +angular.module('loopback-admin').controller('AccountSettingsController', ["$upload", "$rootScope", "activeTab", "LoopBackAuth", "LoopBackAdminConfiguration", function ($upload, $rootScope, activeTab, LoopBackAuth, LoopBackAdminConfiguration) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.auth = LoopBackAuth; + vm.activeTab = activeTab; + vm.changePassword = function (passwords) { + User.changePassword(passwords).$promise.then((function (_this) { + return function (data) { + $rootScope.showToast(data); + $rootScope.closeModal(); + }; + })(this)); + }; + vm.getUsernameForCurrentUser = function () { + if (!this.current || !this.current.email) { + return; + } + if (this.current.username) { + return this.current.username; + } + return this.current.email.split('@')[0]; + }; + vm.updateAccountSettings = function (settings, id) { + var payload, userId; + payload = settings || this.auth.currentUserData; + userId = id || this.auth.currentUserId; + return User.update({ + where: { + id: userId + } + }, payload).$promise.then((function (_this) { + return function (data) { + if (!settings) { + $rootScope.showToast('profileUpdateSuccess', true); + $rootScope.closeModal(); + _this.current = data; + } + }; + })(this)); + }; + vm.removeAvatar = function () { + return $http["delete"](LoopBackAdminConfiguration.urlBase + '/employees/' + this.current.id + '/avatar').success(function (data) { + this.current.avatar_url = ''; + $rootScope.showToast(data); + }); + }; + vm.upload = function (files) { + var file; + if (!files.length) { + return; + } + file = files[0]; + return $upload.upload({ + url: LoopBackAdminConfiguration.urlBase + '/employees/' + id + '/avatar', + file: file + }).success(function (data) { + return LoopBackAuth.currentUserData.avatar_url = data; + }).error(function (data, code) { + if (code === 422) { + return showToast(data.file[0]); + } + }); + }; +}]).directive('cmsCurrentUser', function () { + return { + replace: true, + templateUrl: 'templates/common/current-user.html', + controllerAs: 'ctrl', + controller: ["$state", "LoopBackAuth", "$mdDialog", "$upload", function ($state, LoopBackAuth, $mdDialog, $upload) { + var vm; + vm = this; + vm.auth = LoopBackAuth; + vm.state = $state; + vm.openMenu = function ($mdOpenMenu, ev) { + return $mdOpenMenu(ev); + }; + vm.showAccountSettingsModal = function ($event, fieldToFocus) { + var options; + options = { + templateUrl: 'templates/modals/account-settings.html', + targetEvent: $event, + locals: { + activeTab: 'settings' + }, + clickOutsideToClose: true, + controllerAs: 'modal', + controller: 'AccountSettingsController' + }; + if (fieldToFocus === 'avatar') { + options.locals.activeTab = 'avatar'; + } + $mdDialog.show(options); + }; + }] + }; +}).directive('cmsToolbar', function () { + return { + replace: true, + scope: { + title: '=' + }, + templateUrl: 'templates/common/toolbar.html' + }; }); - 'use strict'; - -angular.module('loopback-admin').directive('mdSidemenu', function() { - return { - restrict: 'E', - scope: { - menu: '=' - }, - template: '', - controllerAs: 'ctrl', - controller: ["$state", function($state) { - var vm; - vm = this; - vm.select = function(state, params) { - return $state.go(state, params); - }; - }] - }; +angular.module('loopback-admin').directive('mdSidemenu', function () { + return { + restrict: 'E', + scope: { + menu: '=' + }, + template: '', + controllerAs: 'ctrl', + controller: ["$state", function ($state) { + var vm; + vm = this; + vm.select = function (state, params) { + return $state.go(state, params); + }; + }] + }; }); 'use strict'; - -angular.module('loopback-admin').directive('cmsSocialButtons', function() { - return { - restrict: 'E', - templateUrl: 'templates/common/social-buttons.tpl.html', - controller: 'SocialLoginCtrl', - controllerAs: 'social' - }; -}).controller('SocialLoginCtrl', ["LoopBackAdminConfiguration", "LoopBackAuth", "$http", "$state", "$mdDialog", "$mdToast", function(LoopBackAdminConfiguration, LoopBackAuth, $http, $state, $mdDialog, $mdToast) { - var vm; - vm = this; - vm.credentials = {}; - vm.loginWith = function(service) { - var left, options, top, url; - url = LoopBackAdminConfiguration.urlBase + '/auth/social/' + service; - left = screen.width / 2 - (580 / 2); - top = screen.height / 2 - (450 / 2); - window.$tempScope = vm; - options = ['menubar=0', 'location=0', 'toolbar=0', 'titlebar=0', 'status=0', 'width=580', 'height=450', 'left=' + left, 'top=' + top].join(', '); - window.open(url, 'Authenticate Account', options); - }; - vm.socialLoginCallback = function(user) { - window.$tempScope = null; - if (user) { - LoopBackAuth.currentUserData = user; - $state.go('dashboard'); - } else { - vm.requestUserEmail(); - } - }; - vm.socialLoginCallbackError = function() { - $mdToast.show($mdToast.simple({ - position: 'bottom right' - }).content('genericSocialError')); - }; - vm.createAndLoginUser = function() { - return $http.post(LoopBackAdminConfiguration.urlBase + '/auth/social/request-email-callback', { - email: vm.credentials.email - }).success(function(data) { - return $state.go('dashboard'); - }).error(function(data) { - if (data.code === 1) { - return vm.requestUserPassword(); - } - }); - }; - vm.connectAccounts = function() { - return $http.post(LoopBackAdminConfiguration.urlBase + '/auth/social/connect-accounts', { - password: vm.credentials.password - }).success(function(data) { - return $state.go('dashboard'); - }).error(function(data) { - return vm.errorMessage = data; - }); - }; - vm.requestUserPassword = function($event) { - $mdDialog.show({ - templateUrl: 'templates/modals/request-password.html', - targetEvent: $event, - controller: 'SocialLoginCtrl' - }); - }; - vm.requestUserEmail = function($event) { - $mdDialog.show({ - templateUrl: 'templates/modals/request-email.html', - targetEvent: $event, - controller: 'SocialLoginCtrl' - }); - }; +angular.module('loopback-admin').directive('cmsSocialButtons', function () { + return { + restrict: 'E', + templateUrl: 'templates/common/social-buttons.tpl.html', + controller: 'SocialLoginCtrl', + controllerAs: 'social' + }; +}).controller('SocialLoginCtrl', ["LoopBackAdminConfiguration", "LoopBackAuth", "$http", "$state", "$mdDialog", "$mdToast", function (LoopBackAdminConfiguration, LoopBackAuth, $http, $state, $mdDialog, $mdToast) { + var vm; + vm = this; + vm.credentials = {}; + vm.loginWith = function (service) { + var left, options, top, url; + url = LoopBackAdminConfiguration.urlBase + '/auth/social/' + service; + left = screen.width / 2 - (580 / 2); + top = screen.height / 2 - (450 / 2); + window.$tempScope = vm; + options = ['menubar=0', 'location=0', 'toolbar=0', 'titlebar=0', 'status=0', 'width=580', 'height=450', 'left=' + left, 'top=' + top].join(', '); + window.open(url, 'Authenticate Account', options); + }; + vm.socialLoginCallback = function (user) { + window.$tempScope = null; + if (user) { + LoopBackAuth.currentUserData = user; + $state.go('dashboard'); + } else { + vm.requestUserEmail(); + } + }; + vm.socialLoginCallbackError = function () { + $mdToast.show($mdToast.simple({ + position: 'bottom right' + }).content('genericSocialError')); + }; + vm.createAndLoginUser = function () { + return $http.post(LoopBackAdminConfiguration.urlBase + '/auth/social/request-email-callback', { + email: vm.credentials.email + }).success(function (data) { + return $state.go('dashboard'); + }).error(function (data) { + if (data.code === 1) { + return vm.requestUserPassword(); + } + }); + }; + vm.connectAccounts = function () { + return $http.post(LoopBackAdminConfiguration.urlBase + '/auth/social/connect-accounts', { + password: vm.credentials.password + }).success(function (data) { + return $state.go('dashboard'); + }).error(function (data) { + return vm.errorMessage = data; + }); + }; + vm.requestUserPassword = function ($event) { + $mdDialog.show({ + templateUrl: 'templates/modals/request-password.html', + targetEvent: $event, + controller: 'SocialLoginCtrl' + }); + }; + vm.requestUserEmail = function ($event) { + $mdDialog.show({ + templateUrl: 'templates/modals/request-email.html', + targetEvent: $event, + controller: 'SocialLoginCtrl' + }); + }; }]); 'use strict'; - -angular.module('loopback-admin').factory('entryFormatter', ["$filter", function($filter) { - return { - formatDate: function(format) { - return function(date) { - return $filter('date')(new Date(date), format); - }; - }, - formatNumber: function(format) { - return function(number) { - return $filter('numeraljs')(number, format); - }; - }, - formatProperty: function(property) { - var format, formatDate, formatNumber, label, type; - label = property.label || property.name; - type = property.type; - switch (type) { - case 'boolean': - case 'choice': - case 'choices': - case 'string': - case 'text': - case 'wysiwyg': - case 'email': - case 'json': - case 'file': - case 'template': - (function(entry) { - return { - name: label, - value: entry.values[property.name] - }; - }); - break; - case 'number': - case 'float': - format = property.format; - formatNumber = this.formatNumber(format); - (function(entry) { - return { - name: label, - value: formatNumber(entry.values[property.name]) +angular.module('loopback-admin').factory('entryFormatter', ["$filter", function ($filter) { + return { + formatDate: function (format) { + return function (date) { + return $filter('date')(new Date(date), format); }; - }); - break; - case 'date': - case 'datetime': - format = property.format; - if (!format) { - format = type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'; - } - formatDate = this.formatDate(format); - (function(entry) { - return { - name: label, - value: formatDate(entry.values[property.name]) + }, + formatNumber: function (format) { + return function (number) { + return $filter('numeraljs')(number, format); }; - }); - break; - case 'reference': - (function(entry) { - return { - name: label, - value: entry.values[property.name] + }, + formatProperty: function (property) { + var format, formatDate, formatNumber, label, type; + label = property.label || property.name; + type = property.type; + switch (type) { + case 'boolean': + case 'choice': + case 'choices': + case 'string': + case 'text': + case 'wysiwyg': + case 'email': + case 'json': + case 'file': + case 'template': + (function (entry) { + return { + name: label, + value: entry.values[property.name] + }; + }); + break; + case 'number': + case 'float': + format = property.format; + formatNumber = this.formatNumber(format); + (function (entry) { + return { + name: label, + value: formatNumber(entry.values[property.name]) + }; + }); + break; + case 'date': + case 'datetime': + format = property.format; + if (!format) { + format = type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'; + } + formatDate = this.formatDate(format); + (function (entry) { + return { + name: label, + value: formatDate(entry.values[property.name]) + }; + }); + break; + case 'reference': + (function (entry) { + return { + name: label, + value: entry.values[property.name] + }; + }); + break; + case 'referenced_many': + case 'referenced_list': + return; + } + }, + getFormatter: function (properties) { + var propertiesFormatters; + propertiesFormatters = properties.map(this.formatProperty.bind(this)); + return function (entry) { + var result; + result = {}; + propertiesFormatters.map(function (formatter) { + if (!formatter) { + return; + } + return formatter(entry); + }).forEach(function (property) { + if (!property) { + return; + } + result[property.name] = property.value; + }); + return result; }; - }); - break; - case 'referenced_many': - case 'referenced_list': - return; - } - }, - getFormatter: function(properties) { - var propertiesFormatters; - propertiesFormatters = properties.map(this.formatProperty.bind(this)); - return function(entry) { - var result; - result = {}; - propertiesFormatters.map(function(formatter) { - if (!formatter) { - return; - } - return formatter(entry); - }).forEach(function(property) { - if (!property) { - return; - } - result[property.name] = property.value; - }); - return result; - }; - } - }; + } + }; }]); 'use strict'; - -angular.module('loopback-admin').factory('LoopbackInjector', ["$injector", function($injector) { - return function(modelName) { - if ($injector.has(modelName)) { - return $injector.get(modelName); - } else { - return void 0; - } - }; +angular.module('loopback-admin').factory('LoopbackInjector', ["$injector", function ($injector) { + return function (modelName) { + if ($injector.has(modelName)) { + return $injector.get(modelName); + } else { + return void 0; + } + }; }]); 'use strict'; - -angular.module('loopback-admin').provider('stringUtils', function() { - return { - camelCase: function(text) { - var f; - if (!text) { - return text; - } - f = text.charAt(0).toUpperCase(); - text = f + text.substr(1); - return text.replace(/[-_.\s](.)/g, function(match, group1) { - return ' ' + group1.toUpperCase(); - }); - }, - $get: function() { - return { - camelCase: this.camelCase - }; - } - }; +angular.module('loopback-admin').provider('stringUtils', function () { + return { + camelCase: function (text) { + var f; + if (!text) { + return text; + } + f = text.charAt(0).toUpperCase(); + text = f + text.substr(1); + return text.replace(/[-_.\s](.)/g, function (match, group1) { + return ' ' + group1.toUpperCase(); + }); + }, + $get: function () { + return { + camelCase: this.camelCase + }; + } + }; }); 'use strict'; - -angular.module('loopback-admin').filter('numeraljs', function() { - return function(input, format) { - if (input === null || format === null) { - return input; - } - if (format === '') { - return ''; - } - return numeral(input).format(format); - }; +angular.module('loopback-admin').filter('numeraljs', function () { + return function (input, format) { + if (input === null || format === null) { + return input; + } + if (format === '') { + return ''; + } + return numeral(input).format(format); + }; }); 'use strict'; - -angular.module('loopback-admin').filter('modelToHuman', function() { - return function(input) { - if (input == null) { - input = ''; - } - return input.replace(/([a-z])([A-Z])/g, '$1 $2'); - }; +angular.module('loopback-admin').filter('modelToHuman', function () { + return function (input) { + if (input == null) { + input = ''; + } + return input.replace(/([a-z])([A-Z])/g, '$1 $2'); + }; }); 'use strict'; - -angular.module('loopback-admin').provider('LoopBackAdminConfiguration', ["LoopBackResourceProvider", function(LoopBackResourceProvider) { - var config, configOptions, initialized; - config = null; - initialized = false; - configOptions = null; - return { - setConfig: function(newConfig) { - return configOptions = newConfig; - }, - $get: ["Model", "$q", "$http", "$injector", function(Model, $q, $http, $injector) { - var application, buildMenuFromModels; - buildMenuFromModels = function() { - return application.models.map(function(model) { - return { - name: model.label, - state: "list", - params: { - model: model.name - } - }; - }); - }; - application = { - models: [], - urlBase: LoopBackResourceProvider.getUrlBase(), - options: configOptions, - defaultErrorMessage: function(response) { - var body; - body = response.data; - if (typeof body === 'object') { - body = JSON.stringify(body); - } - return 'Oops, an error occured else (code: ' + response.status + ') ' + body; +angular.module('loopback-admin').provider('LoopBackAdminConfiguration', ["LoopBackResourceProvider", function (LoopBackResourceProvider) { + var config, configOptions, initialized; + config = null; + initialized = false; + configOptions = null; + return { + setConfig: function (newConfig) { + return configOptions = newConfig; }, - errorMessage: this.defaultErrorMessage, - getErrorMessage: function(response) { - if (typeof this.errorMessage === 'function') { - return this.errorMessage(response); - } - return this.errorMessage; - }, - userModel: $injector.get(configOptions.userModel), - userLoginField: configOptions.userLoginField, - addModel: function(model) { - var foundModel; - if (!model) { - throw new Error("No model given"); - } - foundModel = this.getModelByName(this.models, model.name); - if (!foundModel) { - this.models.push(model); - } - return this; - }, - getModel: function(modelName) { - var foundModel; - foundModel = this.getModelByName(this.models, modelName); - if (!foundModel) { - foundModel = this.getModelByName(this.config.models, modelName); - if (foundModel) { - foundModel = new Model(modelName, foundModel); - this.addModel(foundModel); - } - } - return foundModel; - }, - getModels: function() { - var defer; - defer = $q.defer(); - application.initialize().then(function(cfg) { - return defer.resolve(cfg.models); - }); - return defer.promise; - }, - getModelByName: function(models, modelName) { - return models.filter(function(e) { - return e.name === modelName; - })[0]; - }, - initialize: function() { - var defer; - defer = $q.defer(); - if (initialized && application.models.length) { - defer.resolve(application); - } else { - if (angular.isString(configOptions.resourcePath)) { - $http.get(configOptions.resourcePath).success(function(data) { - var j, len, model, models; - models = data.models; - application.config = data; - for (j = 0, len = models.length; j < len; j++) { - model = models[j]; - application.addModel(new Model(model.name, model)); + $get: ["Model", "$q", "$http", "$injector", function (Model, $q, $http, $injector) { + var application, buildMenuFromModels; + buildMenuFromModels = function () { + return application.models.map(function (model) { + return { + name: model.label, + state: "list", + params: { + model: model.name + } + }; + }); + }; + application = { + models: [], + urlBase: LoopBackResourceProvider.getUrlBase(), + options: configOptions, + defaultErrorMessage: function (response) { + var body; + body = response.data; + if (typeof body === 'object') { + body = JSON.stringify(body); + } + return 'Oops, an error occured else (code: ' + response.status + ') ' + body; + }, + errorMessage: this.defaultErrorMessage, + getErrorMessage: function (response) { + if (typeof this.errorMessage === 'function') { + return this.errorMessage(response); + } + return this.errorMessage; + }, + userModel: $injector.get(configOptions.userModel), + userLoginField: configOptions.userLoginField, + addModel: function (model) { + var foundModel; + if (!model) { + throw new Error("No model given"); + } + foundModel = this.getModelByName(this.models, model.name); + if (!foundModel) { + this.models.push(model); + } + return this; + }, + getModel: function (modelName) { + var foundModel; + foundModel = this.getModelByName(this.models, modelName); + if (!foundModel) { + foundModel = this.getModelByName(this.config.models, modelName); + if (foundModel) { + foundModel = new Model(modelName, foundModel); + this.addModel(foundModel); + } + } + return foundModel; + }, + getModels: function () { + var defer; + defer = $q.defer(); + application.initialize().then(function (cfg) { + return defer.resolve(cfg.models); + }); + return defer.promise; + }, + getModelByName: function (models, modelName) { + return models.filter(function (e) { + return e.name === modelName; + })[0]; + }, + initialize: function () { + var defer; + defer = $q.defer(); + if (initialized && application.models.length) { + defer.resolve(application); + } else { + if (angular.isString(configOptions.resourcePath)) { + $http.get(configOptions.resourcePath).success(function (data) { + var i, len, model, models; + models = data.models; + application.config = data; + for (i = 0, len = models.length; i < len; i++) { + model = models[i]; + application.addModel(new Model(model.name, model)); + } + application.menu = buildMenuFromModels(); + defer.resolve(application); + return initialized = true; + }).error(function (err) { + return defer.reject(err); + }); + } else { + defer.resolve(application); + } + } + return defer.promise; } - application.menu = buildMenuFromModels(); - defer.resolve(application); - return initialized = true; - }).error(function(err) { - return defer.reject(err); - }); - } else { - defer.resolve(application); + }; + return application; + }] + }; +}]); + +angular.module('loopback-admin').filter('text', ["typedText", "$log", function (typedText, $log) { + var filter; + filter = function (input) { + if (typedText[input]) { + return typedText[input]; + } else { + $log.info('text string missing: ' + input); + return 'MISSING ' + input; + } + }; + filter.$stateful = true; + return filter; +}]).constant('typedText', { + homeTagline: 'Loopback Admin', + homeButtonText: 'Login now', + wrongCredentials: 'Wrong email address or password', + noAccount: 'Don\'t have an account?', + registerHere: 'Register here.', + login: 'Login', + password: 'Password', + email: 'Email', + enterYourTwitterEmail: 'Please enter your twitter email', + userWithEmailExists: 'User with this email already exists.', + enterYourPassword: 'Enter your password', + requestPassword: 'An account with this email address already exists, if you want to connect the two accounts please enter existing accounts password in the field below.', + wrongPassword: 'Password seems to be incorrect, please try again.', + connect: 'Connect', + genericSocialError: 'An error occured, please try again later.', + rememberMe: 'Remember me', + loginWithFacebook: 'Login with facebook', + loginWithTwitter: 'Login with twitter', + loginWithGoogle: 'Login with google', + orLoginWith: ' Or login with:', + submit: 'Submit', + close: 'Close', + alreadyHaveAccount: 'Already have an account?', + repeatPassword: 'Repeat Password', + logInHere: 'Login in here.', + register: 'Register', + itemsSelected: 'Items Selected', + upload: 'Upload', + cancel: 'Cancel', + create: 'Create', + 'new': 'New', + searchResults: 'Search Results', + items: 'Items', + created: 'Created', + description: 'Description', + none: 'None', + yes: 'Yes', + no: 'No', + editUsername: 'Edit Username', + changeAvatar: 'Change Avatar', + logOut: 'Log Out', + accountSettings: 'Account Settings', + confirm: 'Confirm', + dashboard: 'Dashboard', + username: 'Username', + fullName: 'Full Name', + firstName: 'First Name', + lastName: 'Last Name', + currentPassword: 'Current Password', + passwordChangeSuccess: 'Your password was changed successfully.', + avatarAcceptedFormats: 'Accepted formats: png, jpeg.', + avatarResizeExpl: 'Your avatar will be resized to 200x200 (px) if it\'s bigger then that.', + view: 'View', + genericError: 'something went wrong, please try again later.', + favoriteExists: 'You have already marked this photo as favorite.', + passMatches: 'Password is correct.', + passDoesntMatch: 'Incorrect password. Please try again.', + profileUpdateSuccess: 'Your profile was updated successfully.', + avatarRemoveSuccess: 'Removed avatar successfully.', + permaDeletedItems: 'Permanently deleted {{ number }} items.', + deleteItems: 'Delete Items', + sureWantToDeleteItems: 'Are you sure you want to delete these items?', + createdUserSuccessfully: 'Created user successfully.', + updatedUserSuccessfully: 'Updated user successfully.', + settingsUpdated: 'Updated settings successfully.', + logOutSuccess: 'Logged out successfully.', + deleteForever: 'Delete Forever', + confirmPermaDelete: 'Are you sure you want to permanently delete these photo(s)?', + 'delete': 'Delete', + permaDeleteWarning: 'Warning: this action is not undoable.', + remove: 'Remove', + addPassword: 'Add password.', + remove: 'Remove.', + add: 'Add', + done: 'Done', + passwordRecovery: 'Password Recovery', + sendEmail: 'send Email', + change: 'Change', + passResetExpl: 'Please enter the email address associated with your account.', + resetPassword: 'Reset Password', + resetErrors: 'There were some problems with your input.', + emailAddress: 'E-Mail Address', + confirmPassword: 'Confirm Password', + newPassword: 'New Password', + forgot: 'Forgot?', + role: 'Role', + status: 'Status', + expiresIn: 'Expires In', + expiresAt: 'Expiry Date', + acceptedAt: 'Accepted Date', + users: 'Users', + deleted: 'Deleted', + search: 'search', + edit: 'Edit', + avatar: 'Avatar', + id: 'ID', + adminArea: 'Admin Area', + dashboardArea: 'Dashboard Area', + loginTitle: 'Login', + registerTitle: 'Register', + resetPasswordTitle: 'Reset Password' +}); + +'use strict'; +angular.module('loopback-admin').run(["$state", "$window", "$rootScope", "$log", "LoopBackAdminConfiguration", function ($state, $window, $rootScope, $log, LoopBackAdminConfiguration) { + var User; + User = LoopBackAdminConfiguration.userModel; + $rootScope.$on('$stateChangeSuccess', function () { + return $window.scrollTo(0, 0); + }); + $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) { + if (error.status === 404) { + $state.go('error'); + event.preventDefault(); + } else if (error.status === 401) { + $state.go('logout'); + } else { + $log.error('State change error: ' + error.message); + throw error; + } + }); + $rootScope.$on('$stateChangeStart', function ($event, toState, toParams, fromState, fromParams) { + var changeState; + if (!User.isAuthenticated()) { + if (toState.name !== 'login' && toState.name !== 'register' && toState.name !== 'landing') { + $event.preventDefault(); + changeState = $state.go('login'); + changeState.then(function () { + $rootScope.$broadcast('$stateChangeSuccess', toState.self, toParams, fromState.self, fromParams); + }); } - } - return defer.promise; + return true; } - }; - return application; - }] - }; + return true; + }); }]); -angular.module('loopback-admin').filter('text', ["typedText", "$log", function(typedText, $log) { - var filter; - filter = function(input) { - if (typedText[input]) { - return typedText[input]; - } else { - $log.info('text string missing: ' + input); - return 'MISSING ' + input; - } - }; - filter.$stateful = true; - return filter; -}]).constant('typedText', { - homeTagline: 'Loopback Admin', - homeButtonText: 'Login now', - wrongCredentials: 'Wrong email address or password', - noAccount: 'Don\'t have an account?', - registerHere: 'Register here.', - login: 'Login', - password: 'Password', - email: 'Email', - enterYourTwitterEmail: 'Please enter your twitter email', - userWithEmailExists: 'User with this email already exists.', - enterYourPassword: 'Enter your password', - requestPassword: 'An account with this email address already exists, if you want to connect the two accounts please enter existing accounts password in the field below.', - wrongPassword: 'Password seems to be incorrect, please try again.', - connect: 'Connect', - genericSocialError: 'An error occured, please try again later.', - rememberMe: 'Remember me', - loginWithFacebook: 'Login with facebook', - loginWithTwitter: 'Login with twitter', - loginWithGoogle: 'Login with google', - orLoginWith: ' Or login with:', - submit: 'Submit', - close: 'Close', - alreadyHaveAccount: 'Already have an account?', - repeatPassword: 'Repeat Password', - logInHere: 'Login in here.', - register: 'Register', - itemsSelected: 'Items Selected', - upload: 'Upload', - cancel: 'Cancel', - create: 'Create', - 'new': 'New', - searchResults: 'Search Results', - items: 'Items', - created: 'Created', - description: 'Description', - none: 'None', - yes: 'Yes', - no: 'No', - editUsername: 'Edit Username', - changeAvatar: 'Change Avatar', - logOut: 'Log Out', - accountSettings: 'Account Settings', - confirm: 'Confirm', - dashboard: 'Dashboard', - username: 'Username', - fullName: 'Full Name', - firstName: 'First Name', - lastName: 'Last Name', - currentPassword: 'Current Password', - passwordChangeSuccess: 'Your password was changed successfully.', - avatarAcceptedFormats: 'Accepted formats: png, jpeg.', - avatarResizeExpl: 'Your avatar will be resized to 200x200 (px) if it\'s bigger then that.', - view: 'View', - genericError: 'something went wrong, please try again later.', - favoriteExists: 'You have already marked this photo as favorite.', - passMatches: 'Password is correct.', - passDoesntMatch: 'Incorrect password. Please try again.', - profileUpdateSuccess: 'Your profile was updated successfully.', - avatarRemoveSuccess: 'Removed avatar successfully.', - permaDeletedItems: 'Permanently deleted {{ number }} items.', - deleteItems: 'Delete Items', - sureWantToDeleteItems: 'Are you sure you want to delete these items?', - createdUserSuccessfully: 'Created user successfully.', - updatedUserSuccessfully: 'Updated user successfully.', - settingsUpdated: 'Updated settings successfully.', - logOutSuccess: 'Logged out successfully.', - deleteForever: 'Delete Forever', - confirmPermaDelete: 'Are you sure you want to permanently delete these photo(s)?', - 'delete': 'Delete', - permaDeleteWarning: 'Warning: this action is not undoable.', - remove: 'Remove', - addPassword: 'Add password.', - remove: 'Remove.', - add: 'Add', - done: 'Done', - passwordRecovery: 'Password Recovery', - sendEmail: 'send Email', - change: 'Change', - passResetExpl: 'Please enter the email address associated with your account.', - resetPassword: 'Reset Password', - resetErrors: 'There were some problems with your input.', - emailAddress: 'E-Mail Address', - confirmPassword: 'Confirm Password', - newPassword: 'New Password', - forgot: 'Forgot?', - role: 'Role', - status: 'Status', - expiresIn: 'Expires In', - expiresAt: 'Expiry Date', - acceptedAt: 'Accepted Date', - users: 'Users', - deleted: 'Deleted', - search: 'search', - edit: 'Edit', - avatar: 'Avatar', - id: 'ID', - adminArea: 'Admin Area', - dashboardArea: 'Dashboard Area', - loginTitle: 'Login', - registerTitle: 'Register', - resetPasswordTitle: 'Reset Password' -}); - 'use strict'; - -angular.module('loopback-admin').run(["$state", "$window", "$rootScope", "$log", "LoopBackAdminConfiguration", function($state, $window, $rootScope, $log, LoopBackAdminConfiguration) { - var User; - User = LoopBackAdminConfiguration.userModel; - $rootScope.$on('$stateChangeSuccess', function() { - return $window.scrollTo(0, 0); - }); - $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) { - if (error.status === 404) { - $state.go('error'); - event.preventDefault(); - } else if (error.status === 401) { - $state.go('logout'); - } else { - $log.error('State change error: ' + error.message); - throw error; - } - }); - $rootScope.$on('$stateChangeStart', function($event, toState, toParams, fromState, fromParams) { - var changeState; - if (!User.isAuthenticated()) { - if (toState.name !== 'login' && toState.name !== 'register' && toState.name !== 'landing') { - $event.preventDefault(); - changeState = $state.go('login'); - changeState.then(function() { - $rootScope.$broadcast('$stateChangeSuccess', toState.self, toParams, fromState.self, fromParams); +angular.module('loopback-admin').run(["$rootScope", "$mdDialog", "$mdToast", function ($rootScope, $mdDialog, $mdToast) { + $rootScope.closeModal = function () { + return $mdDialog.hide(); + }; + $rootScope.getAvatar = function (user) { + if (user.avatar_url) { + return user.avatar_url; + } + return 'images/avatar.png'; + }; + $rootScope.showToast = function (message, theme) { + var toast; + if (theme == null) { + theme = 'default'; + } + toast = $mdToast.simple({ + position: 'bottom right', + hideDelay: 2200 }); - } - return true; - } - return true; - }); -}]); - -'use strict'; - -angular.module('loopback-admin').run(["$rootScope", "$mdDialog", "$mdToast", function($rootScope, $mdDialog, $mdToast) { - $rootScope.closeModal = function() { - return $mdDialog.hide(); - }; - $rootScope.getAvatar = function(user) { - if (user.avatar_url) { - return user.avatar_url; - } - return 'images/avatar.png'; - }; - $rootScope.showToast = function(message, theme) { - var toast; - if (theme == null) { - theme = 'default'; - } - toast = $mdToast.simple({ - position: 'bottom right', - hideDelay: 2200 - }); - toast.content(message).theme(theme); - $mdToast.show(toast); - }; - $rootScope.confirm = function(options) { - var dialog; - dialog = $mdDialog.confirm().title(options.title).textContent(options.body).ariaLabel('Confirm dialog.').targetEvent(options.event).ok('Okay').cancel('Cancel'); - return $mdDialog.show(dialog); - }; + toast.content(message).theme(theme); + $mdToast.show(toast); + }; + $rootScope.confirm = function (options) { + var dialog; + dialog = $mdDialog.confirm().title(options.title).textContent(options.body).ariaLabel('Confirm dialog.').targetEvent(options.event).ok('Okay').cancel('Cancel'); + return $mdDialog.show(dialog); + }; }]); -angular.module('loopback-admin').provider('$mdColors', ["$mdColorPalette", function($mdColorPalette) { - var DARK_CONTRAST_COLOR, LIGHT_CONTRAST_COLOR, STRONG_LIGHT_CONTRAST_COLOR, addCustomStyle, clearStyleSheet, colorToRgbaArray, index, style, stylesheet; - style = angular.element(''); - document.head.appendChild(style[0]); - stylesheet = style[0].sheet; - index = 0; - colorToRgbaArray = function(clr) { - var blu, dig, grn, red; - if (angular.isArray(clr) && clr.length === 3) { - return clr; - } - if (/^rgb/.test(clr)) { - return clr.replace(/(^\s*rgba?\(|\)\s*$)/g, '').split(',').map(function(value, i) { - if (i === 3) { - return parseFloat(value, 10); - } else { - return parseInt(value, 10); +angular.module('loopback-admin').provider('$mdColors', ["$mdColorPalette", function ($mdColorPalette) { + var DARK_CONTRAST_COLOR, LIGHT_CONTRAST_COLOR, STRONG_LIGHT_CONTRAST_COLOR, addCustomStyle, clearStyleSheet, colorToRgbaArray, index, style, stylesheet; + style = angular.element(''); + document.head.appendChild(style[0]); + stylesheet = style[0].sheet; + index = 0; + colorToRgbaArray = function (clr) { + var blu, dig, grn, red; + if (angular.isArray(clr) && clr.length === 3) { + return clr; } - }); - } - if (clr.charAt(0) === '#') { - clr = clr.substring(1); - } - if (!/^([a-fA-F0-9]{3}){1,2}$/g.test(clr)) { - return; - } - dig = clr.length / 3; - red = clr.substr(0, dig); - grn = clr.substr(dig, dig); - blu = clr.substr(dig * 2); - if (dig === 1) { - red += red; - grn += grn; - blu += blu; - } - return [parseInt(red, 16), parseInt(grn, 16), parseInt(blu, 16)]; - }; - DARK_CONTRAST_COLOR = colorToRgbaArray('rgba(0,0,0,0.87)'); - LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgba(255,255,255,0.87'); - STRONG_LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgb(255,255,255)'); - addCustomStyle = function(cssname, name, color, contrast) { - if (contrast == null) { - contrast = ''; - } - if (contrast) { - contrast = "color: " + contrast; - } - stylesheet.insertRule(".md-" + cssname + "-" + name + ".text { color: " + color + " !important }", index); - stylesheet.insertRule(".md-" + cssname + "-" + name + ".background { background-color: " + color + "; " + contrast + " }", index + 1); - index += 2; - }; - clearStyleSheet = function() { - var results; - results = []; - while (stylesheet.cssRules.length > 0) { - results.push(stylesheet.deleteRule(0)); - } - return results; - }; - return { - colorNames: [], - colorStore: {}, - colorSelected: null, - themeNames: [], - themeStore: {}, - getContrastColor: function(palette) { - var contrastDefaultColor, darkColors, lightColors, strongLightColors; - contrastDefaultColor = palette.contrastDefaultColor, lightColors = palette.lightColors, strongLightColors = palette.strongLightColors, darkColors = palette.darkColors; - if (angular.isString(lightColors)) { - lightColors = lightColors.split(' '); - } - if (angular.isString(strongLightColors)) { - strongLightColors = strongLightColors.split(' '); - } - if (angular.isString(darkColors)) { - darkColors = darkColors.split(' '); - } - if (contrastDefaultColor === 'light') { - if ((darkColors != null ? darkColors.indexOf(hueName) : void 0) > -1) { - return DARK_CONTRAST_COLOR; - } else { - if ((strongLightColors != null ? strongLightColors.indexOf(hueName) : void 0) > -1) { - return STRONG_LIGHT_CONTRAST_COLOR; - } else { - return LIGHT_CONTRAST_COLOR; - } - } - } else { - if ((lightColors != null ? lightColors.indexOf(hueName) : void 0) > -1) { - if ((strongLightColors != null ? strongLightColors.indexOf(hueName) : void 0) > -1) { - return STRONG_LIGHT_CONTRAST_COLOR; - } else { - return LIGHT_CONTRAST_COLOR; - } - } else { - return DARK_CONTRAST_COLOR; + if (/^rgb/.test(clr)) { + return clr.replace(/(^\s*rgba?\(|\)\s*$)/g, '').split(',').map(function (value, i) { + if (i === 3) { + return parseFloat(value, 10); + } else { + return parseInt(value, 10); + } + }); } - } - }, - storeAndLoadPalettes: function(colors, themes, primaryPalette) { - this.colorStore = colors; - this.themeStore = themes; - this.colorNames = Object.keys(colors); - this.themeNames = Object.keys(themes); - return this.loadPalette(primaryPalette); - }, - loadPalette: function(newPalette) { - var cleanedThemeName, color, group, groupName, name, ref, theme, themeName; - if (this.colorSelected) { - clearStyleSheet(); - } - this.colorSelected = newPalette; - ref = this.themeStore; - for (themeName in ref) { - theme = ref[themeName]; - cleanedThemeName = themeName === 'default' ? '' : themeName + '-'; - for (groupName in theme) { - group = theme[groupName]; - for (name in group) { - color = group[name]; - addCustomStyle(cleanedThemeName + groupName, name, color.value, color.contrast); - } - } - } - }, - $get: function() { - return { - colorNames: this.colorNames, - colorStore: this.colorStore, - colorSelected: this.colorSelected, - themeNames: this.themeNames, - themeStore: this.themeStore, - loadPalette: this.loadPalette - }; - } - }; -}]).config(["$mdThemingProvider", "$mdColorsProvider", function($mdThemingProvider, $mdColorsProvider) { - var colorStore, palette, paletteName, parsePalette, parseTheme, primaryPalette, ref, themeStore; - colorStore = {}; - parsePalette = function(paletteName, palette) { - var addHue, colors, copyColors, hueColors, paletteContrast; - paletteContrast = $mdThemingProvider._rgba($mdColorsProvider.getContrastColor(palette)); - hueColors = $mdThemingProvider._THEMES['default'].colors['primary'].hues; - colors = {}; - addHue = function(hueName) { - return colors[hueName] = { - value: palette[hueColors[hueName]], - contrast: paletteContrast - }; - }; - copyColors = function(colorName, color) { - if (/#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\b/.test(palette[colorName])) { - colors[colorName] = { - value: palette[colorName], - contrast: paletteContrast + if (clr.charAt(0) === '#') { + clr = clr.substring(1); + } + if (!/^([a-fA-F0-9]{3}){1,2}$/g.test(clr)) { + return; + } + dig = clr.length / 3; + red = clr.substr(0, dig); + grn = clr.substr(dig, dig); + blu = clr.substr(dig * 2); + if (dig === 1) { + red += red; + grn += grn; + blu += blu; + } + return [parseInt(red, 16), parseInt(grn, 16), parseInt(blu, 16)]; + }; + DARK_CONTRAST_COLOR = colorToRgbaArray('rgba(0,0,0,0.87)'); + LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgba(255,255,255,0.87'); + STRONG_LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgb(255,255,255)'); + addCustomStyle = function (cssname, name, color, contrast) { + if (contrast == null) { + contrast = ''; + } + if (contrast) { + contrast = "color: " + contrast; + } + stylesheet.insertRule(".md-" + cssname + "-" + name + ".text { color: " + color + " !important }", index); + stylesheet.insertRule(".md-" + cssname + "-" + name + ".background { background-color: " + color + "; " + contrast + " }", index + 1); + index += 2; + }; + clearStyleSheet = function () { + var results; + results = []; + while (stylesheet.cssRules.length > 0) { + results.push(stylesheet.deleteRule(0)); + } + return results; + }; + return { + colorNames: [], + colorStore: {}, + colorSelected: null, + themeNames: [], + themeStore: {}, + getContrastColor: function (palette) { + var contrastDefaultColor, darkColors, lightColors, strongLightColors; + contrastDefaultColor = palette.contrastDefaultColor, lightColors = palette.lightColors, strongLightColors = palette.strongLightColors, darkColors = palette.darkColors; + if (angular.isString(lightColors)) { + lightColors = lightColors.split(' '); + } + if (angular.isString(strongLightColors)) { + strongLightColors = strongLightColors.split(' '); + } + if (angular.isString(darkColors)) { + darkColors = darkColors.split(' '); + } + if (contrastDefaultColor === 'light') { + if ((darkColors != null ? darkColors.indexOf(hueName) : void 0) > -1) { + return DARK_CONTRAST_COLOR; + } else { + if ((strongLightColors != null ? strongLightColors.indexOf(hueName) : void 0) > -1) { + return STRONG_LIGHT_CONTRAST_COLOR; + } else { + return LIGHT_CONTRAST_COLOR; + } + } + } else { + if ((lightColors != null ? lightColors.indexOf(hueName) : void 0) > -1) { + if ((strongLightColors != null ? strongLightColors.indexOf(hueName) : void 0) > -1) { + return STRONG_LIGHT_CONTRAST_COLOR; + } else { + return LIGHT_CONTRAST_COLOR; + } + } else { + return DARK_CONTRAST_COLOR; + } + } + }, + storeAndLoadPalettes: function (colors, themes, primaryPalette) { + this.colorStore = colors; + this.themeStore = themes; + this.colorNames = Object.keys(colors); + this.themeNames = Object.keys(themes); + return this.loadPalette(primaryPalette); + }, + loadPalette: function (newPalette) { + var cleanedThemeName, color, group, groupName, name, ref, theme, themeName; + if (this.colorSelected) { + clearStyleSheet(); + } + this.colorSelected = newPalette; + ref = this.themeStore; + for (themeName in ref) { + theme = ref[themeName]; + cleanedThemeName = themeName === 'default' ? '' : themeName + '-'; + for (groupName in theme) { + group = theme[groupName]; + for (name in group) { + color = group[name]; + addCustomStyle(cleanedThemeName + groupName, name, color.value, color.contrast); + } + } + } + }, + $get: function () { + return { + colorNames: this.colorNames, + colorStore: this.colorStore, + colorSelected: this.colorSelected, + themeNames: this.themeNames, + themeStore: this.themeStore, + loadPalette: this.loadPalette + }; + } + }; +}]).config(["$mdThemingProvider", "$mdColorsProvider", function ($mdThemingProvider, $mdColorsProvider) { + var colorStore, palette, paletteName, parsePalette, parseTheme, primaryPalette, ref, themeStore; + colorStore = {}; + parsePalette = function (paletteName, palette) { + var addHue, colors, copyColors, hueColors, paletteContrast; + paletteContrast = $mdThemingProvider._rgba($mdColorsProvider.getContrastColor(palette)); + hueColors = $mdThemingProvider._THEMES['default'].colors['primary'].hues; + colors = {}; + addHue = function (hueName) { + return colors[hueName] = { + value: palette[hueColors[hueName]], + contrast: paletteContrast + }; }; - } - }; - colorStore[paletteName] = colors; - Object.keys(palette).forEach(copyColors); - Object.keys(hueColors).forEach(addHue); - }; - ref = $mdThemingProvider._PALETTES; - for (paletteName in ref) { - palette = ref[paletteName]; - parsePalette(paletteName, palette); - } - themeStore = {}; - parseTheme = function(themeName) { - var colors, defineColors, themeColorGroups; - themeColorGroups = $mdThemingProvider._THEMES[themeName].colors; - colors = {}; - defineColors = function(themeGroup) { - var base, definedColors, item, ref1, value; - if ((base = themeStore[themeName])[themeGroup] == null) { - base[themeGroup] = {}; - } - definedColors = colorStore[themeColorGroups[themeGroup].name]; - ref1 = themeColorGroups[themeGroup].hues; - for (item in ref1) { - value = ref1[item]; - themeStore[themeName][themeGroup][item] = definedColors[value]; - } - }; - if (themeStore[themeName] == null) { - themeStore[themeName] = {}; + copyColors = function (colorName, color) { + if (/#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\b/.test(palette[colorName])) { + colors[colorName] = { + value: palette[colorName], + contrast: paletteContrast + }; + } + }; + colorStore[paletteName] = colors; + Object.keys(palette).forEach(copyColors); + Object.keys(hueColors).forEach(addHue); + }; + ref = $mdThemingProvider._PALETTES; + for (paletteName in ref) { + palette = ref[paletteName]; + parsePalette(paletteName, palette); } - Object.keys(themeColorGroups).forEach(defineColors); - }; - Object.keys($mdThemingProvider._THEMES).forEach(parseTheme); - primaryPalette = $mdThemingProvider._THEMES['default'].colors.primary.name; - $mdColorsProvider.storeAndLoadPalettes(colorStore, themeStore, primaryPalette); + themeStore = {}; + parseTheme = function (themeName) { + var colors, defineColors, themeColorGroups; + themeColorGroups = $mdThemingProvider._THEMES[themeName].colors; + colors = {}; + defineColors = function (themeGroup) { + var base, definedColors, item, ref1, value; + if ((base = themeStore[themeName])[themeGroup] == null) { + base[themeGroup] = {}; + } + definedColors = colorStore[themeColorGroups[themeGroup].name]; + ref1 = themeColorGroups[themeGroup].hues; + for (item in ref1) { + value = ref1[item]; + themeStore[themeName][themeGroup][item] = definedColors[value]; + } + }; + if (themeStore[themeName] == null) { + themeStore[themeName] = {}; + } + Object.keys(themeColorGroups).forEach(defineColors); + }; + Object.keys($mdThemingProvider._THEMES).forEach(parseTheme); + primaryPalette = $mdThemingProvider._THEMES['default'].colors.primary.name; + $mdColorsProvider.storeAndLoadPalettes(colorStore, themeStore, primaryPalette); }]); 'use strict'; - -angular.module('loopback-admin').factory('Flickr', ["$q", "$http", "LoopBackAdminConfiguration", function($q, $http, LoopBackAdminConfiguration) { - var baseUrl, flickrApiKey, params; - flickrApiKey = LoopBackAdminConfiguration.options.flickrApiKey; - baseUrl = 'https://api.flickr.com/services/rest/?'; - params = ['method=flickr.groups.pools.getPhotos', 'group_id=1463451@N25', 'safe_search=1', 'jsoncallback=JSON_CALLBACK', "api_key=" + flickrApiKey, 'format=json'].join('&'); - return { - getBackgroundImage: function() { - var defer; - defer = $q.defer(); - if (flickrApiKey) { - $http.get('http://freegeoip.net/json/').success(function(data) { - var latitude, longitude, optParams, region_name; - longitude = data.longitude, latitude = data.latitude, region_name = data.region_name; - optParams = "&tags=" + region_name + "&lat=" + latitude + "&lng=" + longitude + "&extras=url_l"; - return $http.jsonp(baseUrl + params + optParams, { - cache: true - }).success(function(resp) { - var image, images, photos; - photos = resp.photos; - if (photos.photo.length) { - images = photos.photo; - image = images[Math.floor(Math.random() * images.length)]; - return defer.resolve({ - image: 'url(' + image.url_l + ')', - title: image.title - }); +angular.module('loopback-admin').factory('Flickr', ["$q", "$http", "LoopBackAdminConfiguration", function ($q, $http, LoopBackAdminConfiguration) { + var baseUrl, flickrApiKey, params; + flickrApiKey = LoopBackAdminConfiguration.options.flickrApiKey; + baseUrl = 'https://api.flickr.com/services/rest/?'; + params = ['method=flickr.groups.pools.getPhotos', 'group_id=1463451@N25', 'safe_search=1', 'jsoncallback=JSON_CALLBACK', "api_key=" + flickrApiKey, 'format=json'].join('&'); + return { + getBackgroundImage: function () { + var defer; + defer = $q.defer(); + if (flickrApiKey) { + $http.get('http://freegeoip.net/json/').success(function (data) { + var latitude, longitude, optParams, region_name; + longitude = data.longitude, latitude = data.latitude, region_name = data.region_name; + optParams = "&tags=" + region_name + "&lat=" + latitude + "&lng=" + longitude + "&extras=url_l"; + return $http.jsonp(baseUrl + params + optParams, { + cache: true + }).success(function (resp) { + var image, images, photos; + photos = resp.photos; + if (photos.photo.length) { + images = photos.photo; + image = images[Math.floor(Math.random() * images.length)]; + return defer.resolve({ + image: 'url(' + image.url_l + ')', + title: image.title + }); + } else { + return defer.resolve(); + } + }); + }); } else { - return defer.resolve(); + defer.resolve({ + image: "url('./images/background.png')" + }); } - }); - }); - } else { - defer.resolve({ - image: "url('./images/background.png')" - }); - } - return defer.promise; - } - }; + return defer.promise; + } + }; }]); 'use strict'; - -angular.module('loopback-admin').factory('Model', ["$injector", "stringUtils", "$log", "Property", "PropertyTypeConfiguration", "LoopbackInjector", function($injector, stringUtils, $log, Property, PropertyTypeConfiguration, LoopbackInjector) { - var Model; - return Model = (function() { - function Model(name, model) { - var key, value; - this.name = name; - this.label = stringUtils.camelCase(this.name); - this.properties = []; - this.propertyNames = []; - this.relationNames = []; - this.resource = LoopbackInjector(name); - for (key in model) { - value = model[key]; - if (key !== 'properties' && key !== 'relations') { - this[key] = value; - } - } - this.constructProperties(model.properties); - this.constructRelations(model.relations); - } - - Model.prototype.constructRelations = function(modelRelations) { - var _propertyTypes; - _propertyTypes = PropertyTypeConfiguration; - if (modelRelations) { - Object.keys(modelRelations).forEach((function(_this) { - return function(relationName) { - var propertyConstructor, relation; - relation = modelRelations[relationName]; - if (relation != null ? relation.foreignKey : void 0) { - _this.relationNames.push(relationName); +angular.module('loopback-admin').factory('Model', ["$injector", "stringUtils", "$log", "Property", "PropertyTypeConfiguration", "LoopbackInjector", function ($injector, stringUtils, $log, Property, PropertyTypeConfiguration, LoopbackInjector) { + var Model; + return Model = (function () { + function Model(name, model) { + var key, value; + this.name = name; + this.label = stringUtils.camelCase(this.name); + this.properties = []; + this.propertyNames = []; + this.relationNames = []; + this.resource = LoopbackInjector(name); + for (key in model) { + value = model[key]; + if (key !== 'properties' && key !== 'relations') { + this[key] = value; + } } - if (_propertyTypes[relation.type]) { - propertyConstructor = $injector.get(_propertyTypes[relation.type]); - return _this.properties.push(new propertyConstructor(relationName, relation)); - } else { - return $log.warn('no such type defined for', relation.type, relation); + this.constructProperties(model.properties); + this.constructRelations(model.relations); + } + + Model.prototype.constructRelations = function (modelRelations) { + var _propertyTypes; + _propertyTypes = PropertyTypeConfiguration; + if (modelRelations) { + Object.keys(modelRelations).forEach((function (_this) { + return function (relationName) { + var propertyConstructor, relation; + relation = modelRelations[relationName]; + if (relation != null ? relation.foreignKey : void 0) { + _this.relationNames.push(relationName); + } + if (_propertyTypes[relation.type]) { + propertyConstructor = $injector.get(_propertyTypes[relation.type]); + return _this.properties.push(new propertyConstructor(relationName, relation)); + } else { + return $log.warn('no such type defined for', relation.type, relation); + } + }; + })(this)); } - }; - })(this)); - } - }; - - Model.prototype.constructProperties = function(modelProperties) { - var _propertyTypes; - _propertyTypes = PropertyTypeConfiguration; - if (modelProperties) { - Object.keys(modelProperties).forEach((function(_this) { - return function(propertyName) { - var property, propertyConstructor; - property = modelProperties[propertyName]; - if (Object.keys(property).length) { - if (property.id) { - _this.identifier = new Property(propertyName); - } - if (_propertyTypes[property.type.toLowerCase()]) { - _this.propertyNames.push(propertyName); - propertyConstructor = $injector.get(_propertyTypes[property.type.toLowerCase()]); - return _this.properties.push(new propertyConstructor(propertyName, property)); - } else { - return $log.warn('no such type defined for', property.type, property); - } + }; + + Model.prototype.constructProperties = function (modelProperties) { + var _propertyTypes; + _propertyTypes = PropertyTypeConfiguration; + if (modelProperties) { + Object.keys(modelProperties).forEach((function (_this) { + return function (propertyName) { + var property, propertyConstructor; + property = modelProperties[propertyName]; + if (Object.keys(property).length) { + if (property.id) { + _this.identifier = new Property(propertyName); + } + if (_propertyTypes[property.type.toLowerCase()]) { + _this.propertyNames.push(propertyName); + propertyConstructor = $injector.get(_propertyTypes[property.type.toLowerCase()]); + return _this.properties.push(new propertyConstructor(propertyName, property)); + } else { + return $log.warn('no such type defined for', property.type, property); + } + } + }; + })(this)); } - }; - })(this)); - } - }; + }; - return Model; + return Model; - })(); + })(); }]); 'use strict'; - -angular.module('loopback-admin').provider('PropertyTypeConfiguration', ["$injector", function($injector) { - var propertyTypes; - propertyTypes = {}; - return { - registerPropertyType: function(type, PropertyType) { - if (type === 'string' || type === 'objectid') { - PropertyType = ''; - } - return propertyTypes[type] = PropertyType + 'Property'; - }, - $get: function() { - return propertyTypes; - } - }; -}]).provider('PropertyViewConfiguration', ["PropertyTypeConfigurationProvider", "stringUtilsProvider", function(PropertyTypeConfigurationProvider, stringUtilsProvider) { - var camelCase, propertyViews, registerPropertyType; - camelCase = stringUtilsProvider.camelCase; - registerPropertyType = PropertyTypeConfigurationProvider.registerPropertyType; - propertyViews = {}; - return { - registerAlias: function(alias, type) { - if (propertyViews[type]) { - propertyViews[alias] = propertyViews[type]; - return registerPropertyType(alias, camelCase(type)); - } else { - return console.warn('no such type defined for', type, alias); - } - }, - registerPropertyView: function(type, PropertyView) { - propertyViews[type] = PropertyView; - registerPropertyType(type, camelCase(type)); - }, - $get: function() { - return propertyViews; - } - }; -}]).run(["$templateCache", "PropertyViewConfiguration", function($templateCache, PropertyViewConfiguration) { - return Object.keys(PropertyViewConfiguration).forEach(function(propertyName) { - var propery; - propery = PropertyViewConfiguration[propertyName]; - $templateCache.put(propertyName + '-column', propery.column); - return $templateCache.put(propertyName + '-field', propery.field); - }); +angular.module('loopback-admin').provider('PropertyTypeConfiguration', ["$injector", function ($injector) { + var propertyTypes; + propertyTypes = {}; + return { + registerPropertyType: function (type, PropertyType) { + if (type === 'string' || type === 'objectid') { + PropertyType = ''; + } + return propertyTypes[type] = PropertyType + 'Property'; + }, + $get: function () { + return propertyTypes; + } + }; +}]).provider('PropertyViewConfiguration', ["PropertyTypeConfigurationProvider", "stringUtilsProvider", function (PropertyTypeConfigurationProvider, stringUtilsProvider) { + var camelCase, propertyViews, registerPropertyType; + camelCase = stringUtilsProvider.camelCase; + registerPropertyType = PropertyTypeConfigurationProvider.registerPropertyType; + propertyViews = {}; + return { + registerAlias: function (alias, type) { + if (propertyViews[type]) { + propertyViews[alias] = propertyViews[type]; + return registerPropertyType(alias, camelCase(type)); + } else { + return console.warn('no such type defined for', type, alias); + } + }, + registerPropertyView: function (type, PropertyView) { + propertyViews[type] = PropertyView; + registerPropertyType(type, camelCase(type)); + }, + $get: function () { + return propertyViews; + } + }; +}]).run(["$templateCache", "PropertyViewConfiguration", function ($templateCache, PropertyViewConfiguration) { + return Object.keys(PropertyViewConfiguration).forEach(function (propertyName) { + var propery; + propery = PropertyViewConfiguration[propertyName]; + $templateCache.put(propertyName + '-column', propery.column); + return $templateCache.put(propertyName + '-field', propery.field); + }); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbProperty', function() { - return { - restrict: 'E', - scope: { - property: '=', - row: '=', - model: '=', - errorMessages: '=', - form: '=' - }, - template: "
" - }; +angular.module('loopback-admin').directive('lbProperty', function () { + return { + restrict: 'E', + scope: { + property: '=', + row: '=', + model: '=', + errorMessages: '=', + form: '=' + }, + template: "
" + }; }); 'use strict'; +var hasProp = {}.hasOwnProperty; -angular.module('loopback-admin').factory('Property', ["stringUtils", function(stringUtils) { - var Property; - return Property = (function() { - function Property(name, property) { - var key, value; - if (property == null) { - property = {}; - } - this["default"] = null; - this.name = name || Math.random().toString(36).substring(7); - this.label = stringUtils.camelCase(this.name); - this.type = "string"; - this.validation = { - required: false, - minlength: 0, - maxlength: 99999 - }; - for (key in property) { - if (!hasProp.call(property, key)) continue; - value = property[key]; - this[key] = value; - } - this.type = this.type.toLowerCase(); - } +angular.module('loopback-admin').factory('Property', ["stringUtils", function (stringUtils) { + var Property; + return Property = (function () { + function Property(name, property) { + var key, value; + if (property == null) { + property = {}; + } + this["default"] = null; + this.name = name || Math.random().toString(36).substring(7); + this.label = stringUtils.camelCase(this.name); + this.type = "string"; + this.validation = { + required: false, + minlength: 0, + maxlength: 99999 + }; + for (key in property) { + if (!hasProp.call(property, key)) continue; + value = property[key]; + this[key] = value; + } + this.type = this.type.toLowerCase(); + } - return Property; + return Property; - })(); + })(); }]); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('belongsTo', { - column: null, - field: '' - }); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('belongsTo', { + column: null, + field: '' + }); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbBelongsToProperty', function() { - return { - scope: { - property: '=', - value: '=', - form: '=', - errorMessages: '=' - }, - templateUrl: 'templates/property/belongs-to.tpl.html', - restrict: 'E', - link: function(scope, element) { - var j, len, property, ref, resource, value; - property = scope.property; - scope.model = property.getModel(); - resource = scope.model.resource; - scope.count = 0; - scope.rows = []; - ref = scope.value; - for (j = 0, len = ref.length; j < len; j++) { - value = ref[j]; - scope.rows.push(new resource(value)); - scope.count++; - } - scope.name = property.name; - scope.v = property.validation; - } - }; +angular.module('loopback-admin').directive('lbBelongsToProperty', function () { + return { + scope: { + property: '=', + value: '=', + form: '=', + errorMessages: '=' + }, + templateUrl: 'templates/property/belongs-to.tpl.html', + restrict: 'E', + link: function (scope, element) { + var i, len, property, ref, resource, value; + property = scope.property; + scope.model = property.getModel(); + resource = scope.model.resource; + scope.count = 0; + scope.rows = []; + ref = scope.value; + for (i = 0, len = ref.length; i < len; i++) { + value = ref[i]; + scope.rows.push(new resource(value)); + scope.count++; + } + scope.name = property.name; + scope.v = property.validation; + } + }; }); 'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; -angular.module('loopback-admin').factory('BelongsToProperty', ["Property", "LoopBackAdminConfiguration", function(Property, LoopBackAdminConfiguration) { - var BelongsToProperty; - return BelongsToProperty = (function(superClass) { - extend(BelongsToProperty, superClass); +angular.module('loopback-admin').factory('BelongsToProperty', ["Property", "LoopBackAdminConfiguration", function (Property, LoopBackAdminConfiguration) { + var BelongsToProperty; + return BelongsToProperty = (function (superClass) { + extend(BelongsToProperty, superClass); - function BelongsToProperty(name, property) { - BelongsToProperty.__super__.constructor.call(this, name, property); - this.type = "belongsTo"; - } + function BelongsToProperty(name, property) { + BelongsToProperty.__super__.constructor.call(this, name, property); + this.type = "belongsTo"; + } - BelongsToProperty.prototype.getModel = function() { - return LoopBackAdminConfiguration.getModel(this.model); - }; + BelongsToProperty.prototype.getModel = function () { + return LoopBackAdminConfiguration.getModel(this.model); + }; - return BelongsToProperty; + return BelongsToProperty; - })(Property); + })(Property); }]); 'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('boolean', { - column: '', - field: '' - }); + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('boolean', { + column: '', + field: '' + }); }]); 'use strict'; -angular.module('loopback-admin').factory('BooleanProperty', ["ChoiceProperty", function(ChoiceProperty) { - var BooleanProperty; - return BooleanProperty = (function(superClass) { - extend(BooleanProperty, superClass); - - function BooleanProperty(name, property) { - BooleanProperty.__super__.constructor.call(this, name, property); - this.type = "boolean"; - this.choices = [ - { - value: null, - label: 'undefined' - }, { - value: true, - label: 'true' - }, { - value: false, - label: 'false' +angular.module('loopback-admin').factory('BooleanProperty', ["ChoiceProperty", function (ChoiceProperty) { + var BooleanProperty; + return BooleanProperty = (function (superClass) { + extend(BooleanProperty, superClass); + + function BooleanProperty(name, property) { + BooleanProperty.__super__.constructor.call(this, name, property); + this.type = "boolean"; + this.choices = [ + { + value: null, + label: 'undefined' + }, { + value: true, + label: 'true' + }, { + value: false, + label: 'false' + } + ]; } - ]; - } - return BooleanProperty; + return BooleanProperty; - })(ChoiceProperty); + })(ChoiceProperty); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbCheckboxProperty', function() { - return { - scope: { - property: '=', - value: '=' - }, - restrict: 'E', - templateUrl: 'templates/property/checkbox.tpl.html', - link: function(scope, element) { - var property; - property = scope.property; - scope.name = property.name; - scope.v = property.validation; - scope.value = !!scope.value; - } - }; +angular.module('loopback-admin').directive('lbCheckboxProperty', function () { + return { + scope: { + property: '=', + value: '=' + }, + restrict: 'E', + templateUrl: 'templates/property/checkbox.tpl.html', + link: function (scope, element) { + var property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + scope.value = !!scope.value; + } + }; }); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('choice', { - column: '', - field: '' - }); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('choice', { + column: '', + field: '' + }); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbChoiceProperty', function() { - return { - scope: { - property: '=', - value: '=', - row: '=?' - }, - restrict: 'E', - templateUrl: 'templates/property/choice.tpl.html', - compile: function() { - return { - pre: function(scope, element) { - var choices, property; - property = scope.property; - scope.name = property.name; - scope.v = property.validation; - scope.$watch('value', function(newValue, oldValue) { - if (newValue !== oldValue && newValue === void 0) { - scope.value = null; - } - }); - choices = property.choices ? property.choices : []; - scope.choices = typeof choices === 'function' ? choices(scope.row) : choices; +angular.module('loopback-admin').directive('lbChoiceProperty', function () { + return { + scope: { + property: '=', + value: '=', + row: '=?' }, - post: function(scope) { - var listener, updateChoices; - updateChoices = function(choices) { - scope.choices = choices; - return scope.$root.$$phase || scope.$digest(); - }; - listener = scope.$on('choices:update', function(e, data) { - return updateChoices(data.choices); - }); - scope.$on('$destroy', function() { - return listener(); - }); - } - }; - } - }; + restrict: 'E', + templateUrl: 'templates/property/choice.tpl.html', + compile: function () { + return { + pre: function (scope, element) { + var choices, property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + scope.$watch('value', function (newValue, oldValue) { + if (newValue !== oldValue && newValue === void 0) { + scope.value = null; + } + }); + choices = property.choices ? property.choices : []; + scope.choices = typeof choices === 'function' ? choices(scope.row) : choices; + }, + post: function (scope) { + var listener, updateChoices; + updateChoices = function (choices) { + scope.choices = choices; + return scope.$root.$$phase || scope.$digest(); + }; + listener = scope.$on('choices:update', function (e, data) { + return updateChoices(data.choices); + }); + scope.$on('$destroy', function () { + return listener(); + }); + } + }; + } + }; }); 'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } -angular.module('loopback-admin').factory('ChoiceProperty', ["Property", function(Property) { - var ChoiceProperty; - return ChoiceProperty = (function(superClass) { - extend(ChoiceProperty, superClass); + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; - function ChoiceProperty(name, property) { - ChoiceProperty.__super__.constructor.call(this, name, property); - this.type = "choice"; - this.choices = []; - return; - } +angular.module('loopback-admin').factory('ChoiceProperty', ["Property", function (Property) { + var ChoiceProperty; + return ChoiceProperty = (function (superClass) { + extend(ChoiceProperty, superClass); - ChoiceProperty.prototype.getLabelForChoice = function(value, row) { - var choice, choices; - choices = typeof this.choices === 'function' ? this.choices(row) : this.choices; - choice = choices.filter(function(c) { - return c.value === value; - }).pop(); - if (choice) { - return choice.label; - } else { - return null; - } - }; + function ChoiceProperty(name, property) { + ChoiceProperty.__super__.constructor.call(this, name, property); + this.type = "choice"; + this.choices = []; + return; + } + + ChoiceProperty.prototype.getLabelForChoice = function (value, row) { + var choice, choices; + choices = typeof this.choices === 'function' ? this.choices(row) : this.choices; + choice = choices.filter(function (c) { + return c.value === value; + }).pop(); + if (choice) { + return choice.label; + } else { + return null; + } + }; - return ChoiceProperty; + return ChoiceProperty; - })(Property); + })(Property); }]); 'use strict'; - -angular.module('loopback-admin').directive('uiSelectRequired', function() { - return { - restrict: 'A', - require: 'ngModel', - link: function(scope, elm, attrs, ctrl) { - ctrl.$validators.uiSelectRequired = function(modelValue, viewValue) { - var determineVal; - if (angular.isArray(modelValue)) { - determineVal = modelValue; - } else if (angular.isArray(viewValue)) { - determineVal = viewValue; - } else { - return false; +angular.module('loopback-admin').directive('uiSelectRequired', function () { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, elm, attrs, ctrl) { + ctrl.$validators.uiSelectRequired = function (modelValue, viewValue) { + var determineVal; + if (angular.isArray(modelValue)) { + determineVal = modelValue; + } else if (angular.isArray(viewValue)) { + determineVal = viewValue; + } else { + return false; + } + return determineVal.length > 0; + }; } - return determineVal.length > 0; - }; - } - }; + }; }); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - fvp.registerPropertyView('choices', { - column: '', - field: '' - }); - return fvp.registerAlias('array', 'choices'); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + fvp.registerPropertyView('choices', { + column: '', + field: '' + }); + return fvp.registerAlias('array', 'choices'); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbChoicesProperty', ["$compile", "$templateCache", function($compile, $templateCache) { - return { - scope: { - property: '=', - value: '=', - row: '=?' - }, - restrict: 'E', - templateUrl: 'templates/property/choices.tpl.html', - compile: function() { - return { - pre: function(scope, element) { - var choices, property; - property = scope.property; - scope.name = property.name; - scope.v = property.validation; - choices = property.choices ? property.choices : []; - return scope.choices = typeof choices === 'function' ? choices(scope.row) : choices; +angular.module('loopback-admin').directive('lbChoicesProperty', ["$compile", "$templateCache", function ($compile, $templateCache) { + return { + scope: { + property: '=', + value: '=', + row: '=?' }, - post: function(scope) { - var listener; - listener = scope.$on('choices:update', function(e, data) { - scope.scope.choices = data.choices; - return scope.$root.$$phase || scope.$digest(); - }); - scope.$on('$destroy', function() { - return listener(); - }); - } - }; - } - }; + restrict: 'E', + templateUrl: 'templates/property/choices.tpl.html', + compile: function () { + return { + pre: function (scope, element) { + var choices, property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + choices = property.choices ? property.choices : []; + return scope.choices = typeof choices === 'function' ? choices(scope.row) : choices; + }, + post: function (scope) { + var listener; + listener = scope.$on('choices:update', function (e, data) { + scope.scope.choices = data.choices; + return scope.$root.$$phase || scope.$digest(); + }); + scope.$on('$destroy', function () { + return listener(); + }); + } + }; + } + }; }]); 'use strict'; +var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; angular.module('loopback-admin').factory('ChoicesProperty', ["ChoiceProperty", function(ChoiceProperty) { var ChoicesProperty; @@ -1377,739 +1400,782 @@ angular.module('loopback-admin').factory('ChoicesProperty', ["ChoiceProperty", f })(ChoiceProperty); }]); - 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('date', { - column: '', - field: '' - }); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('date', { + column: '', + field: '' + }); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbDateProperty', function() { - return { - scope: { - property: '=', - value: '=' - }, - restrict: 'E', - templateUrl: 'templates/property/date.tpl.html', - link: function(scope, element) { - var property; - property = scope.property; - scope.name = property.name; - scope.rawValue = scope.value; - scope.$watch('rawValue', function(rawValue) { - scope.value = property.parse(rawValue); - }); - scope.v = property.validation; - } - }; +angular.module('loopback-admin').directive('lbDateProperty', function () { + return { + scope: { + property: '=', + value: '=' + }, + restrict: 'E', + templateUrl: 'templates/property/date.tpl.html', + link: function (scope, element) { + var property; + property = scope.property; + scope.name = property.name; + scope.rawValue = scope.value; + scope.$watch('rawValue', function (rawValue) { + scope.value = property.parse(rawValue); + }); + scope.v = property.validation; + } + }; }); 'use strict'; - -angular.module('loopback-admin').factory('DateProperty', ["Property", function(Property) { - var DateProperty; - return DateProperty = (function(superClass) { - extend(DateProperty, superClass); - - function DateProperty(name, property) { - DateProperty.__super__.constructor.call(this, name, property); - this.format = null; - this.parse = function(date) { - if (date == null) { - date = null; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; } - if (date instanceof Date) { - return date; - } else if (angular.isString(date)) { - return new Date(date); - } else { - return null; + function ctor() { + this.constructor = child; } - }; - this.type = "date"; - return; - } - return DateProperty; - - })(Property); -}]).factory('DateTimeProperty', ["DateProperty", function(DateProperty) { - var DateTimeProperty; - return DateTimeProperty = (function(superClass) { - extend(DateTimeProperty, superClass); - - function DateTimeProperty(name, property) { - DateTimeProperty.__super__.constructor.call(this, name, property); - this.format = null; - this.parse = function(date) { - return date; - }; - this.type = 'datetime'; - } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('DateProperty', ["Property", function (Property) { + var DateProperty; + return DateProperty = (function (superClass) { + extend(DateProperty, superClass); + + function DateProperty(name, property) { + DateProperty.__super__.constructor.call(this, name, property); + this.format = null; + this.parse = function (date) { + if (date == null) { + date = null; + } + if (date instanceof Date) { + return date; + } else if (angular.isString(date)) { + return new Date(date); + } else { + return null; + } + }; + this.type = "date"; + return; + } + + return DateProperty; + + })(Property); +}]).factory('DateTimeProperty', ["DateProperty", function (DateProperty) { + var DateTimeProperty; + return DateTimeProperty = (function (superClass) { + extend(DateTimeProperty, superClass); + + function DateTimeProperty(name, property) { + DateTimeProperty.__super__.constructor.call(this, name, property); + this.format = null; + this.parse = function (date) { + return date; + }; + this.type = 'datetime'; + } - return DateTimeProperty; + return DateTimeProperty; - })(DateProperty); + })(DateProperty); }]); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('float', { - column: '', - field: '' - }); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('float', { + column: '', + field: '' + }); }]); 'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } -angular.module('loopback-admin').factory('FloatProperty', ["NumberProperty", function(NumberProperty) { - var FloatProperty; - return FloatProperty = (function(superClass) { - extend(FloatProperty, superClass); + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; - function FloatProperty(name, property) { - FloatProperty.__super__.constructor.call(this, name, property); - this.type = 'float'; - this.format = '0.000'; - } +angular.module('loopback-admin').factory('FloatProperty', ["NumberProperty", function (NumberProperty) { + var FloatProperty; + return FloatProperty = (function (superClass) { + extend(FloatProperty, superClass); - return FloatProperty; + function FloatProperty(name, property) { + FloatProperty.__super__.constructor.call(this, name, property); + this.type = 'float'; + this.format = '0.000'; + } + + return FloatProperty; - })(NumberProperty); + })(NumberProperty); }]); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('hasMany', { - column: '', - field: '' - }); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('hasMany', { + column: '', + field: '' + }); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbHasManyProperty', function() { - return { - scope: { - property: '=', - value: '=', - form: '=', - errorMessages: '=' - }, - templateUrl: 'templates/property/has-many.tpl.html', - restrict: 'E', - link: function(scope, element) { - var j, len, property, ref, resource, value; - property = scope.property; - scope.model = property.getModel(); - resource = scope.model.resource; - scope.count = 0; - scope.rows = []; - ref = scope.value; - for (j = 0, len = ref.length; j < len; j++) { - value = ref[j]; - scope.rows.push(new resource(value)); - scope.count++; - } - scope.name = property.name; - scope.v = property.validation; - } - }; +angular.module('loopback-admin').directive('lbHasManyProperty', function () { + return { + scope: { + property: '=', + value: '=', + form: '=', + errorMessages: '=' + }, + templateUrl: 'templates/property/has-many.tpl.html', + restrict: 'E', + link: function (scope, element) { + var i, len, property, ref, resource, value; + property = scope.property; + scope.model = property.getModel(); + resource = scope.model.resource; + scope.count = 0; + scope.rows = []; + ref = scope.value; + for (i = 0, len = ref.length; i < len; i++) { + value = ref[i]; + scope.rows.push(new resource(value)); + scope.count++; + } + scope.name = property.name; + scope.v = property.validation; + } + }; }); 'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } -angular.module('loopback-admin').factory('HasManyProperty', ["Property", "LoopBackAdminConfiguration", function(Property, LoopBackAdminConfiguration) { - var HasManyProperty; - return HasManyProperty = (function(superClass) { - extend(HasManyProperty, superClass); + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; - function HasManyProperty(name, property) { - HasManyProperty.__super__.constructor.call(this, name, property); - this.type = "hasMany"; - } +angular.module('loopback-admin').factory('HasManyProperty', ["Property", "LoopBackAdminConfiguration", function (Property, LoopBackAdminConfiguration) { + var HasManyProperty; + return HasManyProperty = (function (superClass) { + extend(HasManyProperty, superClass); - HasManyProperty.prototype.getModel = function() { - return LoopBackAdminConfiguration.getModel(this.model); - }; + function HasManyProperty(name, property) { + HasManyProperty.__super__.constructor.call(this, name, property); + this.type = "hasMany"; + } + + HasManyProperty.prototype.getModel = function () { + return LoopBackAdminConfiguration.getModel(this.model); + }; - return HasManyProperty; + return HasManyProperty; - })(Property); + })(Property); }]); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - fvp.registerPropertyView('string', { - column: '', - field: '' - }); - return fvp.registerAlias('objectid', 'string'); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + fvp.registerPropertyView('string', { + column: '', + field: '' + }); + return fvp.registerAlias('objectid', 'string'); }]); 'use strict'; - -angular.module('loopback-admin').directive('lbInputProperty', function() { - return { - scope: { - property: '=', - value: '=', - form: '=', - errorMessages: '=' - }, - templateUrl: 'templates/property/input.tpl.html', - restrict: 'E', - link: function(scope, element) { - var property; - property = scope.property; - scope.name = property.name; - scope.v = property.validation; - } - }; +angular.module('loopback-admin').directive('lbInputProperty', function () { + return { + scope: { + property: '=', + value: '=', + form: '=', + errorMessages: '=' + }, + templateUrl: 'templates/property/input.tpl.html', + restrict: 'E', + link: function (scope, element) { + var property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + } + }; }); 'use strict'; - -angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function(PropertyViewConfigurationProvider) { - var fvp; - fvp = PropertyViewConfigurationProvider; - return fvp.registerPropertyView('number', { - column: '', - field: '' - }); +angular.module('loopback-admin').config(["PropertyViewConfigurationProvider", function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('number', { + column: '', + field: '' + }); }]); 'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; -angular.module('loopback-admin').factory('NumberProperty', ["Property", function(Property) { - var NumberProperty; - return NumberProperty = (function(superClass) { - extend(NumberProperty, superClass); +angular.module('loopback-admin').factory('NumberProperty', ["Property", function (Property) { + var NumberProperty; + return NumberProperty = (function (superClass) { + extend(NumberProperty, superClass); - function NumberProperty(name, property) { - NumberProperty.__super__.constructor.call(this, name, property); - this.type = "number"; - this.format = void 0; - } + function NumberProperty(name, property) { + NumberProperty.__super__.constructor.call(this, name, property); + this.type = "number"; + this.format = void 0; + } - return NumberProperty; + return NumberProperty; - })(Property); + })(Property); }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('app', { - abstract: true, - template: '
', - resolve: { - user: ["LoopBackAdminConfiguration", function(LoopBackAdminConfiguration) { - var User; - User = LoopBackAdminConfiguration.userModel; - return User.getCurrent().$promise; - }], - config: ["user", "LoopBackAdminConfiguration", function(user, LoopBackAdminConfiguration) { - return LoopBackAdminConfiguration.initialize(); - }] - } - }).state('browser', { - parent: 'app', - abstract: true, - controller: 'BrowserController', - controllerAs: 'browserController', - templateUrl: "templates/routing/browser.tpl.html", - resolve: { - config: ["LoopBackAdminConfiguration", function(LoopBackAdminConfiguration) { - return LoopBackAdminConfiguration.initialize(); - }] - } - }); +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('app', { + abstract: true, + template: '
', + resolve: { + user: ["LoopBackAdminConfiguration", function (LoopBackAdminConfiguration) { + var User; + User = LoopBackAdminConfiguration.userModel; + return User.getCurrent().$promise; + }], + config: ["user", "LoopBackAdminConfiguration", function (user, LoopBackAdminConfiguration) { + return LoopBackAdminConfiguration.initialize(); + }] + } + }).state('browser', { + parent: 'app', + abstract: true, + controller: 'BrowserController', + controllerAs: 'browserController', + templateUrl: "templates/routing/browser.tpl.html", + resolve: { + config: ["LoopBackAdminConfiguration", function (LoopBackAdminConfiguration) { + return LoopBackAdminConfiguration.initialize(); + }] + } + }); }]); 'use strict'; - -angular.module('loopback-admin').controller('BrowserController', ["$scope", "$state", "LoopBackAdminConfiguration", function($scope, $state, LoopBackAdminConfiguration) { - var application, vm; - vm = this; - application = LoopBackAdminConfiguration; - vm.menu = application.menu; +angular.module('loopback-admin').controller('BrowserController', ["$scope", "$state", "LoopBackAdminConfiguration", function ($scope, $state, LoopBackAdminConfiguration) { + var application, vm; + vm = this; + application = LoopBackAdminConfiguration; + vm.menu = application.menu; }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('dashboard', { - parent: 'browser', - url: '/dashboard', - controller: 'DashboardController', - controllerAs: 'dashboardController', - templateUrl: "templates/routing/dashboard.tpl.html", - resolve: { - models: ["config", function(config) { - return config.getModels(); - }] - } - }); +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + $stateProvider.state('ban', { + url: '/baneados', + parent: 'browser', + controller: 'BanController', + controllerAs: 'banController', + templateUrl: 'templates/routing/ban.tpl.html', + resolve: { + model: ["config", function (config) { + return config.getModel('BanReport'); + }] + } + }); }]); 'use strict'; - -angular.module('loopback-admin').controller('DashboardController', ["models", function(models) { - var vm; - vm = this; - vm.models = models; +angular.module('loopback-admin').controller('ListController', ["model", function (model) { + var vm; + vm = this; + vm.model = model; }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('error', { - parent: 'app', - templateUrl: 'templates/routing/error.tpl.html', - onEnter: ["config", "$log", "$state", function(config, $log, $state) { - return $log.error(config, $state); - }] - }); +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('dashboard', { + parent: 'browser', + url: '/dashboard', + controller: 'DashboardController', + controllerAs: 'dashboardController', + templateUrl: "templates/routing/dashboard.tpl.html", + resolve: { + models: ["config", function (config) { + return config.getModels(); + }] + } + }); }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('landing', { - url: '/landing', - templateUrl: "templates/routing/landing-page.tpl.html", - controller: 'LandingPageController', - controllerAs: 'landing', - resolve: { - background: ["Flickr", function(Flickr) { - return Flickr.getBackgroundImage(); - }] - } - }); +angular.module('loopback-admin').controller('DashboardController', ["models", function (models) { + var vm; + vm = this; + vm.models = models; }]); 'use strict'; - -angular.module('loopback-admin').controller('LandingPageController', ["background", function(background) { - var vm; - vm = this; - vm.background = background; +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('error', { + parent: 'app', + templateUrl: 'templates/routing/error.tpl.html', + onEnter: ["config", "$log", "$state", function (config, $log, $state) { + return $log.error(config, $state); + }] + }); }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - $stateProvider.state('list', { - url: '/:model/list', - parent: 'browser', - controller: 'ListController', - controllerAs: 'listController', - templateUrl: 'templates/routing/list.tpl.html', - resolve: { - model: ["config", "$stateParams", function(config, $stateParams) { - return config.getModel($stateParams.model); - }] - } - }); +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('landing', { + url: '/landing', + templateUrl: "templates/routing/landing-page.tpl.html", + controller: 'LandingPageController', + controllerAs: 'landing', + resolve: { + background: ["Flickr", function (Flickr) { + return Flickr.getBackgroundImage(); + }] + } + }); }]); 'use strict'; - -angular.module('loopback-admin').controller('ListController', ["model", function(model) { - var vm; - vm = this; - vm.model = model; +angular.module('loopback-admin').controller('LandingPageController', ["background", function (background) { + var vm; + vm = this; + vm.background = background; }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('login', { - url: '/login', - views: { - '': { - templateUrl: "templates/routing/register-login.tpl.html", - controller: ["$scope", function($scope) { - return $scope.pageTitle = 'Login'; - }] - }, - 'content@login': { - templateUrl: "templates/routing/login.tpl.html", - controller: 'loginController', - controllerAs: 'loginController' - } - } - }); +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + $stateProvider.state('list', { + url: '/:model/list', + parent: 'browser', + controller: 'ListController', + controllerAs: 'listController', + templateUrl: 'templates/routing/list.tpl.html', + resolve: { + model: ["config", "$stateParams", function (config, $stateParams) { + return config.getModel($stateParams.model); + }] + } + }); }]); 'use strict'; +angular.module('loopback-admin').controller('ListController', ["model", function (model) { + var vm; + vm = this; + vm.model = model; +}]); -angular.module('loopback-admin').controller('loginController', ["$state", "$rootScope", "LoopBackAdminConfiguration", "$scope", "$mdDialog", function($state, $rootScope, LoopBackAdminConfiguration, $scope, $mdDialog) { - var User, vm; - vm = this; - User = LoopBackAdminConfiguration.userModel; - vm.userLoginField = LoopBackAdminConfiguration.userLoginField; - vm.login = function(credentials) { - var request; - request = User.login(credentials); - return request.$promise.then(function(data) { - $state.go('dashboard'); - })["catch"](function(err) { - vm.error = err; - }); - }; - vm.showPasswordResetModal = function($event) { - $mdDialog.show({ - templateUrl: 'templates/modals/reset-password.html', - targetEvent: $event, - controller: 'ResetPasswordCtrl', - controllerAs: 'resetPassword', - clickOutsideToClose: true - }); - }; -}]).controller('ResetPasswordCtrl', ["$mdDialog", "LoopBackAdminConfiguration", function($mdDialog, LoopBackAdminConfiguration) { - var User, vm; - vm = this; - User = LoopBackAdminConfiguration.userModel; - vm.resetPasswordError = ''; - vm.closePasswordResetModal = function() { - vm.resetPasswordError = ''; - vm.passResetCredentials = {}; - $mdDialog.hide(); - }; - vm.resetPassword = function(passResetCredentials) { - User.resetPassword(passResetCredentials).$promise.then(function(data) { - $rootScope.showToast(data); - return vm.closePasswordResetModal(); - })["catch"](function(data) { - vm.resetPasswordError = data.email || data; +'use strict'; +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('login', { + url: '/login', + views: { + '': { + templateUrl: "templates/routing/register-login.tpl.html", + controller: ["$scope", function ($scope) { + return $scope.pageTitle = 'Login'; + }] + }, + 'content@login': { + templateUrl: "templates/routing/login.tpl.html", + controller: 'loginController', + controllerAs: 'loginController' + } + } }); - }; }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('logout', { - url: '/logout', - controller: 'logoutController', - controllerAs: 'logoutController' - }); +angular.module('loopback-admin').controller('loginController', ["$state", "$rootScope", "LoopBackAdminConfiguration", "$scope", "$mdDialog", function ($state, $rootScope, LoopBackAdminConfiguration, $scope, $mdDialog) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.userLoginField = LoopBackAdminConfiguration.userLoginField; + vm.login = function (credentials) { + var request; + request = User.login(credentials); + return request.$promise.then(function (data) { + if (data.user.role === 'admin') { + $state.go('dashboard'); + } else { + User.logout(); + } + })["catch"](function (err) { + vm.error = err; + }); + }; + vm.showPasswordResetModal = function ($event) { + $mdDialog.show({ + templateUrl: 'templates/modals/reset-password.html', + targetEvent: $event, + controller: 'ResetPasswordCtrl', + controllerAs: 'resetPassword', + clickOutsideToClose: true + }); + }; +}]).controller('ResetPasswordCtrl', ["$mdDialog", "LoopBackAdminConfiguration", function ($mdDialog, LoopBackAdminConfiguration) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.resetPasswordError = ''; + vm.closePasswordResetModal = function () { + vm.resetPasswordError = ''; + vm.passResetCredentials = {}; + $mdDialog.hide(); + }; + vm.resetPassword = function (passResetCredentials) { + User.resetPassword(passResetCredentials).$promise.then(function (data) { + $rootScope.showToast(data); + return vm.closePasswordResetModal(); + })["catch"](function (data) { + vm.resetPasswordError = data.email || data; + }); + }; }]); 'use strict'; - -angular.module('loopback-admin').controller('logoutController', ["$location", "$rootScope", "LoopBackAdminConfiguration", function($location, $rootScope, LoopBackAdminConfiguration) { - var User; - User = LoopBackAdminConfiguration.userModel; - User.logout(); - $location.path('/login'); +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('logout', { + url: '/logout', + controller: 'logoutController', + controllerAs: 'logoutController' + }); }]); 'use strict'; - -angular.module('loopback-admin').config(["$stateProvider", function($stateProvider) { - return $stateProvider.state('register', { - url: '/register', - controller: 'registerController', - controllerAs: 'registerController', - views: { - '': { - templateUrl: "templates/routing/register-login.tpl.html", - controller: ["$scope", function($scope) { - return $scope.pageTitle = 'Register'; - }] - }, - 'content@register': { - templateUrl: "templates/routing/register.tpl.html" - } - } - }); +angular.module('loopback-admin').controller('logoutController', ["$location", "$rootScope", "LoopBackAdminConfiguration", function ($location, $rootScope, LoopBackAdminConfiguration) { + var User; + User = LoopBackAdminConfiguration.userModel; + User.logout(); + $location.path('/login'); }]); 'use strict'; - -angular.module('loopback-admin').controller('registerController', ["$state", "LoopBackAdminConfiguration", function($state, LoopBackAdminConfiguration) { - var User, vm; - vm = this; - User = LoopBackAdminConfiguration.userModel; - vm.login = function() { - var request; - request = User.login(vm.data); - return request.$promise.then(function(data) { - $state.go('dashboard'); - })["catch"](function(err) { - vm.error = err; +angular.module('loopback-admin').config(["$stateProvider", function ($stateProvider) { + return $stateProvider.state('register', { + url: '/register', + controller: 'registerController', + controllerAs: 'registerController', + views: { + '': { + templateUrl: "templates/routing/register-login.tpl.html", + controller: ["$scope", function ($scope) { + return $scope.pageTitle = 'Register'; + }] + }, + 'content@register': { + templateUrl: "templates/routing/register.tpl.html" + } + } }); - }; }]); 'use strict'; +angular.module('loopback-admin').controller('registerController', ["$state", "LoopBackAdminConfiguration", function ($state, LoopBackAdminConfiguration) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.login = function () { + var request; + request = User.login(vm.data); + return request.$promise.then(function (data) { + $state.go('dashboard'); + })["catch"](function (err) { + vm.error = err; + }); + }; +}]); -angular.module('loopback-admin').directive('lbBooleanColumn', function() { - return { - restrict: 'E', - scope: { - value: '=' - }, - templateUrl: 'templates/table/column/boolean.tpl.html', - link: function(scope) { - scope.isOk = !!scope.value; - } - }; +'use strict'; +angular.module('loopback-admin').directive('lbBooleanColumn', function () { + return { + restrict: 'E', + scope: { + value: '=' + }, + templateUrl: 'templates/table/column/boolean.tpl.html', + link: function (scope) { + scope.isOk = !!scope.value; + } + }; }); - 'use strict'; - -angular.module('loopback-admin').directive('lbChoicesColumn', function() { - return { - restrict: 'E', - scope: { - values: '=' - }, - templateUrl: 'templates/table/column/choices.tpl.html' - }; +angular.module('loopback-admin').directive('lbChoicesColumn', function () { + return { + restrict: 'E', + scope: { + values: '=' + }, + templateUrl: 'templates/table/column/choices.tpl.html' + }; }); - 'use strict'; - -angular.module('loopback-admin').directive('lbColumn', function() { - return { - restrict: 'E', - scope: { - property: '=', - row: '=', - model: '=', - rows: '=' - }, - template: "" - }; +angular.module('loopback-admin').directive('lbColumn', function () { + return { + restrict: 'E', + scope: { + property: '=', + row: '=', + model: '=', + rows: '=' + }, + template: "" + }; }); - 'use strict'; - -angular.module('loopback-admin').directive('lbDateColumn', function() { - return { - restrict: 'E', - scope: { - value: '=', - property: '=' - }, - templateUrl: 'templates/table/column/date.tpl.html', - link: function(scope) { - var property; - property = scope.property; - scope.format = property.format; - if (!scope.format) { - scope.format = property.type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'; - } - } - }; +angular.module('loopback-admin').directive('lbDateColumn', function () { + return { + restrict: 'E', + scope: { + value: '=', + property: '=' + }, + templateUrl: 'templates/table/column/date.tpl.html', + link: function (scope) { + var property; + property = scope.property; + scope.format = property.format; + if (!scope.format) { + scope.format = property.type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'; + } + } + }; }); - 'use strict'; - -angular.module('loopback-admin').directive('lbNumberColumn', function() { - return { - restrict: 'E', - scope: { - value: '=', - property: '=' - }, - templateUrl: 'templates/table/column/number.tpl.html' - }; +angular.module('loopback-admin').directive('lbNumberColumn', function () { + return { + restrict: 'E', + scope: { + value: '=', + property: '=' + }, + templateUrl: 'templates/table/column/number.tpl.html' + }; }); - 'use strict'; - -angular.module('loopback-admin').directive('lbStringColumn', function() { - return { - restrict: 'E', - scope: { - value: '=' - }, - templateUrl: 'templates/table/column/string.tpl.html' - }; +angular.module('loopback-admin').directive('lbStringColumn', function () { + return { + restrict: 'E', + scope: { + value: '=' + }, + templateUrl: 'templates/table/column/string.tpl.html' + }; }); 'use strict'; - -angular.module('loopback-admin').controller('TableCtrl', ["$mdDialog", "$rootScope", "$log", function($mdDialog, $rootScope, $log) { - var ref, refreshRows, vm; - vm = this; - vm.deferred = null; - vm.filter = { - options: { - debounce: 500 - } - }; - vm.query = { - filter: null, - limit: 10, - orderPlain: 'id', - orderDirection: 'DESC', - page: 1 - }; - vm.resource = (ref = vm.model) != null ? ref.resource : void 0; - vm.rows = []; - vm.selected = []; - vm.deleteRows = function(selected, $event) { - var options; - options = { - title: 'Delete Items', - body: 'Are you sure you want to delete these items?', - event: $event - }; - $rootScope.confirm(options).then(function() { - var idx, indx, item; - item = selected.pop(); - indx = vm.rows.indexOf(item); - idx = selected.indexOf(item); - item.$remove(); - if (indx > -1) { - return vm.rows.splice(indx, 1); - } - }); - }; - vm.showRowModal = function(type, row, $event) { - return $mdDialog.show({ - locals: { - row: row, - type: type, - rows: vm.rows, - model: vm.model - }, - templateUrl: "templates/modals/table.tpl.html", - targetEvent: $event, - clickOutsideToClose: true, - controller: 'RowDataModel', - controllerAs: 'modal' - }); - }; - refreshRows = function() { - var filter, page, params; - page = parseInt(vm.query.page, 10); - filter = { - include: vm.model.relationNames, - skip: (page - 1) * vm.query.limit, - limit: vm.query.limit, - order: vm.query.orderPlain + ' ' + vm.query.orderDirection - }; - params = { - filter: filter - }; - vm.rows = vm.resource.find(params, function(data, headers) { - return vm.count = parseInt(headers('x-total-count')); - }); - vm.deferred = vm.rows.$promise; - return vm.deferred; - }; - if (vm.resource && angular.isFunction(vm.resource.find)) { - refreshRows(); - } - vm.removeFilter = function() { - vm.filter.show = false; - vm.query.filter = ''; - if (vm.filter.form.$dirty) { - vm.filter.form.$setPristine(); - refreshRows(); - } - }; - vm.onOrderChange = function(order, $event) { - var direction, orderPlain; - $log.info('Scope Order: ' + vm.query.order); - $log.info('Order: ' + order); - direction = 'ASC'; - if (order.charAt(0) === '-') { - direction = 'DESC'; - orderPlain = order.slice(1); +angular.module('loopback-admin').controller('TableCtrl', ["$mdDialog", "$rootScope", "$log", function ($mdDialog, $rootScope, $log) { + var ref, refreshRows, vm; + vm = this; + vm.deferred = null; + vm.filter = { + options: { + debounce: 500 + } + }; + vm.query = { + filter: null, + limit: 10, + orderPlain: 'id', + orderDirection: 'DESC', + page: 1 + }; + vm.resource = (ref = vm.model) != null ? ref.resource : void 0; + vm.rows = []; + vm.selected = []; + vm.deleteRows = function (selected, $event) { + var options; + options = { + title: 'Delete Items', + body: 'Are you sure you want to delete these items?', + event: $event + }; + $rootScope.confirm(options).then(function () { + var idx, indx, item; + item = selected.pop(); + indx = vm.rows.indexOf(item); + idx = selected.indexOf(item); + item.$remove(); + if (indx > -1) { + return vm.rows.splice(indx, 1); + } + }); + }; + vm.showRowModal = function (type, row, $event) { + return $mdDialog.show({ + locals: { + row: row, + type: type, + rows: vm.rows, + model: vm.model + }, + templateUrl: "templates/modals/table.tpl.html", + targetEvent: $event, + clickOutsideToClose: true, + controller: 'RowDataModel', + controllerAs: 'modal' + }); + }; + refreshRows = function () { + var filter, page, params; + page = parseInt(vm.query.page, 10); + filter = { + include: vm.model.relationNames, + skip: (page - 1) * vm.query.limit, + limit: vm.query.limit, + order: vm.query.orderPlain + ' ' + vm.query.orderDirection + }; + params = { + filter: filter + }; + vm.rows = vm.resource.find(params, function (data, headers) { + return vm.count = parseInt(headers('x-total-count')); + }); + vm.deferred = vm.rows.$promise; + return vm.deferred; + }; + if (vm.resource && angular.isFunction(vm.resource.find)) { + refreshRows(); } - vm.query.order = order; - vm.query.orderPlain = orderPlain || order; - vm.query.orderDirection = direction; - refreshRows(); - }; - vm.onPageChange = function(page, limit) { - $log.info('Scope Page: ' + vm.query.page + ' Scope Limit: ' + vm.query.limit); - $log.info('Page: ' + page + ' Limit: ' + limit); - vm.query.page = page; - vm.query.limit = limit; - refreshRows(); - }; - vm.onFilterChange = function(filter, $event) { - $log.info('Scope Filter: ' + vm.query.filter); - $log.info('Filter: ' + filter); - vm.query.page = 1; - refreshRows(); - }; + vm.removeFilter = function () { + vm.filter.show = false; + vm.query.filter = ''; + if (vm.filter.form.$dirty) { + vm.filter.form.$setPristine(); + refreshRows(); + } + }; + vm.onOrderChange = function (order, $event) { + var direction, orderPlain; + $log.info('Scope Order: ' + vm.query.order); + $log.info('Order: ' + order); + direction = 'ASC'; + if (order.charAt(0) === '-') { + direction = 'DESC'; + orderPlain = order.slice(1); + } + vm.query.order = order; + vm.query.orderPlain = orderPlain || order; + vm.query.orderDirection = direction; + refreshRows(); + }; + vm.onPageChange = function (page, limit) { + $log.info('Scope Page: ' + vm.query.page + ' Scope Limit: ' + vm.query.limit); + $log.info('Page: ' + page + ' Limit: ' + limit); + vm.query.page = page; + vm.query.limit = limit; + refreshRows(); + }; + vm.onFilterChange = function (filter, $event) { + $log.info('Scope Filter: ' + vm.query.filter); + $log.info('Filter: ' + filter); + vm.query.page = 1; + refreshRows(); + }; }]); - 'use strict'; - -angular.module('loopback-admin').directive('cmsTable', function() { - return { - bindToController: { - properties: '=', - columnLimit: '=', - model: '=', - template: '@' - }, - controller: 'TableCtrl', - controllerAs: 'table', - scope: {}, - templateUrl: 'templates/table/table.tpl.html' - }; +angular.module('loopback-admin').directive('cmsTable', function () { + return { + bindToController: { + properties: '=', + columnLimit: '=', + model: '=', + template: '@' + }, + controller: 'TableCtrl', + controllerAs: 'table', + scope: {}, + templateUrl: 'templates/table/table.tpl.html' + }; }); - 'use strict'; - -angular.module('loopback-admin').controller('RowDataModel', ["$mdDialog", "$rootScope", "type", "row", "rows", "model", function($mdDialog, $rootScope, type, row, rows, model) { - var fn, resource, vm; - resource = model.resource; - fn = type === 'edit' ? 'prototype$updateAttributes' : 'create'; - vm = this; - vm.form = {}; - vm.model = model; - vm.properties = model.properties; - vm.row = row || new resource(); - vm.type = type; - vm.submit = function(data) { - var error, success; - success = function() { - $mdDialog.hide(); - $rootScope.showToast(type + 'dUserSuccessfully'); - if (type === 'create') { - return rows.push(data); - } - }; - error = function(response) { - var code, codes, errorType, messages, ref; - ref = response.data.error.details, codes = ref.codes, messages = ref.messages; - for (code in codes) { - errorType = codes[code]; - vm.form[code].$setValidity(errorType[0], false); - } - vm.errorMessages = messages; - return $rootScope.showToast(type + 'dUserFailed', 'warn'); - }; - return data['$' + fn](success, error); - }; -}]); +angular.module('loopback-admin').controller('RowDataModel', ["$mdDialog", "$rootScope", "type", "row", "rows", "model", function ($mdDialog, $rootScope, type, row, rows, model) { + var fn, resource, vm; + resource = model.resource; + fn = type === 'edit' ? 'prototype$updateAttributes' : 'create'; + vm = this; + vm.form = {}; + vm.model = model; + vm.properties = model.properties; + vm.row = row || new resource(); + vm.type = type; + vm.submit = function (data) { + var error, success; + success = function () { + $mdDialog.hide(); + $rootScope.showToast(type + 'dUserSuccessfully'); + if (type === 'create') { + return rows.push(data); + } + }; + error = function (response) { + var code, codes, errorType, messages, ref; + ref = response.data.error.details, codes = ref.codes, messages = ref.messages; + for (code in codes) { + errorType = codes[code]; + vm.form[code].$setValidity(errorType[0], false); + } + vm.errorMessages = messages; + return $rootScope.showToast(type + 'dUserFailed', 'warn'); + }; + return data['$' + fn](success, error); + }; +}]); \ No newline at end of file diff --git a/dist/public/js/loopback-admin.templates.js b/dist/public/js/loopback-admin.templates.js index 356edf4..c65b4e1 100644 --- a/dist/public/js/loopback-admin.templates.js +++ b/dist/public/js/loopback-admin.templates.js @@ -486,6 +486,17 @@ angular.module('loopback-admin.theme', []).run(['$templateCache', function($temp ); + $templateCache.put('templates/routing/ban.tpl.html', + "
\n" + + " \n" + + " \n" + + "
" + ); + + $templateCache.put('templates/routing/browser.tpl.html', "\n" + " \n" + @@ -504,6 +515,8 @@ angular.module('loopback-admin.theme', []).run(['$templateCache', function($temp "\n" + "\n" + "
\n" + + " \n" + + " \n" + "
\n" ); diff --git a/package.json b/package.json index 3a7010b..d2e2ed3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loopback-component-admin", - "version": "0.0.7", + "version": "0.2.0", "main": "dist/index.js", "author": { "name": "BoLaMN", @@ -8,12 +8,11 @@ }, "repository": { "type": "git", - "url": "https://github.com/BoLaMN/loopback-component-admin" + "url": "https://github.com/aitoraznar/loopback-component-admin" }, "license": "MIT", "scripts": {}, "devDependencies": { - "coffee-script": "1.10.0", "grunt": "^0.4.5", "grunt-angular-templates": "^0.5.7", "grunt-contrib-clean": "~0.6.0", diff --git a/src/client/app.coffee b/src/client/app.coffee deleted file mode 100644 index 945b67f..0000000 --- a/src/client/app.coffee +++ /dev/null @@ -1,41 +0,0 @@ - -angular.module 'loopback-admin', [ - 'ui.router' - 'md.data.table' - 'ngSanitize' - 'ngAnimate' - 'ngAria' - 'ngMaterial' - 'angularFileUpload' - 'loopback-admin.services' - 'loopback-admin.theme' -] - -.config ($urlRouterProvider, $mdThemingProvider, $mdIconProvider, $compileProvider) -> - $compileProvider.debugInfoEnabled true - - $mdThemingProvider - .theme 'default' - .primaryPalette 'blue' - - dark = $mdThemingProvider.extendPalette 'grey', - contrastDefaultColor: 'light' - - $mdThemingProvider.definePalette 'dark', dark - - $mdThemingProvider.theme 'black' - .primaryPalette 'dark', default: '900' - - $urlRouterProvider - .when '', '/landing' - .when '/', '/landing' - - .otherwise ($injector, $location) -> - state = $injector.get '$state' - state.go 'error' - $location.path() - - $mdIconProvider.defaultFontSet 'material-icons' - - return - diff --git a/src/client/app.js b/src/client/app.js new file mode 100644 index 0000000..bc2e4e3 --- /dev/null +++ b/src/client/app.js @@ -0,0 +1,24 @@ +angular.module('loopback-admin', ['ui.router', 'md.data.table', 'ngSanitize', 'ngAnimate', 'ngAria', 'ngMaterial', + 'angularFileUpload', 'loopback-admin.services', + 'loopback-admin.theme']) + .config(function ($urlRouterProvider, $mdThemingProvider, $mdIconProvider, $compileProvider) { + + var dark; + + $compileProvider.debugInfoEnabled(true); + $mdThemingProvider.theme('default').primaryPalette('blue'); + dark = $mdThemingProvider.extendPalette('grey', { + contrastDefaultColor: 'light' + }); + $mdThemingProvider.definePalette('dark', dark); + $mdThemingProvider.theme('black').primaryPalette('dark', { + "default": '900' + }); + $urlRouterProvider.when('', '/landing').when('/', '/landing').otherwise(function ($injector, $location) { + var state; + state = $injector.get('$state'); + state.go('error'); + return $location.path(); + }); + $mdIconProvider.defaultFontSet('material-icons'); + }); diff --git a/src/client/components/common/directives/component.directive.coffee b/src/client/components/common/directives/component.directive.coffee deleted file mode 100644 index 50d1c77..0000000 --- a/src/client/components/common/directives/component.directive.coffee +++ /dev/null @@ -1,99 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'AccountSettingsController', ($upload, $rootScope, activeTab, LoopBackAuth, LoopBackAdminConfiguration) -> - vm = this - - User = LoopBackAdminConfiguration.userModel - - vm.auth = LoopBackAuth - - vm.activeTab = activeTab - - vm.changePassword = (passwords) -> - User.changePassword(passwords).$promise - .then (data) => - $rootScope.showToast data - $rootScope.closeModal() - return - return - - vm.getUsernameForCurrentUser = -> - if !@current or !@current.email - return - - if @current.username - return @current.username - - @current.email.split('@')[0] - - vm.updateAccountSettings = (settings, id) -> - payload = settings or @auth.currentUserData - userId = id or @auth.currentUserId - - User.update({ where:{id:userId} }, payload).$promise - .then (data) => - if !settings - $rootScope.showToast 'profileUpdateSuccess', true - $rootScope.closeModal() - @current = data - return - - vm.removeAvatar = -> - $http.delete(LoopBackAdminConfiguration.urlBase + '/employees/' + @current.id + '/avatar').success (data) -> - @current.avatar_url = '' - $rootScope.showToast data - return - - - vm.upload = (files) -> - if !files.length - return - - file = files[0] - - $upload.upload - url: LoopBackAdminConfiguration.urlBase + '/employees/' + id + '/avatar' - file: file - .success (data) -> LoopBackAuth.currentUserData.avatar_url = data - .error (data, code) -> if code == 422 then showToast data.file[0] - - return - -.directive 'cmsCurrentUser', -> - replace: true - templateUrl: 'templates/common/current-user.html' - controllerAs: 'ctrl' - controller: ($state, LoopBackAuth, $mdDialog, $upload) -> - vm = this - - vm.auth = LoopBackAuth - - vm.state = $state - - vm.openMenu = ($mdOpenMenu, ev) -> - $mdOpenMenu ev - - vm.showAccountSettingsModal = ($event, fieldToFocus) -> - options = - templateUrl: 'templates/modals/account-settings.html' - targetEvent: $event - locals: - activeTab: 'settings' - clickOutsideToClose: true - controllerAs: 'modal' - controller: 'AccountSettingsController' - - if fieldToFocus is 'avatar' - options.locals.activeTab = 'avatar' - - $mdDialog.show options - - return - return - -.directive 'cmsToolbar', -> - replace: true - scope: { title: '=' } - templateUrl: 'templates/common/toolbar.html' diff --git a/src/client/components/common/directives/component.directive.js b/src/client/components/common/directives/component.directive.js new file mode 100644 index 0000000..622b47a --- /dev/null +++ b/src/client/components/common/directives/component.directive.js @@ -0,0 +1,106 @@ +'use strict'; +angular.module('loopback-admin').controller('AccountSettingsController', function ($upload, $rootScope, activeTab, LoopBackAuth, LoopBackAdminConfiguration) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.auth = LoopBackAuth; + vm.activeTab = activeTab; + vm.changePassword = function (passwords) { + User.changePassword(passwords).$promise.then((function (_this) { + return function (data) { + $rootScope.showToast(data); + $rootScope.closeModal(); + }; + })(this)); + }; + vm.getUsernameForCurrentUser = function () { + if (!this.current || !this.current.email) { + return; + } + if (this.current.username) { + return this.current.username; + } + return this.current.email.split('@')[0]; + }; + vm.updateAccountSettings = function (settings, id) { + var payload, userId; + payload = settings || this.auth.currentUserData; + userId = id || this.auth.currentUserId; + return User.update({ + where: { + id: userId + } + }, payload).$promise.then((function (_this) { + return function (data) { + if (!settings) { + $rootScope.showToast('profileUpdateSuccess', true); + $rootScope.closeModal(); + _this.current = data; + } + }; + })(this)); + }; + vm.removeAvatar = function () { + return $http["delete"](LoopBackAdminConfiguration.urlBase + '/employees/' + this.current.id + '/avatar').success(function (data) { + this.current.avatar_url = ''; + $rootScope.showToast(data); + }); + }; + vm.upload = function (files) { + var file; + if (!files.length) { + return; + } + file = files[0]; + return $upload.upload({ + url: LoopBackAdminConfiguration.urlBase + '/employees/' + id + '/avatar', + file: file + }).success(function (data) { + return LoopBackAuth.currentUserData.avatar_url = data; + }).error(function (data, code) { + if (code === 422) { + return showToast(data.file[0]); + } + }); + }; +}).directive('cmsCurrentUser', function () { + return { + replace: true, + templateUrl: 'templates/common/current-user.html', + controllerAs: 'ctrl', + controller: function ($state, LoopBackAuth, $mdDialog, $upload) { + var vm; + vm = this; + vm.auth = LoopBackAuth; + vm.state = $state; + vm.openMenu = function ($mdOpenMenu, ev) { + return $mdOpenMenu(ev); + }; + vm.showAccountSettingsModal = function ($event, fieldToFocus) { + var options; + options = { + templateUrl: 'templates/modals/account-settings.html', + targetEvent: $event, + locals: { + activeTab: 'settings' + }, + clickOutsideToClose: true, + controllerAs: 'modal', + controller: 'AccountSettingsController' + }; + if (fieldToFocus === 'avatar') { + options.locals.activeTab = 'avatar'; + } + $mdDialog.show(options); + }; + } + }; +}).directive('cmsToolbar', function () { + return { + replace: true, + scope: { + title: '=' + }, + templateUrl: 'templates/common/toolbar.html' + }; +}); \ No newline at end of file diff --git a/src/client/components/common/directives/side-menu.coffee b/src/client/components/common/directives/side-menu.coffee deleted file mode 100644 index 3bb1242..0000000 --- a/src/client/components/common/directives/side-menu.coffee +++ /dev/null @@ -1,24 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'mdSidemenu', -> - restrict: 'E' - scope: { menu: '=' } - template: ''' - ''' - controllerAs: 'ctrl' - controller: ($state) -> - vm = this - - vm.select = (state, params) -> - $state.go state, params - - return \ No newline at end of file diff --git a/src/client/components/common/directives/side-menu.js b/src/client/components/common/directives/side-menu.js new file mode 100644 index 0000000..16b3448 --- /dev/null +++ b/src/client/components/common/directives/side-menu.js @@ -0,0 +1,18 @@ +'use strict'; +angular.module('loopback-admin').directive('mdSidemenu', function () { + return { + restrict: 'E', + scope: { + menu: '=' + }, + template: '', + controllerAs: 'ctrl', + controller: function ($state) { + var vm; + vm = this; + vm.select = function (state, params) { + return $state.go(state, params); + }; + } + }; +}); diff --git a/src/client/components/common/directives/social-login.directive.coffee b/src/client/components/common/directives/social-login.directive.coffee deleted file mode 100644 index 6bf5d36..0000000 --- a/src/client/components/common/directives/social-login.directive.coffee +++ /dev/null @@ -1,79 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'cmsSocialButtons', -> - restrict: 'E' - templateUrl: 'templates/common/social-buttons.tpl.html' - controller: 'SocialLoginCtrl' - controllerAs: 'social' - -.controller 'SocialLoginCtrl', (LoopBackAdminConfiguration, LoopBackAuth, $http, $state, $mdDialog, $mdToast) -> - vm = this - - vm.credentials = {} - - vm.loginWith = (service) -> - url = LoopBackAdminConfiguration.urlBase + '/auth/social/' + service - - left = screen.width / 2 - (580 / 2) - top = screen.height / 2 - (450 / 2) - - window.$tempScope = vm - - options = [ - 'menubar=0' - 'location=0' - 'toolbar=0' - 'titlebar=0' - 'status=0' - 'width=580' - 'height=450' - 'left=' + left - 'top=' + top - ].join ', ' - - window.open url, 'Authenticate Account', options - - return - - vm.socialLoginCallback = (user) -> - window.$tempScope = null - - if user - LoopBackAuth.currentUserData = user - $state.go 'dashboard' - else - vm.requestUserEmail() - - return - - vm.socialLoginCallbackError = -> - $mdToast.show $mdToast.simple(position: 'bottom right').content('genericSocialError') - return - - vm.createAndLoginUser = -> - $http.post LoopBackAdminConfiguration.urlBase + '/auth/social/request-email-callback', email: vm.credentials.email - .success (data) -> $state.go 'dashboard' - .error (data) -> if data.code is 1 then vm.requestUserPassword() - - vm.connectAccounts = -> - $http.post LoopBackAdminConfiguration.urlBase + '/auth/social/connect-accounts', password: vm.credentials.password - .success (data) -> $state.go 'dashboard' - .error (data) -> vm.errorMessage = data - - vm.requestUserPassword = ($event) -> - $mdDialog.show - templateUrl: 'templates/modals/request-password.html' - targetEvent: $event - controller: 'SocialLoginCtrl' - return - - vm.requestUserEmail = ($event) -> - $mdDialog.show - templateUrl: 'templates/modals/request-email.html' - targetEvent: $event - controller: 'SocialLoginCtrl' - return - - return diff --git a/src/client/components/common/directives/social-login.directive.js b/src/client/components/common/directives/social-login.directive.js new file mode 100644 index 0000000..af5eac3 --- /dev/null +++ b/src/client/components/common/directives/social-login.directive.js @@ -0,0 +1,70 @@ +'use strict'; +angular.module('loopback-admin').directive('cmsSocialButtons', function () { + return { + restrict: 'E', + templateUrl: 'templates/common/social-buttons.tpl.html', + controller: 'SocialLoginCtrl', + controllerAs: 'social' + }; +}).controller('SocialLoginCtrl', function (LoopBackAdminConfiguration, LoopBackAuth, $http, $state, $mdDialog, $mdToast) { + var vm; + vm = this; + vm.credentials = {}; + vm.loginWith = function (service) { + var left, options, top, url; + url = LoopBackAdminConfiguration.urlBase + '/auth/social/' + service; + left = screen.width / 2 - (580 / 2); + top = screen.height / 2 - (450 / 2); + window.$tempScope = vm; + options = ['menubar=0', 'location=0', 'toolbar=0', 'titlebar=0', 'status=0', 'width=580', 'height=450', 'left=' + left, 'top=' + top].join(', '); + window.open(url, 'Authenticate Account', options); + }; + vm.socialLoginCallback = function (user) { + window.$tempScope = null; + if (user) { + LoopBackAuth.currentUserData = user; + $state.go('dashboard'); + } else { + vm.requestUserEmail(); + } + }; + vm.socialLoginCallbackError = function () { + $mdToast.show($mdToast.simple({ + position: 'bottom right' + }).content('genericSocialError')); + }; + vm.createAndLoginUser = function () { + return $http.post(LoopBackAdminConfiguration.urlBase + '/auth/social/request-email-callback', { + email: vm.credentials.email + }).success(function (data) { + return $state.go('dashboard'); + }).error(function (data) { + if (data.code === 1) { + return vm.requestUserPassword(); + } + }); + }; + vm.connectAccounts = function () { + return $http.post(LoopBackAdminConfiguration.urlBase + '/auth/social/connect-accounts', { + password: vm.credentials.password + }).success(function (data) { + return $state.go('dashboard'); + }).error(function (data) { + return vm.errorMessage = data; + }); + }; + vm.requestUserPassword = function ($event) { + $mdDialog.show({ + templateUrl: 'templates/modals/request-password.html', + targetEvent: $event, + controller: 'SocialLoginCtrl' + }); + }; + vm.requestUserEmail = function ($event) { + $mdDialog.show({ + templateUrl: 'templates/modals/request-email.html', + targetEvent: $event, + controller: 'SocialLoginCtrl' + }); + }; +}); diff --git a/src/client/components/common/factories/entry-formatter.service.coffee b/src/client/components/common/factories/entry-formatter.service.coffee deleted file mode 100644 index a0ff154..0000000 --- a/src/client/components/common/factories/entry-formatter.service.coffee +++ /dev/null @@ -1,70 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'entryFormatter', ($filter) -> - - formatDate: (format) -> - (date) -> $filter('date') new Date(date), format - - formatNumber: (format) -> - (number) -> $filter('numeraljs') number, format - - formatProperty: (property) -> - label = property.label or property.name - type = property.type - - switch type - when 'boolean', 'choice', 'choices', 'string', 'text', 'wysiwyg', 'email', 'json', 'file', 'template' - (entry) -> - name: label - value: entry.values[property.name] - - when 'number', 'float' - format = property.format - formatNumber = @formatNumber(format) - - (entry) -> - name: label - value: formatNumber(entry.values[property.name]) - - when 'date', 'datetime' - format = property.format - - if !format - format = if type == 'date' then 'yyyy-MM-dd' else 'yyyy-MM-dd HH:mm:ss' - - formatDate = @formatDate(format) - - (entry) -> - name: label - value: formatDate(entry.values[property.name]) - - when 'reference' - (entry) -> - name: label - value: entry.values[property.name] - - when 'referenced_many', 'referenced_list' - return - - return - - getFormatter: (properties) -> - propertiesFormatters = properties.map @formatProperty.bind(this) - - (entry) -> - result = {} - - propertiesFormatters - .map (formatter) -> - if !formatter - return - formatter entry - .forEach (property) -> - if !property - return - result[property.name] = property.value - return - - result \ No newline at end of file diff --git a/src/client/components/common/factories/entry-formatter.service.js b/src/client/components/common/factories/entry-formatter.service.js new file mode 100644 index 0000000..468d339 --- /dev/null +++ b/src/client/components/common/factories/entry-formatter.service.js @@ -0,0 +1,95 @@ +'use strict'; +angular.module('loopback-admin').factory('entryFormatter', function ($filter) { + return { + formatDate: function (format) { + return function (date) { + return $filter('date')(new Date(date), format); + }; + }, + formatNumber: function (format) { + return function (number) { + return $filter('numeraljs')(number, format); + }; + }, + formatProperty: function (property) { + var format, formatDate, formatNumber, label, type; + label = property.label || property.name; + type = property.type; + switch (type) { + case 'boolean': + case 'choice': + case 'choices': + case 'string': + case 'text': + case 'wysiwyg': + case 'email': + case 'json': + case 'file': + case 'template': + (function (entry) { + return { + name: label, + value: entry.values[property.name] + }; + }); + break; + case 'number': + case 'float': + format = property.format; + formatNumber = this.formatNumber(format); + (function (entry) { + return { + name: label, + value: formatNumber(entry.values[property.name]) + }; + }); + break; + case 'date': + case 'datetime': + format = property.format; + if (!format) { + format = type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'; + } + formatDate = this.formatDate(format); + (function (entry) { + return { + name: label, + value: formatDate(entry.values[property.name]) + }; + }); + break; + case 'reference': + (function (entry) { + return { + name: label, + value: entry.values[property.name] + }; + }); + break; + case 'referenced_many': + case 'referenced_list': + return; + } + }, + getFormatter: function (properties) { + var propertiesFormatters; + propertiesFormatters = properties.map(this.formatProperty.bind(this)); + return function (entry) { + var result; + result = {}; + propertiesFormatters.map(function (formatter) { + if (!formatter) { + return; + } + return formatter(entry); + }).forEach(function (property) { + if (!property) { + return; + } + result[property.name] = property.value; + }); + return result; + }; + } + }; +}); diff --git a/src/client/components/common/factories/loopback-injector.coffee b/src/client/components/common/factories/loopback-injector.coffee deleted file mode 100644 index ae7c5a0..0000000 --- a/src/client/components/common/factories/loopback-injector.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'LoopbackInjector', ($injector) -> - (modelName) -> - if $injector.has modelName - return $injector.get modelName - else - undefined \ No newline at end of file diff --git a/src/client/components/common/factories/loopback-injector.js b/src/client/components/common/factories/loopback-injector.js new file mode 100644 index 0000000..5973445 --- /dev/null +++ b/src/client/components/common/factories/loopback-injector.js @@ -0,0 +1,10 @@ +'use strict'; +angular.module('loopback-admin').factory('LoopbackInjector', function ($injector) { + return function (modelName) { + if ($injector.has(modelName)) { + return $injector.get(modelName); + } else { + return void 0; + } + }; +}); diff --git a/src/client/components/common/factories/string-utils.factory.coffee b/src/client/components/common/factories/string-utils.factory.coffee deleted file mode 100644 index 13a3762..0000000 --- a/src/client/components/common/factories/string-utils.factory.coffee +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.provider 'stringUtils', -> - camelCase: (text) -> - if !text - return text - - f = text.charAt(0).toUpperCase() - text = f + text.substr(1) - - return text.replace /[-_.\s](.)/g, (match, group1) -> - return ' ' + group1.toUpperCase() - - $get: -> camelCase: @camelCase diff --git a/src/client/components/common/factories/string-utils.factory.js b/src/client/components/common/factories/string-utils.factory.js new file mode 100644 index 0000000..9ac944c --- /dev/null +++ b/src/client/components/common/factories/string-utils.factory.js @@ -0,0 +1,21 @@ +'use strict'; +angular.module('loopback-admin').provider('stringUtils', function () { + return { + camelCase: function (text) { + var f; + if (!text) { + return text; + } + f = text.charAt(0).toUpperCase(); + text = f + text.substr(1); + return text.replace(/[-_.\s](.)/g, function (match, group1) { + return ' ' + group1.toUpperCase(); + }); + }, + $get: function () { + return { + camelCase: this.camelCase + }; + } + }; +}); diff --git a/src/client/components/common/filters/numberjs.filter.coffee b/src/client/components/common/filters/numberjs.filter.coffee deleted file mode 100644 index 2b32725..0000000 --- a/src/client/components/common/filters/numberjs.filter.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.filter 'numeraljs', -> - (input, format) -> - if input == null or format == null - return input - if format == '' - return '' - numeral(input).format format - diff --git a/src/client/components/common/filters/numberjs.filter.js b/src/client/components/common/filters/numberjs.filter.js new file mode 100644 index 0000000..38e4219 --- /dev/null +++ b/src/client/components/common/filters/numberjs.filter.js @@ -0,0 +1,12 @@ +'use strict'; +angular.module('loopback-admin').filter('numeraljs', function () { + return function (input, format) { + if (input === null || format === null) { + return input; + } + if (format === '') { + return ''; + } + return numeral(input).format(format); + }; +}); diff --git a/src/client/components/common/filters/text.coffee b/src/client/components/common/filters/text.coffee deleted file mode 100644 index 1786408..0000000 --- a/src/client/components/common/filters/text.coffee +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.filter 'modelToHuman', -> - (input = '') -> - input.replace /([a-z])([A-Z])/g, '$1 $2' diff --git a/src/client/components/common/filters/text.js b/src/client/components/common/filters/text.js new file mode 100644 index 0000000..59e624f --- /dev/null +++ b/src/client/components/common/filters/text.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').filter('modelToHuman', function () { + return function (input) { + if (input == null) { + input = ''; + } + return input.replace(/([a-z])([A-Z])/g, '$1 $2'); + }; +}); diff --git a/src/client/components/common/providers/config.provider.coffee b/src/client/components/common/providers/config.provider.coffee deleted file mode 100644 index 29388b8..0000000 --- a/src/client/components/common/providers/config.provider.coffee +++ /dev/null @@ -1,111 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.provider 'LoopBackAdminConfiguration', (LoopBackResourceProvider) -> - config = null - initialized = false - configOptions = null - - setConfig: (newConfig) -> - configOptions = newConfig - - $get: (Model, $q, $http, $injector) -> - - buildMenuFromModels = -> - application.models - .map (model) -> - name: model.label - state: "list" - params: - model: model.name - - application = - models: [] - - urlBase: LoopBackResourceProvider.getUrlBase() - - options: configOptions - - defaultErrorMessage: (response) -> - body = response.data - - if typeof body is 'object' - body = JSON.stringify(body) - - 'Oops, an error occured else (code: ' + response.status + ') ' + body - - errorMessage: @defaultErrorMessage - - getErrorMessage: (response) -> - if typeof(@errorMessage) is 'function' - return @errorMessage(response) - - @errorMessage - - userModel: $injector.get configOptions.userModel - userLoginField: configOptions.userLoginField - - addModel: (model) -> - if !model - throw new Error "No model given" - - foundModel = @getModelByName @models, model.name - - if not foundModel - @models.push model - - @ - - getModel: (modelName) -> - foundModel = @getModelByName @models, modelName - - if !foundModel - foundModel = @getModelByName @config.models, modelName - - if foundModel - foundModel = new Model modelName, foundModel - - @addModel foundModel - - return foundModel - - getModels: -> - defer = $q.defer() - - application.initialize().then (cfg) -> - defer.resolve cfg.models - - defer.promise - - getModelByName: (models, modelName) -> - models - .filter((e) -> e.name is modelName)[0] - - initialize: -> - defer = $q.defer() - - if initialized and application.models.length - defer.resolve application - else - if angular.isString configOptions.resourcePath - $http.get configOptions.resourcePath - .success (data) -> - { models } = data - - application.config = data - - for model in models - application.addModel new Model model.name, model - - application.menu = buildMenuFromModels() - - defer.resolve application - initialized = true - - .error (err) -> defer.reject err - else defer.resolve application - - defer.promise - - application \ No newline at end of file diff --git a/src/client/components/common/providers/config.provider.js b/src/client/components/common/providers/config.provider.js new file mode 100644 index 0000000..398a22e --- /dev/null +++ b/src/client/components/common/providers/config.provider.js @@ -0,0 +1,112 @@ +'use strict'; +angular.module('loopback-admin').provider('LoopBackAdminConfiguration', function (LoopBackResourceProvider) { + var config, configOptions, initialized; + config = null; + initialized = false; + configOptions = null; + return { + setConfig: function (newConfig) { + return configOptions = newConfig; + }, + $get: function (Model, $q, $http, $injector) { + var application, buildMenuFromModels; + buildMenuFromModels = function () { + return application.models.map(function (model) { + return { + name: model.label, + state: "list", + params: { + model: model.name + } + }; + }); + }; + application = { + models: [], + urlBase: LoopBackResourceProvider.getUrlBase(), + options: configOptions, + defaultErrorMessage: function (response) { + var body; + body = response.data; + if (typeof body === 'object') { + body = JSON.stringify(body); + } + return 'Oops, an error occured else (code: ' + response.status + ') ' + body; + }, + errorMessage: this.defaultErrorMessage, + getErrorMessage: function (response) { + if (typeof this.errorMessage === 'function') { + return this.errorMessage(response); + } + return this.errorMessage; + }, + userModel: $injector.get(configOptions.userModel), + userLoginField: configOptions.userLoginField, + addModel: function (model) { + var foundModel; + if (!model) { + throw new Error("No model given"); + } + foundModel = this.getModelByName(this.models, model.name); + if (!foundModel) { + this.models.push(model); + } + return this; + }, + getModel: function (modelName) { + var foundModel; + foundModel = this.getModelByName(this.models, modelName); + if (!foundModel) { + foundModel = this.getModelByName(this.config.models, modelName); + if (foundModel) { + foundModel = new Model(modelName, foundModel); + this.addModel(foundModel); + } + } + return foundModel; + }, + getModels: function () { + var defer; + defer = $q.defer(); + application.initialize().then(function (cfg) { + return defer.resolve(cfg.models); + }); + return defer.promise; + }, + getModelByName: function (models, modelName) { + return models.filter(function (e) { + return e.name === modelName; + })[0]; + }, + initialize: function () { + var defer; + defer = $q.defer(); + if (initialized && application.models.length) { + defer.resolve(application); + } else { + if (angular.isString(configOptions.resourcePath)) { + $http.get(configOptions.resourcePath).success(function (data) { + var i, len, model, models; + models = data.models; + application.config = data; + for (i = 0, len = models.length; i < len; i++) { + model = models[i]; + application.addModel(new Model(model.name, model)); + } + application.menu = buildMenuFromModels(); + defer.resolve(application); + return initialized = true; + }).error(function (err) { + return defer.reject(err); + }); + } else { + defer.resolve(application); + } + } + return defer.promise; + } + }; + return application; + } + }; +}); diff --git a/src/client/components/common/providers/text-strings.coffee b/src/client/components/common/providers/text-strings.coffee deleted file mode 100644 index 6141c15..0000000 --- a/src/client/components/common/providers/text-strings.coffee +++ /dev/null @@ -1,148 +0,0 @@ -angular.module 'loopback-admin' - -.filter 'text', (typedText, $log) -> - - filter = (input) -> - if typedText[input] - typedText[input] - else - $log.info 'text string missing: ' + input - 'MISSING ' + input - - filter.$stateful = true - - filter - -.constant 'typedText', - # landing page - homeTagline: 'Loopback Admin' - homeButtonText: 'Login now' - # Login Page - wrongCredentials: 'Wrong email address or password' - noAccount: 'Don\'t have an account?' - registerHere: 'Register here.' - login: 'Login' - password: 'Password' - email: 'Email' - enterYourTwitterEmail: 'Please enter your twitter email' - userWithEmailExists: 'User with this email already exists.' - enterYourPassword: 'Enter your password' - requestPassword: 'An account with this email address already exists, if you want to connect the two accounts please enter existing accounts password in the field below.' - wrongPassword: 'Password seems to be incorrect, please try again.' - connect: 'Connect' - genericSocialError: 'An error occured, please try again later.' - rememberMe: 'Remember me' - loginWithFacebook: 'Login with facebook' - loginWithTwitter: 'Login with twitter' - loginWithGoogle: 'Login with google' - orLoginWith: ' Or login with:' - - submit: 'Submit' - - # Modals - close: 'Close' - - # Register Page - alreadyHaveAccount: 'Already have an account?' - repeatPassword: 'Repeat Password' - logInHere: 'Login in here.' - register: 'Register' - - itemsSelected: 'Items Selected' - - upload: 'Upload' - cancel: 'Cancel' - create: 'Create' - 'new': 'New' - - searchResults: 'Search Results' - - items: 'Items' - created: 'Created' - description: 'Description' - none: 'None' - yes: 'Yes' - no: 'No' - - # Navbar - editUsername: 'Edit Username' - changeAvatar: 'Change Avatar' - logOut: 'Log Out' - accountSettings: 'Account Settings' - confirm: 'Confirm' - dashboard: 'Dashboard' - - # Account - username: 'Username' - fullName: 'Full Name' - firstName: 'First Name' - lastName: 'Last Name' - currentPassword: 'Current Password' - passwordChangeSuccess: 'Your password was changed successfully.' - avatarAcceptedFormats: 'Accepted formats: png, jpeg.' - avatarResizeExpl: 'Your avatar will be resized to 200x200 (px) if it\'s bigger then that.' - view: 'View' - - # Responses - genericError: 'something went wrong, please try again later.' - favoriteExists: 'You have already marked this photo as favorite.' - passMatches: 'Password is correct.' - passDoesntMatch: 'Incorrect password. Please try again.' - - profileUpdateSuccess: 'Your profile was updated successfully.' - avatarRemoveSuccess: 'Removed avatar successfully.' - permaDeletedItems: 'Permanently deleted {{ number }} items.' - - deleteItems: 'Delete Items' - sureWantToDeleteItems: 'Are you sure you want to delete these items?' - - createdUserSuccessfully: 'Created user successfully.' - updatedUserSuccessfully: 'Updated user successfully.' - settingsUpdated: 'Updated settings successfully.' - logOutSuccess: 'Logged out successfully.' - - deleteForever: 'Delete Forever' - confirmPermaDelete: 'Are you sure you want to permanently delete these photo(s)?' - 'delete': 'Delete' - permaDeleteWarning: 'Warning: this action is not undoable.' - - remove: 'Remove' - - addPassword: 'Add password.' - remove: 'Remove.' - add: 'Add' - done: 'Done' - - # Password reset - passwordRecovery: 'Password Recovery' - sendEmail: 'send Email' - change: 'Change' - passResetExpl: 'Please enter the email address associated with your account.' - resetPassword: 'Reset Password' - resetErrors: 'There were some problems with your input.' - emailAddress: 'E-Mail Address' - confirmPassword: 'Confirm Password' - newPassword: 'New Password' - forgot: 'Forgot?' - - # Invite - role: 'Role' - status: 'Status' - expiresIn: 'Expires In' - expiresAt: 'Expiry Date' - acceptedAt: 'Accepted Date' - - # Admin - users: 'Users' - deleted: 'Deleted' - search: 'search' - edit: 'Edit' - avatar: 'Avatar' - id: 'ID' - adminArea: 'Admin Area' - dashboardArea: 'Dashboard Area' - - # Titles - loginTitle: 'Login' - registerTitle: 'Register' - resetPasswordTitle: 'Reset Password' diff --git a/src/client/components/common/providers/text-strings.js b/src/client/components/common/providers/text-strings.js new file mode 100644 index 0000000..dac2cf2 --- /dev/null +++ b/src/client/components/common/providers/text-strings.js @@ -0,0 +1,115 @@ +angular.module('loopback-admin').filter('text', function (typedText, $log) { + var filter; + filter = function (input) { + if (typedText[input]) { + return typedText[input]; + } else { + $log.info('text string missing: ' + input); + return 'MISSING ' + input; + } + }; + filter.$stateful = true; + return filter; +}).constant('typedText', { + homeTagline: 'Loopback Admin', + homeButtonText: 'Login now', + wrongCredentials: 'Wrong email address or password', + noAccount: 'Don\'t have an account?', + registerHere: 'Register here.', + login: 'Login', + password: 'Password', + email: 'Email', + enterYourTwitterEmail: 'Please enter your twitter email', + userWithEmailExists: 'User with this email already exists.', + enterYourPassword: 'Enter your password', + requestPassword: 'An account with this email address already exists, if you want to connect the two accounts please enter existing accounts password in the field below.', + wrongPassword: 'Password seems to be incorrect, please try again.', + connect: 'Connect', + genericSocialError: 'An error occured, please try again later.', + rememberMe: 'Remember me', + loginWithFacebook: 'Login with facebook', + loginWithTwitter: 'Login with twitter', + loginWithGoogle: 'Login with google', + orLoginWith: ' Or login with:', + submit: 'Submit', + close: 'Close', + alreadyHaveAccount: 'Already have an account?', + repeatPassword: 'Repeat Password', + logInHere: 'Login in here.', + register: 'Register', + itemsSelected: 'Items Selected', + upload: 'Upload', + cancel: 'Cancel', + create: 'Create', + 'new': 'New', + searchResults: 'Search Results', + items: 'Items', + created: 'Created', + description: 'Description', + none: 'None', + yes: 'Yes', + no: 'No', + editUsername: 'Edit Username', + changeAvatar: 'Change Avatar', + logOut: 'Log Out', + accountSettings: 'Account Settings', + confirm: 'Confirm', + dashboard: 'Dashboard', + username: 'Username', + fullName: 'Full Name', + firstName: 'First Name', + lastName: 'Last Name', + currentPassword: 'Current Password', + passwordChangeSuccess: 'Your password was changed successfully.', + avatarAcceptedFormats: 'Accepted formats: png, jpeg.', + avatarResizeExpl: 'Your avatar will be resized to 200x200 (px) if it\'s bigger then that.', + view: 'View', + genericError: 'something went wrong, please try again later.', + favoriteExists: 'You have already marked this photo as favorite.', + passMatches: 'Password is correct.', + passDoesntMatch: 'Incorrect password. Please try again.', + profileUpdateSuccess: 'Your profile was updated successfully.', + avatarRemoveSuccess: 'Removed avatar successfully.', + permaDeletedItems: 'Permanently deleted {{ number }} items.', + deleteItems: 'Delete Items', + sureWantToDeleteItems: 'Are you sure you want to delete these items?', + createdUserSuccessfully: 'Created user successfully.', + updatedUserSuccessfully: 'Updated user successfully.', + settingsUpdated: 'Updated settings successfully.', + logOutSuccess: 'Logged out successfully.', + deleteForever: 'Delete Forever', + confirmPermaDelete: 'Are you sure you want to permanently delete these photo(s)?', + 'delete': 'Delete', + permaDeleteWarning: 'Warning: this action is not undoable.', + remove: 'Remove', + addPassword: 'Add password.', + remove: 'Remove.', + add: 'Add', + done: 'Done', + passwordRecovery: 'Password Recovery', + sendEmail: 'send Email', + change: 'Change', + passResetExpl: 'Please enter the email address associated with your account.', + resetPassword: 'Reset Password', + resetErrors: 'There were some problems with your input.', + emailAddress: 'E-Mail Address', + confirmPassword: 'Confirm Password', + newPassword: 'New Password', + forgot: 'Forgot?', + role: 'Role', + status: 'Status', + expiresIn: 'Expires In', + expiresAt: 'Expiry Date', + acceptedAt: 'Accepted Date', + users: 'Users', + deleted: 'Deleted', + search: 'search', + edit: 'Edit', + avatar: 'Avatar', + id: 'ID', + adminArea: 'Admin Area', + dashboardArea: 'Dashboard Area', + loginTitle: 'Login', + registerTitle: 'Register', + resetPasswordTitle: 'Reset Password' +}); diff --git a/src/client/components/common/run/error-handler.run.coffee b/src/client/components/common/run/error-handler.run.coffee deleted file mode 100644 index f62df1c..0000000 --- a/src/client/components/common/run/error-handler.run.coffee +++ /dev/null @@ -1,37 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.run ($state, $window, $rootScope, $log, LoopBackAdminConfiguration) -> - User = LoopBackAdminConfiguration.userModel - - $rootScope.$on '$stateChangeSuccess', -> - $window.scrollTo 0, 0 - - $rootScope.$on '$stateChangeError', (event, toState, toParams, fromState, fromParams, error) -> - if error.status is 404 - $state.go 'error' - event.preventDefault() - else if error.status is 401 - $state.go 'logout' - else - $log.error 'State change error: ' + error.message - throw error - - return - - $rootScope.$on '$stateChangeStart', ($event, toState, toParams, fromState, fromParams) -> - if !User.isAuthenticated() - if toState.name isnt 'login' and toState.name isnt 'register' and toState.name isnt 'landing' - $event.preventDefault() - - changeState = $state.go 'login' - - changeState.then -> - $rootScope.$broadcast '$stateChangeSuccess', toState.self, toParams, fromState.self, fromParams - return - - return true - true - - return diff --git a/src/client/components/common/run/error-handler.run.js b/src/client/components/common/run/error-handler.run.js new file mode 100644 index 0000000..108ce90 --- /dev/null +++ b/src/client/components/common/run/error-handler.run.js @@ -0,0 +1,33 @@ +'use strict'; +angular.module('loopback-admin').run(function ($state, $window, $rootScope, $log, LoopBackAdminConfiguration) { + var User; + User = LoopBackAdminConfiguration.userModel; + $rootScope.$on('$stateChangeSuccess', function () { + return $window.scrollTo(0, 0); + }); + $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) { + if (error.status === 404) { + $state.go('error'); + event.preventDefault(); + } else if (error.status === 401) { + $state.go('logout'); + } else { + $log.error('State change error: ' + error.message); + throw error; + } + }); + $rootScope.$on('$stateChangeStart', function ($event, toState, toParams, fromState, fromParams) { + var changeState; + if (!User.isAuthenticated()) { + if (toState.name !== 'login' && toState.name !== 'register' && toState.name !== 'landing') { + $event.preventDefault(); + changeState = $state.go('login'); + changeState.then(function () { + $rootScope.$broadcast('$stateChangeSuccess', toState.self, toParams, fromState.self, fromParams); + }); + } + return true; + } + return true; + }); +}); diff --git a/src/client/components/common/run/loader.run.coffee b/src/client/components/common/run/loader.run.coffee deleted file mode 100644 index d173b99..0000000 --- a/src/client/components/common/run/loader.run.coffee +++ /dev/null @@ -1,40 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.run ($rootScope, $mdDialog, $mdToast) -> - - $rootScope.closeModal = -> - $mdDialog.hide() - - $rootScope.getAvatar = (user) -> - if user.avatar_url - return user.avatar_url - - 'images/avatar.png' - - $rootScope.showToast = (message, theme = 'default') -> - toast = $mdToast.simple - position: 'bottom right' - hideDelay: 2200 - - toast.content(message).theme(theme) - - $mdToast.show toast - - return - - $rootScope.confirm = (options) -> - dialog = $mdDialog.confirm() - .title options.title - .textContent options.body - .ariaLabel 'Confirm dialog.' - .targetEvent options.event - .ok 'Okay' - .cancel 'Cancel' - - $mdDialog.show dialog - - return - - diff --git a/src/client/components/common/run/loader.run.js b/src/client/components/common/run/loader.run.js new file mode 100644 index 0000000..b86bf3b --- /dev/null +++ b/src/client/components/common/run/loader.run.js @@ -0,0 +1,29 @@ +'use strict'; +angular.module('loopback-admin').run(function ($rootScope, $mdDialog, $mdToast) { + $rootScope.closeModal = function () { + return $mdDialog.hide(); + }; + $rootScope.getAvatar = function (user) { + if (user.avatar_url) { + return user.avatar_url; + } + return 'images/avatar.png'; + }; + $rootScope.showToast = function (message, theme) { + var toast; + if (theme == null) { + theme = 'default'; + } + toast = $mdToast.simple({ + position: 'bottom right', + hideDelay: 2200 + }); + toast.content(message).theme(theme); + $mdToast.show(toast); + }; + $rootScope.confirm = function (options) { + var dialog; + dialog = $mdDialog.confirm().title(options.title).textContent(options.body).ariaLabel('Confirm dialog.').targetEvent(options.event).ok('Okay').cancel('Cancel'); + return $mdDialog.show(dialog); + }; +}); diff --git a/src/client/components/common/services/colors.service.coffee b/src/client/components/common/services/colors.service.coffee deleted file mode 100644 index 23fb9ce..0000000 --- a/src/client/components/common/services/colors.service.coffee +++ /dev/null @@ -1,185 +0,0 @@ -angular.module 'loopback-admin' - -.provider '$mdColors', ($mdColorPalette) -> - style = angular.element '' - - document.head.appendChild style[0] - - stylesheet = style[0].sheet - index = 0 - - colorToRgbaArray = (clr) -> - if angular.isArray(clr) and clr.length == 3 - return clr - - if /^rgb/.test(clr) - return clr.replace(/(^\s*rgba?\(|\)\s*$)/g, '').split(',').map (value, i) -> - if i == 3 then parseFloat(value, 10) else parseInt(value, 10) - - if clr.charAt(0) == '#' - clr = clr.substring(1) - - if !/^([a-fA-F0-9]{3}){1,2}$/g.test(clr) - return - - dig = clr.length / 3 - - red = clr.substr(0, dig) - grn = clr.substr(dig, dig) - blu = clr.substr(dig * 2) - - if dig == 1 - red += red - grn += grn - blu += blu - - [ parseInt(red, 16), parseInt(grn, 16), parseInt(blu, 16) ] - - DARK_CONTRAST_COLOR = colorToRgbaArray 'rgba(0,0,0,0.87)' - LIGHT_CONTRAST_COLOR = colorToRgbaArray 'rgba(255,255,255,0.87' - STRONG_LIGHT_CONTRAST_COLOR = colorToRgbaArray 'rgb(255,255,255)' - - addCustomStyle = (cssname, name, color, contrast = '') -> - if contrast - contrast = "color: #{contrast}" - - stylesheet.insertRule ".md-#{cssname}-#{name}.text { color: #{color} !important }", index - stylesheet.insertRule ".md-#{cssname}-#{name}.background { background-color: #{color}; #{contrast} }", index + 1 - - index += 2 - - return - - clearStyleSheet = -> - while stylesheet.cssRules.length > 0 - stylesheet.deleteRule 0 - - colorNames: [] - colorStore: {} - - colorSelected: null - - themeNames: [] - themeStore: {} - - getContrastColor: (palette) -> - { contrastDefaultColor, lightColors, strongLightColors, darkColors } = palette - - if angular.isString lightColors - lightColors = lightColors.split ' ' - - if angular.isString strongLightColors - strongLightColors = strongLightColors.split ' ' - - if angular.isString darkColors - darkColors = darkColors.split ' ' - - if contrastDefaultColor is 'light' - if darkColors?.indexOf(hueName) > -1 - DARK_CONTRAST_COLOR - else - if strongLightColors?.indexOf(hueName) > -1 - STRONG_LIGHT_CONTRAST_COLOR - else - LIGHT_CONTRAST_COLOR - else - if lightColors?.indexOf(hueName) > -1 - if strongLightColors?.indexOf(hueName) > -1 - STRONG_LIGHT_CONTRAST_COLOR - else - LIGHT_CONTRAST_COLOR - else - DARK_CONTRAST_COLOR - - storeAndLoadPalettes: (colors, themes, primaryPalette) -> - @colorStore = colors - @themeStore = themes - - @colorNames = Object.keys colors - @themeNames = Object.keys themes - - @loadPalette primaryPalette - - loadPalette: (newPalette) -> - if @colorSelected - clearStyleSheet() - - @colorSelected = newPalette - - for themeName, theme of @themeStore - cleanedThemeName = if themeName is 'default' then '' else themeName + '-' - - for groupName, group of theme - for name, color of group - addCustomStyle cleanedThemeName + groupName, name, color.value, color.contrast - - return - - $get: -> - colorNames: @colorNames - colorStore: @colorStore - - colorSelected: @colorSelected - - themeNames: @themeNames - themeStore: @themeStore - - loadPalette: @loadPalette - -.config ($mdThemingProvider, $mdColorsProvider) -> - colorStore = {} - - parsePalette = (paletteName, palette) -> - paletteContrast = $mdThemingProvider._rgba $mdColorsProvider.getContrastColor palette - hueColors = $mdThemingProvider._THEMES['default'].colors['primary'].hues - - colors = {} - - addHue = (hueName) -> - colors[hueName] = value: palette[hueColors[hueName]], contrast: paletteContrast - - copyColors = (colorName, color) -> - if /#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\b/.test(palette[colorName]) - colors[colorName] = value: palette[colorName], contrast: paletteContrast - return - - colorStore[paletteName] = colors - - Object.keys(palette).forEach copyColors - Object.keys(hueColors).forEach addHue - - return - - for paletteName, palette of $mdThemingProvider._PALETTES - parsePalette paletteName, palette - - themeStore = {} - - parseTheme = (themeName) -> - themeColorGroups = $mdThemingProvider._THEMES[themeName].colors - - colors = {} - - defineColors = (themeGroup) -> - themeStore[themeName][themeGroup] ?= {} - - definedColors = colorStore[themeColorGroups[themeGroup].name] - - for item, value of themeColorGroups[themeGroup].hues - themeStore[themeName][themeGroup][item] = definedColors[value] - - return - - themeStore[themeName] ?= {} - - Object.keys(themeColorGroups).forEach defineColors - - return - - Object.keys($mdThemingProvider._THEMES).forEach parseTheme - - primaryPalette = $mdThemingProvider._THEMES['default'].colors.primary.name - - $mdColorsProvider.storeAndLoadPalettes colorStore, themeStore, primaryPalette - - return diff --git a/src/client/components/common/services/colors.service.js b/src/client/components/common/services/colors.service.js new file mode 100644 index 0000000..f902d89 --- /dev/null +++ b/src/client/components/common/services/colors.service.js @@ -0,0 +1,193 @@ +angular.module('loopback-admin').provider('$mdColors', function ($mdColorPalette) { + var DARK_CONTRAST_COLOR, LIGHT_CONTRAST_COLOR, STRONG_LIGHT_CONTRAST_COLOR, addCustomStyle, clearStyleSheet, colorToRgbaArray, index, style, stylesheet; + style = angular.element(''); + document.head.appendChild(style[0]); + stylesheet = style[0].sheet; + index = 0; + colorToRgbaArray = function (clr) { + var blu, dig, grn, red; + if (angular.isArray(clr) && clr.length === 3) { + return clr; + } + if (/^rgb/.test(clr)) { + return clr.replace(/(^\s*rgba?\(|\)\s*$)/g, '').split(',').map(function (value, i) { + if (i === 3) { + return parseFloat(value, 10); + } else { + return parseInt(value, 10); + } + }); + } + if (clr.charAt(0) === '#') { + clr = clr.substring(1); + } + if (!/^([a-fA-F0-9]{3}){1,2}$/g.test(clr)) { + return; + } + dig = clr.length / 3; + red = clr.substr(0, dig); + grn = clr.substr(dig, dig); + blu = clr.substr(dig * 2); + if (dig === 1) { + red += red; + grn += grn; + blu += blu; + } + return [parseInt(red, 16), parseInt(grn, 16), parseInt(blu, 16)]; + }; + DARK_CONTRAST_COLOR = colorToRgbaArray('rgba(0,0,0,0.87)'); + LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgba(255,255,255,0.87'); + STRONG_LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgb(255,255,255)'); + addCustomStyle = function (cssname, name, color, contrast) { + if (contrast == null) { + contrast = ''; + } + if (contrast) { + contrast = "color: " + contrast; + } + stylesheet.insertRule(".md-" + cssname + "-" + name + ".text { color: " + color + " !important }", index); + stylesheet.insertRule(".md-" + cssname + "-" + name + ".background { background-color: " + color + "; " + contrast + " }", index + 1); + index += 2; + }; + clearStyleSheet = function () { + var results; + results = []; + while (stylesheet.cssRules.length > 0) { + results.push(stylesheet.deleteRule(0)); + } + return results; + }; + return { + colorNames: [], + colorStore: {}, + colorSelected: null, + themeNames: [], + themeStore: {}, + getContrastColor: function (palette) { + var contrastDefaultColor, darkColors, lightColors, strongLightColors; + contrastDefaultColor = palette.contrastDefaultColor, lightColors = palette.lightColors, strongLightColors = palette.strongLightColors, darkColors = palette.darkColors; + if (angular.isString(lightColors)) { + lightColors = lightColors.split(' '); + } + if (angular.isString(strongLightColors)) { + strongLightColors = strongLightColors.split(' '); + } + if (angular.isString(darkColors)) { + darkColors = darkColors.split(' '); + } + if (contrastDefaultColor === 'light') { + if ((darkColors != null ? darkColors.indexOf(hueName) : void 0) > -1) { + return DARK_CONTRAST_COLOR; + } else { + if ((strongLightColors != null ? strongLightColors.indexOf(hueName) : void 0) > -1) { + return STRONG_LIGHT_CONTRAST_COLOR; + } else { + return LIGHT_CONTRAST_COLOR; + } + } + } else { + if ((lightColors != null ? lightColors.indexOf(hueName) : void 0) > -1) { + if ((strongLightColors != null ? strongLightColors.indexOf(hueName) : void 0) > -1) { + return STRONG_LIGHT_CONTRAST_COLOR; + } else { + return LIGHT_CONTRAST_COLOR; + } + } else { + return DARK_CONTRAST_COLOR; + } + } + }, + storeAndLoadPalettes: function (colors, themes, primaryPalette) { + this.colorStore = colors; + this.themeStore = themes; + this.colorNames = Object.keys(colors); + this.themeNames = Object.keys(themes); + return this.loadPalette(primaryPalette); + }, + loadPalette: function (newPalette) { + var cleanedThemeName, color, group, groupName, name, ref, theme, themeName; + if (this.colorSelected) { + clearStyleSheet(); + } + this.colorSelected = newPalette; + ref = this.themeStore; + for (themeName in ref) { + theme = ref[themeName]; + cleanedThemeName = themeName === 'default' ? '' : themeName + '-'; + for (groupName in theme) { + group = theme[groupName]; + for (name in group) { + color = group[name]; + addCustomStyle(cleanedThemeName + groupName, name, color.value, color.contrast); + } + } + } + }, + $get: function () { + return { + colorNames: this.colorNames, + colorStore: this.colorStore, + colorSelected: this.colorSelected, + themeNames: this.themeNames, + themeStore: this.themeStore, + loadPalette: this.loadPalette + }; + } + }; +}).config(function ($mdThemingProvider, $mdColorsProvider) { + var colorStore, palette, paletteName, parsePalette, parseTheme, primaryPalette, ref, themeStore; + colorStore = {}; + parsePalette = function (paletteName, palette) { + var addHue, colors, copyColors, hueColors, paletteContrast; + paletteContrast = $mdThemingProvider._rgba($mdColorsProvider.getContrastColor(palette)); + hueColors = $mdThemingProvider._THEMES['default'].colors['primary'].hues; + colors = {}; + addHue = function (hueName) { + return colors[hueName] = { + value: palette[hueColors[hueName]], + contrast: paletteContrast + }; + }; + copyColors = function (colorName, color) { + if (/#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\b/.test(palette[colorName])) { + colors[colorName] = { + value: palette[colorName], + contrast: paletteContrast + }; + } + }; + colorStore[paletteName] = colors; + Object.keys(palette).forEach(copyColors); + Object.keys(hueColors).forEach(addHue); + }; + ref = $mdThemingProvider._PALETTES; + for (paletteName in ref) { + palette = ref[paletteName]; + parsePalette(paletteName, palette); + } + themeStore = {}; + parseTheme = function (themeName) { + var colors, defineColors, themeColorGroups; + themeColorGroups = $mdThemingProvider._THEMES[themeName].colors; + colors = {}; + defineColors = function (themeGroup) { + var base, definedColors, item, ref1, value; + if ((base = themeStore[themeName])[themeGroup] == null) { + base[themeGroup] = {}; + } + definedColors = colorStore[themeColorGroups[themeGroup].name]; + ref1 = themeColorGroups[themeGroup].hues; + for (item in ref1) { + value = ref1[item]; + themeStore[themeName][themeGroup][item] = definedColors[value]; + } + }; + if (themeStore[themeName] == null) { + themeStore[themeName] = {}; + } + Object.keys(themeColorGroups).forEach(defineColors); + }; + Object.keys($mdThemingProvider._THEMES).forEach(parseTheme); + primaryPalette = $mdThemingProvider._THEMES['default'].colors.primary.name; + $mdColorsProvider.storeAndLoadPalettes(colorStore, themeStore, primaryPalette); +}); diff --git a/src/client/components/common/services/flickr-background.service.coffee b/src/client/components/common/services/flickr-background.service.coffee deleted file mode 100644 index c17add3..0000000 --- a/src/client/components/common/services/flickr-background.service.coffee +++ /dev/null @@ -1,40 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'Flickr', ($q, $http, LoopBackAdminConfiguration) -> - { flickrApiKey } = LoopBackAdminConfiguration.options - - baseUrl = 'https://api.flickr.com/services/rest/?' - - params = [ - 'method=flickr.groups.pools.getPhotos' - 'group_id=1463451@N25' - 'safe_search=1' - 'jsoncallback=JSON_CALLBACK' - "api_key=#{ flickrApiKey }" - 'format=json' - ].join '&' - - getBackgroundImage: -> - defer = $q.defer() - - if flickrApiKey - $http.get('http://freegeoip.net/json/').success (data) -> - { longitude, latitude, region_name } = data - - optParams = "&tags=#{region_name}&lat=#{latitude}&lng=#{longitude}&extras=url_l" - - $http.jsonp(baseUrl + params + optParams, cache: true).success (resp) -> - photos = resp.photos - - if photos.photo.length - images = photos.photo - image = images[Math.floor(Math.random() * images.length)] - - defer.resolve image: 'url(' + image.url_l + ')', title: image.title - else defer.resolve() - - else defer.resolve image: "url('./images/background.png')" - - defer.promise diff --git a/src/client/components/common/services/flickr-background.service.js b/src/client/components/common/services/flickr-background.service.js new file mode 100644 index 0000000..bea006e --- /dev/null +++ b/src/client/components/common/services/flickr-background.service.js @@ -0,0 +1,41 @@ +'use strict'; +angular.module('loopback-admin').factory('Flickr', function ($q, $http, LoopBackAdminConfiguration) { + var baseUrl, flickrApiKey, params; + flickrApiKey = LoopBackAdminConfiguration.options.flickrApiKey; + baseUrl = 'https://api.flickr.com/services/rest/?'; + params = ['method=flickr.groups.pools.getPhotos', 'group_id=1463451@N25', 'safe_search=1', 'jsoncallback=JSON_CALLBACK', "api_key=" + flickrApiKey, 'format=json'].join('&'); + return { + getBackgroundImage: function () { + var defer; + defer = $q.defer(); + if (flickrApiKey) { + $http.get('http://freegeoip.net/json/').success(function (data) { + var latitude, longitude, optParams, region_name; + longitude = data.longitude, latitude = data.latitude, region_name = data.region_name; + optParams = "&tags=" + region_name + "&lat=" + latitude + "&lng=" + longitude + "&extras=url_l"; + return $http.jsonp(baseUrl + params + optParams, { + cache: true + }).success(function (resp) { + var image, images, photos; + photos = resp.photos; + if (photos.photo.length) { + images = photos.photo; + image = images[Math.floor(Math.random() * images.length)]; + return defer.resolve({ + image: 'url(' + image.url_l + ')', + title: image.title + }); + } else { + return defer.resolve(); + } + }); + }); + } else { + defer.resolve({ + image: "url('./images/background.png')" + }); + } + return defer.promise; + } + }; +}); diff --git a/src/client/components/data/model.factory.coffee b/src/client/components/data/model.factory.coffee deleted file mode 100644 index bd94d45..0000000 --- a/src/client/components/data/model.factory.coffee +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'Model', ($injector, stringUtils, $log, Property, PropertyTypeConfiguration, LoopbackInjector) -> - - class Model - constructor: (name, model) -> - @name = name - @label = stringUtils.camelCase @name - - @properties = [] - - @propertyNames = [] - @relationNames = [] - - @resource = LoopbackInjector name - - for key, value of model when key not in [ 'properties', 'relations' ] - @[key] = value - - @constructProperties model.properties - @constructRelations model.relations - - constructRelations: (modelRelations) -> - _propertyTypes = PropertyTypeConfiguration - - if modelRelations - Object.keys(modelRelations).forEach (relationName) => - relation = modelRelations[relationName] - - if relation?.foreignKey - @relationNames.push relationName - - if _propertyTypes[relation.type] - propertyConstructor = $injector.get _propertyTypes[relation.type] - - @properties.push new propertyConstructor relationName, relation - else - $log.warn 'no such type defined for', relation.type, relation - - return - - constructProperties: (modelProperties) -> - _propertyTypes = PropertyTypeConfiguration - - if modelProperties - Object.keys(modelProperties).forEach (propertyName) => - property = modelProperties[propertyName] - - if Object.keys(property).length - if property.id - @identifier = new Property propertyName - - if _propertyTypes[(property.type).toLowerCase()] - @propertyNames.push propertyName - propertyConstructor = $injector.get _propertyTypes[(property.type).toLowerCase()] - - @properties.push new propertyConstructor propertyName, property - else - $log.warn 'no such type defined for', property.type, property - - return diff --git a/src/client/components/data/model.factory.js b/src/client/components/data/model.factory.js new file mode 100644 index 0000000..d28c67b --- /dev/null +++ b/src/client/components/data/model.factory.js @@ -0,0 +1,73 @@ +'use strict'; +angular.module('loopback-admin').factory('Model', function ($injector, stringUtils, $log, Property, PropertyTypeConfiguration, LoopbackInjector) { + var Model; + return Model = (function () { + function Model(name, model) { + var key, value; + this.name = name; + this.label = stringUtils.camelCase(this.name); + this.properties = []; + this.propertyNames = []; + this.relationNames = []; + this.resource = LoopbackInjector(name); + for (key in model) { + value = model[key]; + if (key !== 'properties' && key !== 'relations') { + this[key] = value; + } + } + this.constructProperties(model.properties); + this.constructRelations(model.relations); + } + + Model.prototype.constructRelations = function (modelRelations) { + var _propertyTypes; + _propertyTypes = PropertyTypeConfiguration; + if (modelRelations) { + Object.keys(modelRelations).forEach((function (_this) { + return function (relationName) { + var propertyConstructor, relation; + relation = modelRelations[relationName]; + if (relation != null ? relation.foreignKey : void 0) { + _this.relationNames.push(relationName); + } + if (_propertyTypes[relation.type]) { + propertyConstructor = $injector.get(_propertyTypes[relation.type]); + return _this.properties.push(new propertyConstructor(relationName, relation)); + } else { + return $log.warn('no such type defined for', relation.type, relation); + } + }; + })(this)); + } + }; + + Model.prototype.constructProperties = function (modelProperties) { + var _propertyTypes; + _propertyTypes = PropertyTypeConfiguration; + if (modelProperties) { + Object.keys(modelProperties).forEach((function (_this) { + return function (propertyName) { + var property, propertyConstructor; + property = modelProperties[propertyName]; + if (Object.keys(property).length) { + if (property.id) { + _this.identifier = new Property(propertyName); + } + if (_propertyTypes[property.type.toLowerCase()]) { + _this.propertyNames.push(propertyName); + propertyConstructor = $injector.get(_propertyTypes[property.type.toLowerCase()]); + return _this.properties.push(new propertyConstructor(propertyName, property)); + } else { + return $log.warn('no such type defined for', property.type, property); + } + } + }; + })(this)); + } + }; + + return Model; + + })(); +}); diff --git a/src/client/components/property/property.config.coffee b/src/client/components/property/property.config.coffee deleted file mode 100644 index 0739623..0000000 --- a/src/client/components/property/property.config.coffee +++ /dev/null @@ -1,43 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.provider 'PropertyTypeConfiguration', ($injector) -> - propertyTypes = {} - - registerPropertyType: (type, PropertyType) -> - if type is 'string' or type is 'objectid' - PropertyType = '' - - propertyTypes[type] = PropertyType + 'Property' - - $get: -> propertyTypes - -.provider 'PropertyViewConfiguration', (PropertyTypeConfigurationProvider, stringUtilsProvider) -> - { camelCase } = stringUtilsProvider - { registerPropertyType } = PropertyTypeConfigurationProvider - - propertyViews = {} - - registerAlias: (alias, type) -> - if propertyViews[type] - propertyViews[alias] = propertyViews[type] - registerPropertyType alias, camelCase type - else - console.warn 'no such type defined for', type, alias - - registerPropertyView: (type, PropertyView) -> - propertyViews[type] = PropertyView - registerPropertyType type, camelCase type - - return - - $get: -> propertyViews - -.run ($templateCache, PropertyViewConfiguration) -> - - Object.keys(PropertyViewConfiguration).forEach (propertyName) -> - propery = PropertyViewConfiguration[propertyName] - - $templateCache.put propertyName + '-column', propery.column - $templateCache.put propertyName + '-field', propery.field \ No newline at end of file diff --git a/src/client/components/property/property.config.js b/src/client/components/property/property.config.js new file mode 100644 index 0000000..af51d8f --- /dev/null +++ b/src/client/components/property/property.config.js @@ -0,0 +1,45 @@ +'use strict'; +angular.module('loopback-admin').provider('PropertyTypeConfiguration', function ($injector) { + var propertyTypes; + propertyTypes = {}; + return { + registerPropertyType: function (type, PropertyType) { + if (type === 'string' || type === 'objectid') { + PropertyType = ''; + } + return propertyTypes[type] = PropertyType + 'Property'; + }, + $get: function () { + return propertyTypes; + } + }; +}).provider('PropertyViewConfiguration', function (PropertyTypeConfigurationProvider, stringUtilsProvider) { + var camelCase, propertyViews, registerPropertyType; + camelCase = stringUtilsProvider.camelCase; + registerPropertyType = PropertyTypeConfigurationProvider.registerPropertyType; + propertyViews = {}; + return { + registerAlias: function (alias, type) { + if (propertyViews[type]) { + propertyViews[alias] = propertyViews[type]; + return registerPropertyType(alias, camelCase(type)); + } else { + return console.warn('no such type defined for', type, alias); + } + }, + registerPropertyView: function (type, PropertyView) { + propertyViews[type] = PropertyView; + registerPropertyType(type, camelCase(type)); + }, + $get: function () { + return propertyViews; + } + }; +}).run(function ($templateCache, PropertyViewConfiguration) { + return Object.keys(PropertyViewConfiguration).forEach(function (propertyName) { + var propery; + propery = PropertyViewConfiguration[propertyName]; + $templateCache.put(propertyName + '-column', propery.column); + return $templateCache.put(propertyName + '-field', propery.field); + }); +}); diff --git a/src/client/components/property/property.directive.coffee b/src/client/components/property/property.directive.coffee deleted file mode 100644 index 0bf9fec..0000000 --- a/src/client/components/property/property.directive.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbProperty', -> - restrict: 'E' - scope: - property: '=' - row: '=' - model: '=' - errorMessages: '=' - form: '=' - template: """
""" diff --git a/src/client/components/property/property.directive.js b/src/client/components/property/property.directive.js new file mode 100644 index 0000000..5834cf5 --- /dev/null +++ b/src/client/components/property/property.directive.js @@ -0,0 +1,14 @@ +'use strict'; +angular.module('loopback-admin').directive('lbProperty', function () { + return { + restrict: 'E', + scope: { + property: '=', + row: '=', + model: '=', + errorMessages: '=', + form: '=' + }, + template: "
" + }; +}); diff --git a/src/client/components/property/property.factory.coffee b/src/client/components/property/property.factory.coffee deleted file mode 100644 index db295f7..0000000 --- a/src/client/components/property/property.factory.coffee +++ /dev/null @@ -1,23 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'Property', (stringUtils) -> - class Property - constructor: (name, property = {}) -> - @default = null - - @name = name or Math.random().toString(36).substring(7) - @label = stringUtils.camelCase @name - - @type = "string" - - @validation = - required: false - minlength: 0 - maxlength: 99999 - - for own key, value of property - @[key] = value - - @type = @type.toLowerCase() diff --git a/src/client/components/property/property.factory.js b/src/client/components/property/property.factory.js new file mode 100644 index 0000000..3d37f36 --- /dev/null +++ b/src/client/components/property/property.factory.js @@ -0,0 +1,32 @@ +'use strict'; +var hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('Property', function (stringUtils) { + var Property; + return Property = (function () { + function Property(name, property) { + var key, value; + if (property == null) { + property = {}; + } + this["default"] = null; + this.name = name || Math.random().toString(36).substring(7); + this.label = stringUtils.camelCase(this.name); + this.type = "string"; + this.validation = { + required: false, + minlength: 0, + maxlength: 99999 + }; + for (key in property) { + if (!hasProp.call(property, key)) continue; + value = property[key]; + this[key] = value; + } + this.type = this.type.toLowerCase(); + } + + return Property; + + })(); +}); diff --git a/src/client/components/property/types/belongs-to/belongs-to.config.coffee b/src/client/components/property/types/belongs-to/belongs-to.config.coffee deleted file mode 100644 index 865315a..0000000 --- a/src/client/components/property/types/belongs-to/belongs-to.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'belongsTo', - column: null, - field: '' \ No newline at end of file diff --git a/src/client/components/property/types/belongs-to/belongs-to.config.js b/src/client/components/property/types/belongs-to/belongs-to.config.js new file mode 100644 index 0000000..be3136b --- /dev/null +++ b/src/client/components/property/types/belongs-to/belongs-to.config.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('belongsTo', { + column: null, + field: '' + }); +}); diff --git a/src/client/components/property/types/belongs-to/belongs-to.directive.coffee b/src/client/components/property/types/belongs-to/belongs-to.directive.coffee deleted file mode 100644 index b3d5ad4..0000000 --- a/src/client/components/property/types/belongs-to/belongs-to.directive.coffee +++ /dev/null @@ -1,30 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbBelongsToProperty', -> - scope: - property: '=' - value: '=' - form: '=' - errorMessages: '=' - templateUrl: 'templates/property/belongs-to.tpl.html' - restrict: 'E' - link: (scope, element) -> - property = scope.property - - scope.model = property.getModel() - - { resource } = scope.model - - scope.count = 0 - scope.rows = [] - - for value in scope.value - scope.rows.push new resource value - scope.count++ - - scope.name = property.name - scope.v = property.validation - - return \ No newline at end of file diff --git a/src/client/components/property/types/belongs-to/belongs-to.directive.js b/src/client/components/property/types/belongs-to/belongs-to.directive.js new file mode 100644 index 0000000..74d11b6 --- /dev/null +++ b/src/client/components/property/types/belongs-to/belongs-to.directive.js @@ -0,0 +1,29 @@ +'use strict'; +angular.module('loopback-admin').directive('lbBelongsToProperty', function () { + return { + scope: { + property: '=', + value: '=', + form: '=', + errorMessages: '=' + }, + templateUrl: 'templates/property/belongs-to.tpl.html', + restrict: 'E', + link: function (scope, element) { + var i, len, property, ref, resource, value; + property = scope.property; + scope.model = property.getModel(); + resource = scope.model.resource; + scope.count = 0; + scope.rows = []; + ref = scope.value; + for (i = 0, len = ref.length; i < len; i++) { + value = ref[i]; + scope.rows.push(new resource(value)); + scope.count++; + } + scope.name = property.name; + scope.v = property.validation; + } + }; +}); diff --git a/src/client/components/property/types/belongs-to/belongs-to.factory.coffee b/src/client/components/property/types/belongs-to/belongs-to.factory.coffee deleted file mode 100644 index 748e166..0000000 --- a/src/client/components/property/types/belongs-to/belongs-to.factory.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'BelongsToProperty', (Property, LoopBackAdminConfiguration) -> - class BelongsToProperty extends Property - constructor: (name, property) -> - super name, property - - @type = "belongsTo" - - getModel: -> - LoopBackAdminConfiguration.getModel @model diff --git a/src/client/components/property/types/belongs-to/belongs-to.factory.js b/src/client/components/property/types/belongs-to/belongs-to.factory.js new file mode 100644 index 0000000..0c6dfb7 --- /dev/null +++ b/src/client/components/property/types/belongs-to/belongs-to.factory.js @@ -0,0 +1,34 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('BelongsToProperty', function (Property, LoopBackAdminConfiguration) { + var BelongsToProperty; + return BelongsToProperty = (function (superClass) { + extend(BelongsToProperty, superClass); + + function BelongsToProperty(name, property) { + BelongsToProperty.__super__.constructor.call(this, name, property); + this.type = "belongsTo"; + } + + BelongsToProperty.prototype.getModel = function () { + return LoopBackAdminConfiguration.getModel(this.model); + }; + + return BelongsToProperty; + + })(Property); +}); diff --git a/src/client/components/property/types/boolean/boolean.config.coffee b/src/client/components/property/types/boolean/boolean.config.coffee deleted file mode 100644 index da93e61..0000000 --- a/src/client/components/property/types/boolean/boolean.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'boolean', - column: '', - field: '' \ No newline at end of file diff --git a/src/client/components/property/types/boolean/boolean.config.js b/src/client/components/property/types/boolean/boolean.config.js new file mode 100644 index 0000000..c94ab79 --- /dev/null +++ b/src/client/components/property/types/boolean/boolean.config.js @@ -0,0 +1,24 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('boolean', { + column: '', + field: '' + }); +}); diff --git a/src/client/components/property/types/boolean/boolean.factory.coffee b/src/client/components/property/types/boolean/boolean.factory.coffee deleted file mode 100644 index 2a43b2b..0000000 --- a/src/client/components/property/types/boolean/boolean.factory.coffee +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'BooleanProperty', (ChoiceProperty) -> - class BooleanProperty extends ChoiceProperty - constructor: (name, property) -> - super name, property - - @type = "boolean" - - @choices = [ - { value: null, label: 'undefined' }, - { value: true, label: 'true' }, - { value: false, label: 'false' } - ] - diff --git a/src/client/components/property/types/boolean/boolean.factory.js b/src/client/components/property/types/boolean/boolean.factory.js new file mode 100644 index 0000000..ef2de4b --- /dev/null +++ b/src/client/components/property/types/boolean/boolean.factory.js @@ -0,0 +1,28 @@ +'use strict'; + +angular.module('loopback-admin').factory('BooleanProperty', function (ChoiceProperty) { + var BooleanProperty; + return BooleanProperty = (function (superClass) { + extend(BooleanProperty, superClass); + + function BooleanProperty(name, property) { + BooleanProperty.__super__.constructor.call(this, name, property); + this.type = "boolean"; + this.choices = [ + { + value: null, + label: 'undefined' + }, { + value: true, + label: 'true' + }, { + value: false, + label: 'false' + } + ]; + } + + return BooleanProperty; + + })(ChoiceProperty); +}); diff --git a/src/client/components/property/types/checkbox/checkbox.directive.coffee b/src/client/components/property/types/checkbox/checkbox.directive.coffee deleted file mode 100644 index ced4dfc..0000000 --- a/src/client/components/property/types/checkbox/checkbox.directive.coffee +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbCheckboxProperty', -> - scope: - property: '=' - value: '=' - restrict: 'E' - templateUrl: 'templates/property/checkbox.tpl.html' - link: (scope, element) -> - property = scope.property - - scope.name = property.name - scope.v = property.validation - - scope.value = ! !scope.value - - return diff --git a/src/client/components/property/types/checkbox/checkbox.directive.js b/src/client/components/property/types/checkbox/checkbox.directive.js new file mode 100644 index 0000000..fb24daa --- /dev/null +++ b/src/client/components/property/types/checkbox/checkbox.directive.js @@ -0,0 +1,18 @@ +'use strict'; +angular.module('loopback-admin').directive('lbCheckboxProperty', function () { + return { + scope: { + property: '=', + value: '=' + }, + restrict: 'E', + templateUrl: 'templates/property/checkbox.tpl.html', + link: function (scope, element) { + var property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + scope.value = !!scope.value; + } + }; +}); diff --git a/src/client/components/property/types/choice/choice.config.coffee b/src/client/components/property/types/choice/choice.config.coffee deleted file mode 100644 index 9a0b841..0000000 --- a/src/client/components/property/types/choice/choice.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'choice', - column: '', - field: '' diff --git a/src/client/components/property/types/choice/choice.config.js b/src/client/components/property/types/choice/choice.config.js new file mode 100644 index 0000000..8b0c981 --- /dev/null +++ b/src/client/components/property/types/choice/choice.config.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('choice', { + column: '', + field: '' + }); +}); diff --git a/src/client/components/property/types/choice/choice.directive.coffee b/src/client/components/property/types/choice/choice.directive.coffee deleted file mode 100644 index 36367fe..0000000 --- a/src/client/components/property/types/choice/choice.directive.coffee +++ /dev/null @@ -1,40 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbChoiceProperty', -> - scope: - property: '=' - value: '=' - row: '=?' - restrict: 'E' - templateUrl: 'templates/property/choice.tpl.html' - compile: -> - pre: (scope, element) -> - property = scope.property - - scope.name = property.name - scope.v = property.validation - - scope.$watch 'value', (newValue, oldValue) -> - if newValue != oldValue and newValue == undefined - scope.value = null - return - - choices = if property.choices then property.choices else [] - - scope.choices = if typeof choices is 'function' then choices(scope.row) else choices - - return - post: (scope) -> - updateChoices = (choices) -> - scope.choices = choices - scope.$root.$$phase or scope.$digest() - - listener = scope.$on 'choices:update', (e, data) -> - updateChoices data.choices - - scope.$on '$destroy', -> - listener() - - return diff --git a/src/client/components/property/types/choice/choice.directive.js b/src/client/components/property/types/choice/choice.directive.js new file mode 100644 index 0000000..0b05308 --- /dev/null +++ b/src/client/components/property/types/choice/choice.directive.js @@ -0,0 +1,42 @@ +'use strict'; +angular.module('loopback-admin').directive('lbChoiceProperty', function () { + return { + scope: { + property: '=', + value: '=', + row: '=?' + }, + restrict: 'E', + templateUrl: 'templates/property/choice.tpl.html', + compile: function () { + return { + pre: function (scope, element) { + var choices, property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + scope.$watch('value', function (newValue, oldValue) { + if (newValue !== oldValue && newValue === void 0) { + scope.value = null; + } + }); + choices = property.choices ? property.choices : []; + scope.choices = typeof choices === 'function' ? choices(scope.row) : choices; + }, + post: function (scope) { + var listener, updateChoices; + updateChoices = function (choices) { + scope.choices = choices; + return scope.$root.$$phase || scope.$digest(); + }; + listener = scope.$on('choices:update', function (e, data) { + return updateChoices(data.choices); + }); + scope.$on('$destroy', function () { + return listener(); + }); + } + }; + } + }; +}); diff --git a/src/client/components/property/types/choice/choice.factory.coffee b/src/client/components/property/types/choice/choice.factory.coffee deleted file mode 100644 index c287ecc..0000000 --- a/src/client/components/property/types/choice/choice.factory.coffee +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'ChoiceProperty', (Property) -> - class ChoiceProperty extends Property - constructor: (name, property) -> - super name, property - - @type = "choice" - @choices = [] - - return - - getLabelForChoice: (value, row) -> - choices = if typeof(@choices) is 'function' then @choices(row) else @choices - - choice = choices - .filter (c) -> c.value is value - .pop() - - if choice - choice.label - else null - diff --git a/src/client/components/property/types/choice/choice.factory.js b/src/client/components/property/types/choice/choice.factory.js new file mode 100644 index 0000000..e1dcc46 --- /dev/null +++ b/src/client/components/property/types/choice/choice.factory.js @@ -0,0 +1,45 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('ChoiceProperty', function (Property) { + var ChoiceProperty; + return ChoiceProperty = (function (superClass) { + extend(ChoiceProperty, superClass); + + function ChoiceProperty(name, property) { + ChoiceProperty.__super__.constructor.call(this, name, property); + this.type = "choice"; + this.choices = []; + return; + } + + ChoiceProperty.prototype.getLabelForChoice = function (value, row) { + var choice, choices; + choices = typeof this.choices === 'function' ? this.choices(row) : this.choices; + choice = choices.filter(function (c) { + return c.value === value; + }).pop(); + if (choice) { + return choice.label; + } else { + return null; + } + }; + + return ChoiceProperty; + + })(Property); +}); diff --git a/src/client/components/property/types/choices/choices-required.directive.coffee b/src/client/components/property/types/choices/choices-required.directive.coffee deleted file mode 100644 index 85a7f02..0000000 --- a/src/client/components/property/types/choices/choices-required.directive.coffee +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'uiSelectRequired', -> - restrict: 'A' - require: 'ngModel' - link: (scope, elm, attrs, ctrl) -> - - ctrl.$validators.uiSelectRequired = (modelValue, viewValue) -> - if angular.isArray(modelValue) - determineVal = modelValue - else if angular.isArray(viewValue) - determineVal = viewValue - else return false - - determineVal.length > 0 - - return diff --git a/src/client/components/property/types/choices/choices-required.directive.js b/src/client/components/property/types/choices/choices-required.directive.js new file mode 100644 index 0000000..e2e8570 --- /dev/null +++ b/src/client/components/property/types/choices/choices-required.directive.js @@ -0,0 +1,20 @@ +'use strict'; +angular.module('loopback-admin').directive('uiSelectRequired', function () { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, elm, attrs, ctrl) { + ctrl.$validators.uiSelectRequired = function (modelValue, viewValue) { + var determineVal; + if (angular.isArray(modelValue)) { + determineVal = modelValue; + } else if (angular.isArray(viewValue)) { + determineVal = viewValue; + } else { + return false; + } + return determineVal.length > 0; + }; + } + }; +}); diff --git a/src/client/components/property/types/choices/choices.config.coffee b/src/client/components/property/types/choices/choices.config.coffee deleted file mode 100644 index 394ca5b..0000000 --- a/src/client/components/property/types/choices/choices.config.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'choices', - column: '', - field: '' - - fvp.registerAlias 'array', 'choices' \ No newline at end of file diff --git a/src/client/components/property/types/choices/choices.config.js b/src/client/components/property/types/choices/choices.config.js new file mode 100644 index 0000000..080c2d8 --- /dev/null +++ b/src/client/components/property/types/choices/choices.config.js @@ -0,0 +1,10 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + fvp.registerPropertyView('choices', { + column: '', + field: '' + }); + return fvp.registerAlias('array', 'choices'); +}); diff --git a/src/client/components/property/types/choices/choices.directive.coffee b/src/client/components/property/types/choices/choices.directive.coffee deleted file mode 100644 index f49d597..0000000 --- a/src/client/components/property/types/choices/choices.directive.coffee +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbChoicesProperty', ($compile, $templateCache) -> - scope: - property: '=' - value: '=' - row: '=?' - restrict: 'E' - templateUrl: 'templates/property/choices.tpl.html' - compile: -> - pre: (scope, element) -> - property = scope.property - - scope.name = property.name - scope.v = property.validation - - choices = if property.choices then property.choices else [] - - scope.choices = if typeof choices == 'function' then choices(scope.row) else choices - - post: (scope) -> - listener = scope.$on 'choices:update', (e, data) -> - scope.scope.choices = data.choices - scope.$root.$$phase or scope.$digest() - - scope.$on '$destroy', -> - listener() - - return diff --git a/src/client/components/property/types/choices/choices.directive.js b/src/client/components/property/types/choices/choices.directive.js new file mode 100644 index 0000000..a346391 --- /dev/null +++ b/src/client/components/property/types/choices/choices.directive.js @@ -0,0 +1,34 @@ +'use strict'; +angular.module('loopback-admin').directive('lbChoicesProperty', function ($compile, $templateCache) { + return { + scope: { + property: '=', + value: '=', + row: '=?' + }, + restrict: 'E', + templateUrl: 'templates/property/choices.tpl.html', + compile: function () { + return { + pre: function (scope, element) { + var choices, property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + choices = property.choices ? property.choices : []; + return scope.choices = typeof choices === 'function' ? choices(scope.row) : choices; + }, + post: function (scope) { + var listener; + listener = scope.$on('choices:update', function (e, data) { + scope.scope.choices = data.choices; + return scope.$root.$$phase || scope.$digest(); + }); + scope.$on('$destroy', function () { + return listener(); + }); + } + }; + } + }; +}); diff --git a/src/client/components/property/types/choices/choices.factory.coffee b/src/client/components/property/types/choices/choices.factory.coffee deleted file mode 100644 index 45945ad..0000000 --- a/src/client/components/property/types/choices/choices.factory.coffee +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'ChoicesProperty', (ChoiceProperty) -> - class ChoicesProperty extends ChoiceProperty - constructor: (name, property) -> - super name, property - - @type = "choices" - diff --git a/src/client/components/property/types/choices/choices.factory.js b/src/client/components/property/types/choices/choices.factory.js new file mode 100644 index 0000000..20a4444 --- /dev/null +++ b/src/client/components/property/types/choices/choices.factory.js @@ -0,0 +1,18 @@ +'use strict'; +var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('ChoicesProperty', function(ChoiceProperty) { + var ChoicesProperty; + return ChoicesProperty = (function(superClass) { + extend(ChoicesProperty, superClass); + + function ChoicesProperty(name, property) { + ChoicesProperty.__super__.constructor.call(this, name, property); + this.type = "choices"; + } + + return ChoicesProperty; + + })(ChoiceProperty); +}); \ No newline at end of file diff --git a/src/client/components/property/types/date/date.config.coffee b/src/client/components/property/types/date/date.config.coffee deleted file mode 100644 index e670601..0000000 --- a/src/client/components/property/types/date/date.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'date', - column: '', - field: '' diff --git a/src/client/components/property/types/date/date.config.js b/src/client/components/property/types/date/date.config.js new file mode 100644 index 0000000..1b509df --- /dev/null +++ b/src/client/components/property/types/date/date.config.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('date', { + column: '', + field: '' + }); +}); diff --git a/src/client/components/property/types/date/date.directive.coffee b/src/client/components/property/types/date/date.directive.coffee deleted file mode 100644 index e6b263a..0000000 --- a/src/client/components/property/types/date/date.directive.coffee +++ /dev/null @@ -1,23 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbDateProperty', -> - scope: - property: '=' - value: '=' - restrict: 'E' - templateUrl: 'templates/property/date.tpl.html' - link: (scope, element) -> - property = scope.property - - scope.name = property.name - scope.rawValue = scope.value - - scope.$watch 'rawValue', (rawValue) -> - scope.value = property.parse(rawValue) - return - - scope.v = property.validation - - return diff --git a/src/client/components/property/types/date/date.directive.js b/src/client/components/property/types/date/date.directive.js new file mode 100644 index 0000000..7fea178 --- /dev/null +++ b/src/client/components/property/types/date/date.directive.js @@ -0,0 +1,21 @@ +'use strict'; +angular.module('loopback-admin').directive('lbDateProperty', function () { + return { + scope: { + property: '=', + value: '=' + }, + restrict: 'E', + templateUrl: 'templates/property/date.tpl.html', + link: function (scope, element) { + var property; + property = scope.property; + scope.name = property.name; + scope.rawValue = scope.value; + scope.$watch('rawValue', function (rawValue) { + scope.value = property.parse(rawValue); + }); + scope.v = property.validation; + } + }; +}); diff --git a/src/client/components/property/types/date/date.factory.coffee b/src/client/components/property/types/date/date.factory.coffee deleted file mode 100644 index 4359c32..0000000 --- a/src/client/components/property/types/date/date.factory.coffee +++ /dev/null @@ -1,34 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'DateProperty', (Property) -> - class DateProperty extends Property - constructor: (name, property) -> - super name, property - - @format = null - - @parse = (date = null) -> - if date instanceof Date - return date - else if angular.isString date - return new Date date - else null - - @type = "date" - - return - -.factory 'DateTimeProperty', (DateProperty) -> - class DateTimeProperty extends DateProperty - constructor: (name, property) -> - super name, property - - @format = null - - @parse = (date) -> - return date - - @type = 'datetime' - diff --git a/src/client/components/property/types/date/date.factory.js b/src/client/components/property/types/date/date.factory.js new file mode 100644 index 0000000..abc9d3f --- /dev/null +++ b/src/client/components/property/types/date/date.factory.js @@ -0,0 +1,61 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('DateProperty', function (Property) { + var DateProperty; + return DateProperty = (function (superClass) { + extend(DateProperty, superClass); + + function DateProperty(name, property) { + DateProperty.__super__.constructor.call(this, name, property); + this.format = null; + this.parse = function (date) { + if (date == null) { + date = null; + } + if (date instanceof Date) { + return date; + } else if (angular.isString(date)) { + return new Date(date); + } else { + return null; + } + }; + this.type = "date"; + return; + } + + return DateProperty; + + })(Property); +}).factory('DateTimeProperty', function (DateProperty) { + var DateTimeProperty; + return DateTimeProperty = (function (superClass) { + extend(DateTimeProperty, superClass); + + function DateTimeProperty(name, property) { + DateTimeProperty.__super__.constructor.call(this, name, property); + this.format = null; + this.parse = function (date) { + return date; + }; + this.type = 'datetime'; + } + + return DateTimeProperty; + + })(DateProperty); +}); diff --git a/src/client/components/property/types/float/float.config.coffee b/src/client/components/property/types/float/float.config.coffee deleted file mode 100644 index 3e4f45b..0000000 --- a/src/client/components/property/types/float/float.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'float', - column: '', - field: '' diff --git a/src/client/components/property/types/float/float.config.js b/src/client/components/property/types/float/float.config.js new file mode 100644 index 0000000..7329ddc --- /dev/null +++ b/src/client/components/property/types/float/float.config.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('float', { + column: '', + field: '' + }); +}); diff --git a/src/client/components/property/types/float/float.factory.coffee b/src/client/components/property/types/float/float.factory.coffee deleted file mode 100644 index 36e1498..0000000 --- a/src/client/components/property/types/float/float.factory.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'FloatProperty', (NumberProperty) -> - class FloatProperty extends NumberProperty - constructor: (name, property) -> - super name, property - - @type = 'float' - - @format = '0.000' - diff --git a/src/client/components/property/types/float/float.factory.js b/src/client/components/property/types/float/float.factory.js new file mode 100644 index 0000000..2e72a4e --- /dev/null +++ b/src/client/components/property/types/float/float.factory.js @@ -0,0 +1,31 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('FloatProperty', function (NumberProperty) { + var FloatProperty; + return FloatProperty = (function (superClass) { + extend(FloatProperty, superClass); + + function FloatProperty(name, property) { + FloatProperty.__super__.constructor.call(this, name, property); + this.type = 'float'; + this.format = '0.000'; + } + + return FloatProperty; + + })(NumberProperty); +}); diff --git a/src/client/components/property/types/has-many/has-many.config.coffee b/src/client/components/property/types/has-many/has-many.config.coffee deleted file mode 100644 index 3dfa9a4..0000000 --- a/src/client/components/property/types/has-many/has-many.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'hasMany', - column: '', - field: '' diff --git a/src/client/components/property/types/has-many/has-many.config.js b/src/client/components/property/types/has-many/has-many.config.js new file mode 100644 index 0000000..c3cd9be --- /dev/null +++ b/src/client/components/property/types/has-many/has-many.config.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('hasMany', { + column: '', + field: '' + }); +}); diff --git a/src/client/components/property/types/has-many/has-many.directive.coffee b/src/client/components/property/types/has-many/has-many.directive.coffee deleted file mode 100644 index e8f8f55..0000000 --- a/src/client/components/property/types/has-many/has-many.directive.coffee +++ /dev/null @@ -1,30 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbHasManyProperty', -> - scope: - property: '=' - value: '=' - form: '=' - errorMessages: '=' - templateUrl: 'templates/property/has-many.tpl.html' - restrict: 'E' - link: (scope, element) -> - property = scope.property - - scope.model = property.getModel() - - resource = scope.model.resource - - scope.count = 0 - scope.rows = [] - - for value in scope.value - scope.rows.push new resource value - scope.count++ - - scope.name = property.name - scope.v = property.validation - - return \ No newline at end of file diff --git a/src/client/components/property/types/has-many/has-many.directive.js b/src/client/components/property/types/has-many/has-many.directive.js new file mode 100644 index 0000000..cb312cc --- /dev/null +++ b/src/client/components/property/types/has-many/has-many.directive.js @@ -0,0 +1,29 @@ +'use strict'; +angular.module('loopback-admin').directive('lbHasManyProperty', function () { + return { + scope: { + property: '=', + value: '=', + form: '=', + errorMessages: '=' + }, + templateUrl: 'templates/property/has-many.tpl.html', + restrict: 'E', + link: function (scope, element) { + var i, len, property, ref, resource, value; + property = scope.property; + scope.model = property.getModel(); + resource = scope.model.resource; + scope.count = 0; + scope.rows = []; + ref = scope.value; + for (i = 0, len = ref.length; i < len; i++) { + value = ref[i]; + scope.rows.push(new resource(value)); + scope.count++; + } + scope.name = property.name; + scope.v = property.validation; + } + }; +}); diff --git a/src/client/components/property/types/has-many/has-many.factory.coffee b/src/client/components/property/types/has-many/has-many.factory.coffee deleted file mode 100644 index 717c0e7..0000000 --- a/src/client/components/property/types/has-many/has-many.factory.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'HasManyProperty', (Property, LoopBackAdminConfiguration) -> - class HasManyProperty extends Property - constructor: (name, property) -> - super name, property - - @type = "hasMany" - - getModel: -> - LoopBackAdminConfiguration.getModel @model diff --git a/src/client/components/property/types/has-many/has-many.factory.js b/src/client/components/property/types/has-many/has-many.factory.js new file mode 100644 index 0000000..74ea629 --- /dev/null +++ b/src/client/components/property/types/has-many/has-many.factory.js @@ -0,0 +1,34 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('HasManyProperty', function (Property, LoopBackAdminConfiguration) { + var HasManyProperty; + return HasManyProperty = (function (superClass) { + extend(HasManyProperty, superClass); + + function HasManyProperty(name, property) { + HasManyProperty.__super__.constructor.call(this, name, property); + this.type = "hasMany"; + } + + HasManyProperty.prototype.getModel = function () { + return LoopBackAdminConfiguration.getModel(this.model); + }; + + return HasManyProperty; + + })(Property); +}); diff --git a/src/client/components/property/types/input/input.config.coffee b/src/client/components/property/types/input/input.config.coffee deleted file mode 100644 index 60698a4..0000000 --- a/src/client/components/property/types/input/input.config.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'string', - column: '', - field: '' - - fvp.registerAlias 'objectid', 'string' diff --git a/src/client/components/property/types/input/input.config.js b/src/client/components/property/types/input/input.config.js new file mode 100644 index 0000000..123e329 --- /dev/null +++ b/src/client/components/property/types/input/input.config.js @@ -0,0 +1,10 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + fvp.registerPropertyView('string', { + column: '', + field: '' + }); + return fvp.registerAlias('objectid', 'string'); +}); diff --git a/src/client/components/property/types/input/input.directive.coffee b/src/client/components/property/types/input/input.directive.coffee deleted file mode 100644 index 48cb2d7..0000000 --- a/src/client/components/property/types/input/input.directive.coffee +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbInputProperty', -> - scope: - property: '=' - value: '=' - form: '=' - errorMessages: '=' - templateUrl: 'templates/property/input.tpl.html' - restrict: 'E' - link: (scope, element) -> - property = scope.property - - scope.name = property.name - scope.v = property.validation - - return \ No newline at end of file diff --git a/src/client/components/property/types/input/input.directive.js b/src/client/components/property/types/input/input.directive.js new file mode 100644 index 0000000..e87ebd2 --- /dev/null +++ b/src/client/components/property/types/input/input.directive.js @@ -0,0 +1,19 @@ +'use strict'; +angular.module('loopback-admin').directive('lbInputProperty', function () { + return { + scope: { + property: '=', + value: '=', + form: '=', + errorMessages: '=' + }, + templateUrl: 'templates/property/input.tpl.html', + restrict: 'E', + link: function (scope, element) { + var property; + property = scope.property; + scope.name = property.name; + scope.v = property.validation; + } + }; +}); diff --git a/src/client/components/property/types/number/number.config.coffee b/src/client/components/property/types/number/number.config.coffee deleted file mode 100644 index 6592779..0000000 --- a/src/client/components/property/types/number/number.config.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config (PropertyViewConfigurationProvider) -> - fvp = PropertyViewConfigurationProvider - - fvp.registerPropertyView 'number', - column: '', - field: '' diff --git a/src/client/components/property/types/number/number.config.js b/src/client/components/property/types/number/number.config.js new file mode 100644 index 0000000..b188705 --- /dev/null +++ b/src/client/components/property/types/number/number.config.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('loopback-admin').config(function (PropertyViewConfigurationProvider) { + var fvp; + fvp = PropertyViewConfigurationProvider; + return fvp.registerPropertyView('number', { + column: '', + field: '' + }); +}); diff --git a/src/client/components/property/types/number/number.factory.coffee b/src/client/components/property/types/number/number.factory.coffee deleted file mode 100644 index 396c51a..0000000 --- a/src/client/components/property/types/number/number.factory.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.factory 'NumberProperty', (Property) -> - class NumberProperty extends Property - constructor: (name, property) -> - super name, property - - @type = "number" - - @format = undefined diff --git a/src/client/components/property/types/number/number.factory.js b/src/client/components/property/types/number/number.factory.js new file mode 100644 index 0000000..21ecfa4 --- /dev/null +++ b/src/client/components/property/types/number/number.factory.js @@ -0,0 +1,31 @@ +'use strict'; +var extend = function (child, parent) { + for (var key in parent) { + if (hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + hasProp = {}.hasOwnProperty; + +angular.module('loopback-admin').factory('NumberProperty', function (Property) { + var NumberProperty; + return NumberProperty = (function (superClass) { + extend(NumberProperty, superClass); + + function NumberProperty(name, property) { + NumberProperty.__super__.constructor.call(this, name, property); + this.type = "number"; + this.format = void 0; + } + + return NumberProperty; + + })(Property); +}); diff --git a/src/client/components/routing/app/app.config.coffee b/src/client/components/routing/app/app.config.coffee deleted file mode 100644 index d73f472..0000000 --- a/src/client/components/routing/app/app.config.coffee +++ /dev/null @@ -1,27 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - .state 'app', - abstract: true - template: '
' - resolve: - user: (LoopBackAdminConfiguration) -> - User = LoopBackAdminConfiguration.userModel - - User.getCurrent().$promise - config: (user, LoopBackAdminConfiguration) -> - LoopBackAdminConfiguration.initialize() - - .state 'browser', - parent: 'app' - abstract: true - controller: 'BrowserController' - controllerAs: 'browserController' - templateUrl: "templates/routing/browser.tpl.html" - resolve: - config: (LoopBackAdminConfiguration) -> - LoopBackAdminConfiguration.initialize() diff --git a/src/client/components/routing/app/app.config.js b/src/client/components/routing/app/app.config.js new file mode 100644 index 0000000..3fa28c7 --- /dev/null +++ b/src/client/components/routing/app/app.config.js @@ -0,0 +1,28 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('app', { + abstract: true, + template: '
', + resolve: { + user: function (LoopBackAdminConfiguration) { + var User; + User = LoopBackAdminConfiguration.userModel; + return User.getCurrent().$promise; + }, + config: function (user, LoopBackAdminConfiguration) { + return LoopBackAdminConfiguration.initialize(); + } + } + }).state('browser', { + parent: 'app', + abstract: true, + controller: 'BrowserController', + controllerAs: 'browserController', + templateUrl: "templates/routing/browser.tpl.html", + resolve: { + config: function (LoopBackAdminConfiguration) { + return LoopBackAdminConfiguration.initialize(); + } + } + }); +}); diff --git a/src/client/components/routing/app/app.controller.coffee b/src/client/components/routing/app/app.controller.coffee deleted file mode 100644 index 5f04db4..0000000 --- a/src/client/components/routing/app/app.controller.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'BrowserController', ($scope, $state, LoopBackAdminConfiguration) -> - vm = this - - application = LoopBackAdminConfiguration - - vm.menu = application.menu - - return \ No newline at end of file diff --git a/src/client/components/routing/app/app.controller.js b/src/client/components/routing/app/app.controller.js new file mode 100644 index 0000000..90c14a6 --- /dev/null +++ b/src/client/components/routing/app/app.controller.js @@ -0,0 +1,7 @@ +'use strict'; +angular.module('loopback-admin').controller('BrowserController', function ($scope, $state, LoopBackAdminConfiguration) { + var application, vm; + vm = this; + application = LoopBackAdminConfiguration; + vm.menu = application.menu; +}); diff --git a/src/client/components/routing/ban/ban.config.js b/src/client/components/routing/ban/ban.config.js new file mode 100644 index 0000000..79db1ac --- /dev/null +++ b/src/client/components/routing/ban/ban.config.js @@ -0,0 +1,15 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + $stateProvider.state('ban', { + url: '/baneados', + parent: 'browser', + controller: 'BanController', + controllerAs: 'banController', + templateUrl: 'templates/routing/ban.tpl.html', + resolve: { + model: function (config) { + return config.getModel('BanReport'); + } + } + }); +}); diff --git a/src/client/components/routing/ban/ban.controller.js b/src/client/components/routing/ban/ban.controller.js new file mode 100644 index 0000000..3638dce --- /dev/null +++ b/src/client/components/routing/ban/ban.controller.js @@ -0,0 +1,6 @@ +'use strict'; +angular.module('loopback-admin').controller('ListController', function (model) { + var vm; + vm = this; + vm.model = model; +}); diff --git a/src/client/components/routing/dashboard/dashboard.config.coffee b/src/client/components/routing/dashboard/dashboard.config.coffee deleted file mode 100644 index e6b4a2d..0000000 --- a/src/client/components/routing/dashboard/dashboard.config.coffee +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'dashboard', - parent: 'browser' - url: '/dashboard' - controller: 'DashboardController' - controllerAs: 'dashboardController' - templateUrl: "templates/routing/dashboard.tpl.html" - resolve: - models: (config) -> - config.getModels() diff --git a/src/client/components/routing/dashboard/dashboard.config.js b/src/client/components/routing/dashboard/dashboard.config.js new file mode 100644 index 0000000..5325b43 --- /dev/null +++ b/src/client/components/routing/dashboard/dashboard.config.js @@ -0,0 +1,15 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('dashboard', { + parent: 'browser', + url: '/dashboard', + controller: 'DashboardController', + controllerAs: 'dashboardController', + templateUrl: "templates/routing/dashboard.tpl.html", + resolve: { + models: function (config) { + return config.getModels(); + } + } + }); +}); diff --git a/src/client/components/routing/dashboard/dashboard.controller.coffee b/src/client/components/routing/dashboard/dashboard.controller.coffee deleted file mode 100644 index 7b2f3c8..0000000 --- a/src/client/components/routing/dashboard/dashboard.controller.coffee +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'DashboardController', (models) -> - vm = this - - vm.models = models - - return - diff --git a/src/client/components/routing/dashboard/dashboard.controller.js b/src/client/components/routing/dashboard/dashboard.controller.js new file mode 100644 index 0000000..e40253b --- /dev/null +++ b/src/client/components/routing/dashboard/dashboard.controller.js @@ -0,0 +1,6 @@ +'use strict'; +angular.module('loopback-admin').controller('DashboardController', function (models) { + var vm; + vm = this; + vm.models = models; +}); diff --git a/src/client/components/routing/error/error.config.coffee b/src/client/components/routing/error/error.config.coffee deleted file mode 100644 index f0f10ae..0000000 --- a/src/client/components/routing/error/error.config.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'error', - parent: 'app' - templateUrl: 'templates/routing/error.tpl.html' - onEnter: (config, $log, $state) -> - $log.error config, $state diff --git a/src/client/components/routing/error/error.config.js b/src/client/components/routing/error/error.config.js new file mode 100644 index 0000000..224e085 --- /dev/null +++ b/src/client/components/routing/error/error.config.js @@ -0,0 +1,10 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('error', { + parent: 'app', + templateUrl: 'templates/routing/error.tpl.html', + onEnter: function (config, $log, $state) { + return $log.error(config, $state); + } + }); +}); diff --git a/src/client/components/routing/landing/landing.config.coffee b/src/client/components/routing/landing/landing.config.coffee deleted file mode 100644 index 39b14cc..0000000 --- a/src/client/components/routing/landing/landing.config.coffee +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'landing', - url: '/landing' - templateUrl: "templates/routing/landing-page.tpl.html" - controller: 'LandingPageController' - controllerAs: 'landing' - resolve: - background: (Flickr) -> - Flickr.getBackgroundImage() diff --git a/src/client/components/routing/landing/landing.config.js b/src/client/components/routing/landing/landing.config.js new file mode 100644 index 0000000..cf07094 --- /dev/null +++ b/src/client/components/routing/landing/landing.config.js @@ -0,0 +1,14 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('landing', { + url: '/landing', + templateUrl: "templates/routing/landing-page.tpl.html", + controller: 'LandingPageController', + controllerAs: 'landing', + resolve: { + background: function (Flickr) { + return Flickr.getBackgroundImage(); + } + } + }); +}); diff --git a/src/client/components/routing/landing/landing.controller.coffee b/src/client/components/routing/landing/landing.controller.coffee deleted file mode 100644 index fd920b9..0000000 --- a/src/client/components/routing/landing/landing.controller.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'LandingPageController', (background) -> - vm = this - - vm.background = background - - return diff --git a/src/client/components/routing/landing/landing.controller.js b/src/client/components/routing/landing/landing.controller.js new file mode 100644 index 0000000..0d2c9e8 --- /dev/null +++ b/src/client/components/routing/landing/landing.controller.js @@ -0,0 +1,6 @@ +'use strict'; +angular.module('loopback-admin').controller('LandingPageController', function (background) { + var vm; + vm = this; + vm.background = background; +}); diff --git a/src/client/components/routing/list/list.config.coffee b/src/client/components/routing/list/list.config.coffee deleted file mode 100644 index 7f280ad..0000000 --- a/src/client/components/routing/list/list.config.coffee +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'list', - url: '/:model/list' - parent: 'browser' - controller: 'ListController' - controllerAs: 'listController' - templateUrl: 'templates/routing/list.tpl.html' - resolve: - model: (config, $stateParams) -> - config.getModel $stateParams.model - - return diff --git a/src/client/components/routing/list/list.config.js b/src/client/components/routing/list/list.config.js new file mode 100644 index 0000000..b23cb52 --- /dev/null +++ b/src/client/components/routing/list/list.config.js @@ -0,0 +1,15 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + $stateProvider.state('list', { + url: '/:model/list', + parent: 'browser', + controller: 'ListController', + controllerAs: 'listController', + templateUrl: 'templates/routing/list.tpl.html', + resolve: { + model: function (config, $stateParams) { + return config.getModel($stateParams.model); + } + } + }); +}); diff --git a/src/client/components/routing/list/list.controller.coffee b/src/client/components/routing/list/list.controller.coffee deleted file mode 100644 index 7281951..0000000 --- a/src/client/components/routing/list/list.controller.coffee +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'ListController', (model) -> - vm = this - - vm.model = model - - return - diff --git a/src/client/components/routing/list/list.controller.js b/src/client/components/routing/list/list.controller.js new file mode 100644 index 0000000..3638dce --- /dev/null +++ b/src/client/components/routing/list/list.controller.js @@ -0,0 +1,6 @@ +'use strict'; +angular.module('loopback-admin').controller('ListController', function (model) { + var vm; + vm = this; + vm.model = model; +}); diff --git a/src/client/components/routing/login/login.config.coffee b/src/client/components/routing/login/login.config.coffee deleted file mode 100644 index 239fd66..0000000 --- a/src/client/components/routing/login/login.config.coffee +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'login', - url: '/login' - views: - '': - templateUrl: "templates/routing/register-login.tpl.html" - controller: ($scope) -> - $scope.pageTitle = 'Login' - 'content@login': - templateUrl: "templates/routing/login.tpl.html" - controller: 'loginController' - controllerAs: 'loginController' \ No newline at end of file diff --git a/src/client/components/routing/login/login.config.js b/src/client/components/routing/login/login.config.js new file mode 100644 index 0000000..3a631a8 --- /dev/null +++ b/src/client/components/routing/login/login.config.js @@ -0,0 +1,19 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('login', { + url: '/login', + views: { + '': { + templateUrl: "templates/routing/register-login.tpl.html", + controller: function ($scope) { + return $scope.pageTitle = 'Login'; + } + }, + 'content@login': { + templateUrl: "templates/routing/login.tpl.html", + controller: 'loginController', + controllerAs: 'loginController' + } + } + }); +}); diff --git a/src/client/components/routing/login/login.controller.coffee b/src/client/components/routing/login/login.controller.coffee deleted file mode 100644 index c94349e..0000000 --- a/src/client/components/routing/login/login.controller.coffee +++ /dev/null @@ -1,60 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'loginController', ($state, $rootScope, LoopBackAdminConfiguration, $scope, $mdDialog) -> - vm = this - - User = LoopBackAdminConfiguration.userModel - - vm.userLoginField = LoopBackAdminConfiguration.userLoginField - - vm.login = (credentials) -> - request = User.login credentials - - request.$promise - .then (data) -> - $state.go 'dashboard' - return - .catch (err) -> - vm.error = err - return - - vm.showPasswordResetModal = ($event) -> - $mdDialog.show - templateUrl: 'templates/modals/reset-password.html' - targetEvent: $event - controller: 'ResetPasswordCtrl' - controllerAs: 'resetPassword' - clickOutsideToClose: true - - return - return - -.controller 'ResetPasswordCtrl', ($mdDialog, LoopBackAdminConfiguration) -> - vm = this - - User = LoopBackAdminConfiguration.userModel - - vm.resetPasswordError = '' - - vm.closePasswordResetModal = -> - vm.resetPasswordError = '' - vm.passResetCredentials = {} - - $mdDialog.hide() - - return - - vm.resetPassword = (passResetCredentials) -> - User.resetPassword(passResetCredentials).$promise - .then (data) -> - $rootScope.showToast data - vm.closePasswordResetModal() - .catch (data) -> - vm.resetPasswordError = data.email or data - - return - return - - return diff --git a/src/client/components/routing/login/login.controller.js b/src/client/components/routing/login/login.controller.js new file mode 100644 index 0000000..2576571 --- /dev/null +++ b/src/client/components/routing/login/login.controller.js @@ -0,0 +1,47 @@ +'use strict'; +angular.module('loopback-admin').controller('loginController', function ($state, $rootScope, LoopBackAdminConfiguration, $scope, $mdDialog) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.userLoginField = LoopBackAdminConfiguration.userLoginField; + vm.login = function (credentials) { + var request; + request = User.login(credentials); + return request.$promise.then(function (data) { + if (data.user.role === 'admin') { + $state.go('dashboard'); + } else { + User.logout(); + } + })["catch"](function (err) { + vm.error = err; + }); + }; + vm.showPasswordResetModal = function ($event) { + $mdDialog.show({ + templateUrl: 'templates/modals/reset-password.html', + targetEvent: $event, + controller: 'ResetPasswordCtrl', + controllerAs: 'resetPassword', + clickOutsideToClose: true + }); + }; +}).controller('ResetPasswordCtrl', function ($mdDialog, LoopBackAdminConfiguration) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.resetPasswordError = ''; + vm.closePasswordResetModal = function () { + vm.resetPasswordError = ''; + vm.passResetCredentials = {}; + $mdDialog.hide(); + }; + vm.resetPassword = function (passResetCredentials) { + User.resetPassword(passResetCredentials).$promise.then(function (data) { + $rootScope.showToast(data); + return vm.closePasswordResetModal(); + })["catch"](function (data) { + vm.resetPasswordError = data.email || data; + }); + }; +}); diff --git a/src/client/components/routing/logout/logout.config.coffee b/src/client/components/routing/logout/logout.config.coffee deleted file mode 100644 index 9b31020..0000000 --- a/src/client/components/routing/logout/logout.config.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'logout', - url: '/logout' - controller: 'logoutController' - controllerAs: 'logoutController' diff --git a/src/client/components/routing/logout/logout.config.js b/src/client/components/routing/logout/logout.config.js new file mode 100644 index 0000000..f6f46c5 --- /dev/null +++ b/src/client/components/routing/logout/logout.config.js @@ -0,0 +1,8 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('logout', { + url: '/logout', + controller: 'logoutController', + controllerAs: 'logoutController' + }); +}); diff --git a/src/client/components/routing/logout/logout.controller.coffee b/src/client/components/routing/logout/logout.controller.coffee deleted file mode 100644 index 2995033..0000000 --- a/src/client/components/routing/logout/logout.controller.coffee +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'logoutController', ($location, $rootScope, LoopBackAdminConfiguration) -> - User = LoopBackAdminConfiguration.userModel - User.logout() - - $location.path '/login' - - return diff --git a/src/client/components/routing/logout/logout.controller.js b/src/client/components/routing/logout/logout.controller.js new file mode 100644 index 0000000..4c6ea0d --- /dev/null +++ b/src/client/components/routing/logout/logout.controller.js @@ -0,0 +1,7 @@ +'use strict'; +angular.module('loopback-admin').controller('logoutController', function ($location, $rootScope, LoopBackAdminConfiguration) { + var User; + User = LoopBackAdminConfiguration.userModel; + User.logout(); + $location.path('/login'); +}); diff --git a/src/client/components/routing/register/register.config.coffee b/src/client/components/routing/register/register.config.coffee deleted file mode 100644 index f369184..0000000 --- a/src/client/components/routing/register/register.config.coffee +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.config ($stateProvider) -> - - $stateProvider - - .state 'register', - url: '/register' - controller: 'registerController' - controllerAs: 'registerController' - views: - '': - templateUrl: "templates/routing/register-login.tpl.html" - controller: ($scope) -> - $scope.pageTitle = 'Register' - 'content@register': - templateUrl: "templates/routing/register.tpl.html" diff --git a/src/client/components/routing/register/register.config.js b/src/client/components/routing/register/register.config.js new file mode 100644 index 0000000..9e7ee02 --- /dev/null +++ b/src/client/components/routing/register/register.config.js @@ -0,0 +1,19 @@ +'use strict'; +angular.module('loopback-admin').config(function ($stateProvider) { + return $stateProvider.state('register', { + url: '/register', + controller: 'registerController', + controllerAs: 'registerController', + views: { + '': { + templateUrl: "templates/routing/register-login.tpl.html", + controller: function ($scope) { + return $scope.pageTitle = 'Register'; + } + }, + 'content@register': { + templateUrl: "templates/routing/register.tpl.html" + } + } + }); +}); diff --git a/src/client/components/routing/register/register.controller.coffee b/src/client/components/routing/register/register.controller.coffee deleted file mode 100644 index 267cbf9..0000000 --- a/src/client/components/routing/register/register.controller.coffee +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'registerController', ($state, LoopBackAdminConfiguration) -> - vm = this - - User = LoopBackAdminConfiguration.userModel - - vm.login = -> - request = User.login vm.data - - request.$promise - .then (data) -> - $state.go 'dashboard' - return - .catch (err) -> - vm.error = err - return - - return diff --git a/src/client/components/routing/register/register.controller.js b/src/client/components/routing/register/register.controller.js new file mode 100644 index 0000000..325e2a6 --- /dev/null +++ b/src/client/components/routing/register/register.controller.js @@ -0,0 +1,15 @@ +'use strict'; +angular.module('loopback-admin').controller('registerController', function ($state, LoopBackAdminConfiguration) { + var User, vm; + vm = this; + User = LoopBackAdminConfiguration.userModel; + vm.login = function () { + var request; + request = User.login(vm.data); + return request.$promise.then(function (data) { + $state.go('dashboard'); + })["catch"](function (err) { + vm.error = err; + }); + }; +}); diff --git a/src/client/components/table/column/boolean.directive.coffee b/src/client/components/table/column/boolean.directive.coffee deleted file mode 100644 index bb23dc9..0000000 --- a/src/client/components/table/column/boolean.directive.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbBooleanColumn', -> - restrict: 'E' - scope: - value: '=' - templateUrl: 'templates/table/column/boolean.tpl.html' - link: (scope) -> - scope.isOk = ! !scope.value - - return diff --git a/src/client/components/table/column/boolean.directive.js b/src/client/components/table/column/boolean.directive.js new file mode 100644 index 0000000..ad7a0c3 --- /dev/null +++ b/src/client/components/table/column/boolean.directive.js @@ -0,0 +1,13 @@ +'use strict'; +angular.module('loopback-admin').directive('lbBooleanColumn', function () { + return { + restrict: 'E', + scope: { + value: '=' + }, + templateUrl: 'templates/table/column/boolean.tpl.html', + link: function (scope) { + scope.isOk = !!scope.value; + } + }; +}); \ No newline at end of file diff --git a/src/client/components/table/column/choices.directive.coffee b/src/client/components/table/column/choices.directive.coffee deleted file mode 100644 index 521c5f3..0000000 --- a/src/client/components/table/column/choices.directive.coffee +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbChoicesColumn', -> - restrict: 'E' - scope: - values: '=' - templateUrl: 'templates/table/column/choices.tpl.html' \ No newline at end of file diff --git a/src/client/components/table/column/choices.directive.js b/src/client/components/table/column/choices.directive.js new file mode 100644 index 0000000..3693d2b --- /dev/null +++ b/src/client/components/table/column/choices.directive.js @@ -0,0 +1,10 @@ +'use strict'; +angular.module('loopback-admin').directive('lbChoicesColumn', function () { + return { + restrict: 'E', + scope: { + values: '=' + }, + templateUrl: 'templates/table/column/choices.tpl.html' + }; +}); \ No newline at end of file diff --git a/src/client/components/table/column/column.directive.coffee b/src/client/components/table/column/column.directive.coffee deleted file mode 100644 index 7a7d955..0000000 --- a/src/client/components/table/column/column.directive.coffee +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbColumn', -> - restrict: 'E' - scope: - property: '=' - row: '=' - model: '=' - rows: '=' - template: """""" diff --git a/src/client/components/table/column/column.directive.js b/src/client/components/table/column/column.directive.js new file mode 100644 index 0000000..7e29d99 --- /dev/null +++ b/src/client/components/table/column/column.directive.js @@ -0,0 +1,13 @@ +'use strict'; +angular.module('loopback-admin').directive('lbColumn', function () { + return { + restrict: 'E', + scope: { + property: '=', + row: '=', + model: '=', + rows: '=' + }, + template: "" + }; +}); \ No newline at end of file diff --git a/src/client/components/table/column/date.directive.coffee b/src/client/components/table/column/date.directive.coffee deleted file mode 100644 index abbbfed..0000000 --- a/src/client/components/table/column/date.directive.coffee +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbDateColumn', -> - restrict: 'E' - scope: - value: '=' - property: '=' - templateUrl: 'templates/table/column/date.tpl.html' - link: (scope) -> - property = scope.property - scope.format = property.format - - if !scope.format - scope.format = if property.type == 'date' then 'yyyy-MM-dd' else 'yyyy-MM-dd HH:mm:ss' - - return diff --git a/src/client/components/table/column/date.directive.js b/src/client/components/table/column/date.directive.js new file mode 100644 index 0000000..80db6b9 --- /dev/null +++ b/src/client/components/table/column/date.directive.js @@ -0,0 +1,19 @@ +'use strict'; +angular.module('loopback-admin').directive('lbDateColumn', function () { + return { + restrict: 'E', + scope: { + value: '=', + property: '=' + }, + templateUrl: 'templates/table/column/date.tpl.html', + link: function (scope) { + var property; + property = scope.property; + scope.format = property.format; + if (!scope.format) { + scope.format = property.type === 'date' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'; + } + } + }; +}); \ No newline at end of file diff --git a/src/client/components/table/column/number.directive.coffee b/src/client/components/table/column/number.directive.coffee deleted file mode 100644 index 19dab7a..0000000 --- a/src/client/components/table/column/number.directive.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbNumberColumn', -> - restrict: 'E' - scope: - value: '=' - property: '=' - templateUrl: 'templates/table/column/number.tpl.html' diff --git a/src/client/components/table/column/number.directive.js b/src/client/components/table/column/number.directive.js new file mode 100644 index 0000000..aac0778 --- /dev/null +++ b/src/client/components/table/column/number.directive.js @@ -0,0 +1,11 @@ +'use strict'; +angular.module('loopback-admin').directive('lbNumberColumn', function () { + return { + restrict: 'E', + scope: { + value: '=', + property: '=' + }, + templateUrl: 'templates/table/column/number.tpl.html' + }; +}); \ No newline at end of file diff --git a/src/client/components/table/column/string.directive.coffee b/src/client/components/table/column/string.directive.coffee deleted file mode 100644 index 2474e0c..0000000 --- a/src/client/components/table/column/string.directive.coffee +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'lbStringColumn', -> - restrict: 'E' - scope: - value: '=' - templateUrl: 'templates/table/column/string.tpl.html' \ No newline at end of file diff --git a/src/client/components/table/column/string.directive.js b/src/client/components/table/column/string.directive.js new file mode 100644 index 0000000..9d45f35 --- /dev/null +++ b/src/client/components/table/column/string.directive.js @@ -0,0 +1,10 @@ +'use strict'; +angular.module('loopback-admin').directive('lbStringColumn', function () { + return { + restrict: 'E', + scope: { + value: '=' + }, + templateUrl: 'templates/table/column/string.tpl.html' + }; +}); diff --git a/src/client/components/table/table.controller.coffee b/src/client/components/table/table.controller.coffee deleted file mode 100644 index f23f46b..0000000 --- a/src/client/components/table/table.controller.coffee +++ /dev/null @@ -1,130 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'TableCtrl', ($mdDialog, $rootScope, $log) -> - vm = this - - vm.deferred = null - - vm.filter = - options: - debounce: 500 - - vm.query = - filter: null - limit: 10 - orderPlain: 'id' - orderDirection: 'DESC' - page: 1 - - vm.resource = vm.model?.resource - vm.rows = [] - - vm.selected = [] - - vm.deleteRows = (selected, $event) -> - options = - title: 'Delete Items' - body: 'Are you sure you want to delete these items?' - event: $event - - $rootScope.confirm options - .then -> - item = selected.pop() - - indx = vm.rows.indexOf item - idx = selected.indexOf item - - item.$remove() - - if indx > -1 - vm.rows.splice indx, 1 - - return - - vm.showRowModal = (type, row, $event) -> - $mdDialog.show - locals: - row: row - type: type - rows: vm.rows - model: vm.model - templateUrl: "templates/modals/table.tpl.html" - targetEvent: $event - clickOutsideToClose: true - controller: 'RowDataModel' - controllerAs: 'modal' - - refreshRows = -> - page = parseInt vm.query.page, 10 - - filter = - include: vm.model.relationNames - skip: (page - 1) * vm.query.limit - limit: vm.query.limit - order: vm.query.orderPlain + ' ' + vm.query.orderDirection - - params = - filter: filter - - vm.rows = vm.resource.find params, (data, headers) -> - vm.count = parseInt headers('x-total-count') - - vm.deferred = vm.rows.$promise - - vm.deferred - - if vm.resource and angular.isFunction vm.resource.find - refreshRows() - - vm.removeFilter = -> - vm.filter.show = false - vm.query.filter = '' - - if vm.filter.form.$dirty - vm.filter.form.$setPristine() - - refreshRows() - - return - - vm.onOrderChange = (order, $event) -> - $log.info 'Scope Order: ' + vm.query.order - $log.info 'Order: ' + order - - direction = 'ASC' - - if order.charAt(0) is '-' - direction = 'DESC' - orderPlain = order.slice 1 - - vm.query.order = order - vm.query.orderPlain = orderPlain or order - vm.query.orderDirection = direction - - refreshRows() - - return - - vm.onPageChange = (page, limit) -> - $log.info 'Scope Page: ' + vm.query.page + ' Scope Limit: ' + vm.query.limit - $log.info 'Page: ' + page + ' Limit: ' + limit - - vm.query.page = page - vm.query.limit = limit - - refreshRows() - - return - - vm.onFilterChange = (filter, $event) -> - $log.info 'Scope Filter: ' + vm.query.filter - $log.info 'Filter: ' + filter - - vm.query.page = 1 - - refreshRows() - - return - return diff --git a/src/client/components/table/table.controller.js b/src/client/components/table/table.controller.js new file mode 100644 index 0000000..fba4474 --- /dev/null +++ b/src/client/components/table/table.controller.js @@ -0,0 +1,110 @@ +'use strict'; +angular.module('loopback-admin').controller('TableCtrl', function ($mdDialog, $rootScope, $log) { + var ref, refreshRows, vm; + vm = this; + vm.deferred = null; + vm.filter = { + options: { + debounce: 500 + } + }; + vm.query = { + filter: null, + limit: 10, + orderPlain: 'id', + orderDirection: 'DESC', + page: 1 + }; + vm.resource = (ref = vm.model) != null ? ref.resource : void 0; + vm.rows = []; + vm.selected = []; + vm.deleteRows = function (selected, $event) { + var options; + options = { + title: 'Delete Items', + body: 'Are you sure you want to delete these items?', + event: $event + }; + $rootScope.confirm(options).then(function () { + var idx, indx, item; + item = selected.pop(); + indx = vm.rows.indexOf(item); + idx = selected.indexOf(item); + item.$remove(); + if (indx > -1) { + return vm.rows.splice(indx, 1); + } + }); + }; + vm.showRowModal = function (type, row, $event) { + return $mdDialog.show({ + locals: { + row: row, + type: type, + rows: vm.rows, + model: vm.model + }, + templateUrl: "templates/modals/table.tpl.html", + targetEvent: $event, + clickOutsideToClose: true, + controller: 'RowDataModel', + controllerAs: 'modal' + }); + }; + refreshRows = function () { + var filter, page, params; + page = parseInt(vm.query.page, 10); + filter = { + include: vm.model.relationNames, + skip: (page - 1) * vm.query.limit, + limit: vm.query.limit, + order: vm.query.orderPlain + ' ' + vm.query.orderDirection + }; + params = { + filter: filter + }; + vm.rows = vm.resource.find(params, function (data, headers) { + return vm.count = parseInt(headers('x-total-count')); + }); + vm.deferred = vm.rows.$promise; + return vm.deferred; + }; + if (vm.resource && angular.isFunction(vm.resource.find)) { + refreshRows(); + } + vm.removeFilter = function () { + vm.filter.show = false; + vm.query.filter = ''; + if (vm.filter.form.$dirty) { + vm.filter.form.$setPristine(); + refreshRows(); + } + }; + vm.onOrderChange = function (order, $event) { + var direction, orderPlain; + $log.info('Scope Order: ' + vm.query.order); + $log.info('Order: ' + order); + direction = 'ASC'; + if (order.charAt(0) === '-') { + direction = 'DESC'; + orderPlain = order.slice(1); + } + vm.query.order = order; + vm.query.orderPlain = orderPlain || order; + vm.query.orderDirection = direction; + refreshRows(); + }; + vm.onPageChange = function (page, limit) { + $log.info('Scope Page: ' + vm.query.page + ' Scope Limit: ' + vm.query.limit); + $log.info('Page: ' + page + ' Limit: ' + limit); + vm.query.page = page; + vm.query.limit = limit; + refreshRows(); + }; + vm.onFilterChange = function (filter, $event) { + $log.info('Scope Filter: ' + vm.query.filter); + $log.info('Filter: ' + filter); + vm.query.page = 1; + refreshRows(); + }; +}); \ No newline at end of file diff --git a/src/client/components/table/table.directive.coffee b/src/client/components/table/table.directive.coffee deleted file mode 100644 index e91ed5b..0000000 --- a/src/client/components/table/table.directive.coffee +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.directive 'cmsTable', -> - bindToController: - properties: '=' - columnLimit: '=' - model: '=' - template: '@' - controller: 'TableCtrl' - controllerAs: 'table' - scope: {} - templateUrl: 'templates/table/table.tpl.html' diff --git a/src/client/components/table/table.directive.js b/src/client/components/table/table.directive.js new file mode 100644 index 0000000..fdf4504 --- /dev/null +++ b/src/client/components/table/table.directive.js @@ -0,0 +1,15 @@ +'use strict'; +angular.module('loopback-admin').directive('cmsTable', function () { + return { + bindToController: { + properties: '=', + columnLimit: '=', + model: '=', + template: '@' + }, + controller: 'TableCtrl', + controllerAs: 'table', + scope: {}, + templateUrl: 'templates/table/table.tpl.html' + }; +}); \ No newline at end of file diff --git a/src/client/components/table/table.modal-controller.coffee b/src/client/components/table/table.modal-controller.coffee deleted file mode 100644 index 2760023..0000000 --- a/src/client/components/table/table.modal-controller.coffee +++ /dev/null @@ -1,41 +0,0 @@ -'use strict' - -angular.module 'loopback-admin' - -.controller 'RowDataModel', ($mdDialog, $rootScope, type, row, rows, model) -> - resource = model.resource - fn = if type is 'edit' then 'prototype$updateAttributes' else 'create' - - vm = this - - vm.form = {} - - vm.model = model - vm.properties = model.properties - - vm.row = row or new resource() - vm.type = type - - vm.submit = (data) -> - - success = -> - $mdDialog.hide() - $rootScope.showToast type + 'dUserSuccessfully' - - if type is 'create' - rows.push data - - error = (response) -> - { codes, messages } = response.data.error.details - - for code, errorType of codes - vm.form[code].$setValidity errorType[0], false - - vm.errorMessages = messages - - $rootScope.showToast type + 'dUserFailed', 'warn' - - data['$' + fn] success, error - - return - diff --git a/src/client/components/table/table.modal-controller.js b/src/client/components/table/table.modal-controller.js new file mode 100644 index 0000000..1c792c8 --- /dev/null +++ b/src/client/components/table/table.modal-controller.js @@ -0,0 +1,33 @@ +'use strict'; +angular.module('loopback-admin').controller('RowDataModel', function ($mdDialog, $rootScope, type, row, rows, model) { + var fn, resource, vm; + resource = model.resource; + fn = type === 'edit' ? 'prototype$updateAttributes' : 'create'; + vm = this; + vm.form = {}; + vm.model = model; + vm.properties = model.properties; + vm.row = row || new resource(); + vm.type = type; + vm.submit = function (data) { + var error, success; + success = function () { + $mdDialog.hide(); + $rootScope.showToast(type + 'dUserSuccessfully'); + if (type === 'create') { + return rows.push(data); + } + }; + error = function (response) { + var code, codes, errorType, messages, ref; + ref = response.data.error.details, codes = ref.codes, messages = ref.messages; + for (code in codes) { + errorType = codes[code]; + vm.form[code].$setValidity(errorType[0], false); + } + vm.errorMessages = messages; + return $rootScope.showToast(type + 'dUserFailed', 'warn'); + }; + return data['$' + fn](success, error); + }; +}); \ No newline at end of file diff --git a/src/client/templates/routing/ban.tpl.html b/src/client/templates/routing/ban.tpl.html new file mode 100644 index 0000000..1425852 --- /dev/null +++ b/src/client/templates/routing/ban.tpl.html @@ -0,0 +1,7 @@ +
+ + +
\ No newline at end of file diff --git a/src/client/templates/routing/dashboard.tpl.html b/src/client/templates/routing/dashboard.tpl.html index ddf0f2a..7ad3754 100644 --- a/src/client/templates/routing/dashboard.tpl.html +++ b/src/client/templates/routing/dashboard.tpl.html @@ -1,6 +1,8 @@
+ +
diff --git a/src/component/admin-spec.coffee b/src/component/admin-spec.coffee deleted file mode 100644 index 7e92a32..0000000 --- a/src/component/admin-spec.coffee +++ /dev/null @@ -1,104 +0,0 @@ -'use strict' - -fs = require 'fs' - -{ defaults, - extend, - clone } = require 'lodash' - -{ services } = require 'loopback-sdk-angular' - -path = require 'path' - -formatProperties = (properties) -> - result = {} - - for key of properties - result[key] = clone properties[key] - - if Array.isArray properties[key].type - result[key].type = 'Array' - result[key].subtype = properties[key].type[0] - else - result[key].type = properties[key].type.name - - result - -_models = {} - -getModelInfo = (loopbackApplication, modelName) -> - if _models[modelName] - return _models[modelName] - - model = loopbackApplication.models[modelName] - - baseModel = undefined - baseProperties = undefined - - if model.definition.base - baseModel = getModelInfo loopbackApplication, model.definition.base - baseProperties = formatProperties baseModel.definition.properties - - properties = formatProperties model.definition.properties - - result = - name: model.definition.name - properties: extend properties, baseProperties - - keys = [ - 'description' - 'plural' - 'idInjection' - 'persistUndefinedAsNull' - 'strict' - 'hidden' - 'validations' - 'relations' - 'acls' - 'methods' - 'mixins' - ] - - keys.forEach (key) -> - result[key] = model.definition?.settings?[key] - return - - _models[modelName] = result - - result - -module.exports = (loopbackApplication, options, callback) -> - mountPath = options.mountPath - - host = loopbackApplication.get 'host' - port = loopbackApplication.get 'port' - api = loopbackApplication.get 'restApiRoot' - - url = options.url or 'http://' + host + ':' + port + api - - sdkFile = services loopbackApplication, 'loopback-admin.services', url - sdkFilePath = path.join __dirname, 'public/js/loopback-admin.resources.js' - - fs.writeFileSync sdkFilePath, sdkFile, 'utf-8' - - handler = loopbackApplication.handler 'rest' - models = [] - - process.nextTick -> - handler.adapter.getClasses().forEach (modelClass) -> - if modelClass.ctor - models.push getModelInfo loopbackApplication, modelClass.name - - config = - options: options - models: models.sort() - - configFile = path.join __dirname, 'public/config.json' - configJSON = JSON.stringify config - - fs.writeFileSync configFile, configJSON, 'utf-8' - - callback configJSON - - return - return diff --git a/src/component/admin-spec.js b/src/component/admin-spec.js new file mode 100644 index 0000000..e3a6a54 --- /dev/null +++ b/src/component/admin-spec.js @@ -0,0 +1,83 @@ +'use strict'; +var _models, clone, defaults, extend, formatProperties, fs, getModelInfo, path, ref, services; + +fs = require('fs'); + +ref = require('lodash'), defaults = ref.defaults, extend = ref.extend, clone = ref.clone; + +services = require('loopback-sdk-angular').services; + +path = require('path'); + +formatProperties = function (properties) { + var key, result; + result = {}; + for (key in properties) { + result[key] = clone(properties[key]); + if (Array.isArray(properties[key].type)) { + result[key].type = 'Array'; + result[key].subtype = properties[key].type[0]; + } else { + result[key].type = properties[key].type.name; + } + } + return result; +}; + +_models = {}; + +getModelInfo = function (loopbackApplication, modelName) { + var baseModel, baseProperties, keys, model, properties, result; + if (_models[modelName]) { + return _models[modelName]; + } + model = loopbackApplication.models[modelName]; + baseModel = void 0; + baseProperties = void 0; + if (model.definition.base) { + baseModel = getModelInfo(loopbackApplication, model.definition.base); + baseProperties = formatProperties(baseModel.definition.properties); + } + properties = formatProperties(model.definition.properties); + result = { + name: model.definition.name, + properties: extend(properties, baseProperties) + }; + keys = ['description', 'plural', 'idInjection', 'persistUndefinedAsNull', 'strict', 'hidden', 'validations', 'relations', 'acls', 'methods', 'mixins']; + keys.forEach(function (key) { + var ref1, ref2; + result[key] = (ref1 = model.definition) != null ? (ref2 = ref1.settings) != null ? ref2[key] : void 0 : void 0; + }); + _models[modelName] = result; + return result; +}; + +module.exports = function (loopbackApplication, options, callback) { + var api, handler, host, models, mountPath, port, sdkFile, sdkFilePath, url; + mountPath = options.mountPath; + host = loopbackApplication.get('host'); + port = loopbackApplication.get('port'); + api = loopbackApplication.get('restApiRoot'); + url = options.url || 'http://' + host + ':' + port + api; + sdkFile = services(loopbackApplication, 'loopback-admin.services', url); + sdkFilePath = path.join(__dirname, 'public/js/loopback-admin.resources.js'); + fs.writeFileSync(sdkFilePath, sdkFile, 'utf-8'); + handler = loopbackApplication.handler('rest'); + models = []; + process.nextTick(function () { + var config, configFile, configJSON; + handler.adapter.getClasses().forEach(function (modelClass) { + if (modelClass.ctor) { + return models.push(getModelInfo(loopbackApplication, modelClass.name)); + } + }); + config = { + options: options, + models: models.sort() + }; + configFile = path.join(__dirname, 'public/config.json'); + configJSON = JSON.stringify(config); + fs.writeFileSync(configFile, configJSON, 'utf-8'); + callback(configJSON); + }); +}; \ No newline at end of file diff --git a/src/component/create-user.coffee b/src/component/create-user.coffee deleted file mode 100644 index 6915bc2..0000000 --- a/src/component/create-user.coffee +++ /dev/null @@ -1,89 +0,0 @@ - -module.exports = (loopbackApplication, options) -> - ACL = loopbackApplication.models.ACL - Role = loopbackApplication.models.Role - RoleMapping = loopbackApplication.models.RoleMapping - User = loopbackApplication.models[options.userModel] - - if !User - User = loopbackApplication.models.User - - User.count (error, count) -> - if error - console.log 'Error setting up default admin.' - console.dir error - return - - if count is 0 - Role.findOne { where: name: 'admin' }, (error, result) -> - if error - console.log 'Error setting up default admin role.' - console.dir error - return - - if !result - createAdminRole Role, (error, role) -> - if error - console.log 'Error creating admin role.' - console.dir error - return - - createDefaultAdmin User, RoleMapping, ACL, role.id - return - else - createDefaultAdmin User, RoleMapping, ACL, result.id - return - return - return - -createAdminRole = (Role, callback) -> - role = - name: 'admin' - description: 'admin' - - Role.create role, callback - return - -createDefaultAdmin = (User, RoleMapping, ACL, roleId) -> - User.create { - email: 'admin@example.com' - username: 'admin' - password: 'password' - created: new Date - }, (error, user) -> - if error - console.log 'Error creating \'admin\' user.' - console.dir error - return - - RoleMapping.create { - principalType: 'USER' - principalId: user.getId() - roleId: roleId - }, (error, result) -> - if error - console.log 'Error creating \'admin\' role mapping.' - console.dir error - return - - console.log 'Created default \'admin\' user with password \'password\'.' - return - - ACL.create - model: User.definition.name - property: '*' - accessType: '*' - permission: 'ALLOW' - principalType: 'ROLE' - principalId: 'admin' - - ACL.create - model: 'AccessToken' - property: '*' - accessType: '*' - permission: 'ALLOW' - principalType: 'ROLE' - principalId: 'admin' - - return - return diff --git a/src/component/create-user.js b/src/component/create-user.js new file mode 100644 index 0000000..31973ea --- /dev/null +++ b/src/component/create-user.js @@ -0,0 +1,96 @@ +var createAdminRole, createDefaultAdmin; + +module.exports = function (loopbackApplication, options) { + var ACL, Role, RoleMapping, User; + ACL = loopbackApplication.models.ACL; + Role = loopbackApplication.models.Role; + RoleMapping = loopbackApplication.models.RoleMapping; + User = loopbackApplication.models[options.userModel]; + if (!User) { + User = loopbackApplication.models.User; + } + User.count(function (error, count) { + if (error) { + console.log('Error setting up default admin.'); + console.dir(error); + return; + } + if (count === 0) { + Role.findOne({ + where: { + name: 'admin' + } + }, function (error, result) { + if (error) { + console.log('Error setting up default admin role.'); + console.dir(error); + return; + } + if (!result) { + createAdminRole(Role, function (error, role) { + if (error) { + console.log('Error creating admin role.'); + console.dir(error); + return; + } + createDefaultAdmin(User, RoleMapping, ACL, role.id); + }); + } else { + createDefaultAdmin(User, RoleMapping, ACL, result.id); + } + }); + } + }); +}; + +createAdminRole = function (Role, callback) { + var role; + role = { + name: 'admin', + description: 'admin' + }; + Role.create(role, callback); +}; + +createDefaultAdmin = function (User, RoleMapping, ACL, roleId) { + User.create({ + email: 'admin@example.com', + username: 'admin', + password: 'password', + created: new Date + }, function (error, user) { + if (error) { + console.log('Error creating \'admin\' user.'); + console.dir(error); + return; + } + RoleMapping.create({ + principalType: 'USER', + principalId: user.getId(), + roleId: roleId + }, function (error, result) { + if (error) { + console.log('Error creating \'admin\' role mapping.'); + console.dir(error); + return; + } + console.log('Created default \'admin\' user with password \'password\'.'); + }); + ACL.create({ + model: User.definition.name, + property: '*', + accessType: '*', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: 'admin' + }); + ACL.create({ + model: 'AccessToken', + property: '*', + accessType: '*', + permission: 'ALLOW', + principalType: 'ROLE', + principalId: 'admin' + }); + }); +}; diff --git a/src/component/index.coffee b/src/component/index.coffee deleted file mode 100644 index 8555a08..0000000 --- a/src/component/index.coffee +++ /dev/null @@ -1,112 +0,0 @@ -'use strict' - -cors = require 'cors' -path = require 'path' -url = require 'url' -fs = require 'fs' - -{ defaults } = require 'lodash' - -createUser = require './create-user' -generateAdminSpec = require './admin-spec' - -STATIC_ROOT = path.join __dirname, 'public' - -attachXTotalCount = (loopbackApplication) -> - remotes = loopbackApplication.remotes() - - remotes.after '*.find', (ctx, next) -> - filter = undefined - - if ctx.args and ctx.args.filter - if typeof ctx.args.filter is 'object' - filter = ctx.args.filter.where - else - filter = JSON.parse(ctx.args.filter).where - - if !ctx.res._headerSent - @count filter, (err, count) -> - ctx.res.set 'Access-Control-Expose-Headers', 'X-Total-Count' - ctx.res.set 'X-Total-Count', count - next() - return - else - next() - - return - return - -writeConfig = (config) -> - configJSON = JSON.stringify config - - configJS = """ - angular.module('loopback-admin') - - .config(["LoopBackAdminConfigurationProvider", function(LoopBackAdminConfigurationProvider) { - LoopBackAdminConfigurationProvider.setConfig(#{ configJSON }); - }]); - """ - - fs.writeFileSync(path.join(__dirname, 'public/js/loopback-admin.config.js'), configJS, 'utf-8') - - return - -mountAdmin = (loopbackApplication, adminApp, opts) -> - generateAdminSpec loopbackApplication, opts, (adminObject) -> - resourcePath = opts.resourcePath - - if resourcePath[0] isnt '/' - resourcePath = '/' + resourcePath - - remotes = loopbackApplication.remotes() - - setupCors adminApp, remotes - - adminApp.get resourcePath, (req, res) -> - res.status(200).send adminObject - return - return - -setupCors = (adminApp, remotes) -> - corsOptions = remotes.options and remotes.options.cors or - origin: true - credentials: true - - adminApp.use cors(corsOptions) - - return - -routes = (loopbackApplication, options) -> - loopback = loopbackApplication.loopback - - options = defaults({}, options, - resourcePath: 'config.json' - mountPath: '/admin' - userModel: 'User' - userLoginField: 'username' - apiInfo: loopbackApplication.get('apiInfo') or {}) - - router = new loopback.Router() - - attachXTotalCount loopbackApplication - # createUser loopbackApplication, options - mountAdmin loopbackApplication, router, options - writeConfig options - - router.use loopback.static STATIC_ROOT - - router - -module.exports = (loopbackApplication, options) -> - options = defaults {}, options, mountPath: '/admin' - - loopbackApplication.use options.mountPath, routes(loopbackApplication, options) - loopbackApplication.set 'loopback-component-admin', options - - loopbackApplication.once 'started', -> - baseUrl = loopbackApplication.get('url').replace /\/$/, '' - adminPath = options.mountPath or options.route - - console.log 'Browse your Admin UI at %s%s', baseUrl, adminPath - - return \ No newline at end of file diff --git a/src/component/index.js b/src/component/index.js new file mode 100644 index 0000000..15dac9c --- /dev/null +++ b/src/component/index.js @@ -0,0 +1,106 @@ +'use strict'; +var STATIC_ROOT, attachXTotalCount, cors, createUser, defaults, fs, generateAdminSpec, mountAdmin, path, routes, setupCors, url, writeConfig; + +cors = require('cors'); + +path = require('path'); + +url = require('url'); + +fs = require('fs'); + +defaults = require('lodash').defaults; + +createUser = require('./create-user'); + +generateAdminSpec = require('./admin-spec'); + +STATIC_ROOT = path.join(__dirname, 'public'); + +attachXTotalCount = function (loopbackApplication) { + var remotes; + remotes = loopbackApplication.remotes(); + remotes.after('*.find', function (ctx, next) { + var filter; + filter = void 0; + if (ctx.args && ctx.args.filter) { + if (typeof ctx.args.filter === 'object') { + filter = ctx.args.filter.where; + } else { + filter = JSON.parse(ctx.args.filter).where; + } + } + if (!ctx.res._headerSent) { + this.count(filter, function (err, count) { + ctx.res.set('Access-Control-Expose-Headers', 'X-Total-Count'); + ctx.res.set('X-Total-Count', count); + next(); + }); + } else { + next(); + } + }); +}; + +writeConfig = function (config) { + var configJS, configJSON; + configJSON = JSON.stringify(config); + configJS = "angular.module('loopback-admin')\n\n.config([\"LoopBackAdminConfigurationProvider\", function(LoopBackAdminConfigurationProvider) {\n LoopBackAdminConfigurationProvider.setConfig(" + configJSON + ");\n}]);"; + fs.writeFileSync(path.join(__dirname, 'public/js/loopback-admin.config.js'), configJS, 'utf-8'); +}; + +mountAdmin = function (loopbackApplication, adminApp, opts) { + return generateAdminSpec(loopbackApplication, opts, function (adminObject) { + var remotes, resourcePath; + resourcePath = opts.resourcePath; + if (resourcePath[0] !== '/') { + resourcePath = '/' + resourcePath; + } + remotes = loopbackApplication.remotes(); + setupCors(adminApp, remotes); + adminApp.get(resourcePath, function (req, res) { + res.status(200).send(adminObject); + }); + }); +}; + +setupCors = function (adminApp, remotes) { + var corsOptions; + corsOptions = remotes.options && remotes.options.cors || { + origin: true, + credentials: true + }; + adminApp.use(cors(corsOptions)); +}; + +routes = function (loopbackApplication, options) { + var loopback, router; + loopback = loopbackApplication.loopback; + options = defaults({}, options, { + resourcePath: 'config.json', + mountPath: '/admin', + userModel: 'User', + userLoginField: 'username', + apiInfo: loopbackApplication.get('apiInfo') || {} + }); + router = new loopback.Router(); + attachXTotalCount(loopbackApplication); + mountAdmin(loopbackApplication, router, options); + writeConfig(options); + router.use(loopback["static"](STATIC_ROOT)); + return router; +}; + +module.exports = function (loopbackApplication, options) { + options = defaults({}, options, { + mountPath: '/admin' + }); + loopbackApplication.use(options.mountPath, routes(loopbackApplication, options)); + loopbackApplication.set('loopback-component-admin', options); + loopbackApplication.once('started', function () { + var adminPath, baseUrl; + baseUrl = loopbackApplication.get('url').replace(/\/$/, ''); + adminPath = options.mountPath || options.route; + return console.log('Browse your Admin UI at %s%s', baseUrl, adminPath); + }); +};