diff --git a/client/core/src/autocomplete/autocomplete.js b/client/core/src/autocomplete/autocomplete.js index 4c2fa6e89..09ee9c453 100644 --- a/client/core/src/autocomplete/autocomplete.js +++ b/client/core/src/autocomplete/autocomplete.js @@ -33,6 +33,10 @@ class Autocomplete extends Component { this._preLoad = true; this.getItems(); } + if (value && !this.width) { + let rectangle = this.$element[0].getBoundingClientRect(); + this.width = Math.round(rectangle.width) - 10; + } this._showDropDown = value; } @@ -271,9 +275,6 @@ class Autocomplete extends Component { this.showDropDown = this.mouseFocus; }); }); - - let rectangle = this.$element[0].getBoundingClientRect(); - this.width = Math.round(rectangle.width) - 10; } $onDestroy() { @@ -301,7 +302,6 @@ module.component('vnAutocomplete', { itemAs: '@?', field: '=', label: '@', - itemTemplate: '@?', multiple: '@?' }, transclude: { diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index 625fd5a82..bb6b753b2 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -187,7 +187,6 @@ export default class Watcher extends Component { if (response === 'ACCEPT') { Object.assign(this.data, this.orgData); this.$state.go(this.state); - } else { this.state = null; } diff --git a/client/modules.json b/client/modules.json new file mode 100644 index 000000000..6dbad069d --- /dev/null +++ b/client/modules.json @@ -0,0 +1,8 @@ +{ + "salix": [], + "auth": [], + "core": [], + "client": [], + "production": [], + "route": [] +} diff --git a/client/route/index.js b/client/route/index.js new file mode 100644 index 000000000..eadbde870 --- /dev/null +++ b/client/route/index.js @@ -0,0 +1 @@ +export * from './src/route'; diff --git a/client/route/routes.json b/client/route/routes.json new file mode 100644 index 000000000..e6da8754f --- /dev/null +++ b/client/route/routes.json @@ -0,0 +1,13 @@ +{ + "module": "route", + "name": "Route", + + "validations" : false, + "routes": [ + { + "url": "/routes", + "state": "routes", + "component": "vn-route-index" + } + ] +} \ No newline at end of file diff --git a/client/route/src/index/index.html b/client/route/src/index/index.html new file mode 100644 index 000000000..6cdc1a1d8 --- /dev/null +++ b/client/route/src/index/index.html @@ -0,0 +1,23 @@ +< +
+
+ + + + + + + + + + +
+ + + +
diff --git a/client/route/src/index/index.js b/client/route/src/index/index.js new file mode 100644 index 000000000..c8dc8ffd6 --- /dev/null +++ b/client/route/src/index/index.js @@ -0,0 +1,18 @@ +import ngModule from '../module'; +import './style.css'; +import './item-route'; + +export default class Controller { + constructor() { + this.model = {}; + } + search(index) { + index.filter.search = this.model.search; + index.accept(); + } +} + +ngModule.component('vnRouteIndex', { + template: require('./index.html'), + controller: Controller +}); diff --git a/client/route/src/index/item-route.js b/client/route/src/index/item-route.js new file mode 100644 index 000000000..e69de29bb diff --git a/client/route/src/index/style.css b/client/route/src/index/style.css new file mode 100644 index 000000000..e69de29bb diff --git a/client/route/src/locale/es.json b/client/route/src/locale/es.json new file mode 100644 index 000000000..0db3279e4 --- /dev/null +++ b/client/route/src/locale/es.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/client/route/src/module.js b/client/route/src/module.js new file mode 100644 index 000000000..779683e38 --- /dev/null +++ b/client/route/src/module.js @@ -0,0 +1,5 @@ +import {ng} from 'vendor'; +import 'core'; + +const ngModule = ng.module('route', []); +export default ngModule; diff --git a/client/route/src/route.js b/client/route/src/route.js new file mode 100644 index 000000000..69a09db10 --- /dev/null +++ b/client/route/src/route.js @@ -0,0 +1,4 @@ +export * from './module'; + +// import components +import './index/index'; diff --git a/client/salix/src/configroutes.js b/client/salix/src/configroutes.js index 734931316..8a3bdd156 100644 --- a/client/salix/src/configroutes.js +++ b/client/salix/src/configroutes.js @@ -1,5 +1,5 @@ import './spliting'; -import deps from 'spliting/modules.json'; +import deps from 'client/modules.json'; import ngModule from './module'; import {splitingRegister} from 'core'; diff --git a/gulpfile.js b/gulpfile.js index 866a65599..0383a1215 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -17,7 +17,8 @@ var srcDir = './client'; var buildDir = './services/nginx/static'; var langs = ['es', 'en']; -var modules = require('./spliting/modules.json'); +var modules = require('./client/modules.json'); + var webpackConfig = require('./webpack.config.js'); // Main tasks @@ -41,7 +42,8 @@ gulp.task('services', function() { 'auth', 'salix', 'client', - 'production' + 'production', + 'route' ]; for (var service of lbServices) @@ -69,36 +71,9 @@ gulp.task('install', () => { })); }); -// Spliting - -var splitingFiles = './spliting/*'; - -gulp.task('spliting', function(cb) { - var importTpl = fs.readFileSync('./spliting/import.tpl.js', 'utf8'); - var requireTpl = fs.readFileSync('./spliting/require.tpl.js', 'utf8'); - - for (var modName in modules) { - var deps = modules[modName]; - var splitFile = `${srcDir}/${modName}/src/spliting.js`; - - try { - fs.unlinkSync(splitFile); - } catch (e) {} - - fs.appendFileSync(splitFile, importTpl); - - var i = deps.length; - while (i--) - fs.appendFileSync(splitFile, - requireTpl.replace(/\$module/g, deps[i])); - } - - cb(); -}); - // Webpack -gulp.task('webpack', ['spliting'], function(cb) { +gulp.task('webpack', function(cb) { var configCopy = Object.create(webpackConfig); var compiler = webpack(configCopy); @@ -109,7 +84,7 @@ gulp.task('webpack', ['spliting'], function(cb) { }); }); -gulp.task('webpack-dev-server', ['spliting'], function() { +gulp.task('webpack-dev-server', function() { var configCopy = Object.create(webpackConfig); for (var entry in configCopy.entry) { @@ -170,7 +145,6 @@ gulp.task('routes', function() { // Watch gulp.task('watch', function() { - gulp.watch(splitingFiles, ['spliting']); gulp.watch(routeFiles, ['routes']); gulp.watch(localeFiles, ['locales']); }); diff --git a/services/nginx/conf-dev.conf b/services/nginx/conf-dev.conf index f5af8b9f6..e36a5a82a 100644 --- a/services/nginx/conf-dev.conf +++ b/services/nginx/conf-dev.conf @@ -40,6 +40,9 @@ http { location ~ ^/production(?:/(.*))?$ { proxy_pass http://127.0.0.1:3004/$1$is_args$args; } + location ~ ^/route(?:/(.*))?$ { + proxy_pass http://127.0.0.1:3005/$1$is_args$args; + } # Este tiene que ser el Ășltimo location ~ ^(?:/(.*))?$ { proxy_pass http://127.0.0.1:3001/$1$is_args$args; diff --git a/services/nginx/conf-prod.conf b/services/nginx/conf-prod.conf index a1204c7a5..32d749780 100644 --- a/services/nginx/conf-prod.conf +++ b/services/nginx/conf-prod.conf @@ -35,6 +35,9 @@ http { location ~ ^/production(?:/(.*))?$ { proxy_pass http://production:3004/$1$is_args$args; } + location ~ ^/route(?:/(.*))?$ { + proxy_pass http://route:3005/$1$is_args$args; + } # Este tiene que ser el Ășltimo location ~ ^(?:/(.*))?$ { proxy_pass http://salix:3001/$1$is_args$args; diff --git a/services/route/.editorconfig b/services/route/.editorconfig new file mode 100644 index 000000000..3ee22e5d3 --- /dev/null +++ b/services/route/.editorconfig @@ -0,0 +1,13 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/services/route/.eslintignore b/services/route/.eslintignore new file mode 100644 index 000000000..44f397018 --- /dev/null +++ b/services/route/.eslintignore @@ -0,0 +1 @@ +/client/ \ No newline at end of file diff --git a/services/route/.eslintrc b/services/route/.eslintrc new file mode 100644 index 000000000..a6e52975a --- /dev/null +++ b/services/route/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "loopback" +} \ No newline at end of file diff --git a/services/route/.gitignore b/services/route/.gitignore new file mode 100644 index 000000000..aff1045b4 --- /dev/null +++ b/services/route/.gitignore @@ -0,0 +1,19 @@ +*.csv +*.dat +*.iml +*.log +*.out +*.pid +*.seed +*.sublime-* +*.swo +*.swp +*.tgz +*.xml +.DS_Store +.idea +.project +.strong-pm +coverage +node_modules +npm-debug.log diff --git a/services/route/.yo-rc.json b/services/route/.yo-rc.json new file mode 100644 index 000000000..02f3fc17b --- /dev/null +++ b/services/route/.yo-rc.json @@ -0,0 +1,3 @@ +{ + "generator-loopback": {} +} \ No newline at end of file diff --git a/services/route/Dockerfile b/services/route/Dockerfile new file mode 100644 index 000000000..0a4749712 --- /dev/null +++ b/services/route/Dockerfile @@ -0,0 +1,13 @@ +FROM node:6.9.1 + +COPY . /app + +WORKDIR /app + +RUN npm install + +RUN npm -g install pm2 + +CMD ["pm2-docker", "."] + +EXPOSE 3005 diff --git a/services/route/README.md b/services/route/README.md new file mode 100644 index 000000000..866baed5e --- /dev/null +++ b/services/route/README.md @@ -0,0 +1,3 @@ +# My Application + +The project is generated by [LoopBack](http://loopback.io). \ No newline at end of file diff --git a/services/route/common/models/route.json b/services/route/common/models/route.json new file mode 100644 index 000000000..a9525aaa5 --- /dev/null +++ b/services/route/common/models/route.json @@ -0,0 +1,29 @@ +{ + "name": "Route", + "base": "MyModel", + "validateUpsert": true, + "properties": { + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "date": { + "type": "date" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "DENY" + } + ] +} \ No newline at end of file diff --git a/services/route/package.json b/services/route/package.json new file mode 100644 index 000000000..3e8498bd7 --- /dev/null +++ b/services/route/package.json @@ -0,0 +1,33 @@ +{ + "name": "vn-route", + "version": "1.0.0", + "main": "server/server.js", + "scripts": { + "lint": "eslint .", + "start": "node .", + "posttest": "npm run lint && nsp check" + }, + "dependencies": { + "compression": "^1.0.3", + "cors": "^2.5.2", + "helmet": "^1.3.0", + "i18n": "^0.8.3", + "loopback": "^3.8.0", + "loopback-boot": "^2.24.0", + "loopback-component-explorer": "^4.2.0", + "loopback-connector-mysql": "^3.0.0", + "loopback-connector-remote": "^3.1.1", + "loopback-context": "^3.1.0", + "serve-favicon": "^2.0.1", + "strong-error-handler": "^2.1.0" + }, + "devDependencies": { + "nsp": "^2.1.0" + }, + "repository": { + "type": "git", + "url": "https://git.verdnatura.es/salix" + }, + "license": "GPL-3.0", + "description": "vn-route" +} diff --git a/services/route/server/boot/authentication.js b/services/route/server/boot/authentication.js new file mode 100644 index 000000000..8e88d4b55 --- /dev/null +++ b/services/route/server/boot/authentication.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function enableAuthentication(server) { + // enable authentication + server.enableAuth(); +}; diff --git a/services/route/server/boot/root.js b/services/route/server/boot/root.js new file mode 100644 index 000000000..a158fdfe5 --- /dev/null +++ b/services/route/server/boot/root.js @@ -0,0 +1,4 @@ + +module.exports = function(server) { + require ('../../../service/boot/root.js')(server); +}; diff --git a/services/route/server/component-config.json b/services/route/server/component-config.json new file mode 100644 index 000000000..f36959a48 --- /dev/null +++ b/services/route/server/component-config.json @@ -0,0 +1,5 @@ +{ + "loopback-component-explorer": { + "mountPath": "/explorer" + } +} diff --git a/services/route/server/config.json b/services/route/server/config.json new file mode 100644 index 000000000..383a2d909 --- /dev/null +++ b/services/route/server/config.json @@ -0,0 +1,22 @@ +{ + "restApiRoot": "/api", + "host": "0.0.0.0", + "port": 3005, + "remoting": { + "context": false, + "rest": { + "normalizeHttpPath": false, + "xml": false + }, + "json": { + "strict": false, + "limit": "100kb" + }, + "urlencoded": { + "extended": true, + "limit": "100kb" + }, + "cors": false, + "handleErrors": false + } +} diff --git a/services/route/server/datasources.json b/services/route/server/datasources.json new file mode 100644 index 000000000..7b160e957 --- /dev/null +++ b/services/route/server/datasources.json @@ -0,0 +1,36 @@ +{ + "db": { + "name": "db", + "connector": "memory", + "file": "db.json" + }, + "auth": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "", + "connectTimeout": 20000, + "acquireTimeout": 20000 + }, + "vn": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "", + "connectTimeout": 20000, + "acquireTimeout": 20000 + }, + "client": { + "name": "client", + "connector": "remote", + "url": "http://localhost:3002/api" + } +} diff --git a/services/route/server/datasources.test.json b/services/route/server/datasources.test.json new file mode 100644 index 000000000..6e81700ce --- /dev/null +++ b/services/route/server/datasources.test.json @@ -0,0 +1,36 @@ +{ + "db": + { + "name": "db", + "connector": "memory", + "file": "db.json" + }, + "auth": + { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "" + }, + "vn": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "", + "connectTimeout": 20000, + "acquireTimeout": 20000 + }, + "client": { + "name": "client", + "connector": "remote", + "url": "http://localhost:3002/api" + } +} diff --git a/services/route/server/middleware.development.json b/services/route/server/middleware.development.json new file mode 100644 index 000000000..071c11a30 --- /dev/null +++ b/services/route/server/middleware.development.json @@ -0,0 +1,10 @@ +{ + "final:after": { + "strong-error-handler": { + "params": { + "debug": true, + "log": true + } + } + } +} diff --git a/services/route/server/middleware.json b/services/route/server/middleware.json new file mode 100644 index 000000000..810050770 --- /dev/null +++ b/services/route/server/middleware.json @@ -0,0 +1,60 @@ +{ + "initial:before": { + "loopback#favicon": {} + }, + "initial": { + "compression": {}, + "cors": { + "params": { + "origin": true, + "credentials": true, + "maxAge": 86400 + } + }, + "helmet#xssFilter": {}, + "helmet#frameguard": { + "params": [ + "deny" + ] + }, + "helmet#hsts": { + "params": { + "maxAge": 0, + "includeSubdomains": true + } + }, + "helmet#hidePoweredBy": {}, + "helmet#ieNoOpen": {}, + "helmet#noSniff": {}, + "helmet#noCache": { + "enabled": false + }, + "loopback-context#per-request": { + "params": { + "enableHttpContext": true + } + } + }, + "session": {}, + "auth": { + "loopback#token": {} + }, + "auth:after": { + "./middleware/currentUser": {} + }, + "parse": {}, + "routes": { + "loopback#rest": { + "paths": [ + "${restApiRoot}" + ] + } + }, + "files": {}, + "final": { + "loopback#urlNotFound": {} + }, + "final:after": { + "strong-error-handler": {} + } +} diff --git a/services/route/server/middleware/currentUser.js b/services/route/server/middleware/currentUser.js new file mode 100644 index 000000000..6024b442e --- /dev/null +++ b/services/route/server/middleware/currentUser.js @@ -0,0 +1,13 @@ +module.exports = function(options) { + return function storeCurrentUser(req, res, next) { + if (!req.accessToken) { + return next(); + } + let LoopBackContext = require('loopback-context'); + let loopbackContext = LoopBackContext.getCurrentContext(); + if (loopbackContext) { + loopbackContext.set('currentUser', req.accessToken.userId); + } + next(); + }; +}; diff --git a/services/route/server/model-config.json b/services/route/server/model-config.json new file mode 100644 index 000000000..b75a5d0fe --- /dev/null +++ b/services/route/server/model-config.json @@ -0,0 +1,50 @@ +{ + "_meta": { + "sources": [ + "loopback/common/models", + "loopback/server/models", + "../../service/models", + "../common/models", + "./models" + ], + "mixins": [ + "loopback/common/mixins", + "loopback/server/mixins", + "../common/mixins", + "./mixins" + ] + }, + "user": { + "dataSource": "auth" + }, + "AccessToken": { + "dataSource": "auth", + "relations": { + "user": { + "type": "belongsTo", + "model": "user", + "foreignKey": "userId" + } + } + }, + "ACL": { + "dataSource": "auth", + "public": false + }, + "RoleMapping": { + "dataSource": "auth", + "public": false + }, + "Role": { + "dataSource": "auth", + "public": false + }, + "Account": { + "dataSource": "auth" + }, + "Route": { + "dataSource": "vn", + "public": true + } + +} diff --git a/services/route/server/server.js b/services/route/server/server.js new file mode 100644 index 000000000..ef738abce --- /dev/null +++ b/services/route/server/server.js @@ -0,0 +1,29 @@ +'use strict'; + +var loopback = require('loopback'); +var boot = require('loopback-boot'); + +var app = module.exports = loopback(); + +app.start = function() { + // start the web server + return app.listen(function() { + app.emit('started'); + var baseUrl = app.get('url').replace(/\/$/, ''); + console.log('Web server listening at: %s', baseUrl); + if (app.get('loopback-component-explorer')) { + var explorerPath = app.get('loopback-component-explorer').mountPath; + console.log('Browse your REST API at %s%s', baseUrl, explorerPath); + } + }); +}; + +// Bootstrap the application, configure models, datasources and middleware. +// Sub-apps like REST API are mounted via boot scripts. +boot(app, __dirname, function(err) { + if (err) throw err; + + // start the server if `$ node server.js` + if (require.main === module) + app.start(); +}); diff --git a/spliting/import.tpl.js b/spliting/import.tpl.js deleted file mode 100644 index 86ad3e68b..000000000 --- a/spliting/import.tpl.js +++ /dev/null @@ -1 +0,0 @@ -import * as core from 'core'; diff --git a/spliting/modules.json b/spliting/modules.json deleted file mode 100644 index 3efb5f977..000000000 --- a/spliting/modules.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "salix": ["client", "production"], - "auth": [], - "core": [], - "client": [], - "production": [] -} diff --git a/spliting/require.tpl.js b/spliting/require.tpl.js deleted file mode 100644 index d3fe92000..000000000 --- a/spliting/require.tpl.js +++ /dev/null @@ -1,11 +0,0 @@ - -export const $module = () => { - return new Promise(resolve => { - require.ensure([], () => { - require('$module'); - resolve('$module'); - }, '$module'); - }); -}; - -core.splitingRegister.register('$module', $module);