├── .editorconfig ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .swagger-codegen-ignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app.json ├── build.gradle ├── pom.xml ├── screenshots ├── ER_Model.png ├── api_doc.png ├── api_doc2.png ├── customers.png ├── db_schema.png ├── login.png ├── logo.svg ├── order_details.png ├── order_stats.png ├── orders.png ├── product_stats.png └── sprout.svg ├── src └── main │ ├── java │ └── com │ │ └── app │ │ ├── MainApp.java │ │ ├── api │ │ ├── GlobalExceptionHandler.java │ │ ├── MainController.java │ │ ├── SessionController.java │ │ ├── Version.java │ │ ├── customer │ │ │ └── CustomerController.java │ │ ├── employee │ │ │ └── EmployeeController.java │ │ ├── order │ │ │ ├── OrderController.java │ │ │ └── OrderStatsController.java │ │ ├── product │ │ │ ├── ProductController.java │ │ │ └── ProductStatsController.java │ │ └── user │ │ │ ├── UserController.java │ │ │ └── UserService.java │ │ ├── config │ │ ├── CorsFilter.java │ │ ├── GenerateTokenForUserFilter.java │ │ ├── SecurityConfig.java │ │ ├── SwaggerConfig.java │ │ └── VerifyTokenFilter.java │ │ ├── identity │ │ ├── TokenUser.java │ │ ├── TokenUtil.java │ │ ├── UserAuthentication.java │ │ └── UserDetailsService.java │ │ ├── model │ │ ├── VersionModel.java │ │ ├── customer │ │ │ ├── Customer.java │ │ │ └── CustomerResponse.java │ │ ├── data │ │ │ └── SingleSerise.java │ │ ├── employee │ │ │ ├── Employee.java │ │ │ └── EmployeeResponse.java │ │ ├── order │ │ │ ├── CompositeOrderProductKey.java │ │ │ ├── Order.java │ │ │ ├── OrderDetail.java │ │ │ ├── OrderDetailResponse.java │ │ │ ├── OrderInfo.java │ │ │ ├── OrderInfoResponse.java │ │ │ ├── OrderItem.java │ │ │ └── OrderResponse.java │ │ ├── product │ │ │ ├── Product.java │ │ │ └── ProductResponse.java │ │ ├── response │ │ │ ├── OperationResponse.java │ │ │ ├── PageResponse.java │ │ │ └── SingleDataSeriseResponse.java │ │ ├── session │ │ │ ├── SessionItem.java │ │ │ └── SessionResponse.java │ │ └── user │ │ │ ├── Login.java │ │ │ ├── Role.java │ │ │ ├── User.java │ │ │ └── UserResponse.java │ │ └── repo │ │ ├── CustomerRepo.java │ │ ├── EmployeeRepo.java │ │ ├── OrderInfoRepo.java │ │ ├── OrderItemRepo.java │ │ ├── OrderRepo.java │ │ ├── ProductRepo.java │ │ └── UserRepo.java │ └── resources │ ├── application.properties │ ├── data.sql │ ├── public │ ├── 3rdpartylicenses.txt │ ├── assets │ │ ├── css │ │ │ ├── font-awesome.css │ │ │ ├── font-awesome.css.map │ │ │ ├── font-awesome.min.css │ │ │ └── sonicglyph.css │ │ ├── fonts │ │ │ ├── OpenSans-Italic.woff │ │ │ ├── OpenSans-Regular.woff │ │ │ ├── OpenSans-Semibold.woff │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── images │ │ │ └── logo.svg │ │ └── scss │ │ │ ├── _base.scss │ │ │ ├── _base.scss~7e877128953f01225c7f977ebe54c7ae2aef2cab │ │ │ ├── _base.scss~HEAD │ │ │ └── _var.scss │ ├── data-table.b0aebd744ce7adb780a9.svg │ ├── data-table.bce071e976865da51100.eot │ ├── favicon.ico │ ├── index.html │ ├── inline.1163a12954ba6efe8643.bundle.js │ ├── inline.202b9fb55dba165518b2.bundle.js │ ├── inline.2e9c4af0eb06e53c2b0f.bundle.js │ ├── inline.4a54791b65b724ea83d8.bundle.js │ ├── inline.5421b4d677ed3a6e159d.bundle.js │ ├── inline.769c42d7685f1bf09bdd.bundle.js │ ├── inline.9a21fd36d580b81640e7.bundle.js │ ├── inline.a96fe04c5878c6cd9188.bundle.js │ ├── inline.bundle.js │ ├── inline.bundle.js.map │ ├── inline.c956289fcb65e29a059a.bundle.js │ ├── inline.ea0d0509378aa3a4611b.bundle.js │ ├── main.098a7cbb8140adabfb04.bundle.js │ ├── main.09faa257ce8d57bbcaa3.bundle.js │ ├── main.1cbbdd22055428425b75.bundle.js │ ├── main.3bfd67e90d0114eecea6.bundle.js │ ├── main.6134e01f1d7c42a023fb.bundle.js │ ├── main.808cd10916d5da16db68.bundle.js │ ├── main.a208c7d01e8e9f746ad9.bundle.js │ ├── main.bundle.js │ ├── main.bundle.js.map │ ├── main.c520c6aca7c72a06796a.bundle.js │ ├── main.d6eac9f63fe2289c6a1d.bundle.js │ ├── main.d77ede97c1ffe49a5e73.bundle.js │ ├── polyfills.03d8fe7fc8ba544d90c1.bundle.js │ ├── polyfills.4099be82af5f3ca64968.bundle.js │ ├── polyfills.8d155b24e2b8d7fdd062.bundle.js │ ├── polyfills.bundle.js │ ├── polyfills.bundle.js.map │ ├── polyfills.c8463d254b8964e11c09.bundle.js │ ├── polyfills.f6df94400e33b6fc1b2a.bundle.js │ ├── redoc │ │ ├── index.html │ │ └── redoc.min.js │ ├── scripts.05c6a124eeea0f122a7b.bundle.js │ ├── scripts.7c0572b9888db625d230.bundle.js │ ├── scripts.888529150911c36b4900.bundle.js │ ├── scripts.bundle.js │ ├── scripts.c50979c932367250c94b.bundle.js │ ├── styles.11e43cd179a9132db388.bundle.css │ ├── styles.3815f4695c9a91daa948.bundle.css │ ├── styles.9823ab1b736db3e9cff2.bundle.css │ ├── styles.b0161f74151cd2bb6d70.bundle.css │ ├── styles.b20455bb8c59102545b0.bundle.css │ ├── styles.bundle.js │ ├── styles.bundle.js.map │ ├── styles.ca7df7a1a2f07a69738f.bundle.css │ ├── swagger │ │ ├── css │ │ │ ├── print.css │ │ │ ├── reset.css │ │ │ ├── screen.css │ │ │ ├── style.css │ │ │ └── typography.css │ │ ├── fonts │ │ │ ├── DroidSans-Bold.ttf │ │ │ ├── DroidSans.ttf │ │ │ ├── Metropolis-Regular.otf │ │ │ └── Metropolis-Thin.otf │ │ ├── images │ │ │ ├── collapse.gif │ │ │ ├── expand.gif │ │ │ ├── explorer_icons.png │ │ │ ├── throbber.gif │ │ │ └── wordnik_api.png │ │ ├── index.htm │ │ ├── index.html │ │ ├── lang │ │ │ ├── ca.js │ │ │ ├── el.js │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── fr.js │ │ │ ├── geo.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── ko-kr.js │ │ │ ├── pl.js │ │ │ ├── pt.js │ │ │ ├── ru.js │ │ │ ├── tr.js │ │ │ ├── translator.js │ │ │ └── zh-cn.js │ │ ├── lib │ │ │ ├── backbone-min.js │ │ │ ├── es5-shim.js │ │ │ ├── handlebars-4.0.5.js │ │ │ ├── highlight.9.1.0.pack.js │ │ │ ├── highlight.9.1.0.pack_extended.js │ │ │ ├── jquery-1.8.0.min.js │ │ │ ├── jquery.ba-bbq.min.js │ │ │ ├── jquery.slideto.min.js │ │ │ ├── jquery.wiggle.min.js │ │ │ ├── js-yaml.min.js │ │ │ ├── jsoneditor.min.js │ │ │ ├── lodash.min.js │ │ │ ├── marked.js │ │ │ ├── object-assign-pollyfill.js │ │ │ ├── sanitize-html.min.js │ │ │ └── swagger-oauth.js │ │ ├── o2c.html │ │ ├── swagger-ui.js │ │ └── swagger-ui.min.js │ ├── vendor.133d2f30a7fd3d1f21b9.bundle.js │ ├── vendor.bundle.js │ ├── vendor.bundle.js.map │ └── vendor.e9e2c769d0efd00d3b8a.bundle.js │ └── schema.sql └── webui ├── .angular-cli.json ├── dist ├── 3rdpartylicenses.txt ├── assets │ ├── css │ │ ├── font-awesome.css │ │ ├── font-awesome.css.map │ │ ├── font-awesome.min.css │ │ └── sonicglyph.css │ ├── fonts │ │ ├── OpenSans-Italic.woff │ │ ├── OpenSans-Regular.woff │ │ ├── OpenSans-Semibold.woff │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── images │ │ └── logo.svg │ └── scss │ │ ├── _base.scss │ │ ├── _base.scss~7e877128953f01225c7f977ebe54c7ae2aef2cab │ │ ├── _base.scss~HEAD │ │ └── _var.scss ├── data-table.b0aebd744ce7adb780a9.svg ├── data-table.bce071e976865da51100.eot ├── favicon.ico ├── index.html ├── inline.ea0d0509378aa3a4611b.bundle.js ├── main.c520c6aca7c72a06796a.bundle.js ├── polyfills.4099be82af5f3ca64968.bundle.js ├── scripts.05c6a124eeea0f122a7b.bundle.js └── styles.9823ab1b736db3e9cff2.bundle.css ├── package.json ├── src ├── app │ ├── app-config.ts │ ├── app-routing.module.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── components │ │ ├── badge │ │ │ └── badge.component.ts │ │ ├── legend │ │ │ ├── legend.component.ts │ │ │ └── legend.scss │ │ └── logo │ │ │ ├── logo.component.html │ │ │ └── logo.component.ts │ ├── directives │ │ └── track_scroll │ │ │ └── track_scroll.directive.ts │ ├── home.component.html │ ├── home.component.ts │ ├── home.scss │ ├── pages │ │ ├── 404 │ │ │ ├── page-not-found.component.html │ │ │ ├── page-not-found.component.ts │ │ │ └── page-not-found.scss │ │ ├── customers │ │ │ ├── customers.component.html │ │ │ ├── customers.component.ts │ │ │ └── customers.scss │ │ ├── dashboard │ │ │ ├── dashboard.component.html │ │ │ ├── dashboard.component.ts │ │ │ └── dashboard.scss │ │ ├── employees │ │ │ ├── employees.component.html │ │ │ ├── employees.component.ts │ │ │ └── employees.scss │ │ ├── login │ │ │ ├── login.component.html │ │ │ ├── login.component.ts │ │ │ └── login.scss │ │ ├── logout │ │ │ ├── logout.component.html │ │ │ ├── logout.component.ts │ │ │ └── logout.scss │ │ ├── order_details │ │ │ ├── order_details.component.html │ │ │ ├── order_details.component.ts │ │ │ └── order_details.scss │ │ ├── order_stats │ │ │ ├── order_stats.component.html │ │ │ ├── order_stats.component.ts │ │ │ └── order_stats.scss │ │ ├── orders │ │ │ ├── orders.component.html │ │ │ ├── orders.component.ts │ │ │ └── orders.scss │ │ ├── product_stats │ │ │ ├── product_stats.component.html │ │ │ ├── product_stats.component.ts │ │ │ └── product_stats.scss │ │ └── products │ │ │ ├── products.component.html │ │ │ ├── products.component.ts │ │ │ └── products.scss │ └── services │ │ ├── api │ │ ├── api-request.service.ts │ │ ├── customer.service.ts │ │ ├── employee.service.ts │ │ ├── login.service.ts │ │ ├── order.service.ts │ │ ├── product.service.ts │ │ └── translate.service.ts │ │ ├── auth_guard.service.ts │ │ └── user-info.service.ts ├── assets │ ├── css │ │ ├── font-awesome.css │ │ ├── font-awesome.css.map │ │ ├── font-awesome.min.css │ │ └── sonicglyph.css │ ├── fonts │ │ ├── OpenSans-Italic.woff │ │ ├── OpenSans-Regular.woff │ │ ├── OpenSans-Semibold.woff │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── images │ │ └── logo.svg │ └── scss │ │ ├── _base.scss │ │ ├── _base.scss~7e877128953f01225c7f977ebe54c7ae2aef2cab │ │ ├── _base.scss~HEAD │ │ └── _var.scss ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── styles.scss ├── tsconfig.json └── typings.d.ts └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Java Builds 2 | target/ 3 | build/ 4 | bin/ 5 | .gradle/ 6 | .classpath 7 | 8 | # WebUI Builds 9 | tmp/ 10 | 11 | # WebUI dependencies 12 | node_modules/ 13 | bower_components/ 14 | 15 | # IDEs and editors 16 | **/.idea 17 | **/*.iml 18 | **/.vscode 19 | .settings/ 20 | 21 | # misc 22 | **/.sass-cache 23 | **/npm-debug.log 24 | typings/ 25 | 26 | #System Files 27 | **/.DS_Store 28 | **/.project 29 | **/.settings 30 | **/.classpath 31 | **/.metadata 32 | **/Thumbs.db 33 | -------------------------------------------------------------------------------- /.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # Thsi matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mrinmoy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Angular2_SpringBoot", 3 | "scripts": { 4 | }, 5 | "env": { 6 | }, 7 | "formation": { 8 | }, 9 | "addons": [ 10 | 11 | ], 12 | "buildpacks": [ 13 | { 14 | "url": "heroku/java" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.3.RELEASE") 7 | } 8 | } 9 | 10 | /** 11 | * Include the gradle-download-task plugin 12 | */ 13 | plugins { 14 | id 'de.undercouch.download' version '3.2.0' 15 | } 16 | import de.undercouch.gradle.tasks.download.Download 17 | 18 | 19 | apply plugin: 'java' 20 | apply plugin: 'eclipse' 21 | apply plugin: 'org.springframework.boot' 22 | 23 | 24 | jar { 25 | baseName = 'app' 26 | version = '1.0.0' 27 | } 28 | 29 | repositories { 30 | mavenCentral() 31 | } 32 | 33 | sourceCompatibility = 1.8 34 | targetCompatibility = 1.8 35 | 36 | dependencies { 37 | compile("org.springframework.boot:spring-boot-starter-web") 38 | compile("org.springframework.boot:spring-boot-starter-tomcat") 39 | compile("org.springframework.boot:spring-boot-starter-actuator") 40 | compile("org.springframework.boot:spring-boot-starter-security") 41 | compile("org.springframework.boot:spring-boot-starter-data-jpa") 42 | compile("org.springframework.boot:spring-boot-starter-jdbc") 43 | compile("io.springfox:springfox-swagger2:2.6.1") 44 | compile("io.springfox:springfox-swagger-ui:2.6.1") 45 | compile group: 'org.slf4j' , name: 'slf4j-api' , version: '1.7.22' 46 | compile group: 'io.jsonwebtoken' , name: 'jjwt' , version: '0.7.0' 47 | compile group: 'com.google.guava' , name: 'guava' , version: '21.0' 48 | compile group: 'com.github.javafaker' , name: 'javafaker' , version: '0.12' 49 | compile group: 'joda-time' , name: 'joda-time' , version: '2.9.7' 50 | compile group: 'commons-io' , name: 'commons-io', version: '2.5' 51 | compile group: 'org.json' , name: 'json' , version: '20160810' 52 | compile group: 'org.projectlombok' , name: 'lombok' , version: '1.16.12' 53 | runtime("com.h2database:h2") 54 | //runtime("mysql:mysql-connector-java") 55 | } 56 | 57 | 58 | 59 | task removeWebui(type: Delete) { 60 | delete "${sourceSets.main.resources.srcDirs[0]}/webui" 61 | } 62 | 63 | task copyWebui(type: Copy) { 64 | from "webui/dist" 65 | into "${sourceSets.main.resources.srcDirs[0]}/webui" 66 | exclude "*.gz" 67 | //eachFile { println it.name } 68 | } 69 | 70 | task downloadRedoc(type: Download) { 71 | src "https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js" 72 | dest "${sourceSets.main.resources.srcDirs[0]}/public/redoc" 73 | overwrite true 74 | } 75 | 76 | task var << { 77 | sourceSets { 78 | main { 79 | println "java.srcDirs = ${java.srcDirs}" 80 | println "resources.srcDirs = ${resources.srcDirs[0]}" 81 | println "output.classesDir = ${output.classesDir}" 82 | println "output.resourcesDir = ${output.resourcesDir}" 83 | } 84 | } 85 | } 86 | 87 | 88 | compileJava.dependsOn downloadRedoc 89 | copyWebui.dependsOn removeWebui 90 | compileJava.dependsOn copyWebui 91 | 92 | -------------------------------------------------------------------------------- /screenshots/ER_Model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/ER_Model.png -------------------------------------------------------------------------------- /screenshots/api_doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/api_doc.png -------------------------------------------------------------------------------- /screenshots/api_doc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/api_doc2.png -------------------------------------------------------------------------------- /screenshots/customers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/customers.png -------------------------------------------------------------------------------- /screenshots/db_schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/db_schema.png -------------------------------------------------------------------------------- /screenshots/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/login.png -------------------------------------------------------------------------------- /screenshots/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /screenshots/order_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/order_details.png -------------------------------------------------------------------------------- /screenshots/order_stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/order_stats.png -------------------------------------------------------------------------------- /screenshots/orders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/orders.png -------------------------------------------------------------------------------- /screenshots/product_stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/screenshots/product_stats.png -------------------------------------------------------------------------------- /screenshots/sprout.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/app/MainApp.java: -------------------------------------------------------------------------------- 1 | package com.app; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 6 | import org.springframework.boot.autoconfigure.domain.EntityScan; 7 | import org.springframework.transaction.annotation.*; 8 | 9 | @SpringBootApplication 10 | @EnableJpaRepositories(basePackages ={ "com.app.repo"}) 11 | @EntityScan(basePackages ={ "com.app.model"}) 12 | @EnableTransactionManagement 13 | public class MainApp { 14 | public static void main(String[] args) throws Exception { 15 | new SpringApplication(MainApp.class).run(args); 16 | } 17 | } 18 | 19 | 20 | 21 | /* 22 | SpringBoot Notes 23 | 24 | @Bean :tells Spring 'here is an instance of this class, please keep hold of it and give it back to me when I ask'. 25 | @Autowired :says 'please give me an instance of this class, for example, one that I created with an @Bean annotation earlier'. 26 | 27 | */ 28 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.app.api; 2 | 3 | import org.springframework.dao.DataIntegrityViolationException; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.ExceptionHandler; 7 | import org.springframework.web.bind.annotation.ResponseStatus; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import com.app.model.response.*; 11 | import static com.app.model.response.OperationResponse.*; 12 | 13 | /* 14 | @ControllerAdvice tells your spring application that this class will do the exception handling for your application. 15 | @RestController will make it a controller and let this class render the response. 16 | Use @ExceptionHandler annotation to define the class of Exception it will catch. (A Base class will catch all the Inherited and extended classes) 17 | */ 18 | @ControllerAdvice 19 | @RestController 20 | public class GlobalExceptionHandler { 21 | @ExceptionHandler(value = DataIntegrityViolationException.class) 22 | public OperationResponse handleBaseException(DataIntegrityViolationException e){ 23 | OperationResponse resp = new OperationResponse(); 24 | resp.setOperationStatus(ResponseStatusEnum.ERROR); 25 | resp.setOperationMessage(e.getRootCause().getMessage()); 26 | return resp; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/MainController.java: -------------------------------------------------------------------------------- 1 | package com.app.api; 2 | 3 | import org.springframework.stereotype.*; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.web.bind.annotation.*; 6 | import springfox.documentation.annotations.*; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | @Slf4j 10 | @ApiIgnore 11 | @Controller // Dont use RestController as this method is mapping to a static file not a JSON 12 | public class MainController { 13 | 14 | @RequestMapping(value={"/"}) 15 | public String index() { 16 | return "index.html"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/SessionController.java: -------------------------------------------------------------------------------- 1 | package com.app.api; 2 | 3 | import io.swagger.annotations.*; 4 | 5 | import org.springframework.http.MediaType; 6 | import org.springframework.web.bind.annotation.*; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.security.core.AuthenticationException; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | 11 | import java.util.*; 12 | import javax.servlet.*; 13 | import javax.servlet.http.*; 14 | 15 | import com.app.repo.*; 16 | import com.app.model.*; 17 | import com.app.model.session.*; 18 | import com.app.model.response.*; 19 | import com.app.model.user.*; 20 | import static com.app.model.response.OperationResponse.*; 21 | 22 | /* 23 | This is a dummy rest controller, for the purpose of documentation (/session) path is map to a filter 24 | - This will only be invoked if security is disabled 25 | - If Security is enabled then SessionFilter.java is invoked 26 | - Enabling and Disabling Security is done at config/applicaton.properties 'security.ignored=/**' 27 | */ 28 | 29 | @RestController 30 | @Api(tags = {"Authentication"}) 31 | public class SessionController { 32 | 33 | @Autowired 34 | private UserRepo userRepo; 35 | 36 | @ApiResponses(value = { @ApiResponse(code = 200, message = "Will return a security token, which must be passed in every request", response = SessionResponse.class) }) 37 | @RequestMapping(value = "/session", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) 38 | @ResponseBody 39 | public SessionResponse newSession(@RequestBody Login login, HttpServletRequest request, HttpServletResponse response) { 40 | User user = userRepo.findOneByUserIdAndPassword(login.getUsername(), login.getPassword()).orElse(null); 41 | SessionResponse resp = new SessionResponse(); 42 | SessionItem sessionItem = new SessionItem(); 43 | if (user != null){ 44 | sessionItem.setToken("xxx.xxx.xxx"); 45 | sessionItem.setUserId(user.getUserId()); 46 | sessionItem.setFirstName(user.getFirstName()); 47 | sessionItem.setLastName(user.getLastName()); 48 | sessionItem.setEmail(user.getEmail()); 49 | //sessionItem.setRole(user.getRole()); 50 | 51 | resp.setOperationStatus(ResponseStatusEnum.SUCCESS); 52 | resp.setOperationMessage("Dummy Login Success"); 53 | resp.setItem(sessionItem); 54 | } 55 | else{ 56 | resp.setOperationStatus(ResponseStatusEnum.ERROR); 57 | resp.setOperationMessage("Login Failed"); 58 | } 59 | return resp; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/Version.java: -------------------------------------------------------------------------------- 1 | package com.app.api; 2 | 3 | import io.swagger.annotations.*; 4 | import org.springframework.http.*; 5 | import org.springframework.web.bind.annotation.*; 6 | import org.springframework.web.multipart.MultipartFile; 7 | import static org.springframework.http.MediaType.*; 8 | 9 | import com.app.model.VersionModel; 10 | 11 | @RestController 12 | @RequestMapping(value = "/version", produces = { "application/json" }) 13 | @Api(tags = {"Common"}) 14 | public class Version { 15 | @ApiOperation(value = "Gets the version of the REST API", notes = "", response = VersionModel.class) 16 | @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns the version info for the REST API.", response = VersionModel.class) }) 17 | @RequestMapping( method = RequestMethod.GET) 18 | public VersionModel getVersion() { 19 | //Authentication ath = SecurityContextHolder.getContext().getAuthentication(); 20 | //TokenUser usr = (TokenUser)ath.getDetails(); 21 | //String customerId = usr.getUser().getCustomerId() 22 | VersionModel r = new VersionModel(); 23 | r.setVersion("1.0.0"); 24 | r.setMajor(1); 25 | r.setMinor(0); 26 | r.setPatch(0); 27 | return r; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/order/OrderStatsController.java: -------------------------------------------------------------------------------- 1 | package com.app.api.order; 2 | 3 | import io.swagger.annotations.*; 4 | //import springfox.documentation.annotations.*; 5 | import org.springframework.http.*; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.web.bind.annotation.*; 9 | import org.springframework.web.multipart.MultipartFile; 10 | import org.springframework.data.domain.*; 11 | //import static org.springframework.http.MediaType.*; 12 | 13 | import java.util.*; 14 | import java.lang.*; 15 | import java.math.BigDecimal; 16 | import com.app.api.*; 17 | import com.app.repo.*; 18 | import com.app.model.order.*; 19 | import com.app.model.response.*; 20 | import com.app.model.data.*; 21 | import static com.app.model.response.OperationResponse.*; 22 | 23 | @RestController 24 | @RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE) 25 | @Api(tags = {"Order"}) 26 | public class OrderStatsController { 27 | 28 | @Autowired private JdbcTemplate jdbcTemplate; 29 | 30 | @ApiOperation(value = "Order Stats", response = SingleDataSeriseResponse.class) 31 | @RequestMapping(value = "/order-stats/{type}", method = RequestMethod.GET) 32 | public SingleDataSeriseResponse getOrderStats(@PathVariable("type") String type ) { 33 | String fieldName = ""; 34 | if (type.equalsIgnoreCase("status") || type.equalsIgnoreCase("order_status")){ 35 | fieldName = " order_status "; 36 | } 37 | else if (type.equalsIgnoreCase("paytype") || type.equalsIgnoreCase("payment_type")){ 38 | fieldName = " payment_type "; 39 | } 40 | else if (type.equalsIgnoreCase("country") || type.equalsIgnoreCase("ship_country")){ 41 | fieldName = " ship_country "; 42 | } 43 | else{ 44 | fieldName = " order_status "; 45 | } 46 | 47 | String sql = "select count(*) as value, " + fieldName + " as name from orders group by " + fieldName; 48 | String countType = new String(); 49 | long count; 50 | SingleSerise singleSerise; 51 | SingleDataSeriseResponse resp = new SingleDataSeriseResponse(); 52 | ArrayList dataItemList = new ArrayList(); 53 | 54 | 55 | List> list = jdbcTemplate.queryForList(sql); 56 | 57 | for (Map row : list) { 58 | singleSerise = new SingleSerise((String)row.get("name"), new BigDecimal((long)row.get("value")) ); 59 | dataItemList.add(singleSerise); 60 | } 61 | resp.setItems(dataItemList); 62 | resp.setOperationStatus(ResponseStatusEnum.SUCCESS); 63 | resp.setOperationMessage("Orders by " + fieldName); 64 | //resp.setItems(singleSerise); 65 | return resp; 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/product/ProductStatsController.java: -------------------------------------------------------------------------------- 1 | package com.app.api.product; 2 | 3 | import io.swagger.annotations.*; 4 | //import springfox.documentation.annotations.*; 5 | import org.springframework.http.*; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.web.bind.annotation.*; 9 | import org.springframework.web.multipart.MultipartFile; 10 | import org.springframework.data.domain.*; 11 | //import static org.springframework.http.MediaType.*; 12 | 13 | import java.util.*; 14 | import java.math.BigDecimal; 15 | import com.app.api.*; 16 | import com.app.repo.*; 17 | import com.app.model.order.*; 18 | import com.app.model.response.*; 19 | import com.app.model.data.*; 20 | import static com.app.model.response.OperationResponse.*; 21 | 22 | @RestController 23 | @RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE) 24 | @Api(tags = {"Product"}) 25 | public class ProductStatsController { 26 | 27 | @Autowired private JdbcTemplate jdbcTemplate; 28 | 29 | @ApiOperation(value = "Product Stats", response = SingleDataSeriseResponse.class) 30 | @RequestMapping(value = "/product-stats-by-quantity", method = RequestMethod.GET) 31 | public SingleDataSeriseResponse getProductStatsByQuantity() { 32 | 33 | String sql = "select product_name as name, sum(quantity) as value from order_details group by product_name "; 34 | String countType = new String(); 35 | long count; 36 | SingleSerise singleSerise; 37 | SingleDataSeriseResponse resp = new SingleDataSeriseResponse(); 38 | ArrayList dataItemList = new ArrayList(); 39 | 40 | 41 | List> list = jdbcTemplate.queryForList(sql); 42 | 43 | for (Map row : list) { 44 | singleSerise = new SingleSerise((String)row.get("name"),(BigDecimal)row.get("value") ); 45 | dataItemList.add(singleSerise); 46 | } 47 | resp.setItems(dataItemList); 48 | resp.setOperationStatus(ResponseStatusEnum.SUCCESS); 49 | resp.setOperationMessage("Orders by Quantity Ordered"); 50 | //resp.setItems(singleSerise); 51 | return resp; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/user/UserController.java: -------------------------------------------------------------------------------- 1 | package com.app.api.user; 2 | 3 | import io.swagger.annotations.*; 4 | import org.springframework.web.bind.annotation.*; 5 | 6 | import org.springframework.http.*; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import com.google.common.base.Strings; 11 | import org.apache.commons.io.IOUtils; 12 | import org.json.*; 13 | 14 | import com.app.model.response.*; 15 | import com.app.model.user.*; 16 | import static com.app.model.response.OperationResponse.*; 17 | 18 | @RestController 19 | @Api(tags = {"Authentication"}) 20 | public class UserController { 21 | 22 | @Autowired 23 | private UserService userService; 24 | 25 | @ApiOperation(value = "Gets current user information", response = UserResponse.class) 26 | @RequestMapping(value = "/user", method = RequestMethod.GET, produces = {"application/json"}) 27 | public UserResponse getUserInformation(@RequestParam(value = "name", required = false) String userIdParam, HttpServletRequest req) { 28 | 29 | String loggedInUserId = userService.getLoggedInUserId(); 30 | 31 | User user; 32 | boolean provideUserDetails = false; 33 | 34 | if (Strings.isNullOrEmpty(userIdParam)) { 35 | provideUserDetails = true; 36 | user = userService.getLoggedInUser(); 37 | } 38 | else if (loggedInUserId.equals(userIdParam)) { 39 | provideUserDetails = true; 40 | user = userService.getLoggedInUser(); 41 | } 42 | else { 43 | //Check if the current user is superuser then provide the details of requested user 44 | provideUserDetails = true; 45 | user = userService.getUserInfoByUserId(userIdParam); 46 | } 47 | 48 | UserResponse resp = new UserResponse(); 49 | if (provideUserDetails) { 50 | resp.setOperationStatus(ResponseStatusEnum.SUCCESS); 51 | } 52 | else { 53 | resp.setOperationStatus(ResponseStatusEnum.NO_ACCESS); 54 | resp.setOperationMessage("No Access"); 55 | } 56 | resp.setData(user); 57 | return resp; 58 | } 59 | 60 | 61 | @ApiOperation(value = "Add new user", response = OperationResponse.class) 62 | @RequestMapping(value = "/user", method = RequestMethod.POST, produces = {"application/json"}) 63 | public OperationResponse addNewUser(@RequestBody User user, HttpServletRequest req) { 64 | boolean userAddSuccess = userService.addNewUser(user); 65 | OperationResponse resp = new OperationResponse(); 66 | if (userAddSuccess==true){ 67 | resp.setOperationStatus(ResponseStatusEnum.SUCCESS); 68 | resp.setOperationMessage("User Added"); 69 | } 70 | else{ 71 | resp.setOperationStatus(ResponseStatusEnum.ERROR); 72 | resp.setOperationMessage("Unable to add user"); 73 | } 74 | return resp; 75 | } 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/app/api/user/UserService.java: -------------------------------------------------------------------------------- 1 | package com.app.api.user; 2 | import java.util.List; 3 | import com.app.model.*; 4 | import com.google.common.base.Strings; 5 | 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.security.core.Authentication; 11 | import org.springframework.security.core.context.SecurityContextHolder; 12 | 13 | import com.app.repo.UserRepo; 14 | import com.app.model.user.*; 15 | 16 | @Service 17 | public class UserService { 18 | 19 | @Autowired 20 | private UserRepo userRepo; 21 | 22 | public String getLoggedInUserId(){ 23 | Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 24 | if (auth==null){ 25 | return "nosession"; 26 | } 27 | return auth.getName(); 28 | } 29 | 30 | 31 | public User getLoggedInUser() { 32 | String loggedInUserId = this.getLoggedInUserId(); 33 | User user = this.getUserInfoByUserId(loggedInUserId); 34 | return user; 35 | } 36 | 37 | public User getUserInfoByUserId(String userId){ 38 | User user = this.userRepo.findOneByUserId(userId).orElseGet( () -> new User()); 39 | return user; 40 | } 41 | 42 | public boolean insertOrSaveUser(User user) { 43 | this.userRepo.save(user); 44 | return true; 45 | } 46 | 47 | public boolean addNewUser(User user) { 48 | User newUser = this.getUserInfoByUserId(user.getUserId()); 49 | if (newUser.getUserId().equals("new")){ 50 | // This means the username is not found therfore its is returning a default value of "new" 51 | return this.insertOrSaveUser(user); 52 | } 53 | else{ 54 | return false; 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/app/config/CorsFilter.java: -------------------------------------------------------------------------------- 1 | package com.app.config; 2 | 3 | import java.io.IOException; 4 | import javax.servlet.*; 5 | import javax.servlet.http.*; 6 | import org.springframework.stereotype.*; 7 | 8 | public class CorsFilter implements javax.servlet.Filter { 9 | @Override 10 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 11 | HttpServletResponse res = (HttpServletResponse) response; 12 | HttpServletRequest req = (HttpServletRequest) request; 13 | 14 | res.setHeader("Access-Control-Allow-Origin", "*"); 15 | res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS"); 16 | res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host, Referer, Connection, User-Agent, authorization, sw-useragent, sw-version"); 17 | 18 | // Just REPLY OK if request method is OPTIONS for CORS (pre-flight) 19 | if ( req.getMethod().equals("OPTIONS") ) { 20 | res.setStatus(HttpServletResponse.SC_OK); 21 | return; 22 | } 23 | chain.doFilter(request, response); 24 | } 25 | 26 | @Override 27 | public void destroy() {} 28 | 29 | @Override 30 | public void init(FilterConfig filterConfig) throws ServletException {} 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/app/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.app.config; 2 | 3 | import org.springframework.security.config.annotation.web.builders.*; 4 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 5 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 7 | import org.springframework.security.web.access.channel.ChannelProcessingFilter; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.context.annotation.Configuration; 10 | import com.app.identity.*; 11 | import org.springframework.core.annotation.Order; 12 | 13 | 14 | @Configuration 15 | @EnableWebSecurity 16 | @Order(1) 17 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 18 | 19 | @Autowired 20 | private TokenUtil tokenUtil; 21 | 22 | @Override 23 | public void configure(WebSecurity web) throws Exception { 24 | // Filters will not get executed for the resources 25 | web.ignoring().antMatchers("/", "/resources/**", "/static/**", "/public/**", "/webui/**", "/h2-console/**" 26 | , "/configuration/**", "/swagger-ui/**", "/swagger-resources/**", "/api-docs", "/api-docs/**", "/v2/api-docs/**" 27 | , "/*.html", "/**/*.html" ,"/**/*.css","/**/*.js","/**/*.png","/**/*.jpg", "/**/*.gif", "/**/*.svg", "/**/*.ico", "/**/*.ttf","/**/*.woff","/**/*.otf"); 28 | } 29 | 30 | //If Security is not working check application.properties if it is set to ignore 31 | @Override 32 | protected void configure(HttpSecurity http) throws Exception { 33 | http 34 | .exceptionHandling().and() 35 | .anonymous().and() 36 | // Disable Cross site references 37 | .csrf().disable() 38 | // Add CORS Filter 39 | .addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class) 40 | // Custom Token based authentication based on the header previously given to the client 41 | .addFilterBefore(new VerifyTokenFilter(tokenUtil), UsernamePasswordAuthenticationFilter.class) 42 | // custom JSON based authentication by POST of {"username":"","password":""} which sets the token header upon authentication 43 | .addFilterBefore(new GenerateTokenForUserFilter ("/session", authenticationManager(), tokenUtil), UsernamePasswordAuthenticationFilter.class) 44 | .authorizeRequests() 45 | .anyRequest().authenticated() 46 | ; 47 | } 48 | 49 | /* 50 | * If You want to store encoded password in your databases and authenticate user 51 | * based on encoded password then uncomment the below method and provde an encoder 52 | 53 | //@Autowired 54 | //private UserDetailsService userDetailsService; 55 | 56 | @Override 57 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 58 | auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); 59 | } 60 | */ 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/app/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.app.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.scheduling.annotation.*; 5 | 6 | 7 | import org.joda.time.LocalDate; 8 | import org.springframework.context.annotation.*; 9 | import org.springframework.http.ResponseEntity; 10 | 11 | import springfox.documentation.builders.*; 12 | import springfox.documentation.service.*; 13 | import springfox.documentation.spi.DocumentationType; 14 | import springfox.documentation.spring.web.plugins.Docket; 15 | import springfox.documentation.spi.service.contexts.SecurityContext; 16 | import springfox.documentation.swagger.web.*; 17 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 18 | //import static springfox.documentation.builders.PathSelectors.ant; 19 | import static com.google.common.collect.Lists.*; 20 | import java.util.*; 21 | import com.app.identity.*; 22 | 23 | 24 | 25 | @Configuration 26 | @EnableSwagger2 27 | public class SwaggerConfig{ 28 | 29 | ApiInfo apiInfo() { 30 | return new ApiInfoBuilder() 31 | .title("API Reference") 32 | .version("1.0.0") 33 | .build(); 34 | } 35 | 36 | @Bean 37 | public Docket customImplementation(){ 38 | return new Docket(DocumentationType.SWAGGER_2) 39 | .apiInfo(apiInfo()) 40 | .securitySchemes(newArrayList(apiKey())) 41 | .select().paths(PathSelectors.any()) 42 | //.apis(RequestHandlerSelectors.any()) // If you want to list all the apis including springboots own 43 | .apis(RequestHandlerSelectors.basePackage("com.app.api")) 44 | .build() 45 | .pathMapping("/") 46 | .useDefaultResponseMessages(false) 47 | .directModelSubstitute(LocalDate.class, String.class) 48 | .genericModelSubstitutes(ResponseEntity.class) 49 | ; 50 | } 51 | 52 | private ApiKey apiKey() { 53 | //return new ApiKey("Authorization", "api_key", "header"); 54 | return new ApiKey("Authorization", "", "header"); // <<< === Create a Heaader (We are createing header named "Authorization" here) 55 | } 56 | 57 | @Bean 58 | SecurityConfiguration security() { 59 | //return new SecurityConfiguration("emailSecurity_client", "secret", "Spring", "emailSecurity", "apiKey", ApiKeyVehicle.HEADER, "api_key", ","); 60 | return new SecurityConfiguration("emailSecurity_client", "secret", "Spring", "emailSecurity", "", ApiKeyVehicle.HEADER, "", ","); 61 | } 62 | 63 | // This path will be called when swagger is loaded first time to get a token 64 | /* 65 | @Bean 66 | public UiConfiguration uiConfig() { 67 | return new UiConfiguration("session"); 68 | } 69 | */ 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/app/config/VerifyTokenFilter.java: -------------------------------------------------------------------------------- 1 | package com.app.config; 2 | 3 | import org.springframework.security.core.Authentication; 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | import org.springframework.web.filter.GenericFilterBean; 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.*; 8 | import javax.servlet.http.*; 9 | import java.io.*; 10 | import java.util.*; 11 | import io.jsonwebtoken.JwtException; 12 | import com.app.identity.*; 13 | 14 | /* 15 | This filter checks if there is a token in the Request service header and the token is not expired 16 | it is applied to all the routes which are protected 17 | */ 18 | public class VerifyTokenFilter extends GenericFilterBean { 19 | 20 | private final TokenUtil tokenUtil; 21 | //private AuthenticationFailureHandler loginFailureHandler = new SimpleUrlAuthenticationFailureHandler(); 22 | 23 | public VerifyTokenFilter(TokenUtil tokenUtil) { 24 | this.tokenUtil = tokenUtil; 25 | } 26 | 27 | @Override 28 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { 29 | HttpServletRequest request = (HttpServletRequest) req; 30 | HttpServletResponse response = (HttpServletResponse) res; 31 | try { 32 | Optional authentication = tokenUtil.verifyToken(request); 33 | if (authentication.isPresent()) { 34 | SecurityContextHolder.getContext().setAuthentication(authentication.get()); 35 | } 36 | else{ 37 | SecurityContextHolder.getContext().setAuthentication(null); 38 | } 39 | filterChain.doFilter(req, res); 40 | } 41 | catch (JwtException e) { 42 | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 43 | } 44 | finally { 45 | SecurityContextHolder.getContext().setAuthentication(null); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/app/identity/TokenUser.java: -------------------------------------------------------------------------------- 1 | package com.app.identity; 2 | 3 | import org.springframework.security.core.authority.AuthorityUtils; 4 | import com.app.model.user.Role; 5 | import com.app.model.user.User; 6 | 7 | public class TokenUser extends org.springframework.security.core.userdetails.User { 8 | private User user; 9 | 10 | //For returning a normal user 11 | public TokenUser(User user) { 12 | super( user.getUserId(), user.getPassword(), AuthorityUtils.createAuthorityList(user.getRole().toString() ) ); 13 | //super(user.getUserName(), user.getPassword(), true, true, true, true, AuthorityUtils.createAuthorityList(user.getRole().toString())); 14 | this.user = user; 15 | } 16 | 17 | public User getUser() { 18 | return user; 19 | } 20 | 21 | public String getRole() { 22 | return user.getRole().toString(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/app/identity/TokenUtil.java: -------------------------------------------------------------------------------- 1 | package com.app.identity; 2 | 3 | import org.springframework.security.core.Authentication; 4 | import org.springframework.stereotype.Service; 5 | import io.jsonwebtoken.*; 6 | import javax.servlet.http.*; 7 | import java.util.*; 8 | import java.io.IOException; 9 | 10 | import com.app.model.user.Role; 11 | import com.app.model.user.User; 12 | 13 | @Service 14 | public class TokenUtil { 15 | 16 | //private static final long VALIDITY_TIME_MS = 10 * 24 * 60 * 60 * 1000;// 10 days Validity 17 | private static final long VALIDITY_TIME_MS = 2 * 60 * 60 * 1000; // 2 hours validity 18 | private static final String AUTH_HEADER_NAME = "Authorization"; 19 | 20 | private String secret="mrin"; 21 | 22 | public Optional verifyToken(HttpServletRequest request) { 23 | final String token = request.getHeader(AUTH_HEADER_NAME); 24 | 25 | if (token != null && !token.isEmpty()){ 26 | final TokenUser user = parseUserFromToken(token.replace("Bearer","").trim()); 27 | if (user != null) { 28 | return Optional.of(new UserAuthentication(user)); 29 | } 30 | } 31 | return Optional.empty(); 32 | 33 | } 34 | 35 | //Get User Info from the Token 36 | public TokenUser parseUserFromToken(String token){ 37 | 38 | Claims claims = Jwts.parser() 39 | .setSigningKey(secret) 40 | .parseClaimsJws(token) 41 | .getBody(); 42 | 43 | User user = new User(); 44 | user.setUserId( (String)claims.get("userId")); 45 | user.setRole(Role.valueOf((String)claims.get("role"))); 46 | if (user.getUserId() != null && user.getRole() != null) { 47 | return new TokenUser(user); 48 | } else { 49 | return null; 50 | } 51 | } 52 | 53 | public String createTokenForUser(TokenUser tokenUser) { 54 | return createTokenForUser(tokenUser.getUser()); 55 | } 56 | 57 | public String createTokenForUser(User user) { 58 | return Jwts.builder() 59 | .setExpiration(new Date(System.currentTimeMillis() + VALIDITY_TIME_MS)) 60 | .setSubject(user.getFullName()) 61 | .claim("userId", user.getUserId()) 62 | .claim("role", user.getRole().toString()) 63 | .signWith(SignatureAlgorithm.HS256, secret) 64 | .compact(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/app/identity/UserAuthentication.java: -------------------------------------------------------------------------------- 1 | package com.app.identity; 2 | 3 | import org.springframework.security.core.Authentication; 4 | import org.springframework.security.core.GrantedAuthority; 5 | import java.util.Collection; 6 | 7 | public class UserAuthentication implements Authentication { 8 | private final TokenUser user; 9 | private boolean authenticated = true; 10 | 11 | public UserAuthentication(TokenUser user) { 12 | this.user = user; 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return user.getUsername(); 18 | } 19 | 20 | @Override 21 | public Collection getAuthorities() { 22 | return user.getAuthorities(); 23 | } 24 | 25 | @Override 26 | public Object getCredentials() { 27 | return user.getPassword(); 28 | } 29 | 30 | @Override 31 | public TokenUser getDetails() { 32 | return user; 33 | } 34 | 35 | @Override 36 | public Object getPrincipal() { 37 | return user.getUsername(); 38 | } 39 | 40 | @Override 41 | public boolean isAuthenticated() { 42 | return authenticated; 43 | } 44 | 45 | @Override 46 | public void setAuthenticated(boolean authenticated) { 47 | this.authenticated = authenticated; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/app/identity/UserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.app.identity; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.security.authentication.AccountStatusUserDetailsChecker; 5 | import org.springframework.security.core.Authentication; 6 | import org.springframework.security.core.GrantedAuthority; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 9 | import org.springframework.security.authentication.DisabledException; 10 | import org.springframework.security.authentication.AuthenticationServiceException; 11 | import org.springframework.stereotype.Service; 12 | 13 | import com.app.model.user.Role; 14 | import com.app.model.user.User; 15 | import com.app.repo.UserRepo; 16 | 17 | import java.util.Optional; 18 | 19 | @Service 20 | public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService { 21 | 22 | @Autowired 23 | private UserRepo userRepo; 24 | private final AccountStatusUserDetailsChecker detailsChecker = new AccountStatusUserDetailsChecker(); 25 | 26 | @Override 27 | public final TokenUser loadUserByUsername(String username) throws UsernameNotFoundException, DisabledException { 28 | 29 | final User user = userRepo.findOneByUserId(username).orElseThrow(() -> new UsernameNotFoundException("User not found")); 30 | TokenUser currentUser; 31 | if (user.isActive() == true){ 32 | currentUser = new TokenUser(user); 33 | } 34 | else{ 35 | throw new DisabledException("User is not activated (Disabled User)"); 36 | //If pending activation return a disabled user 37 | //currentUser = new TokenUser(user, false); 38 | } 39 | detailsChecker.check(currentUser); 40 | return currentUser; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/VersionModel.java: -------------------------------------------------------------------------------- 1 | package com.app.model; 2 | 3 | import lombok.*; 4 | 5 | @Data // For Getters and Setters 6 | public class VersionModel { 7 | private String version = null; 8 | private Integer major = null; 9 | private Integer minor = null; 10 | private Integer patch = null; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/customer/Customer.java: -------------------------------------------------------------------------------- 1 | package com.app.model.customer; 2 | 3 | import lombok.*; 4 | import java.util.*; 5 | import javax.persistence.*; 6 | import io.swagger.annotations.ApiModelProperty; 7 | 8 | @Data 9 | @Entity 10 | @Table(name = "customers") 11 | public class Customer { 12 | 13 | //@GeneratedValue(strategy = GenerationType.AUTO) 14 | @Id 15 | private Integer id; 16 | private String lastName; 17 | private String firstName; 18 | private String email; 19 | private String company; 20 | private String phone; 21 | private String address1; 22 | private String address2; 23 | private String city; 24 | private String state; 25 | private String postalCode; 26 | private String country; 27 | public Customer(){} 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/customer/CustomerResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.customer; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class CustomerResponse extends PageResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | private List items; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/data/SingleSerise.java: -------------------------------------------------------------------------------- 1 | package com.app.model.data; 2 | 3 | import lombok.*; 4 | import java.util.*; 5 | import java.math.BigDecimal; 6 | import javax.persistence.*; 7 | import io.swagger.annotations.ApiModelProperty; 8 | 9 | @Data 10 | public class SingleSerise { 11 | private String name; 12 | private BigDecimal value; 13 | 14 | public SingleSerise( String name, BigDecimal value){ 15 | this.name = name; 16 | this.value = value; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/employee/Employee.java: -------------------------------------------------------------------------------- 1 | package com.app.model.employee; 2 | 3 | import lombok.*; 4 | import java.util.*; 5 | import javax.persistence.*; 6 | import io.swagger.annotations.ApiModelProperty; 7 | 8 | @Data 9 | @Entity 10 | @Table(name = "employees") 11 | public class Employee { 12 | 13 | @Id 14 | //@GeneratedValue(strategy = GenerationType.AUTO) 15 | private Integer id; 16 | private String lastName; 17 | private String firstName; 18 | private String email; 19 | private String avatar; 20 | private String jobTitle; 21 | private String department; 22 | private Integer managerId; 23 | private String phone; 24 | private String address1; 25 | private String address2; 26 | private String city; 27 | private String state; 28 | private String postalCode; 29 | private String country; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/employee/EmployeeResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.employee; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class EmployeeResponse extends PageResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | private List items; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/CompositeOrderProductKey.java: -------------------------------------------------------------------------------- 1 | package com.app.model.order; 2 | 3 | import java.io.Serializable; 4 | import javax.persistence.*; 5 | import lombok.*; 6 | 7 | @Data 8 | @Embeddable 9 | public class CompositeOrderProductKey implements Serializable { 10 | private int orderId; 11 | private int productId; 12 | 13 | public CompositeOrderProductKey(int orderId, int productId){ 14 | this.orderId =orderId; 15 | this.productId =productId; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/Order.java: -------------------------------------------------------------------------------- 1 | package com.app.model.order; 2 | 3 | import lombok.*; 4 | import java.util.*; 5 | import java.math.*; 6 | import javax.persistence.*; 7 | import io.swagger.annotations.ApiModelProperty; 8 | 9 | @Data 10 | @Entity 11 | @Table(name = "orders") 12 | public class Order { 13 | //@GeneratedValue(strategy = GenerationType.AUTO) 14 | @Id 15 | private Integer id; 16 | private Integer employeeId; 17 | private Integer customerId; 18 | private Date orderDate; 19 | private Date shippedDate; 20 | private Date paidDate; 21 | private String shipName; 22 | private String shipAddress1; 23 | private String shipAddress2; 24 | private String shipCity; 25 | private String shipState; 26 | private String shipPostalCode; 27 | private String shipCountry; 28 | private BigDecimal shippingFee; 29 | @ApiModelProperty(allowableValues = "Check, Cash, Card") private String paymentType; 30 | @ApiModelProperty(allowableValues = "On Hold, Shipped, Complete, New")private String orderStatus; 31 | 32 | //Constructors 33 | public Order(){} 34 | public Order(Integer id , Integer employeeId , Integer customerId , Date orderDate , String orderStatus, 35 | Date shippedDate , String shipName , String shipAddress1, String shipAddress2, String shipCity , String shipState, String shipPostalCode, String shipCountry, 36 | BigDecimal shippingFee , String paymentType , Date paidDate 37 | ){ 38 | this.id=id; 39 | this.employeeId = employeeId ; 40 | this.customerId = customerId ; 41 | this.orderDate = orderDate; 42 | this.orderStatus = orderStatus; 43 | this.shippedDate = shippedDate; 44 | this.shipName = shipName; 45 | this.shipAddress1= shipAddress1; 46 | this.shipAddress2= shipAddress2; 47 | this.shipCity = shipCity; 48 | this.shipState = shipState; 49 | this.shipPostalCode= shipPostalCode; 50 | this.shipCountry = shipCountry; 51 | this.shippingFee = shippingFee; 52 | this.paymentType = paymentType; 53 | this.paidDate = paidDate; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/OrderDetailResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.order; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class OrderDetailResponse extends PageResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | //private List items; 13 | private List items; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/OrderInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * OrderInfo contains extra details of the order 3 | * Such as Customer Info (Name, Company , Email) 4 | */ 5 | package com.app.model.order; 6 | 7 | import lombok.*; 8 | import java.util.*; 9 | import java.math.*; 10 | import javax.persistence.*; 11 | import io.swagger.annotations.ApiModelProperty; 12 | 13 | @Data 14 | @Entity 15 | @EqualsAndHashCode(callSuper=false) 16 | @Table(name = "order_info") 17 | public class OrderInfo { 18 | @Id 19 | private Integer orderId; 20 | private Integer employeeId; 21 | private Integer customerId; 22 | private Date orderDate; 23 | private Date shippedDate; 24 | private Date paidDate; 25 | private String shipName; 26 | private String shipAddress1; 27 | private String shipAddress2; 28 | private String shipCity; 29 | private String shipState; 30 | private String shipPostalCode; 31 | private String shipCountry; 32 | private BigDecimal shippingFee; 33 | @ApiModelProperty(allowableValues = "Check, Cash, Card") private String paymentType; 34 | @ApiModelProperty(allowableValues = "On Hold, Shipped, Complete, New")private String orderStatus; 35 | 36 | private String customerName; 37 | private String customerPhone; 38 | private String customerEmail; 39 | private String customerCompany; 40 | private String employeeName; 41 | private String employeeDepartment; 42 | private String employeeJobTitle; 43 | 44 | public OrderInfo(){} 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/OrderInfoResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.order; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class OrderInfoResponse extends PageResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | private List items; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/OrderItem.java: -------------------------------------------------------------------------------- 1 | package com.app.model.order; 2 | 3 | import lombok.*; 4 | import java.io.Serializable; 5 | import java.util.*; 6 | import java.math.*; 7 | import javax.persistence.*; 8 | import io.swagger.annotations.ApiModelProperty; 9 | 10 | @Data 11 | @Entity 12 | @Table(name = "order_items") 13 | public class OrderItem { 14 | 15 | @EmbeddedId 16 | @AttributeOverrides({ 17 | @AttributeOverride(name = "orderId" , column = @Column(name = "order_id")), 18 | @AttributeOverride(name = "productId", column = @Column(name = "product_id")) 19 | }) 20 | CompositeOrderProductKey orderItemKey; 21 | private BigDecimal quantity; 22 | private BigDecimal unitPrice; 23 | private BigDecimal discount; 24 | 25 | @ApiModelProperty(allowableValues = "On Order, Allocated, No Stock") 26 | private String orderItemStatus; 27 | private Date dateAllocated; 28 | 29 | public OrderItem(){} 30 | 31 | //To Create orderitem by passing product_id and order_id as seperate variables 32 | public OrderItem(int orderId, int productId, BigDecimal quantity, BigDecimal unitPrice, BigDecimal discount, String orderItemStatus, Date dateAllocated){ 33 | this(new CompositeOrderProductKey(orderId, productId), quantity, unitPrice, discount, orderItemStatus, dateAllocated); 34 | } 35 | 36 | //TO Create orderitem by passing Composite Key 37 | public OrderItem(CompositeOrderProductKey orderItemKey, BigDecimal quantity, BigDecimal unitPrice, BigDecimal discount, String orderItemStatus, Date dateAllocated){ 38 | this.orderItemKey = orderItemKey; 39 | this.quantity = quantity; 40 | this.unitPrice = unitPrice; 41 | this.discount = discount; 42 | this.dateAllocated=dateAllocated; 43 | this.orderItemStatus =orderItemStatus; 44 | } 45 | 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/order/OrderResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.order; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class OrderResponse extends PageResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | private List items; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/product/Product.java: -------------------------------------------------------------------------------- 1 | package com.app.model.product; 2 | 3 | import lombok.*; 4 | import java.util.*; 5 | import javax.persistence.*; 6 | import io.swagger.annotations.ApiModelProperty; 7 | 8 | @Data 9 | @Entity 10 | @Table(name = "products") 11 | public class Product { 12 | //@GeneratedValue(strategy = GenerationType.AUTO) 13 | @Id 14 | private Integer id; 15 | private String productCode; 16 | private String productName; 17 | private String description; 18 | private Long standardCost; 19 | private Long listPrice; 20 | private Integer targetLevel; 21 | private Integer reorderLevel; 22 | private Integer minimumReorderQuantity; 23 | private String quantityPerUnit; 24 | private Integer discontinued; 25 | @ApiModelProperty(allowableValues = "Camera, Laptop, Tablet, Phone") private String category; 26 | public Product(){} 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/product/ProductResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.product; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class ProductResponse extends PageResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | private List items; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/response/OperationResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | This is the common structure for all responses 3 | if the response contains a list(array) then it will have 'items' field 4 | if the response contains a single item then it will have 'item' field 5 | */ 6 | 7 | 8 | package com.app.model.response; 9 | 10 | import io.swagger.annotations.*; 11 | import lombok.*; 12 | 13 | @Data //for getters and setters 14 | public class OperationResponse { 15 | public enum ResponseStatusEnum {SUCCESS, ERROR, WARNING, NO_ACCESS}; 16 | @ApiModelProperty(required = true) 17 | private ResponseStatusEnum operationStatus; 18 | private String operationMessage; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/response/PageResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.response; 2 | 3 | import io.swagger.annotations.*; 4 | import org.springframework.data.domain.*; 5 | import lombok.*; 6 | import java.util.*; 7 | import static com.app.model.response.OperationResponse.*; 8 | 9 | //@Data //for getters and setters 10 | public class PageResponse extends OperationResponse { 11 | @Getter @Setter private boolean first; 12 | @Getter @Setter private boolean last; 13 | @Getter @Setter private int currentPageNumber; 14 | @Getter @Setter private int itemsInPage; 15 | @Getter @Setter private int pageSize; 16 | @Getter @Setter private int totalPages; 17 | @Getter @Setter private long totalItems; 18 | @Getter @Setter private Sort sort; 19 | private List items; 20 | 21 | public void setPageStats(Page pg, boolean setDefaultMessage){ 22 | this.first = pg.isFirst(); 23 | this.last = pg.isLast(); 24 | this.currentPageNumber = pg.getNumber(); 25 | this.itemsInPage = pg.getNumberOfElements(); 26 | this.pageSize = pg.getSize(); 27 | this.totalPages = pg.getTotalPages(); 28 | this.totalItems = pg.getTotalElements(); 29 | //this.items = pg.getContent(); 30 | this.sort = pg.getSort(); 31 | if (setDefaultMessage == true){ 32 | this.setOperationStatus(ResponseStatusEnum.SUCCESS); 33 | this.setOperationMessage("Page " + (pg.getNumber()+ 1 ) + " of " + pg.getTotalPages() ); 34 | } 35 | } 36 | 37 | public void setPageTotal(int count, boolean setDefaultMessage){ 38 | //this.items = list; 39 | this.first = true; 40 | this.last = true; 41 | this.itemsInPage = count; 42 | this.totalItems = count; 43 | this.totalPages = 1; 44 | this.pageSize = count; 45 | if (setDefaultMessage == true){ 46 | this.setOperationStatus(ResponseStatusEnum.SUCCESS); 47 | this.setOperationMessage("Total " + count + " items "); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/response/SingleDataSeriseResponse.java: -------------------------------------------------------------------------------- 1 | //This is a common http response model for providing data series 2 | 3 | package com.app.model.response; 4 | 5 | import lombok.*; 6 | import java.util.*; 7 | import io.swagger.annotations.*; 8 | import com.app.model.data.*; 9 | 10 | @Data 11 | @EqualsAndHashCode(callSuper=false) 12 | public class SingleDataSeriseResponse extends OperationResponse { 13 | private List items; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/session/SessionItem.java: -------------------------------------------------------------------------------- 1 | package com.app.model.session; 2 | 3 | import lombok.*; 4 | import java.util.*; 5 | import io.swagger.annotations.ApiModelProperty; 6 | 7 | @Data 8 | public class SessionItem { 9 | private String token; 10 | private String userId; 11 | private String firstName; 12 | private String lastName; 13 | private String email; 14 | private List roles; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/session/SessionResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.session; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class SessionResponse extends OperationResponse { 11 | @ApiModelProperty(required = true, value = "") 12 | private SessionItem item; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/user/Login.java: -------------------------------------------------------------------------------- 1 | package com.app.model.user; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | 6 | @Data 7 | public class Login { 8 | 9 | @ApiModelProperty(example = "demo", required = true) 10 | private String username = ""; 11 | 12 | @ApiModelProperty(example = "demo", required = true) 13 | private String password = ""; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/user/Role.java: -------------------------------------------------------------------------------- 1 | package com.app.model.user; 2 | 3 | public enum Role { 4 | USER, ADMIN 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/app/model/user/UserResponse.java: -------------------------------------------------------------------------------- 1 | package com.app.model.user; 2 | 3 | import io.swagger.annotations.*; 4 | import lombok.*; 5 | import java.util.*; 6 | import com.app.model.response.*; 7 | 8 | @Data 9 | @EqualsAndHashCode(callSuper=false) 10 | public class UserResponse extends OperationResponse { 11 | private User data = new User(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/CustomerRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.domain.*; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import java.util.Optional; 6 | import java.util.*; 7 | import com.app.model.customer.*; 8 | 9 | public interface CustomerRepo extends JpaRepository { 10 | public List findAll(); 11 | public Page findAll(Pageable p); 12 | Customer save(Customer c); 13 | void delete(Customer c); 14 | void delete(Integer id); 15 | boolean exists( Integer id); 16 | 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/EmployeeRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.domain.*; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import java.util.Optional; 6 | import java.util.*; 7 | import com.app.model.employee.*; 8 | 9 | 10 | public interface EmployeeRepo extends JpaRepository { 11 | public List findAll(); 12 | public Page findAll(Pageable p); 13 | Employee save(Employee e); 14 | void delete(Employee e); 15 | void delete(Integer id); 16 | boolean exists( Integer id); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/OrderInfoRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.domain.*; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import java.util.Optional; 6 | import java.util.*; 7 | import com.app.model.order.*; 8 | 9 | 10 | public interface OrderInfoRepo extends JpaRepository { 11 | public List findAll(); 12 | public Page findAll(Pageable p); 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/OrderItemRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.domain.*; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import java.util.Optional; 6 | import java.util.*; 7 | import com.app.model.order.*; 8 | 9 | 10 | public interface OrderItemRepo extends JpaRepository { 11 | public List findAll(); 12 | public Page findAll(Pageable p); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/OrderRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.domain.*; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import java.util.Optional; 6 | import java.util.*; 7 | import com.app.model.order.*; 8 | 9 | 10 | public interface OrderRepo extends JpaRepository { 11 | public List findAll(); 12 | public Page findAll(Pageable p); 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/ProductRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.domain.*; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import java.util.Optional; 6 | import java.util.*; 7 | import com.app.model.product.*; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | @Transactional 11 | public interface ProductRepo extends JpaRepository { 12 | public List findAll(); 13 | public Page findAll(Pageable p); 14 | Optional findOneById(Integer id); 15 | 16 | //Product save(Product p); 17 | //void delete(Product p) ; 18 | //void delete(Integer id); 19 | //Product deleteById(Integer id); 20 | //boolean exists( Integer id); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/com/app/repo/UserRepo.java: -------------------------------------------------------------------------------- 1 | package com.app.repo; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import com.app.model.user.User; 5 | import java.util.Optional; 6 | 7 | public interface UserRepo extends JpaRepository { 8 | Optional findOneByUserId(String userId); 9 | Optional findOneByUserIdAndPassword(String userId, String password); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # File is used by sprigboot 2 | server.contextPath=/ 3 | server.port=9119 4 | spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/webui/ 5 | 6 | #Temporary disable security to enable it remove this 7 | #security.ignored=/** 8 | 9 | springfox.documentation.swagger.v2.path=/api-docs 10 | 11 | # ****** H2 In Memort Database Connection Info ******* 12 | spring.datasource.url=jdbc:h2:mem:demo;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE 13 | spring.datasource.username=sa 14 | spring.datasource.password= 15 | spring.datasource.driver-class-name=org.h2.Driver 16 | spring.datasource.platform=h2 17 | spring.datasource.initialize=true 18 | spring.h2.console.enabled=true 19 | spring.jpa.hibernate.ddl-auto=none 20 | spring.datasource.continue-on-error=false 21 | 22 | spring.jpa.show-sql=false 23 | spring.jpa.properties.hibernate.format_sql=false 24 | #spring.jpa.properties.hibernate.default_schema=demo 25 | -------------------------------------------------------------------------------- /src/main/resources/public/assets/css/sonicglyph.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'sonicglyph'; 3 | src: url('../fonts/sonicglyph.woff') format('woff'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | .s-glyph { 8 | display: inline-block; 9 | font: normal normal normal 16px/1 sonicglyph; 10 | font-size: inherit; 11 | text-rendering: auto; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/public/assets/fonts/OpenSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/assets/fonts/OpenSans-Italic.woff -------------------------------------------------------------------------------- /src/main/resources/public/assets/fonts/OpenSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/assets/fonts/OpenSans-Regular.woff -------------------------------------------------------------------------------- /src/main/resources/public/assets/fonts/OpenSans-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/assets/fonts/OpenSans-Semibold.woff -------------------------------------------------------------------------------- /src/main/resources/public/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/main/resources/public/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/main/resources/public/assets/scss/_var.scss: -------------------------------------------------------------------------------- 1 | //Fonts 2 | $s-f-family: Metropolis,Avenir Next,Helvetica Neue,Arial,sans-serif; 3 | $s-f1-size: 24px; 4 | $s-f2-size: 20px; 5 | $s-f3-size: 18px; 6 | $s-f4-size: 16px; 7 | $s-f5-size: 14px; 8 | $s-f6-size: 12px; 9 | $s-f-body-size: 12px; 10 | $s-f-tiny-size: 10px; 11 | $s-f-small-size : 16px; 12 | $s-f-medium-size: 24px; 13 | $s-f-large-size : 32px; 14 | 15 | //****************** Color Scheme ******************** 16 | 17 | //Status Colors 18 | $s-c-error : #CE1126; //critical 19 | $s-c-warning: #E3642B; 20 | $s-c-alert : #FFCC00; 21 | $s-c-good : #6EA204; 22 | $s-c-info : #007cbb; 23 | 24 | //Text Colors 25 | $s-c-text : #333; // Main Text color used in most places 26 | $s-c-inverse-text : #eee; // Text Color used on contrasting backgrounds such as buttons/tabs 27 | $s-c-disable-text : gray; // Text Color used for displaying less emphasized text (eg:detail chart axis color) 28 | $s-c-link-text : #007cbb; 29 | 30 | //Backgrounds 31 | $s-bg-main : #ffffff; // Main Body Background Color 32 | $s-bg-soft-white : whitesmoke; // Alternate Body Background (Such as Windows, Panels, Dropdowns) 33 | $s-bg-inverse : #32404e; 34 | $s-bg-gray : rgb(250, 250, 250); 35 | $s-bg-white : #fff; 36 | 37 | //Borders 38 | $s-c-bd : #ccc; 39 | 40 | //Named Colors 41 | $s-c-white : #fff; 42 | $s-c-gray : gray; 43 | $s-c-soft-white : whitesmoke; 44 | $s-c-primary : #005d84; 45 | -------------------------------------------------------------------------------- /src/main/resources/public/data-table.b0aebd744ce7adb780a9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/resources/public/data-table.bce071e976865da51100.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/data-table.bce071e976865da51100.eot -------------------------------------------------------------------------------- /src/main/resources/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/public/index.html: -------------------------------------------------------------------------------- 1 | Web UILoading... -------------------------------------------------------------------------------- /src/main/resources/public/inline.1163a12954ba6efe8643.bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var u,i,f,l=0,s=[];l 2 | 3 | 4 | ReDoc 5 | 6 | 7 | 8 | 9 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/css/reset.css: -------------------------------------------------------------------------------- 1 | a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0} -------------------------------------------------------------------------------- /src/main/resources/public/swagger/css/typography.css: -------------------------------------------------------------------------------- 1 | html { 2 | overflow-x: hidden; 3 | border-spacing:0; 4 | margin:0; 5 | margin-right: calc(-1 * (100vw - 100%)); 6 | } 7 | 8 | @font-face { 9 | font-family: metropolis ; 10 | src: url(../fonts/Metropolis-Thin.otf); 11 | } 12 | @font-face { 13 | font-family: metropolis-reg ; 14 | src: url(../fonts/Metropolis-Regular.otf); 15 | } 16 | 17 | .path .toggleOperation {font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;} 18 | 19 | li.operation div.heading{ 20 | border-width: 2px !important; 21 | padding: 3px !important; 22 | } 23 | .markdown p{ 24 | font-family: metropolis-reg; 25 | } 26 | 27 | .http_method a{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;} 28 | 29 | #header #logo .logo__img{ 30 | margin-top:8px !important;; 31 | } 32 | 33 | .swagger-section #header{ 34 | padding: 10px !important; 35 | background-color:whitesmoke !important; 36 | height:36px !important; 37 | 38 | } 39 | #auth_container{ 40 | width:auto !important; 41 | height:auto !important; 42 | padding:0 2px; 43 | } 44 | #auth_container .authorize__btn, .header__btn{ 45 | padding: 8px !important; 46 | border-radius:2px !important; 47 | background-color:#ff6c0c !important; 48 | font-family: metropolis-reg !important; 49 | 50 | 51 | } 52 | .swagger-section #api_selector input{ 53 | padding:5px !important; 54 | border: 2px solid orange; 55 | border-radius: 2px; 56 | } 57 | a:hover{ 58 | text-decoration:none !important; 59 | } 60 | 61 | #header{ 62 | box-shadow: 0 3px 5px rgba(57, 63, 72, 0.3); 63 | } -------------------------------------------------------------------------------- /src/main/resources/public/swagger/fonts/DroidSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/fonts/DroidSans-Bold.ttf -------------------------------------------------------------------------------- /src/main/resources/public/swagger/fonts/DroidSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/fonts/DroidSans.ttf -------------------------------------------------------------------------------- /src/main/resources/public/swagger/fonts/Metropolis-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/fonts/Metropolis-Regular.otf -------------------------------------------------------------------------------- /src/main/resources/public/swagger/fonts/Metropolis-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/fonts/Metropolis-Thin.otf -------------------------------------------------------------------------------- /src/main/resources/public/swagger/images/collapse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/images/collapse.gif -------------------------------------------------------------------------------- /src/main/resources/public/swagger/images/expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/images/expand.gif -------------------------------------------------------------------------------- /src/main/resources/public/swagger/images/explorer_icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/images/explorer_icons.png -------------------------------------------------------------------------------- /src/main/resources/public/swagger/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/images/throbber.gif -------------------------------------------------------------------------------- /src/main/resources/public/swagger/images/wordnik_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/src/main/resources/public/swagger/images/wordnik_api.png -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/ca.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Advertència: Obsolet", 6 | "Implementation Notes":"Notes d'implementació", 7 | "Response Class":"Classe de la Resposta", 8 | "Status":"Estatus", 9 | "Parameters":"Paràmetres", 10 | "Parameter":"Paràmetre", 11 | "Value":"Valor", 12 | "Description":"Descripció", 13 | "Parameter Type":"Tipus del Paràmetre", 14 | "Data Type":"Tipus de la Dada", 15 | "Response Messages":"Missatges de la Resposta", 16 | "HTTP Status Code":"Codi d'Estatus HTTP", 17 | "Reason":"Raó", 18 | "Response Model":"Model de la Resposta", 19 | "Request URL":"URL de la Sol·licitud", 20 | "Response Body":"Cos de la Resposta", 21 | "Response Code":"Codi de la Resposta", 22 | "Response Headers":"Capçaleres de la Resposta", 23 | "Hide Response":"Amagar Resposta", 24 | "Try it out!":"Prova-ho!", 25 | "Show/Hide":"Mostrar/Amagar", 26 | "List Operations":"Llista Operacions", 27 | "Expand Operations":"Expandir Operacions", 28 | "Raw":"Cru", 29 | "can't parse JSON. Raw result":"no puc analitzar el JSON. Resultat cru", 30 | "Example Value":"Valor d'Exemple", 31 | "Model Schema":"Esquema del Model", 32 | "Model":"Model", 33 | "apply":"aplicar", 34 | "Username":"Nom d'usuari", 35 | "Password":"Contrasenya", 36 | "Terms of service":"Termes del servei", 37 | "Created by":"Creat per", 38 | "See more at":"Veure més en", 39 | "Contact the developer":"Contactar amb el desenvolupador", 40 | "api version":"versió de la api", 41 | "Response Content Type":"Tipus de Contingut de la Resposta", 42 | "fetching resource":"recollint recurs", 43 | "fetching resource list":"recollins llista de recursos", 44 | "Explore":"Explorant", 45 | "Show Swagger Petstore Example Apis":"Mostrar API d'Exemple Swagger Petstore", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"No es pot llegir del servidor. Potser no teniu la configuració de control d'accés apropiada.", 47 | "Please specify the protocol for":"Si us plau, especifiqueu el protocol per a", 48 | "Can't read swagger JSON from":"No es pot llegir el JSON de swagger des de", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Finalitzada la càrrega del recurs informatiu. Renderitzant Swagger UI", 50 | "Unable to read api":"No es pot llegir l'api", 51 | "from path":"des de la ruta", 52 | "server returned":"el servidor ha retornat" 53 | }); 54 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/el.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Προειδοποίηση: Έχει αποσυρθεί", 6 | "Implementation Notes":"Σημειώσεις Υλοποίησης", 7 | "Response Class":"Απόκριση", 8 | "Status":"Κατάσταση", 9 | "Parameters":"Παράμετροι", 10 | "Parameter":"Παράμετρος", 11 | "Value":"Τιμή", 12 | "Description":"Περιγραφή", 13 | "Parameter Type":"Τύπος Παραμέτρου", 14 | "Data Type":"Τύπος Δεδομένων", 15 | "Response Messages":"Μηνύματα Απόκρισης", 16 | "HTTP Status Code":"Κωδικός Κατάστασης HTTP", 17 | "Reason":"Αιτιολογία", 18 | "Response Model":"Μοντέλο Απόκρισης", 19 | "Request URL":"URL Αιτήματος", 20 | "Response Body":"Σώμα Απόκρισης", 21 | "Response Code":"Κωδικός Απόκρισης", 22 | "Response Headers":"Επικεφαλίδες Απόκρισης", 23 | "Hide Response":"Απόκρυψη Απόκρισης", 24 | "Headers":"Επικεφαλίδες", 25 | "Try it out!":"Δοκιμάστε το!", 26 | "Show/Hide":"Εμφάνιση/Απόκρυψη", 27 | "List Operations":"Λίστα Λειτουργιών", 28 | "Expand Operations":"Ανάπτυξη Λειτουργιών", 29 | "Raw":"Ακατέργαστο", 30 | "can't parse JSON. Raw result":"αδυναμία ανάλυσης JSON. Ακατέργαστο αποτέλεσμα", 31 | "Example Value":"Παράδειγμα Τιμής", 32 | "Model Schema":"Σχήμα Μοντέλου", 33 | "Model":"Μοντέλο", 34 | "Click to set as parameter value":"Πατήστε για να θέσετε τιμή παραμέτρου", 35 | "apply":"εφαρμογή", 36 | "Username":"Όνομα χρήση", 37 | "Password":"Κωδικός πρόσβασης", 38 | "Terms of service":"Όροι χρήσης", 39 | "Created by":"Δημιουργήθηκε από", 40 | "See more at":"Δείτε περισσότερα στο", 41 | "Contact the developer":"Επικοινωνήστε με τον προγραμματιστή", 42 | "api version":"έκδοση api", 43 | "Response Content Type":"Τύπος Περιεχομένου Απόκρισης", 44 | "Parameter content type:":"Τύπος περιεχομένου παραμέτρου:", 45 | "fetching resource":"παραλαβή πόρου", 46 | "fetching resource list":"παραλαβή λίστας πόρων", 47 | "Explore":"Εξερεύνηση", 48 | "Show Swagger Petstore Example Apis":"Εμφάνιση Api Δειγμάτων Petstore του Swagger", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Αδυναμία ανάγνωσης από τον εξυπηρετητή. Μπορεί να μην έχει κατάλληλες ρυθμίσεις για access-control-origin.", 50 | "Please specify the protocol for":"Παρακαλώ προσδιορίστε το πρωτόκολλο για", 51 | "Can't read swagger JSON from":"Αδυναμία ανάγνωσης swagger JSON από", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"Ολοκλήρωση Φόρτωσης Πληροφορικών Πόρου. Παρουσίαση Swagger UI", 53 | "Unable to read api":"Αδυναμία ανάγνωσης api", 54 | "from path":"από το μονοπάτι", 55 | "server returned":"ο εξυπηρετηρής επέστρεψε" 56 | }); 57 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/en.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Warning: Deprecated", 6 | "Implementation Notes":"Implementation Notes", 7 | "Response Class":"Response Class", 8 | "Status":"Status", 9 | "Parameters":"Parameters", 10 | "Parameter":"Parameter", 11 | "Value":"Value", 12 | "Description":"Description", 13 | "Parameter Type":"Parameter Type", 14 | "Data Type":"Data Type", 15 | "Response Messages":"Response Messages", 16 | "HTTP Status Code":"HTTP Status Code", 17 | "Reason":"Reason", 18 | "Response Model":"Response Model", 19 | "Request URL":"Request URL", 20 | "Response Body":"Response Body", 21 | "Response Code":"Response Code", 22 | "Response Headers":"Response Headers", 23 | "Hide Response":"Hide Response", 24 | "Headers":"Headers", 25 | "Try it out!":"Try it out!", 26 | "Show/Hide":"Show/Hide", 27 | "List Operations":"List Operations", 28 | "Expand Operations":"Expand Operations", 29 | "Raw":"Raw", 30 | "can't parse JSON. Raw result":"can't parse JSON. Raw result", 31 | "Example Value":"Example Value", 32 | "Model Schema":"Model Schema", 33 | "Model":"Model", 34 | "Click to set as parameter value":"Click to set as parameter value", 35 | "apply":"apply", 36 | "Username":"Username", 37 | "Password":"Password", 38 | "Terms of service":"Terms of service", 39 | "Created by":"Created by", 40 | "See more at":"See more at", 41 | "Contact the developer":"Contact the developer", 42 | "api version":"api version", 43 | "Response Content Type":"Response Content Type", 44 | "Parameter content type:":"Parameter content type:", 45 | "fetching resource":"fetching resource", 46 | "fetching resource list":"fetching resource list", 47 | "Explore":"Explore", 48 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", 50 | "Please specify the protocol for":"Please specify the protocol for", 51 | "Can't read swagger JSON from":"Can't read swagger JSON from", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", 53 | "Unable to read api":"Unable to read api", 54 | "from path":"from path", 55 | "server returned":"server returned" 56 | }); 57 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/es.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Advertencia: Obsoleto", 6 | "Implementation Notes":"Notas de implementación", 7 | "Response Class":"Clase de la Respuesta", 8 | "Status":"Status", 9 | "Parameters":"Parámetros", 10 | "Parameter":"Parámetro", 11 | "Value":"Valor", 12 | "Description":"Descripción", 13 | "Parameter Type":"Tipo del Parámetro", 14 | "Data Type":"Tipo del Dato", 15 | "Response Messages":"Mensajes de la Respuesta", 16 | "HTTP Status Code":"Código de Status HTTP", 17 | "Reason":"Razón", 18 | "Response Model":"Modelo de la Respuesta", 19 | "Request URL":"URL de la Solicitud", 20 | "Response Body":"Cuerpo de la Respuesta", 21 | "Response Code":"Código de la Respuesta", 22 | "Response Headers":"Encabezados de la Respuesta", 23 | "Hide Response":"Ocultar Respuesta", 24 | "Try it out!":"Pruébalo!", 25 | "Show/Hide":"Mostrar/Ocultar", 26 | "List Operations":"Listar Operaciones", 27 | "Expand Operations":"Expandir Operaciones", 28 | "Raw":"Crudo", 29 | "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo", 30 | "Example Value":"Valor de Ejemplo", 31 | "Model Schema":"Esquema del Modelo", 32 | "Model":"Modelo", 33 | "apply":"aplicar", 34 | "Username":"Nombre de usuario", 35 | "Password":"Contraseña", 36 | "Terms of service":"Términos de Servicio", 37 | "Created by":"Creado por", 38 | "See more at":"Ver más en", 39 | "Contact the developer":"Contactar al desarrollador", 40 | "api version":"versión de la api", 41 | "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta", 42 | "fetching resource":"buscando recurso", 43 | "fetching resource list":"buscando lista del recurso", 44 | "Explore":"Explorar", 45 | "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.", 47 | "Please specify the protocol for":"Por favor, especificar el protocola para", 48 | "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI", 50 | "Unable to read api":"No se puede leer la api", 51 | "from path":"desde ruta", 52 | "server returned":"el servidor retornó" 53 | }); 54 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/fr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Avertissement : Obsolète", 6 | "Implementation Notes":"Notes d'implémentation", 7 | "Response Class":"Classe de la réponse", 8 | "Status":"Statut", 9 | "Parameters":"Paramètres", 10 | "Parameter":"Paramètre", 11 | "Value":"Valeur", 12 | "Description":"Description", 13 | "Parameter Type":"Type du paramètre", 14 | "Data Type":"Type de données", 15 | "Response Messages":"Messages de la réponse", 16 | "HTTP Status Code":"Code de statut HTTP", 17 | "Reason":"Raison", 18 | "Response Model":"Modèle de réponse", 19 | "Request URL":"URL appelée", 20 | "Response Body":"Corps de la réponse", 21 | "Response Code":"Code de la réponse", 22 | "Response Headers":"En-têtes de la réponse", 23 | "Hide Response":"Cacher la réponse", 24 | "Headers":"En-têtes", 25 | "Try it out!":"Testez !", 26 | "Show/Hide":"Afficher/Masquer", 27 | "List Operations":"Liste des opérations", 28 | "Expand Operations":"Développer les opérations", 29 | "Raw":"Brut", 30 | "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut", 31 | "Example Value":"Exemple la valeur", 32 | "Model Schema":"Définition du modèle", 33 | "Model":"Modèle", 34 | "apply":"appliquer", 35 | "Username":"Nom d'utilisateur", 36 | "Password":"Mot de passe", 37 | "Terms of service":"Conditions de service", 38 | "Created by":"Créé par", 39 | "See more at":"Voir plus sur", 40 | "Contact the developer":"Contacter le développeur", 41 | "api version":"version de l'api", 42 | "Response Content Type":"Content Type de la réponse", 43 | "fetching resource":"récupération de la ressource", 44 | "fetching resource list":"récupération de la liste de ressources", 45 | "Explore":"Explorer", 46 | "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger", 47 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.", 48 | "Please specify the protocol for":"Veuillez spécifier un protocole pour", 49 | "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de", 50 | "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI", 51 | "Unable to read api":"Impossible de lire l'api", 52 | "from path":"à partir du chemin", 53 | "server returned":"réponse du serveur" 54 | }); 55 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/geo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება", 6 | "Implementation Notes":"იმპლემენტაციის აღწერა", 7 | "Response Class":"რესპონს კლასი", 8 | "Status":"სტატუსი", 9 | "Parameters":"პარამეტრები", 10 | "Parameter":"პარამეტრი", 11 | "Value":"მნიშვნელობა", 12 | "Description":"აღწერა", 13 | "Parameter Type":"პარამეტრის ტიპი", 14 | "Data Type":"მონაცემის ტიპი", 15 | "Response Messages":"პასუხი", 16 | "HTTP Status Code":"HTTP სტატუსი", 17 | "Reason":"მიზეზი", 18 | "Response Model":"რესპონს მოდელი", 19 | "Request URL":"მოთხოვნის URL", 20 | "Response Body":"პასუხის სხეული", 21 | "Response Code":"პასუხის კოდი", 22 | "Response Headers":"პასუხის ჰედერები", 23 | "Hide Response":"დამალე პასუხი", 24 | "Headers":"ჰედერები", 25 | "Try it out!":"ცადე !", 26 | "Show/Hide":"გამოჩენა/დამალვა", 27 | "List Operations":"ოპერაციების სია", 28 | "Expand Operations":"ოპერაციები ვრცლად", 29 | "Raw":"ნედლი", 30 | "can't parse JSON. Raw result":"JSON-ის დამუშავება ვერ მოხერხდა. ნედლი პასუხი", 31 | "Example Value":"მაგალითი", 32 | "Model Schema":"მოდელის სტრუქტურა", 33 | "Model":"მოდელი", 34 | "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე", 35 | "apply":"გამოყენება", 36 | "Username":"მოხმარებელი", 37 | "Password":"პაროლი", 38 | "Terms of service":"მომსახურების პირობები", 39 | "Created by":"შექმნა", 40 | "See more at":"ნახე ვრცლად", 41 | "Contact the developer":"დაუკავშირდი დეველოპერს", 42 | "api version":"api ვერსია", 43 | "Response Content Type":"პასუხის კონტენტის ტიპი", 44 | "Parameter content type:":"პარამეტრის კონტენტის ტიპი:", 45 | "fetching resource":"რესურსების მიღება", 46 | "fetching resource list":"რესურსების სიის მიღება", 47 | "Explore":"ნახვა", 48 | "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება. შეამოწმეთ access-control-origin.", 50 | "Please specify the protocol for":"მიუთითეთ პროტოკოლი", 51 | "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება", 53 | "Unable to read api":"api წაკითხვა ვერ მოხერხდა", 54 | "from path":"მისამართიდან", 55 | "server returned":"სერვერმა დააბრუნა" 56 | }); 57 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/it.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Attenzione: Deprecato", 6 | "Implementation Notes":"Note di implementazione", 7 | "Response Class":"Classe della risposta", 8 | "Status":"Stato", 9 | "Parameters":"Parametri", 10 | "Parameter":"Parametro", 11 | "Value":"Valore", 12 | "Description":"Descrizione", 13 | "Parameter Type":"Tipo di parametro", 14 | "Data Type":"Tipo di dato", 15 | "Response Messages":"Messaggi della risposta", 16 | "HTTP Status Code":"Codice stato HTTP", 17 | "Reason":"Motivo", 18 | "Response Model":"Modello di risposta", 19 | "Request URL":"URL della richiesta", 20 | "Response Body":"Corpo della risposta", 21 | "Response Code":"Oggetto della risposta", 22 | "Response Headers":"Intestazioni della risposta", 23 | "Hide Response":"Nascondi risposta", 24 | "Try it out!":"Provalo!", 25 | "Show/Hide":"Mostra/Nascondi", 26 | "List Operations":"Mostra operazioni", 27 | "Expand Operations":"Espandi operazioni", 28 | "Raw":"Grezzo (raw)", 29 | "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).", 30 | "Model Schema":"Schema del modello", 31 | "Model":"Modello", 32 | "apply":"applica", 33 | "Username":"Nome utente", 34 | "Password":"Password", 35 | "Terms of service":"Condizioni del servizio", 36 | "Created by":"Creato da", 37 | "See more at":"Informazioni aggiuntive:", 38 | "Contact the developer":"Contatta lo sviluppatore", 39 | "api version":"versione api", 40 | "Response Content Type":"Tipo di contenuto (content type) della risposta", 41 | "fetching resource":"recuperando la risorsa", 42 | "fetching resource list":"recuperando lista risorse", 43 | "Explore":"Esplora", 44 | "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore", 45 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.", 46 | "Please specify the protocol for":"Si prega di specificare il protocollo per", 47 | "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:", 48 | "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata", 49 | "Unable to read api":"Impossibile leggere la api", 50 | "from path":"da cartella", 51 | "server returned":"il server ha restituito" 52 | }); 53 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/ja.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"警告: 廃止予定", 6 | "Implementation Notes":"実装メモ", 7 | "Response Class":"レスポンスクラス", 8 | "Status":"ステータス", 9 | "Parameters":"パラメータ群", 10 | "Parameter":"パラメータ", 11 | "Value":"値", 12 | "Description":"説明", 13 | "Parameter Type":"パラメータタイプ", 14 | "Data Type":"データタイプ", 15 | "Response Messages":"レスポンスメッセージ", 16 | "HTTP Status Code":"HTTPステータスコード", 17 | "Reason":"理由", 18 | "Response Model":"レスポンスモデル", 19 | "Request URL":"リクエストURL", 20 | "Response Body":"レスポンスボディ", 21 | "Response Code":"レスポンスコード", 22 | "Response Headers":"レスポンスヘッダ", 23 | "Hide Response":"レスポンスを隠す", 24 | "Headers":"ヘッダ", 25 | "Try it out!":"実際に実行!", 26 | "Show/Hide":"表示/非表示", 27 | "List Operations":"操作一覧", 28 | "Expand Operations":"操作の展開", 29 | "Raw":"未加工", 30 | "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果", 31 | "Example Value":"値の例", 32 | "Model Schema":"モデルスキーマ", 33 | "Model":"モデル", 34 | "Click to set as parameter value":"パラメータ値と設定するにはクリック", 35 | "apply":"実行", 36 | "Username":"ユーザ名", 37 | "Password":"パスワード", 38 | "Terms of service":"サービス利用規約", 39 | "Created by":"Created by", 40 | "See more at":"詳細を見る", 41 | "Contact the developer":"開発者に連絡", 42 | "api version":"APIバージョン", 43 | "Response Content Type":"レスポンス コンテンツタイプ", 44 | "Parameter content type:":"パラメータコンテンツタイプ:", 45 | "fetching resource":"リソースの取得", 46 | "fetching resource list":"リソース一覧の取得", 47 | "Explore":"調査", 48 | "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.", 50 | "Please specify the protocol for":"プロトコルを指定してください", 51 | "Can't read swagger JSON from":"次からswagger JSONを読み込めません", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています", 53 | "Unable to read api":"APIを読み込めません", 54 | "from path":"次のパスから", 55 | "server returned":"サーバからの返答" 56 | }); 57 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/ko-kr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"경고:폐기예정됨", 6 | "Implementation Notes":"구현 노트", 7 | "Response Class":"응답 클래스", 8 | "Status":"상태", 9 | "Parameters":"매개변수들", 10 | "Parameter":"매개변수", 11 | "Value":"값", 12 | "Description":"설명", 13 | "Parameter Type":"매개변수 타입", 14 | "Data Type":"데이터 타입", 15 | "Response Messages":"응답 메세지", 16 | "HTTP Status Code":"HTTP 상태 코드", 17 | "Reason":"원인", 18 | "Response Model":"응답 모델", 19 | "Request URL":"요청 URL", 20 | "Response Body":"응답 본문", 21 | "Response Code":"응답 코드", 22 | "Response Headers":"응답 헤더", 23 | "Hide Response":"응답 숨기기", 24 | "Headers":"헤더", 25 | "Try it out!":"써보기!", 26 | "Show/Hide":"보이기/숨기기", 27 | "List Operations":"목록 작업", 28 | "Expand Operations":"전개 작업", 29 | "Raw":"원본", 30 | "can't parse JSON. Raw result":"JSON을 파싱할수 없음. 원본결과:", 31 | "Model Schema":"모델 스키마", 32 | "Model":"모델", 33 | "apply":"적용", 34 | "Username":"사용자 이름", 35 | "Password":"암호", 36 | "Terms of service":"이용약관", 37 | "Created by":"작성자", 38 | "See more at":"추가정보:", 39 | "Contact the developer":"개발자에게 문의", 40 | "api version":"api버전", 41 | "Response Content Type":"응답Content Type", 42 | "fetching resource":"리소스 가져오기", 43 | "fetching resource list":"리소스 목록 가져오기", 44 | "Explore":"탐색", 45 | "Show Swagger Petstore Example Apis":"Swagger Petstore 예제 보기", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"서버로부터 읽어들일수 없습니다. access-control-origin 설정이 올바르지 않을수 있습니다.", 47 | "Please specify the protocol for":"다음을 위한 프로토콜을 정하세요", 48 | "Can't read swagger JSON from":"swagger JSON 을 다음으로 부터 읽을수 없습니다", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"리소스 정보 불러오기 완료. Swagger UI 랜더링", 50 | "Unable to read api":"api를 읽을 수 없습니다.", 51 | "from path":"다음 경로로 부터", 52 | "server returned":"서버 응답함." 53 | }); 54 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/pl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Uwaga: Wycofane", 6 | "Implementation Notes":"Uwagi Implementacji", 7 | "Response Class":"Klasa Odpowiedzi", 8 | "Status":"Status", 9 | "Parameters":"Parametry", 10 | "Parameter":"Parametr", 11 | "Value":"Wartość", 12 | "Description":"Opis", 13 | "Parameter Type":"Typ Parametru", 14 | "Data Type":"Typ Danych", 15 | "Response Messages":"Wiadomości Odpowiedzi", 16 | "HTTP Status Code":"Kod Statusu HTTP", 17 | "Reason":"Przyczyna", 18 | "Response Model":"Model Odpowiedzi", 19 | "Request URL":"URL Wywołania", 20 | "Response Body":"Treść Odpowiedzi", 21 | "Response Code":"Kod Odpowiedzi", 22 | "Response Headers":"Nagłówki Odpowiedzi", 23 | "Hide Response":"Ukryj Odpowiedź", 24 | "Headers":"Nagłówki", 25 | "Try it out!":"Wypróbuj!", 26 | "Show/Hide":"Pokaż/Ukryj", 27 | "List Operations":"Lista Operacji", 28 | "Expand Operations":"Rozwiń Operacje", 29 | "Raw":"Nieprzetworzone", 30 | "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane", 31 | "Model Schema":"Schemat Modelu", 32 | "Model":"Model", 33 | "apply":"użyj", 34 | "Username":"Nazwa użytkownika", 35 | "Password":"Hasło", 36 | "Terms of service":"Warunki używania", 37 | "Created by":"Utworzone przez", 38 | "See more at":"Zobacz więcej na", 39 | "Contact the developer":"Kontakt z deweloperem", 40 | "api version":"wersja api", 41 | "Response Content Type":"Typ Zasobu Odpowiedzi", 42 | "fetching resource":"ładowanie zasobu", 43 | "fetching resource list":"ładowanie listy zasobów", 44 | "Explore":"Eksploruj", 45 | "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.", 47 | "Please specify the protocol for":"Proszę podać protokół dla", 48 | "Can't read swagger JSON from":"Nie można odczytać swagger JSON z", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI", 50 | "Unable to read api":"Nie można odczytać api", 51 | "from path":"ze ścieżki", 52 | "server returned":"serwer zwrócił" 53 | }); 54 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/pt.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Aviso: Depreciado", 6 | "Implementation Notes":"Notas de Implementação", 7 | "Response Class":"Classe de resposta", 8 | "Status":"Status", 9 | "Parameters":"Parâmetros", 10 | "Parameter":"Parâmetro", 11 | "Value":"Valor", 12 | "Description":"Descrição", 13 | "Parameter Type":"Tipo de parâmetro", 14 | "Data Type":"Tipo de dados", 15 | "Response Messages":"Mensagens de resposta", 16 | "HTTP Status Code":"Código de status HTTP", 17 | "Reason":"Razão", 18 | "Response Model":"Modelo resposta", 19 | "Request URL":"URL requisição", 20 | "Response Body":"Corpo da resposta", 21 | "Response Code":"Código da resposta", 22 | "Response Headers":"Cabeçalho da resposta", 23 | "Headers":"Cabeçalhos", 24 | "Hide Response":"Esconder resposta", 25 | "Try it out!":"Tente agora!", 26 | "Show/Hide":"Mostrar/Esconder", 27 | "List Operations":"Listar operações", 28 | "Expand Operations":"Expandir operações", 29 | "Raw":"Cru", 30 | "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru", 31 | "Model Schema":"Modelo esquema", 32 | "Model":"Modelo", 33 | "apply":"Aplicar", 34 | "Username":"Usuário", 35 | "Password":"Senha", 36 | "Terms of service":"Termos do serviço", 37 | "Created by":"Criado por", 38 | "See more at":"Veja mais em", 39 | "Contact the developer":"Contate o desenvolvedor", 40 | "api version":"Versão api", 41 | "Response Content Type":"Tipo de conteúdo da resposta", 42 | "fetching resource":"busca recurso", 43 | "fetching resource list":"buscando lista de recursos", 44 | "Explore":"Explorar", 45 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin", 47 | "Please specify the protocol for":"Por favor especifique o protocolo", 48 | "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI", 50 | "Unable to read api":"Não foi possível ler api", 51 | "from path":"do caminho", 52 | "server returned":"servidor retornou" 53 | }); 54 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/ru.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Предупреждение: Устарело", 6 | "Implementation Notes":"Заметки", 7 | "Response Class":"Пример ответа", 8 | "Status":"Статус", 9 | "Parameters":"Параметры", 10 | "Parameter":"Параметр", 11 | "Value":"Значение", 12 | "Description":"Описание", 13 | "Parameter Type":"Тип параметра", 14 | "Data Type":"Тип данных", 15 | "HTTP Status Code":"HTTP код", 16 | "Reason":"Причина", 17 | "Response Model":"Структура ответа", 18 | "Request URL":"URL запроса", 19 | "Response Body":"Тело ответа", 20 | "Response Code":"HTTP код ответа", 21 | "Response Headers":"Заголовки ответа", 22 | "Hide Response":"Спрятать ответ", 23 | "Headers":"Заголовки", 24 | "Response Messages":"Что может прийти в ответ", 25 | "Try it out!":"Попробовать!", 26 | "Show/Hide":"Показать/Скрыть", 27 | "List Operations":"Операции кратко", 28 | "Expand Operations":"Операции подробно", 29 | "Raw":"В сыром виде", 30 | "can't parse JSON. Raw result":"Не удается распарсить ответ:", 31 | "Example Value":"Пример", 32 | "Model Schema":"Структура", 33 | "Model":"Описание", 34 | "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра", 35 | "apply":"применить", 36 | "Username":"Имя пользователя", 37 | "Password":"Пароль", 38 | "Terms of service":"Условия использования", 39 | "Created by":"Разработано", 40 | "See more at":"Еще тут", 41 | "Contact the developer":"Связаться с разработчиком", 42 | "api version":"Версия API", 43 | "Response Content Type":"Content Type ответа", 44 | "Parameter content type:":"Content Type параметра:", 45 | "fetching resource":"Получение ресурса", 46 | "fetching resource list":"Получение ресурсов", 47 | "Explore":"Показать", 48 | "Show Swagger Petstore Example Apis":"Показать примеры АПИ", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа", 50 | "Please specify the protocol for":"Пожалуйста, укажите протокол для", 51 | "Can't read swagger JSON from":"Не получается прочитать swagger json из", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим", 53 | "Unable to read api":"Не удалось прочитать api", 54 | "from path":"по адресу", 55 | "server returned":"сервер сказал" 56 | }); 57 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/tr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Uyarı: Deprecated", 6 | "Implementation Notes":"Gerçekleştirim Notları", 7 | "Response Class":"Dönen Sınıf", 8 | "Status":"Statü", 9 | "Parameters":"Parametreler", 10 | "Parameter":"Parametre", 11 | "Value":"Değer", 12 | "Description":"Açıklama", 13 | "Parameter Type":"Parametre Tipi", 14 | "Data Type":"Veri Tipi", 15 | "Response Messages":"Dönüş Mesajı", 16 | "HTTP Status Code":"HTTP Statü Kodu", 17 | "Reason":"Gerekçe", 18 | "Response Model":"Dönüş Modeli", 19 | "Request URL":"İstek URL", 20 | "Response Body":"Dönüş İçeriği", 21 | "Response Code":"Dönüş Kodu", 22 | "Response Headers":"Dönüş Üst Bilgileri", 23 | "Hide Response":"Dönüşü Gizle", 24 | "Headers":"Üst Bilgiler", 25 | "Try it out!":"Dene!", 26 | "Show/Hide":"Göster/Gizle", 27 | "List Operations":"Operasyonları Listele", 28 | "Expand Operations":"Operasyonları Aç", 29 | "Raw":"Ham", 30 | "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç", 31 | "Model Schema":"Model Şema", 32 | "Model":"Model", 33 | "apply":"uygula", 34 | "Username":"Kullanıcı Adı", 35 | "Password":"Parola", 36 | "Terms of service":"Servis şartları", 37 | "Created by":"Oluşturan", 38 | "See more at":"Daha fazlası için", 39 | "Contact the developer":"Geliştirici ile İletişime Geçin", 40 | "api version":"api versiyon", 41 | "Response Content Type":"Dönüş İçerik Tipi", 42 | "fetching resource":"kaynak getiriliyor", 43 | "fetching resource list":"kaynak listesi getiriliyor", 44 | "Explore":"Keşfet", 45 | "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.", 47 | "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz", 48 | "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor", 50 | "Unable to read api":"api okunamadı", 51 | "from path":"yoldan", 52 | "server returned":"sunucuya dönüldü" 53 | }); 54 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/translator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Translator for documentation pages. 5 | * 6 | * To enable translation you should include one of language-files in your index.html 7 | * after . 8 | * For example - 9 | * 10 | * If you wish to translate some new texts you should do two things: 11 | * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. 12 | * 2. Mark that text it templates this way New Phrase or . 13 | * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. 14 | * 15 | */ 16 | window.SwaggerTranslator = { 17 | 18 | _words:[], 19 | 20 | translate: function(sel) { 21 | var $this = this; 22 | sel = sel || '[data-sw-translate]'; 23 | 24 | $(sel).each(function() { 25 | $(this).html($this._tryTranslate($(this).html())); 26 | 27 | $(this).val($this._tryTranslate($(this).val())); 28 | $(this).attr('title', $this._tryTranslate($(this).attr('title'))); 29 | }); 30 | }, 31 | 32 | _tryTranslate: function(word) { 33 | return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; 34 | }, 35 | 36 | learn: function(wordsMap) { 37 | this._words = wordsMap; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lang/zh-cn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"警告:已过时", 6 | "Implementation Notes":"实现备注", 7 | "Response Class":"响应类", 8 | "Status":"状态", 9 | "Parameters":"参数", 10 | "Parameter":"参数", 11 | "Value":"值", 12 | "Description":"描述", 13 | "Parameter Type":"参数类型", 14 | "Data Type":"数据类型", 15 | "Response Messages":"响应消息", 16 | "HTTP Status Code":"HTTP状态码", 17 | "Reason":"原因", 18 | "Response Model":"响应模型", 19 | "Request URL":"请求URL", 20 | "Response Body":"响应体", 21 | "Response Code":"响应码", 22 | "Response Headers":"响应头", 23 | "Hide Response":"隐藏响应", 24 | "Headers":"头", 25 | "Try it out!":"试一下!", 26 | "Show/Hide":"显示/隐藏", 27 | "List Operations":"显示操作", 28 | "Expand Operations":"展开操作", 29 | "Raw":"原始", 30 | "can't parse JSON. Raw result":"无法解析JSON. 原始结果", 31 | "Example Value":"示例", 32 | "Click to set as parameter value":"点击设置参数", 33 | "Model Schema":"模型架构", 34 | "Model":"模型", 35 | "apply":"应用", 36 | "Username":"用户名", 37 | "Password":"密码", 38 | "Terms of service":"服务条款", 39 | "Created by":"创建者", 40 | "See more at":"查看更多:", 41 | "Contact the developer":"联系开发者", 42 | "api version":"api版本", 43 | "Response Content Type":"响应Content Type", 44 | "Parameter content type:":"参数类型:", 45 | "fetching resource":"正在获取资源", 46 | "fetching resource list":"正在获取资源列表", 47 | "Explore":"浏览", 48 | "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", 50 | "Please specify the protocol for":"请指定协议:", 51 | "Can't read swagger JSON from":"无法读取swagger JSON于", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", 53 | "Unable to read api":"无法读取api", 54 | "from path":"从路径", 55 | "server returned":"服务器返回" 56 | }); 57 | -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lib/highlight.9.1.0.pack_extended.js: -------------------------------------------------------------------------------- 1 | "use strict";!function(){var h,l;h=hljs.configure,hljs.configure=function(l){var i=l.highlightSizeThreshold;hljs.highlightSizeThreshold=i===+i?i:null,h.call(this,l)},l=hljs.highlightBlock,hljs.highlightBlock=function(h){var i=h.innerHTML,g=hljs.highlightSizeThreshold;(null==g||g>i.length)&&l.call(hljs,h)}}(); -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lib/jquery.slideto.min.js: -------------------------------------------------------------------------------- 1 | !function(i){i.fn.slideto=function(o){return o=i.extend({slide_duration:"slow",highlight_duration:3e3,highlight:!0,highlight_color:"#FFFF99"},o),this.each(function(){obj=i(this),i("body").animate({scrollTop:obj.offset().top},o.slide_duration,function(){o.highlight&&i.ui.version&&obj.effect("highlight",{color:o.highlight_color},o.highlight_duration)})})}}(jQuery); -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lib/jquery.wiggle.min.js: -------------------------------------------------------------------------------- 1 | jQuery.fn.wiggle=function(e){var a={speed:50,wiggles:3,travel:5,callback:null},e=jQuery.extend(a,e);return this.each(function(){var a=this,l=(jQuery(this).wrap('
').css("position","relative"),0);for(i=1;i<=e.wiggles;i++)jQuery(this).animate({left:"-="+e.travel},e.speed).animate({left:"+="+2*e.travel},2*e.speed).animate({left:"-="+e.travel},e.speed,function(){l++,jQuery(a).parent().hasClass("wiggle-wrap")&&jQuery(a).parent().replaceWith(a),l==e.wiggles&&jQuery.isFunction(e.callback)&&e.callback()})})}; -------------------------------------------------------------------------------- /src/main/resources/public/swagger/lib/object-assign-pollyfill.js: -------------------------------------------------------------------------------- 1 | "function"!=typeof Object.assign&&!function(){Object.assign=function(n){"use strict";if(void 0===n||null===n)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(n),o=1;o 2 | var qp = null; 3 | if(/code|token|error/.test(window.location.hash)) { 4 | qp = location.hash.substring(1); 5 | } 6 | else { 7 | qp = location.search.substring(1); 8 | } 9 | qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}', 10 | function(key, value) { 11 | return key===""?value:decodeURIComponent(value) } 12 | ):{} 13 | 14 | if (window.opener.swaggerUiAuth.tokenUrl) 15 | window.opener.processOAuthCode(qp); 16 | else 17 | window.opener.onOAuthComplete(qp); 18 | 19 | window.close(); 20 | 21 | -------------------------------------------------------------------------------- /webui/.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "Mrin WebUI" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "tsconfig": "tsconfig.json", 18 | "prefix": "app", 19 | "styles": [ 20 | "styles.scss", 21 | "../node_modules/@clr/icons/clr-icons.min.css", 22 | "../node_modules/@clr/ui/clr-ui.min.css", 23 | "../node_modules/@swimlane/ngx-datatable/release/assets/icons.css" 24 | ], 25 | "scripts": [ 26 | "../node_modules/@webcomponents/custom-elements/custom-elements.min.js", 27 | "../node_modules/@clr/icons/clr-icons.min.js" 28 | ], 29 | "environmentSource": "environments/environment.ts", 30 | "environments": { 31 | "dev": "environments/environment.ts", 32 | "prod": "environments/environment.prod.ts" 33 | } 34 | } 35 | ], 36 | "lint": [ 37 | { 38 | "files": "src/**/*.ts", 39 | "project": "src/tsconfig.json" 40 | } 41 | ], 42 | "defaults": { 43 | "styleExt": "scss", 44 | "component": { 45 | "viewEncapsulation": "Emulated" 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /webui/dist/assets/css/sonicglyph.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'sonicglyph'; 3 | src: url('../fonts/sonicglyph.woff') format('woff'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | .s-glyph { 8 | display: inline-block; 9 | font: normal normal normal 16px/1 sonicglyph; 10 | font-size: inherit; 11 | text-rendering: auto; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | -------------------------------------------------------------------------------- /webui/dist/assets/fonts/OpenSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/assets/fonts/OpenSans-Italic.woff -------------------------------------------------------------------------------- /webui/dist/assets/fonts/OpenSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/assets/fonts/OpenSans-Regular.woff -------------------------------------------------------------------------------- /webui/dist/assets/fonts/OpenSans-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/assets/fonts/OpenSans-Semibold.woff -------------------------------------------------------------------------------- /webui/dist/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /webui/dist/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /webui/dist/assets/scss/_base.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-size:12px; 3 | font-weight: normal; 4 | overflow: auto; 5 | margin:0; 6 | padding:0; 7 | } 8 | 9 | /* 10 | h1 { font:$s-f1-size $s-f-family;font-weight:600 } 11 | h2 { font:$s-f2-size $s-f-family;font-weight:600 } 12 | h3 { font:$s-f3-size $s-f-family;font-weight:600 } 13 | h4 { font:$s-f4-size $s-f-family;font-weight:600 } 14 | h5 { font:$s-f5-size $s-f-family;font-weight:600 } 15 | h6 { font:$s-f6-size $s-f-family;font-weight:600 } 16 | */ 17 | 18 | //.s-f {font-family: $s-f-family;} 19 | .s-f1 { font:$s-f1-size;} 20 | .s-f2 { font:$s-f2-size;} 21 | .s-f3 { font:$s-f3-size;} 22 | .s-f4 { font:$s-f4-size;} 23 | .s-f5 { font:$s-f5-size;} 24 | .s-f6 { font:$s-f6-size;} 25 | 26 | .s-f-tiny { font-size:$s-f-tiny-size;} 27 | .s-f-body { font-size:$s-f-body-size;} 28 | .s-f-small { font-size:$s-f-small-size;} 29 | .s-f-medium { font-size:$s-f-medium-size;} 30 | .s-f-large { font-size:$s-f-large-size;} 31 | 32 | .s-bold-500 { font-weight: 500; } 33 | .s-bold-600 { font-weight: 600; } 34 | .s-bold { font-weight: bold; } // weight:700 35 | 36 | .s-c-text { color: $s-c-text; } 37 | .s-c-inverse-text { color: $s-c-inverse-text; } 38 | .s-c-disable-text { color: $s-c-disable-text; } 39 | 40 | .s-c-white { color: $s-c-white; } 41 | .s-c-gray { color: $s-c-gray; } 42 | .s-c-primary { color: $s-c-primary; } 43 | .s-c-info { color: $s-c-info; } 44 | .s-c-error { color: $s-c-error; } 45 | .s-c-warning { color: $s-c-warning; } 46 | .s-c-good { color: $s-c-good; } 47 | 48 | .s-bg-main { background-color: $s-bg-main; } 49 | .s-bg-inverse { background-color: $s-bg-inverse; } 50 | .s-bg-soft-white { background-color: $s-bg-soft-white;} 51 | .s-bg-info { background-color: $s-c-info; } 52 | .s-bg-error { background-color: $s-c-error; } 53 | .s-bg-warning { background-color: $s-c-warning; } 54 | .s-bg-good { background-color: $s-c-good; } 55 | 56 | .s-shadow-1 { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); } 57 | .s-shadow-2 { box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } 58 | .s-shadow-3 { box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } 59 | .s-shadow-4 { box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); } 60 | .s-shadow-5 { box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22); } 61 | 62 | .s-hidden { display: none;} 63 | .s-ellipses { text-overflow: ellipsis;overflow: hidden;} 64 | .s-nowrap { white-space: nowrap;} 65 | .s-err-msg { color: $s-c-error;} 66 | .s-link { color :$s-c-link-text;cursor:pointer;text-decoration: none;} 67 | .s-link:hover { text-decoration: underline;} 68 | 69 | //Padding 70 | .pad-16{ padding:16px;} 71 | .no-margin{ padding:0; margin:0} 72 | 73 | //Align 74 | .s-hbox-align-right{ 75 | display: flex; 76 | justify-content: flex-end; 77 | flex-direction: row; 78 | } 79 | 80 | .s-hbox-align-left{ 81 | display: flex; 82 | justify-content: flex-start; 83 | flex-direction: row; 84 | } 85 | 86 | .s-hbox-align-center{ 87 | display: flex; 88 | justify-content: center; 89 | flex-direction: row; 90 | } 91 | -------------------------------------------------------------------------------- /webui/dist/assets/scss/_var.scss: -------------------------------------------------------------------------------- 1 | //Fonts 2 | $s-f-family: Metropolis,Avenir Next,Helvetica Neue,Arial,sans-serif; 3 | $s-f1-size: 24px; 4 | $s-f2-size: 20px; 5 | $s-f3-size: 18px; 6 | $s-f4-size: 16px; 7 | $s-f5-size: 14px; 8 | $s-f6-size: 12px; 9 | $s-f-body-size: 12px; 10 | $s-f-tiny-size: 10px; 11 | $s-f-small-size : 16px; 12 | $s-f-medium-size: 24px; 13 | $s-f-large-size : 32px; 14 | 15 | //****************** Color Scheme ******************** 16 | 17 | //Status Colors 18 | $s-c-error : #CE1126; //critical 19 | $s-c-warning: #E3642B; 20 | $s-c-alert : #FFCC00; 21 | $s-c-good : #6EA204; 22 | $s-c-info : #007cbb; 23 | 24 | //Text Colors 25 | $s-c-text : #333; // Main Text color used in most places 26 | $s-c-inverse-text : #eee; // Text Color used on contrasting backgrounds such as buttons/tabs 27 | $s-c-disable-text : gray; // Text Color used for displaying less emphasized text (eg:detail chart axis color) 28 | $s-c-link-text : #007cbb; 29 | 30 | //Backgrounds 31 | $s-bg-main : #ffffff; // Main Body Background Color 32 | $s-bg-soft-white : whitesmoke; // Alternate Body Background (Such as Windows, Panels, Dropdowns) 33 | $s-bg-inverse : #32404e; 34 | $s-bg-gray : rgb(250, 250, 250); 35 | $s-bg-white : #fff; 36 | 37 | //Borders 38 | $s-c-bd : #ccc; 39 | 40 | //Named Colors 41 | $s-c-white : #fff; 42 | $s-c-gray : gray; 43 | $s-c-soft-white : whitesmoke; 44 | $s-c-primary : #005d84; 45 | -------------------------------------------------------------------------------- /webui/dist/data-table.b0aebd744ce7adb780a9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /webui/dist/data-table.bce071e976865da51100.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/data-table.bce071e976865da51100.eot -------------------------------------------------------------------------------- /webui/dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/dist/favicon.ico -------------------------------------------------------------------------------- /webui/dist/index.html: -------------------------------------------------------------------------------- 1 | Web UILoading... -------------------------------------------------------------------------------- /webui/dist/inline.ea0d0509378aa3a4611b.bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var u,i,f,l=0,s=[];l` 5 | }) 6 | 7 | export class AppComponent { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /webui/src/app/components/badge/badge.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | @Component({ 3 | selector: 's-badge', 4 | template: `{{text}}` 5 | }) 6 | 7 | export class BadgeComponent implements OnInit { 8 | @Input() public text:string; 9 | @Input() public badgeCls:string; 10 | 11 | constructor() { } 12 | 13 | ngOnInit() { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /webui/src/app/components/legend/legend.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector : 's-legend', 5 | styleUrls: [ './legend.scss'], 6 | template : ` 7 |
8 |
9 |
10 |
11 |
{{l.value}}
12 |
{{l.name}}
13 |
14 |
15 |
16 | ` 17 | }) 18 | 19 | export class LegendComponent{ 20 | @Input() legend:any[]; 21 | } 22 | -------------------------------------------------------------------------------- /webui/src/app/components/legend/legend.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | .s-legend-wrap{ 3 | display:flex; 4 | flex-direction: row; 5 | margin:5px 0; 6 | .s-legend-item{ 7 | display:flex; 8 | flex-direction: row; 9 | height:32px; 10 | margin-right:20px; 11 | align-items:stretch; 12 | .s-legend-color{ 13 | width:5px; 14 | } 15 | .s-legend-value-wrap{ 16 | margin:0px 3px; 17 | } 18 | .s-legend-label{ 19 | font-size:12px; 20 | height:14px; 21 | line-height: 15px; 22 | } 23 | .s-legend-value{ 24 | font-size:18px; 25 | height:18px; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /webui/src/app/components/logo/logo.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | @Component({ 3 | selector: 's-logo', 4 | templateUrl: './logo.component.html' 5 | }) 6 | 7 | export class LogoComponent{ 8 | @Input() fontColor = "#63666A"; 9 | @Input() public iconColor: string = "#E3642B"; 10 | } 11 | -------------------------------------------------------------------------------- /webui/src/app/directives/track_scroll/track_scroll.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, OnInit, Input, Output, HostListener, EventEmitter, ElementRef ,Inject, Injectable} from '@angular/core'; 2 | import { DOCUMENT } from '@angular/common'; 3 | 4 | @Directive({ selector: '[trackScroll]' }) 5 | 6 | export class TrackScrollDirective { 7 | @Output() bottom = new EventEmitter(); 8 | constructor(@Inject(DOCUMENT) private document: Document) {} 9 | 10 | @HostListener('document:scroll', []) 11 | public track() { 12 | /* 13 | if (document.body.scrollHeight == window.scrollY + window.innerHeight) { 14 | this.bottom.emit(true); 15 | } 16 | */ 17 | if (Math.abs(document.body.scrollHeight - (window.scrollY + window.innerHeight)) <= 100){ 18 | this.bottom.emit(true); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /webui/src/app/home.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 8 |
9 |
10 | Alert Type: Info 11 |
12 |
13 | 14 |
15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 | 23 | SprinGular 24 |
25 |
26 | {{ header.label }} 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 | 35 | 42 | 43 |
44 | -------------------------------------------------------------------------------- /webui/src/app/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewEncapsulation, ViewChild, OnInit } from '@angular/core'; 2 | import { Router,ActivatedRoute, NavigationEnd } from '@angular/router'; 3 | 4 | import { LogoComponent } from './components/logo/logo.component'; 5 | import { LoginService } from './services/api/login.service'; 6 | import { UserInfoService} from './services/user-info.service'; 7 | 8 | import 'rxjs/add/operator/filter'; 9 | import 'rxjs/add/operator/map'; 10 | import 'rxjs/add/operator/mergeMap'; 11 | import 'rxjs/add/operator/switchMap'; 12 | import { Subscription } from 'rxjs/Subscription'; 13 | import { Observable } from 'rxjs/Observable'; 14 | import { Observer } from 'rxjs/Observer'; 15 | 16 | @Component({ 17 | selector : 'home-comp', 18 | templateUrl: './home.component.html', 19 | styleUrls : ['./home.scss'], 20 | encapsulation: ViewEncapsulation.None 21 | }) 22 | export class HomeComponent { 23 | 24 | public showAppAlert:boolean = false; 25 | public appHeaderItems=[ 26 | { 27 | label : 'Dashboard', 28 | href : '/home/dashboard', 29 | subNav : [ 30 | { label:"Order Stats" , href:"/home/dashboard/order" }, 31 | { label:"Product Stats", href:"/home/dashboard/product"} 32 | ] 33 | }, 34 | { label: 'Orders' , href: '/home/orders' , subNav: []}, 35 | { label: 'Products' , href: '/home/products' , subNav: []}, 36 | { label: 'Customers', href: '/home/customers' , subNav: []}, 37 | { label: 'Employees', href: '/home/employees' , subNav: []} 38 | ]; 39 | 40 | public selectedHeaderItemIndex:number=0; 41 | public selectedSubNavItemIndex:number=1; 42 | public userName: string=""; 43 | 44 | constructor( 45 | private router:Router, 46 | private activeRoute:ActivatedRoute, 47 | private loginService:LoginService, 48 | private userInfoService:UserInfoService 49 | ) { 50 | // This block is to retrieve the data from the routes (routes are defined in app-routing.module.ts) 51 | router.events 52 | .filter(event => event instanceof NavigationEnd) 53 | .map( _ => this.router.routerState.root) 54 | .map(route => { 55 | while (route.firstChild) route = route.firstChild;; 56 | return route; 57 | }) 58 | .mergeMap( route => route.data) 59 | .subscribe(data => { 60 | console.log("Route data===: ", data[0]); 61 | this.selectedHeaderItemIndex = data[0]?data[0].selectedHeaderItemIndex:-1; 62 | this.selectedSubNavItemIndex = data[0]?data[0].selectedSubNavItemIndex:-1; 63 | }); 64 | this.userName = this.userInfoService.getUserName(); 65 | 66 | } 67 | 68 | navbarSelectionChange(val){ 69 | // console.log(val); 70 | } 71 | 72 | closeAppAlert(){ 73 | this.showAppAlert=false; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /webui/src/app/home.scss: -------------------------------------------------------------------------------- 1 | @import '../assets/scss/var'; 2 | -------------------------------------------------------------------------------- /webui/src/app/pages/404/page-not-found.component.html: -------------------------------------------------------------------------------- 1 |
404 Page Not Found
2 | -------------------------------------------------------------------------------- /webui/src/app/pages/404/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ActivatedRoute, Router} from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'page-not-found', 6 | templateUrl: './page-not-found.component.html', 7 | styleUrls: [ './page-not-found.scss'], 8 | }) 9 | 10 | export class PageNotFoundComponent { 11 | constructor(private router: Router, private activatedRoute: ActivatedRoute){ 12 | console.log("404 : %s",router.url) 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /webui/src/app/pages/404/page-not-found.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | .s-page-not-found { 3 | position: fixed; 4 | top:0; 5 | left:0; 6 | width:100%; 7 | height:60px; 8 | display:flex; 9 | align-items: center; 10 | padding:15px; 11 | background-color: $s-c-primary ; 12 | color:$s-c-inverse-text; 13 | font-size: $s-f-medium-size; 14 | } 15 | -------------------------------------------------------------------------------- /webui/src/app/pages/customers/customers.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Lazy Loading Data

4 |

This is an example of lazy loading data. There are about 100 customer and 5 | the page initially loads 10 customer. 6 | When you scroll to bottom it loads another 10, till it loads all the 100 customer 7 |

8 |
9 | 20 | 21 | 22 |
Loading...
23 |
24 | -------------------------------------------------------------------------------- /webui/src/app/pages/customers/customers.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit,TemplateRef, ViewChild,HostListener } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { CustomerService } from '../../services/api/customer.service'; 4 | 5 | @Component({ 6 | selector: 's-customers-pg', 7 | templateUrl: './customers.component.html', 8 | styleUrls: [ './customers.scss'], 9 | }) 10 | 11 | export class CustomersComponent implements OnInit { 12 | 13 | 14 | 15 | columns:any[]; 16 | rows:any[]; 17 | pageSize:number=10; 18 | currentPage:number=0; 19 | isLastPageLoaded:boolean=false; 20 | isLoading:boolean=false; 21 | 22 | constructor(private router: Router, private customerService: CustomerService) { } 23 | 24 | ngOnInit() { 25 | let me = this; 26 | me.getPageData(); 27 | 28 | this.columns=[ 29 | {prop:"id" , name: "ID" , width:50 }, 30 | {prop:"firstName", name: "First Name" , width:120 }, 31 | {prop:"lastName" , name: "Last Name" , width:120 }, 32 | {prop:"company" , name: "Company" , width:120 }, 33 | {prop:"email" , name: "Email" , width:200 }, 34 | {prop:"phone" , name: "Phone" , width:160 }, 35 | {prop:"address" , name: "Address" , width:220 }, 36 | ]; 37 | } 38 | 39 | getPageData(isAppend:boolean=false) { 40 | 41 | if (this.isLastPageLoaded===false){ 42 | let me = this; 43 | me.isLoading=true; 44 | this.customerService.getCustomers(this.currentPage,this.pageSize).subscribe((data) => { 45 | me.isLastPageLoaded=data.last; 46 | me.currentPage = data.currentPageNumber+1; 47 | if (isAppend===true){ 48 | me.rows = me.rows.concat(data.items); 49 | } 50 | else{ 51 | me.rows = data.items; 52 | } 53 | me.isLoading=false; 54 | }); 55 | } 56 | } 57 | 58 | onScroll() { 59 | console.log("bottom") 60 | if (this.isLoading===false){ 61 | this.getPageData(true); 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /webui/src/app/pages/customers/customers.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /webui/src/app/pages/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /webui/src/app/pages/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 's-dashboard-pg', 5 | templateUrl: './dashboard.component.html', 6 | styleUrls: [ './dashboard.scss'], 7 | }) 8 | 9 | export class DashboardComponent { 10 | constructor( ) { } 11 | } 12 | -------------------------------------------------------------------------------- /webui/src/app/pages/dashboard/dashboard.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | .s-dashboard-pg { 3 | margin: 0px; 4 | display:flex; 5 | flex-wrap:wrap; 6 | flex-direction:row; 7 | justify-content:center; 8 | .chart-box{ 9 | margin:16px; 10 | padding:0 16px; 11 | background-color: #fff; 12 | border:1px solid #ccc; 13 | border-radius: 2px; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /webui/src/app/pages/employees/employees.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /webui/src/app/pages/employees/employees.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit,TemplateRef, ViewChild } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { EmployeeService } from '../../services/api/employee.service'; 4 | 5 | 6 | @Component({ 7 | selector : 's-employees-pg', 8 | templateUrl: './employees.component.html', 9 | styleUrls : [ './employees.scss'], 10 | }) 11 | 12 | export class EmployeesComponent implements OnInit { 13 | 14 | columns:any[]; 15 | rows:any[]; 16 | 17 | constructor(private router: Router, private employeeService: EmployeeService) { } 18 | 19 | ngOnInit() { 20 | var me = this; 21 | me.getPageData(); 22 | 23 | this.columns=[ 24 | {prop:"id" , name: "ID" , width:50 }, 25 | {prop:"firstName" , name: "First Name" , width:120 }, 26 | {prop:"lastName" , name: "Last Name" , width:120 }, 27 | {prop:"email" , name: "Email" , width:250 }, 28 | {prop:"phone" , name: "Phone" , width:160 }, 29 | {prop:"department", name: "Department" , width:220 } 30 | ]; 31 | } 32 | 33 | getPageData() { 34 | var me = this; 35 | this.employeeService.getEmployees().subscribe((data) => { 36 | this.rows = data.items; 37 | }); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /webui/src/app/pages/employees/employees.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /webui/src/app/pages/login/login.component.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /webui/src/app/pages/login/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { LoginService } from '../../services/api/login.service'; 3 | import { Router } from '@angular/router'; 4 | 5 | @Component({ 6 | selector : 's-login-pg', 7 | templateUrl: './login.component.html', 8 | styleUrls : [ './login.scss'], 9 | }) 10 | 11 | export class LoginComponent implements OnInit { 12 | model: any = {}; 13 | errMsg:string = ''; 14 | constructor( 15 | private router: Router, 16 | private loginService: LoginService) { } 17 | 18 | ngOnInit() { 19 | // reset login status 20 | this.loginService.logout(false); 21 | } 22 | 23 | login() { 24 | this.loginService.getToken(this.model.username, this.model.password) 25 | .subscribe(resp => { 26 | if (resp.user === undefined || resp.user.token === undefined || resp.user.token === "INVALID" ){ 27 | this.errMsg = 'Username or password is incorrect'; 28 | return; 29 | } 30 | this.router.navigate([resp.landingPage]); 31 | }, 32 | errResponse => { 33 | switch(errResponse.status){ 34 | case 401: 35 | this.errMsg = 'Username or password is incorrect'; 36 | break; 37 | case 404: 38 | this.errMsg = 'Service not found'; 39 | case 408: 40 | this.errMsg = 'Request Timedout'; 41 | case 500: 42 | this.errMsg = 'Internal Server Error'; 43 | default: 44 | this.errMsg = 'Server Error'; 45 | } 46 | } 47 | ); 48 | } 49 | 50 | onSignUp(){ 51 | this.router.navigate(['signup']); 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /webui/src/app/pages/login/login.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | :host { 3 | display:flex; 4 | flex-direction: row; 5 | justify-content: center; 6 | } 7 | 8 | .s-login-pg{ 9 | width:400px; 10 | display:flex; 11 | padding:0; 12 | margin:48px 16px 16px 16px; 13 | flex-direction: column; 14 | align-items: center; 15 | background-color: white; 16 | border: 1px solid #ccc; 17 | border-radius: 2px; 18 | box-shadow: 0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.15); 19 | .s-login-pg-head{ 20 | width:100%; 21 | height:220px; 22 | display:flex; 23 | flex-direction: column; 24 | align-items: center; 25 | background-color: #998; 26 | padding:16px; 27 | color:white; 28 | } 29 | .s-login-pg-form{ 30 | width:100%; 31 | height:200px; 32 | display:flex; 33 | flex-direction: column; 34 | align-items: center; 35 | margin:24px 16px; 36 | input{ 37 | margin: 16px; 38 | } 39 | } 40 | .s-login-pg-foot{ 41 | width:100%; 42 | min-height:40px; 43 | display:flex; 44 | flex-direction: column; 45 | align-items: center; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /webui/src/app/pages/logout/logout.component.html: -------------------------------------------------------------------------------- 1 |
2 |

You are now signed out

3 |

You may Sign in again

4 | 5 |
6 | -------------------------------------------------------------------------------- /webui/src/app/pages/logout/logout.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ActivatedRoute, Router} from '@angular/router'; 3 | import { UserInfoService, LoginInfoInStorage} from '../../services/user-info.service'; 4 | 5 | @Component({ 6 | selector : 's-logout-pg', 7 | templateUrl: './logout.component.html', 8 | styleUrls : [ './logout.scss'], 9 | }) 10 | 11 | export class LogoutComponent { 12 | constructor(private userInfoService: UserInfoService){ 13 | this.userInfoService.removeUserInfo(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /webui/src/app/pages/logout/logout.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | :host { 3 | display:flex; 4 | flex-direction: row; 5 | justify-content: center; 6 | background-color: $s-bg-gray; 7 | } 8 | -------------------------------------------------------------------------------- /webui/src/app/pages/order_details/order_details.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | .order-detail-pg{ 3 | width:750px; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /webui/src/app/pages/order_stats/order_stats.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Orders by Status

4 | 10 | 11 |
12 | 13 |
14 |

Orders By Payment Type

15 | 21 | 22 |
23 | 24 |
25 |

Orders By Country

26 | 38 | 39 |
40 | 41 | 51 | 52 | 53 | 54 |
55 | -------------------------------------------------------------------------------- /webui/src/app/pages/order_stats/order_stats.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { OrderService } from '../../services/api/order.service'; 3 | import { Router } from '@angular/router'; 4 | import { NgxChartsModule} from '@swimlane/ngx-charts'; 5 | import 'rxjs/add/operator/mergeMap'; 6 | 7 | 8 | @Component({ 9 | selector: 's-order_stats-pg', 10 | templateUrl: './order_stats.component.html', 11 | styleUrls: [ './order_stats.scss'], 12 | }) 13 | 14 | export class OrderStatsComponent implements OnInit { 15 | view: any[] = [460, 180]; 16 | ordersByStatusData : any[] = []; 17 | ordersByPaymentData: any[] = []; 18 | ordersByCountryData: any[] = []; 19 | colorScheme = { 20 | domain: ['#007cbb', '#61c673', '#ff8e28', '#ef2e2e'] 21 | }; 22 | barColorScheme = { 23 | domain: ['#007cbb'] 24 | } 25 | 26 | constructor(private router: Router, private orderService: OrderService) { } 27 | 28 | ngOnInit() { 29 | var me = this; 30 | this.getPageData() 31 | } 32 | 33 | getPageData() { 34 | var me = this; 35 | 36 | /** 37 | * This is an Example of sequencing RxJS observable using mergeMap 38 | * (We are sequencing the API calls as the H2 DB used by the backend is failing to serve multiple request at once) 39 | */ 40 | me.orderService.getOrderStats("status") 41 | .mergeMap(function(statusData) { 42 | me.ordersByStatusData = statusData.items; 43 | console.log("Received Orders By Status"); 44 | return me.orderService.getOrderStats("paytype"); 45 | }).mergeMap( function(payTypeData) { 46 | me.ordersByPaymentData = payTypeData.items; 47 | console.log("Received Orders By Payment Type"); 48 | return me.orderService.getOrderStats("country") 49 | }).subscribe(function(countryData){ 50 | me.ordersByCountryData = countryData.items; 51 | console.log("Received Orders By Country"); 52 | }); 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /webui/src/app/pages/order_stats/order_stats.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | h4{margin-top: 16px;} 3 | .s-order-dash-pg { 4 | margin: 0px; 5 | display:flex; 6 | flex-wrap:wrap; 7 | flex-direction:row; 8 | justify-content:center; 9 | .chart-box{ 10 | margin:16px; 11 | padding:0 16px; 12 | background-color: #fff; 13 | border:1px solid #ccc; 14 | border-radius: 2px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /webui/src/app/pages/orders/orders.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Large Dataset with - Dynamic DOM

3 |

Here we are loading about 600 rows in one ajax call. 4 | However to keep the DOM footprint low we don not create those many DOM elements. 5 | As the user scrolls up and down , DOM elements are added and removed based on the data in memory. 6 |

7 | 8 |
9 |
10 |
11 |
12 | 28 |
29 |
Loading...
30 | 31 |
32 | 42 | 43 |
44 | 45 | 46 |
47 |
48 |
49 | 50 | 51 | {{value}} 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /webui/src/app/pages/orders/orders.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit,TemplateRef, ViewChild } from '@angular/core'; 2 | import { OrderService } from '../../services/api/order.service'; 3 | import { Router } from '@angular/router'; 4 | import 'rxjs/add/operator/mergeMap'; 5 | 6 | 7 | @Component({ 8 | selector: 's-orders-pg', 9 | templateUrl: './orders.component.html', 10 | styleUrls: [ './orders.scss'], 11 | }) 12 | 13 | export class OrdersComponent implements OnInit { 14 | @ViewChild('orderStatusCellTpl') statusCellTpl: TemplateRef; 15 | @ViewChild('orderIdTpl') orderIdTpl: TemplateRef; 16 | columns:any[]; 17 | rows:any[]; 18 | orderByStatusData: any[] = []; 19 | isLoading:boolean=false; 20 | constructor(private router: Router, private orderService: OrderService) { } 21 | 22 | ngOnInit() { 23 | var me = this; 24 | me.getPageData(); 25 | this.columns=[ 26 | {prop:"orderId" , name: "ID" , width:65, cellTemplate: this.orderIdTpl }, 27 | {prop:"orderDate" , name: "Order Date" , width:105 }, 28 | {prop:"orderStatus" , name: "Status" , width:85, cellTemplate: this.statusCellTpl }, 29 | {prop:"customerName" , name: "Name" , width:150 }, 30 | {prop:"customerEmail" , name: "Email" , width:200 }, 31 | {prop:"customerCompany" , name: "Company" , width:110 }, 32 | {prop:"paymentType" , name: "Pay Type" , width:80 }, 33 | {prop:"paidDate" , name: "Pay Date" , width:105 }, 34 | {prop:"shippedDate" , name: "Ship Date" , width:105 }, 35 | {prop:"shipCountry" , name: "Ship Country" , width:110 } 36 | ]; 37 | } 38 | 39 | getPageData() { 40 | var me = this; 41 | let legendColors = {"On Hold":'#ef2e2e', "Shipped":'#ff8e28', "Complete":'#61c673', "New":'#007cbb'}; 42 | me.isLoading=true; 43 | me.orderService.getOrderStats("status") 44 | .mergeMap(function(statusData){ 45 | me.orderByStatusData = statusData.items.map(function(v,i,a){ 46 | return {name:v.name, value:v.value, color:legendColors[v.name]} 47 | }); 48 | console.log("Got Order Stats"); 49 | return me.orderService.getOrderInfo(); 50 | }) 51 | .subscribe(function(orderData){ 52 | me.rows = orderData; 53 | me.isLoading=false; 54 | console.log("Got Order Data"); 55 | }) 56 | } 57 | 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /webui/src/app/pages/orders/orders.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | .s-info-bar{ 3 | display:flex; 4 | flex-direction: row; 5 | justify-content:space-between; 6 | button{outline:none;} 7 | } 8 | 9 | -------------------------------------------------------------------------------- /webui/src/app/pages/product_stats/product_stats.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

Products By Quantity Ordered

5 | 17 | 18 |
19 | 20 |
21 | -------------------------------------------------------------------------------- /webui/src/app/pages/product_stats/product_stats.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ProductService } from '../../services/api/product.service'; 3 | import { Router } from '@angular/router'; 4 | import { NgxChartsModule} from '@swimlane/ngx-charts'; 5 | 6 | @Component({ 7 | selector: 's-product_stats-pg', 8 | templateUrl: './product_stats.component.html', 9 | styleUrls: [ './product_stats.scss'], 10 | }) 11 | 12 | export class ProductStatsComponent { 13 | 14 | 15 | public productByQuantityData=[]; 16 | public barColorScheme = {domain: ['#007cbb']} 17 | 18 | constructor(private router: Router, private productService: ProductService ) { } 19 | ngOnInit() { 20 | var me = this; 21 | this.getPageData() 22 | } 23 | 24 | getPageData() { 25 | var me = this; 26 | me.productService.getProductStatsByQuantityOrdered() 27 | .subscribe(function(countryData){ 28 | me.productByQuantityData = countryData.items; 29 | console.log("Received Orders By Country"); 30 | }); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /webui/src/app/pages/product_stats/product_stats.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | h4{margin-top: 16px;} 3 | .s-product-dash-pg { 4 | margin: 0px; 5 | display:flex; 6 | flex-wrap:wrap; 7 | flex-direction:row; 8 | justify-content:center; 9 | .chart-box{ 10 | margin:16px; 11 | padding:0 16px; 12 | background-color: #fff; 13 | border:1px solid #ccc; 14 | border-radius: 2px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /webui/src/app/pages/products/products.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 12 | 13 |
14 | 15 |
16 | 17 | 18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /webui/src/app/pages/products/products.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit,TemplateRef, ViewChild } from '@angular/core'; 2 | import { ProductService } from '../../services/api/product.service'; 3 | import { Router } from '@angular/router'; 4 | 5 | @Component({ 6 | selector: 's-products-pg', 7 | templateUrl: './products.component.html', 8 | styleUrls: [ './products.scss'], 9 | }) 10 | 11 | export class ProductsComponent implements OnInit { 12 | 13 | @ViewChild('productDiscontinuedTpl') productDiscontinuedTpl: TemplateRef; 14 | 15 | //ngx-Datatable Variables 16 | columns:any[]; 17 | rows:any[]; 18 | 19 | 20 | constructor( private router: Router, private productService: ProductService) {} 21 | ngOnInit() { 22 | var me = this; 23 | me.getPolicyData(); 24 | this.columns=[ 25 | {prop:"productCode" , name: "Code" , width:60 }, 26 | {prop:"productName" , name: "Name" , width:200 }, 27 | {prop:"standardCost" , name: "Standard Cost", width:100 }, 28 | {prop:"listPrice" , name: "List Price" , width:100 }, 29 | {prop:"category" , name: "Category" , width:100 }, 30 | {prop:"targetLevel" , name: "Target Level" , width:100 }, 31 | {prop:"reorderLevel" , name: "Reorder Level", width:100 }, 32 | {prop:"minimumReorderQuantity", name: "Min Order", width:100 }, 33 | {prop:"discontinued" , name: "Discontinued" , width:90, cellTemplate: this.productDiscontinuedTpl} 34 | ]; 35 | 36 | } 37 | 38 | getPolicyData() { 39 | this.productService.getProducts().subscribe( (policyData) => { 40 | this.rows = policyData; 41 | }); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /webui/src/app/pages/products/products.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/scss/var'; 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /webui/src/app/services/api/api-request.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { HttpClient, HttpHeaders, HttpResponse, HttpRequest, HttpParams } from '@angular/common/http'; 3 | import { Router } from '@angular/router'; 4 | import { Observable} from 'rxjs'; 5 | import 'rxjs/add/operator/catch'; 6 | import { UserInfoService, LoginInfoInStorage} from '../user-info.service'; 7 | import { AppConfig } from '../../app-config'; 8 | 9 | 10 | @Injectable() 11 | export class ApiRequestService { 12 | 13 | constructor( 14 | private appConfig:AppConfig, 15 | private http: HttpClient, 16 | private router:Router, 17 | private userInfoService:UserInfoService 18 | ) {} 19 | 20 | /** 21 | * This is a Global place to add all the request headers for every REST calls 22 | */ 23 | getHeaders():HttpHeaders { 24 | let headers = new HttpHeaders(); 25 | let token = this.userInfoService.getStoredToken(); 26 | headers = headers.append('Content-Type', 'application/json'); 27 | if (token !== null) { 28 | headers = headers.append("Authorization", token); 29 | } 30 | return headers; 31 | } 32 | 33 | get(url:string, urlParams?:HttpParams):Observable{ 34 | let me = this; 35 | return this.http.get(this.appConfig.baseApiPath + url, {headers:this.getHeaders(), params:urlParams} ) 36 | .catch(function(error:any){ 37 | console.log("Some error in catch"); 38 | if (error.status === 401 || error.status === 403){ 39 | me.router.navigate(['/logout']); 40 | } 41 | return Observable.throw(error || 'Server error') 42 | }); 43 | } 44 | 45 | post(url:string, body:Object):Observable{ 46 | let me = this; 47 | return this.http.post(this.appConfig.baseApiPath + url, JSON.stringify(body), { headers:this.getHeaders()}) 48 | .catch(function(error:any){ 49 | if (error.status === 401){ 50 | me.router.navigate(['/logout']); 51 | } 52 | return Observable.throw(error || 'Server error') 53 | }); 54 | } 55 | 56 | put(url:string, body:Object):Observable{ 57 | let me = this; 58 | return this.http.put(this.appConfig.baseApiPath + url, JSON.stringify(body), { headers:this.getHeaders()}) 59 | .catch(function(error:any){ 60 | if (error.status === 401){ 61 | me.router.navigate(['/logout']); 62 | } 63 | return Observable.throw(error || 'Server error') 64 | }); 65 | } 66 | 67 | delete(url:string):Observable{ 68 | let me = this; 69 | return this.http.delete(this.appConfig.baseApiPath + url, { headers:this.getHeaders()}) 70 | .catch(function(error:any){ 71 | if (error.status === 401){ 72 | me.router.navigate(['/logout']); 73 | } 74 | return Observable.throw(error || 'Server error') 75 | }); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /webui/src/app/services/api/customer.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { Observable, ReplaySubject, Subject } from 'rxjs'; 3 | import { TranslateService } from './translate.service'; 4 | import { ApiRequestService } from './api-request.service'; 5 | import { HttpParams} from "@angular/common/http"; 6 | @Injectable() 7 | export class CustomerService { 8 | 9 | constructor( 10 | private apiRequest: ApiRequestService, 11 | private translate:TranslateService 12 | ) {} 13 | 14 | getCustomers(page?:number, size?:number): Observable { 15 | let me = this; 16 | let params: HttpParams = new HttpParams(); 17 | params = params.append('page', typeof page === "number"? page.toString():"0"); 18 | params = params.append('size', typeof size === "number"? size.toString():"1000"); 19 | 20 | let customerListSubject = new Subject(); // Will use this subject to emit data that we want 21 | 22 | this.apiRequest.get('api/customers',params) 23 | .subscribe(jsonResp => { 24 | let items = jsonResp.items.map(function(v, i, a){ 25 | let newRow = Object.assign({}, v, { 26 | address: `${v.address1},
${v.city}, ${v.state} ${v.postalCode}
${v.country}` 27 | }); 28 | return newRow; 29 | }); 30 | 31 | let returnObj = Object.assign({},jsonResp,{ 32 | items:items 33 | }) 34 | customerListSubject.next(returnObj); // incidentList is a Subject and emits an event thats being listened to by the components 35 | }); 36 | 37 | return customerListSubject; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /webui/src/app/services/api/employee.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { Observable, ReplaySubject, Subject } from 'rxjs'; 3 | import { ApiRequestService } from './api-request.service'; 4 | import { TranslateService } from './translate.service'; 5 | import { HttpParams} from "@angular/common/http"; 6 | 7 | @Injectable() 8 | export class EmployeeService { 9 | constructor( 10 | private apiRequest: ApiRequestService, 11 | private translate:TranslateService 12 | ) {} 13 | 14 | getEmployees(page?:number, size?:number): Observable { 15 | //Create Request URL params 16 | let me = this; 17 | let params: HttpParams = new HttpParams(); 18 | params = params.append('page', typeof page === "number"? page.toString():"0"); 19 | params = params.append('size', typeof size === "number"? size.toString():"1000"); 20 | return this.apiRequest.get('api/employees',params); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /webui/src/app/services/api/order.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { Observable, ReplaySubject, Subject } from 'rxjs'; 3 | import { ApiRequestService } from './api-request.service'; 4 | import { TranslateService } from './translate.service'; 5 | import { HttpParams} from "@angular/common/http"; 6 | 7 | @Injectable() 8 | export class OrderService { 9 | 10 | constructor( 11 | private apiRequest: ApiRequestService, 12 | private translate:TranslateService 13 | ) {} 14 | 15 | /** 16 | * Gets List of orders 17 | */ 18 | getOrderInfo(page?:number, size?:number): Observable { 19 | //Create Request URL params 20 | let me = this; 21 | let params: HttpParams = new HttpParams(); 22 | params = params.append('page', typeof page === "number"? page.toString():"0"); 23 | params = params.append('size', typeof size === "number"? size.toString():"1000"); 24 | let orderListSubject = new Subject(); // Will use this subject to emit data that we want 25 | this.apiRequest.get('api/orders',params) 26 | .subscribe(jsonResp => { 27 | let returnObj = jsonResp.items.map(function(v, i, a){ 28 | let newRow = Object.assign({}, v, { 29 | orderDate : me.translate.getDateString(v.orderDate), 30 | paidDate : me.translate.getDateString(v.paidDate), 31 | shippedDate: me.translate.getDateString(v.shippedDate) 32 | }); 33 | return newRow; 34 | }); 35 | orderListSubject.next(returnObj); // incidentList is a Subject and emits an event thats being listened to by the components 36 | }); 37 | return orderListSubject; 38 | } 39 | 40 | /** 41 | * Gets Orders and Order Lines (Products in each order) 42 | */ 43 | getOrderDetails(orderId:number): Observable { 44 | //Create Request URL params 45 | let me = this; 46 | let params: HttpParams = new HttpParams(); 47 | if (orderId){ 48 | params = params.append('orderid', orderId.toString()); 49 | } 50 | let orderDetailSubject = new Subject(); // Will use this subject to emit data that we want 51 | this.apiRequest.get('api/order-details',params) 52 | .subscribe(jsonResp => { 53 | let returnObj = jsonResp.items.map(function(v, i, a){ 54 | let newRow = Object.assign({}, v, { 55 | orderDate : me.translate.getDateString(v.orderDate), 56 | paidDate : me.translate.getDateString(v.paidDate), 57 | shippedDate: me.translate.getDateString(v.shippedDate) 58 | }); 59 | return newRow; 60 | }); 61 | orderDetailSubject.next(returnObj); // incidentList is a Subject and emits an event thats being listened to by the components 62 | }); 63 | 64 | return orderDetailSubject; 65 | } 66 | 67 | getOrderStats(field:string): Observable { 68 | return this.apiRequest.get('api/order-stats/' + field ); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /webui/src/app/services/api/product.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { Observable, ReplaySubject, Subject } from 'rxjs'; 3 | import { TranslateService } from './translate.service'; 4 | import { ApiRequestService } from './api-request.service'; 5 | import { HttpParams} from "@angular/common/http"; 6 | 7 | @Injectable() 8 | export class ProductService { 9 | constructor( 10 | private apiRequest: ApiRequestService, 11 | private translate:TranslateService 12 | ) {} 13 | 14 | getProducts(page?:number, size?:number): Observable { 15 | //Create Request URL params 16 | let me = this; 17 | let params: HttpParams = new HttpParams(); 18 | params = params.append('page', typeof page === "number"? page.toString():"0"); 19 | params = params.append('size', typeof size === "number"? size.toString():"1000"); 20 | 21 | let productList = new Subject(); // Will use this subject to emit data that we want 22 | this.apiRequest.get('api/products',params) 23 | .subscribe(jsonResp => { 24 | let returnObj = jsonResp.items.map(function(v, i, a){ 25 | let newRow = Object.assign({}, v, { 26 | listPrice : me.translate.getCurrencyString(v.listPrice), 27 | standardCost: me.translate.getCurrencyString(v.standardCost) 28 | }); 29 | return newRow; 30 | }); 31 | productList.next(returnObj); // incidentList is a Subject and emits an event thats being listened to by the components 32 | }); 33 | 34 | return productList; 35 | } 36 | 37 | 38 | getProductStatsByQuantityOrdered(): Observable { 39 | return this.apiRequest.get('api/product-stats-by-quantity'); 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /webui/src/app/services/api/translate.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { AppConfig } from '../../app-config'; 3 | 4 | @Injectable() 5 | export class TranslateService { 6 | constructor(private appConfig:AppConfig) { 7 | // Code to get Locale Info from Session Storage 8 | } 9 | 10 | getDateString(datenum:number):string{ 11 | return new Date(datenum).toLocaleDateString(this.appConfig.locale, this.appConfig.dateFormat); 12 | } 13 | 14 | getCurrencyString(number:number):string { 15 | return number.toLocaleString(this.appConfig.locale, this.appConfig.currencyFormat); 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /webui/src/app/services/auth_guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { UserInfoService } from './user-info.service'; 3 | import { LoginService } from './api/login.service'; 4 | import { Router, CanActivate, CanActivateChild,ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 5 | 6 | @Injectable() 7 | export class AuthGuard implements CanActivate, CanActivateChild { 8 | 9 | constructor( 10 | private router: Router, 11 | private loginService: LoginService, 12 | private userInfoService: UserInfoService 13 | ) { } 14 | 15 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 16 | let url: string = state.url; 17 | return this.checkLogin(url); 18 | //return true; 19 | } 20 | 21 | canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 22 | return this.canActivate(route, state); 23 | } 24 | 25 | checkLogin(url: string): boolean { 26 | if (this.userInfoService.isLoggedIn()) { 27 | return true; 28 | } 29 | console.log("User is not logged - This routing guard prvents redirection to any routes that needs logging."); 30 | //Store the original url in login service and then redirect to login page 31 | this.loginService.landingPage = url; 32 | this.router.navigate(['login',]); 33 | return false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /webui/src/app/services/user-info.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | export interface UserInStorage{ 4 | userId:string; 5 | email:string; 6 | displayName:string; 7 | token:string; 8 | } 9 | 10 | export interface LoginInfoInStorage{ 11 | success:boolean; 12 | message:string; 13 | landingPage:string; 14 | user?:UserInStorage; 15 | } 16 | 17 | @Injectable() 18 | export class UserInfoService { 19 | 20 | public currentUserKey:string="currentUser"; 21 | public storage:Storage = sessionStorage; // <--- you may switch between sessionStorage or LocalStrage (only one place to change) 22 | 23 | constructor() {} 24 | 25 | //Store userinfo from session storage 26 | storeUserInfo(userInfoString:string) { 27 | this.storage.setItem(this.currentUserKey, userInfoString); 28 | } 29 | 30 | //Remove userinfo from session storage 31 | removeUserInfo() { 32 | this.storage.removeItem(this.currentUserKey); 33 | } 34 | 35 | //Get userinfo from session storage 36 | getUserInfo():UserInStorage|null { 37 | try{ 38 | let userInfoString:string = this.storage.getItem(this.currentUserKey); 39 | if (userInfoString) { 40 | let userObj:UserInStorage = JSON.parse(this.storage.getItem(this.currentUserKey)); 41 | return userObj; 42 | } 43 | else{ 44 | return null; 45 | } 46 | } 47 | catch (e) { 48 | return null; 49 | } 50 | } 51 | 52 | isLoggedIn():boolean{ 53 | return this.storage.getItem(this.currentUserKey)?true:false; 54 | } 55 | 56 | //Get User's Display name from session storage 57 | getUserName():string{ 58 | let userObj:UserInStorage = this.getUserInfo(); 59 | if (userObj!== null){ 60 | return userObj.displayName 61 | } 62 | return "no-user"; 63 | } 64 | 65 | getStoredToken():string|null { 66 | let userObj:UserInStorage = this.getUserInfo(); 67 | if (userObj !== null){ 68 | return userObj.token; 69 | } 70 | return null; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /webui/src/assets/css/sonicglyph.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'sonicglyph'; 3 | src: url('../fonts/sonicglyph.woff') format('woff'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | .s-glyph { 8 | display: inline-block; 9 | font: normal normal normal 16px/1 sonicglyph; 10 | font-size: inherit; 11 | text-rendering: auto; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | -------------------------------------------------------------------------------- /webui/src/assets/fonts/OpenSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/src/assets/fonts/OpenSans-Italic.woff -------------------------------------------------------------------------------- /webui/src/assets/fonts/OpenSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/src/assets/fonts/OpenSans-Regular.woff -------------------------------------------------------------------------------- /webui/src/assets/fonts/OpenSans-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/src/assets/fonts/OpenSans-Semibold.woff -------------------------------------------------------------------------------- /webui/src/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/src/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /webui/src/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/src/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /webui/src/assets/scss/_var.scss: -------------------------------------------------------------------------------- 1 | //Fonts 2 | $s-f-family: Metropolis,Avenir Next,Helvetica Neue,Arial,sans-serif; 3 | $s-f1-size: 24px; 4 | $s-f2-size: 20px; 5 | $s-f3-size: 18px; 6 | $s-f4-size: 16px; 7 | $s-f5-size: 14px; 8 | $s-f6-size: 12px; 9 | $s-f-body-size: 12px; 10 | $s-f-tiny-size: 10px; 11 | $s-f-small-size : 16px; 12 | $s-f-medium-size: 24px; 13 | $s-f-large-size : 32px; 14 | 15 | //****************** Color Scheme ******************** 16 | 17 | //Status Colors 18 | $s-c-error : #CE1126; //critical 19 | $s-c-warning: #E3642B; 20 | $s-c-alert : #FFCC00; 21 | $s-c-good : #6EA204; 22 | $s-c-info : #007cbb; 23 | 24 | //Text Colors 25 | $s-c-text : #333; // Main Text color used in most places 26 | $s-c-inverse-text : #eee; // Text Color used on contrasting backgrounds such as buttons/tabs 27 | $s-c-disable-text : gray; // Text Color used for displaying less emphasized text (eg:detail chart axis color) 28 | $s-c-link-text : #007cbb; 29 | 30 | //Backgrounds 31 | $s-bg-main : #ffffff; // Main Body Background Color 32 | $s-bg-soft-white : whitesmoke; // Alternate Body Background (Such as Windows, Panels, Dropdowns) 33 | $s-bg-inverse : #32404e; 34 | $s-bg-gray : rgb(250, 250, 250); 35 | $s-bg-white : #fff; 36 | 37 | //Borders 38 | $s-c-bd : #ccc; 39 | 40 | //Named Colors 41 | $s-c-white : #fff; 42 | $s-c-gray : gray; 43 | $s-c-soft-white : whitesmoke; 44 | $s-c-primary : #005d84; 45 | -------------------------------------------------------------------------------- /webui/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /webui/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /webui/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebJournal/Angular-SpringBoot-REST-JWT/613c35cf81f77cce74b6fec0ef5bbf8ddfe53297/webui/src/favicon.ico -------------------------------------------------------------------------------- /webui/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Web UI 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Loading... 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /webui/src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { enableProdMode } from '@angular/core'; 3 | import { environment } from './environments/environment'; 4 | import { AppModule } from './app/app.module'; 5 | 6 | if (environment.production) { 7 | enableProdMode(); 8 | } 9 | 10 | platformBrowserDynamic().bootstrapModule(AppModule); 11 | -------------------------------------------------------------------------------- /webui/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | // This file includes polyfills needed by Angular 2 and is loaded before 2 | // the app. You can add your own extra polyfills to this file. 3 | import 'core-js/es6/symbol'; 4 | import 'core-js/es6/object'; 5 | import 'core-js/es6/function'; 6 | import 'core-js/es6/parse-int'; 7 | import 'core-js/es6/parse-float'; 8 | import 'core-js/es6/number'; 9 | import 'core-js/es6/math'; 10 | import 'core-js/es6/string'; 11 | import 'core-js/es6/date'; 12 | import 'core-js/es6/array'; 13 | import 'core-js/es6/regexp'; 14 | import 'core-js/es6/map'; 15 | import 'core-js/es6/weak-map'; 16 | import 'core-js/es6/set'; 17 | 18 | import 'core-js/es7/reflect'; 19 | import 'zone.js/dist/zone'; 20 | -------------------------------------------------------------------------------- /webui/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import './assets/scss/var'; 3 | @import './assets/scss/base'; 4 | 5 | html { 6 | /* make sure we use up the whole viewport */ 7 | width: 100%; 8 | min-height: 100vh; 9 | } 10 | body { 11 | width: 100%; 12 | background-color: $s-bg-gray; 13 | //min-height: 100vh; /* this helps with the sticky footer */ 14 | } 15 | 16 | 17 | //Import classes from swimlane datatable 18 | ngx-datatable { 19 | font-family: Metropolis,Avenir Next,Helvetica Neue,Arial,sans-serif; 20 | font-size:13px; 21 | border:1px solid #ccc; 22 | border-radius: 2px; 23 | padding:0; 24 | background-color: #fff; 25 | .datatable-header, .datatable-footer { 26 | font-size:11px; 27 | line-height:18px; 28 | font-weight:bold; 29 | background-color:#fafafa; 30 | } 31 | .datatable-header{ 32 | //border-bottom: 2px solid #ccc; 33 | box-shadow: 0 2px 4px 0px #ccc; 34 | .datatable-header-cell{ 35 | line-height:22px; 36 | padding-left:10px; 37 | height:22px; 38 | } 39 | } 40 | .datatable-header .datatable-header-cell:not(:first-child) { 41 | border-left:1px solid #ccc; 42 | } 43 | 44 | .datatable-footer{ 45 | border-top: 1px solid #ccc; 46 | .page-count{ 47 | margin: 10px; 48 | } 49 | .pages a{ 50 | padding:8px; 51 | color:inherit; 52 | } 53 | .pages.active a{ 54 | padding:8px; 55 | color:#007cbb; 56 | background-color:#ddd; 57 | text-align: center; 58 | } 59 | } 60 | 61 | .datatable-header-inner{ 62 | padding:12px; 63 | } 64 | .datatable-body-cell{ 65 | padding:8px 0 10px 20px; 66 | border-top: 1px solid #ddd; 67 | } 68 | .pager i { 69 | font-size:18px; 70 | vertical-align: middle; 71 | } 72 | 73 | } 74 | 75 | // NGX Chart Classes 76 | ngx-charts-advanced-pie-chart .item-value{ 77 | margin-top: 0 !important; 78 | } 79 | 80 | header.legend-title{ 81 | background-color: transparent; 82 | color:#333; 83 | height:inherit; 84 | } 85 | 86 | .s-dashboard-pg .chart-legend .legend-wrap { 87 | width: 105px; 88 | } 89 | 90 | 91 | // Custom Classes 92 | .s-badge{ 93 | font-size:11px; 94 | font-weight:normal; 95 | border-radius: 2px; 96 | padding:2px 5px; 97 | 98 | &.s-badge-error, 99 | &.s-badge-onhold { background-color: $s-c-error; color:$s-c-white;} 100 | &.s-badge-warning { background-color: #ff8e28; color:$s-c-text;} 101 | &.s-badge-good { background-color: $s-c-good; color:$s-c-text;} 102 | &.s-badge-new { background-color: $s-c-info; color:$s-c-white;} 103 | } 104 | 105 | .tile{ 106 | display:flex; 107 | padding:16px; 108 | margin:16px; 109 | border-radius:2px; 110 | &.column { flex-direction: column;} 111 | &.center { align-items: center;} 112 | &.white { 113 | background-color: $s-bg-white; 114 | border:1px solid #ccc; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /webui/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "../dist/out-tsc", 5 | "baseUrl": "", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "./node_modules/@types" 14 | ], 15 | "lib": ["es2017", "dom"], 16 | "module": "es2015", 17 | "types": [] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /webui/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | // Typings reference file, you can add your own global typings here 2 | // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html 3 | 4 | declare var System: any; 5 | declare var require: any; 6 | --------------------------------------------------------------------------------