diff --git a/.angular-cli.json b/.angular-cli.json index 322b2321..3a3bcb70 100644 --- a/.angular-cli.json +++ b/.angular-cli.json @@ -3,62 +3,63 @@ "project": { "name": "great-big-example-application" }, - "apps": [ - { - "root": "src/main/webapp/", - "outDir": "target/www/app", - "assets": [ - "content", - "i18n", - "favicon.ico", - "node_modules/@angular/material/prebuilt-themes" - ], - "index": "index.html", - "main": "app/app.main.ts", - "polyfills": "app/polyfills.ts", - "test": "../../../test.ts", - "tsconfig": "../../../tsconfig.json", - "prefix": "jhi", - "mobile": false, - "styles": [ - "content/scss/vendor.scss", - "content/scss/global.scss" - ], - "scripts": [] - } - ], + "apps": [{ + "root": "src/main/webapp", + "outDir": "target/www/app", + "assets": [ + "content", + "i18n", + "favicon.ico" + ], + "index": "index.html", + "main": "app/app.main.ts", + "polyfills": "app/polyfills.ts", + "test": "src/test/javascript/spec/entry.ts", + "tsconfig": "../../../tsconfig.json", + "prefix": "jhi", + "mobile": false, + "styles": [ + "content/scss/vendor.scss", + "content/scss/global.scss" + ], + "scripts": [] + }], "e2e": { "protractor": { - "config": "protractor.conf.js" + "config": "src/test/javascript/protractor.conf.js" } }, - "lint": [ - { - "project": "./tsconfig.json", - "exclude": "**/node_modules/**/*" + "lint": [{ + "project": "../../../tsconfig.json" }, { - "project": "./tsconfig-aot.json", - "exclude": "**/node_modules/**/*" + "project": "../../../tsconfig-aot.json" } ], "test": { "karma": { - "config": "./karma.conf.js" + "config": "src/test/javascript/karma.conf.js" } }, "defaults": { "styleExt": "scss", "prefixInterfaces": false, - "component": { - "inlineStyle": true, - "inlineTemplate": false + "component" : { + "inlineStyle" : true, + "inlineTemplate": false, + "spec": false + }, + "directive" : { + "spec": false + }, + "guard" : { + "spec": false + }, + "pipe" : { + "spec": false }, - "spec": { - "component": false, - "directive": false, - "pipe": false, - "service": false + "service" : { + "spec": false } }, "packageManager": "yarn" diff --git a/.gitattributes b/.gitattributes index 266b4f52..8ab72fe6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -21,7 +21,7 @@ *.properties text *.sass text *.scss text -*.sh text +*.sh text eol=lf *.sql text *.txt text *.ts text diff --git a/.gitignore b/.gitignore index 82a825ed..3eaf753e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ node_tmp/ node_modules/ npm-debug.log.* +/.awcache/* ###################### # SASS @@ -117,7 +118,7 @@ Desktop.ini ###################### # Logs ###################### -*.log +*.log* ###################### # Others diff --git a/.yo-rc.json b/.yo-rc.json index 2a68b34a..c0db23bf 100644 --- a/.yo-rc.json +++ b/.yo-rc.json @@ -1,82 +1,84 @@ { - "generator-jhipster": { - "promptValues": { - "packageName": "org.exampleapps.greatbig", - "nativeLanguage": "en" - }, - "jhipsterVersion": "4.6.1", - "baseName": "GreatBigExampleApplication", - "packageName": "org.exampleapps.greatbig", - "packageFolder": "org/exampleapps/greatbig", - "serverPort": "8090", - "authenticationType": "jwt", - "hibernateCache": "ehcache", - "clusteredHttpSession": false, - "websocket": "spring-websocket", - "databaseType": "sql", - "devDatabaseType": "h2Disk", - "prodDatabaseType": "postgresql", - "searchEngine": "elasticsearch", - "messageBroker": false, - "serviceDiscoveryType": false, - "buildTool": "maven", - "enableSocialSignIn": true, - "jwtSecretKey": "7c10615c946ddf4de8dd2fbf6469aeb8eb4c48c6", - "clientFramework": "angularX", - "useSass": true, - "clientPackageManager": "yarn", - "applicationType": "monolith", - "testFrameworks": [ - "gatling", - "protractor" - ], - "jhiPrefix": "jhi", - "otherModules": [ - { - "name": "generator-jhipster-nav-element", - "version": "1.2.2" - }, - { - "name": "generator-jhipster-bootstrap-material-design", - "version": "3.5.1" - }, - { - "name": "generator-jhipster-swagger2markup", - "version": "1.2.0" - }, - { - "name": "generator-jhipster-entity-audit", - "version": "2.4.0" - }, - { - "name": "generator-jhipster-darktheme", - "version": "0.0.7" - }, - { - "name": "generator-jhipster-bootswatch", - "version": "1.0.2" - }, - { - "name": "generator-jhipster-material", - "version": "0.0.0" - }, - { - "name": "generator-jhipster-fortune", - "version": "0.0.2" - }, - { - "name": "generator-jhipster-google-analytics", - "version": "0.0.1" - } - ], - "enableTranslation": true, - "nativeLanguage": "en", - "languages": [ - "en", - "fr", - "de", - "es" - ], - "herokuAppName": "great-big-example-application" - } -} \ No newline at end of file + "generator-jhipster": { + "promptValues": { + "packageName": "org.exampleapps.greatbig", + "nativeLanguage": "en" + }, + "jhipsterVersion": "4.14.3", + "baseName": "GreatBigExampleApplication", + "packageName": "org.exampleapps.greatbig", + "packageFolder": "org/exampleapps/greatbig", + "serverPort": "8090", + "authenticationType": "jwt", + "hibernateCache": "ehcache", + "clusteredHttpSession": false, + "websocket": "spring-websocket", + "databaseType": "sql", + "devDatabaseType": "h2Disk", + "prodDatabaseType": "postgresql", + "searchEngine": "elasticsearch", + "messageBroker": false, + "serviceDiscoveryType": false, + "buildTool": "maven", + "enableSocialSignIn": true, + "jwtSecretKey": "7c10615c946ddf4de8dd2fbf6469aeb8eb4c48c6", + "clientFramework": "angularX", + "useSass": true, + "clientPackageManager": "yarn", + "applicationType": "monolith", + "testFrameworks": [ + "gatling", + "protractor" + ], + "jhiPrefix": "jhi", + "otherModules": [ + { + "name": "generator-jhipster-nav-element", + "version": "1.2.2" + }, + { + "name": "generator-jhipster-bootstrap-material-design", + "version": "3.5.1" + }, + { + "name": "generator-jhipster-swagger2markup", + "version": "1.2.0" + }, + { + "name": "generator-jhipster-entity-audit", + "version": "2.4.0" + }, + { + "name": "generator-jhipster-darktheme", + "version": "0.0.7" + }, + { + "name": "generator-jhipster-bootswatch", + "version": "1.0.2" + }, + { + "name": "generator-jhipster-material", + "version": "0.0.0" + }, + { + "name": "generator-jhipster-fortune", + "version": "0.0.2" + }, + { + "name": "generator-jhipster-google-analytics", + "version": "0.0.1" + } + ], + "enableTranslation": true, + "nativeLanguage": "en", + "languages": [ + "en", + "fr", + "de", + "es" + ], + "herokuAppName": "great-big-example-application", + "cacheProvider": "ehcache", + "enableHibernateCache": true + } +} diff --git a/docs/contents/articles/102-troubleshooting.md b/docs/contents/articles/102-troubleshooting.md index de9d8941..bce8f937 100644 --- a/docs/contents/articles/102-troubleshooting.md +++ b/docs/contents/articles/102-troubleshooting.md @@ -24,4 +24,4 @@ ERROR: reflect-metadata shim is required when using class decorators FIX: -Add var reflect = require('reflect-metadata'); to test.ts +Add var reflect = require('reflect-metadata'); to entry.ts diff --git a/docs/package.json b/docs/package.json index 292fc2f6..a82cc44b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "moment": "2.3.x", + "moment": "2.19.x", "typogr": "0.5.x", "underscore": "1.4.x", "wintersmith": "2.3.1", diff --git a/test.ts b/entry.ts similarity index 100% rename from test.ts rename to entry.ts diff --git a/karma.conf.js b/karma.conf.js index 42a93319..578acbfe 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,7 +14,7 @@ module.exports = (config) => { // list of files / patterns to load in the browser files: [ - 'test.ts', + 'entry.ts', 'node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css' ], @@ -25,7 +25,7 @@ module.exports = (config) => { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - 'test.ts': ['webpack', 'sourcemap'] + 'entry.ts': ['webpack', 'sourcemap'] }, webpack: webpackConfig(WATCH), diff --git a/package.json b/package.json index 6944d9ba..3141aac7 100644 --- a/package.json +++ b/package.json @@ -8,20 +8,20 @@ "node_modules" ], "dependencies": { - "@angular/animations": "4.4.3", - "@angular/common": "4.4.3", - "@angular/compiler": "4.4.3", - "@angular/core": "4.4.3", - "@angular/flex-layout": "2.0.0-rc.1", - "@angular/forms": "4.4.3", - "@angular/http": "4.4.3", - "@angular/material": "2.0.0-beta.7", - "@angular/platform-browser": "4.4.3", - "@angular/platform-browser-dynamic": "4.4.3", - "@angular/router": "4.4.6", + "@angular/animations": "5.2.0", + "@angular/cdk": "5.2.0", + "@angular/common": "5.2.0", + "@angular/compiler": "5.2.0", + "@angular/core": "5.2.0", + "@angular/flex-layout": "2.0.0-beta.12", + "@angular/forms": "5.2.0", + "@angular/material": "5.2.0", + "@angular/platform-browser": "5.2.0", + "@angular/platform-browser-dynamic": "5.2.0", + "@angular/router": "5.2.0", "@angularclass/form-validators": "^1.0.12", - "@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5", - "@ngrx/db": "2.0.2", + "@ng-bootstrap/ng-bootstrap": "1.0.0", + "@ngrx/db": "2.1.0", "@ngrx/effects": "4.0.5", "@ngrx/router-store": "4.0.4", "@ngrx/store": "4.0.3", @@ -30,19 +30,20 @@ "@swimlane/ngx-datatable": "9.3.1", "amcharts3": "3.21.2", "ammap3": "3.21.6", - "angular-in-memory-web-api": "0.4.6", + "angular-in-memory-web-api": "0.5.1", "angular-router-loader": "0.6.0", "angular-sortablejs": "2.0.6", "angular2-cookie": "1.2.6", "angular2-infinite-scroll": "0.3.43", "angular2-moment": "1.7.0", "angular2-notifications": "0.7.7", - "angularfire2": "2.0.0-beta.8", - "angularfire2-offline": "2.0.7", + "angularfire2": "4.0.0-rc0", + "angularfire2-offline": "dancancro/angularfire2-offline", "animate.css": "3.5.2", - "bootstrap": "4.0.0-beta", + "bootstrap": "4.0.0", "chart.js": "1.1.1", "chartist": "0.11.0", + "core-js": "2.4.1", "easy-pie-chart": "2.1.7", "firebase": "4.4.0", "font-awesome": "4.7.0", @@ -54,50 +55,59 @@ "jquery-slimscroll": "1.3.8", "leaflet-map": "0.2.1", "moment": "2.18.1", - "ng-jhipster": "0.2.12", + "ng-jhipster": "0.4.0", "ng2-handsontable": "1.0.3", "ng2-slim-loading-bar": "4.0.0", - "ng2-webstorage": "1.8.0", + "ngx-webstorage": "2.0.1", "ngrx-store-freeze": "0.2.0", "ngrx-store-localstorage": "0.2.2", - "ngx-cookie": "1.0.0", + "ngx-cookie": "2.0.1", "ngx-infinite-scroll": "0.5.1", "ngx-pipes": "1.6.5", "ngx-uploader": "3.3.11", "normalize.css": "7.0.0", "reflect-metadata": "0.1.10", + "reselect": "3.0.1", "roboto-fontface": "0.8.0", + "rxjs": "5.5.6", "simple-peer": "8.1.1", + "sockjs-client": "1.1.4", "sortablejs": "1.6.1", - "swagger-ui": "3.2.2", + "swagger-ui": "2.2.10", "tether": "1.4.0", "ts-helpers": "1.1.2", - "webstomp-client": "1.0.8" + "webstomp-client": "1.0.6", + "zone.js": "0.8.19" }, "devDependencies": { - "@angular/cli": "1.3.0-rc.0", - "@angular/compiler-cli": "5.0.0-beta.7", + "@angular/cli": "1.6.6", + "@angular/compiler-cli": "5.2.0", "@angularclass/hmr": "2.1.3", "@ngrx/store-devtools": "4.0.0", + "@ngtools/webpack": "1.8.5", "@types/fullcalendar": "3.5.0", "@types/hammerjs": "2.0.35", "@types/jasmine": "2.6.0", "@types/jquery.slimscroll": "1.3.31", "@types/leaflet": "1.2.0", "@types/localforage": "0.0.34", + "@types/node": "8.0.18", + "@types/selenium-webdriver": "3.0.4", "@types/simple-peer": "6.1.2", "@types/uuid": "3.4.2", "@types/webpack-env": "1.13.1", "add-asset-html-webpack-plugin": "2.1.2", "angular2-template-loader": "0.6.2", - "awesome-typescript-loader": "3.2.1", + "awesome-typescript-loader": "3.2.2", "browser-sync": "2.18.13", "browser-sync-webpack-plugin": "1.2.0", - "codelyzer": "3.2.0", - "copy-webpack-plugin": "4.0.1", + "codelyzer": "4.0.1", + "copy-webpack-plugin": "4.2.3", "event-stream": "3.3.4", "exports-loader": "0.6.4", - "extract-text-webpack-plugin": "3.0.0", + "extract-text-webpack-plugin": "3.0.2", + "file-loader": "1.1.5", + "generator-jhipster": "4.14.3", "generator-jhipster-bootstrap-material-design": "3.5.1", "generator-jhipster-bootswatch": "1.0.2", "generator-jhipster-darktheme": "0.0.7", @@ -128,36 +138,45 @@ "karma-webpack": "2.0.4", "lazypipe": "1.0.1", "lcov-parse": "1.0.0", + "loader-utils": "^1.1.0", "merge-jsons-webpack-plugin": "1.0.11", "ng-router-loader": "2.1.0", "ngc-webpack": "3.2.2", "node-sass": "4.5.3", - "phantomjs-prebuilt": "2.1.15", + "phantomjs-prebuilt": "2.1.16", + "postcss-loader": "2.0.9", "protractor": "5.1.2", "protractor-jasmine2-screenshot-reporter": "0.4.1", "proxy-middleware": "0.15.0", "raw-loader": "^0.5.1", + "rimraf": "2.6.1", "run-sequence": "2.2.0", "rxjs-tslint-rules": "3.0.1", "sass-lint": "1.11.1", "sass-loader": "6.0.6", "source-map-explorer": "1.5.0", + "source-map": "0.6.1", "sourcemap-istanbul-instrumenter-loader": "0.2.0", "string-replace-webpack-plugin": "0.1.3", + "style-loader": "0.18.2", "sw-precache": "5.2.0", "to-string-loader": "1.1.5", "ts-node": "3.3.0", "tslint": "5.7.0", "tslint-loader": "3.5.3", + "typescript": "2.6.2", "typedoc": "0.8.0", "typedoc-plugin-external-module-name": "1.0.9", + "uglifyjs-webpack-plugin": "1.1.5", "web-app-manifest-loader": "0.1.1", "webdriver-manager": "12.0.6", - "webpack": "3.6.0", - "webpack-dev-server": "2.8.2", + "webpack": "3.10.0", + "webpack-dev-server": "2.9.5", "webpack-notifier": "1.5.0", "webpack-visualizer-plugin": "0.1.11", - "write-file-webpack-plugin": "4.1.0" + "workbox-webpack-plugin": "3.0.0-beta.1", + "write-file-webpack-plugin": "4.1.0", + "xml2js": "0.4.17" }, "engines": { "node": "6.11.0" @@ -168,11 +187,10 @@ "ngc": "ngc -p tsconfig-aot.json", "cleanup": "rimraf target/{aot,www}", "start": "yarn run webpack:dev", - "webpack:dev": "webpack-dev-server --config webpack/webpack.dev.js --progress --inline --hot --profile --port=9070", - "webpack:build:vendor": "webpack --config webpack/webpack.vendor.js --progress --profile", + "webpack:dev": "yarn run webpack-dev-server --config webpack/webpack.dev.js --progress --inline --hot --profile --port=9070 --watch-content-base", "webpack:build:dev": "webpack --config webpack/webpack.dev.js --progress --profile", "webpack:build": "yarn run cleanup && yarn run webpack:build:vendor && yarn run webpack:build:dev", - "webpack:prod": "yarn run cleanup && webpack -p --config webpack/webpack.vendor.js --progress --profile && webpack -p --config webpack/webpack.prod.js --progress --profile", + "webpack:prod:main": "yarn run webpack -- --config webpack/webpack.prod.js --profile", "webpack:run:prod": "webpack-dev-server --config webpack/webpack.prod.js --progress --inline --hot --profile --port=9070", "webpack:test": "yarn run test", "webpack-dev-server": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js", diff --git a/pom.xml b/pom.xml index bda89b67..ee004c0d 100644 --- a/pom.xml +++ b/pom.xml @@ -22,12 +22,15 @@ 2.5 3.5 0.4.13 + 1.3.4 3.2.2 - 1.4 + 1.6 2.2.5 - 2.2.4 - 5.2.8.Final + 2.2.1 + + 5.2.12.Final 2.6.0 2.8.8 2.8.8 @@ -36,31 +39,45 @@ 2.8.8 0.7.9 1.8 + + 3.20.0-GA 1.0.0 + 0.1.7 1.1.3 1.1.8 0.7.0 - 1.1.4-2 + 1.1.4-2 3.6 2.0.0 + + 3.5.3 + 3.6 4.9 jdt_apt 1.1.0.Final - 3.6.0 - 1.4.1 + 2.6.1 + 3.7.0 + 2.10 + 3.0.0-M1 3.0.1 + 2.18.1 + 2.6 yyyyMMddHHmmss ${java.version} ${java.version} 3.0.0 3.1.3 - v6.11.0 + v8.9.4 9.4.1212 0.0.20 + UTF-8 + UTF-8 ${project.build.directory}/test-results false 3.2.2 @@ -96,14 +113,31 @@ ${project.basedir}/src/test/ + + 1.5.9.RELEASE + 1.5.9.RELEASE 1.0.0.RELEASE 2.7.0 1.1.0.Final - v0.24.6 + v1.3.2 + + + + io.github.jhipster + jhipster-dependencies + ${jhipster-dependencies.version} + pom + import + + + + + io.github.jhipster @@ -344,6 +378,10 @@ org.springframework.boot spring-boot-starter-aop + + org.springframework.boot + spring-boot-starter-cache + org.springframework.boot spring-boot-starter-data-jpa @@ -438,6 +476,11 @@ org.springframework.boot spring-boot-starter-cloud-connectors + + + org.springframework.cloud + spring-cloud-spring-service-connector + org.springframework.security @@ -471,6 +514,10 @@ org.springframework.social spring-social-twitter + + org.zalando + problem-spring-web + @@ -564,6 +611,12 @@ mapstruct-processor ${mapstruct.version} + + + org.hibernate + hibernate-jpamodelgen + ${hibernate.version} + @@ -596,6 +649,7 @@ org.apache.maven.plugins maven-eclipse-plugin + ${maven-eclipse-plugin.version} true true @@ -620,7 +674,7 @@ [${maven.version},) - You are running an older version of Java. JHipster requires at least JDK ${java.version} + You are running an incompatible version of Java. JHipster requires JDK ${java.version} [${java.version}.0,) @@ -648,15 +702,32 @@ src/main/resources/ true - **/*.xml - **/*.yml + config/*.yml src/main/resources/ false - **/*.xml + config/*.yml + + + + + + + docker-resources + validate + + copy-resources + + + target/ + + + src/main/docker/ + false + **/*.yml @@ -668,6 +739,7 @@ org.apache.maven.plugins maven-surefire-plugin + ${maven-surefire-plugin.version} alphabetical @@ -719,7 +791,7 @@ GreatBigExampleUser password - hibernate:spring:org.exampleapps.greatbig.domain?dialect=&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy + hibernate:spring:org.exampleapps.greatbig.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy true debug @@ -737,7 +809,12 @@ org.springframework.boot spring-boot-starter-data-jpa - ${project.parent.version} + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-data-elasticsearch + ${spring-boot-starter-data-elasticsearch.version} javax.validation @@ -749,10 +826,18 @@ org.springframework.boot spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + ${start-class} true true - org.exampleapps.greatbig.GreatBigExampleApplicationApp @@ -913,6 +992,7 @@ generate-resources run webpack:build + false @@ -935,14 +1015,28 @@ spring-boot-devtools true + + com.h2database + h2 + org.apache.maven.plugins maven-war-plugin + ${maven-war-plugin.version} - src/main/webapp/ + false + target/www/ + + + src/main/webapp + + WEB-INF/** + + + @@ -966,6 +1060,7 @@ maven-clean-plugin + ${maven-clean-plugin.version} @@ -977,14 +1072,26 @@ org.apache.maven.plugins maven-war-plugin + ${maven-war-plugin.version} + false target/www/ + + + src/main/webapp + + WEB-INF/** + + + org.springframework.boot spring-boot-maven-plugin + ${spring-boot.version} + ${start-class} true @@ -1027,6 +1134,7 @@ test run webpack:test + false @@ -1037,10 +1145,32 @@ generate-resources run webpack:prod + false + + pl.project13.maven + git-commit-id-plugin + 2.2.4 + + + + revision + + + + + false + true + + ^git.commit.id.abbrev$ + ^git.commit.id.describe$ + ^git.branch$ + + + @@ -1077,14 +1207,18 @@ org.apache.maven.plugins maven-war-plugin + ${maven-war-plugin.version} + false src/main/webapp/ org.springframework.boot spring-boot-maven-plugin + ${spring-boot.version} + ${start-class} true true true @@ -1097,6 +1231,7 @@ org.apache.maven.plugins maven-compiler-plugin + ${maven-compiler-plugin.version} default-compile diff --git a/src/main/docker/.dockerignore b/src/main/docker/.dockerignore new file mode 100644 index 00000000..28e6b138 --- /dev/null +++ b/src/main/docker/.dockerignore @@ -0,0 +1,5 @@ +# https://docs.docker.com/engine/reference/builder/#dockerignore-file +# by default ignore everything except the jar file +**/* +!*.jar +!*.war diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile index d403534f..9d844df9 100644 --- a/src/main/docker/Dockerfile +++ b/src/main/docker/Dockerfile @@ -4,10 +4,10 @@ ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \ JHIPSTER_SLEEP=0 \ JAVA_OPTS="" -# add directly the war -ADD *.war /app.war - -EXPOSE 8090 CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \ sleep ${JHIPSTER_SLEEP} && \ java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.war + +EXPOSE 8070 + +ADD *.war /app.war diff --git a/src/main/docker/elasticsearch.yml b/src/main/docker/elasticsearch.yml index 94bb13a1..b4a2fc9e 100644 --- a/src/main/docker/elasticsearch.yml +++ b/src/main/docker/elasticsearch.yml @@ -1,7 +1,7 @@ version: '2' services: greatbigexampleapplication-elasticsearch: - image: elasticsearch:2.4.1 + image: elasticsearch:2.4.6 # volumes: # - ~/volumes/jhipster/GreatBigExampleApplication/elasticsearch/:/usr/share/elasticsearch/data/ ports: diff --git a/src/main/docker/postgresql.yml b/src/main/docker/postgresql.yml index 560f8136..754fce87 100644 --- a/src/main/docker/postgresql.yml +++ b/src/main/docker/postgresql.yml @@ -1,7 +1,7 @@ version: '2' services: greatbigexampleapplication-postgresql: - image: postgres:9.6.2 + image: postgres:9.6.5 # volumes: # - ~/volumes/jhipster/GreatBigExampleApplication/postgresql/:/var/lib/postgresql/data/ environment: diff --git a/src/main/docker/sonar.yml b/src/main/docker/sonar.yml index c8e59e02..6cbc05af 100644 --- a/src/main/docker/sonar.yml +++ b/src/main/docker/sonar.yml @@ -1,7 +1,7 @@ version: '2' services: greatbigexampleapplication-sonar: - image: sonarqube:6.4-alpine + image: sonarqube:6.5-alpine ports: - - 9010:9010 + - 9000:9000 - 9092:9092 diff --git a/src/main/java/org/exampleapps/greatbig/GreatBigExampleApplicationApp.java b/src/main/java/org/exampleapps/greatbig/GreatBigExampleApplicationApp.java index 96e7330f..4edb753e 100644 --- a/src/main/java/org/exampleapps/greatbig/GreatBigExampleApplicationApp.java +++ b/src/main/java/org/exampleapps/greatbig/GreatBigExampleApplicationApp.java @@ -15,9 +15,6 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.core.env.Environment; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; - import javax.annotation.PostConstruct; import java.net.InetAddress; import java.net.UnknownHostException; @@ -25,8 +22,7 @@ import java.util.Collection; @ComponentScan -@EnableAutoConfiguration(exclude = {ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, - MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class}) +@EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class}) @EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class}) public class GreatBigExampleApplicationApp { @@ -43,7 +39,7 @@ public GreatBigExampleApplicationApp(Environment env) { *

* Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile *

- * You can find more information on how profiles work with JHipster on http://jhipster.github.io/profiles/. + * You can find more information on how profiles work with JHipster on http://www.jhipster.tech/profiles/. */ @PostConstruct public void initApplication() { @@ -53,7 +49,7 @@ public void initApplication() { "with both the 'dev' and 'prod' profiles at the same time."); } if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) { - log.error("You have misconfigured your application! It should not" + + log.error("You have misconfigured your application! It should not " + "run with both the 'dev' and 'cloud' profiles at the same time."); } } diff --git a/src/main/java/org/exampleapps/greatbig/config/ApplicationProperties.java b/src/main/java/org/exampleapps/greatbig/config/ApplicationProperties.java index 11e8a496..f1c663cd 100644 --- a/src/main/java/org/exampleapps/greatbig/config/ApplicationProperties.java +++ b/src/main/java/org/exampleapps/greatbig/config/ApplicationProperties.java @@ -3,9 +3,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** - * Properties specific to JHipster. + * Properties specific to Great Big Example Application. *

* Properties are configured in the application.yml file. + * See {@link io.github.jhipster.config.JHipsterProperties} for a good example. */ @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) public class ApplicationProperties { diff --git a/src/main/java/org/exampleapps/greatbig/config/CacheConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/CacheConfiguration.java index 2eee3270..0abba7a4 100644 --- a/src/main/java/org/exampleapps/greatbig/config/CacheConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/CacheConfiguration.java @@ -37,6 +37,8 @@ public CacheConfiguration(JHipsterProperties jHipsterProperties) { @Bean public JCacheManagerCustomizer cacheManagerCustomizer() { return cm -> { + cm.createCache(org.exampleapps.greatbig.repository.UserRepository.USERS_BY_LOGIN_CACHE, jcacheConfiguration); + cm.createCache(org.exampleapps.greatbig.repository.UserRepository.USERS_BY_EMAIL_CACHE, jcacheConfiguration); cm.createCache(org.exampleapps.greatbig.domain.User.class.getName(), jcacheConfiguration); cm.createCache(org.exampleapps.greatbig.domain.User.class.getName() + ".authorities", jcacheConfiguration); cm.createCache(org.exampleapps.greatbig.domain.Authority.class.getName(), jcacheConfiguration); diff --git a/src/main/java/org/exampleapps/greatbig/config/Constants.java b/src/main/java/org/exampleapps/greatbig/config/Constants.java index 2344e9d8..c1fb0f57 100644 --- a/src/main/java/org/exampleapps/greatbig/config/Constants.java +++ b/src/main/java/org/exampleapps/greatbig/config/Constants.java @@ -5,12 +5,13 @@ */ public final class Constants { - //Regex for acceptable logins + // Regex for acceptable logins public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$"; public static final String SYSTEM_ACCOUNT = "system"; public static final String ANONYMOUS_USER = "anonymoususer"; - + public static final String DEFAULT_LANGUAGE = "en"; + private Constants() { } } diff --git a/src/main/java/org/exampleapps/greatbig/config/DatabaseConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/DatabaseConfiguration.java index 03c93d61..f4ee73d3 100644 --- a/src/main/java/org/exampleapps/greatbig/config/DatabaseConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/DatabaseConfiguration.java @@ -4,7 +4,6 @@ import io.github.jhipster.config.liquibase.AsyncSpringLiquibase; import liquibase.integration.spring.SpringLiquibase; -import org.h2.tools.Server; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; @@ -13,6 +12,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.core.task.TaskExecutor; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @@ -20,6 +20,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.SQLException; @Configuration @@ -45,8 +47,31 @@ public DatabaseConfiguration(Environment env) { */ @Bean(initMethod = "start", destroyMethod = "stop") @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) - public Server h2TCPServer() throws SQLException { - return Server.createTcpServer("-tcp","-tcpAllowOthers"); + public Object h2TCPServer() throws SQLException { + try { + // We don't want to include H2 when we are packaging for the "prod" profile and won't + // actually need it, so we have to load / invoke things at runtime through reflection. + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Class serverClass = Class.forName("org.h2.tools.Server", true, loader); + Method createServer = serverClass.getMethod("createTcpServer", String[].class); + return createServer.invoke(null, new Object[] { new String[] { "-tcp", "-tcpAllowOthers" } }); + + } catch (ClassNotFoundException | LinkageError e) { + throw new RuntimeException("Failed to load and initialize org.h2.tools.Server", e); + + } catch (SecurityException | NoSuchMethodException e) { + throw new RuntimeException("Failed to get method org.h2.tools.Server.createTcpServer()", e); + + } catch (IllegalAccessException | IllegalArgumentException e) { + throw new RuntimeException("Failed to invoke org.h2.tools.Server.createTcpServer()", e); + + } catch (InvocationTargetException e) { + Throwable t = e.getTargetException(); + if (t instanceof SQLException) { + throw (SQLException) t; + } + throw new RuntimeException("Unchecked exception in org.h2.tools.Server.createTcpServer()", t); + } } @Bean diff --git a/src/main/java/org/exampleapps/greatbig/config/DefaultProfileUtil.java b/src/main/java/org/exampleapps/greatbig/config/DefaultProfileUtil.java index 73a7856f..777885c0 100644 --- a/src/main/java/org/exampleapps/greatbig/config/DefaultProfileUtil.java +++ b/src/main/java/org/exampleapps/greatbig/config/DefaultProfileUtil.java @@ -25,7 +25,7 @@ private DefaultProfileUtil() { * @param app the Spring application */ public static void addDefaultProfile(SpringApplication app) { - Map defProperties = new HashMap<>(); + Map defProperties = new HashMap<>(); /* * The default profile to use when no other profiles are defined * This cannot be set in the application.yml file. diff --git a/src/main/java/org/exampleapps/greatbig/config/ElasticsearchConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/ElasticsearchConfiguration.java index a8bd46bc..2c95a11d 100644 --- a/src/main/java/org/exampleapps/greatbig/config/ElasticsearchConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/ElasticsearchConfiguration.java @@ -5,12 +5,13 @@ import org.elasticsearch.client.Client; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -// import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.EntityMapper; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; + import com.github.vanroy.springdata.jest.JestElasticsearchTemplate; import com.github.vanroy.springdata.jest.mapper.DefaultJestResultsMapper; import io.searchbox.client.JestClient; @@ -19,10 +20,12 @@ public class ElasticsearchConfiguration { @Bean - public JestElasticsearchTemplate elasticsearchTemplate(JestClient client, Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) { + // public ElasticsearchTemplate elasticsearchTemplate(Client client, Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) { + // return new ElasticsearchTemplate(client, new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).build())); + public JestElasticsearchTemplate elasticsearchTemplate(JestClient client, Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) { return new JestElasticsearchTemplate(client, new DefaultJestResultsMapper( new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).build()))); - } + } public class CustomEntityMapper implements EntityMapper { diff --git a/src/main/java/org/exampleapps/greatbig/config/JacksonConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/JacksonConfiguration.java index 29a71fef..e0eae68d 100644 --- a/src/main/java/org/exampleapps/greatbig/config/JacksonConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/JacksonConfiguration.java @@ -5,11 +5,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.zalando.problem.ProblemModule; +import org.zalando.problem.validation.ConstraintViolationProblemModule; @Configuration public class JacksonConfiguration { - /** + /* * Support for Hibernate types in Jackson. */ @Bean @@ -17,11 +19,28 @@ public Hibernate5Module hibernate5Module() { return new Hibernate5Module(); } - /** + /* * Jackson Afterburner module to speed up serialization/deserialization. */ @Bean public AfterburnerModule afterburnerModule() { return new AfterburnerModule(); } + + /* + * Module for serialization/deserialization of RFC7807 Problem. + */ + @Bean + ProblemModule problemModule() { + return new ProblemModule(); + } + + /* + * Module for serialization/deserialization of ConstraintViolationProblem. + */ + @Bean + ConstraintViolationProblemModule constraintViolationProblemModule() { + return new ConstraintViolationProblemModule(); + } + } diff --git a/src/main/java/org/exampleapps/greatbig/config/LoggingConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/LoggingConfiguration.java index b115e229..2c87d4ae 100644 --- a/src/main/java/org/exampleapps/greatbig/config/LoggingConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/LoggingConfiguration.java @@ -1,13 +1,22 @@ package org.exampleapps.greatbig.config; +import java.net.InetSocketAddress; +import java.util.Iterator; + import io.github.jhipster.config.JHipsterProperties; import ch.qos.logback.classic.AsyncAppender; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.boolex.OnMarkerEvaluator; +import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.LoggerContextListener; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.filter.EvaluatorFilter; import ch.qos.logback.core.spi.ContextAwareBase; -import net.logstash.logback.appender.LogstashSocketAppender; +import ch.qos.logback.core.spi.FilterReply; +import net.logstash.logback.appender.LogstashTcpSocketAppender; +import net.logstash.logback.encoder.LogstashEncoder; import net.logstash.logback.stacktrace.ShortenedThrowableConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +26,10 @@ @Configuration public class LoggingConfiguration { + private static final String LOGSTASH_APPENDER_NAME = "LOGSTASH"; + + private static final String ASYNC_LOGSTASH_APPENDER_NAME = "ASYNC_LOGSTASH"; + private final Logger log = LoggerFactory.getLogger(LoggingConfiguration.class); private LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); @@ -34,39 +47,46 @@ public LoggingConfiguration(@Value("${spring.application.name}") String appName, this.jHipsterProperties = jHipsterProperties; if (jHipsterProperties.getLogging().getLogstash().isEnabled()) { addLogstashAppender(context); - - // Add context listener - LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener(); - loggerContextListener.setContext(context); - context.addListener(loggerContextListener); + addContextListener(context); + } + if (jHipsterProperties.getMetrics().getLogs().isEnabled()) { + setMetricsMarkerLogbackFilter(context); } } - public void addLogstashAppender(LoggerContext context) { + private void addContextListener(LoggerContext context) { + LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener(); + loggerContextListener.setContext(context); + context.addListener(loggerContextListener); + } + + private void addLogstashAppender(LoggerContext context) { log.info("Initializing Logstash logging"); - LogstashSocketAppender logstashAppender = new LogstashSocketAppender(); - logstashAppender.setName("LOGSTASH"); + LogstashTcpSocketAppender logstashAppender = new LogstashTcpSocketAppender(); + logstashAppender.setName(LOGSTASH_APPENDER_NAME); logstashAppender.setContext(context); String customFields = "{\"app_name\":\"" + appName + "\",\"app_port\":\"" + serverPort + "\"}"; + // More documentation is available at: https://github.com/logstash/logstash-logback-encoder + LogstashEncoder logstashEncoder=new LogstashEncoder(); + // Set the Logstash appender config from JHipster properties + logstashEncoder.setCustomFields(customFields); // Set the Logstash appender config from JHipster properties - logstashAppender.setSyslogHost(jHipsterProperties.getLogging().getLogstash().getHost()); - logstashAppender.setPort(jHipsterProperties.getLogging().getLogstash().getPort()); - logstashAppender.setCustomFields(customFields); + logstashAppender.addDestinations(new InetSocketAddress(jHipsterProperties.getLogging().getLogstash().getHost(),jHipsterProperties.getLogging().getLogstash().getPort())); - // Limit the maximum length of the forwarded stacktrace so that it won't exceed the 8KB UDP limit of logstash ShortenedThrowableConverter throwableConverter = new ShortenedThrowableConverter(); - throwableConverter.setMaxLength(7500); throwableConverter.setRootCauseFirst(true); - logstashAppender.setThrowableConverter(throwableConverter); + logstashEncoder.setThrowableConverter(throwableConverter); + logstashEncoder.setCustomFields(customFields); + logstashAppender.setEncoder(logstashEncoder); logstashAppender.start(); // Wrap the appender in an Async appender for performance AsyncAppender asyncLogstashAppender = new AsyncAppender(); asyncLogstashAppender.setContext(context); - asyncLogstashAppender.setName("ASYNC_LOGSTASH"); + asyncLogstashAppender.setName(ASYNC_LOGSTASH_APPENDER_NAME); asyncLogstashAppender.setQueueSize(jHipsterProperties.getLogging().getLogstash().getQueueSize()); asyncLogstashAppender.addAppender(logstashAppender); asyncLogstashAppender.start(); @@ -74,6 +94,32 @@ public void addLogstashAppender(LoggerContext context) { context.getLogger("ROOT").addAppender(asyncLogstashAppender); } + // Configure a log filter to remove "metrics" logs from all appenders except the "LOGSTASH" appender + private void setMetricsMarkerLogbackFilter(LoggerContext context) { + log.info("Filtering metrics logs from all appenders except the {} appender", LOGSTASH_APPENDER_NAME); + OnMarkerEvaluator onMarkerMetricsEvaluator = new OnMarkerEvaluator(); + onMarkerMetricsEvaluator.setContext(context); + onMarkerMetricsEvaluator.addMarker("metrics"); + onMarkerMetricsEvaluator.start(); + EvaluatorFilter metricsFilter = new EvaluatorFilter<>(); + metricsFilter.setContext(context); + metricsFilter.setEvaluator(onMarkerMetricsEvaluator); + metricsFilter.setOnMatch(FilterReply.DENY); + metricsFilter.start(); + + for (ch.qos.logback.classic.Logger logger : context.getLoggerList()) { + for (Iterator> it = logger.iteratorForAppenders(); it.hasNext();) { + Appender appender = it.next(); + if (!appender.getName().equals(ASYNC_LOGSTASH_APPENDER_NAME)) { + log.debug("Filter metrics logs from the {} appender", appender.getName()); + appender.setContext(context); + appender.addFilter(metricsFilter); + appender.start(); + } + } + } + } + /** * Logback configuration is achieved by configuration file and API. * When configuration file change is detected, the configuration is reset. diff --git a/src/main/java/org/exampleapps/greatbig/config/MetricsConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/MetricsConfiguration.java index e687a29b..a0f7cc33 100644 --- a/src/main/java/org/exampleapps/greatbig/config/MetricsConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/MetricsConfiguration.java @@ -3,6 +3,7 @@ import io.github.jhipster.config.JHipsterProperties; import com.codahale.metrics.JmxReporter; +import com.codahale.metrics.JvmAttributeGaugeSet; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Slf4jReporter; import com.codahale.metrics.health.HealthCheckRegistry; @@ -13,6 +14,8 @@ import com.zaxxer.hikari.HikariDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.*; @@ -29,8 +32,10 @@ public class MetricsConfiguration extends MetricsConfigurerAdapter { private static final String PROP_METRIC_REG_JVM_THREADS = "jvm.threads"; private static final String PROP_METRIC_REG_JVM_FILES = "jvm.files"; private static final String PROP_METRIC_REG_JVM_BUFFERS = "jvm.buffers"; + private static final String PROP_METRIC_REG_JVM_ATTRIBUTE_SET = "jvm.attributes"; private static final String PROP_METRIC_REG_JCACHE_STATISTICS = "jcache.statistics"; + private final Logger log = LoggerFactory.getLogger(MetricsConfiguration.class); private MetricRegistry metricRegistry = new MetricRegistry(); @@ -70,7 +75,7 @@ public void init() { metricRegistry.register(PROP_METRIC_REG_JVM_THREADS, new ThreadStatesGaugeSet()); metricRegistry.register(PROP_METRIC_REG_JVM_FILES, new FileDescriptorRatioGauge()); metricRegistry.register(PROP_METRIC_REG_JVM_BUFFERS, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer())); - + metricRegistry.register(PROP_METRIC_REG_JVM_ATTRIBUTE_SET, new JvmAttributeGaugeSet()); metricRegistry.register(PROP_METRIC_REG_JCACHE_STATISTICS, new JCacheGaugeSet()); if (hikariDataSource != null) { log.debug("Monitoring the datasource"); @@ -83,8 +88,10 @@ public void init() { } if (jHipsterProperties.getMetrics().getLogs().isEnabled()) { log.info("Initializing Metrics Log reporting"); + Marker metricsMarker = MarkerFactory.getMarker("metrics"); final Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry) .outputTo(LoggerFactory.getLogger("metrics")) + .markWith(metricsMarker) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .build(); diff --git a/src/main/java/org/exampleapps/greatbig/config/SecurityConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/SecurityConfiguration.java index 9f936059..93535a9d 100644 --- a/src/main/java/org/exampleapps/greatbig/config/SecurityConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/SecurityConfiguration.java @@ -3,11 +3,10 @@ import org.exampleapps.greatbig.security.*; import org.exampleapps.greatbig.security.jwt.*; -import io.github.jhipster.security.*; - import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -19,13 +18,14 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.filter.CorsFilter; +import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport; import javax.annotation.PostConstruct; @Configuration +@Import(SecurityProblemSupport.class) @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @@ -38,14 +38,14 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private final CorsFilter corsFilter; - public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, - TokenProvider tokenProvider, - CorsFilter corsFilter) { + private final SecurityProblemSupport problemSupport; + public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService,TokenProvider tokenProvider,CorsFilter corsFilter, SecurityProblemSupport problemSupport) { this.authenticationManagerBuilder = authenticationManagerBuilder; this.userDetailsService = userDetailsService; this.tokenProvider = tokenProvider; this.corsFilter = corsFilter; + this.problemSupport = problemSupport; } @PostConstruct @@ -53,17 +53,12 @@ public void init() { try { authenticationManagerBuilder .userDetailsService(userDetailsService) - .passwordEncoder(passwordEncoder()); + .passwordEncoder(passwordEncoder()); } catch (Exception e) { throw new BeanInitializationException("Security configuration failed", e); } } - @Bean - public Http401UnauthorizedEntryPoint http401UnauthorizedEntryPoint() { - return new Http401UnauthorizedEntryPoint(); - } - @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); @@ -86,7 +81,8 @@ protected void configure(HttpSecurity http) throws Exception { http .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class) .exceptionHandling() - .authenticationEntryPoint(http401UnauthorizedEntryPoint()) + .authenticationEntryPoint(problemSupport) + .accessDeniedHandler(problemSupport) .and() .csrf() .disable() @@ -101,11 +97,9 @@ protected void configure(HttpSecurity http) throws Exception { .antMatchers("/api/register").permitAll() .antMatchers("/api/activate").permitAll() .antMatchers("/api/authenticate").permitAll() - .antMatchers("/api/account/reset_password/init").permitAll() - .antMatchers("/api/account/reset_password/finish").permitAll() + .antMatchers("/api/account/reset-password/init").permitAll() + .antMatchers("/api/account/reset-password/finish").permitAll() .antMatchers("/api/profile-info").permitAll() - .antMatchers("/api/profiles/*/follow").authenticated() - .antMatchers("/api/profiles/**").permitAll() .antMatchers("/api/**").authenticated() .antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/websocket/**").permitAll() @@ -123,8 +117,4 @@ private JWTConfigurer securityConfigurerAdapter() { return new JWTConfigurer(tokenProvider); } - @Bean - public SecurityEvaluationContextExtension securityEvaluationContextExtension() { - return new SecurityEvaluationContextExtension(); - } } diff --git a/src/main/java/org/exampleapps/greatbig/config/WebConfigurer.java b/src/main/java/org/exampleapps/greatbig/config/WebConfigurer.java index b34e033d..12d1b8c4 100644 --- a/src/main/java/org/exampleapps/greatbig/config/WebConfigurer.java +++ b/src/main/java/org/exampleapps/greatbig/config/WebConfigurer.java @@ -21,6 +21,7 @@ import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; +import org.springframework.http.MediaType; import java.io.File; import java.nio.file.Paths; @@ -70,9 +71,9 @@ public void onStartup(ServletContext servletContext) throws ServletException { public void customize(ConfigurableEmbeddedServletContainer container) { MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT); // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711 - mappings.add("html", "text/html;charset=utf-8"); + mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=utf-8"); // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64 - mappings.add("json", "text/html;charset=utf-8"); + mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=utf-8"); container.setMimeMappings(mappings); // When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets. setLocationForStaticAssets(container); @@ -102,14 +103,14 @@ private void setLocationForStaticAssets(ConfigurableEmbeddedServletContainer con } /** - * Resolve path prefix to static resources. + * Resolve path prefix to static resources. */ private String resolvePathPrefix() { String fullExecutablePath = this.getClass().getResource("").getPath(); String rootPath = Paths.get(".").toUri().normalize().getPath(); String extractedPath = fullExecutablePath.replace(rootPath, ""); int extractionEndIndex = extractedPath.indexOf("target/"); - if(extractionEndIndex <= 0) { + if (extractionEndIndex <= 0) { return ""; } return extractedPath.substring(0, extractionEndIndex); @@ -163,6 +164,7 @@ public CorsFilter corsFilter() { if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) { log.debug("Registering CORS filter"); source.registerCorsConfiguration("/api/**", config); + source.registerCorsConfiguration("/management/**", config); source.registerCorsConfiguration("/v2/api-docs", config); } return new CorsFilter(source); @@ -173,10 +175,24 @@ public CorsFilter corsFilter() { */ private void initH2Console(ServletContext servletContext) { log.debug("Initialize H2 console"); - ServletRegistration.Dynamic h2ConsoleServlet = servletContext.addServlet("H2Console", new org.h2.server.web.WebServlet()); - h2ConsoleServlet.addMapping("/h2-console/*"); - h2ConsoleServlet.setInitParameter("-properties", "src/main/resources/"); - h2ConsoleServlet.setLoadOnStartup(1); + try { + // We don't want to include H2 when we are packaging for the "prod" profile and won't + // actually need it, so we have to load / invoke things at runtime through reflection. + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Class servletClass = Class.forName("org.h2.server.web.WebServlet", true, loader); + Servlet servlet = (Servlet) servletClass.newInstance(); + + ServletRegistration.Dynamic h2ConsoleServlet = servletContext.addServlet("H2Console", servlet); + h2ConsoleServlet.addMapping("/h2-console/*"); + h2ConsoleServlet.setInitParameter("-properties", "src/main/resources/"); + h2ConsoleServlet.setLoadOnStartup(1); + + } catch (ClassNotFoundException | LinkageError e) { + throw new RuntimeException("Failed to load and initialize org.h2.server.web.WebServlet", e); + + } catch (IllegalAccessException | InstantiationException e) { + throw new RuntimeException("Failed to instantiate org.h2.server.web.WebServlet", e); + } } @Autowired(required = false) diff --git a/src/main/java/org/exampleapps/greatbig/config/WebsocketSecurityConfiguration.java b/src/main/java/org/exampleapps/greatbig/config/WebsocketSecurityConfiguration.java index 08363922..0d6be4a4 100644 --- a/src/main/java/org/exampleapps/greatbig/config/WebsocketSecurityConfiguration.java +++ b/src/main/java/org/exampleapps/greatbig/config/WebsocketSecurityConfiguration.java @@ -12,17 +12,13 @@ public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMes @Override protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages - .nullDestMatcher().authenticated().simpDestMatchers("/topic/tracker") - .hasAuthority(AuthoritiesConstants.ADMIN).simpDestMatchers("/topic/message") - .hasAuthority(AuthoritiesConstants.ADMIN) + .nullDestMatcher().authenticated() + .simpDestMatchers("/topic/tracker").hasAuthority(AuthoritiesConstants.ADMIN) // matches any destination that starts with /topic/ // (i.e. cannot send messages directly to /topic/) // (i.e. cannot subscribe to /topic/messages/* to get messages sent to // /topic/messages-user) .simpDestMatchers("/topic/**").authenticated() - // matches any destination that starts with /chat/private and /chat/* - .simpDestMatchers("/chat/private*").hasAuthority(AuthoritiesConstants.USER) - .simpDestMatchers("/chat/**").permitAll() // message types other than MESSAGE and SUBSCRIBE .simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll() // catch all diff --git a/src/main/java/org/exampleapps/greatbig/config/audit/AuditEventConverter.java b/src/main/java/org/exampleapps/greatbig/config/audit/AuditEventConverter.java index 120925e6..2184c85c 100644 --- a/src/main/java/org/exampleapps/greatbig/config/audit/AuditEventConverter.java +++ b/src/main/java/org/exampleapps/greatbig/config/audit/AuditEventConverter.java @@ -35,6 +35,9 @@ public List convertToAuditEvent(Iterable persi * @return the converted list. */ public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) { + if (persistentAuditEvent == null) { + return null; + } return new AuditEvent(Date.from(persistentAuditEvent.getAuditEventDate()), persistentAuditEvent.getPrincipal(), persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData())); } diff --git a/src/main/java/org/exampleapps/greatbig/domain/Authority.java b/src/main/java/org/exampleapps/greatbig/domain/Authority.java index ba3192ec..74cbd64e 100644 --- a/src/main/java/org/exampleapps/greatbig/domain/Authority.java +++ b/src/main/java/org/exampleapps/greatbig/domain/Authority.java @@ -16,12 +16,13 @@ @Entity @Table(name = "jhi_authority") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) + public class Authority implements Serializable { private static final long serialVersionUID = 1L; @NotNull - @Size(min = 0, max = 50) + @Size(max = 50) @Id @Column(length = 50) private String name; diff --git a/src/main/java/org/exampleapps/greatbig/domain/PersistentAuditEvent.java b/src/main/java/org/exampleapps/greatbig/domain/PersistentAuditEvent.java index 638d8ec2..01e9ec73 100644 --- a/src/main/java/org/exampleapps/greatbig/domain/PersistentAuditEvent.java +++ b/src/main/java/org/exampleapps/greatbig/domain/PersistentAuditEvent.java @@ -8,7 +8,8 @@ import java.util.Map; /** - * Persist AuditEvent managed by the Spring Boot actuator + * Persist AuditEvent managed by the Spring Boot actuator. + * * @see org.springframework.boot.actuate.audit.AuditEvent */ @Entity @@ -27,6 +28,7 @@ public class PersistentAuditEvent implements Serializable { @Column(name = "event_date") private Instant auditEventDate; + @Column(name = "event_type") private String auditEventType; diff --git a/src/main/java/org/exampleapps/greatbig/domain/SocialUserConnection.java b/src/main/java/org/exampleapps/greatbig/domain/SocialUserConnection.java index 9eb11011..0af40e06 100644 --- a/src/main/java/org/exampleapps/greatbig/domain/SocialUserConnection.java +++ b/src/main/java/org/exampleapps/greatbig/domain/SocialUserConnection.java @@ -14,6 +14,7 @@ @Entity @Table(name = "jhi_social_user_connection") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) + public class SocialUserConnection implements Serializable { private static final long serialVersionUID = 1L; diff --git a/src/main/java/org/exampleapps/greatbig/domain/User.java b/src/main/java/org/exampleapps/greatbig/domain/User.java index a87c4dd2..423f13b7 100644 --- a/src/main/java/org/exampleapps/greatbig/domain/User.java +++ b/src/main/java/org/exampleapps/greatbig/domain/User.java @@ -1,7 +1,6 @@ package org.exampleapps.greatbig.domain; import org.exampleapps.greatbig.config.Constants; -import org.exampleapps.greatbig.domain.Author; import com.fasterxml.jackson.annotation.JsonIgnore; import org.apache.commons.lang3.StringUtils; @@ -9,7 +8,6 @@ import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.validator.constraints.Email; -import org.springframework.data.elasticsearch.annotations.Document; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -28,7 +26,7 @@ @Entity @Table(name = "jhi_user") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) -@Document(indexName = "user") +@org.springframework.data.elasticsearch.annotations.Document(indexName = "user") public class User extends AbstractAuditingEntity implements Serializable { private static final long serialVersionUID = 1L; @@ -67,8 +65,8 @@ public class User extends AbstractAuditingEntity implements Serializable { @Column(nullable = false) private boolean activated = false; - @Size(min = 2, max = 5) - @Column(name = "lang_key", length = 5) + @Size(min = 2, max = 6) + @Column(name = "lang_key", length = 6) private String langKey; @Size(max = 256) @@ -90,9 +88,10 @@ public class User extends AbstractAuditingEntity implements Serializable { @JsonIgnore @ManyToMany - @JoinTable(name = "jhi_user_authority", joinColumns = { - @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { - @JoinColumn(name = "authority_name", referencedColumnName = "name") }) + @JoinTable( + name = "jhi_user_authority", + joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")}) @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) @BatchSize(size = 20) private Set authorities = new HashSet<>(); @@ -109,7 +108,7 @@ public String getLogin() { return login; } - //Lowercase the login before saving it in database + // Lowercase the login before saving it in database public void setLogin(String login) { this.login = StringUtils.lowerCase(login, Locale.ENGLISH); } @@ -222,8 +221,15 @@ public int hashCode() { @Override public String toString() { - return "User{" + "login='" + login + '\'' + ", firstName='" + firstName + '\'' + ", lastName='" + lastName - + '\'' + ", email='" + email + '\'' + ", imageUrl='" + imageUrl + '\'' + ", activated='" + activated - + '\'' + ", langKey='" + langKey + '\'' + ", activationKey='" + activationKey + '\'' + "}"; + return "User{" + + "login='" + login + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", email='" + email + '\'' + + ", imageUrl='" + imageUrl + '\'' + + ", activated='" + activated + '\'' + + ", langKey='" + langKey + '\'' + + ", activationKey='" + activationKey + '\'' + + "}"; } } diff --git a/src/main/java/org/exampleapps/greatbig/repository/CustomAuditEventRepository.java b/src/main/java/org/exampleapps/greatbig/repository/CustomAuditEventRepository.java index 8c423159..28326496 100644 --- a/src/main/java/org/exampleapps/greatbig/repository/CustomAuditEventRepository.java +++ b/src/main/java/org/exampleapps/greatbig/repository/CustomAuditEventRepository.java @@ -4,6 +4,8 @@ import org.exampleapps.greatbig.config.audit.AuditEventConverter; import org.exampleapps.greatbig.domain.PersistentAuditEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.boot.actuate.audit.AuditEventRepository; import org.springframework.stereotype.Repository; @@ -11,7 +13,9 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * An implementation of Spring Boot's AuditEventRepository. @@ -21,10 +25,17 @@ public class CustomAuditEventRepository implements AuditEventRepository { private static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE"; + /** + * Should be the same as in Liquibase migration. + */ + protected static final int EVENT_DATA_COLUMN_MAX_LENGTH = 255; + private final PersistenceAuditEventRepository persistenceAuditEventRepository; private final AuditEventConverter auditEventConverter; + private final Logger log = LoggerFactory.getLogger(getClass()); + public CustomAuditEventRepository(PersistenceAuditEventRepository persistenceAuditEventRepository, AuditEventConverter auditEventConverter) { @@ -70,8 +81,32 @@ public void add(AuditEvent event) { persistentAuditEvent.setPrincipal(event.getPrincipal()); persistentAuditEvent.setAuditEventType(event.getType()); persistentAuditEvent.setAuditEventDate(event.getTimestamp().toInstant()); - persistentAuditEvent.setData(auditEventConverter.convertDataToStrings(event.getData())); + Map eventData = auditEventConverter.convertDataToStrings(event.getData()); + persistentAuditEvent.setData(truncate(eventData)); persistenceAuditEventRepository.save(persistentAuditEvent); } } + + /** + * Truncate event data that might exceed column length. + */ + private Map truncate(Map data) { + Map results = new HashMap<>(); + + if (data != null) { + for (Map.Entry entry : data.entrySet()) { + String value = entry.getValue(); + if (value != null) { + int length = value.length(); + if (length > EVENT_DATA_COLUMN_MAX_LENGTH) { + value = value.substring(0, EVENT_DATA_COLUMN_MAX_LENGTH); + log.warn("Event data for {} too long ({}) has been truncated to {}. Consider increasing column width.", + entry.getKey(), length, EVENT_DATA_COLUMN_MAX_LENGTH); + } + } + results.put(entry.getKey(), value); + } + } + return results; + } } diff --git a/src/main/java/org/exampleapps/greatbig/repository/CustomSocialConnectionRepository.java b/src/main/java/org/exampleapps/greatbig/repository/CustomSocialConnectionRepository.java index f517bba0..3ddad9cf 100644 --- a/src/main/java/org/exampleapps/greatbig/repository/CustomSocialConnectionRepository.java +++ b/src/main/java/org/exampleapps/greatbig/repository/CustomSocialConnectionRepository.java @@ -118,9 +118,9 @@ public void addConnection(Connection connection) { public void updateConnection(Connection connection) { SocialUserConnection socialUserConnection = socialUserConnectionRepository.findOneByUserIdAndProviderIdAndProviderUserId(userId, connection.getKey().getProviderId(), connection.getKey().getProviderUserId()); if (socialUserConnection != null) { - SocialUserConnection socialUserConnectionToUdpate = connectionToUserSocialConnection(connection, socialUserConnection.getRank()); - socialUserConnectionToUdpate.setId(socialUserConnection.getId()); - socialUserConnectionRepository.save(socialUserConnectionToUdpate); + SocialUserConnection socialUserConnectionToUpdate = connectionToUserSocialConnection(connection, socialUserConnection.getRank()); + socialUserConnectionToUpdate.setId(socialUserConnection.getId()); + socialUserConnectionRepository.save(socialUserConnectionToUpdate); } } diff --git a/src/main/java/org/exampleapps/greatbig/repository/UserRepository.java b/src/main/java/org/exampleapps/greatbig/repository/UserRepository.java index b7ae1996..763c4979 100644 --- a/src/main/java/org/exampleapps/greatbig/repository/UserRepository.java +++ b/src/main/java/org/exampleapps/greatbig/repository/UserRepository.java @@ -1,6 +1,8 @@ package org.exampleapps.greatbig.repository; import org.exampleapps.greatbig.domain.User; + +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.EntityGraph; @@ -16,21 +18,30 @@ @Repository public interface UserRepository extends JpaRepository { + String USERS_BY_LOGIN_CACHE = "usersByLogin"; + + String USERS_BY_EMAIL_CACHE = "usersByEmail"; + Optional findOneByActivationKey(String activationKey); List findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime); Optional findOneByResetKey(String resetKey); - Optional findOneByEmail(String email); + Optional findOneByEmailIgnoreCase(String email); Optional findOneByLogin(String login); @EntityGraph(attributePaths = "authorities") - User findOneWithAuthoritiesById(Long id); + Optional findOneWithAuthoritiesById(Long id); @EntityGraph(attributePaths = "authorities") + @Cacheable(cacheNames = USERS_BY_LOGIN_CACHE) Optional findOneWithAuthoritiesByLogin(String login); + @EntityGraph(attributePaths = "authorities") + @Cacheable(cacheNames = USERS_BY_EMAIL_CACHE) + Optional findOneWithAuthoritiesByEmail(String email); + Page findAllByLoginNot(Pageable pageable, String login); } diff --git a/src/main/java/org/exampleapps/greatbig/security/DomainUserDetailsService.java b/src/main/java/org/exampleapps/greatbig/security/DomainUserDetailsService.java index 210fcb9d..1677954b 100644 --- a/src/main/java/org/exampleapps/greatbig/security/DomainUserDetailsService.java +++ b/src/main/java/org/exampleapps/greatbig/security/DomainUserDetailsService.java @@ -34,18 +34,24 @@ public DomainUserDetailsService(UserRepository userRepository) { public UserDetails loadUserByUsername(final String login) { log.debug("Authenticating {}", login); String lowercaseLogin = login.toLowerCase(Locale.ENGLISH); - Optional userFromDatabase = userRepository.findOneWithAuthoritiesByLogin(lowercaseLogin); - return userFromDatabase.map(user -> { - if (!user.getActivated()) { - throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated"); - } - List grantedAuthorities = user.getAuthorities().stream() - .map(authority -> new SimpleGrantedAuthority(authority.getName())) - .collect(Collectors.toList()); - return new org.springframework.security.core.userdetails.User(lowercaseLogin, - user.getPassword(), - grantedAuthorities); - }).orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " + - "database")); + Optional userByEmailFromDatabase = userRepository.findOneWithAuthoritiesByEmail(lowercaseLogin); + return userByEmailFromDatabase.map(user -> createSpringSecurityUser(lowercaseLogin, user)).orElseGet(() -> { + Optional userByLoginFromDatabase = userRepository.findOneWithAuthoritiesByLogin(lowercaseLogin); + return userByLoginFromDatabase.map(user -> createSpringSecurityUser(lowercaseLogin, user)) + .orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " + + "database")); + }); + } + + private org.springframework.security.core.userdetails.User createSpringSecurityUser(String lowercaseLogin, User user) { + if (!user.getActivated()) { + throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated"); + } + List grantedAuthorities = user.getAuthorities().stream() + .map(authority -> new SimpleGrantedAuthority(authority.getName())) + .collect(Collectors.toList()); + return new org.springframework.security.core.userdetails.User(user.getLogin(), + user.getPassword(), + grantedAuthorities); } } diff --git a/src/main/java/org/exampleapps/greatbig/security/SecurityUtils.java b/src/main/java/org/exampleapps/greatbig/security/SecurityUtils.java index 07273a69..6c059ba0 100644 --- a/src/main/java/org/exampleapps/greatbig/security/SecurityUtils.java +++ b/src/main/java/org/exampleapps/greatbig/security/SecurityUtils.java @@ -1,10 +1,11 @@ package org.exampleapps.greatbig.security; -import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; +import java.util.Optional; + /** * Utility class for Spring Security. */ @@ -18,19 +19,18 @@ private SecurityUtils() { * * @return the login of the current user */ - public static String getCurrentUserLogin() { + public static Optional getCurrentUserLogin() { SecurityContext securityContext = SecurityContextHolder.getContext(); - Authentication authentication = securityContext.getAuthentication(); - String userName = null; - if (authentication != null) { - if (authentication.getPrincipal() instanceof UserDetails) { - UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); - userName = springSecurityUser.getUsername(); - } else if (authentication.getPrincipal() instanceof String) { - userName = (String) authentication.getPrincipal(); - } - } - return userName; + return Optional.ofNullable(securityContext.getAuthentication()) + .map(authentication -> { + if (authentication.getPrincipal() instanceof UserDetails) { + UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); + return springSecurityUser.getUsername(); + } else if (authentication.getPrincipal() instanceof String) { + return (String) authentication.getPrincipal(); + } + return null; + }); } /** @@ -38,13 +38,11 @@ public static String getCurrentUserLogin() { * * @return the JWT of the current user */ - public static String getCurrentUserJWT() { + public static Optional getCurrentUserJWT() { SecurityContext securityContext = SecurityContextHolder.getContext(); - Authentication authentication = securityContext.getAuthentication(); - if (authentication != null && authentication.getCredentials() instanceof String) { - return (String) authentication.getCredentials(); - } - return null; + return Optional.ofNullable(securityContext.getAuthentication()) + .filter(authentication -> authentication.getCredentials() instanceof String) + .map(authentication -> (String) authentication.getCredentials()); } /** @@ -54,12 +52,10 @@ public static String getCurrentUserJWT() { */ public static boolean isAuthenticated() { SecurityContext securityContext = SecurityContextHolder.getContext(); - Authentication authentication = securityContext.getAuthentication(); - if (authentication != null) { - return authentication.getAuthorities().stream() - .noneMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(AuthoritiesConstants.ANONYMOUS)); - } - return false; + return Optional.ofNullable(securityContext.getAuthentication()) + .map(authentication -> authentication.getAuthorities().stream() + .noneMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(AuthoritiesConstants.ANONYMOUS))) + .orElse(false); } /** @@ -72,11 +68,9 @@ public static boolean isAuthenticated() { */ public static boolean isCurrentUserInRole(String authority) { SecurityContext securityContext = SecurityContextHolder.getContext(); - Authentication authentication = securityContext.getAuthentication(); - if (authentication != null) { - return authentication.getAuthorities().stream() - .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority)); - } - return false; + return Optional.ofNullable(securityContext.getAuthentication()) + .map(authentication -> authentication.getAuthorities().stream() + .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority))) + .orElse(false); } } diff --git a/src/main/java/org/exampleapps/greatbig/security/SpringSecurityAuditorAware.java b/src/main/java/org/exampleapps/greatbig/security/SpringSecurityAuditorAware.java index 74bf32be..ad9757a1 100644 --- a/src/main/java/org/exampleapps/greatbig/security/SpringSecurityAuditorAware.java +++ b/src/main/java/org/exampleapps/greatbig/security/SpringSecurityAuditorAware.java @@ -13,7 +13,6 @@ public class SpringSecurityAuditorAware implements AuditorAware { @Override public String getCurrentAuditor() { - String userName = SecurityUtils.getCurrentUserLogin(); - return userName != null ? userName : Constants.SYSTEM_ACCOUNT; + return SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT); } } diff --git a/src/main/java/org/exampleapps/greatbig/security/jwt/TokenProvider.java b/src/main/java/org/exampleapps/greatbig/security/jwt/TokenProvider.java index aa25a0cc..8178121f 100644 --- a/src/main/java/org/exampleapps/greatbig/security/jwt/TokenProvider.java +++ b/src/main/java/org/exampleapps/greatbig/security/jwt/TokenProvider.java @@ -47,7 +47,7 @@ public void init() { 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe(); } - public String createToken(Authentication authentication, Boolean rememberMe) { + public String createToken(Authentication authentication, boolean rememberMe) { String authorities = authentication.getAuthorities().stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); diff --git a/src/main/java/org/exampleapps/greatbig/service/MailService.java b/src/main/java/org/exampleapps/greatbig/service/MailService.java index 67f2426b..22bfe83a 100644 --- a/src/main/java/org/exampleapps/greatbig/service/MailService.java +++ b/src/main/java/org/exampleapps/greatbig/service/MailService.java @@ -110,6 +110,7 @@ public void sendSocialRegistrationValidationEmail(User user, String provider) { Locale locale = Locale.forLanguageTag(user.getLangKey()); Context context = new Context(locale); context.setVariable(USER, user); + context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl()); context.setVariable("provider", StringUtils.capitalize(provider)); String content = templateEngine.process("socialRegistrationValidationEmail", context); String subject = messageSource.getMessage("email.social.registration.title", null, locale); diff --git a/src/main/java/org/exampleapps/greatbig/service/SocialService.java b/src/main/java/org/exampleapps/greatbig/service/SocialService.java index 15ed90b0..b8b29d7e 100644 --- a/src/main/java/org/exampleapps/greatbig/service/SocialService.java +++ b/src/main/java/org/exampleapps/greatbig/service/SocialService.java @@ -4,6 +4,7 @@ import org.exampleapps.greatbig.domain.User; import org.exampleapps.greatbig.repository.AuthorityRepository; import org.exampleapps.greatbig.repository.UserRepository; +import org.exampleapps.greatbig.security.AuthoritiesConstants; import org.exampleapps.greatbig.repository.search.UserSearchRepository; import org.apache.commons.lang3.RandomStringUtils; @@ -88,7 +89,7 @@ private User createUserIfNotExist(UserProfile userProfile, String langKey, Strin throw new IllegalArgumentException("Email cannot be null with an existing login"); } if (!StringUtils.isBlank(email)) { - Optional user = userRepository.findOneByEmail(email); + Optional user = userRepository.findOneByEmailIgnoreCase(email); if (user.isPresent()) { log.info("User already exist associate the connection to this account"); return user.get(); @@ -98,7 +99,7 @@ private User createUserIfNotExist(UserProfile userProfile, String langKey, Strin String login = getLoginDependingOnProviderId(userProfile, providerId); String encryptedPassword = passwordEncoder.encode(RandomStringUtils.random(10)); Set authorities = new HashSet<>(1); - authorities.add(authorityRepository.findOne("ROLE_USER")); + authorities.add(authorityRepository.findOne(AuthoritiesConstants.USER)); User newUser = new User(); newUser.setLogin(login); @@ -116,7 +117,7 @@ private User createUserIfNotExist(UserProfile userProfile, String langKey, Strin } /** - * @return login if provider manage a login like Twitter or Github otherwise email address. + * @return login if provider manage a login like Twitter or GitHub otherwise email address. * Because provider like Google or Facebook didn't provide login or login like "12099388847393" */ private String getLoginDependingOnProviderId(UserProfile userProfile, String providerId) { @@ -124,7 +125,7 @@ private String getLoginDependingOnProviderId(UserProfile userProfile, String pro case "twitter": return userProfile.getUsername().toLowerCase(); default: - return userProfile.getEmail(); + return userProfile.getFirstName().toLowerCase() + "_" + userProfile.getLastName().toLowerCase(); } } diff --git a/src/main/java/org/exampleapps/greatbig/service/UserService.java b/src/main/java/org/exampleapps/greatbig/service/UserService.java index 099b9757..84b10b6f 100644 --- a/src/main/java/org/exampleapps/greatbig/service/UserService.java +++ b/src/main/java/org/exampleapps/greatbig/service/UserService.java @@ -1,5 +1,6 @@ package org.exampleapps.greatbig.service; +import org.exampleapps.greatbig.config.CacheConfiguration; import org.exampleapps.greatbig.domain.Authority; import org.exampleapps.greatbig.domain.User; import org.exampleapps.greatbig.repository.AuthorityRepository; @@ -13,6 +14,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cache.CacheManager; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.scheduling.annotation.Scheduled; @@ -44,12 +46,15 @@ public class UserService { private final AuthorityRepository authorityRepository; - public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, SocialService socialService, UserSearchRepository userSearchRepository, AuthorityRepository authorityRepository) { + private final CacheManager cacheManager; + + public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, SocialService socialService, UserSearchRepository userSearchRepository, AuthorityRepository authorityRepository, CacheManager cacheManager) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; this.socialService = socialService; this.userSearchRepository = userSearchRepository; this.authorityRepository = authorityRepository; + this.cacheManager = cacheManager; } public Optional activateRegistration(String key) { @@ -60,6 +65,8 @@ public Optional activateRegistration(String key) { user.setActivated(true); user.setActivationKey(null); userSearchRepository.save(user); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); log.debug("Activated user: {}", user); return user; }); @@ -74,35 +81,38 @@ public Optional completePasswordReset(String newPassword, String key) { user.setPassword(passwordEncoder.encode(newPassword)); user.setResetKey(null); user.setResetDate(null); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); return user; }); } public Optional requestPasswordReset(String mail) { - return userRepository.findOneByEmail(mail) + return userRepository.findOneByEmailIgnoreCase(mail) .filter(User::getActivated) .map(user -> { user.setResetKey(RandomUtil.generateResetKey()); user.setResetDate(Instant.now()); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); return user; }); } - public User createUser(String login, String password, String firstName, String lastName, String email, - String imageUrl, String langKey) { + public User registerUser(UserDTO userDTO, String password) { User newUser = new User(); Authority authority = authorityRepository.findOne(AuthoritiesConstants.USER); Set authorities = new HashSet<>(); String encryptedPassword = passwordEncoder.encode(password); - newUser.setLogin(login); + newUser.setLogin(userDTO.getLogin()); // new user gets initially a generated password newUser.setPassword(encryptedPassword); - newUser.setFirstName(firstName); - newUser.setLastName(lastName); - newUser.setEmail(email); - newUser.setImageUrl(imageUrl); - newUser.setLangKey(langKey); + newUser.setFirstName(userDTO.getFirstName()); + newUser.setLastName(userDTO.getLastName()); + newUser.setEmail(userDTO.getEmail()); + newUser.setImageUrl(userDTO.getImageUrl()); + newUser.setLangKey(userDTO.getLangKey()); // new user is not active newUser.setActivated(false); // new user gets registration key @@ -111,6 +121,8 @@ public User createUser(String login, String password, String firstName, String l newUser.setAuthorities(authorities); userRepository.save(newUser); userSearchRepository.save(newUser); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(newUser.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(newUser.getEmail()); log.debug("Created Information for User: {}", newUser); return newUser; } @@ -123,15 +135,14 @@ public User createUser(UserDTO userDTO) { user.setEmail(userDTO.getEmail()); user.setImageUrl(userDTO.getImageUrl()); if (userDTO.getLangKey() == null) { - user.setLangKey("en"); // default language + user.setLangKey(Constants.DEFAULT_LANGUAGE); // default language } else { user.setLangKey(userDTO.getLangKey()); } if (userDTO.getAuthorities() != null) { - Set authorities = new HashSet<>(); - userDTO.getAuthorities().forEach( - authority -> authorities.add(authorityRepository.findOne(authority)) - ); + Set authorities = userDTO.getAuthorities().stream() + .map(authorityRepository::findOne) + .collect(Collectors.toSet()); user.setAuthorities(authorities); } String encryptedPassword = passwordEncoder.encode(RandomUtil.generatePassword()); @@ -141,6 +152,8 @@ public User createUser(UserDTO userDTO) { user.setActivated(true); userRepository.save(user); userSearchRepository.save(user); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); log.debug("Created Information for User: {}", user); return user; } @@ -155,15 +168,19 @@ public User createUser(UserDTO userDTO) { * @param imageUrl image URL of user */ public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) { - userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin()).ifPresent(user -> { - user.setFirstName(firstName); - user.setLastName(lastName); - user.setEmail(email); - user.setLangKey(langKey); - user.setImageUrl(imageUrl); - userSearchRepository.save(user); - log.debug("Changed Information for User: {}", user); - }); + SecurityUtils.getCurrentUserLogin() + .flatMap(userRepository::findOneByLogin) + .ifPresent(user -> { + user.setFirstName(firstName); + user.setLastName(lastName); + user.setEmail(email); + user.setLangKey(langKey); + user.setImageUrl(imageUrl); + userSearchRepository.save(user); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); + log.debug("Changed Information for User: {}", user); + }); } /** @@ -189,6 +206,8 @@ public Optional updateUser(UserDTO userDTO) { .map(authorityRepository::findOne) .forEach(managedAuthorities::add); userSearchRepository.save(user); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); log.debug("Changed Information for User: {}", user); return user; }) @@ -200,16 +219,22 @@ public void deleteUser(String login) { socialService.deleteUserSocialConnection(user.getLogin()); userRepository.delete(user); userSearchRepository.delete(user); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); log.debug("Deleted User: {}", user); }); } public void changePassword(String password) { - userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin()).ifPresent(user -> { - String encryptedPassword = passwordEncoder.encode(password); - user.setPassword(encryptedPassword); - log.debug("Changed password for User: {}", user); - }); + SecurityUtils.getCurrentUserLogin() + .flatMap(userRepository::findOneByLogin) + .ifPresent(user -> { + String encryptedPassword = passwordEncoder.encode(password); + user.setPassword(encryptedPassword); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); + log.debug("Changed password for User: {}", user); + }); } @Transactional(readOnly = true) @@ -223,16 +248,15 @@ public Optional getUserWithAuthoritiesByLogin(String login) { } @Transactional(readOnly = true) - public User getUserWithAuthorities(Long id) { + public Optional getUserWithAuthorities(Long id) { return userRepository.findOneWithAuthoritiesById(id); } @Transactional(readOnly = true) - public User getUserWithAuthorities() { - return userRepository.findOneWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin()).orElse(null); + public Optional getUserWithAuthorities() { + return SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneWithAuthoritiesByLogin); } - /** * Not activated users should be automatically deleted after 3 days. *

@@ -245,6 +269,8 @@ public void removeNotActivatedUsers() { log.debug("Deleting not activated user {}", user.getLogin()); userRepository.delete(user); userSearchRepository.delete(user); + cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); + cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail()); } } @@ -280,4 +306,5 @@ public void setCurrentUser(User user) { */ public void clearCurrentUser() { } + } diff --git a/src/main/java/org/exampleapps/greatbig/service/dto/UserDTO.java b/src/main/java/org/exampleapps/greatbig/service/dto/UserDTO.java index 3a15ab04..82b6b74d 100644 --- a/src/main/java/org/exampleapps/greatbig/service/dto/UserDTO.java +++ b/src/main/java/org/exampleapps/greatbig/service/dto/UserDTO.java @@ -40,7 +40,7 @@ public class UserDTO { private boolean activated = false; - @Size(min = 2, max = 5) + @Size(min = 2, max = 6) private String langKey; private String createdBy; @@ -58,31 +58,21 @@ public UserDTO() { } public UserDTO(User user) { - this(user.getId(), user.getLogin(), user.getFirstName(), user.getLastName(), - user.getEmail(), user.getActivated(), user.getImageUrl(), user.getLangKey(), - user.getCreatedBy(), user.getCreatedDate(), user.getLastModifiedBy(), user.getLastModifiedDate(), - user.getAuthorities().stream().map(Authority::getName) - .collect(Collectors.toSet())); - } - - public UserDTO(Long id, String login, String firstName, String lastName, - String email, boolean activated, String imageUrl, String langKey, - String createdBy, Instant createdDate, String lastModifiedBy, Instant lastModifiedDate, - Set authorities) { - - this.id = id; - this.login = login; - this.firstName = firstName; - this.lastName = lastName; - this.email = email; - this.activated = activated; - this.imageUrl = imageUrl; - this.langKey = langKey; - this.createdBy = createdBy; - this.createdDate = createdDate; - this.lastModifiedBy = lastModifiedBy; - this.lastModifiedDate = lastModifiedDate; - this.authorities = authorities; + this.id = user.getId(); + this.login = user.getLogin(); + this.firstName = user.getFirstName(); + this.lastName = user.getLastName(); + this.email = user.getEmail(); + this.activated = user.getActivated(); + this.imageUrl = user.getImageUrl(); + this.langKey = user.getLangKey(); + this.createdBy = user.getCreatedBy(); + this.createdDate = user.getCreatedDate(); + this.lastModifiedBy = user.getLastModifiedBy(); + this.lastModifiedDate = user.getLastModifiedDate(); + this.authorities = user.getAuthorities().stream() + .map(Authority::getName) + .collect(Collectors.toSet()); } public Long getId() { @@ -105,38 +95,74 @@ public String getFirstName() { return firstName; } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { return lastName; } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public String getEmail() { return email; } + public void setEmail(String email) { + this.email = email; + } + public String getImageUrl() { return imageUrl; } + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + public boolean isActivated() { return activated; } + public void setActivated(boolean activated) { + this.activated = activated; + } + public String getLangKey() { return langKey; } + public void setLangKey(String langKey) { + this.langKey = langKey; + } + public String getCreatedBy() { return createdBy; } + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + public Instant getCreatedDate() { return createdDate; } + public void setCreatedDate(Instant createdDate) { + this.createdDate = createdDate; + } + public String getLastModifiedBy() { return lastModifiedBy; } + public void setLastModifiedBy(String lastModifiedBy) { + this.lastModifiedBy = lastModifiedBy; + } + public Instant getLastModifiedDate() { return lastModifiedDate; } @@ -149,6 +175,10 @@ public Set getAuthorities() { return authorities; } + public void setAuthorities(Set authorities) { + this.authorities = authorities; + } + @Override public String toString() { return "UserDTO{" + diff --git a/src/main/java/org/exampleapps/greatbig/service/mapper/UserMapper.java b/src/main/java/org/exampleapps/greatbig/service/mapper/UserMapper.java index 67488e7b..e931bc06 100644 --- a/src/main/java/org/exampleapps/greatbig/service/mapper/UserMapper.java +++ b/src/main/java/org/exampleapps/greatbig/service/mapper/UserMapper.java @@ -43,7 +43,7 @@ public User userDTOToUser(UserDTO userDTO) { user.setActivated(userDTO.isActivated()); user.setLangKey(userDTO.getLangKey()); Set authorities = this.authoritiesFromStrings(userDTO.getAuthorities()); - if(authorities != null) { + if (authorities != null) { user.setAuthorities(authorities); } return user; diff --git a/src/main/java/org/exampleapps/greatbig/service/util/RandomUtil.java b/src/main/java/org/exampleapps/greatbig/service/util/RandomUtil.java index 0d5b45d4..10198a84 100644 --- a/src/main/java/org/exampleapps/greatbig/service/util/RandomUtil.java +++ b/src/main/java/org/exampleapps/greatbig/service/util/RandomUtil.java @@ -31,10 +31,10 @@ public static String generateActivationKey() { } /** - * Generate a reset key. - * - * @return the generated reset key - */ + * Generate a reset key. + * + * @return the generated reset key + */ public static String generateResetKey() { return RandomStringUtils.randomNumeric(DEF_COUNT); } diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/AccountResource.java b/src/main/java/org/exampleapps/greatbig/web/rest/AccountResource.java index 148539ef..c56b95c0 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/AccountResource.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/AccountResource.java @@ -8,17 +8,14 @@ import org.exampleapps.greatbig.service.MailService; import org.exampleapps.greatbig.service.UserService; import org.exampleapps.greatbig.service.dto.UserDTO; +import org.exampleapps.greatbig.web.rest.errors.*; import org.exampleapps.greatbig.web.rest.vm.KeyAndPasswordVM; import org.exampleapps.greatbig.web.rest.vm.ManagedUserVM; -import org.exampleapps.greatbig.web.rest.util.HeaderUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; @@ -40,10 +37,7 @@ public class AccountResource { private final MailService mailService; - private static final String CHECK_ERROR_MESSAGE = "Incorrect password"; - - public AccountResource(UserRepository userRepository, UserService userService, - MailService mailService) { + public AccountResource(UserRepository userRepository, UserService userService, MailService mailService) { this.userRepository = userRepository; this.userService = userService; @@ -54,47 +48,36 @@ public AccountResource(UserRepository userRepository, UserService userService, * POST /register : register the user. * * @param managedUserVM the managed user View Model - * @return the ResponseEntity with status 201 (Created) if the user is registered or 400 (Bad Request) if the login or email is already in use + * @throws InvalidPasswordException 400 (Bad Request) if the password is incorrect + * @throws EmailAlreadyUsedException 400 (Bad Request) if the email is already used + * @throws LoginAlreadyUsedException 400 (Bad Request) if the login is already used */ - @PostMapping(path = "/register", - produces={MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE}) + @PostMapping("/register") @Timed - public ResponseEntity registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) { - - HttpHeaders textPlainHeaders = new HttpHeaders(); - textPlainHeaders.setContentType(MediaType.TEXT_PLAIN); + @ResponseStatus(HttpStatus.CREATED) + public void registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) { if (!checkPasswordLength(managedUserVM.getPassword())) { - return new ResponseEntity<>(CHECK_ERROR_MESSAGE, HttpStatus.BAD_REQUEST); + throw new InvalidPasswordException(); } - return userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()) - .map(user -> new ResponseEntity<>("login already in use", textPlainHeaders, HttpStatus.BAD_REQUEST)) - .orElseGet(() -> userRepository.findOneByEmail(managedUserVM.getEmail()) - .map(user -> new ResponseEntity<>("email address already in use", textPlainHeaders, HttpStatus.BAD_REQUEST)) - .orElseGet(() -> { - User user = userService - .createUser(managedUserVM.getLogin(), managedUserVM.getPassword(), - managedUserVM.getFirstName(), managedUserVM.getLastName(), - managedUserVM.getEmail().toLowerCase(), managedUserVM.getImageUrl(), - managedUserVM.getLangKey()); - - mailService.sendActivationEmail(user); - return new ResponseEntity<>(HttpStatus.CREATED); - }) - ); + userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()).ifPresent(u -> {throw new LoginAlreadyUsedException();}); + userRepository.findOneByEmailIgnoreCase(managedUserVM.getEmail()).ifPresent(u -> {throw new EmailAlreadyUsedException();}); + User user = userService.registerUser(managedUserVM, managedUserVM.getPassword()); + mailService.sendActivationEmail(user); } /** * GET /activate : activate the registered user. * * @param key the activation key - * @return the ResponseEntity with status 200 (OK) and the activated user in body, or status 500 (Internal Server Error) if the user couldn't be activated + * @throws RuntimeException 500 (Internal Server Error) if the user couldn't be activated */ @GetMapping("/activate") @Timed - public ResponseEntity activateAccount(@RequestParam(value = "key") String key) { - return userService.activateRegistration(key) - .map(user -> new ResponseEntity(HttpStatus.OK)) - .orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); + public void activateAccount(@RequestParam(value = "key") String key) { + Optional user = userService.activateRegistration(key); + if (!user.isPresent()) { + throw new InternalServerErrorException("No user was found for this reset key"); + } } /** @@ -113,94 +96,92 @@ public String isAuthenticated(HttpServletRequest request) { /** * GET /account : get the current user. * - * @return the ResponseEntity with status 200 (OK) and the current user in body, or status 500 (Internal Server Error) if the user couldn't be returned + * @return the current user + * @throws RuntimeException 500 (Internal Server Error) if the user couldn't be returned */ @GetMapping("/account") @Timed - public ResponseEntity getAccount() { - return Optional.ofNullable(userService.getUserWithAuthorities()) - .map(user -> new ResponseEntity<>(new UserDTO(user), HttpStatus.OK)) - .orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); + public UserDTO getAccount() { + return userService.getUserWithAuthorities() + .map(UserDTO::new) + .orElseThrow(() -> new InternalServerErrorException("User could not be found")); } /** * POST /account : update the current user information. * * @param userDTO the current user information - * @return the ResponseEntity with status 200 (OK), or status 400 (Bad Request) or 500 (Internal Server Error) if the user couldn't be updated + * @throws EmailAlreadyUsedException 400 (Bad Request) if the email is already used + * @throws RuntimeException 500 (Internal Server Error) if the user login wasn't found */ @PostMapping("/account") @Timed - public ResponseEntity saveAccount(@Valid @RequestBody UserDTO userDTO) { - final String userLogin = SecurityUtils.getCurrentUserLogin(); - Optional existingUser = userRepository.findOneByEmail(userDTO.getEmail()); + public void saveAccount(@Valid @RequestBody UserDTO userDTO) { + final String userLogin = SecurityUtils.getCurrentUserLogin().orElseThrow(() -> new InternalServerErrorException("Current user login not found")); + Optional existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()); if (existingUser.isPresent() && (!existingUser.get().getLogin().equalsIgnoreCase(userLogin))) { - return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("user-management", "emailexists", "Email already in use")).body(null); + throw new EmailAlreadyUsedException(); } - return userRepository - .findOneByLogin(userLogin) - .map(u -> { - userService.updateUser(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(), - userDTO.getLangKey(), userDTO.getImageUrl()); - return new ResponseEntity(HttpStatus.OK); - }) - .orElseGet(() -> new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); - } + Optional user = userRepository.findOneByLogin(userLogin); + if (!user.isPresent()) { + throw new InternalServerErrorException("User could not be found"); + } + userService.updateUser(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(), + userDTO.getLangKey(), userDTO.getImageUrl()); + } /** - * POST /account/change_password : changes the current user's password + * POST /account/change-password : changes the current user's password * * @param password the new password - * @return the ResponseEntity with status 200 (OK), or status 400 (Bad Request) if the new password is not strong enough + * @throws InvalidPasswordException 400 (Bad Request) if the new password is incorrect */ - @PostMapping(path = "/account/change_password", - produces = MediaType.TEXT_PLAIN_VALUE) + @PostMapping(path = "/account/change-password") @Timed - public ResponseEntity changePassword(@RequestBody String password) { + public void changePassword(@RequestBody String password) { if (!checkPasswordLength(password)) { - return new ResponseEntity<>(CHECK_ERROR_MESSAGE, HttpStatus.BAD_REQUEST); + throw new InvalidPasswordException(); } userService.changePassword(password); - return new ResponseEntity<>(HttpStatus.OK); - } + } /** - * POST /account/reset_password/init : Send an email to reset the password of the user + * POST /account/reset-password/init : Send an email to reset the password of the user * * @param mail the mail of the user - * @return the ResponseEntity with status 200 (OK) if the email was sent, or status 400 (Bad Request) if the email address is not registered + * @throws EmailNotFoundException 400 (Bad Request) if the email address is not registered */ - @PostMapping(path = "/account/reset_password/init", - produces = MediaType.TEXT_PLAIN_VALUE) + @PostMapping(path = "/account/reset-password/init") @Timed - public ResponseEntity requestPasswordReset(@RequestBody String mail) { - return userService.requestPasswordReset(mail) - .map(user -> { - mailService.sendPasswordResetMail(user); - return new ResponseEntity<>("email was sent", HttpStatus.OK); - }).orElse(new ResponseEntity<>("email address not registered", HttpStatus.BAD_REQUEST)); + public void requestPasswordReset(@RequestBody String mail) { + mailService.sendPasswordResetMail( + userService.requestPasswordReset(mail) + .orElseThrow(EmailNotFoundException::new) + ); } /** - * POST /account/reset_password/finish : Finish to reset the password of the user + * POST /account/reset-password/finish : Finish to reset the password of the user * * @param keyAndPassword the generated key and the new password - * @return the ResponseEntity with status 200 (OK) if the password has been reset, - * or status 400 (Bad Request) or 500 (Internal Server Error) if the password could not be reset + * @throws InvalidPasswordException 400 (Bad Request) if the password is incorrect + * @throws RuntimeException 500 (Internal Server Error) if the password could not be reset */ - @PostMapping(path = "/account/reset_password/finish", - produces = MediaType.TEXT_PLAIN_VALUE) + @PostMapping(path = "/account/reset-password/finish") @Timed - public ResponseEntity finishPasswordReset(@RequestBody KeyAndPasswordVM keyAndPassword) { + public void finishPasswordReset(@RequestBody KeyAndPasswordVM keyAndPassword) { if (!checkPasswordLength(keyAndPassword.getNewPassword())) { - return new ResponseEntity<>(CHECK_ERROR_MESSAGE, HttpStatus.BAD_REQUEST); + throw new InvalidPasswordException(); + } + Optional user = + userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey()); + + if (!user.isPresent()) { + throw new InternalServerErrorException("No user was found for this reset key"); } - return userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey()) - .map(user -> new ResponseEntity(HttpStatus.OK)) - .orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); } - private boolean checkPasswordLength(String password) { + private static boolean checkPasswordLength(String password) { return !StringUtils.isEmpty(password) && password.length() >= ManagedUserVM.PASSWORD_MIN_LENGTH && password.length() <= ManagedUserVM.PASSWORD_MAX_LENGTH; diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/AuditResource.java b/src/main/java/org/exampleapps/greatbig/web/rest/AuditResource.java index d322f035..465dcfc8 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/AuditResource.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/AuditResource.java @@ -4,7 +4,6 @@ import org.exampleapps.greatbig.web.rest.util.PaginationUtil; import io.github.jhipster.web.util.ResponseUtil; -import io.swagger.annotations.ApiParam; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -31,13 +30,13 @@ public AuditResource(AuditEventService auditEventService) { } /** - * GET /audits : get a page of AuditEvents. + * GET /audits : get a page of AuditEvents. * * @param pageable the pagination information * @return the ResponseEntity with status 200 (OK) and the list of AuditEvents in body */ @GetMapping - public ResponseEntity> getAll(@ApiParam Pageable pageable) { + public ResponseEntity> getAll(Pageable pageable) { Page page = auditEventService.findAll(pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/management/audits"); return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); @@ -55,7 +54,7 @@ public ResponseEntity> getAll(@ApiParam Pageable pageable) { public ResponseEntity> getByDates( @RequestParam(value = "fromDate") LocalDate fromDate, @RequestParam(value = "toDate") LocalDate toDate, - @ApiParam Pageable pageable) { + Pageable pageable) { Page page = auditEventService.findByDates( fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant(), diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/SocialController.java b/src/main/java/org/exampleapps/greatbig/web/rest/SocialController.java index 5a2265c8..fa29eb78 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/SocialController.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/SocialController.java @@ -1,5 +1,6 @@ package org.exampleapps.greatbig.web.rest; +import org.exampleapps.greatbig.config.Constants; import org.exampleapps.greatbig.service.SocialService; import org.slf4j.Logger; @@ -28,7 +29,7 @@ public SocialController(SocialService socialService, ProviderSignInUtils provide } @GetMapping("/signup") - public RedirectView signUp(WebRequest webRequest, @CookieValue(name = "NG_TRANSLATE_LANG_KEY", required = false, defaultValue = "\"en\"") String langKey) { + public RedirectView signUp(WebRequest webRequest, @CookieValue(name = "NG_TRANSLATE_LANG_KEY", required = false, defaultValue = Constants.DEFAULT_LANGUAGE) String langKey) { try { Connection connection = providerSignInUtils.getConnectionFromSession(webRequest); socialService.createSocialUser(connection, langKey.replace("\"", "")); diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/UserJWTController.java b/src/main/java/org/exampleapps/greatbig/web/rest/UserJWTController.java index 1ce117be..825703fa 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/UserJWTController.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/UserJWTController.java @@ -7,20 +7,16 @@ import com.codahale.metrics.annotation.Timed; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; -import java.util.Collections; /** * Controller to authenticate users. @@ -29,8 +25,6 @@ @RequestMapping("/api") public class UserJWTController { - private final Logger log = LoggerFactory.getLogger(UserJWTController.class); - private final TokenProvider tokenProvider; private final AuthenticationManager authenticationManager; @@ -42,23 +36,18 @@ public UserJWTController(TokenProvider tokenProvider, AuthenticationManager auth @PostMapping("/authenticate") @Timed - public ResponseEntity authorize(@Valid @RequestBody LoginVM loginVM, HttpServletResponse response) { + public ResponseEntity authorize(@Valid @RequestBody LoginVM loginVM) { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword()); - try { - Authentication authentication = this.authenticationManager.authenticate(authenticationToken); - SecurityContextHolder.getContext().setAuthentication(authentication); - boolean rememberMe = (loginVM.isRememberMe() == null) ? false : loginVM.isRememberMe(); - String jwt = tokenProvider.createToken(authentication, rememberMe); - response.addHeader(JWTConfigurer.AUTHORIZATION_HEADER, "Bearer " + jwt); - return ResponseEntity.ok(new JWTToken(jwt)); - } catch (AuthenticationException ae) { - log.trace("Authentication exception trace: {}", ae); - return new ResponseEntity<>(Collections.singletonMap("AuthenticationException", - ae.getLocalizedMessage()), HttpStatus.UNAUTHORIZED); - } + Authentication authentication = this.authenticationManager.authenticate(authenticationToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + boolean rememberMe = (loginVM.isRememberMe() == null) ? false : loginVM.isRememberMe(); + String jwt = tokenProvider.createToken(authentication, rememberMe); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(JWTConfigurer.AUTHORIZATION_HEADER, "Bearer " + jwt); + return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK); } /** diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/UserResource.java b/src/main/java/org/exampleapps/greatbig/web/rest/UserResource.java index 6df637b8..559060b1 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/UserResource.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/UserResource.java @@ -9,11 +9,12 @@ import org.exampleapps.greatbig.service.MailService; import org.exampleapps.greatbig.service.UserService; import org.exampleapps.greatbig.service.dto.UserDTO; -import org.exampleapps.greatbig.web.rest.vm.ManagedUserVM; +import org.exampleapps.greatbig.web.rest.errors.BadRequestAlertException; +import org.exampleapps.greatbig.web.rest.errors.EmailAlreadyUsedException; +import org.exampleapps.greatbig.web.rest.errors.LoginAlreadyUsedException; import org.exampleapps.greatbig.web.rest.util.HeaderUtil; import org.exampleapps.greatbig.web.rest.util.PaginationUtil; import io.github.jhipster.web.util.ResponseUtil; -import io.swagger.annotations.ApiParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,22 +65,19 @@ public class UserResource { private final Logger log = LoggerFactory.getLogger(UserResource.class); - private static final String ENTITY_NAME = "userManagement"; - private final UserRepository userRepository; - private final MailService mailService; - private final UserService userService; + private final MailService mailService; + private final UserSearchRepository userSearchRepository; - public UserResource(UserRepository userRepository, MailService mailService, - UserService userService, UserSearchRepository userSearchRepository) { + public UserResource(UserRepository userRepository, UserService userService, MailService mailService, UserSearchRepository userSearchRepository) { this.userRepository = userRepository; - this.mailService = mailService; this.userService = userService; + this.mailService = mailService; this.userSearchRepository = userSearchRepository; } @@ -90,31 +88,26 @@ public UserResource(UserRepository userRepository, MailService mailService, * mail with an activation link. * The user needs to be activated on creation. * - * @param managedUserVM the user to create + * @param userDTO the user to create * @return the ResponseEntity with status 201 (Created) and with body the new user, or with status 400 (Bad Request) if the login or email is already in use * @throws URISyntaxException if the Location URI syntax is incorrect + * @throws BadRequestAlertException 400 (Bad Request) if the login or email is already in use */ @PostMapping("/users") @Timed @Secured(AuthoritiesConstants.ADMIN) - public ResponseEntity createUser(@Valid @RequestBody ManagedUserVM managedUserVM) throws URISyntaxException { - log.debug("REST request to save User : {}", managedUserVM); - - if (managedUserVM.getId() != null) { - return ResponseEntity.badRequest() - .headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "idexists", "A new user cannot already have an ID")) - .body(null); - // Lowercase the user login before comparing with database - } else if (userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()).isPresent()) { - return ResponseEntity.badRequest() - .headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "userexists", "Login already in use")) - .body(null); - } else if (userRepository.findOneByEmail(managedUserVM.getEmail()).isPresent()) { - return ResponseEntity.badRequest() - .headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "emailexists", "Email already in use")) - .body(null); + public ResponseEntity createUser(@Valid @RequestBody UserDTO userDTO) throws URISyntaxException { + log.debug("REST request to save User : {}", userDTO); + + if (userDTO.getId() != null) { + throw new BadRequestAlertException("A new user cannot already have an ID", "userManagement", "idexists"); + // Lowercase the user login before comparing with database + } else if (userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).isPresent()) { + throw new LoginAlreadyUsedException(); + } else if (userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).isPresent()) { + throw new EmailAlreadyUsedException(); } else { - User newUser = userService.createUser(managedUserVM); + User newUser = userService.createUser(userDTO); mailService.sendCreationEmail(newUser); return ResponseEntity.created(new URI("/api/users/" + newUser.getLogin())) .headers(HeaderUtil.createAlert( "userManagement.created", newUser.getLogin())) @@ -123,41 +116,41 @@ public ResponseEntity createUser(@Valid @RequestBody ManagedUserVM managedUserVM } /** - * PUT /users : Updates an existing User. + * PUT /users : Updates an existing User. * - * @param managedUserVM the user to update - * @return the ResponseEntity with status 200 (OK) and with body the updated user, - * or with status 400 (Bad Request) if the login or email is already in use, - * or with status 500 (Internal Server Error) if the user couldn't be updated + * @param userDTO the user to update + * @return the ResponseEntity with status 200 (OK) and with body the updated user + * @throws EmailAlreadyUsedException 400 (Bad Request) if the email is already in use + * @throws LoginAlreadyUsedException 400 (Bad Request) if the login is already in use */ @PutMapping("/users") @Timed @Secured(AuthoritiesConstants.ADMIN) - public ResponseEntity updateUser(@Valid @RequestBody ManagedUserVM managedUserVM) { - log.debug("REST request to update User : {}", managedUserVM); - Optional existingUser = userRepository.findOneByEmail(managedUserVM.getEmail()); - if (existingUser.isPresent() && (!existingUser.get().getId().equals(managedUserVM.getId()))) { - return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "emailexists", "Email already in use")).body(null); + public ResponseEntity updateUser(@Valid @RequestBody UserDTO userDTO) { + log.debug("REST request to update User : {}", userDTO); + Optional existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()); + if (existingUser.isPresent() && (!existingUser.get().getId().equals(userDTO.getId()))) { + throw new EmailAlreadyUsedException(); } - existingUser = userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()); - if (existingUser.isPresent() && (!existingUser.get().getId().equals(managedUserVM.getId()))) { - return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "userexists", "Login already in use")).body(null); + existingUser = userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()); + if (existingUser.isPresent() && (!existingUser.get().getId().equals(userDTO.getId()))) { + throw new LoginAlreadyUsedException(); } - Optional updatedUser = userService.updateUser(managedUserVM); + Optional updatedUser = userService.updateUser(userDTO); return ResponseUtil.wrapOrNotFound(updatedUser, - HeaderUtil.createAlert("userManagement.updated", managedUserVM.getLogin())); + HeaderUtil.createAlert("userManagement.updated", userDTO.getLogin())); } /** - * GET /users : get all users. + * GET /users : get all users. * * @param pageable the pagination information * @return the ResponseEntity with status 200 (OK) and with body all users */ @GetMapping("/users") @Timed - public ResponseEntity> getAllUsers(@ApiParam Pageable pageable) { + public ResponseEntity> getAllUsers(Pageable pageable) { final Page page = userService.getAllManagedUsers(pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/users"); return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); @@ -174,7 +167,7 @@ public List getAuthorities() { } /** - * GET /users/:login : get the "login" user. + * GET /users/:login : get the "login" user. * * @param login the login of the user to find * @return the ResponseEntity with status 200 (OK) and with body the "login" user, or with status 404 (Not Found) @@ -204,7 +197,7 @@ public ResponseEntity deleteUser(@PathVariable String login) { } /** - * SEARCH /_search/users/:query : search for the User corresponding + * SEARCH /_search/users/:query : search for the User corresponding * to the query. * * @param query the query to search diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/BadRequestAlertException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/BadRequestAlertException.java new file mode 100644 index 00000000..649b8be3 --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/BadRequestAlertException.java @@ -0,0 +1,40 @@ +package org.exampleapps.greatbig.web.rest.errors; + +import org.zalando.problem.AbstractThrowableProblem; +import org.zalando.problem.Status; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +public class BadRequestAlertException extends AbstractThrowableProblem { + + private final String entityName; + + private final String errorKey; + + public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) { + this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey); + } + + public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) { + super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(entityName, errorKey)); + this.entityName = entityName; + this.errorKey = errorKey; + } + + public String getEntityName() { + return entityName; + } + + public String getErrorKey() { + return errorKey; + } + + private static Map getAlertParameters(String entityName, String errorKey) { + Map parameters = new HashMap<>(); + parameters.put("message", "error." + errorKey); + parameters.put("params", entityName); + return parameters; + } +} diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/CustomParameterizedException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/CustomParameterizedException.java index 6742125d..4945a4c2 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/errors/CustomParameterizedException.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/CustomParameterizedException.java @@ -1,8 +1,12 @@ package org.exampleapps.greatbig.web.rest.errors; +import org.zalando.problem.AbstractThrowableProblem; + import java.util.HashMap; import java.util.Map; +import static org.zalando.problem.Status.BAD_REQUEST; + /** * Custom, parameterized exception, which can be translated on the client side. * For example: @@ -17,33 +21,34 @@ * "error.myCustomError" : "The server says {{param0}} to {{param1}}" * */ -public class CustomParameterizedException extends RuntimeException { +public class CustomParameterizedException extends AbstractThrowableProblem { private static final long serialVersionUID = 1L; private static final String PARAM = "param"; - private final String message; + public CustomParameterizedException(String message, String... params) { + this(message, toParamMap(params)); + } - private final Map paramMap = new HashMap<>(); + public CustomParameterizedException(String message, Map paramMap) { + super(ErrorConstants.PARAMETERIZED_TYPE, "Parameterized Exception", BAD_REQUEST, null, null, null, toProblemParameters(message, paramMap)); + } - public CustomParameterizedException(String message, String... params) { - super(message); - this.message = message; + public static Map toParamMap(String... params) { + Map paramMap = new HashMap<>(); if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { paramMap.put(PARAM + i, params[i]); } } + return paramMap; } - public CustomParameterizedException(String message, Map paramMap) { - super(message); - this.message = message; - this.paramMap.putAll(paramMap); - } - - public ParameterizedErrorVM getErrorVM() { - return new ParameterizedErrorVM(message, paramMap); + public static Map toProblemParameters(String message, Map paramMap) { + Map parameters = new HashMap<>(); + parameters.put("message", message); + parameters.put("params", paramMap); + return parameters; } } diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/EmailAlreadyUsedException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/EmailAlreadyUsedException.java new file mode 100644 index 00000000..8f20e72a --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/EmailAlreadyUsedException.java @@ -0,0 +1,8 @@ +package org.exampleapps.greatbig.web.rest.errors; + +public class EmailAlreadyUsedException extends BadRequestAlertException { + + public EmailAlreadyUsedException() { + super(ErrorConstants.EMAIL_ALREADY_USED_TYPE, "Email address already in use", "userManagement", "emailexists"); + } +} diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/EmailNotFoundException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/EmailNotFoundException.java new file mode 100644 index 00000000..fe127e7d --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/EmailNotFoundException.java @@ -0,0 +1,11 @@ +package org.exampleapps.greatbig.web.rest.errors; + +import org.zalando.problem.AbstractThrowableProblem; +import org.zalando.problem.Status; + +public class EmailNotFoundException extends AbstractThrowableProblem { + + public EmailNotFoundException() { + super(ErrorConstants.EMAIL_NOT_FOUND_TYPE, "Email address not registered", Status.BAD_REQUEST); + } +} diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/ErrorConstants.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/ErrorConstants.java index e4c379d6..1e991d54 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/errors/ErrorConstants.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/ErrorConstants.java @@ -1,14 +1,20 @@ package org.exampleapps.greatbig.web.rest.errors; +import java.net.URI; + public final class ErrorConstants { public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure"; - public static final String ERR_ACCESS_DENIED = "error.accessDenied"; public static final String ERR_VALIDATION = "error.validation"; - public static final String ERR_METHOD_NOT_SUPPORTED = "error.methodNotSupported"; - public static final String ERR_INTERNAL_SERVER_ERROR = "error.internalServerError"; + public static final String PROBLEM_BASE_URL = "http://www.jhipster.tech/problem"; + public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); + public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); + public static final URI PARAMETERIZED_TYPE = URI.create(PROBLEM_BASE_URL + "/parameterized"); + public static final URI INVALID_PASSWORD_TYPE = URI.create(PROBLEM_BASE_URL + "/invalid-password"); + public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used"); + public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used"); + public static final URI EMAIL_NOT_FOUND_TYPE = URI.create(PROBLEM_BASE_URL + "/email-not-found"); private ErrorConstants() { } - } diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/ExceptionTranslator.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/ExceptionTranslator.java index 3dd1f02d..e0291ebe 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/errors/ExceptionTranslator.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/ExceptionTranslator.java @@ -1,87 +1,98 @@ package org.exampleapps.greatbig.web.rest.errors; -import java.util.List; +import org.exampleapps.greatbig.web.rest.util.HeaderUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.annotation.AnnotationUtils; import org.springframework.dao.ConcurrencyFailureException; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.ResponseEntity.BodyBuilder; -import org.springframework.security.access.AccessDeniedException; import org.springframework.validation.BindingResult; -import org.springframework.validation.FieldError; -import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.NativeWebRequest; +import org.zalando.problem.DefaultProblem; +import org.zalando.problem.Problem; +import org.zalando.problem.ProblemBuilder; +import org.zalando.problem.Status; +import org.zalando.problem.spring.web.advice.ProblemHandling; +import org.zalando.problem.spring.web.advice.validation.ConstraintViolationProblem; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.stream.Collectors; /** * Controller advice to translate the server side exceptions to client-friendly json structures. + * The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807) */ @ControllerAdvice -public class ExceptionTranslator { +public class ExceptionTranslator implements ProblemHandling { - private final Logger log = LoggerFactory.getLogger(ExceptionTranslator.class); - - @ExceptionHandler(ConcurrencyFailureException.class) - @ResponseStatus(HttpStatus.CONFLICT) - @ResponseBody - public ErrorVM processConcurrencyError(ConcurrencyFailureException ex) { - return new ErrorVM(ErrorConstants.ERR_CONCURRENCY_FAILURE); - } + /** + * Post-process Problem payload to add the message key for front-end if needed + */ + @Override + public ResponseEntity process(@Nullable ResponseEntity entity, NativeWebRequest request) { + if (entity == null || entity.getBody() == null) { + return entity; + } + Problem problem = entity.getBody(); + if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) { + return entity; + } + ProblemBuilder builder = Problem.builder() + .withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType()) + .withStatus(problem.getStatus()) + .withTitle(problem.getTitle()) + .with("path", request.getNativeRequest(HttpServletRequest.class).getRequestURI()); - @ExceptionHandler(MethodArgumentNotValidException.class) - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ResponseBody - public ErrorVM processValidationError(MethodArgumentNotValidException ex) { - BindingResult result = ex.getBindingResult(); - List fieldErrors = result.getFieldErrors(); - ErrorVM dto = new ErrorVM(ErrorConstants.ERR_VALIDATION); - for (FieldError fieldError : fieldErrors) { - dto.add(fieldError.getObjectName(), fieldError.getField(), fieldError.getCode()); + if (problem instanceof ConstraintViolationProblem) { + builder + .with("violations", ((ConstraintViolationProblem) problem).getViolations()) + .with("message", ErrorConstants.ERR_VALIDATION); + return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode()); + } else { + builder + .withCause(((DefaultProblem) problem).getCause()) + .withDetail(problem.getDetail()) + .withInstance(problem.getInstance()); + problem.getParameters().forEach(builder::with); + if (!problem.getParameters().containsKey("message") && problem.getStatus() != null) { + builder.with("message", "error.http." + problem.getStatus().getStatusCode()); + } + return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode()); } - return dto; } - @ExceptionHandler(CustomParameterizedException.class) - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ResponseBody - public ParameterizedErrorVM processParameterizedValidationError(CustomParameterizedException ex) { - return ex.getErrorVM(); - } + @Override + public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, @Nonnull NativeWebRequest request) { + BindingResult result = ex.getBindingResult(); + List fieldErrors = result.getFieldErrors().stream() + .map(f -> new FieldErrorVM(f.getObjectName(), f.getField(), f.getCode())) + .collect(Collectors.toList()); - @ExceptionHandler(AccessDeniedException.class) - @ResponseStatus(HttpStatus.FORBIDDEN) - @ResponseBody - public ErrorVM processAccessDeniedException(AccessDeniedException e) { - return new ErrorVM(ErrorConstants.ERR_ACCESS_DENIED, e.getMessage()); + Problem problem = Problem.builder() + .withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE) + .withTitle("Method argument not valid") + .withStatus(defaultConstraintViolationStatus()) + .with("message", ErrorConstants.ERR_VALIDATION) + .with("fieldErrors", fieldErrors) + .build(); + return create(ex, problem, request); } - @ExceptionHandler(HttpRequestMethodNotSupportedException.class) - @ResponseBody - @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) - public ErrorVM processMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) { - return new ErrorVM(ErrorConstants.ERR_METHOD_NOT_SUPPORTED, exception.getMessage()); + @ExceptionHandler(BadRequestAlertException.class) + public ResponseEntity handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) { + return create(ex, request, HeaderUtil.createFailureAlert(ex.getEntityName(), ex.getErrorKey(), ex.getMessage())); } - @ExceptionHandler(Exception.class) - public ResponseEntity processException(Exception ex) { - if (log.isDebugEnabled()) { - log.debug("An unexpected error occurred: {}", ex.getMessage(), ex); - } else { - log.error("An unexpected error occurred: {}", ex.getMessage()); - } - BodyBuilder builder; - ErrorVM errorVM; - ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class); - if (responseStatus != null) { - builder = ResponseEntity.status(responseStatus.value()); - errorVM = new ErrorVM("error." + responseStatus.value().value(), responseStatus.reason()); - } else { - builder = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR); - errorVM = new ErrorVM(ErrorConstants.ERR_INTERNAL_SERVER_ERROR, "Internal server error"); - } - return builder.body(errorVM); + @ExceptionHandler(ConcurrencyFailureException.class) + public ResponseEntity handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) { + Problem problem = Problem.builder() + .withStatus(Status.CONFLICT) + .with("message", ErrorConstants.ERR_CONCURRENCY_FAILURE) + .build(); + return create(ex, problem, request); } } diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/InternalServerErrorException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/InternalServerErrorException.java new file mode 100644 index 00000000..9f0af529 --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/InternalServerErrorException.java @@ -0,0 +1,14 @@ +package org.exampleapps.greatbig.web.rest.errors; + +import org.zalando.problem.AbstractThrowableProblem; +import org.zalando.problem.Status; + +/** + * Simple exception with a message, that returns an Internal Server Error code. + */ +public class InternalServerErrorException extends AbstractThrowableProblem { + + public InternalServerErrorException(String message) { + super(ErrorConstants.DEFAULT_TYPE, message, Status.INTERNAL_SERVER_ERROR); + } +} diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/InvalidPasswordException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/InvalidPasswordException.java new file mode 100644 index 00000000..c9068398 --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/InvalidPasswordException.java @@ -0,0 +1,11 @@ +package org.exampleapps.greatbig.web.rest.errors; + +import org.zalando.problem.AbstractThrowableProblem; +import org.zalando.problem.Status; + +public class InvalidPasswordException extends AbstractThrowableProblem { + + public InvalidPasswordException() { + super(ErrorConstants.INVALID_PASSWORD_TYPE, "Incorrect password", Status.BAD_REQUEST); + } +} diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/LoginAlreadyUsedException.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/LoginAlreadyUsedException.java new file mode 100644 index 00000000..e70e23df --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/LoginAlreadyUsedException.java @@ -0,0 +1,8 @@ +package org.exampleapps.greatbig.web.rest.errors; + +public class LoginAlreadyUsedException extends BadRequestAlertException { + + public LoginAlreadyUsedException() { + super(ErrorConstants.LOGIN_ALREADY_USED_TYPE, "Login already in use", "userManagement", "userexists"); + } +} diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/errors/package-info.java b/src/main/java/org/exampleapps/greatbig/web/rest/errors/package-info.java new file mode 100644 index 00000000..82b902b2 --- /dev/null +++ b/src/main/java/org/exampleapps/greatbig/web/rest/errors/package-info.java @@ -0,0 +1,6 @@ +/** + * Specific errors used with Zalando's "problem-spring-web" library. + * + * More information on https://github.com/zalando/problem-spring-web + */ +package org.exampleapps.greatbig.web.rest.errors; diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/util/HeaderUtil.java b/src/main/java/org/exampleapps/greatbig/web/rest/util/HeaderUtil.java index dec7a217..26cb828c 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/util/HeaderUtil.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/util/HeaderUtil.java @@ -3,6 +3,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; + /** * Utility class for HTTP headers creation. */ diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/util/PaginationUtil.java b/src/main/java/org/exampleapps/greatbig/web/rest/util/PaginationUtil.java index 45bf3cba..b0158209 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/util/PaginationUtil.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/util/PaginationUtil.java @@ -11,7 +11,7 @@ * Utility class for handling pagination. * *

- * Pagination uses the same principles as the Github API, + * Pagination uses the same principles as the GitHub API, * and follow RFC 5988 (Link header). */ public final class PaginationUtil { diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/vm/LoginVM.java b/src/main/java/org/exampleapps/greatbig/web/rest/vm/LoginVM.java index f6c89031..cd15a954 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/vm/LoginVM.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/vm/LoginVM.java @@ -1,8 +1,6 @@ package org.exampleapps.greatbig.web.rest.vm; -import org.exampleapps.greatbig.config.Constants; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; /** @@ -10,7 +8,6 @@ */ public class LoginVM { - @Pattern(regexp = Constants.LOGIN_REGEX) @NotNull @Size(min = 1, max = 50) private String username; diff --git a/src/main/java/org/exampleapps/greatbig/web/rest/vm/ManagedUserVM.java b/src/main/java/org/exampleapps/greatbig/web/rest/vm/ManagedUserVM.java index f2b33e1f..5c9c31dd 100644 --- a/src/main/java/org/exampleapps/greatbig/web/rest/vm/ManagedUserVM.java +++ b/src/main/java/org/exampleapps/greatbig/web/rest/vm/ManagedUserVM.java @@ -3,9 +3,6 @@ import org.exampleapps.greatbig.service.dto.UserDTO; import javax.validation.constraints.Size; -import java.time.Instant; -import java.util.Set; - /** * View Model extending the UserDTO, which is meant to be used in the user management UI. */ @@ -18,31 +15,18 @@ public class ManagedUserVM extends UserDTO { @Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH) private String password; - private String bio; - - public String getBio() { - return bio; - } - public ManagedUserVM() { // Empty constructor needed for Jackson. } - public ManagedUserVM(Long id, String login, String password, String firstName, String lastName, - String email, boolean activated, String imageUrl, String langKey, - String createdBy, Instant createdDate, String lastModifiedBy, Instant lastModifiedDate, - Set authorities) { - - super(id, login, firstName, lastName, email, activated, imageUrl, langKey, - createdBy, createdDate, lastModifiedBy, lastModifiedDate, authorities); - - this.password = password; - } - public String getPassword() { return password; } + public void setPassword(String password) { + this.password = password; + } + @Override public String toString() { return "ManagedUserVM{" + diff --git a/src/main/java/org/exampleapps/greatbig/web/websocket/ChatService.java b/src/main/java/org/exampleapps/greatbig/web/websocket/ChatService.java index 6372541b..dca8ec97 100644 --- a/src/main/java/org/exampleapps/greatbig/web/websocket/ChatService.java +++ b/src/main/java/org/exampleapps/greatbig/web/websocket/ChatService.java @@ -45,7 +45,7 @@ public ChatService(SimpMessageSendingOperations messagingTemplate, MessageReposi @SubscribeMapping("/chat/public") public void subscribe(StompHeaderAccessor stompHeaderAccessor, Principal principal) { - String login = SecurityUtils.getCurrentUserLogin(); + String login = SecurityUtils.getCurrentUserLogin().get(); String ipAddress = stompHeaderAccessor.getSessionAttributes().get(IP_ADDRESS).toString(); log.debug("User {} subscribed to Chat from IP {}", login, ipAddress); MessageDTO messageDTO = new MessageDTO(); diff --git a/src/main/kotlin/org/exampleapps/greatbig/web/rest/ArticleHandler.kt b/src/main/kotlin/org/exampleapps/greatbig/web/rest/ArticleHandler.kt index e8e9b7ee..0b572d66 100644 --- a/src/main/kotlin/org/exampleapps/greatbig/web/rest/ArticleHandler.kt +++ b/src/main/kotlin/org/exampleapps/greatbig/web/rest/ArticleHandler.kt @@ -67,7 +67,7 @@ class ArticleHandler(val repository: ArticleRepository, if (favorited != "") userRepository.findOneByLogin(favorited).get() else null ), p) val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) val headers = PaginationUtil.generatePaginationHttpHeaders(articles, "/api/articles") @@ -83,7 +83,7 @@ class ArticleHandler(val repository: ArticleRepository, log.debug("\n\nREST request to get article feed") val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) val articles = repository.findByAuthorIdInOrderByCreatedAtDesc(currentAuthor.followers.map { it.id }, PageRequest(offset/limit, limit)) @@ -100,7 +100,7 @@ class ArticleHandler(val repository: ArticleRepository, log.debug("\n\nREST request to get Article for : ", slug) val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) repository.findBySlug(slug)?.let { return articleView(it, currentAuthor) } @@ -123,7 +123,7 @@ class ArticleHandler(val repository: ArticleRepository, } val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) // search for tags val tags = newArticle.tags.map { @@ -146,8 +146,8 @@ class ArticleHandler(val repository: ArticleRepository, repository.findBySlug(slug)?.let { val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) - if (it.author.id != currentUser.id) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) + if (it.author.id != currentUser.get().getId()) throw ForbiddenRequestException() // check for errors @@ -200,7 +200,7 @@ class ArticleHandler(val repository: ArticleRepository, log.debug("\n\nREST request to delete Article for: ", slug) repository.findBySlug(slug)?.let { - if (it.author.id != userService.getUserWithAuthorities().id) + if (it.author.id != userService.getUserWithAuthorities().get().getId()) throw ForbiddenRequestException() // commentRepository.deleteAll(commentRepository.findByArticle(it)) @@ -218,7 +218,7 @@ class ArticleHandler(val repository: ArticleRepository, repository.findBySlug(slug)?.let { val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) return commentsView(commentRepository.findByArticleOrderByCreatedAtDesc(it), currentAuthor) } throw NotFoundException() @@ -235,7 +235,7 @@ class ArticleHandler(val repository: ArticleRepository, repository.findBySlug(slug)?.let { val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) val newComment = Comment(body = comment.body!!, article = it, author = currentAuthor) return commentView(commentRepository.save(newComment), currentAuthor) } @@ -258,7 +258,7 @@ class ArticleHandler(val repository: ArticleRepository, } if (comment.article.id != it.id) throw ForbiddenRequestException() - if (comment.author.id != currentUser.id) + if (comment.author.id != currentUser.get().getId()) throw ForbiddenRequestException() return commentRepository.delete(comment) @@ -275,7 +275,7 @@ class ArticleHandler(val repository: ArticleRepository, repository.findBySlug(slug)?.let { val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) if (!it.favorited.contains(currentAuthor)) { it.favorited.add(currentAuthor) return articleView(repository.save(it), currentAuthor) @@ -294,7 +294,7 @@ class ArticleHandler(val repository: ArticleRepository, repository.findBySlug(slug)?.let { val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) if (it.favorited.contains(currentAuthor)) { it.favorited.remove(currentAuthor) return articleView(repository.save(it), currentAuthor) diff --git a/src/main/kotlin/org/exampleapps/greatbig/web/rest/ProfileHandler.kt b/src/main/kotlin/org/exampleapps/greatbig/web/rest/ProfileHandler.kt index 89889ad6..26bbc677 100644 --- a/src/main/kotlin/org/exampleapps/greatbig/web/rest/ProfileHandler.kt +++ b/src/main/kotlin/org/exampleapps/greatbig/web/rest/ProfileHandler.kt @@ -23,7 +23,7 @@ class ProfileHandler(val userRepository: UserRepository, val user = userRepository.findOneByLogin(username); authorRepository.findById(user.get().getId())?.let { val currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) return view(it, currentAuthor) } throw NotFoundException() @@ -36,7 +36,7 @@ class ProfileHandler(val userRepository: UserRepository, val user = userRepository.findOneByLogin(username); authorRepository.findById(user.get().getId())?.let { var currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) if (!currentAuthor.followers.contains(it)) { currentAuthor.followers.add(it) // currentAuthor = userService.setCurrentUser(userRepository.save(currentUser)) @@ -53,7 +53,7 @@ class ProfileHandler(val userRepository: UserRepository, val user = userRepository.findOneByLogin(username); authorRepository.findById(user.get().getId())?.let { var currentUser = userService.getUserWithAuthorities() - val currentAuthor = authorRepository.findById(currentUser.getId()) + val currentAuthor = authorRepository.findById(currentUser.get().getId()) if (currentAuthor.followers.contains(it)) { currentAuthor.followers.remove(it) // currentAuthor = userService.setCurrentUser(userRepository.save(currentUser)) diff --git a/src/main/resources/.h2.server.properties b/src/main/resources/.h2.server.properties index 816f35da..520078d3 100644 --- a/src/main/resources/.h2.server.properties +++ b/src/main/resources/.h2.server.properties @@ -1,6 +1,5 @@ #H2 Server Properties -# 0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/greatbigexampleapplication|GreatBigExampleApplication -0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:mem\:greatBigExampleApplication|greatBigExampleApplication +0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/greatbigexampleapplication|GreatBigExampleApplication webAllowOthers=true webPort=8082 webSSL=false diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt index c3d8cf72..db090f7e 100644 --- a/src/main/resources/banner.txt +++ b/src/main/resources/banner.txt @@ -7,4 +7,4 @@ ${AnsiColor.GREEN} ╚═════╝ ${AnsiColor.RED} ╚═╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═╝ ${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} :: -:: http://jhipster.github.io ::${AnsiColor.DEFAULT} +:: http://www.jhipster.tech ::${AnsiColor.DEFAULT} diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml index 7d49f315..1c7e988f 100644 --- a/src/main/resources/config/application-dev.yml +++ b/src/main/resources/config/application-dev.yml @@ -3,8 +3,8 @@ # # This configuration overrides the application.yml file. # -# More information on profiles: https://jhipster.github.io/profiles/ -# More information on configuration properties: https://jhipster.github.io/common-application-properties/ +# More information on profiles: http://www.jhipster.tech/profiles/ +# More information on configuration properties: http://www.jhipster.tech/common-application-properties/ # =================================================================== # =================================================================== @@ -13,6 +13,12 @@ # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html # =================================================================== +logging: + level: + ROOT: DEBUG + org.exampleapps.greatbig: DEBUG + io.github.jhipster: DEBUG + spring: profiles: active: dev @@ -26,7 +32,7 @@ spring: serialization.indent_output: true datasource: type: com.zaxxer.hikari.HikariDataSource - url: jdbc:h2:mem:greatbigexampleapplication;DB_CLOSE_DELAY=-1 + url: jdbc:h2:file:./target/h2db/db/greatbigexampleapplication;DB_CLOSE_DELAY=-1 username: GreatBigExampleApplication password: h2: @@ -51,11 +57,6 @@ spring: home: target/elasticsearch logs: target/elasticsearch/log data: target/elasticsearch/data - transport: - tcp: - connect_timeout: 120s - jest: - readTimeout: 10000 mail: host: localhost port: 25 @@ -83,8 +84,8 @@ liquibase: # ssl: # key-store: keystore.p12 # key-store-password: -# keyStoreType: PKCS12 -# keyAlias: GreatBigExampleApplication +# key-store-type: PKCS12 +# key-alias: GreatBigExampleApplication # =================================================================== server: port: 8070 @@ -92,7 +93,7 @@ server: # =================================================================== # JHipster specific properties # -# Full reference is available at: https://jhipster.github.io/common-application-properties/ +# Full reference is available at: http://www.jhipster.tech/common-application-properties/ # =================================================================== jhipster: @@ -105,9 +106,9 @@ jhipster: # CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API cors: allowed-origins: "*" - allowed-methods: GET, PUT, POST, DELETE, OPTIONS + allowed-methods: "*" allowed-headers: "*" - exposed-headers: + exposed-headers: "Authorization,Link,X-Total-Count" allow-credentials: true max-age: 1800 security: @@ -140,13 +141,14 @@ jhipster: port: 5000 queue-size: 512 + # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class # to have type-safe configuration, like in the JHipsterProperties above # # More documentation is available at: -# https://jhipster.github.io/common-application-properties/ +# http://www.jhipster.tech/common-application-properties/ # =================================================================== application: diff --git a/src/main/resources/config/application-prod.yml b/src/main/resources/config/application-prod.yml index 73e445af..51fbe83b 100644 --- a/src/main/resources/config/application-prod.yml +++ b/src/main/resources/config/application-prod.yml @@ -3,8 +3,8 @@ # # This configuration overrides the application.yml file. # -# More information on profiles: https://jhipster.github.io/profiles/ -# More information on configuration properties: https://jhipster.github.io/common-application-properties/ +# More information on profiles: http://www.jhipster.tech/profiles/ +# More information on configuration properties: http://www.jhipster.tech/common-application-properties/ # =================================================================== # =================================================================== @@ -13,6 +13,12 @@ # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html # =================================================================== +logging: + level: + ROOT: INFO + org.exampleapps.greatbig: INFO + io.github.jhipster: INFO + spring: devtools: restart: @@ -22,8 +28,8 @@ spring: datasource: type: com.zaxxer.hikari.HikariDataSource url: jdbc:postgresql://localhost:5432/GreatBigExampleApplication - username: GreatBigExampleUser - password: password + username: GreatBigExampleApplication + password: jpa: database-platform: io.github.jhipster.domain.util.FixedPostgreSQL82Dialect database: POSTGRESQL @@ -38,15 +44,6 @@ spring: elasticsearch: cluster-name: cluster-nodes: localhost:9300 - properties: - path: - home: target/elasticsearch - transport: - tcp: - connect_timeout: 120s - jest: - readTimeout: 10000 - # uri: ${SEARCHBOX_SSL_URL} mail: host: localhost port: 25 @@ -72,8 +69,10 @@ liquibase: # ssl: # key-store: keystore.p12 # key-store-password: -# keyStoreType: PKCS12 -# keyAlias: GreatBigExampleApplication +# key-store-type: PKCS12 +# key-alias: GreatBigExampleApplication +# # The ciphers suite enforce the security by deactivating some old and deprecated SSL cipher, this list was tested against SSL Labs (https://www.ssllabs.com/ssltest/) +# ciphers: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA # =================================================================== server: port: 8090 @@ -85,7 +84,7 @@ server: # =================================================================== # JHipster specific properties # -# Full reference is available at: https://jhipster.github.io/common-application-properties/ +# Full reference is available at: http://www.jhipster.tech/common-application-properties/ # =================================================================== jhipster: @@ -127,13 +126,14 @@ jhipster: port: 5000 queue-size: 512 + # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class # to have type-safe configuration, like in the JHipsterProperties above # # More documentation is available at: -# https://jhipster.github.io/common-application-properties/ +# http://www.jhipster.tech/common-application-properties/ # =================================================================== application: diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index c8a4f86a..e7826c06 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -4,8 +4,8 @@ # This configuration will be overridden by the Spring profile you use, # for example application-dev.yml if you use the "dev" profile. # -# More information on profiles: https://jhipster.github.io/profiles/ -# More information on configuration properties: https://jhipster.github.io/common-application-properties/ +# More information on profiles: http://www.jhipster.tech/profiles/ +# More information on configuration properties: http://www.jhipster.tech/common-application-properties/ # =================================================================== # =================================================================== @@ -18,6 +18,9 @@ management: security: roles: ADMIN context-path: /management + info: + git: + mode: full health: mail: enabled: false # When using the MailService, configure an SMTP server and set this to true @@ -62,7 +65,6 @@ spring: client-secret: xxx # jhipster-needle-add-social-configuration - security: basic: enabled: false @@ -79,7 +81,7 @@ info: # =================================================================== # JHipster specific properties # -# Full reference is available at: https://jhipster.github.io/common-application-properties/ +# Full reference is available at: http://www.jhipster.tech/common-application-properties/ # =================================================================== jhipster: @@ -90,9 +92,9 @@ jhipster: # By default CORS is disabled. Uncomment to enable. #cors: #allowed-origins: "*" - #allowed-methods: GET, PUT, POST, DELETE, OPTIONS + #allowed-methods: "*" #allowed-headers: "*" - #exposed-headers: + #exposed-headers: "Authorization,Link,X-Total-Count" #allow-credentials: true #max-age: 1800 mail: @@ -119,7 +121,7 @@ jhipster: # to have type-safe configuration, like in the JHipsterProperties above # # More documentation is available at: -# https://jhipster.github.io/common-application-properties/ +# http://www.jhipster.tech/common-application-properties/ # =================================================================== application: diff --git a/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml index 61a18ca9..64d93ec5 100644 --- a/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml +++ b/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml @@ -3,7 +3,7 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> @@ -23,19 +23,19 @@ - + - + - + @@ -83,7 +83,6 @@ constraintName="fk_authority_name" referencedColumnNames="name" referencedTableName="jhi_authority"/> - - - diff --git a/src/main/resources/i18n/messages_fr.properties b/src/main/resources/i18n/messages_fr.properties index 226e0518..a6804026 100644 --- a/src/main/resources/i18n/messages_fr.properties +++ b/src/main/resources/i18n/messages_fr.properties @@ -12,7 +12,7 @@ email.activation.text2=Cordialement, email.signature=GreatBigExampleApplication. # Creation email -email.creation.text1=Your GreatBigExampleApplication account has been created, please click on the URL below to access it: +email.creation.text1=Votre compte GreatBigExampleApplication a été créé, merci de cliquer sur le lien ci-dessous pour y accéder : # Reset email email.reset.title=GreatBigExampleApplication Réinitialisation de mot de passe diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 0bd49303..fcc8c8dc 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -22,10 +22,6 @@ --> - - - - @@ -56,15 +52,11 @@ + + + true - - - - - diff --git a/src/main/resources/mails/activationEmail.html b/src/main/resources/mails/activationEmail.html index bc2cc907..aa382298 100644 --- a/src/main/resources/mails/activationEmail.html +++ b/src/main/resources/mails/activationEmail.html @@ -3,7 +3,7 @@ JHipster activation - +

diff --git a/src/main/resources/mails/creationEmail.html b/src/main/resources/mails/creationEmail.html index a85210da..07a6064d 100644 --- a/src/main/resources/mails/creationEmail.html +++ b/src/main/resources/mails/creationEmail.html @@ -3,7 +3,7 @@ JHipster creation - +

diff --git a/src/main/resources/mails/passwordResetEmail.html b/src/main/resources/mails/passwordResetEmail.html index 304486d6..dfddb2aa 100644 --- a/src/main/resources/mails/passwordResetEmail.html +++ b/src/main/resources/mails/passwordResetEmail.html @@ -3,7 +3,7 @@ JHipster password reset - +

diff --git a/src/main/resources/mails/socialRegistrationValidationEmail.html b/src/main/resources/mails/socialRegistrationValidationEmail.html index 0dbc68f9..a9da3403 100644 --- a/src/main/resources/mails/socialRegistrationValidationEmail.html +++ b/src/main/resources/mails/socialRegistrationValidationEmail.html @@ -3,7 +3,7 @@ JHipster activation - +

diff --git a/src/main/webapp/app/account/account.module.ts b/src/main/webapp/app/account/account.module.ts index fbd54074..307d9fa9 100644 --- a/src/main/webapp/app/account/account.module.ts +++ b/src/main/webapp/app/account/account.module.ts @@ -46,4 +46,4 @@ import { ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationAccountModule { } +export class GreatBigExampleApplicationAccountModule {} diff --git a/src/main/webapp/app/account/activate/activate.component.html b/src/main/webapp/app/account/activate/activate.component.html index c91e9a67..6a28eef7 100644 --- a/src/main/webapp/app/account/activate/activate.component.html +++ b/src/main/webapp/app/account/activate/activate.component.html @@ -1,6 +1,6 @@

-
-
+
+

Activation

diff --git a/src/main/webapp/app/account/activate/activate.component.spec.ts b/src/main/webapp/app/account/activate/activate.component.spec.ts index 6d4b2b29..074abc5c 100644 --- a/src/main/webapp/app/account/activate/activate.component.spec.ts +++ b/src/main/webapp/app/account/activate/activate.component.spec.ts @@ -1,11 +1,11 @@ import { TestBed, async, tick, fakeAsync, inject } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs/Observable'; + import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { LoginModalService } from '../../shared'; -import { ActivateService } from '../../account/activate/activate.service'; -import { ActivateComponent } from '../../account/activate/activate.component'; +import { ActivateService } from '../activate/activate.service'; +import { ActivateComponent } from '../activate/activate.component'; describe('Component Tests', () => { @@ -22,13 +22,10 @@ describe('Component Tests', () => { { provide: ActivatedRoute, useValue: new MockActivatedRoute({ 'key': 'ABC123' }) - }, - { - provide: LoginModalService, - useValue: null } ] - }).overrideTemplate(ActivateComponent, '') + }) + .overrideTemplate(ActivateComponent, '') .compileComponents(); })); diff --git a/src/main/webapp/app/account/activate/activate.service.ts b/src/main/webapp/app/account/activate/activate.service.ts index fae0a31e..b6848ac4 100644 --- a/src/main/webapp/app/account/activate/activate.service.ts +++ b/src/main/webapp/app/account/activate/activate.service.ts @@ -1,18 +1,16 @@ import { Injectable } from '@angular/core'; -import { Http, Response, URLSearchParams } from '@angular/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; @Injectable() export class ActivateService { - constructor(private http: Http) {} + constructor(private http: HttpClient) {} get(key: string): Observable { - const params: URLSearchParams = new URLSearchParams(); - params.set('key', key); - - return this.http.get('api/activate', { - search: params - }).map((res: Response) => res); + return this.http.get(SERVER_API_URL + 'api/activate', { + params: new HttpParams().set('key', key) + }); } } diff --git a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html index a1dfde05..bcbc9111 100644 --- a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html +++ b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html @@ -1,6 +1,6 @@
-
-
+
+

Reset password

diff --git a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.spec.ts b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.spec.ts index 4033f0ef..e0620c5b 100644 --- a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.spec.ts +++ b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.spec.ts @@ -1,7 +1,8 @@ -import { ComponentFixture, TestBed, inject } from '@angular/core/testing'; +import { ComponentFixture, TestBed, inject, tick, fakeAsync } from '@angular/core/testing'; +import { Observable } from 'rxjs/Observable'; import { Renderer, ElementRef } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { LoginModalService } from '../../../shared'; + import { GreatBigExampleApplicationTestModule } from '../../../../mocks/test.module'; import { PasswordResetFinishComponent } from './password-reset-finish.component'; import { PasswordResetFinishService } from './password-reset-finish.service'; @@ -20,10 +21,6 @@ describe('Component Tests', () => { declarations: [PasswordResetFinishComponent], providers: [ PasswordResetFinishService, - { - provide: LoginModalService, - useValue: null - }, { provide: ActivatedRoute, useValue: new MockActivatedRoute({ 'key': 'XYZPDQ' }) @@ -39,9 +36,15 @@ describe('Component Tests', () => { useValue: new ElementRef(null) } ] - }).overrideTemplate(PasswordResetFinishComponent, '') + }) + .overrideTemplate(PasswordResetFinishComponent, '') .createComponent(PasswordResetFinishComponent); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PasswordResetFinishComponent); comp = fixture.componentInstance; + comp.ngOnInit(); }); it('should define its initial state', () => { @@ -70,5 +73,54 @@ describe('Component Tests', () => { }) ); + it('should ensure the two passwords entered match', () => { + comp.resetAccount.password = 'password'; + comp.confirmPassword = 'non-matching'; + + comp.finishReset(); + + expect(comp.doNotMatch).toEqual('ERROR'); + }); + + it('should update success to OK after resetting password', + inject([PasswordResetFinishService], + fakeAsync((service: PasswordResetFinishService) => { + spyOn(service, 'save').and.returnValue(Observable.of({})); + + comp.resetAccount.password = 'password'; + comp.confirmPassword = 'password'; + + comp.finishReset(); + tick(); + + expect(service.save).toHaveBeenCalledWith({ + key: 'XYZPDQ', + newPassword: 'password' + }); + expect(comp.success).toEqual('OK'); + }) + ) + ); + + it('should notify of generic error', + inject([PasswordResetFinishService], + fakeAsync((service: PasswordResetFinishService) => { + spyOn(service, 'save').and.returnValue(Observable.throw('ERROR')); + + comp.resetAccount.password = 'password'; + comp.confirmPassword = 'password'; + + comp.finishReset(); + tick(); + + expect(service.save).toHaveBeenCalledWith({ + key: 'XYZPDQ', + newPassword: 'password' + }); + expect(comp.success).toBeNull(); + expect(comp.error).toEqual('ERROR'); + }) + ) + ); }); }); diff --git a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts index 4c9b30f8..74c6fb42 100644 --- a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts +++ b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts @@ -1,13 +1,14 @@ import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../../app.constants'; @Injectable() export class PasswordResetFinishService { - constructor(private http: Http) {} + constructor(private http: HttpClient) {} save(keyAndPassword: any): Observable { - return this.http.post('api/account/reset_password/finish', keyAndPassword); + return this.http.post(SERVER_API_URL + 'api/account/reset-password/finish', keyAndPassword); } } diff --git a/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html b/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html index 7639d96f..70e4021c 100644 --- a/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html +++ b/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html @@ -1,6 +1,6 @@
-
-
+
+

Reset your password

@@ -19,7 +19,7 @@

Reset your password

+ [(ngModel)]="resetAccount.email" minlength=5 maxlength=100 #emailInput="ngModel" email required>
diff --git a/src/main/webapp/app/account/password-reset/init/password-reset-init.component.spec.ts b/src/main/webapp/app/account/password-reset/init/password-reset-init.component.spec.ts index cc91eb37..47761e9a 100644 --- a/src/main/webapp/app/account/password-reset/init/password-reset-init.component.spec.ts +++ b/src/main/webapp/app/account/password-reset/init/password-reset-init.component.spec.ts @@ -1,13 +1,15 @@ import { ComponentFixture, TestBed, inject } from '@angular/core/testing'; -import { Renderer, ElementRef } from '@angular/core'; +import { Renderer2, ElementRef } from '@angular/core'; import { Observable } from 'rxjs/Observable'; + import { GreatBigExampleApplicationTestModule } from '../../../../mocks/test.module'; import { PasswordResetInitComponent } from './password-reset-init.component'; import { PasswordResetInitService } from './password-reset-init.service'; +import { EMAIL_NOT_FOUND_TYPE } from '../../../../app/shared'; describe('Component Tests', () => { - describe('PasswordResetInitComponent', function() { + describe('PasswordResetInitComponent', () => { let fixture: ComponentFixture; let comp: PasswordResetInitComponent; @@ -18,7 +20,7 @@ describe('Component Tests', () => { providers: [ PasswordResetInitService, { - provide: Renderer, + provide: Renderer2, useValue: { invokeElementMethod(renderElement: any, methodName: string, args?: any[]) { } } @@ -28,7 +30,8 @@ describe('Component Tests', () => { useValue: new ElementRef(null) } ] - }).overrideTemplate(PasswordResetInitComponent, '') + }) + .overrideTemplate(PasswordResetInitComponent, '') .createComponent(PasswordResetInitComponent); comp = fixture.componentInstance; comp.ngOnInit(); @@ -77,7 +80,9 @@ describe('Component Tests', () => { inject([PasswordResetInitService], (service: PasswordResetInitService) => { spyOn(service, 'save').and.returnValue(Observable.throw({ status: 400, - data: 'email address not registered' + json() { + return { type: EMAIL_NOT_FOUND_TYPE }; + } })); comp.resetAccount.email = 'user@domain.com'; diff --git a/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts b/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts index dee8a3a8..70939fa8 100644 --- a/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts +++ b/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit, AfterViewInit, Renderer, ElementRef } from '@angular/core'; import { PasswordResetInitService } from './password-reset-init.service'; +import { EMAIL_NOT_FOUND_TYPE } from '../../../shared'; @Component({ selector: 'jhi-password-reset-init', @@ -35,7 +36,7 @@ export class PasswordResetInitComponent implements OnInit, AfterViewInit { this.success = 'OK'; }, (response) => { this.success = null; - if (response.status === 400 && response.data === 'email address not registered') { + if (response.status === 400 && response.json().type === EMAIL_NOT_FOUND_TYPE) { this.errorEmailNotExists = 'ERROR'; } else { this.error = 'ERROR'; diff --git a/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts b/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts index 0cceffb7..e7089125 100644 --- a/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts +++ b/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts @@ -1,13 +1,14 @@ import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../../app.constants'; @Injectable() export class PasswordResetInitService { - constructor(private http: Http) {} + constructor(private http: HttpClient) {} save(mail: string): Observable { - return this.http.post('api/account/reset_password/init', mail); + return this.http.post(SERVER_API_URL + 'api/account/reset-password/init', mail); } } diff --git a/src/main/webapp/app/account/password/password-strength-bar.component.spec.ts b/src/main/webapp/app/account/password/password-strength-bar.component.spec.ts index 063cafdb..1e8ca88a 100644 --- a/src/main/webapp/app/account/password/password-strength-bar.component.spec.ts +++ b/src/main/webapp/app/account/password/password-strength-bar.component.spec.ts @@ -12,7 +12,8 @@ describe('Component Tests', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [PasswordStrengthBarComponent] - }).overrideTemplate(PasswordStrengthBarComponent, '') + }) + .overrideTemplate(PasswordStrengthBarComponent, '') .compileComponents(); })); diff --git a/src/main/webapp/app/account/password/password-strength-bar.component.ts b/src/main/webapp/app/account/password/password-strength-bar.component.ts index 9d816f91..0f23d393 100644 --- a/src/main/webapp/app/account/password/password-strength-bar.component.ts +++ b/src/main/webapp/app/account/password/password-strength-bar.component.ts @@ -49,7 +49,7 @@ export class PasswordStrengthBarComponent { force = (passedMatches === 3) ? Math.min(force, 40) : force; return force; - }; + } getColor(s: number): any { let idx = 0; @@ -65,7 +65,7 @@ export class PasswordStrengthBarComponent { idx = 4; } return {idx: idx + 1, col: this.colors[idx]}; - }; + } @Input() set passwordToCheck(password: string) { diff --git a/src/main/webapp/app/account/password/password.component.html b/src/main/webapp/app/account/password/password.component.html index 2534bccd..aaf47e1d 100644 --- a/src/main/webapp/app/account/password/password.component.html +++ b/src/main/webapp/app/account/password/password.component.html @@ -1,6 +1,6 @@
-
-
+
+

Password for [{{account.login}}]

diff --git a/src/main/webapp/app/account/password/password.component.spec.ts b/src/main/webapp/app/account/password/password.component.spec.ts index e4454568..18f69774 100644 --- a/src/main/webapp/app/account/password/password.component.spec.ts +++ b/src/main/webapp/app/account/password/password.component.spec.ts @@ -1,5 +1,7 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; + import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; import { PasswordComponent } from './password.component'; import { PasswordService } from './password.service'; @@ -10,85 +12,86 @@ import { MockTrackerService } from '../../../mocks/mock-tracker.service'; describe('Component Tests', () => { - describe('PasswordComponent', () => { - - let comp: PasswordComponent; - let fixture: ComponentFixture; - let service: PasswordService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [PasswordComponent], - providers: [ - Principal, - AccountService, - { - provide: JhiTrackerService, - useClass: MockTrackerService - }, - PasswordService - ] - }).overrideTemplate(PasswordComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(PasswordComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(PasswordService); - }); + describe('PasswordComponent', () => { - it('should show error if passwords do not match', () => { - // GIVEN - comp.password = 'password1'; - comp.confirmPassword = 'password2'; - // WHEN - comp.changePassword(); - // THEN - expect(comp.doNotMatch).toBe('ERROR'); - expect(comp.error).toBeNull(); - expect(comp.success).toBeNull(); - }); + let comp: PasswordComponent; + let fixture: ComponentFixture; + let service: PasswordService; - it('should call Auth.changePassword when passwords match', () => { - // GIVEN - spyOn(service, 'save').and.returnValue(Observable.of(true)); - comp.password = comp.confirmPassword = 'myPassword'; + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [GreatBigExampleApplicationTestModule], + declarations: [PasswordComponent], + providers: [ + Principal, + AccountService, + { + provide: JhiTrackerService, + useClass: MockTrackerService + }, + PasswordService + ] + }) + .overrideTemplate(PasswordComponent, '') + .compileComponents(); + })); - // WHEN - comp.changePassword(); + beforeEach(() => { + fixture = TestBed.createComponent(PasswordComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(PasswordService); + }); - // THEN - expect(service.save).toHaveBeenCalledWith('myPassword'); - }); + it('should show error if passwords do not match', () => { + // GIVEN + comp.password = 'password1'; + comp.confirmPassword = 'password2'; + // WHEN + comp.changePassword(); + // THEN + expect(comp.doNotMatch).toBe('ERROR'); + expect(comp.error).toBeNull(); + expect(comp.success).toBeNull(); + }); - it('should set success to OK upon success', function() { - // GIVEN - spyOn(service, 'save').and.returnValue(Observable.of(true)); - comp.password = comp.confirmPassword = 'myPassword'; + it('should call Auth.changePassword when passwords match', () => { + // GIVEN + spyOn(service, 'save').and.returnValue(Observable.of(new HttpResponse({ body: true }))); + comp.password = comp.confirmPassword = 'myPassword'; - // WHEN - comp.changePassword(); + // WHEN + comp.changePassword(); - // THEN - expect(comp.doNotMatch).toBeNull(); - expect(comp.error).toBeNull(); - expect(comp.success).toBe('OK'); - }); + // THEN + expect(service.save).toHaveBeenCalledWith('myPassword'); + }); + + it('should set success to OK upon success', function () { + // GIVEN + spyOn(service, 'save').and.returnValue(Observable.of(new HttpResponse({ body: true }))); + comp.password = comp.confirmPassword = 'myPassword'; + + // WHEN + comp.changePassword(); + + // THEN + expect(comp.doNotMatch).toBeNull(); + expect(comp.error).toBeNull(); + expect(comp.success).toBe('OK'); + }); - it('should notify of error if change password fails', function() { - // GIVEN - spyOn(service, 'save').and.returnValue(Observable.throw('ERROR')); - comp.password = comp.confirmPassword = 'myPassword'; + it('should notify of error if change password fails', function () { + // GIVEN + spyOn(service, 'save').and.returnValue(Observable.throw('ERROR')); + comp.password = comp.confirmPassword = 'myPassword'; - // WHEN - comp.changePassword(); + // WHEN + comp.changePassword(); - // THEN - expect(comp.doNotMatch).toBeNull(); - expect(comp.success).toBeNull(); - expect(comp.error).toBe('ERROR'); + // THEN + expect(comp.doNotMatch).toBeNull(); + expect(comp.success).toBeNull(); + expect(comp.error).toBe('ERROR'); + }); }); - }); }); diff --git a/src/main/webapp/app/account/password/password.service.ts b/src/main/webapp/app/account/password/password.service.ts index 63fe5256..f22ff475 100644 --- a/src/main/webapp/app/account/password/password.service.ts +++ b/src/main/webapp/app/account/password/password.service.ts @@ -1,13 +1,14 @@ import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; @Injectable() export class PasswordService { - constructor(private http: Http) {} + constructor(private http: HttpClient) {} save(newPassword: string): Observable { - return this.http.post('api/account/change_password', newPassword); + return this.http.post(SERVER_API_URL + 'api/account/change-password', newPassword); } } diff --git a/src/main/webapp/app/account/register/register.component.html b/src/main/webapp/app/account/register/register.component.html index 3506be5a..426fd9a6 100644 --- a/src/main/webapp/app/account/register/register.component.html +++ b/src/main/webapp/app/account/register/register.component.html @@ -1,6 +1,6 @@
-
-
+
+

Registration

@@ -23,42 +23,51 @@

Registration

The password and its confirmation do not match!
-
+
+
+
+ required minlength="1" maxlength="50" pattern="^[_'.@A-Za-z0-9-]*$">
Your username is required. - + Your username is required to be at least 1 character. - + Your username cannot be longer than 50 characters. - - Your username can only contain lower-case letters and digits. + + Your username can only contain letters and digits.
+ [(ngModel)]="registerAccount.email" minlength=5 maxlength=100 email required>
- + Your email is required. - + Your email is invalid. - + Your email is required to be at least 5 characters. - + Your email cannot be longer than 100 characters.
@@ -66,15 +75,18 @@

Registration

+ [(ngModel)]="registerAccount.password" minlength=4 maxlength=50 required>
- + Your password is required. - + Your password is required to be at least 4 characters. - + Your password cannot be longer than 50 characters.
@@ -83,15 +95,18 @@

Registration

+ [(ngModel)]="confirmPassword" minlength=4 maxlength=50 required>
- + Your confirmation password is required. - + Your confirmation password is required to be at least 4 characters. - + Your confirmation password cannot be longer than 50 characters.
@@ -102,9 +117,7 @@

Registration

If you want to - sign in - , you can try the default accounts:
- Administrator (login="admin" and password="admin")
- User - (login="user" and password="user").
+ sign in, you can try the default accounts:
- Administrator (login="admin" and password="admin")
- User (login="user" and password="user").
diff --git a/src/main/webapp/app/account/register/register.component.spec.ts b/src/main/webapp/app/account/register/register.component.spec.ts index d73f5af4..1153ac32 100644 --- a/src/main/webapp/app/account/register/register.component.spec.ts +++ b/src/main/webapp/app/account/register/register.component.spec.ts @@ -1,12 +1,12 @@ import { ComponentFixture, TestBed, async, inject, tick, fakeAsync } from '@angular/core/testing'; -import { Renderer, ElementRef } from '@angular/core'; import { Observable } from 'rxjs/Observable'; + import { JhiLanguageService } from 'ng-jhipster'; import { MockLanguageService } from '../../../mocks/mock-language.service'; import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { LoginModalService } from '../../shared'; import { Register } from './register.service'; import { RegisterComponent } from './register.component'; +import { EMAIL_ALREADY_USED_TYPE, LOGIN_ALREADY_USED_TYPE } from '../../shared'; describe('Component Tests', () => { @@ -19,21 +19,10 @@ describe('Component Tests', () => { imports: [GreatBigExampleApplicationTestModule], declarations: [RegisterComponent], providers: [ - Register, - { - provide: LoginModalService, - useValue: null - }, - { - provide: Renderer, - useValue: null - }, - { - provide: ElementRef, - useValue: null - } + Register ] - }).overrideTemplate(RegisterComponent, '') + }) + .overrideTemplate(RegisterComponent, '') .compileComponents(); })); @@ -80,7 +69,9 @@ describe('Component Tests', () => { fakeAsync((service: Register) => { spyOn(service, 'save').and.returnValue(Observable.throw({ status: 400, - _body: 'login already in use' + json() { + return { type: LOGIN_ALREADY_USED_TYPE }; + } })); comp.registerAccount.password = comp.confirmPassword = 'password'; @@ -99,7 +90,9 @@ describe('Component Tests', () => { fakeAsync((service: Register) => { spyOn(service, 'save').and.returnValue(Observable.throw({ status: 400, - _body: 'email address already in use' + json() { + return { type: EMAIL_ALREADY_USED_TYPE }; + } })); comp.registerAccount.password = comp.confirmPassword = 'password'; diff --git a/src/main/webapp/app/account/register/register.component.ts b/src/main/webapp/app/account/register/register.component.ts index f996910a..41a0914f 100644 --- a/src/main/webapp/app/account/register/register.component.ts +++ b/src/main/webapp/app/account/register/register.component.ts @@ -3,7 +3,7 @@ import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { JhiLanguageService } from 'ng-jhipster'; import { Register } from './register.service'; -import { LoginModalService } from '../../shared'; +import { LoginModalService, EMAIL_ALREADY_USED_TYPE, LOGIN_ALREADY_USED_TYPE } from '../../shared'; @Component({ selector: 'jhi-register', @@ -61,9 +61,9 @@ export class RegisterComponent implements OnInit, AfterViewInit { private processError(response) { this.success = null; - if (response.status === 400 && response._body === 'login already in use') { + if (response.status === 400 && response.json().type === LOGIN_ALREADY_USED_TYPE) { this.errorUserExists = 'ERROR'; - } else if (response.status === 400 && response._body === 'email address already in use') { + } else if (response.status === 400 && response.json().type === EMAIL_ALREADY_USED_TYPE) { this.errorEmailExists = 'ERROR'; } else { this.error = 'ERROR'; diff --git a/src/main/webapp/app/account/register/register.route.ts b/src/main/webapp/app/account/register/register.route.ts index b26454d5..ca834d5d 100644 --- a/src/main/webapp/app/account/register/register.route.ts +++ b/src/main/webapp/app/account/register/register.route.ts @@ -1,6 +1,5 @@ import { Route } from '@angular/router'; -import { UserRouteAccessService } from '../../shared'; import { RegisterComponent } from './register.component'; export const registerRoute: Route = { @@ -9,6 +8,5 @@ export const registerRoute: Route = { data: { authorities: [], pageTitle: 'register.title' - }, - canActivate: [UserRouteAccessService] + } }; diff --git a/src/main/webapp/app/account/register/register.service.ts b/src/main/webapp/app/account/register/register.service.ts index 6807b85b..7e740a34 100644 --- a/src/main/webapp/app/account/register/register.service.ts +++ b/src/main/webapp/app/account/register/register.service.ts @@ -1,13 +1,14 @@ import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; @Injectable() export class Register { - constructor(private http: Http) {} + constructor(private http: HttpClient) {} save(account: any): Observable { - return this.http.post('api/register', account); + return this.http.post(SERVER_API_URL + 'api/register', account); } } diff --git a/src/main/webapp/app/account/settings/settings.component.html b/src/main/webapp/app/account/settings/settings.component.html index a0afff11..cf9dbbd3 100644 --- a/src/main/webapp/app/account/settings/settings.component.html +++ b/src/main/webapp/app/account/settings/settings.component.html @@ -1,6 +1,6 @@
-
-
+
+

User settings for [{{settingsAccount.login}}]

@@ -14,15 +14,18 @@

+ [(ngModel)]="settingsAccount.firstName" minlength=1 maxlength=50 #firstNameInput="ngModel" required>
- + Your first name is required. - + Your first name is required to be at least 1 character. - + Your first name cannot be longer than 50 characters.
@@ -30,15 +33,18 @@

+ [(ngModel)]="settingsAccount.lastName" minlength=1 maxlength=50 #lastNameInput="ngModel" required>
- + Your last name is required. - + Your last name is required to be at least 1 character. - + Your last name cannot be longer than 50 characters.
@@ -46,18 +52,22 @@

+ [(ngModel)]="settingsAccount.email" minlength="5" maxlength="100" #emailInput="ngModel" email required>
- + Your email is required. - + Your email is invalid. - + Your email is required to be at least 5 characters. - + Your email cannot be longer than 100 characters.
diff --git a/src/main/webapp/app/account/settings/settings.component.spec.ts b/src/main/webapp/app/account/settings/settings.component.spec.ts index dfe7de06..275adbd0 100644 --- a/src/main/webapp/app/account/settings/settings.component.spec.ts +++ b/src/main/webapp/app/account/settings/settings.component.spec.ts @@ -1,14 +1,13 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { Observable } from 'rxjs/Observable'; -import { JhiLanguageHelper } from '../../shared'; + import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; import { Principal, AccountService } from '../../shared'; import { SettingsComponent } from './settings.component'; -import { MockAccountService } from '../../../mocks/mock-account.service'; -import { MockPrincipal } from '../../../mocks/mock-principal.service'; import { JhiTrackerService } from '../../shared/tracker/tracker.service'; import { MockTrackerService } from '../../../mocks/mock-tracker.service'; + describe('Component Tests', () => { describe('SettingsComponent', () => { @@ -23,24 +22,13 @@ describe('Component Tests', () => { imports: [GreatBigExampleApplicationTestModule], declarations: [SettingsComponent], providers: [ - { - provide: Principal, - useClass: MockPrincipal - }, - { - provide: AccountService, - useClass: MockAccountService - }, { provide: JhiTrackerService, useClass: MockTrackerService }, - { - provide: JhiLanguageHelper, - useValue: null - }, ] - }).overrideTemplate(SettingsComponent, '') + }) + .overrideTemplate(SettingsComponent, '') .compileComponents(); })); diff --git a/src/main/webapp/app/account/settings/settings.component.ts b/src/main/webapp/app/account/settings/settings.component.ts index 2b3d0325..8f014205 100644 --- a/src/main/webapp/app/account/settings/settings.component.ts +++ b/src/main/webapp/app/account/settings/settings.component.ts @@ -56,8 +56,7 @@ export class SettingsComponent implements OnInit { langKey: account.langKey, lastName: account.lastName, login: account.login, - imageUrl: account.imageUrl, - // bio: account.bio + imageUrl: account.imageUrl }; } } diff --git a/src/main/webapp/app/account/social/social-auth.component.ts b/src/main/webapp/app/account/social/social-auth.component.ts index e8e25e71..2321f69f 100644 --- a/src/main/webapp/app/account/social/social-auth.component.ts +++ b/src/main/webapp/app/account/social/social-auth.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Inject } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { LoginService } from '../../shared'; diff --git a/src/main/webapp/app/account/social/social-register.component.html b/src/main/webapp/app/account/social/social-register.component.html index f2e9707c..5bd1ccc5 100644 --- a/src/main/webapp/app/account/social/social-register.component.html +++ b/src/main/webapp/app/account/social/social-register.component.html @@ -1,6 +1,6 @@
-
-
+
+

Registration with

Registration

diff --git a/src/main/webapp/app/admin/admin.module.ts b/src/main/webapp/app/admin/admin.module.ts index fe9cd231..8d4b05d0 100644 --- a/src/main/webapp/app/admin/admin.module.ts +++ b/src/main/webapp/app/admin/admin.module.ts @@ -74,4 +74,4 @@ import { ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationAdminModule { } +export class GreatBigExampleApplicationAdminModule {} diff --git a/src/main/webapp/app/admin/audits/audits.component.html b/src/main/webapp/app/admin/audits/audits.component.html index 9fcbaf7e..4e3838fa 100644 --- a/src/main/webapp/app/admin/audits/audits.component.html +++ b/src/main/webapp/app/admin/audits/audits.component.html @@ -4,17 +4,22 @@

Audits

Filter by date

-

- from +

+
+ from +
- to - -

+ +
+ To +
+ +
- +
@@ -39,7 +44,7 @@

Filter by date

- +
diff --git a/src/main/webapp/app/admin/audits/audits.component.spec.ts b/src/main/webapp/app/admin/audits/audits.component.spec.ts index da13db61..d3336adf 100644 --- a/src/main/webapp/app/admin/audits/audits.component.spec.ts +++ b/src/main/webapp/app/admin/audits/audits.component.spec.ts @@ -1,13 +1,16 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { DatePipe } from '@angular/common'; import { NgbPaginationConfig } from '@ng-bootstrap/ng-bootstrap'; -import { JhiParseLinks } from 'ng-jhipster'; + import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; import { PaginationConfig } from '../../core/config/uib-pagination.config' import { AuditsComponent } from '../../admin/audits/audits.component'; import { AuditsService } from '../../admin/audits/audits.service'; import { ITEMS_PER_PAGE } from '../../shared'; +function build2DigitsDatePart(datePart: number) { + return `0${datePart}`.slice(-2); +} + function getDate(isToday = true) { let date: Date = new Date(); if (isToday) { @@ -21,7 +24,9 @@ function getDate(isToday = true) { date = new Date(date.getFullYear(), date.getMonth() - 1, date.getDate()); } } - return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; + const monthString = build2DigitsDatePart(date.getMonth() + 1); + const dateString = build2DigitsDatePart(date.getDate()); + return `${date.getFullYear()}-${monthString}-${dateString}`; } describe('Component Tests', () => { @@ -30,7 +35,6 @@ describe('Component Tests', () => { let comp: AuditsComponent; let fixture: ComponentFixture; - let service: AuditsService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -39,18 +43,16 @@ describe('Component Tests', () => { providers: [ AuditsService, NgbPaginationConfig, - JhiParseLinks, - PaginationConfig, - DatePipe + PaginationConfig ] - }).overrideTemplate(AuditsComponent, '') + }) + .overrideTemplate(AuditsComponent, '') .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(AuditsComponent); comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(AuditsService); }); describe('today function ', () => { diff --git a/src/main/webapp/app/admin/audits/audits.component.ts b/src/main/webapp/app/admin/audits/audits.component.ts index b8eb8001..c6ea50e0 100644 --- a/src/main/webapp/app/admin/audits/audits.component.ts +++ b/src/main/webapp/app/admin/audits/audits.component.ts @@ -5,95 +5,92 @@ import { JhiParseLinks } from 'ng-jhipster'; import { Audit } from './audit.model'; import { AuditsService } from './audits.service'; import { ITEMS_PER_PAGE } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; @Component({ selector: 'jhi-audit', templateUrl: './audits.component.html' }) export class AuditsComponent implements OnInit { - audits: Audit[]; - fromDate: string; - itemsPerPage: any; - links: any; - page: number; - orderProp: string; - reverse: boolean; - toDate: string; - totalItems: number; + audits: Audit[]; + fromDate: string; + itemsPerPage: any; + links: any; + page: number; + orderProp: string; + reverse: boolean; + toDate: string; + totalItems: number; + datePipe: DatePipe; - constructor( - private auditsService: AuditsService, - private parseLinks: JhiParseLinks, - private paginationConfig: PaginationConfig, - private datePipe: DatePipe - ) { - this.itemsPerPage = ITEMS_PER_PAGE; - this.page = 1; - this.reverse = false; - this.orderProp = 'timestamp'; - } + constructor( + private auditsService: AuditsService, + private parseLinks: JhiParseLinks + ) { + this.itemsPerPage = ITEMS_PER_PAGE; + this.page = 1; + this.reverse = false; + this.orderProp = 'timestamp'; + this.datePipe = new DatePipe('en'); + } - getAudits() { - return this.sortAudits(this.audits); - } + getAudits() { + return this.sortAudits(this.audits); + } - loadPage(page: number) { - this.page = page; - this.onChangeDate(); - } + loadPage(page: number) { + this.page = page; + this.onChangeDate(); + } - ngOnInit() { - this.today(); - this.previousMonth(); - this.onChangeDate(); - } + ngOnInit() { + this.today(); + this.previousMonth(); + this.onChangeDate(); + } - onChangeDate() { - this.auditsService.query({ - page: this.page - 1, size: this.itemsPerPage, - fromDate: this.fromDate, toDate: this.toDate - }).subscribe((res) => { + onChangeDate() { + this.auditsService.query({page: this.page - 1, size: this.itemsPerPage, + fromDate: this.fromDate, toDate: this.toDate}).subscribe((res) => { - this.audits = res.json(); - this.links = this.parseLinks.parse(res.headers.get('link')); - this.totalItems = + res.headers.get('X-Total-Count'); - }); - } + this.audits = res.body; + this.links = this.parseLinks.parse(res.headers.get('link')); + this.totalItems = + res.headers.get('X-Total-Count'); + }); + } - previousMonth() { - const dateFormat = 'yyyy-MM-dd'; - let fromDate: Date = new Date(); + previousMonth() { + const dateFormat = 'yyyy-MM-dd'; + let fromDate: Date = new Date(); - if (fromDate.getMonth() === 0) { - fromDate = new Date(fromDate.getFullYear() - 1, 11, fromDate.getDate()); - } else { - fromDate = new Date(fromDate.getFullYear(), fromDate.getMonth() - 1, fromDate.getDate()); - } + if (fromDate.getMonth() === 0) { + fromDate = new Date(fromDate.getFullYear() - 1, 11, fromDate.getDate()); + } else { + fromDate = new Date(fromDate.getFullYear(), fromDate.getMonth() - 1, fromDate.getDate()); + } - this.fromDate = this.datePipe.transform(fromDate, dateFormat); - } + this.fromDate = this.datePipe.transform(fromDate, dateFormat); + } - today() { - const dateFormat = 'yyyy-MM-dd'; - // Today + 1 day - needed if the current day must be included - const today: Date = new Date(); - today.setDate(today.getDate() + 1); - const date = new Date(today.getFullYear(), today.getMonth(), today.getDate()); - this.toDate = this.datePipe.transform(date, dateFormat); - } + today() { + const dateFormat = 'yyyy-MM-dd'; + // Today + 1 day - needed if the current day must be included + const today: Date = new Date(); + today.setDate(today.getDate() + 1); + const date = new Date(today.getFullYear(), today.getMonth(), today.getDate()); + this.toDate = this.datePipe.transform(date, dateFormat); + } - private sortAudits(audits: Audit[]) { - audits = audits.slice(0).sort((a, b) => { - if (a[this.orderProp] < b[this.orderProp]) { - return -1; - } else if ([b[this.orderProp] < a[this.orderProp]]) { - return 1; - } else { - return 0; - } - }); + private sortAudits(audits: Audit[]) { + audits = audits.slice(0).sort((a, b) => { + if (a[this.orderProp] < b[this.orderProp]) { + return -1; + } else if ([b[this.orderProp] < a[this.orderProp]]) { + return 1; + } else { + return 0; + } + }); - return this.reverse ? audits.reverse() : audits; - } + return this.reverse ? audits.reverse() : audits; + } } diff --git a/src/main/webapp/app/admin/audits/audits.service.ts b/src/main/webapp/app/admin/audits/audits.service.ts index acd90c86..3400c2fc 100644 --- a/src/main/webapp/app/admin/audits/audits.service.ts +++ b/src/main/webapp/app/admin/audits/audits.service.ts @@ -1,23 +1,22 @@ import { Injectable } from '@angular/core'; -import { Http, Response, URLSearchParams } from '@angular/http'; +import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; +import { Audit } from './audit.model'; +import { createRequestOption} from '../../shared/model/request-util'; @Injectable() export class AuditsService { - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - query(req: any): Observable { - const params: URLSearchParams = new URLSearchParams(); - params.set('fromDate', req.fromDate); - params.set('toDate', req.toDate); - params.set('page', req.page); - params.set('size', req.size); - params.set('sort', req.sort); + query(req: any): Observable> { + const params: HttpParams = createRequestOption(req); - const options = { - search: params - }; + const requestURL = SERVER_API_URL + 'management/audits'; - return this.http.get('management/audits', options); + return this.http.get(requestURL, { + params, + observe: 'response' + }); } } diff --git a/src/main/webapp/app/admin/configuration/configuration.component.html b/src/main/webapp/app/admin/configuration/configuration.component.html index 250eee73..fab1a389 100644 --- a/src/main/webapp/app/admin/configuration/configuration.component.html +++ b/src/main/webapp/app/admin/configuration/configuration.component.html @@ -17,7 +17,7 @@

Configuration

{{key}}
- {{entry.properties[key] | json}} + {{entry.properties[key] | json}}
@@ -37,7 +37,7 @@

Configuration

diff --git a/src/main/webapp/app/admin/configuration/configuration.service.ts b/src/main/webapp/app/admin/configuration/configuration.service.ts index d403a4b9..f2dd153b 100644 --- a/src/main/webapp/app/admin/configuration/configuration.service.ts +++ b/src/main/webapp/app/admin/configuration/configuration.service.ts @@ -1,18 +1,19 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; @Injectable() export class JhiConfigurationService { - constructor(private http: Http) { + constructor(private http: HttpClient) { } get(): Observable { - return this.http.get('management/configprops').map((res: Response) => { + return this.http.get(SERVER_API_URL + 'management/configprops', { observe: 'response' }).map((res: HttpResponse) => { const properties: any[] = []; - const propertiesObject = res.json(); + const propertiesObject = res.body; for (const key in propertiesObject) { if (propertiesObject.hasOwnProperty(key)) { @@ -28,10 +29,10 @@ export class JhiConfigurationService { } getEnv(): Observable { - return this.http.get('management/env').map((res: Response) => { + return this.http.get(SERVER_API_URL + 'management/env', { observe: 'response' }).map((res: HttpResponse) => { const properties: any = {}; - const propertiesObject = res.json(); + const propertiesObject = res.body; for (const key in propertiesObject) { if (propertiesObject.hasOwnProperty(key)) { diff --git a/src/main/webapp/app/admin/health/health.component.spec.ts b/src/main/webapp/app/admin/health/health.component.spec.ts index 5e907fea..7f9a4f83 100644 --- a/src/main/webapp/app/admin/health/health.component.spec.ts +++ b/src/main/webapp/app/admin/health/health.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; + import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; import { JhiHealthCheckComponent } from '../../admin/health/health.component'; import { JhiHealthService } from '../../admin/health/health.service'; @@ -17,13 +17,10 @@ describe('Component Tests', () => { imports: [GreatBigExampleApplicationTestModule], declarations: [JhiHealthCheckComponent], providers: [ - JhiHealthService, - { - provide: NgbModal, - useValue: null - } + JhiHealthService ] - }).overrideTemplate(JhiHealthCheckComponent, '') + }) + .overrideTemplate(JhiHealthCheckComponent, '') .compileComponents(); })); diff --git a/src/main/webapp/app/admin/health/health.service.ts b/src/main/webapp/app/admin/health/health.service.ts index ef756296..80d193aa 100644 --- a/src/main/webapp/app/admin/health/health.service.ts +++ b/src/main/webapp/app/admin/health/health.service.ts @@ -1,18 +1,19 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; @Injectable() export class JhiHealthService { separator: string; - constructor(private http: Http) { + constructor(private http: HttpClient) { this.separator = '.'; } checkHealth(): Observable { - return this.http.get('management/health').map((res: Response) => res.json()); + return this.http.get(SERVER_API_URL + 'management/health'); } transformHealthData(data): any { diff --git a/src/main/webapp/app/admin/logs/logs.component.html b/src/main/webapp/app/admin/logs/logs.component.html index 242ef556..368eb0e5 100644 --- a/src/main/webapp/app/admin/logs/logs.component.html +++ b/src/main/webapp/app/admin/logs/logs.component.html @@ -5,7 +5,7 @@

Logs

Filter -
Date
{{item.key}} - {{item.val}} + {{item.val}}
+
@@ -16,11 +16,11 @@

Logs

Name
{{logger.name | slice:0:140}} - - - - - + + + + +
diff --git a/src/main/webapp/app/admin/logs/logs.component.ts b/src/main/webapp/app/admin/logs/logs.component.ts index 29cdc8fe..c2fcf104 100644 --- a/src/main/webapp/app/admin/logs/logs.component.ts +++ b/src/main/webapp/app/admin/logs/logs.component.ts @@ -23,13 +23,13 @@ export class LogsComponent implements OnInit { } ngOnInit() { - this.logsService.findAll().subscribe((loggers) => this.loggers = loggers); + this.logsService.findAll().subscribe((response) => this.loggers = response.body); } changeLevel(name: string, level: string) { const log = new Log(name, level); this.logsService.changeLevel(log).subscribe(() => { - this.logsService.findAll().subscribe((loggers) => this.loggers = loggers); + this.logsService.findAll().subscribe((response) => this.loggers = response.body); }); } } diff --git a/src/main/webapp/app/admin/logs/logs.service.ts b/src/main/webapp/app/admin/logs/logs.service.ts index 526ee74b..b98db1a3 100644 --- a/src/main/webapp/app/admin/logs/logs.service.ts +++ b/src/main/webapp/app/admin/logs/logs.service.ts @@ -1,18 +1,19 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Log } from './log.model'; @Injectable() export class LogsService { - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - changeLevel(log: Log): Observable { - return this.http.put('management/logs', log); + changeLevel(log: Log): Observable> { + return this.http.put(SERVER_API_URL + 'management/logs', log, {observe: 'response'}); } - findAll(): Observable { - return this.http.get('management/logs').map((res: Response) => res.json()); + findAll(): Observable> { + return this.http.get(SERVER_API_URL + 'management/logs', {observe: 'response'}); } } diff --git a/src/main/webapp/app/admin/metrics/metrics-modal.component.html b/src/main/webapp/app/admin/metrics/metrics-modal.component.html index b8f0391a..72da2ff6 100644 --- a/src/main/webapp/app/admin/metrics/metrics-modal.component.html +++ b/src/main/webapp/app/admin/metrics/metrics-modal.component.html @@ -21,7 +21,7 @@
-
+
{{st.value.className}}.{{st.value.methodName}}({{st.value.fileName}}:{{st.value.lineNumber}}) @@ -31,10 +31,10 @@
- - - - + + + + @@ -44,7 +44,7 @@
- +
Blocked TimeBlocked CountWaited TimeWaited CountBlocked TimeBlocked CountWaited TimeWaited Count Lock Name
{{entry.value.blockedCount}} {{entry.value.waitedTime}} {{entry.value.waitedCount}}{{entry.value.lockName}}{{entry.value.lockName}}
@@ -52,5 +52,5 @@
diff --git a/src/main/webapp/app/admin/metrics/metrics.component.html b/src/main/webapp/app/admin/metrics/metrics.component.html index fbdee701..360cbac6 100644 --- a/src/main/webapp/app/admin/metrics/metrics.component.html +++ b/src/main/webapp/app/admin/metrics/metrics.component.html @@ -11,34 +11,34 @@

JVM Metrics

Memory

Total Memory ({{metrics.gauges['jvm.memory.total.used'].value / 1000000 | number:'1.0-0'}}M / {{metrics.gauges['jvm.memory.total.max'].value / 1000000 | number:'1.0-0'}}M)

- + {{metrics.gauges['jvm.memory.total.used'].value * 100 / metrics.gauges['jvm.memory.total.max'].value | number:'1.0-0'}}%

Heap Memory ({{metrics.gauges['jvm.memory.heap.used'].value / 1000000 | number:'1.0-0'}}M / {{metrics.gauges['jvm.memory.heap.max'].value / 1000000 | number:'1.0-0'}}M)

- + {{metrics.gauges['jvm.memory.heap.used'].value * 100 / metrics.gauges['jvm.memory.heap.max'].value | number:'1.0-0'}}%

Non-Heap Memory ({{metrics.gauges['jvm.memory.non-heap.used'].value / 1000000 | number:'1.0-0'}}M / {{metrics.gauges['jvm.memory.non-heap.committed'].value / 1000000 | number:'1.0-0'}}M)

- + {{metrics.gauges['jvm.memory.non-heap.used'].value * 100 / metrics.gauges['jvm.memory.non-heap.committed'].value | number:'1.0-0'}}%
Threads (Total: {{metrics.gauges['jvm.threads.count'].value}})

Runnable {{metrics.gauges['jvm.threads.runnable.count'].value}}

- + {{metrics.gauges['jvm.threads.runnable.count'].value * 100 / metrics.gauges['jvm.threads.count'].value | number:'1.0-0'}}%

Timed Waiting ({{metrics.gauges['jvm.threads.timed_waiting.count'].value}})

- + {{metrics.gauges['jvm.threads.timed_waiting.count'].value * 100 / metrics.gauges['jvm.threads.count'].value | number:'1.0-0'}}%

Waiting ({{metrics.gauges['jvm.threads.waiting.count'].value}})

- + {{metrics.gauges['jvm.threads.waiting.count'].value * 100 / metrics.gauges['jvm.threads.count'].value | number:'1.0-0'}}%

Blocked ({{metrics.gauges['jvm.threads.blocked.count'].value}})

- + {{metrics.gauges['jvm.threads.blocked.count'].value * 100 / metrics.gauges['jvm.threads.count'].value | number:'1.0-0'}}%
@@ -84,7 +84,7 @@

HTTP requests (events per second)

OK - + {{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].count}} @@ -104,7 +104,7 @@

HTTP requests (events per second)

Not Found - + {{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].count}} @@ -124,7 +124,7 @@

HTTP requests (events per second)

Server error - + {{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].count}} @@ -176,7 +176,7 @@

Services statistics (time in mill

- +

Cache statistics

@@ -214,7 +214,6 @@

Cache statistics

-

DataSource statistics (time in millisecond)

@@ -235,7 +234,7 @@

- + {{metrics.gauges['HikariPool-1.pool.ActiveConnections'].value * 100 / metrics.gauges['HikariPool-1.pool.TotalConnections'].value | number:'1.0-0'}}% diff --git a/src/main/webapp/app/admin/metrics/metrics.component.ts b/src/main/webapp/app/admin/metrics/metrics.component.ts index d670e52d..87b26885 100644 --- a/src/main/webapp/app/admin/metrics/metrics.component.ts +++ b/src/main/webapp/app/admin/metrics/metrics.component.ts @@ -35,12 +35,12 @@ export class JhiMetricsMonitoringComponent implements OnInit { this.cachesStats = {}; Object.keys(metrics.timers).forEach((key) => { const value = metrics.timers[key]; - if (key.indexOf('web.rest') !== -1 || key.indexOf('service') !== -1) { + if (key.includes('web.rest') || key.includes('service')) { this.servicesStats[key] = value; } }); Object.keys(metrics.gauges).forEach((key) => { - if (key.indexOf('jcache.statistics') !== -1) { + if (key.includes('jcache.statistics')) { const value = metrics.gauges[key].value; // remove gets or puts const index = key.lastIndexOf('.'); diff --git a/src/main/webapp/app/admin/metrics/metrics.service.ts b/src/main/webapp/app/admin/metrics/metrics.service.ts index 65ea897b..0ec16f5c 100644 --- a/src/main/webapp/app/admin/metrics/metrics.service.ts +++ b/src/main/webapp/app/admin/metrics/metrics.service.ts @@ -1,17 +1,18 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; @Injectable() export class JhiMetricsService { - constructor(private http: Http) {} + constructor(private http: HttpClient) {} getMetrics(): Observable { - return this.http.get('management/metrics').map((res: Response) => res.json()); + return this.http.get(SERVER_API_URL + 'management/metrics'); } threadDump(): Observable { - return this.http.get('management/dump').map((res: Response) => res.json()); + return this.http.get(SERVER_API_URL + 'management/dump'); } } diff --git a/src/main/webapp/app/admin/tracker/tracker.route.ts b/src/main/webapp/app/admin/tracker/tracker.route.ts index 4fb2348e..fbf3629b 100644 --- a/src/main/webapp/app/admin/tracker/tracker.route.ts +++ b/src/main/webapp/app/admin/tracker/tracker.route.ts @@ -1,8 +1,6 @@ import { Route } from '@angular/router'; -import { UserRouteAccessService } from '../../shared'; import { JhiTrackerComponent } from './tracker.component'; -import { JhiTrackerService } from '../../shared'; export const trackerRoute: Route = { path: 'jhi-tracker', diff --git a/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.spec.ts b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.spec.ts new file mode 100644 index 00000000..769757fd --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.spec.ts @@ -0,0 +1,60 @@ +import { ComponentFixture, TestBed, async, inject, fakeAsync, tick } from '@angular/core/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { Observable } from 'rxjs/Observable'; +import { JhiEventManager } from 'ng-jhipster'; + +import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; +import { UserMgmtDeleteDialogComponent } from './user-management-delete-dialog.component'; +import { UserService } from '../../core/services/user.service'; + +describe('Component Tests', () => { + + describe('User Management Delete Component', () => { + let comp: UserMgmtDeleteDialogComponent; + let fixture: ComponentFixture; + let service: UserService; + let mockEventManager: any; + let mockActiveModal: any; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [GreatBigExampleApplicationTestModule], + declarations: [UserMgmtDeleteDialogComponent], + providers: [ + UserService + ] + }) + .overrideTemplate(UserMgmtDeleteDialogComponent, '') + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UserMgmtDeleteDialogComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(UserService); + mockEventManager = fixture.debugElement.injector.get(JhiEventManager); + mockActiveModal = fixture.debugElement.injector.get(NgbActiveModal); + }); + + describe('confirmDelete', () => { + it('Should call delete service on confirmDelete', + inject([], + fakeAsync(() => { + // GIVEN + spyOn(service, 'delete').and.returnValue(Observable.of({})); + + // WHEN + comp.confirmDelete('user'); + tick(); + + // THEN + expect(service.delete).toHaveBeenCalledWith('user'); + expect(mockActiveModal.dismissSpy).toHaveBeenCalled(); + expect(mockEventManager.broadcastSpy).toHaveBeenCalled(); + }) + ) + ); + }); + }); + +}); diff --git a/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts index 6a775fd2..e5d7dc8f 100644 --- a/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts +++ b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { User, UserService } from '../../shared'; @@ -27,10 +27,8 @@ export class UserMgmtDeleteDialogComponent { confirmDelete(login) { this.userService.delete(login).subscribe((response) => { - this.eventManager.broadcast({ - name: 'userListModification', - content: 'Deleted a user' - }); + this.eventManager.broadcast({ name: 'userListModification', + content: 'Deleted a user'}); this.activeModal.dismiss(true); }); } @@ -38,21 +36,20 @@ export class UserMgmtDeleteDialogComponent { @Component({ selector: 'jhi-user-delete-dialog', - template: '' + template: '' }) export class UserDeleteDialogComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private userModalService: UserModalService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.userModalService.open(UserMgmtDeleteDialogComponent, params['login']); + this.userModalService.open(UserMgmtDeleteDialogComponent as Component, params['login']); }); } diff --git a/src/main/webapp/app/admin/user-management/user-management-detail.component.html b/src/main/webapp/app/admin/user-management/user-management-detail.component.html index d5deb8fa..66591020 100644 --- a/src/main/webapp/app/admin/user-management/user-management-detail.component.html +++ b/src/main/webapp/app/admin/user-management/user-management-detail.component.html @@ -6,10 +6,11 @@

Login
{{user.login}} - Deactivated - Activated + +
First Name
{{user.firstName}}
diff --git a/src/main/webapp/app/admin/user-management/user-management-detail.component.spec.ts b/src/main/webapp/app/admin/user-management/user-management-detail.component.spec.ts new file mode 100644 index 00000000..866e58af --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-detail.component.spec.ts @@ -0,0 +1,73 @@ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; +import { Observable } from 'rxjs/Observable'; + +import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; +import { MockActivatedRoute } from '../../../mocks/mock-route.service'; +import { UserMgmtDetailComponent } from './user-management-detail.component'; +import { UserService } from '../../core/services/user.service'; +import { User } from '../../core/store/user/user.model'; + +describe('Component Tests', () => { + + describe('User Management Detail Component', () => { + let comp: UserMgmtDetailComponent; + let fixture: ComponentFixture; + let service: UserService; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [GreatBigExampleApplicationTestModule], + declarations: [UserMgmtDetailComponent], + providers: [ + { + provide: ActivatedRoute, + useValue: new MockActivatedRoute({ login: 'user' }) + }, + UserService + ] + }) + .overrideTemplate(UserMgmtDetailComponent, '') + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UserMgmtDetailComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(UserService); + }); + + describe('OnInit', () => { + it('Should call load all on init', () => { + // GIVEN + + spyOn(service, 'find').and.returnValue(Observable.of(new HttpResponse({ + body: new User(1, 'user', 'first', 'last', 'first@last.com', true, 'en', ['ROLE_USER'], 'admin', null, null, null) + }))); + + // WHEN + comp.ngOnInit(); + + // THEN + expect(service.find).toHaveBeenCalledWith('user'); + expect(comp.user).toEqual(jasmine.objectContaining({ + id: 1, + login: 'user', + firstName: 'first', + lastName: 'last', + email: 'first@last.com', + activated: true, + langKey: 'en', + authorities: ['ROLE_USER'], + createdBy: 'admin', + createdDate: null, + lastModifiedBy: null, + lastModifiedDate: null, + password: null + })); + }); + }); + }); + +}); diff --git a/src/main/webapp/app/admin/user-management/user-management-detail.component.ts b/src/main/webapp/app/admin/user-management/user-management-detail.component.ts index 65485aae..bcd21e46 100644 --- a/src/main/webapp/app/admin/user-management/user-management-detail.component.ts +++ b/src/main/webapp/app/admin/user-management/user-management-detail.component.ts @@ -26,8 +26,8 @@ export class UserMgmtDetailComponent implements OnInit, OnDestroy { } load(login) { - this.userService.find(login).subscribe((user) => { - this.user = user; + this.userService.find(login).subscribe((response) => { + this.user = response.body; }); } diff --git a/src/main/webapp/app/admin/user-management/user-management-dialog.component.html b/src/main/webapp/app/admin/user-management/user-management-dialog.component.html index 8f8c6947..c7e51a6a 100644 --- a/src/main/webapp/app/admin/user-management/user-management-dialog.component.html +++ b/src/main/webapp/app/admin/user-management/user-management-dialog.component.html @@ -27,9 +27,14 @@

- - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + - + + +
ID Slug Title Description Body Created At Updated At Author
ID Slug Title Description Body Created At Updated At Author
{{article.id}}{{article.slug}}{{article.title}}{{article.description}}{{article.body}}{{article.createdAt | date:'medium'}}{{article.updatedAt | date:'medium'}} - - -
-
{{article.id}}{{article.slug}}{{article.title}}{{article.description}}{{article.body}}{{article.createdAt | date:'medium'}}{{article.updatedAt | date:'medium'}} + + +
+ - - -
-
diff --git a/src/main/webapp/app/entities/article/article.component.spec.ts b/src/main/webapp/app/entities/article/article.component.spec.ts new file mode 100644 index 00000000..0cb6f7b2 --- /dev/null +++ b/src/main/webapp/app/entities/article/article.component.spec.ts @@ -0,0 +1,55 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { Observable } from 'rxjs/Observable'; +import { HttpHeaders, HttpResponse } from '@angular/common/http'; + +import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; +import { ArticleComponent } from './article.component'; +import { ArticleService } from './article.service'; +import { Article } from './article.model'; + +describe('Component Tests', () => { + + describe('Article Management Component', () => { + let comp: ArticleComponent; + let fixture: ComponentFixture; + let service: ArticleService; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [GreatBigExampleApplicationTestModule], + declarations: [ArticleComponent], + providers: [ + ArticleService + ] + }) + .overrideTemplate(ArticleComponent, '') + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ArticleComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(ArticleService); + }); + + describe('OnInit', () => { + it('Should call load all on init', () => { + // GIVEN + const headers = new HttpHeaders().append('link', 'link;link'); + spyOn(service, 'query').and.returnValue(Observable.of(new HttpResponse({ + body: [new Article(123)], + headers + }))); + + // WHEN + comp.ngOnInit(); + + // THEN + expect(service.query).toHaveBeenCalled(); + expect(comp.articles[0]).toEqual(jasmine.objectContaining({ id: 123 })); + }); + }); + }); + +}); diff --git a/src/main/webapp/app/entities/article/article.component.ts b/src/main/webapp/app/entities/article/article.component.ts index 327d25c5..0aa15d61 100644 --- a/src/main/webapp/app/entities/article/article.component.ts +++ b/src/main/webapp/app/entities/article/article.component.ts @@ -1,12 +1,12 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Subscription } from 'rxjs/Rx'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService, JhiDataUtils } from 'ng-jhipster'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; +import { JhiEventManager, JhiParseLinks, JhiAlertService, JhiDataUtils } from 'ng-jhipster'; import { Article } from './article.model'; import { ArticleService } from './article.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { ITEMS_PER_PAGE, Principal } from '../../shared'; @Component({ selector: 'jhi-article', @@ -28,7 +28,7 @@ export class ArticleComponent implements OnInit, OnDestroy { constructor( private articleService: ArticleService, - private alertService: JhiAlertService, + private jhiAlertService: JhiAlertService, private dataUtils: JhiDataUtils, private eventManager: JhiEventManager, private parseLinks: JhiParseLinks, @@ -43,7 +43,8 @@ export class ArticleComponent implements OnInit, OnDestroy { }; this.predicate = 'id'; this.reverse = true; - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; } loadAll() { @@ -54,9 +55,9 @@ export class ArticleComponent implements OnInit, OnDestroy { size: this.itemsPerPage, sort: this.sort() }).subscribe( - (res: ResponseWrapper) => this.onSuccess(res.json, res.headers), - (res: ResponseWrapper) => this.onError(res.json) - ); + (res: HttpResponse) => this.onSuccess(res.body, res.headers), + (res: HttpErrorResponse) => this.onError(res.message) + ); return; } this.articleService.query({ @@ -64,9 +65,9 @@ export class ArticleComponent implements OnInit, OnDestroy { size: this.itemsPerPage, sort: this.sort() }).subscribe( - (res: ResponseWrapper) => this.onSuccess(res.json, res.headers), - (res: ResponseWrapper) => this.onError(res.json) - ); + (res: HttpResponse) => this.onSuccess(res.body, res.headers), + (res: HttpErrorResponse) => this.onError(res.message) + ); } reset() { @@ -150,6 +151,6 @@ export class ArticleComponent implements OnInit, OnDestroy { } private onError(error) { - this.alertService.error(error.message, null, null); + this.jhiAlertService.error(error.message, null, null); } } diff --git a/src/main/webapp/app/entities/article/article.module.ts b/src/main/webapp/app/entities/article/article.module.ts index 9ae52378..470cc8a6 100644 --- a/src/main/webapp/app/entities/article/article.module.ts +++ b/src/main/webapp/app/entities/article/article.module.ts @@ -46,4 +46,4 @@ const ENTITY_STATES = [ ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationArticleModule { } +export class GreatBigExampleApplicationArticleModule {} diff --git a/src/main/webapp/app/entities/article/article.route.ts b/src/main/webapp/app/entities/article/article.route.ts index ec03a7d4..989a86bf 100644 --- a/src/main/webapp/app/entities/article/article.route.ts +++ b/src/main/webapp/app/entities/article/article.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { ArticleComponent } from './article.component'; import { ArticleDetailComponent } from './article-detail.component'; import { ArticlePopupComponent } from './article-dialog.component'; import { ArticleDeletePopupComponent } from './article-delete-dialog.component'; -import { Principal } from '../../shared'; - export const articleRoute: Routes = [ { path: 'article', diff --git a/src/main/webapp/app/entities/article/article.service.spec.ts b/src/main/webapp/app/entities/article/article.service.spec.ts new file mode 100644 index 00000000..e670c497 --- /dev/null +++ b/src/main/webapp/app/entities/article/article.service.spec.ts @@ -0,0 +1,70 @@ +/* tslint:disable max-line-length */ +import { TestBed, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { JhiDateUtils } from 'ng-jhipster'; + +import { ArticleService } from './article.service'; +import { SERVER_API_URL } from '../../app.constants'; + +describe('Service Tests', () => { + + describe('Article Service', () => { + let injector: TestBed; + let service: ArticleService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientTestingModule + ], + providers: [ + JhiDateUtils, + ArticleService + ] + }); + injector = getTestBed(); + service = injector.get(ArticleService); + httpMock = injector.get(HttpTestingController); + }); + + describe('Service methods', () => { + it('should call correct URL', () => { + service.find(123).subscribe(() => { }); + + const req = httpMock.expectOne({ method: 'GET' }); + + const resourceUrl = SERVER_API_URL + 'api/articles'; + expect(req.request.url).toEqual(resourceUrl + '/' + 123); + }); + it('should return Article', () => { + + service.find(123).subscribe((received) => { + expect(received.body.id).toEqual(123); + }); + + const req = httpMock.expectOne({ method: 'GET' }); + req.flush({ id: 123 }); + }); + + it('should propagate not found response', () => { + + service.find(123).subscribe(null, (_error: any) => { + expect(_error.status).toEqual(404); + }); + + const req = httpMock.expectOne({ method: 'GET' }); + req.flush('Invalid request parameters', { + status: 404, statusText: 'Bad Request' + }); + + }); + }); + + afterEach(() => { + httpMock.verify(); + }); + + }); + +}); diff --git a/src/main/webapp/app/entities/article/article.service.ts b/src/main/webapp/app/entities/article/article.service.ts index bf3b7928..7e379bd1 100644 --- a/src/main/webapp/app/entities/article/article.service.ts +++ b/src/main/webapp/app/entities/article/article.service.ts @@ -1,76 +1,85 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; + import { JhiDateUtils } from 'ng-jhipster'; import { Article } from './article.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse
; @Injectable() export class ArticleService { - private resourceUrl = 'api/articles'; - private resourceSearchUrl = 'api/_search/articles'; + private resourceUrl = SERVER_API_URL + 'api/articles'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/articles'; - constructor(private http: Http, private dateUtils: JhiDateUtils) { } + constructor(private http: HttpClient, private dateUtils: JhiDateUtils) { } - create(article: Article): Observable
{ + create(article: Article): Observable { const copy = this.convert(article); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + return this.http.post
(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(article: Article): Observable
{ + update(article: Article): Observable { const copy = this.convert(article); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + return this.http.put
(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable
{ - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + find(id: number): Observable { + return this.http.get
(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Article = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Article[] = res.body; + const body: Article[] = []; for (let i = 0; i < jsonResponse.length; i++) { - this.convertItemFromServer(jsonResponse[i]); + body.push(this.convertItemFromServer(jsonResponse[i])); } - return new ResponseWrapper(res.headers, jsonResponse, res.status); + return res.clone({body}); } - private convertItemFromServer(entity: any) { - entity.createdAt = this.dateUtils - .convertDateTimeFromServer(entity.createdAt); - entity.updatedAt = this.dateUtils - .convertDateTimeFromServer(entity.updatedAt); + /** + * Convert a returned JSON object to Article. + */ + private convertItemFromServer(article: Article): Article { + const copy: Article = Object.assign({}, article); + copy.createdAt = this.dateUtils + .convertDateTimeFromServer(article.createdAt); + copy.updatedAt = this.dateUtils + .convertDateTimeFromServer(article.updatedAt); + return copy; } + /** + * Convert a Article to a JSON which can be sent to the server. + */ private convert(article: Article): Article { const copy: Article = Object.assign({}, article); diff --git a/src/main/webapp/app/entities/author/author-delete-dialog.component.spec.ts b/src/main/webapp/app/entities/author/author-delete-dialog.component.spec.ts new file mode 100644 index 00000000..2e40354c --- /dev/null +++ b/src/main/webapp/app/entities/author/author-delete-dialog.component.spec.ts @@ -0,0 +1,61 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed, async, inject, fakeAsync, tick } from '@angular/core/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { Observable } from 'rxjs/Observable'; +import { JhiEventManager } from 'ng-jhipster'; + +import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; +import { AuthorDeleteDialogComponent } from './author-delete-dialog.component'; +import { AuthorService } from './author.service'; + +describe('Component Tests', () => { + + describe('Author Management Delete Component', () => { + let comp: AuthorDeleteDialogComponent; + let fixture: ComponentFixture; + let service: AuthorService; + let mockEventManager: any; + let mockActiveModal: any; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [GreatBigExampleApplicationTestModule], + declarations: [AuthorDeleteDialogComponent], + providers: [ + AuthorService + ] + }) + .overrideTemplate(AuthorDeleteDialogComponent, '') + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AuthorDeleteDialogComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(AuthorService); + mockEventManager = fixture.debugElement.injector.get(JhiEventManager); + mockActiveModal = fixture.debugElement.injector.get(NgbActiveModal); + }); + + describe('confirmDelete', () => { + it('Should call delete service on confirmDelete', + inject([], + fakeAsync(() => { + // GIVEN + spyOn(service, 'delete').and.returnValue(Observable.of({})); + + // WHEN + comp.confirmDelete(123); + tick(); + + // THEN + expect(service.delete).toHaveBeenCalledWith(123); + expect(mockActiveModal.dismissSpy).toHaveBeenCalled(); + expect(mockEventManager.broadcastSpy).toHaveBeenCalled(); + }) + ) + ); + }); + }); + +}); diff --git a/src/main/webapp/app/entities/author/author-delete-dialog.component.ts b/src/main/webapp/app/entities/author/author-delete-dialog.component.ts index 3bfa55f9..906d7aea 100644 --- a/src/main/webapp/app/entities/author/author-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/author/author-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Author } from './author.model'; @@ -44,18 +44,17 @@ export class AuthorDeleteDialogComponent { }) export class AuthorDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private authorPopupService: AuthorPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.authorPopupService - .open(AuthorDeleteDialogComponent, params['id']); + this.authorPopupService + .open(AuthorDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/author/author-detail.component.html b/src/main/webapp/app/entities/author/author-detail.component.html index ac811145..55525db2 100644 --- a/src/main/webapp/app/entities/author/author-detail.component.html +++ b/src/main/webapp/app/entities/author/author-detail.component.html @@ -35,6 +35,7 @@

Autho diff --git a/src/main/webapp/app/entities/author/author-detail.component.spec.ts b/src/main/webapp/app/entities/author/author-detail.component.spec.ts index 86a8986a..294a7696 100644 --- a/src/main/webapp/app/entities/author/author-detail.component.spec.ts +++ b/src/main/webapp/app/entities/author/author-detail.component.spec.ts @@ -1,11 +1,9 @@ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; + import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; import { AuthorDetailComponent } from './author-detail.component'; import { AuthorService } from './author.service'; import { Author } from './author.model'; @@ -22,17 +20,10 @@ describe('Component Tests', () => { imports: [GreatBigExampleApplicationTestModule], declarations: [AuthorDetailComponent], providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - AuthorService, - JhiEventManager + AuthorService ] - }).overrideTemplate(AuthorDetailComponent, '') + }) + .overrideTemplate(AuthorDetailComponent, '') .compileComponents(); })); @@ -46,14 +37,16 @@ describe('Component Tests', () => { it('Should call load all on init', () => { // GIVEN - spyOn(service, 'find').and.returnValue(Observable.of(new Author(10))); + spyOn(service, 'find').and.returnValue(Observable.of(new HttpResponse({ + body: new Author(123) + }))); // WHEN comp.ngOnInit(); // THEN expect(service.find).toHaveBeenCalledWith(123); - expect(comp.author).toEqual(jasmine.objectContaining({ id: 10 })); + expect(comp.author).toEqual(jasmine.objectContaining({ id: 123 })); }); }); }); diff --git a/src/main/webapp/app/entities/author/author-detail.component.ts b/src/main/webapp/app/entities/author/author-detail.component.ts index c22f315b..66032c16 100644 --- a/src/main/webapp/app/entities/author/author-detail.component.ts +++ b/src/main/webapp/app/entities/author/author-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager , JhiDataUtils } from 'ng-jhipster'; +import { JhiEventManager, JhiDataUtils } from 'ng-jhipster'; import { Author } from './author.model'; import { AuthorService } from './author.service'; @@ -32,9 +33,10 @@ export class AuthorDetailComponent implements OnInit, OnDestroy { } load(id) { - this.authorService.find(id).subscribe((author) => { - this.author = author; - }); + this.authorService.find(id) + .subscribe((authorResponse: HttpResponse) => { + this.author = authorResponse.body; + }); } byteSize(field) { return this.dataUtils.byteSize(field); diff --git a/src/main/webapp/app/entities/author/author-dialog.component.html b/src/main/webapp/app/entities/author/author-dialog.component.html index b78e7929..a6823f5d 100644 --- a/src/main/webapp/app/entities/author/author-dialog.component.html +++ b/src/main/webapp/app/entities/author/author-dialog.component.html @@ -15,11 +15,11 @@

- + - -
@@ -60,21 +60,23 @@

[routerLink]="['../author', author.id ]" class="btn btn-info btn-sm"> - View + View

diff --git a/src/main/webapp/app/entities/author/author.component.spec.ts b/src/main/webapp/app/entities/author/author.component.spec.ts new file mode 100644 index 00000000..88d49254 --- /dev/null +++ b/src/main/webapp/app/entities/author/author.component.spec.ts @@ -0,0 +1,55 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { Observable } from 'rxjs/Observable'; +import { HttpHeaders, HttpResponse } from '@angular/common/http'; + +import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; +import { AuthorComponent } from './author.component'; +import { AuthorService } from './author.service'; +import { Author } from './author.model'; + +describe('Component Tests', () => { + + describe('Author Management Component', () => { + let comp: AuthorComponent; + let fixture: ComponentFixture; + let service: AuthorService; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [GreatBigExampleApplicationTestModule], + declarations: [AuthorComponent], + providers: [ + AuthorService + ] + }) + .overrideTemplate(AuthorComponent, '') + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AuthorComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(AuthorService); + }); + + describe('OnInit', () => { + it('Should call load all on init', () => { + // GIVEN + const headers = new HttpHeaders().append('link', 'link;link'); + spyOn(service, 'query').and.returnValue(Observable.of(new HttpResponse({ + body: [new Author(123)], + headers + }))); + + // WHEN + comp.ngOnInit(); + + // THEN + expect(service.query).toHaveBeenCalled(); + expect(comp.authors[0]).toEqual(jasmine.objectContaining({ id: 123 })); + }); + }); + }); + +}); diff --git a/src/main/webapp/app/entities/author/author.component.ts b/src/main/webapp/app/entities/author/author.component.ts index 4c8a61c5..bd82d396 100644 --- a/src/main/webapp/app/entities/author/author.component.ts +++ b/src/main/webapp/app/entities/author/author.component.ts @@ -1,49 +1,51 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Subscription } from 'rxjs/Rx'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; +import { JhiEventManager, JhiAlertService, JhiDataUtils } from 'ng-jhipster'; import { Author } from './author.model'; import { AuthorService } from './author.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ selector: 'jhi-author', templateUrl: './author.component.html' }) export class AuthorComponent implements OnInit, OnDestroy { - authors: Author[]; +authors: Author[]; currentAccount: any; eventSubscriber: Subscription; currentSearch: string; constructor( private authorService: AuthorService, - private alertService: JhiAlertService, + private jhiAlertService: JhiAlertService, + private dataUtils: JhiDataUtils, private eventManager: JhiEventManager, private activatedRoute: ActivatedRoute, private principal: Principal ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; } loadAll() { if (this.currentSearch) { this.authorService.search({ query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.authors = res.json, - (res: ResponseWrapper) => this.onError(res.json) + }).subscribe( + (res: HttpResponse) => this.authors = res.body, + (res: HttpErrorResponse) => this.onError(res.message) ); return; - } + } this.authorService.query().subscribe( - (res: ResponseWrapper) => { - this.authors = res.json; + (res: HttpResponse) => { + this.authors = res.body; this.currentSearch = ''; }, - (res: ResponseWrapper) => this.onError(res.json) + (res: HttpErrorResponse) => this.onError(res.message) ); } @@ -75,18 +77,18 @@ export class AuthorComponent implements OnInit, OnDestroy { return item.id; } - // byteSize(field) { - // return this.dataUtils.byteSize(field); - // } + byteSize(field) { + return this.dataUtils.byteSize(field); + } - // openFile(contentType, field) { - // return this.dataUtils.openFile(contentType, field); - // } + openFile(contentType, field) { + return this.dataUtils.openFile(contentType, field); + } registerChangeInAuthors() { this.eventSubscriber = this.eventManager.subscribe('authorListModification', (response) => this.loadAll()); } private onError(error) { - this.alertService.error(error.message, null, null); + this.jhiAlertService.error(error.message, null, null); } } diff --git a/src/main/webapp/app/entities/author/author.module.ts b/src/main/webapp/app/entities/author/author.module.ts index 46bf821d..e0562772 100644 --- a/src/main/webapp/app/entities/author/author.module.ts +++ b/src/main/webapp/app/entities/author/author.module.ts @@ -48,4 +48,4 @@ const ENTITY_STATES = [ ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationAuthorModule { } +export class GreatBigExampleApplicationAuthorModule {} diff --git a/src/main/webapp/app/entities/author/author.route.ts b/src/main/webapp/app/entities/author/author.route.ts index 83e44e25..ac48ddb6 100644 --- a/src/main/webapp/app/entities/author/author.route.ts +++ b/src/main/webapp/app/entities/author/author.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { AuthorComponent } from './author.component'; import { AuthorDetailComponent } from './author-detail.component'; import { AuthorPopupComponent } from './author-dialog.component'; import { AuthorDeletePopupComponent } from './author-delete-dialog.component'; -import { Principal } from '../../shared'; - export const authorRoute: Routes = [ { path: 'author', diff --git a/src/main/webapp/app/entities/author/author.service.spec.ts b/src/main/webapp/app/entities/author/author.service.spec.ts new file mode 100644 index 00000000..99d791f3 --- /dev/null +++ b/src/main/webapp/app/entities/author/author.service.spec.ts @@ -0,0 +1,70 @@ +/* tslint:disable max-line-length */ +import { TestBed, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { JhiDateUtils } from 'ng-jhipster'; + +import { AuthorService } from './author.service'; +import { SERVER_API_URL } from '../../app.constants'; + +describe('Service Tests', () => { + + describe('Author Service', () => { + let injector: TestBed; + let service: AuthorService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientTestingModule + ], + providers: [ + JhiDateUtils, + AuthorService + ] + }); + injector = getTestBed(); + service = injector.get(AuthorService); + httpMock = injector.get(HttpTestingController); + }); + + describe('Service methods', () => { + it('should call correct URL', () => { + service.find(123).subscribe(() => { }); + + const req = httpMock.expectOne({ method: 'GET' }); + + const resourceUrl = SERVER_API_URL + 'api/authors'; + expect(req.request.url).toEqual(resourceUrl + '/' + 123); + }); + it('should return Author', () => { + + service.find(123).subscribe((received) => { + expect(received.body.id).toEqual(123); + }); + + const req = httpMock.expectOne({ method: 'GET' }); + req.flush({ id: 123 }); + }); + + it('should propagate not found response', () => { + + service.find(123).subscribe(null, (_error: any) => { + expect(_error.status).toEqual(404); + }); + + const req = httpMock.expectOne({ method: 'GET' }); + req.flush('Invalid request parameters', { + status: 404, statusText: 'Bad Request' + }); + + }); + }); + + afterEach(() => { + httpMock.verify(); + }); + + }); + +}); diff --git a/src/main/webapp/app/entities/author/author.service.ts b/src/main/webapp/app/entities/author/author.service.ts index 70ab6f12..e0c86d4a 100644 --- a/src/main/webapp/app/entities/author/author.service.ts +++ b/src/main/webapp/app/entities/author/author.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Author } from './author.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class AuthorService { - private resourceUrl = 'api/authors'; - private resourceSearchUrl = 'api/_search/authors'; + private resourceUrl = SERVER_API_URL + 'api/authors'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/authors'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(author: Author): Observable { + create(author: Author): Observable { const copy = this.convert(author); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(author: Author): Observable { + update(author: Author): Observable { const copy = this.convert(author); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Author = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Author[] = res.body; + const body: Author[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({body}); + } + + /** + * Convert a returned JSON object to Author. + */ + private convertItemFromServer(author: Author): Author { + const copy: Author = Object.assign({}, author); + return copy; } + /** + * Convert a Author to a JSON which can be sent to the server. + */ private convert(author: Author): Author { const copy: Author = Object.assign({}, author); return copy; diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-delete-dialog.component.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-delete-dialog.component.ts index 899427ab..586affbe 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { ClaimRebuttal } from './claim-rebuttal.model'; @@ -40,22 +40,21 @@ export class ClaimRebuttalDeleteDialogComponent { @Component({ selector: 'jhi-claim-rebuttal-delete-popup', - template: './claim-rebuttal-delete-dialog.component.html' + template: '' }) export class ClaimRebuttalDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private claimRebuttalPopupService: ClaimRebuttalPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.claimRebuttalPopupService - .open(ClaimRebuttalDeleteDialogComponent, params['id']); + this.claimRebuttalPopupService + .open(ClaimRebuttalDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.html b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.html index c7d58657..f1d32acd 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.html +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.html @@ -27,6 +27,7 @@

  Edit diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.spec.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.spec.ts deleted file mode 100644 index 371c695e..00000000 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { ClaimRebuttalDetailComponent } from './claim-rebuttal-detail.component'; -import { ClaimRebuttalService } from './claim-rebuttal.service'; -import { ClaimRebuttal } from './claim-rebuttal.model'; - -describe('Component Tests', () => { - - describe('ClaimRebuttal Management Detail Component', () => { - let comp: ClaimRebuttalDetailComponent; - let fixture: ComponentFixture; - let service: ClaimRebuttalService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [ClaimRebuttalDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - ClaimRebuttalService, - JhiEventManager - ] - }).overrideTemplate(ClaimRebuttalDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ClaimRebuttalDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(ClaimRebuttalService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new ClaimRebuttal(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.claimRebuttal).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.ts index b4ef0b95..143f93a5 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.ts +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { ClaimRebuttal } from './claim-rebuttal.model'; import { ClaimRebuttalService } from './claim-rebuttal.service'; @@ -31,9 +32,10 @@ export class ClaimRebuttalDetailComponent implements OnInit, OnDestroy { } load(id) { - this.claimRebuttalService.find(id).subscribe((claimRebuttal) => { - this.claimRebuttal = claimRebuttal; - }); + this.claimRebuttalService.find(id) + .subscribe((claimRebuttalResponse: HttpResponse) => { + this.claimRebuttal = claimRebuttalResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-dialog.component.html b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-dialog.component.html index 51059a12..cbd447f9 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-dialog.component.html +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal-dialog.component.html @@ -15,22 +15,22 @@

+ [(ngModel)]="claimRebuttal.rebuttalId" />
+ [(ngModel)]="claimRebuttal.sortOrder" />
@@ -48,21 +48,23 @@

[routerLink]="['../claim-rebuttal', claimRebuttal.id ]" class="btn btn-info btn-sm"> - View + View

diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.component.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.component.ts index d9ee6beb..3ad27fe7 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.component.ts +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { ClaimRebuttal } from './claim-rebuttal.model'; import { ClaimRebuttalService } from './claim-rebuttal.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-claim-rebuttal', - templateUrl: './claim-rebuttal.component.html' + selector: 'jhi-claim-rebuttal', + templateUrl: './claim-rebuttal.component.html' }) export class ClaimRebuttalComponent implements OnInit, OnDestroy { - claimRebuttals: ClaimRebuttal[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +claimRebuttals: ClaimRebuttal[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private claimRebuttalService: ClaimRebuttalService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private claimRebuttalService: ClaimRebuttalService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.claimRebuttalService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.claimRebuttals = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.claimRebuttalService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.claimRebuttals = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.claimRebuttalService.query().subscribe( + (res: HttpResponse) => { + this.claimRebuttals = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.claimRebuttalService.query().subscribe( - (res: ResponseWrapper) => { - this.claimRebuttals = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInClaimRebuttals(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInClaimRebuttals(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: ClaimRebuttal) { - return item.id; - } - registerChangeInClaimRebuttals() { - this.eventSubscriber = this.eventManager.subscribe('claimRebuttalListModification', (response) => this.loadAll()); - } + trackId(index: number, item: ClaimRebuttal) { + return item.id; + } + registerChangeInClaimRebuttals() { + this.eventSubscriber = this.eventManager.subscribe('claimRebuttalListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.module.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.module.ts index b1c4c757..cb0990eb 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.module.ts +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - ClaimRebuttalService, - ClaimRebuttalPopupService, - ClaimRebuttalComponent, - ClaimRebuttalDetailComponent, - ClaimRebuttalDialogComponent, - ClaimRebuttalPopupComponent, - ClaimRebuttalDeletePopupComponent, - ClaimRebuttalDeleteDialogComponent, - claimRebuttalRoute, - claimRebuttalPopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...claimRebuttalRoute, - ...claimRebuttalPopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + ClaimRebuttalService, + ClaimRebuttalPopupService, ClaimRebuttalComponent, ClaimRebuttalDetailComponent, ClaimRebuttalDialogComponent, - ClaimRebuttalDeleteDialogComponent, ClaimRebuttalPopupComponent, ClaimRebuttalDeletePopupComponent, - ], - entryComponents: [ - ClaimRebuttalComponent, - ClaimRebuttalDialogComponent, - ClaimRebuttalPopupComponent, ClaimRebuttalDeleteDialogComponent, - ClaimRebuttalDeletePopupComponent, - ], - providers: [ - ClaimRebuttalService, - ClaimRebuttalPopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + claimRebuttalRoute, + claimRebuttalPopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...claimRebuttalRoute, + ...claimRebuttalPopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + ClaimRebuttalComponent, + ClaimRebuttalDetailComponent, + ClaimRebuttalDialogComponent, + ClaimRebuttalDeleteDialogComponent, + ClaimRebuttalPopupComponent, + ClaimRebuttalDeletePopupComponent, + ], + entryComponents: [ + ClaimRebuttalComponent, + ClaimRebuttalDialogComponent, + ClaimRebuttalPopupComponent, + ClaimRebuttalDeleteDialogComponent, + ClaimRebuttalDeletePopupComponent, + ], + providers: [ + ClaimRebuttalService, + ClaimRebuttalPopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationClaimRebuttalModule { } +export class GreatBigExampleApplicationClaimRebuttalModule {} diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.route.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.route.ts index 8404d405..d35c14a5 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.route.ts +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { ClaimRebuttalComponent } from './claim-rebuttal.component'; import { ClaimRebuttalDetailComponent } from './claim-rebuttal-detail.component'; import { ClaimRebuttalPopupComponent } from './claim-rebuttal-dialog.component'; import { ClaimRebuttalDeletePopupComponent } from './claim-rebuttal-delete-dialog.component'; -import { Principal } from '../../shared'; - export const claimRebuttalRoute: Routes = [ { path: 'claim-rebuttal', diff --git a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.service.ts b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.service.ts index a800b6ea..faf22b27 100644 --- a/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.service.ts +++ b/src/main/webapp/app/entities/claim-rebuttal/claim-rebuttal.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { ClaimRebuttal } from './claim-rebuttal.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class ClaimRebuttalService { - private resourceUrl = 'api/claim-rebuttals'; - private resourceSearchUrl = 'api/_search/claim-rebuttals'; + private resourceUrl = SERVER_API_URL + 'api/claim-rebuttals'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/claim-rebuttals'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(claimRebuttal: ClaimRebuttal): Observable { + create(claimRebuttal: ClaimRebuttal): Observable { const copy = this.convert(claimRebuttal); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(claimRebuttal: ClaimRebuttal): Observable { + update(claimRebuttal: ClaimRebuttal): Observable { const copy = this.convert(claimRebuttal); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response' }); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: ClaimRebuttal = this.convertItemFromServer(res.body); + return res.clone({ body }); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: ClaimRebuttal[] = res.body; + const body: ClaimRebuttal[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({ body }); + } + + /** + * Convert a returned JSON object to ClaimRebuttal. + */ + private convertItemFromServer(claimRebuttal: ClaimRebuttal): ClaimRebuttal { + const copy: ClaimRebuttal = Object.assign({}, claimRebuttal); + return copy; } + /** + * Convert a ClaimRebuttal to a JSON which can be sent to the server. + */ private convert(claimRebuttal: ClaimRebuttal): ClaimRebuttal { const copy: ClaimRebuttal = Object.assign({}, claimRebuttal); return copy; diff --git a/src/main/webapp/app/entities/claim/claim-delete-dialog.component.ts b/src/main/webapp/app/entities/claim/claim-delete-dialog.component.ts index 909bfd94..7d5b6ab3 100644 --- a/src/main/webapp/app/entities/claim/claim-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/claim/claim-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Claim } from './claim.model'; @@ -40,22 +40,21 @@ export class ClaimDeleteDialogComponent { @Component({ selector: 'jhi-claim-delete-popup', - template: './claim-delete-dialog-component.html' + template: '' }) export class ClaimDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private claimPopupService: ClaimPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.claimPopupService - .open(ClaimDeleteDialogComponent, params['id']); + this.claimPopupService + .open(ClaimDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/claim/claim-detail.component.html b/src/main/webapp/app/entities/claim/claim-detail.component.html index 1bbab84e..684bb1a8 100644 --- a/src/main/webapp/app/entities/claim/claim-detail.component.html +++ b/src/main/webapp/app/entities/claim/claim-detail.component.html @@ -31,6 +31,7 @@

Claim< diff --git a/src/main/webapp/app/entities/claim/claim-detail.component.spec.ts b/src/main/webapp/app/entities/claim/claim-detail.component.spec.ts deleted file mode 100644 index 621c61dd..00000000 --- a/src/main/webapp/app/entities/claim/claim-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { ClaimDetailComponent } from './claim-detail.component'; -import { ClaimService } from './claim.service'; -import { Claim } from './claim.model'; - -describe('Component Tests', () => { - - describe('Claim Management Detail Component', () => { - let comp: ClaimDetailComponent; - let fixture: ComponentFixture; - let service: ClaimService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [ClaimDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - ClaimService, - JhiEventManager - ] - }).overrideTemplate(ClaimDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ClaimDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(ClaimService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Claim(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.claim).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/claim/claim-detail.component.ts b/src/main/webapp/app/entities/claim/claim-detail.component.ts index 92a44b0b..1f984bca 100644 --- a/src/main/webapp/app/entities/claim/claim-detail.component.ts +++ b/src/main/webapp/app/entities/claim/claim-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Claim } from './claim.model'; import { ClaimService } from './claim.service'; @@ -31,9 +32,10 @@ export class ClaimDetailComponent implements OnInit, OnDestroy { } load(id) { - this.claimService.find(id).subscribe((claim) => { - this.claim = claim; - }); + this.claimService.find(id) + .subscribe((claimResponse: HttpResponse) => { + this.claim = claimResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/claim/claim-dialog.component.html b/src/main/webapp/app/entities/claim/claim-dialog.component.html index ad684b45..5a1b132b 100644 --- a/src/main/webapp/app/entities/claim/claim-dialog.component.html +++ b/src/main/webapp/app/entities/claim/claim-dialog.component.html @@ -15,7 +15,7 @@

@@ -50,21 +50,23 @@

[routerLink]="['../claim', claim.id ]" class="btn btn-info btn-sm"> - View + View

diff --git a/src/main/webapp/app/entities/claim/claim.component.ts b/src/main/webapp/app/entities/claim/claim.component.ts index 9c28fb3b..53366bc0 100644 --- a/src/main/webapp/app/entities/claim/claim.component.ts +++ b/src/main/webapp/app/entities/claim/claim.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { Claim } from './claim.model'; import { ClaimService } from './claim.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-claim', - templateUrl: './claim.component.html' + selector: 'jhi-claim', + templateUrl: './claim.component.html' }) export class ClaimComponent implements OnInit, OnDestroy { - claims: Claim[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +claims: Claim[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private claimService: ClaimService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private claimService: ClaimService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.claimService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.claims = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.claimService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.claims = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.claimService.query().subscribe( + (res: HttpResponse) => { + this.claims = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.claimService.query().subscribe( - (res: ResponseWrapper) => { - this.claims = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInClaims(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInClaims(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Claim) { - return item.id; - } - registerChangeInClaims() { - this.eventSubscriber = this.eventManager.subscribe('claimListModification', (response) => this.loadAll()); - } + trackId(index: number, item: Claim) { + return item.id; + } + registerChangeInClaims() { + this.eventSubscriber = this.eventManager.subscribe('claimListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/claim/claim.module.ts b/src/main/webapp/app/entities/claim/claim.module.ts index b5ab484a..3067043e 100644 --- a/src/main/webapp/app/entities/claim/claim.module.ts +++ b/src/main/webapp/app/entities/claim/claim.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - ClaimService, - ClaimPopupService, - ClaimComponent, - ClaimDetailComponent, - ClaimDialogComponent, - ClaimPopupComponent, - ClaimDeletePopupComponent, - ClaimDeleteDialogComponent, - claimRoute, - claimPopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...claimRoute, - ...claimPopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + ClaimService, + ClaimPopupService, ClaimComponent, ClaimDetailComponent, ClaimDialogComponent, - ClaimDeleteDialogComponent, ClaimPopupComponent, ClaimDeletePopupComponent, - ], - entryComponents: [ - ClaimComponent, - ClaimDialogComponent, - ClaimPopupComponent, ClaimDeleteDialogComponent, - ClaimDeletePopupComponent, - ], - providers: [ - ClaimService, - ClaimPopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + claimRoute, + claimPopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...claimRoute, + ...claimPopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + ClaimComponent, + ClaimDetailComponent, + ClaimDialogComponent, + ClaimDeleteDialogComponent, + ClaimPopupComponent, + ClaimDeletePopupComponent, + ], + entryComponents: [ + ClaimComponent, + ClaimDialogComponent, + ClaimPopupComponent, + ClaimDeleteDialogComponent, + ClaimDeletePopupComponent, + ], + providers: [ + ClaimService, + ClaimPopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationClaimModule { } +export class GreatBigExampleApplicationClaimModule {} diff --git a/src/main/webapp/app/entities/claim/claim.route.ts b/src/main/webapp/app/entities/claim/claim.route.ts index 76e0057b..5bc72e7d 100644 --- a/src/main/webapp/app/entities/claim/claim.route.ts +++ b/src/main/webapp/app/entities/claim/claim.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { ClaimComponent } from './claim.component'; import { ClaimDetailComponent } from './claim-detail.component'; import { ClaimPopupComponent } from './claim-dialog.component'; import { ClaimDeletePopupComponent } from './claim-delete-dialog.component'; -import { Principal } from '../../shared'; - export const claimRoute: Routes = [ { path: 'claim', diff --git a/src/main/webapp/app/entities/claim/claim.service.ts b/src/main/webapp/app/entities/claim/claim.service.ts index 95e8ccb7..dc42427e 100644 --- a/src/main/webapp/app/entities/claim/claim.service.ts +++ b/src/main/webapp/app/entities/claim/claim.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Claim } from './claim.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class ClaimService { - private resourceUrl = 'api/claims'; - private resourceSearchUrl = 'api/_search/claims'; + private resourceUrl = SERVER_API_URL + 'api/claims'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/claims'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(claim: Claim): Observable { + create(claim: Claim): Observable { const copy = this.convert(claim); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(claim: Claim): Observable { + update(claim: Claim): Observable { const copy = this.convert(claim); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response' }); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Claim = this.convertItemFromServer(res.body); + return res.clone({ body }); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Claim[] = res.body; + const body: Claim[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({ body }); + } + + /** + * Convert a returned JSON object to Claim. + */ + private convertItemFromServer(claim: Claim): Claim { + const copy: Claim = Object.assign({}, claim); + return copy; } + /** + * Convert a Claim to a JSON which can be sent to the server. + */ private convert(claim: Claim): Claim { const copy: Claim = Object.assign({}, claim); return copy; diff --git a/src/main/webapp/app/entities/comment/comment-delete-dialog.component.ts b/src/main/webapp/app/entities/comment/comment-delete-dialog.component.ts index a0138ff5..ea880fc4 100644 --- a/src/main/webapp/app/entities/comment/comment-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/comment/comment-delete-dialog.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; -import { JhiAlertService, JhiEventManager } from 'ng-jhipster'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { JhiEventManager } from 'ng-jhipster'; import { Comment } from './comment.model'; import { CommentPopupService } from './comment-popup.service'; @@ -19,7 +19,6 @@ export class CommentDeleteDialogComponent { constructor( private commentService: CommentService, public activeModal: NgbActiveModal, - private alertService: JhiAlertService, private eventManager: JhiEventManager ) { } @@ -36,7 +35,6 @@ export class CommentDeleteDialogComponent { }); this.activeModal.dismiss(true); }); - this.alertService.success('greatBigExampleApplicationApp.comment.deleted', { param: id }, null); } } @@ -46,18 +44,17 @@ export class CommentDeleteDialogComponent { }) export class CommentDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private commentPopupService: CommentPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.commentPopupService - .open(CommentDeleteDialogComponent, params['id']); + this.commentPopupService + .open(CommentDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/comment/comment-detail.component.html b/src/main/webapp/app/entities/comment/comment-detail.component.html index 6eb2a022..2ca78f54 100644 --- a/src/main/webapp/app/entities/comment/comment-detail.component.html +++ b/src/main/webapp/app/entities/comment/comment-detail.component.html @@ -39,6 +39,7 @@

Comm diff --git a/src/main/webapp/app/entities/comment/comment-detail.component.spec.ts b/src/main/webapp/app/entities/comment/comment-detail.component.spec.ts deleted file mode 100644 index 60c2ab21..00000000 --- a/src/main/webapp/app/entities/comment/comment-detail.component.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { CommentDetailComponent } from './comment-detail.component'; -import { CommentService } from './comment.service'; -import { Comment } from './comment.model'; - -describe('Component Tests', () => { - - describe('Comment Management Detail Component', () => { - let comp: CommentDetailComponent; - let fixture: ComponentFixture; - let service: CommentService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [CommentDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - CommentService, - JhiEventManager - ] - }).overrideTemplate(CommentDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(CommentDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(CommentService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Comment(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.comment).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/comment/comment-detail.component.ts b/src/main/webapp/app/entities/comment/comment-detail.component.ts index a901acb1..dce62893 100644 --- a/src/main/webapp/app/entities/comment/comment-detail.component.ts +++ b/src/main/webapp/app/entities/comment/comment-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs/Rx'; -import { JhiEventManager , JhiDataUtils } from 'ng-jhipster'; +import { HttpResponse } from '@angular/common/http'; +import { Subscription } from 'rxjs/Subscription'; +import { JhiEventManager, JhiDataUtils } from 'ng-jhipster'; import { Comment } from './comment.model'; import { CommentService } from './comment.service'; @@ -32,9 +33,10 @@ export class CommentDetailComponent implements OnInit, OnDestroy { } load(id) { - this.commentService.find(id).subscribe((comment) => { - this.comment = comment; - }); + this.commentService.find(id) + .subscribe((commentResponse: HttpResponse) => { + this.comment = commentResponse.body; + }); } byteSize(field) { return this.dataUtils.byteSize(field); diff --git a/src/main/webapp/app/entities/comment/comment-dialog.component.html b/src/main/webapp/app/entities/comment/comment-dialog.component.html index 1367bd24..7bb35937 100644 --- a/src/main/webapp/app/entities/comment/comment-dialog.component.html +++ b/src/main/webapp/app/entities/comment/comment-dialog.component.html @@ -15,7 +15,7 @@

diff --git a/src/main/webapp/app/entities/contact/contact.component.ts b/src/main/webapp/app/entities/contact/contact.component.ts index b63843dd..402caddd 100644 --- a/src/main/webapp/app/entities/contact/contact.component.ts +++ b/src/main/webapp/app/entities/contact/contact.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { Contact } from './contact.model'; import { ContactService } from './contact.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-contact', - templateUrl: './contact.component.html' + selector: 'jhi-contact', + templateUrl: './contact.component.html' }) export class ContactComponent implements OnInit, OnDestroy { - contacts: Contact[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +contacts: Contact[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private contactService: ContactService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private contactService: ContactService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.contactService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.contacts = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.contactService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.contacts = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.contactService.query().subscribe( + (res: HttpResponse) => { + this.contacts = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.contactService.query().subscribe( - (res: ResponseWrapper) => { - this.contacts = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInContacts(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInContacts(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Contact) { - return item.id; - } - registerChangeInContacts() { - this.eventSubscriber = this.eventManager.subscribe('contactListModification', (response) => this.loadAll()); - } + trackId(index: number, item: Contact) { + return item.id; + } + registerChangeInContacts() { + this.eventSubscriber = this.eventManager.subscribe('contactListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/contact/contact.module.ts b/src/main/webapp/app/entities/contact/contact.module.ts index bb827ec2..a527daa9 100644 --- a/src/main/webapp/app/entities/contact/contact.module.ts +++ b/src/main/webapp/app/entities/contact/contact.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - ContactService, - ContactPopupService, - ContactComponent, - ContactDetailComponent, - ContactDialogComponent, - ContactPopupComponent, - ContactDeletePopupComponent, - ContactDeleteDialogComponent, - contactRoute, - contactPopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...contactRoute, - ...contactPopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + ContactService, + ContactPopupService, ContactComponent, ContactDetailComponent, ContactDialogComponent, - ContactDeleteDialogComponent, ContactPopupComponent, ContactDeletePopupComponent, - ], - entryComponents: [ - ContactComponent, - ContactDialogComponent, - ContactPopupComponent, ContactDeleteDialogComponent, - ContactDeletePopupComponent, - ], - providers: [ - ContactService, - ContactPopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + contactRoute, + contactPopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...contactRoute, + ...contactPopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + ContactComponent, + ContactDetailComponent, + ContactDialogComponent, + ContactDeleteDialogComponent, + ContactPopupComponent, + ContactDeletePopupComponent, + ], + entryComponents: [ + ContactComponent, + ContactDialogComponent, + ContactPopupComponent, + ContactDeleteDialogComponent, + ContactDeletePopupComponent, + ], + providers: [ + ContactService, + ContactPopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationContactModule { } +export class GreatBigExampleApplicationContactModule {} diff --git a/src/main/webapp/app/entities/contact/contact.route.ts b/src/main/webapp/app/entities/contact/contact.route.ts index cbf19439..c10a7fec 100644 --- a/src/main/webapp/app/entities/contact/contact.route.ts +++ b/src/main/webapp/app/entities/contact/contact.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { ContactComponent } from './contact.component'; import { ContactDetailComponent } from './contact-detail.component'; import { ContactPopupComponent } from './contact-dialog.component'; import { ContactDeletePopupComponent } from './contact-delete-dialog.component'; -import { Principal } from '../../shared'; - export const contactRoute: Routes = [ { path: 'contact', diff --git a/src/main/webapp/app/entities/contact/contact.service.ts b/src/main/webapp/app/entities/contact/contact.service.ts index 5bd6e61f..1c272608 100644 --- a/src/main/webapp/app/entities/contact/contact.service.ts +++ b/src/main/webapp/app/entities/contact/contact.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Contact } from './contact.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class ContactService { - private resourceUrl = 'api/contacts'; - private resourceSearchUrl = 'api/_search/contacts'; + private resourceUrl = SERVER_API_URL + 'api/contacts'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/contacts'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(contact: Contact): Observable { + create(contact: Contact): Observable { const copy = this.convert(contact); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(contact: Contact): Observable { + update(contact: Contact): Observable { const copy = this.convert(contact); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Contact = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Contact[] = res.body; + const body: Contact[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({body}); + } + + /** + * Convert a returned JSON object to Contact. + */ + private convertItemFromServer(contact: Contact): Contact { + const copy: Contact = Object.assign({}, contact); + return copy; } + /** + * Convert a Contact to a JSON which can be sent to the server. + */ private convert(contact: Contact): Contact { const copy: Contact = Object.assign({}, contact); return copy; diff --git a/src/main/webapp/app/entities/crisis/crisis-delete-dialog.component.ts b/src/main/webapp/app/entities/crisis/crisis-delete-dialog.component.ts index b1f6c582..fb9fbb40 100644 --- a/src/main/webapp/app/entities/crisis/crisis-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/crisis/crisis-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Crisis } from './crisis.model'; @@ -44,18 +44,17 @@ export class CrisisDeleteDialogComponent { }) export class CrisisDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private crisisPopupService: CrisisPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.crisisPopupService - .open(CrisisDeleteDialogComponent, params['id']); + this.crisisPopupService + .open(CrisisDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/crisis/crisis-detail.component.html b/src/main/webapp/app/entities/crisis/crisis-detail.component.html index 4224c762..ecb025ce 100644 --- a/src/main/webapp/app/entities/crisis/crisis-detail.component.html +++ b/src/main/webapp/app/entities/crisis/crisis-detail.component.html @@ -19,6 +19,7 @@

Crisi diff --git a/src/main/webapp/app/entities/crisis/crisis-detail.component.spec.ts b/src/main/webapp/app/entities/crisis/crisis-detail.component.spec.ts deleted file mode 100644 index 2374dab9..00000000 --- a/src/main/webapp/app/entities/crisis/crisis-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { CrisisDetailComponent } from './crisis-detail.component'; -import { CrisisService } from './crisis.service'; -import { Crisis } from '../../entities/crisis/crisis.model'; - -describe('Component Tests', () => { - - describe('Crisis Management Detail Component', () => { - let comp: CrisisDetailComponent; - let fixture: ComponentFixture; - let service: CrisisService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [CrisisDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - CrisisService, - JhiEventManager - ] - }).overrideTemplate(CrisisDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(CrisisDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(CrisisService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Crisis(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.crisis).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/crisis/crisis-detail.component.ts b/src/main/webapp/app/entities/crisis/crisis-detail.component.ts index 03a93ae8..8313119c 100644 --- a/src/main/webapp/app/entities/crisis/crisis-detail.component.ts +++ b/src/main/webapp/app/entities/crisis/crisis-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Crisis } from './crisis.model'; import { CrisisService } from './crisis.service'; @@ -31,9 +32,10 @@ export class CrisisDetailComponent implements OnInit, OnDestroy { } load(id) { - this.crisisService.find(id).subscribe((crisis) => { - this.crisis = crisis; - }); + this.crisisService.find(id) + .subscribe((crisisResponse: HttpResponse) => { + this.crisis = crisisResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/crisis/crisis-dialog.component.html b/src/main/webapp/app/entities/crisis/crisis-dialog.component.html index 356a6616..239e6955 100644 --- a/src/main/webapp/app/entities/crisis/crisis-dialog.component.html +++ b/src/main/webapp/app/entities/crisis/crisis-dialog.component.html @@ -15,7 +15,7 @@

diff --git a/src/main/webapp/app/entities/crisis/crisis.component.ts b/src/main/webapp/app/entities/crisis/crisis.component.ts index 83d37036..d0cbdde6 100644 --- a/src/main/webapp/app/entities/crisis/crisis.component.ts +++ b/src/main/webapp/app/entities/crisis/crisis.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { Crisis } from './crisis.model'; import { CrisisService } from './crisis.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-crisis', - templateUrl: './crisis.component.html' + selector: 'jhi-crisis', + templateUrl: './crisis.component.html' }) export class CrisisComponent implements OnInit, OnDestroy { - crises: Crisis[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +crises: Crisis[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private crisisService: CrisisService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private crisisService: CrisisService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.crisisService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.crises = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.crisisService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.crises = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.crisisService.query().subscribe( + (res: HttpResponse) => { + this.crises = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.crisisService.query().subscribe( - (res: ResponseWrapper) => { - this.crises = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInCrises(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInCrises(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Crisis) { - return item.id; - } - registerChangeInCrises() { - this.eventSubscriber = this.eventManager.subscribe('crisisListModification', (response) => this.loadAll()); - } + trackId(index: number, item: Crisis) { + return item.id; + } + registerChangeInCrises() { + this.eventSubscriber = this.eventManager.subscribe('crisisListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/crisis/crisis.module.ts b/src/main/webapp/app/entities/crisis/crisis.module.ts index f858957a..e5f00cb6 100644 --- a/src/main/webapp/app/entities/crisis/crisis.module.ts +++ b/src/main/webapp/app/entities/crisis/crisis.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - CrisisService, - CrisisPopupService, - CrisisComponent, - CrisisDetailComponent, - CrisisDialogComponent, - CrisisPopupComponent, - CrisisDeletePopupComponent, - CrisisDeleteDialogComponent, - crisisRoute, - crisisPopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...crisisRoute, - ...crisisPopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + CrisisService, + CrisisPopupService, CrisisComponent, CrisisDetailComponent, CrisisDialogComponent, - CrisisDeleteDialogComponent, CrisisPopupComponent, CrisisDeletePopupComponent, - ], - entryComponents: [ - CrisisComponent, - CrisisDialogComponent, - CrisisPopupComponent, CrisisDeleteDialogComponent, - CrisisDeletePopupComponent, - ], - providers: [ - CrisisService, - CrisisPopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + crisisRoute, + crisisPopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...crisisRoute, + ...crisisPopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + CrisisComponent, + CrisisDetailComponent, + CrisisDialogComponent, + CrisisDeleteDialogComponent, + CrisisPopupComponent, + CrisisDeletePopupComponent, + ], + entryComponents: [ + CrisisComponent, + CrisisDialogComponent, + CrisisPopupComponent, + CrisisDeleteDialogComponent, + CrisisDeletePopupComponent, + ], + providers: [ + CrisisService, + CrisisPopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationCrisisModule { } +export class GreatBigExampleApplicationCrisisModule {} diff --git a/src/main/webapp/app/entities/crisis/crisis.route.ts b/src/main/webapp/app/entities/crisis/crisis.route.ts index bb3d2223..269809e6 100644 --- a/src/main/webapp/app/entities/crisis/crisis.route.ts +++ b/src/main/webapp/app/entities/crisis/crisis.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { CrisisComponent } from './crisis.component'; import { CrisisDetailComponent } from './crisis-detail.component'; import { CrisisPopupComponent } from './crisis-dialog.component'; import { CrisisDeletePopupComponent } from './crisis-delete-dialog.component'; -import { Principal } from '../../shared'; - export const crisisRoute: Routes = [ { path: 'crisis', diff --git a/src/main/webapp/app/entities/crisis/crisis.service.ts b/src/main/webapp/app/entities/crisis/crisis.service.ts index 13fa5602..4ae42600 100644 --- a/src/main/webapp/app/entities/crisis/crisis.service.ts +++ b/src/main/webapp/app/entities/crisis/crisis.service.ts @@ -1,58 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; + import { Crisis } from './crisis.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class CrisisService { - private resourceUrl = 'api/crises'; - private resourceSearchUrl = 'api/_search/crises'; + private resourceUrl = SERVER_API_URL + 'api/crises'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/crises'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(crisis: Crisis): Observable { + create(crisis: Crisis): Observable { const copy = this.convert(crisis); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(crisis: Crisis): Observable { + update(crisis: Crisis): Observable { const copy = this.convert(crisis); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Crisis = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Crisis[] = res.body; + const body: Crisis[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({body}); + } + + /** + * Convert a returned JSON object to Crisis. + */ + private convertItemFromServer(crisis: Crisis): Crisis { + const copy: Crisis = Object.assign({}, crisis); + return copy; } + /** + * Convert a Crisis to a JSON which can be sent to the server. + */ private convert(crisis: Crisis): Crisis { const copy: Crisis = Object.assign({}, crisis); return copy; diff --git a/src/main/webapp/app/entities/entity.module.ts b/src/main/webapp/app/entities/entity.module.ts index 10845ecd..c491811a 100644 --- a/src/main/webapp/app/entities/entity.module.ts +++ b/src/main/webapp/app/entities/entity.module.ts @@ -7,11 +7,11 @@ import { GreatBigExampleApplicationContactModule } from './contact/contact.modul import { GreatBigExampleApplicationNoteModule } from './note/note.module'; import { GreatBigExampleApplicationRebuttalModule } from './rebuttal/rebuttal.module'; import { GreatBigExampleApplicationClaimRebuttalModule } from './claim-rebuttal/claim-rebuttal.module'; -import { GreatBigExampleApplicationArticleModule } from './article/article.module'; -import { GreatBigExampleApplicationTagModule } from './tag/tag.module'; import { GreatBigExampleApplicationMessageModule } from './message/message.module'; -import { GreatBigExampleApplicationAuthorModule } from './author/author.module'; +import { GreatBigExampleApplicationTagModule } from './tag/tag.module'; +import { GreatBigExampleApplicationArticleModule } from './article/article.module'; import { GreatBigExampleApplicationCommentModule } from './comment/comment.module'; +import { GreatBigExampleApplicationAuthorModule } from './author/author.module'; import { GreatBigExampleApplicationTalkModule } from './talk/talk.module'; /* jhipster-needle-add-entity-module-import - JHipster will add entity modules imports here */ @@ -24,11 +24,11 @@ import { GreatBigExampleApplicationTalkModule } from './talk/talk.module'; GreatBigExampleApplicationNoteModule, GreatBigExampleApplicationRebuttalModule, GreatBigExampleApplicationClaimRebuttalModule, - GreatBigExampleApplicationArticleModule, - GreatBigExampleApplicationTagModule, GreatBigExampleApplicationMessageModule, - GreatBigExampleApplicationAuthorModule, + GreatBigExampleApplicationTagModule, + GreatBigExampleApplicationArticleModule, GreatBigExampleApplicationCommentModule, + GreatBigExampleApplicationAuthorModule, GreatBigExampleApplicationTalkModule, /* jhipster-needle-add-entity-module - JHipster will add entity modules here */ ], diff --git a/src/main/webapp/app/entities/hero/hero-delete-dialog.component.ts b/src/main/webapp/app/entities/hero/hero-delete-dialog.component.ts index 1dd0c28b..db9b9889 100644 --- a/src/main/webapp/app/entities/hero/hero-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/hero/hero-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Hero } from './hero.model'; @@ -40,22 +40,21 @@ export class HeroDeleteDialogComponent { @Component({ selector: 'jhi-hero-delete-popup', - template: './hero-delete-dialog.component.html' + template: '' }) export class HeroDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private heroPopupService: HeroPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.heroPopupService - .open(HeroDeleteDialogComponent, params['id']); + this.heroPopupService + .open(HeroDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/hero/hero-detail.component.html b/src/main/webapp/app/entities/hero/hero-detail.component.html index c3c52659..bd6f67b1 100644 --- a/src/main/webapp/app/entities/hero/hero-detail.component.html +++ b/src/main/webapp/app/entities/hero/hero-detail.component.html @@ -19,6 +19,7 @@

Hero   Edit diff --git a/src/main/webapp/app/entities/hero/hero-detail.component.spec.ts b/src/main/webapp/app/entities/hero/hero-detail.component.spec.ts deleted file mode 100644 index e9e9a035..00000000 --- a/src/main/webapp/app/entities/hero/hero-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { HeroDetailComponent } from './hero-detail.component'; -import { HeroService } from './hero.service'; -import { Hero } from './hero.model'; - -describe('Component Tests', () => { - - describe('Hero Management Detail Component', () => { - let comp: HeroDetailComponent; - let fixture: ComponentFixture; - let service: HeroService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [HeroDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - HeroService, - JhiEventManager - ] - }).overrideTemplate(HeroDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(HeroDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(HeroService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Hero(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.hero).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/hero/hero-detail.component.ts b/src/main/webapp/app/entities/hero/hero-detail.component.ts index 184f1948..2503aab6 100644 --- a/src/main/webapp/app/entities/hero/hero-detail.component.ts +++ b/src/main/webapp/app/entities/hero/hero-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Hero } from './hero.model'; import { HeroService } from './hero.service'; @@ -31,9 +32,10 @@ export class HeroDetailComponent implements OnInit, OnDestroy { } load(id) { - this.heroService.find(id).subscribe((hero) => { - this.hero = hero; - }); + this.heroService.find(id) + .subscribe((heroResponse: HttpResponse) => { + this.hero = heroResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/hero/hero-dialog.component.html b/src/main/webapp/app/entities/hero/hero-dialog.component.html index 915a8ff4..8e94585d 100644 --- a/src/main/webapp/app/entities/hero/hero-dialog.component.html +++ b/src/main/webapp/app/entities/hero/hero-dialog.component.html @@ -15,7 +15,7 @@

diff --git a/src/main/webapp/app/entities/hero/hero.component.ts b/src/main/webapp/app/entities/hero/hero.component.ts index 508538ff..6ff1c94a 100644 --- a/src/main/webapp/app/entities/hero/hero.component.ts +++ b/src/main/webapp/app/entities/hero/hero.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { Hero } from './hero.model'; import { HeroService } from './hero.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-hero', - templateUrl: './hero.component.html' + selector: 'jhi-hero', + templateUrl: './hero.component.html' }) export class HeroComponent implements OnInit, OnDestroy { - heroes: Hero[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +heroes: Hero[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private heroService: HeroService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private heroService: HeroService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.heroService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.heroes = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.heroService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.heroes = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.heroService.query().subscribe( + (res: HttpResponse) => { + this.heroes = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.heroService.query().subscribe( - (res: ResponseWrapper) => { - this.heroes = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInHeroes(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInHeroes(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Hero) { - return item.id; - } - registerChangeInHeroes() { - this.eventSubscriber = this.eventManager.subscribe('heroListModification', (response) => this.loadAll()); - } + trackId(index: number, item: Hero) { + return item.id; + } + registerChangeInHeroes() { + this.eventSubscriber = this.eventManager.subscribe('heroListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/hero/hero.module.ts b/src/main/webapp/app/entities/hero/hero.module.ts index cec2cd8c..b4b770e0 100644 --- a/src/main/webapp/app/entities/hero/hero.module.ts +++ b/src/main/webapp/app/entities/hero/hero.module.ts @@ -46,4 +46,4 @@ const ENTITY_STATES = [ ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationHeroModule { } +export class GreatBigExampleApplicationHeroModule {} diff --git a/src/main/webapp/app/entities/hero/hero.route.ts b/src/main/webapp/app/entities/hero/hero.route.ts index 3f8d9e3f..e4997579 100644 --- a/src/main/webapp/app/entities/hero/hero.route.ts +++ b/src/main/webapp/app/entities/hero/hero.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { HeroComponent } from './hero.component'; import { HeroDetailComponent } from './hero-detail.component'; import { HeroPopupComponent } from './hero-dialog.component'; import { HeroDeletePopupComponent } from './hero-delete-dialog.component'; -import { Principal } from '../../shared'; - export const heroRoute: Routes = [ { path: 'hero', diff --git a/src/main/webapp/app/entities/hero/hero.service.ts b/src/main/webapp/app/entities/hero/hero.service.ts index 05ca5275..f301005b 100644 --- a/src/main/webapp/app/entities/hero/hero.service.ts +++ b/src/main/webapp/app/entities/hero/hero.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Hero } from './hero.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class HeroService { - private resourceUrl = 'api/heroes'; - private resourceSearchUrl = 'api/_search/heroes'; + private resourceUrl = SERVER_API_URL + 'api/heroes'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/heroes'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(hero: Hero): Observable { + create(hero: Hero): Observable { const copy = this.convert(hero); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(hero: Hero): Observable { + update(hero: Hero): Observable { const copy = this.convert(hero); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Hero = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Hero[] = res.body; + const body: Hero[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({body}); + } + + /** + * Convert a returned JSON object to Hero. + */ + private convertItemFromServer(hero: Hero): Hero { + const copy: Hero = Object.assign({}, hero); + return copy; } + /** + * Convert a Hero to a JSON which can be sent to the server. + */ private convert(hero: Hero): Hero { const copy: Hero = Object.assign({}, hero); return copy; diff --git a/src/main/webapp/app/entities/message/message-delete-dialog.component.ts b/src/main/webapp/app/entities/message/message-delete-dialog.component.ts index 7a711c67..52eda924 100644 --- a/src/main/webapp/app/entities/message/message-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/message/message-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Message } from './message.model'; @@ -44,18 +44,17 @@ export class MessageDeleteDialogComponent { }) export class MessageDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private messagePopupService: MessagePopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.messagePopupService - .open(MessageDeleteDialogComponent, params['id']); + this.messagePopupService + .open(MessageDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/message/message-detail.component.html b/src/main/webapp/app/entities/message/message-detail.component.html index 259ec9c2..e8912e2a 100644 --- a/src/main/webapp/app/entities/message/message-detail.component.html +++ b/src/main/webapp/app/entities/message/message-detail.component.html @@ -31,6 +31,7 @@

Mess diff --git a/src/main/webapp/app/entities/message/message-detail.component.spec.ts b/src/main/webapp/app/entities/message/message-detail.component.spec.ts deleted file mode 100644 index 7afcd9da..00000000 --- a/src/main/webapp/app/entities/message/message-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { MessageDetailComponent } from './message-detail.component'; -import { MessageService } from './message.service'; -import { Message } from './message.model'; - -describe('Component Tests', () => { - - describe('Message Management Detail Component', () => { - let comp: MessageDetailComponent; - let fixture: ComponentFixture; - let service: MessageService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [MessageDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - MessageService, - JhiEventManager - ] - }).overrideTemplate(MessageDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(MessageDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(MessageService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Message(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.message).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/message/message-detail.component.ts b/src/main/webapp/app/entities/message/message-detail.component.ts index 31437f13..a0b927f5 100644 --- a/src/main/webapp/app/entities/message/message-detail.component.ts +++ b/src/main/webapp/app/entities/message/message-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Message } from './message.model'; import { MessageService } from './message.service'; @@ -31,9 +32,10 @@ export class MessageDetailComponent implements OnInit, OnDestroy { } load(id) { - this.messageService.find(id).subscribe((message) => { - this.message = message; - }); + this.messageService.find(id) + .subscribe((messageResponse: HttpResponse) => { + this.message = messageResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/message/message-dialog.component.html b/src/main/webapp/app/entities/message/message-dialog.component.html index ee317451..122d97a6 100644 --- a/src/main/webapp/app/entities/message/message-dialog.component.html +++ b/src/main/webapp/app/entities/message/message-dialog.component.html @@ -15,12 +15,12 @@

+ [(ngModel)]="message.message" required/>
@@ -32,20 +32,20 @@
+ />
@@ -50,21 +50,23 @@

[routerLink]="['../message', message.id ]" class="btn btn-info btn-sm"> - View + View

diff --git a/src/main/webapp/app/entities/message/message.component.ts b/src/main/webapp/app/entities/message/message.component.ts index 44544469..2c842b41 100644 --- a/src/main/webapp/app/entities/message/message.component.ts +++ b/src/main/webapp/app/entities/message/message.component.ts @@ -1,146 +1,147 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiParseLinks, JhiAlertService } from 'ng-jhipster'; import { Message } from './message.model'; import { MessageService } from './message.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { ITEMS_PER_PAGE, Principal } from '../../shared'; @Component({ - selector: 'jhi-message', - templateUrl: './message.component.html' + selector: 'jhi-message', + templateUrl: './message.component.html' }) export class MessageComponent implements OnInit, OnDestroy { - messages: Message[]; - currentAccount: any; - eventSubscriber: Subscription; - itemsPerPage: number; - links: any; - page: any; - predicate: any; - queryCount: any; - reverse: any; - totalItems: number; - currentSearch: string; + messages: Message[]; + currentAccount: any; + eventSubscriber: Subscription; + itemsPerPage: number; + links: any; + page: any; + predicate: any; + queryCount: any; + reverse: any; + totalItems: number; + currentSearch: string; - constructor( - private messageService: MessageService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private parseLinks: JhiParseLinks, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.messages = []; - this.itemsPerPage = ITEMS_PER_PAGE; - this.page = 0; - this.links = { - last: 0 - }; - this.predicate = 'id'; - this.reverse = true; - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private messageService: MessageService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private parseLinks: JhiParseLinks, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.messages = []; + this.itemsPerPage = ITEMS_PER_PAGE; + this.page = 0; + this.links = { + last: 0 + }; + this.predicate = 'id'; + this.reverse = true; + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.messageService.search({ - query: this.currentSearch, - page: this.page, - size: this.itemsPerPage, - sort: this.sort() - }).subscribe( - (res: ResponseWrapper) => this.onSuccess(res.json, res.headers), - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.messageService.search({ + query: this.currentSearch, + page: this.page, + size: this.itemsPerPage, + sort: this.sort() + }).subscribe( + (res: HttpResponse) => this.onSuccess(res.body, res.headers), + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.messageService.query({ + page: this.page, + size: this.itemsPerPage, + sort: this.sort() + }).subscribe( + (res: HttpResponse) => this.onSuccess(res.body, res.headers), + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.messageService.query({ - page: this.page, - size: this.itemsPerPage, - sort: this.sort() - }).subscribe( - (res: ResponseWrapper) => this.onSuccess(res.json, res.headers), - (res: ResponseWrapper) => this.onError(res.json) - ); - } - reset() { - this.page = 0; - this.messages = []; - this.loadAll(); - } + reset() { + this.page = 0; + this.messages = []; + this.loadAll(); + } - loadPage(page) { - this.page = page; - this.loadAll(); - } + loadPage(page) { + this.page = page; + this.loadAll(); + } - clear() { - this.messages = []; - this.links = { - last: 0 - }; - this.page = 0; - this.predicate = 'id'; - this.reverse = true; - this.currentSearch = ''; - this.loadAll(); - } + clear() { + this.messages = []; + this.links = { + last: 0 + }; + this.page = 0; + this.predicate = 'id'; + this.reverse = true; + this.currentSearch = ''; + this.loadAll(); + } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.messages = []; + this.links = { + last: 0 + }; + this.page = 0; + this.predicate = '_score'; + this.reverse = false; + this.currentSearch = query; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInMessages(); } - this.messages = []; - this.links = { - last: 0 - }; - this.page = 0; - this.predicate = '_score'; - this.reverse = false; - this.currentSearch = query; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInMessages(); - } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Message) { - return item.id; - } - registerChangeInMessages() { - this.eventSubscriber = this.eventManager.subscribe('messageListModification', (response) => this.reset()); - } + trackId(index: number, item: Message) { + return item.id; + } + registerChangeInMessages() { + this.eventSubscriber = this.eventManager.subscribe('messageListModification', (response) => this.reset()); + } - sort() { - const result = [this.predicate + ',' + (this.reverse ? 'asc' : 'desc')]; - if (this.predicate !== 'id') { - result.push('id'); + sort() { + const result = [this.predicate + ',' + (this.reverse ? 'asc' : 'desc')]; + if (this.predicate !== 'id') { + result.push('id'); + } + return result; } - return result; - } - private onSuccess(data, headers) { - this.links = this.parseLinks.parse(headers.get('link')); - this.totalItems = headers.get('X-Total-Count'); - for (let i = 0; i < data.length; i++) { - this.messages.push(data[i]); + private onSuccess(data, headers) { + this.links = this.parseLinks.parse(headers.get('link')); + this.totalItems = headers.get('X-Total-Count'); + for (let i = 0; i < data.length; i++) { + this.messages.push(data[i]); + } } - } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/message/message.module.ts b/src/main/webapp/app/entities/message/message.module.ts index f56156da..683f9435 100644 --- a/src/main/webapp/app/entities/message/message.module.ts +++ b/src/main/webapp/app/entities/message/message.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - MessageService, - MessagePopupService, - MessageComponent, - MessageDetailComponent, - MessageDialogComponent, - MessagePopupComponent, - MessageDeletePopupComponent, - MessageDeleteDialogComponent, - messageRoute, - messagePopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...messageRoute, - ...messagePopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + MessageService, + MessagePopupService, MessageComponent, MessageDetailComponent, MessageDialogComponent, - MessageDeleteDialogComponent, MessagePopupComponent, MessageDeletePopupComponent, - ], - entryComponents: [ - MessageComponent, - MessageDialogComponent, - MessagePopupComponent, MessageDeleteDialogComponent, - MessageDeletePopupComponent, - ], - providers: [ - MessageService, - MessagePopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + messageRoute, + messagePopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...messageRoute, + ...messagePopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + MessageComponent, + MessageDetailComponent, + MessageDialogComponent, + MessageDeleteDialogComponent, + MessagePopupComponent, + MessageDeletePopupComponent, + ], + entryComponents: [ + MessageComponent, + MessageDialogComponent, + MessagePopupComponent, + MessageDeleteDialogComponent, + MessageDeletePopupComponent, + ], + providers: [ + MessageService, + MessagePopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationMessageModule { } +export class GreatBigExampleApplicationMessageModule {} diff --git a/src/main/webapp/app/entities/message/message.route.ts b/src/main/webapp/app/entities/message/message.route.ts index 5c29bf57..13ac03fc 100644 --- a/src/main/webapp/app/entities/message/message.route.ts +++ b/src/main/webapp/app/entities/message/message.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { MessageComponent } from './message.component'; import { MessageDetailComponent } from './message-detail.component'; import { MessagePopupComponent } from './message-dialog.component'; import { MessageDeletePopupComponent } from './message-delete-dialog.component'; -import { Principal } from '../../shared'; - export const messageRoute: Routes = [ { path: 'message', diff --git a/src/main/webapp/app/entities/message/message.service.ts b/src/main/webapp/app/entities/message/message.service.ts index 33c36678..a6c98ca9 100644 --- a/src/main/webapp/app/entities/message/message.service.ts +++ b/src/main/webapp/app/entities/message/message.service.ts @@ -1,76 +1,85 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; + import { JhiDateUtils } from 'ng-jhipster'; import { Message } from './message.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class MessageService { - private resourceUrl = 'api/messages'; - private resourceSearchUrl = 'api/_search/messages'; + private resourceUrl = SERVER_API_URL + 'api/messages'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/messages'; - constructor(private http: Http, private dateUtils: JhiDateUtils) { } + constructor(private http: HttpClient, private dateUtils: JhiDateUtils) { } - create(message: Message): Observable { + create(message: Message): Observable { const copy = this.convert(message); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(message: Message): Observable { + update(message: Message): Observable { const copy = this.convert(message); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Message = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Message[] = res.body; + const body: Message[] = []; for (let i = 0; i < jsonResponse.length; i++) { - this.convertItemFromServer(jsonResponse[i]); + body.push(this.convertItemFromServer(jsonResponse[i])); } - return new ResponseWrapper(res.headers, jsonResponse, res.status); + return res.clone({body}); } - private convertItemFromServer(entity: any) { - entity.createdAt = this.dateUtils - .convertDateTimeFromServer(entity.createdAt); - entity.updatedAt = this.dateUtils - .convertDateTimeFromServer(entity.updatedAt); + /** + * Convert a returned JSON object to Message. + */ + private convertItemFromServer(message: Message): Message { + const copy: Message = Object.assign({}, message); + copy.createdAt = this.dateUtils + .convertDateTimeFromServer(message.createdAt); + copy.updatedAt = this.dateUtils + .convertDateTimeFromServer(message.updatedAt); + return copy; } + /** + * Convert a Message to a JSON which can be sent to the server. + */ private convert(message: Message): Message { const copy: Message = Object.assign({}, message); diff --git a/src/main/webapp/app/entities/note/note-delete-dialog.component.ts b/src/main/webapp/app/entities/note/note-delete-dialog.component.ts index 2225da00..4aba1c9c 100644 --- a/src/main/webapp/app/entities/note/note-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/note/note-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Note } from './note.model'; @@ -44,18 +44,17 @@ export class NoteDeleteDialogComponent { }) export class NoteDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private notePopupService: NotePopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.notePopupService - .open(NoteDeleteDialogComponent, params['id']); + this.notePopupService + .open(NoteDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/note/note-detail.component.html b/src/main/webapp/app/entities/note/note-detail.component.html index 1535efd8..dfd84ed6 100644 --- a/src/main/webapp/app/entities/note/note-detail.component.html +++ b/src/main/webapp/app/entities/note/note-detail.component.html @@ -31,6 +31,7 @@

Note   Edit diff --git a/src/main/webapp/app/entities/note/note-detail.component.spec.ts b/src/main/webapp/app/entities/note/note-detail.component.spec.ts deleted file mode 100644 index d50df2d3..00000000 --- a/src/main/webapp/app/entities/note/note-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { NoteDetailComponent } from './note-detail.component'; -import { NoteService } from './note.service'; -import { Note } from './note.model'; - -describe('Component Tests', () => { - - describe('Note Management Detail Component', () => { - let comp: NoteDetailComponent; - let fixture: ComponentFixture; - let service: NoteService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [NoteDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - NoteService, - JhiEventManager - ] - }).overrideTemplate(NoteDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(NoteDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(NoteService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Note(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.note).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/note/note-detail.component.ts b/src/main/webapp/app/entities/note/note-detail.component.ts index f0c84615..ae72c620 100644 --- a/src/main/webapp/app/entities/note/note-detail.component.ts +++ b/src/main/webapp/app/entities/note/note-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Note } from './note.model'; import { NoteService } from './note.service'; @@ -31,13 +32,13 @@ export class NoteDetailComponent implements OnInit, OnDestroy { } load(id) { - this.noteService.find(id).subscribe((note) => { - this.note = note; - }); + this.noteService.find(id) + .subscribe((noteResponse: HttpResponse) => { + this.note = noteResponse.body; + }); } previousState() { - window.history.back(); // FIXME: Inject Location: this.location.back(); - // Using the window is not good =( + window.history.back(); } ngOnDestroy() { diff --git a/src/main/webapp/app/entities/note/note-dialog.component.html b/src/main/webapp/app/entities/note/note-dialog.component.html index 81475596..d98c049c 100644 --- a/src/main/webapp/app/entities/note/note-dialog.component.html +++ b/src/main/webapp/app/entities/note/note-dialog.component.html @@ -15,27 +15,27 @@

+ [(ngModel)]="note.colour" />
+ [(ngModel)]="note.left" />
+ [(ngModel)]="note.top" />
@@ -50,21 +50,23 @@

[routerLink]="['../note', note.id ]" class="btn btn-info btn-sm"> - View + View

diff --git a/src/main/webapp/app/entities/note/note.component.ts b/src/main/webapp/app/entities/note/note.component.ts index 479da90a..b15e1039 100644 --- a/src/main/webapp/app/entities/note/note.component.ts +++ b/src/main/webapp/app/entities/note/note.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { Note } from './note.model'; import { NoteService } from './note.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-note', - templateUrl: './note.component.html' + selector: 'jhi-note', + templateUrl: './note.component.html' }) export class NoteComponent implements OnInit, OnDestroy { - notes: Note[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +notes: Note[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private noteService: NoteService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private noteService: NoteService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.noteService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.notes = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.noteService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.notes = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.noteService.query().subscribe( + (res: HttpResponse) => { + this.notes = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.noteService.query().subscribe( - (res: ResponseWrapper) => { - this.notes = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInNotes(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInNotes(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Note) { - return item.id; - } - registerChangeInNotes() { - this.eventSubscriber = this.eventManager.subscribe('noteListModification', (response) => this.loadAll()); - } + trackId(index: number, item: Note) { + return item.id; + } + registerChangeInNotes() { + this.eventSubscriber = this.eventManager.subscribe('noteListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/note/note.module.ts b/src/main/webapp/app/entities/note/note.module.ts index 397d7f65..274901c5 100644 --- a/src/main/webapp/app/entities/note/note.module.ts +++ b/src/main/webapp/app/entities/note/note.module.ts @@ -46,4 +46,4 @@ const ENTITY_STATES = [ ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationNoteModule { } +export class GreatBigExampleApplicationNoteModule {} diff --git a/src/main/webapp/app/entities/note/note.route.ts b/src/main/webapp/app/entities/note/note.route.ts index 84335699..db44cdf4 100644 --- a/src/main/webapp/app/entities/note/note.route.ts +++ b/src/main/webapp/app/entities/note/note.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { NoteComponent } from './note.component'; import { NoteDetailComponent } from './note-detail.component'; import { NotePopupComponent } from './note-dialog.component'; import { NoteDeletePopupComponent } from './note-delete-dialog.component'; -import { Principal } from '../../shared'; - export const noteRoute: Routes = [ { path: 'note', diff --git a/src/main/webapp/app/entities/note/note.service.ts b/src/main/webapp/app/entities/note/note.service.ts index 0a121d79..442b5438 100644 --- a/src/main/webapp/app/entities/note/note.service.ts +++ b/src/main/webapp/app/entities/note/note.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Note } from './note.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class NoteService { - private resourceUrl = 'api/notes'; - private resourceSearchUrl = 'api/_search/notes'; + private resourceUrl = SERVER_API_URL + 'api/notes'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/notes'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(note: Note): Observable { + create(note: Note): Observable { const copy = this.convert(note); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(note: Note): Observable { + update(note: Note): Observable { const copy = this.convert(note); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Note = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Note[] = res.body; + const body: Note[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({body}); + } + + /** + * Convert a returned JSON object to Note. + */ + private convertItemFromServer(note: Note): Note { + const copy: Note = Object.assign({}, note); + return copy; } + /** + * Convert a Note to a JSON which can be sent to the server. + */ private convert(note: Note): Note { const copy: Note = Object.assign({}, note); return copy; diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal-delete-dialog.component.ts b/src/main/webapp/app/entities/rebuttal/rebuttal-delete-dialog.component.ts index e4f1d987..868ac1cb 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/rebuttal/rebuttal-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Rebuttal } from './rebuttal.model'; @@ -44,18 +44,17 @@ export class RebuttalDeleteDialogComponent { }) export class RebuttalDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private rebuttalPopupService: RebuttalPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.rebuttalPopupService - .open(RebuttalDeleteDialogComponent, params['id']); + this.rebuttalPopupService + .open(RebuttalDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.html b/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.html index df3ec34b..ad3713d5 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.html +++ b/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.html @@ -35,6 +35,7 @@

Reb diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.spec.ts b/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.spec.ts deleted file mode 100644 index c93a00c1..00000000 --- a/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { RebuttalDetailComponent } from './rebuttal-detail.component'; -import { RebuttalService } from './rebuttal.service'; -import { Rebuttal } from './rebuttal.model'; - -describe('Component Tests', () => { - - describe('Rebuttal Management Detail Component', () => { - let comp: RebuttalDetailComponent; - let fixture: ComponentFixture; - let service: RebuttalService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [RebuttalDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - RebuttalService, - JhiEventManager - ] - }).overrideTemplate(RebuttalDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(RebuttalDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(RebuttalService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Rebuttal(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.rebuttal).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.ts b/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.ts index 6226f5cf..a4578319 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.ts +++ b/src/main/webapp/app/entities/rebuttal/rebuttal-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Rebuttal } from './rebuttal.model'; import { RebuttalService } from './rebuttal.service'; @@ -31,9 +32,10 @@ export class RebuttalDetailComponent implements OnInit, OnDestroy { } load(id) { - this.rebuttalService.find(id).subscribe((rebuttal) => { - this.rebuttal = rebuttal; - }); + this.rebuttalService.find(id) + .subscribe((rebuttalResponse: HttpResponse) => { + this.rebuttal = rebuttalResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal-dialog.component.html b/src/main/webapp/app/entities/rebuttal/rebuttal-dialog.component.html index 69da3e55..cf8e47a5 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal-dialog.component.html +++ b/src/main/webapp/app/entities/rebuttal/rebuttal-dialog.component.html @@ -15,7 +15,7 @@

@@ -52,21 +52,23 @@

[routerLink]="['../rebuttal', rebuttal.id ]" class="btn btn-info btn-sm"> - View + View

diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal.component.ts b/src/main/webapp/app/entities/rebuttal/rebuttal.component.ts index 9eaa08db..b031a6d3 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal.component.ts +++ b/src/main/webapp/app/entities/rebuttal/rebuttal.component.ts @@ -1,84 +1,85 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; import { Rebuttal } from './rebuttal.model'; import { RebuttalService } from './rebuttal.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { Principal } from '../../shared'; @Component({ - selector: 'jhi-rebuttal', - templateUrl: './rebuttal.component.html' + selector: 'jhi-rebuttal', + templateUrl: './rebuttal.component.html' }) export class RebuttalComponent implements OnInit, OnDestroy { - rebuttals: Rebuttal[]; - currentAccount: any; - eventSubscriber: Subscription; - currentSearch: string; +rebuttals: Rebuttal[]; + currentAccount: any; + eventSubscriber: Subscription; + currentSearch: string; - constructor( - private rebuttalService: RebuttalService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private rebuttalService: RebuttalService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.rebuttalService.search({ - query: this.currentSearch, - }).subscribe( - (res: ResponseWrapper) => this.rebuttals = res.json, - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.rebuttalService.search({ + query: this.currentSearch, + }).subscribe( + (res: HttpResponse) => this.rebuttals = res.body, + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.rebuttalService.query().subscribe( + (res: HttpResponse) => { + this.rebuttals = res.body; + this.currentSearch = ''; + }, + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.rebuttalService.query().subscribe( - (res: ResponseWrapper) => { - this.rebuttals = res.json; - this.currentSearch = ''; - }, - (res: ResponseWrapper) => this.onError(res.json) - ); - } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.currentSearch = query; + this.loadAll(); } - this.currentSearch = query; - this.loadAll(); - } - clear() { - this.currentSearch = ''; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInRebuttals(); - } + clear() { + this.currentSearch = ''; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInRebuttals(); + } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Rebuttal) { - return item.id; - } - registerChangeInRebuttals() { - this.eventSubscriber = this.eventManager.subscribe('rebuttalListModification', (response) => this.loadAll()); - } + trackId(index: number, item: Rebuttal) { + return item.id; + } + registerChangeInRebuttals() { + this.eventSubscriber = this.eventManager.subscribe('rebuttalListModification', (response) => this.loadAll()); + } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal.module.ts b/src/main/webapp/app/entities/rebuttal/rebuttal.module.ts index 8e8c16c7..7d3ec691 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal.module.ts +++ b/src/main/webapp/app/entities/rebuttal/rebuttal.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - RebuttalService, - RebuttalPopupService, - RebuttalComponent, - RebuttalDetailComponent, - RebuttalDialogComponent, - RebuttalPopupComponent, - RebuttalDeletePopupComponent, - RebuttalDeleteDialogComponent, - rebuttalRoute, - rebuttalPopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...rebuttalRoute, - ...rebuttalPopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + RebuttalService, + RebuttalPopupService, RebuttalComponent, RebuttalDetailComponent, RebuttalDialogComponent, - RebuttalDeleteDialogComponent, RebuttalPopupComponent, RebuttalDeletePopupComponent, - ], - entryComponents: [ - RebuttalComponent, - RebuttalDialogComponent, - RebuttalPopupComponent, RebuttalDeleteDialogComponent, - RebuttalDeletePopupComponent, - ], - providers: [ - RebuttalService, - RebuttalPopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + rebuttalRoute, + rebuttalPopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...rebuttalRoute, + ...rebuttalPopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + RebuttalComponent, + RebuttalDetailComponent, + RebuttalDialogComponent, + RebuttalDeleteDialogComponent, + RebuttalPopupComponent, + RebuttalDeletePopupComponent, + ], + entryComponents: [ + RebuttalComponent, + RebuttalDialogComponent, + RebuttalPopupComponent, + RebuttalDeleteDialogComponent, + RebuttalDeletePopupComponent, + ], + providers: [ + RebuttalService, + RebuttalPopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationRebuttalModule { } +export class GreatBigExampleApplicationRebuttalModule {} diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal.route.ts b/src/main/webapp/app/entities/rebuttal/rebuttal.route.ts index 82f26df8..32f612e2 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal.route.ts +++ b/src/main/webapp/app/entities/rebuttal/rebuttal.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { RebuttalComponent } from './rebuttal.component'; import { RebuttalDetailComponent } from './rebuttal-detail.component'; import { RebuttalPopupComponent } from './rebuttal-dialog.component'; import { RebuttalDeletePopupComponent } from './rebuttal-delete-dialog.component'; -import { Principal } from '../../shared'; - export const rebuttalRoute: Routes = [ { path: 'rebuttal', diff --git a/src/main/webapp/app/entities/rebuttal/rebuttal.service.ts b/src/main/webapp/app/entities/rebuttal/rebuttal.service.ts index c83b64c5..0a8fe7ea 100644 --- a/src/main/webapp/app/entities/rebuttal/rebuttal.service.ts +++ b/src/main/webapp/app/entities/rebuttal/rebuttal.service.ts @@ -1,76 +1,85 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; + import { JhiDateUtils } from 'ng-jhipster'; import { Rebuttal } from './rebuttal.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class RebuttalService { - private resourceUrl = 'api/rebuttals'; - private resourceSearchUrl = 'api/_search/rebuttals'; + private resourceUrl = SERVER_API_URL + 'api/rebuttals'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/rebuttals'; - constructor(private http: Http, private dateUtils: JhiDateUtils) { } + constructor(private http: HttpClient, private dateUtils: JhiDateUtils) { } - create(rebuttal: Rebuttal): Observable { + create(rebuttal: Rebuttal): Observable { const copy = this.convert(rebuttal); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(rebuttal: Rebuttal): Observable { + update(rebuttal: Rebuttal): Observable { const copy = this.convert(rebuttal); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - const jsonResponse = res.json(); - this.convertItemFromServer(jsonResponse); - return jsonResponse; - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response'}) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response'}); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Rebuttal = this.convertItemFromServer(res.body); + return res.clone({body}); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Rebuttal[] = res.body; + const body: Rebuttal[] = []; for (let i = 0; i < jsonResponse.length; i++) { - this.convertItemFromServer(jsonResponse[i]); + body.push(this.convertItemFromServer(jsonResponse[i])); } - return new ResponseWrapper(res.headers, jsonResponse, res.status); + return res.clone({body}); } - private convertItemFromServer(entity: any) { - entity.date = this.dateUtils - .convertDateTimeFromServer(entity.date); - entity.expires = this.dateUtils - .convertDateTimeFromServer(entity.expires); + /** + * Convert a returned JSON object to Rebuttal. + */ + private convertItemFromServer(rebuttal: Rebuttal): Rebuttal { + const copy: Rebuttal = Object.assign({}, rebuttal); + copy.date = this.dateUtils + .convertDateTimeFromServer(rebuttal.date); + copy.expires = this.dateUtils + .convertDateTimeFromServer(rebuttal.expires); + return copy; } + /** + * Convert a Rebuttal to a JSON which can be sent to the server. + */ private convert(rebuttal: Rebuttal): Rebuttal { const copy: Rebuttal = Object.assign({}, rebuttal); diff --git a/src/main/webapp/app/entities/tag/tag-delete-dialog.component.ts b/src/main/webapp/app/entities/tag/tag-delete-dialog.component.ts index e72ec957..e0b23e9f 100644 --- a/src/main/webapp/app/entities/tag/tag-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/tag/tag-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Tag } from './tag.model'; @@ -44,18 +44,17 @@ export class TagDeleteDialogComponent { }) export class TagDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private tagPopupService: TagPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.tagPopupService - .open(TagDeleteDialogComponent, params['id']); + this.tagPopupService + .open(TagDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/tag/tag-detail.component.html b/src/main/webapp/app/entities/tag/tag-detail.component.html index fd1e90e9..de0af765 100644 --- a/src/main/webapp/app/entities/tag/tag-detail.component.html +++ b/src/main/webapp/app/entities/tag/tag-detail.component.html @@ -19,6 +19,7 @@

Tag   Edit diff --git a/src/main/webapp/app/entities/tag/tag-detail.component.spec.ts b/src/main/webapp/app/entities/tag/tag-detail.component.spec.ts deleted file mode 100644 index 3fdf3c7f..00000000 --- a/src/main/webapp/app/entities/tag/tag-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { TagDetailComponent } from './tag-detail.component'; -import { TagService } from './tag.service'; -import { Tag } from './tag.model'; - -describe('Component Tests', () => { - - describe('Tag Management Detail Component', () => { - let comp: TagDetailComponent; - let fixture: ComponentFixture; - let service: TagService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [TagDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - TagService, - JhiEventManager - ] - }).overrideTemplate(TagDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(TagDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(TagService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Tag(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.tag).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/tag/tag-detail.component.ts b/src/main/webapp/app/entities/tag/tag-detail.component.ts index a677cf67..d761eedd 100644 --- a/src/main/webapp/app/entities/tag/tag-detail.component.ts +++ b/src/main/webapp/app/entities/tag/tag-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager } from 'ng-jhipster'; +import { JhiEventManager } from 'ng-jhipster'; import { Tag } from './tag.model'; import { TagService } from './tag.service'; @@ -31,9 +32,10 @@ export class TagDetailComponent implements OnInit, OnDestroy { } load(id) { - this.tagService.find(id).subscribe((tag) => { - this.tag = tag; - }); + this.tagService.find(id) + .subscribe((tagResponse: HttpResponse) => { + this.tag = tagResponse.body; + }); } previousState() { window.history.back(); diff --git a/src/main/webapp/app/entities/tag/tag-dialog.component.html b/src/main/webapp/app/entities/tag/tag-dialog.component.html index cfdfc7d0..1eb99168 100644 --- a/src/main/webapp/app/entities/tag/tag-dialog.component.html +++ b/src/main/webapp/app/entities/tag/tag-dialog.component.html @@ -15,7 +15,7 @@

diff --git a/src/main/webapp/app/entities/tag/tag.component.ts b/src/main/webapp/app/entities/tag/tag.component.ts index 42e89f80..948eee16 100644 --- a/src/main/webapp/app/entities/tag/tag.component.ts +++ b/src/main/webapp/app/entities/tag/tag.component.ts @@ -1,146 +1,147 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager, JhiParseLinks, JhiPaginationUtil, JhiLanguageService, JhiAlertService } from 'ng-jhipster'; +import { JhiEventManager, JhiParseLinks, JhiAlertService } from 'ng-jhipster'; import { Tag } from './tag.model'; import { TagService } from './tag.service'; -import { ITEMS_PER_PAGE, Principal, ResponseWrapper } from '../../shared'; -import { PaginationConfig } from '../../core/config/uib-pagination.config'; +import { ITEMS_PER_PAGE, Principal } from '../../shared'; @Component({ - selector: 'jhi-tag', - templateUrl: './tag.component.html' + selector: 'jhi-tag', + templateUrl: './tag.component.html' }) export class TagComponent implements OnInit, OnDestroy { - tags: Tag[]; - currentAccount: any; - eventSubscriber: Subscription; - itemsPerPage: number; - links: any; - page: any; - predicate: any; - queryCount: any; - reverse: any; - totalItems: number; - currentSearch: string; + tags: Tag[]; + currentAccount: any; + eventSubscriber: Subscription; + itemsPerPage: number; + links: any; + page: any; + predicate: any; + queryCount: any; + reverse: any; + totalItems: number; + currentSearch: string; - constructor( - private tagService: TagService, - private alertService: JhiAlertService, - private eventManager: JhiEventManager, - private parseLinks: JhiParseLinks, - private activatedRoute: ActivatedRoute, - private principal: Principal - ) { - this.tags = []; - this.itemsPerPage = ITEMS_PER_PAGE; - this.page = 0; - this.links = { - last: 0 - }; - this.predicate = 'id'; - this.reverse = true; - this.currentSearch = activatedRoute.snapshot.params['search'] ? activatedRoute.snapshot.params['search'] : ''; - } + constructor( + private tagService: TagService, + private jhiAlertService: JhiAlertService, + private eventManager: JhiEventManager, + private parseLinks: JhiParseLinks, + private activatedRoute: ActivatedRoute, + private principal: Principal + ) { + this.tags = []; + this.itemsPerPage = ITEMS_PER_PAGE; + this.page = 0; + this.links = { + last: 0 + }; + this.predicate = 'id'; + this.reverse = true; + this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ? + this.activatedRoute.snapshot.params['search'] : ''; + } - loadAll() { - if (this.currentSearch) { - this.tagService.search({ - query: this.currentSearch, - page: this.page, - size: this.itemsPerPage, - sort: this.sort() - }).subscribe( - (res: ResponseWrapper) => this.onSuccess(res.json, res.headers), - (res: ResponseWrapper) => this.onError(res.json) + loadAll() { + if (this.currentSearch) { + this.tagService.search({ + query: this.currentSearch, + page: this.page, + size: this.itemsPerPage, + sort: this.sort() + }).subscribe( + (res: HttpResponse) => this.onSuccess(res.body, res.headers), + (res: HttpErrorResponse) => this.onError(res.message) + ); + return; + } + this.tagService.query({ + page: this.page, + size: this.itemsPerPage, + sort: this.sort() + }).subscribe( + (res: HttpResponse) => this.onSuccess(res.body, res.headers), + (res: HttpErrorResponse) => this.onError(res.message) ); - return; } - this.tagService.query({ - page: this.page, - size: this.itemsPerPage, - sort: this.sort() - }).subscribe( - (res: ResponseWrapper) => this.onSuccess(res.json, res.headers), - (res: ResponseWrapper) => this.onError(res.json) - ); - } - reset() { - this.page = 0; - this.tags = []; - this.loadAll(); - } + reset() { + this.page = 0; + this.tags = []; + this.loadAll(); + } - loadPage(page) { - this.page = page; - this.loadAll(); - } + loadPage(page) { + this.page = page; + this.loadAll(); + } - clear() { - this.tags = []; - this.links = { - last: 0 - }; - this.page = 0; - this.predicate = 'id'; - this.reverse = true; - this.currentSearch = ''; - this.loadAll(); - } + clear() { + this.tags = []; + this.links = { + last: 0 + }; + this.page = 0; + this.predicate = 'id'; + this.reverse = true; + this.currentSearch = ''; + this.loadAll(); + } - search(query) { - if (!query) { - return this.clear(); + search(query) { + if (!query) { + return this.clear(); + } + this.tags = []; + this.links = { + last: 0 + }; + this.page = 0; + this.predicate = '_score'; + this.reverse = false; + this.currentSearch = query; + this.loadAll(); + } + ngOnInit() { + this.loadAll(); + this.principal.identity().then((account) => { + this.currentAccount = account; + }); + this.registerChangeInTags(); } - this.tags = []; - this.links = { - last: 0 - }; - this.page = 0; - this.predicate = '_score'; - this.reverse = false; - this.currentSearch = query; - this.loadAll(); - } - ngOnInit() { - this.loadAll(); - this.principal.identity().then((account) => { - this.currentAccount = account; - }); - this.registerChangeInTags(); - } - ngOnDestroy() { - this.eventManager.destroy(this.eventSubscriber); - } + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } - trackId(index: number, item: Tag) { - return item.id; - } - registerChangeInTags() { - this.eventSubscriber = this.eventManager.subscribe('tagListModification', (response) => this.reset()); - } + trackId(index: number, item: Tag) { + return item.id; + } + registerChangeInTags() { + this.eventSubscriber = this.eventManager.subscribe('tagListModification', (response) => this.reset()); + } - sort() { - const result = [this.predicate + ',' + (this.reverse ? 'asc' : 'desc')]; - if (this.predicate !== 'id') { - result.push('id'); + sort() { + const result = [this.predicate + ',' + (this.reverse ? 'asc' : 'desc')]; + if (this.predicate !== 'id') { + result.push('id'); + } + return result; } - return result; - } - private onSuccess(data, headers) { - this.links = this.parseLinks.parse(headers.get('link')); - this.totalItems = headers.get('X-Total-Count'); - for (let i = 0; i < data.length; i++) { - this.tags.push(data[i]); + private onSuccess(data, headers) { + this.links = this.parseLinks.parse(headers.get('link')); + this.totalItems = headers.get('X-Total-Count'); + for (let i = 0; i < data.length; i++) { + this.tags.push(data[i]); + } } - } - private onError(error) { - this.alertService.error(error.message, null, null); - } + private onError(error) { + this.jhiAlertService.error(error.message, null, null); + } } diff --git a/src/main/webapp/app/entities/tag/tag.module.ts b/src/main/webapp/app/entities/tag/tag.module.ts index 6c88989a..904678a7 100644 --- a/src/main/webapp/app/entities/tag/tag.module.ts +++ b/src/main/webapp/app/entities/tag/tag.module.ts @@ -3,47 +3,47 @@ import { RouterModule } from '@angular/router'; import { GreatBigExampleApplicationSharedModule } from '../../shared'; import { - TagService, - TagPopupService, - TagComponent, - TagDetailComponent, - TagDialogComponent, - TagPopupComponent, - TagDeletePopupComponent, - TagDeleteDialogComponent, - tagRoute, - tagPopupRoute, -} from './'; - -const ENTITY_STATES = [ - ...tagRoute, - ...tagPopupRoute, -]; - -@NgModule({ - imports: [ - GreatBigExampleApplicationSharedModule, - RouterModule.forChild(ENTITY_STATES) - ], - declarations: [ + TagService, + TagPopupService, TagComponent, TagDetailComponent, TagDialogComponent, - TagDeleteDialogComponent, TagPopupComponent, TagDeletePopupComponent, - ], - entryComponents: [ - TagComponent, - TagDialogComponent, - TagPopupComponent, TagDeleteDialogComponent, - TagDeletePopupComponent, - ], - providers: [ - TagService, - TagPopupService, - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + tagRoute, + tagPopupRoute, +} from './'; + +const ENTITY_STATES = [ + ...tagRoute, + ...tagPopupRoute, +]; + +@NgModule({ + imports: [ + GreatBigExampleApplicationSharedModule, + RouterModule.forChild(ENTITY_STATES) + ], + declarations: [ + TagComponent, + TagDetailComponent, + TagDialogComponent, + TagDeleteDialogComponent, + TagPopupComponent, + TagDeletePopupComponent, + ], + entryComponents: [ + TagComponent, + TagDialogComponent, + TagPopupComponent, + TagDeleteDialogComponent, + TagDeletePopupComponent, + ], + providers: [ + TagService, + TagPopupService, + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) -export class GreatBigExampleApplicationTagModule { } +export class GreatBigExampleApplicationTagModule {} diff --git a/src/main/webapp/app/entities/tag/tag.route.ts b/src/main/webapp/app/entities/tag/tag.route.ts index 0b030290..bfd46238 100644 --- a/src/main/webapp/app/entities/tag/tag.route.ts +++ b/src/main/webapp/app/entities/tag/tag.route.ts @@ -1,16 +1,11 @@ -import { Injectable } from '@angular/core'; -import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router'; +import { Routes } from '@angular/router'; import { UserRouteAccessService } from '../../shared'; -import { JhiPaginationUtil } from 'ng-jhipster'; - import { TagComponent } from './tag.component'; import { TagDetailComponent } from './tag-detail.component'; import { TagPopupComponent } from './tag-dialog.component'; import { TagDeletePopupComponent } from './tag-delete-dialog.component'; -import { Principal } from '../../shared'; - export const tagRoute: Routes = [ { path: 'tag', diff --git a/src/main/webapp/app/entities/tag/tag.service.ts b/src/main/webapp/app/entities/tag/tag.service.ts index 82b2a3d7..45c5e7ed 100644 --- a/src/main/webapp/app/entities/tag/tag.service.ts +++ b/src/main/webapp/app/entities/tag/tag.service.ts @@ -1,59 +1,79 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { SERVER_API_URL } from '../../app.constants'; import { Tag } from './tag.model'; -import { ResponseWrapper, createRequestOption } from '../../shared'; +import { createRequestOption } from '../../shared'; + +export type EntityResponseType = HttpResponse; @Injectable() export class TagService { - private resourceUrl = 'api/tags'; - private resourceSearchUrl = 'api/_search/tags'; + private resourceUrl = SERVER_API_URL + 'api/tags'; + private resourceSearchUrl = SERVER_API_URL + 'api/_search/tags'; - constructor(private http: Http) { } + constructor(private http: HttpClient) { } - create(tag: Tag): Observable { + create(tag: Tag): Observable { const copy = this.convert(tag); - return this.http.post(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.post(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - update(tag: Tag): Observable { + update(tag: Tag): Observable { const copy = this.convert(tag); - return this.http.put(this.resourceUrl, copy).map((res: Response) => { - return res.json(); - }); + return this.http.put(this.resourceUrl, copy, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - find(id: number): Observable { - return this.http.get(`${this.resourceUrl}/${id}`).map((res: Response) => { - return res.json(); - }); + find(id: number): Observable { + return this.http.get(`${this.resourceUrl}/${id}`, { observe: 'response' }) + .map((res: EntityResponseType) => this.convertResponse(res)); } - query(req?: any): Observable { + query(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceUrl, options) - .map((res: Response) => this.convertResponse(res)); + return this.http.get(this.resourceUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); } - delete(id: number): Observable { - return this.http.delete(`${this.resourceUrl}/${id}`); + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response' }); } - search(req?: any): Observable { + search(req?: any): Observable> { const options = createRequestOption(req); - return this.http.get(this.resourceSearchUrl, options) - .map((res: any) => this.convertResponse(res)); + return this.http.get(this.resourceSearchUrl, { params: options, observe: 'response' }) + .map((res: HttpResponse) => this.convertArrayResponse(res)); + } + + private convertResponse(res: EntityResponseType): EntityResponseType { + const body: Tag = this.convertItemFromServer(res.body); + return res.clone({ body }); } - private convertResponse(res: Response): ResponseWrapper { - const jsonResponse = res.json(); - return new ResponseWrapper(res.headers, jsonResponse, res.status); + private convertArrayResponse(res: HttpResponse): HttpResponse { + const jsonResponse: Tag[] = res.body; + const body: Tag[] = []; + for (let i = 0; i < jsonResponse.length; i++) { + body.push(this.convertItemFromServer(jsonResponse[i])); + } + return res.clone({ body }); + } + + /** + * Convert a returned JSON object to Tag. + */ + private convertItemFromServer(tag: Tag): Tag { + const copy: Tag = Object.assign({}, tag); + return copy; } + /** + * Convert a Tag to a JSON which can be sent to the server. + */ private convert(tag: Tag): Tag { const copy: Tag = Object.assign({}, tag); return copy; diff --git a/src/main/webapp/app/entities/talk/talk-delete-dialog.component.ts b/src/main/webapp/app/entities/talk/talk-delete-dialog.component.ts index 61090398..014ceba5 100644 --- a/src/main/webapp/app/entities/talk/talk-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/talk/talk-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { JhiEventManager } from 'ng-jhipster'; import { Talk } from './talk.model'; @@ -44,18 +44,17 @@ export class TalkDeleteDialogComponent { }) export class TalkDeletePopupComponent implements OnInit, OnDestroy { - modalRef: NgbModalRef; routeSub: any; constructor( private route: ActivatedRoute, private talkPopupService: TalkPopupService - ) { } + ) {} ngOnInit() { this.routeSub = this.route.params.subscribe((params) => { - this.modalRef = this.talkPopupService - .open(TalkDeleteDialogComponent, params['id']); + this.talkPopupService + .open(TalkDeleteDialogComponent as Component, params['id']); }); } diff --git a/src/main/webapp/app/entities/talk/talk-detail.component.html b/src/main/webapp/app/entities/talk/talk-detail.component.html index 7b00d4ca..6946029c 100644 --- a/src/main/webapp/app/entities/talk/talk-detail.component.html +++ b/src/main/webapp/app/entities/talk/talk-detail.component.html @@ -35,6 +35,7 @@

Talk   Edit diff --git a/src/main/webapp/app/entities/talk/talk-detail.component.spec.ts b/src/main/webapp/app/entities/talk/talk-detail.component.spec.ts deleted file mode 100644 index 1803c3c2..00000000 --- a/src/main/webapp/app/entities/talk/talk-detail.component.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* tslint:disable max-line-length */ -import { ComponentFixture, TestBed, async, inject } from '@angular/core/testing'; -import { OnInit } from '@angular/core'; -import { DatePipe } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { JhiDateUtils, JhiDataUtils, JhiEventManager } from 'ng-jhipster'; -import { GreatBigExampleApplicationTestModule } from '../../../mocks/test.module'; -import { MockActivatedRoute } from '../../../mocks/mock-route.service'; -import { TalkDetailComponent } from './talk-detail.component'; -import { TalkService } from './talk.service'; -import { Talk } from './talk.model'; - -describe('Component Tests', () => { - - describe('Talk Management Detail Component', () => { - let comp: TalkDetailComponent; - let fixture: ComponentFixture; - let service: TalkService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [GreatBigExampleApplicationTestModule], - declarations: [TalkDetailComponent], - providers: [ - JhiDateUtils, - JhiDataUtils, - DatePipe, - { - provide: ActivatedRoute, - useValue: new MockActivatedRoute({ id: 123 }) - }, - TalkService, - JhiEventManager - ] - }).overrideTemplate(TalkDetailComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(TalkDetailComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(TalkService); - }); - - describe('OnInit', () => { - it('Should call load all on init', () => { - // GIVEN - - spyOn(service, 'find').and.returnValue(Observable.of(new Talk(10))); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.find).toHaveBeenCalledWith(123); - expect(comp.talk).toEqual(jasmine.objectContaining({ id: 10 })); - }); - }); - }); - -}); diff --git a/src/main/webapp/app/entities/talk/talk-detail.component.ts b/src/main/webapp/app/entities/talk/talk-detail.component.ts index 2aa7a26a..4436288a 100644 --- a/src/main/webapp/app/entities/talk/talk-detail.component.ts +++ b/src/main/webapp/app/entities/talk/talk-detail.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { HttpResponse } from '@angular/common/http'; import { Subscription } from 'rxjs/Subscription'; -import { JhiEventManager , JhiDataUtils } from 'ng-jhipster'; +import { JhiEventManager, JhiDataUtils } from 'ng-jhipster'; import { Talk } from './talk.model'; import { TalkService } from './talk.service'; @@ -32,9 +33,10 @@ export class TalkDetailComponent implements OnInit, OnDestroy { } load(id) { - this.talkService.find(id).subscribe((talk) => { - this.talk = talk; - }); + this.talkService.find(id) + .subscribe((talkResponse: HttpResponse) => { + this.talk = talkResponse.body; + }); } byteSize(field) { return this.dataUtils.byteSize(field); diff --git a/src/main/webapp/app/entities/talk/talk-dialog.component.html b/src/main/webapp/app/entities/talk/talk-dialog.component.html index 45889b0b..7ad30b68 100644 --- a/src/main/webapp/app/entities/talk/talk-dialog.component.html +++ b/src/main/webapp/app/entities/talk/talk-dialog.component.html @@ -15,7 +15,7 @@