├── Chapter01 ├── ES6 │ ├── 01. ES6 Block scoping, let, and const.js │ ├── 02. ES6 Classes.js │ ├── 03. ES6 Enhanced object literals.js │ ├── 04. ES6 Arrow functions.js │ ├── 05. ES6 Default parameter value.js │ ├── 06. ES6 Rest parameters.js │ ├── 07. ES6 Spread syntax.js │ ├── 08. ES6 Destructuring.js │ ├── 09. ES6 Template Literals.js │ ├── 10. ES6 Promise.js │ └── 11. ES6 Modules │ │ ├── app.js │ │ ├── index.html │ │ ├── roles.js │ │ ├── tasks.js │ │ └── user.js └── Java devloper's view │ ├── 01. Objects and classes.js │ ├── 02. Objects, properties, and property attributes.js │ ├── 03. Prototype and inheritance.js │ ├── 04. Scope and this.js │ ├── 04. User.java │ ├── 05. Keyword this.js │ └── 06. Hoisting.js ├── Chapter02 └── MessagesApp │ ├── README.md │ ├── stage1 │ └── index.html │ ├── stage2 │ ├── components │ │ └── MessageList.js │ └── index.html │ ├── stage3 │ ├── components │ │ ├── MessageList.js │ │ └── MessageListItem.js │ └── index.html │ ├── stage4 │ ├── components │ │ ├── MessageList.js │ │ └── MessageListItem.js │ ├── directives │ │ └── focus.directive.js │ ├── filters │ │ └── datetime.filter.js │ ├── index.html │ └── mixins │ │ └── lifecycle-logger.mixin.js │ └── stage5 │ ├── components │ ├── MessageList.js │ └── MessageListItem.js │ ├── directives │ └── focus.directive.js │ ├── filters │ └── datetime.filter.js │ ├── index.html │ ├── mixins │ └── lifecycle-logger.mixin.js │ ├── plugins │ └── lifecycle-logger.plugin.js │ └── vue.js ├── Chapter03 ├── 01.SpinUnContainer │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── Message.java │ │ │ ├── MessageRepository.java │ │ │ └── MessageService.java │ │ └── resources │ │ └── log4j2.xml ├── 02.AnnotationConfiguration │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── Message.java │ │ │ ├── MessageRepository.java │ │ │ └── MessageService.java │ │ └── resources │ │ └── log4j2.xml ├── 03.SpringMVC │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── AuditingFilter.java │ │ │ ├── Message.java │ │ │ ├── MessageController.java │ │ │ ├── MessageRepository.java │ │ │ └── MessageService.java │ │ └── resources │ │ ├── application.properties │ │ ├── log4j2.xml │ │ └── templates │ │ └── welcome.html ├── 04.JDBCDriver │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── AuditingFilter.java │ │ │ ├── Message.java │ │ │ ├── MessageController.java │ │ │ ├── MessageData.java │ │ │ ├── MessageRepository.java │ │ │ └── MessageService.java │ │ └── resources │ │ ├── application.properties │ │ └── templates │ │ └── welcome.html ├── 05.SpringJDBC │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── AuditingFilter.java │ │ │ ├── Message.java │ │ │ ├── MessageController.java │ │ │ ├── MessageData.java │ │ │ ├── MessageRepository.java │ │ │ └── MessageService.java │ │ └── resources │ │ ├── application.properties │ │ └── templates │ │ └── welcome.html ├── 06.Hibernate │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── AuditingFilter.java │ │ │ ├── Message.java │ │ │ ├── MessageController.java │ │ │ ├── MessageData.java │ │ │ ├── MessageRepository.java │ │ │ └── MessageService.java │ │ └── resources │ │ ├── application.properties │ │ └── templates │ │ └── welcome.html ├── 07.SpringAOP │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── AuditingFilter.java │ │ │ ├── Message.java │ │ │ ├── MessageController.java │ │ │ ├── MessageData.java │ │ │ ├── MessageRepository.java │ │ │ ├── MessageService.java │ │ │ ├── SecurityCheck.java │ │ │ └── SecurityChecker.java │ │ └── resources │ │ ├── application.properties │ │ └── templates │ │ └── welcome.html ├── 08.SpringTransaction │ └── MessagesApp │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── AppConfig.java │ │ │ ├── Application.java │ │ │ ├── AuditingFilter.java │ │ │ ├── Message.java │ │ │ ├── MessageController.java │ │ │ ├── MessageData.java │ │ │ ├── MessageRepository.java │ │ │ ├── MessageService.java │ │ │ ├── SecurityCheck.java │ │ │ └── SecurityChecker.java │ │ └── resources │ │ ├── application.properties │ │ └── templates │ │ └── welcome.html └── 09.PutItTogether │ └── MessagesApp │ ├── .editorconfig │ ├── .gitignore │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── app │ │ └── messages │ │ ├── Application.java │ │ ├── config │ │ └── AppConfig.java │ │ ├── model │ │ └── Message.java │ │ ├── repository │ │ └── MessageRepository.java │ │ ├── security │ │ ├── SecurityCheck.java │ │ └── SecurityChecker.java │ │ ├── service │ │ └── MessageService.java │ │ └── web │ │ ├── AuditingFilter.java │ │ ├── MessageController.java │ │ └── MessageData.java │ └── resources │ ├── application.properties │ ├── static │ ├── axios.v0.18.0.min.js │ ├── components │ │ ├── MessageList.js │ │ └── MessageListItem.js │ ├── directives │ │ └── focus.directive.js │ ├── filters │ │ └── datetime.filter.js │ ├── mixins │ │ └── lifecycle-logger.mixin.js │ ├── plugins │ │ └── lifecycle-logger.plugin.js │ └── vue.js │ └── templates │ ├── index.html │ └── welcome.html ├── Chapter05 ├── MongoDB │ ├── activities.js │ ├── attachments.js │ ├── boards.js │ ├── card_lists.js │ ├── cards.js │ ├── teams.js │ └── users.js ├── TaskAgilePhysicalDataModel.mwb ├── TaskAgilePhysicalDataModel.mwb.bak └── database-setup.sql ├── Chapter07 └── 1.SpringMVCTest │ └── MessagesApp │ ├── .editorconfig │ ├── .gitignore │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── app │ │ │ └── messages │ │ │ ├── Application.java │ │ │ ├── config │ │ │ ├── AppConfig.java │ │ │ ├── AppRepositoryConfig.java │ │ │ └── AppServiceConfig.java │ │ │ ├── model │ │ │ └── Message.java │ │ │ ├── repository │ │ │ └── MessageRepository.java │ │ │ ├── security │ │ │ ├── SecurityCheck.java │ │ │ └── SecurityChecker.java │ │ │ ├── service │ │ │ └── MessageService.java │ │ │ └── web │ │ │ ├── AuditingFilter.java │ │ │ ├── MessageController.java │ │ │ └── MessageData.java │ └── resources │ │ ├── application.properties │ │ ├── static │ │ ├── axios.v0.18.0.min.js │ │ ├── components │ │ │ ├── MessageList.js │ │ │ └── MessageListItem.js │ │ ├── directives │ │ │ └── focus.directive.js │ │ ├── filters │ │ │ └── datetime.filter.js │ │ ├── mixins │ │ │ └── lifecycle-logger.mixin.js │ │ ├── plugins │ │ │ └── lifecycle-logger.plugin.js │ │ └── vue.js │ │ └── templates │ │ ├── index.html │ │ └── welcome.html │ └── test │ └── java │ └── app │ └── messages │ └── web │ └── MessageControllerTest.java ├── Chapter08 └── vuejs.spring-boot.mysql │ ├── .editorconfig │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── front-end │ ├── .browserslistrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ └── .gitkeep │ │ ├── main.js │ │ ├── router.js │ │ ├── store.js │ │ └── views │ │ │ └── LoginPage.vue │ ├── tests │ │ ├── e2e │ │ │ ├── custom-assertions │ │ │ │ └── elementCount.js │ │ │ └── specs │ │ │ │ └── login.e2e.js │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ └── LoginPage.spec.js │ └── vue.config.js │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── taskagile │ │ │ ├── TaskAgileApplication.java │ │ │ └── web │ │ │ └── pages │ │ │ └── MainController.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── taskagile │ └── TaskAgileApplicationTests.java ├── Chapter09 └── vuejs.spring-boot.mysql │ ├── .editorconfig │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── front-end │ ├── .browserslistrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── static │ │ │ └── images │ │ │ └── logo.png │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── components │ │ │ └── .gitkeep │ │ ├── main.js │ │ ├── router.js │ │ ├── services │ │ │ └── registration │ │ │ │ ├── __mocks__ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ ├── store.js │ │ └── views │ │ │ ├── LoginPage.vue │ │ │ └── RegisterPage.vue │ ├── tests │ │ ├── e2e │ │ │ ├── custom-assertions │ │ │ │ └── elementCount.js │ │ │ └── specs │ │ │ │ └── login.e2e.js │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ ├── LoginPage.spec.js │ │ │ ├── RegisterPage.spec.js │ │ │ └── services.registration.spec.js │ └── vue.config.js │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── taskagile │ │ │ ├── TaskAgileApplication.java │ │ │ ├── domain │ │ │ ├── application │ │ │ │ ├── UserService.java │ │ │ │ ├── commands │ │ │ │ │ └── RegistrationCommand.java │ │ │ │ └── impl │ │ │ │ │ └── UserServiceImpl.java │ │ │ ├── common │ │ │ │ ├── event │ │ │ │ │ ├── DefaultDomainEventPublisher.java │ │ │ │ │ ├── DomainEvent.java │ │ │ │ │ └── DomainEventPublisher.java │ │ │ │ ├── mail │ │ │ │ │ ├── DefaultMailManager.java │ │ │ │ │ ├── MailManager.java │ │ │ │ │ └── MessageVariable.java │ │ │ │ ├── model │ │ │ │ │ └── AbstractBaseEntity.java │ │ │ │ └── security │ │ │ │ │ ├── PasswordEncryptor.java │ │ │ │ │ └── PasswordEncryptorDelegator.java │ │ │ └── model │ │ │ │ └── user │ │ │ │ ├── EmailAddressExistsException.java │ │ │ │ ├── RegistrationException.java │ │ │ │ ├── RegistrationManagement.java │ │ │ │ ├── User.java │ │ │ │ ├── UserRegisteredEventHandler.java │ │ │ │ ├── UserRepository.java │ │ │ │ ├── UsernameExistsException.java │ │ │ │ └── events │ │ │ │ └── UserRegisteredEvent.java │ │ │ ├── infrastructure │ │ │ └── repository │ │ │ │ ├── HibernateSupport.java │ │ │ │ └── HibernateUserRepository.java │ │ │ ├── utils │ │ │ └── JsonUtils.java │ │ │ └── web │ │ │ ├── apis │ │ │ └── RegistrationApiController.java │ │ │ ├── pages │ │ │ └── MainController.java │ │ │ ├── payload │ │ │ └── RegistrationPayload.java │ │ │ └── results │ │ │ ├── ApiResult.java │ │ │ └── Result.java │ └── resources │ │ ├── application.properties │ │ └── static │ │ └── static │ │ └── images │ │ └── logo.png │ └── test │ ├── java │ └── com │ │ └── taskagile │ │ ├── TaskAgileApplicationTests.java │ │ ├── domain │ │ ├── application │ │ │ └── impl │ │ │ │ └── UserServiceImplTests.java │ │ └── model │ │ │ └── user │ │ │ └── RegistrationManagementTests.java │ │ ├── infrastructure │ │ └── repository │ │ │ └── HibernateUserRepositoryTests.java │ │ └── web │ │ ├── apis │ │ └── RegistrationApiControllerTests.java │ │ └── payload │ │ └── RegistrationPayloadTests.java │ └── resources │ ├── application.properties │ └── hibernate.properties ├── Chapter10 └── vuejs.spring-boot.mysql │ ├── .editorconfig │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── front-end │ ├── .browserslistrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── jest.config.js │ ├── nightwatch.config.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── static │ │ │ └── images │ │ │ └── logo.png │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── components │ │ │ ├── Logo.vue │ │ │ └── PageFooter.vue │ │ ├── main.js │ │ ├── router.js │ │ ├── services │ │ │ ├── __mocks__ │ │ │ │ ├── authentication.js │ │ │ │ └── registration.js │ │ │ ├── authentication.js │ │ │ └── registration.js │ │ ├── store.js │ │ ├── utils │ │ │ └── error-parser.js │ │ └── views │ │ │ ├── HomePage.vue │ │ │ ├── LoginPage.vue │ │ │ └── RegisterPage.vue │ ├── tests │ │ ├── e2e │ │ │ ├── custom-assertions │ │ │ │ └── elementCount.js │ │ │ ├── data │ │ │ │ └── .gitkeep │ │ │ ├── page-objects │ │ │ │ ├── HomePage.js │ │ │ │ ├── LoginPage.js │ │ │ │ └── RegisterPage.js │ │ │ └── specs │ │ │ │ ├── 0.register.e2e.js │ │ │ │ └── 1.login.e2e.js │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ ├── LoginPage.spec.js │ │ │ ├── RegisterPage.spec.js │ │ │ ├── services.authentication.spec.js │ │ │ ├── services.registration.spec.js │ │ │ └── utils.error-parser.spec.js │ └── vue.config.js │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── taskagile │ │ │ ├── TaskAgileApplication.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ └── SecurityConfiguration.java │ │ │ ├── domain │ │ │ ├── application │ │ │ │ ├── UserService.java │ │ │ │ ├── commands │ │ │ │ │ └── RegistrationCommand.java │ │ │ │ └── impl │ │ │ │ │ └── UserServiceImpl.java │ │ │ ├── common │ │ │ │ ├── event │ │ │ │ │ ├── DefaultDomainEventPublisher.java │ │ │ │ │ ├── DomainEvent.java │ │ │ │ │ └── DomainEventPublisher.java │ │ │ │ ├── mail │ │ │ │ │ ├── DefaultMailManager.java │ │ │ │ │ ├── MailManager.java │ │ │ │ │ ├── Mailer.java │ │ │ │ │ ├── Message.java │ │ │ │ │ ├── MessageVariable.java │ │ │ │ │ └── SimpleMessage.java │ │ │ │ ├── model │ │ │ │ │ └── AbstractBaseEntity.java │ │ │ │ └── security │ │ │ │ │ ├── PasswordEncryptor.java │ │ │ │ │ └── PasswordEncryptorDelegator.java │ │ │ └── model │ │ │ │ └── user │ │ │ │ ├── EmailAddressExistsException.java │ │ │ │ ├── RegistrationException.java │ │ │ │ ├── RegistrationManagement.java │ │ │ │ ├── SimpleUser.java │ │ │ │ ├── User.java │ │ │ │ ├── UserRegisteredEventHandler.java │ │ │ │ ├── UserRepository.java │ │ │ │ ├── UsernameExistsException.java │ │ │ │ └── events │ │ │ │ └── UserRegisteredEvent.java │ │ │ ├── infrastructure │ │ │ ├── mail │ │ │ │ └── AsyncMailer.java │ │ │ └── repository │ │ │ │ ├── HibernateSupport.java │ │ │ │ └── HibernateUserRepository.java │ │ │ ├── utils │ │ │ └── JsonUtils.java │ │ │ └── web │ │ │ ├── apis │ │ │ ├── RegistrationApiController.java │ │ │ └── authenticate │ │ │ │ ├── AuthenticationFilter.java │ │ │ │ ├── SimpleAuthenticationFailureHandler.java │ │ │ │ ├── SimpleAuthenticationSuccessHandler.java │ │ │ │ └── SimpleLogoutSuccessHandler.java │ │ │ ├── pages │ │ │ └── MainController.java │ │ │ ├── payload │ │ │ └── RegistrationPayload.java │ │ │ └── results │ │ │ ├── ApiResult.java │ │ │ └── Result.java │ └── resources │ │ ├── application.properties │ │ ├── mail-templates │ │ └── welcome.ftl │ │ └── static │ │ └── static │ │ └── images │ │ └── logo.png │ └── test │ ├── java │ └── com │ │ └── taskagile │ │ ├── TaskAgileApplicationTests.java │ │ ├── domain │ │ ├── application │ │ │ └── impl │ │ │ │ └── UserServiceImplTests.java │ │ ├── common │ │ │ └── mail │ │ │ │ └── DefaultMailManagerTests.java │ │ └── model │ │ │ └── user │ │ │ └── RegistrationManagementTests.java │ │ ├── infrastructure │ │ ├── mail │ │ │ └── AsyncMailerTests.java │ │ └── repository │ │ │ └── HibernateUserRepositoryTests.java │ │ └── web │ │ ├── apis │ │ ├── RegistrationApiControllerTests.java │ │ └── authenticate │ │ │ └── AuthenticationFilterTests.java │ │ └── payload │ │ └── RegistrationPayloadTests.java │ └── resources │ ├── application.properties │ ├── hibernate.properties │ └── mail-templates │ └── test.ftl ├── Chapter11 └── vuejs.spring-boot.mysql │ ├── .editorconfig │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── front-end │ ├── .browserslistrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── jest.config.js │ ├── nightwatch.config.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── images │ │ │ └── logo.png │ │ └── index.html │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── components │ │ │ ├── Logo.vue │ │ │ ├── PageFooter.vue │ │ │ └── PageHeader.vue │ │ ├── i18n.js │ │ ├── locale │ │ │ ├── index.js │ │ │ └── messages │ │ │ │ ├── en_US.json │ │ │ │ └── zh_CN.json │ │ ├── main.js │ │ ├── modals │ │ │ ├── CreateBoardModal.vue │ │ │ └── CreateTeamModal.vue │ │ ├── router.js │ │ ├── services │ │ │ ├── __mocks__ │ │ │ │ ├── authentication.js │ │ │ │ └── registration.js │ │ │ ├── authentication.js │ │ │ ├── boards.js │ │ │ ├── me.js │ │ │ ├── registration.js │ │ │ └── teams.js │ │ ├── store │ │ │ ├── actions.js │ │ │ ├── getters.js │ │ │ ├── index.js │ │ │ └── mutations.js │ │ ├── utils │ │ │ └── error-parser.js │ │ └── views │ │ │ ├── BoardPage.vue │ │ │ ├── HomePage.vue │ │ │ ├── LoginPage.vue │ │ │ └── RegisterPage.vue │ ├── tests │ │ ├── e2e │ │ │ ├── custom-assertions │ │ │ │ └── elementCount.js │ │ │ ├── data │ │ │ │ └── .gitkeep │ │ │ ├── page-objects │ │ │ │ ├── HomePage.js │ │ │ │ ├── LoginPage.js │ │ │ │ └── RegisterPage.js │ │ │ └── specs │ │ │ │ ├── 0.register.e2e.js │ │ │ │ └── 1.login.e2e.js │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ ├── LoginPage.spec.js │ │ │ ├── RegisterPage.spec.js │ │ │ ├── services.authentication.spec.js │ │ │ ├── services.registration.spec.js │ │ │ └── utils.error-parser.spec.js │ └── vue.config.js │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── taskagile │ │ │ ├── TaskAgileApplication.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ └── SecurityConfiguration.java │ │ │ ├── domain │ │ │ ├── application │ │ │ │ ├── BoardService.java │ │ │ │ ├── TeamService.java │ │ │ │ ├── UserService.java │ │ │ │ ├── commands │ │ │ │ │ ├── CreateBoardCommand.java │ │ │ │ │ ├── CreateTeamCommand.java │ │ │ │ │ └── RegistrationCommand.java │ │ │ │ └── impl │ │ │ │ │ ├── BoardServiceImpl.java │ │ │ │ │ ├── TeamServiceImpl.java │ │ │ │ │ └── UserServiceImpl.java │ │ │ ├── common │ │ │ │ ├── event │ │ │ │ │ ├── DefaultDomainEventPublisher.java │ │ │ │ │ ├── DomainEvent.java │ │ │ │ │ └── DomainEventPublisher.java │ │ │ │ ├── mail │ │ │ │ │ ├── DefaultMailManager.java │ │ │ │ │ ├── MailManager.java │ │ │ │ │ ├── Mailer.java │ │ │ │ │ ├── Message.java │ │ │ │ │ ├── MessageVariable.java │ │ │ │ │ └── SimpleMessage.java │ │ │ │ ├── model │ │ │ │ │ ├── AbstractBaseEntity.java │ │ │ │ │ └── AbstractBaseId.java │ │ │ │ └── security │ │ │ │ │ ├── AccessDeniedHandlerImpl.java │ │ │ │ │ ├── CurrentUser.java │ │ │ │ │ ├── PasswordEncryptor.java │ │ │ │ │ └── PasswordEncryptorDelegator.java │ │ │ └── model │ │ │ │ ├── board │ │ │ │ ├── Board.java │ │ │ │ ├── BoardId.java │ │ │ │ ├── BoardManagement.java │ │ │ │ ├── BoardMember.java │ │ │ │ ├── BoardMemberRepository.java │ │ │ │ ├── BoardRepository.java │ │ │ │ └── events │ │ │ │ │ └── BoardCreatedEvent.java │ │ │ │ ├── team │ │ │ │ ├── Team.java │ │ │ │ ├── TeamId.java │ │ │ │ ├── TeamRepository.java │ │ │ │ └── events │ │ │ │ │ └── TeamCreatedEvent.java │ │ │ │ └── user │ │ │ │ ├── EmailAddressExistsException.java │ │ │ │ ├── RegistrationException.java │ │ │ │ ├── RegistrationManagement.java │ │ │ │ ├── SimpleUser.java │ │ │ │ ├── User.java │ │ │ │ ├── UserId.java │ │ │ │ ├── UserRegisteredEventHandler.java │ │ │ │ ├── UserRepository.java │ │ │ │ ├── UsernameExistsException.java │ │ │ │ └── events │ │ │ │ └── UserRegisteredEvent.java │ │ │ ├── infrastructure │ │ │ ├── mail │ │ │ │ └── AsyncMailer.java │ │ │ └── repository │ │ │ │ ├── HibernateBoardMemberRepository.java │ │ │ │ ├── HibernateBoardRepository.java │ │ │ │ ├── HibernateSupport.java │ │ │ │ ├── HibernateTeamRepository.java │ │ │ │ └── HibernateUserRepository.java │ │ │ ├── utils │ │ │ └── JsonUtils.java │ │ │ └── web │ │ │ ├── apis │ │ │ ├── ApiExceptionHandler.java │ │ │ ├── BoardApiController.java │ │ │ ├── MeApiController.java │ │ │ ├── RegistrationApiController.java │ │ │ ├── TeamApiController.java │ │ │ └── authenticate │ │ │ │ ├── AuthenticationFilter.java │ │ │ │ ├── SimpleAuthenticationFailureHandler.java │ │ │ │ ├── SimpleAuthenticationSuccessHandler.java │ │ │ │ └── SimpleLogoutSuccessHandler.java │ │ │ ├── pages │ │ │ └── MainController.java │ │ │ ├── payload │ │ │ ├── CreateBoardPayload.java │ │ │ ├── CreateTeamPayload.java │ │ │ └── RegistrationPayload.java │ │ │ └── results │ │ │ ├── ApiResult.java │ │ │ ├── CreateBoardResult.java │ │ │ ├── CreateTeamResult.java │ │ │ ├── MyDataResult.java │ │ │ └── Result.java │ └── resources │ │ ├── application.properties │ │ ├── mail-templates │ │ └── welcome.ftl │ │ └── spy.properties │ └── test │ ├── java │ └── com │ │ └── taskagile │ │ ├── TaskAgileApplicationTests.java │ │ ├── domain │ │ ├── application │ │ │ └── impl │ │ │ │ └── UserServiceImplTests.java │ │ ├── common │ │ │ └── mail │ │ │ │ └── DefaultMailManagerTests.java │ │ └── model │ │ │ └── user │ │ │ └── RegistrationManagementTests.java │ │ ├── infrastructure │ │ ├── mail │ │ │ └── AsyncMailerTests.java │ │ └── repository │ │ │ └── HibernateUserRepositoryTests.java │ │ └── web │ │ ├── apis │ │ ├── RegistrationApiControllerTests.java │ │ └── authenticate │ │ │ └── AuthenticationFilterTests.java │ │ └── payload │ │ └── RegistrationPayloadTests.java │ └── resources │ ├── application.properties │ ├── hibernate.properties │ └── mail-templates │ └── test.ftl ├── Chapter12 └── vuejs.spring-boot.mysql │ ├── .editorconfig │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── front-end │ ├── .browserslistrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── jest.config.js │ ├── nightwatch.config.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── images │ │ │ └── logo.png │ │ └── index.html │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── components │ │ │ ├── Logo.vue │ │ │ ├── PageFooter.vue │ │ │ └── PageHeader.vue │ │ ├── event-bus.js │ │ ├── i18n.js │ │ ├── locale │ │ │ ├── index.js │ │ │ └── messages │ │ │ │ ├── en_US.json │ │ │ │ └── zh_CN.json │ │ ├── main.js │ │ ├── modals │ │ │ ├── AddMemberModal.vue │ │ │ ├── CreateBoardModal.vue │ │ │ └── CreateTeamModal.vue │ │ ├── real-time-client.js │ │ ├── router.js │ │ ├── services │ │ │ ├── __mocks__ │ │ │ │ ├── authentication.js │ │ │ │ └── registration.js │ │ │ ├── authentication.js │ │ │ ├── boards.js │ │ │ ├── card-lists.js │ │ │ ├── cards.js │ │ │ ├── me.js │ │ │ ├── registration.js │ │ │ └── teams.js │ │ ├── store │ │ │ ├── actions.js │ │ │ ├── getters.js │ │ │ ├── index.js │ │ │ └── mutations.js │ │ ├── utils │ │ │ ├── error-parser.js │ │ │ └── notify.js │ │ └── views │ │ │ ├── BoardPage.vue │ │ │ ├── HomePage.vue │ │ │ ├── LoginPage.vue │ │ │ └── RegisterPage.vue │ ├── tests │ │ ├── e2e │ │ │ ├── custom-assertions │ │ │ │ └── elementCount.js │ │ │ ├── data │ │ │ │ └── .gitkeep │ │ │ ├── page-objects │ │ │ │ ├── HomePage.js │ │ │ │ ├── LoginPage.js │ │ │ │ └── RegisterPage.js │ │ │ └── specs │ │ │ │ ├── 0.register.e2e.js │ │ │ │ └── 1.login.e2e.js │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ ├── LoginPage.spec.js │ │ │ ├── RegisterPage.spec.js │ │ │ ├── services.authentication.spec.js │ │ │ ├── services.registration.spec.js │ │ │ └── utils.error-parser.spec.js │ └── vue.config.js │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── taskagile │ │ │ ├── TaskAgileApplication.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ ├── SecurityConfiguration.java │ │ │ └── WebSocketConfiguration.java │ │ │ ├── domain │ │ │ ├── application │ │ │ │ ├── BoardService.java │ │ │ │ ├── CardListService.java │ │ │ │ ├── CardService.java │ │ │ │ ├── TeamService.java │ │ │ │ ├── UserService.java │ │ │ │ ├── commands │ │ │ │ │ ├── AddCardCommand.java │ │ │ │ │ ├── AddCardListCommand.java │ │ │ │ │ ├── ChangeCardListPositionsCommand.java │ │ │ │ │ ├── ChangeCardPositionsCommand.java │ │ │ │ │ ├── CreateBoardCommand.java │ │ │ │ │ ├── CreateTeamCommand.java │ │ │ │ │ └── RegistrationCommand.java │ │ │ │ └── impl │ │ │ │ │ ├── BoardServiceImpl.java │ │ │ │ │ ├── CardListServiceImpl.java │ │ │ │ │ ├── CardServiceImpl.java │ │ │ │ │ ├── TeamServiceImpl.java │ │ │ │ │ └── UserServiceImpl.java │ │ │ ├── common │ │ │ │ ├── event │ │ │ │ │ ├── DefaultDomainEventPublisher.java │ │ │ │ │ ├── DomainEvent.java │ │ │ │ │ └── DomainEventPublisher.java │ │ │ │ ├── mail │ │ │ │ │ ├── DefaultMailManager.java │ │ │ │ │ ├── MailManager.java │ │ │ │ │ ├── Mailer.java │ │ │ │ │ ├── Message.java │ │ │ │ │ ├── MessageVariable.java │ │ │ │ │ └── SimpleMessage.java │ │ │ │ ├── model │ │ │ │ │ ├── AbstractBaseEntity.java │ │ │ │ │ └── AbstractBaseId.java │ │ │ │ └── security │ │ │ │ │ ├── AccessDeniedHandlerImpl.java │ │ │ │ │ ├── CurrentUser.java │ │ │ │ │ ├── PasswordEncryptor.java │ │ │ │ │ ├── PasswordEncryptorDelegator.java │ │ │ │ │ └── TokenManager.java │ │ │ └── model │ │ │ │ ├── board │ │ │ │ ├── Board.java │ │ │ │ ├── BoardId.java │ │ │ │ ├── BoardManagement.java │ │ │ │ ├── BoardMember.java │ │ │ │ ├── BoardMemberRepository.java │ │ │ │ ├── BoardRepository.java │ │ │ │ └── events │ │ │ │ │ ├── BoardCreatedEvent.java │ │ │ │ │ └── BoardMemberAddedEvent.java │ │ │ │ ├── card │ │ │ │ ├── Card.java │ │ │ │ ├── CardId.java │ │ │ │ ├── CardPosition.java │ │ │ │ ├── CardPositionsInList.java │ │ │ │ ├── CardRepository.java │ │ │ │ └── events │ │ │ │ │ └── CardAddedEvent.java │ │ │ │ ├── cardlist │ │ │ │ ├── CardList.java │ │ │ │ ├── CardListId.java │ │ │ │ ├── CardListPosition.java │ │ │ │ ├── CardListRepository.java │ │ │ │ └── events │ │ │ │ │ └── CardListAddedEvent.java │ │ │ │ ├── team │ │ │ │ ├── Team.java │ │ │ │ ├── TeamId.java │ │ │ │ ├── TeamRepository.java │ │ │ │ └── events │ │ │ │ │ └── TeamCreatedEvent.java │ │ │ │ └── user │ │ │ │ ├── EmailAddressExistsException.java │ │ │ │ ├── RegistrationException.java │ │ │ │ ├── RegistrationManagement.java │ │ │ │ ├── SimpleUser.java │ │ │ │ ├── User.java │ │ │ │ ├── UserFinder.java │ │ │ │ ├── UserId.java │ │ │ │ ├── UserNotFoundException.java │ │ │ │ ├── UserRegisteredEventHandler.java │ │ │ │ ├── UserRepository.java │ │ │ │ ├── UsernameExistsException.java │ │ │ │ └── events │ │ │ │ └── UserRegisteredEvent.java │ │ │ ├── infrastructure │ │ │ ├── mail │ │ │ │ └── AsyncMailer.java │ │ │ └── repository │ │ │ │ ├── HibernateBoardMemberRepository.java │ │ │ │ ├── HibernateBoardRepository.java │ │ │ │ ├── HibernateCardListRepository.java │ │ │ │ ├── HibernateCardRepository.java │ │ │ │ ├── HibernateSupport.java │ │ │ │ ├── HibernateTeamRepository.java │ │ │ │ └── HibernateUserRepository.java │ │ │ ├── utils │ │ │ └── JsonUtils.java │ │ │ └── web │ │ │ ├── apis │ │ │ ├── ApiExceptionHandler.java │ │ │ ├── BoardApiController.java │ │ │ ├── CardApiController.java │ │ │ ├── CardListApiController.java │ │ │ ├── MeApiController.java │ │ │ ├── RegistrationApiController.java │ │ │ ├── TeamApiController.java │ │ │ └── authenticate │ │ │ │ ├── AuthenticationFilter.java │ │ │ │ ├── SimpleAuthenticationFailureHandler.java │ │ │ │ ├── SimpleAuthenticationSuccessHandler.java │ │ │ │ └── SimpleLogoutSuccessHandler.java │ │ │ ├── pages │ │ │ └── MainController.java │ │ │ ├── payload │ │ │ ├── AddBoardMemberPayload.java │ │ │ ├── AddCardListPayload.java │ │ │ ├── AddCardPayload.java │ │ │ ├── ChangeCardListPositionsPayload.java │ │ │ ├── ChangeCardPositionsPayload.java │ │ │ ├── CreateBoardPayload.java │ │ │ ├── CreateTeamPayload.java │ │ │ └── RegistrationPayload.java │ │ │ ├── results │ │ │ ├── AddCardListResult.java │ │ │ ├── AddCardResult.java │ │ │ ├── ApiResult.java │ │ │ ├── BoardResult.java │ │ │ ├── CreateBoardResult.java │ │ │ ├── CreateTeamResult.java │ │ │ ├── MyDataResult.java │ │ │ └── Result.java │ │ │ ├── socket │ │ │ ├── Action.java │ │ │ ├── ChannelHandler.java │ │ │ ├── ChannelHandlerInvoker.java │ │ │ ├── ChannelHandlerResolver.java │ │ │ ├── ChannelHandlers.java │ │ │ ├── ChannelValue.java │ │ │ ├── IncomingMessage.java │ │ │ ├── Payload.java │ │ │ ├── RealTimeSession.java │ │ │ ├── SubscriptionHub.java │ │ │ ├── WebSocketMessages.java │ │ │ ├── WebSocketRequestDispatcher.java │ │ │ └── handlers │ │ │ │ └── BoardChannelHandler.java │ │ │ └── updater │ │ │ └── CardUpdater.java │ └── resources │ │ ├── application.properties │ │ ├── mail-templates │ │ └── welcome.ftl │ │ └── spy.properties │ └── test │ ├── java │ └── com │ │ └── taskagile │ │ ├── TaskAgileApplicationTests.java │ │ ├── domain │ │ ├── application │ │ │ └── impl │ │ │ │ └── UserServiceImplTests.java │ │ ├── common │ │ │ └── mail │ │ │ │ └── DefaultMailManagerTests.java │ │ └── model │ │ │ └── user │ │ │ └── RegistrationManagementTests.java │ │ ├── infrastructure │ │ ├── mail │ │ │ └── AsyncMailerTests.java │ │ └── repository │ │ │ └── HibernateUserRepositoryTests.java │ │ └── web │ │ ├── apis │ │ ├── RegistrationApiControllerTests.java │ │ └── authenticate │ │ │ └── AuthenticationFilterTests.java │ │ ├── payload │ │ └── RegistrationPayloadTests.java │ │ └── socket │ │ ├── ChannelHandlerInvokerTests.java │ │ └── ChannelHandlerResolverTests.java │ └── resources │ ├── application.properties │ ├── hibernate.properties │ └── mail-templates │ └── test.ftl ├── Chapter13 └── vuejs.spring-boot.mysql │ ├── .editorconfig │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── front-end │ ├── .browserslistrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── jest.config.js │ ├── nightwatch.config.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── images │ │ │ └── logo.png │ │ └── index.html │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── components │ │ │ ├── Logo.vue │ │ │ ├── PageFooter.vue │ │ │ ├── PageHeader.vue │ │ │ └── Uploader.vue │ │ ├── event-bus.js │ │ ├── i18n.js │ │ ├── locale │ │ │ ├── index.js │ │ │ └── messages │ │ │ │ ├── en_US.json │ │ │ │ └── zh_CN.json │ │ ├── main.js │ │ ├── modals │ │ │ ├── AddMemberModal.vue │ │ │ ├── CardModal.vue │ │ │ ├── CreateBoardModal.vue │ │ │ └── CreateTeamModal.vue │ │ ├── real-time-client.js │ │ ├── router.js │ │ ├── services │ │ │ ├── __mocks__ │ │ │ │ ├── authentication.js │ │ │ │ └── registration.js │ │ │ ├── authentication.js │ │ │ ├── boards.js │ │ │ ├── card-lists.js │ │ │ ├── cards.js │ │ │ ├── me.js │ │ │ ├── registration.js │ │ │ └── teams.js │ │ ├── store │ │ │ ├── actions.js │ │ │ ├── getters.js │ │ │ ├── index.js │ │ │ └── mutations.js │ │ ├── utils │ │ │ ├── error-parser.js │ │ │ └── notify.js │ │ └── views │ │ │ ├── BoardPage.vue │ │ │ ├── HomePage.vue │ │ │ ├── LoginPage.vue │ │ │ └── RegisterPage.vue │ ├── tests │ │ ├── e2e │ │ │ ├── custom-assertions │ │ │ │ └── elementCount.js │ │ │ ├── data │ │ │ │ └── .gitkeep │ │ │ ├── page-objects │ │ │ │ ├── HomePage.js │ │ │ │ ├── LoginPage.js │ │ │ │ └── RegisterPage.js │ │ │ └── specs │ │ │ │ ├── 0.register.e2e.js │ │ │ │ └── 1.login.e2e.js │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ ├── LoginPage.spec.js │ │ │ ├── RegisterPage.spec.js │ │ │ ├── services.authentication.spec.js │ │ │ ├── services.registration.spec.js │ │ │ └── utils.error-parser.spec.js │ └── vue.config.js │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── setup │ ├── 1.init-database.sql │ └── 2.refactoring-database.sql │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── taskagile │ │ │ ├── TaskAgileApplication.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ ├── MessageConfiguration.java │ │ │ ├── SecurityConfiguration.java │ │ │ └── WebSocketConfiguration.java │ │ │ ├── domain │ │ │ ├── application │ │ │ │ ├── ActivityService.java │ │ │ │ ├── BoardService.java │ │ │ │ ├── CardListService.java │ │ │ │ ├── CardService.java │ │ │ │ ├── TeamService.java │ │ │ │ ├── UserService.java │ │ │ │ ├── commands │ │ │ │ │ ├── AddBoardMemberCommand.java │ │ │ │ │ ├── AddCardAttachmentCommand.java │ │ │ │ │ ├── AddCardCommand.java │ │ │ │ │ ├── AddCardCommentCommand.java │ │ │ │ │ ├── AddCardListCommand.java │ │ │ │ │ ├── AnonymousCommand.java │ │ │ │ │ ├── ChangeCardDescriptionCommand.java │ │ │ │ │ ├── ChangeCardListPositionsCommand.java │ │ │ │ │ ├── ChangeCardPositionsCommand.java │ │ │ │ │ ├── ChangeCardTitleCommand.java │ │ │ │ │ ├── CreateBoardCommand.java │ │ │ │ │ ├── CreateTeamCommand.java │ │ │ │ │ ├── RegisterCommand.java │ │ │ │ │ └── UserCommand.java │ │ │ │ └── impl │ │ │ │ │ ├── ActivityServiceImpl.java │ │ │ │ │ ├── BoardServiceImpl.java │ │ │ │ │ ├── CardListServiceImpl.java │ │ │ │ │ ├── CardServiceImpl.java │ │ │ │ │ ├── TeamServiceImpl.java │ │ │ │ │ └── UserServiceImpl.java │ │ │ ├── common │ │ │ │ ├── event │ │ │ │ │ ├── DomainEvent.java │ │ │ │ │ ├── DomainEventPublisher.java │ │ │ │ │ ├── TriggeredBy.java │ │ │ │ │ └── TriggeredFrom.java │ │ │ │ ├── file │ │ │ │ │ ├── AbstractBaseFileStorage.java │ │ │ │ │ ├── FileStorage.java │ │ │ │ │ ├── FileStorageException.java │ │ │ │ │ ├── FileStorageResolver.java │ │ │ │ │ ├── FileUrlCreator.java │ │ │ │ │ └── TempFile.java │ │ │ │ ├── mail │ │ │ │ │ ├── DefaultMailManager.java │ │ │ │ │ ├── MailManager.java │ │ │ │ │ ├── Mailer.java │ │ │ │ │ ├── Message.java │ │ │ │ │ ├── MessageVariable.java │ │ │ │ │ └── SimpleMessage.java │ │ │ │ ├── model │ │ │ │ │ ├── AbstractBaseEntity.java │ │ │ │ │ └── AbstractBaseId.java │ │ │ │ └── security │ │ │ │ │ ├── AccessDeniedHandlerImpl.java │ │ │ │ │ ├── ApiRequestAccessDeniedExceptionTranslationFilter.java │ │ │ │ │ ├── CurrentUser.java │ │ │ │ │ ├── PasswordEncryptor.java │ │ │ │ │ ├── PasswordEncryptorDelegator.java │ │ │ │ │ └── TokenManager.java │ │ │ └── model │ │ │ │ ├── activity │ │ │ │ ├── Activity.java │ │ │ │ ├── ActivityDetail.java │ │ │ │ ├── ActivityId.java │ │ │ │ ├── ActivityRepository.java │ │ │ │ ├── ActivityType.java │ │ │ │ ├── BoardActivities.java │ │ │ │ ├── CardActivities.java │ │ │ │ ├── CardListActivities.java │ │ │ │ └── DomainEventToActivityConverter.java │ │ │ │ ├── attachment │ │ │ │ ├── Attachment.java │ │ │ │ ├── AttachmentCreationException.java │ │ │ │ ├── AttachmentId.java │ │ │ │ ├── AttachmentManagement.java │ │ │ │ ├── AttachmentRepository.java │ │ │ │ ├── ImageProcessor.java │ │ │ │ ├── ThumbnailCreationException.java │ │ │ │ ├── ThumbnailCreator.java │ │ │ │ └── events │ │ │ │ │ └── CardAttachmentAddedEvent.java │ │ │ │ ├── board │ │ │ │ ├── Board.java │ │ │ │ ├── BoardId.java │ │ │ │ ├── BoardManagement.java │ │ │ │ ├── BoardMember.java │ │ │ │ ├── BoardMemberRepository.java │ │ │ │ ├── BoardRepository.java │ │ │ │ └── events │ │ │ │ │ ├── BoardCreatedEvent.java │ │ │ │ │ ├── BoardDomainEvent.java │ │ │ │ │ └── BoardMemberAddedEvent.java │ │ │ │ ├── card │ │ │ │ ├── Card.java │ │ │ │ ├── CardId.java │ │ │ │ ├── CardPosition.java │ │ │ │ ├── CardPositionsInList.java │ │ │ │ ├── CardRepository.java │ │ │ │ └── events │ │ │ │ │ ├── CardAddedEvent.java │ │ │ │ │ ├── CardDescriptionChangedEvent.java │ │ │ │ │ ├── CardDomainEvent.java │ │ │ │ │ └── CardTitleChangedEvent.java │ │ │ │ ├── cardlist │ │ │ │ ├── CardList.java │ │ │ │ ├── CardListId.java │ │ │ │ ├── CardListPosition.java │ │ │ │ ├── CardListRepository.java │ │ │ │ └── events │ │ │ │ │ └── CardListAddedEvent.java │ │ │ │ ├── team │ │ │ │ ├── Team.java │ │ │ │ ├── TeamId.java │ │ │ │ ├── TeamRepository.java │ │ │ │ └── events │ │ │ │ │ └── TeamCreatedEvent.java │ │ │ │ └── user │ │ │ │ ├── EmailAddressExistsException.java │ │ │ │ ├── RegistrationException.java │ │ │ │ ├── RegistrationManagement.java │ │ │ │ ├── SimpleUser.java │ │ │ │ ├── User.java │ │ │ │ ├── UserFinder.java │ │ │ │ ├── UserId.java │ │ │ │ ├── UserNotFoundException.java │ │ │ │ ├── UserRepository.java │ │ │ │ ├── UsernameExistsException.java │ │ │ │ └── events │ │ │ │ └── UserRegisteredEvent.java │ │ │ ├── infrastructure │ │ │ ├── file │ │ │ │ ├── local │ │ │ │ │ ├── LocalFileServlet.java │ │ │ │ │ └── LocalFileStorage.java │ │ │ │ └── s3 │ │ │ │ │ └── S3FileStorage.java │ │ │ ├── mail │ │ │ │ └── AsyncMailer.java │ │ │ ├── messaging │ │ │ │ ├── ActivityTracker.java │ │ │ │ └── AmqpDomainEventPublisher.java │ │ │ └── repository │ │ │ │ ├── HibernateActivityRepository.java │ │ │ │ ├── HibernateAttachmentRepository.java │ │ │ │ ├── HibernateBoardMemberRepository.java │ │ │ │ ├── HibernateBoardRepository.java │ │ │ │ ├── HibernateCardListRepository.java │ │ │ │ ├── HibernateCardRepository.java │ │ │ │ ├── HibernateSupport.java │ │ │ │ ├── HibernateTeamRepository.java │ │ │ │ └── HibernateUserRepository.java │ │ │ ├── utils │ │ │ ├── ImageUtils.java │ │ │ ├── IpAddress.java │ │ │ ├── JsonUtils.java │ │ │ ├── RequestUtils.java │ │ │ └── Size.java │ │ │ └── web │ │ │ ├── apis │ │ │ ├── AbstractBaseController.java │ │ │ ├── ApiExceptionHandler.java │ │ │ ├── BoardApiController.java │ │ │ ├── CardApiController.java │ │ │ ├── CardListApiController.java │ │ │ ├── MeApiController.java │ │ │ ├── RegistrationApiController.java │ │ │ ├── TeamApiController.java │ │ │ └── authenticate │ │ │ │ ├── AuthenticationFilter.java │ │ │ │ ├── SimpleAuthenticationFailureHandler.java │ │ │ │ ├── SimpleAuthenticationSuccessHandler.java │ │ │ │ └── SimpleLogoutSuccessHandler.java │ │ │ ├── pages │ │ │ └── MainController.java │ │ │ ├── payload │ │ │ ├── AddBoardMemberPayload.java │ │ │ ├── AddCardCommentPayload.java │ │ │ ├── AddCardListPayload.java │ │ │ ├── AddCardPayload.java │ │ │ ├── ChangeCardDescriptionPayload.java │ │ │ ├── ChangeCardListPositionsPayload.java │ │ │ ├── ChangeCardPositionsPayload.java │ │ │ ├── ChangeCardTitlePayload.java │ │ │ ├── CreateBoardPayload.java │ │ │ ├── CreateTeamPayload.java │ │ │ └── RegistrationPayload.java │ │ │ ├── results │ │ │ ├── AddCardListResult.java │ │ │ ├── AddCardResult.java │ │ │ ├── ApiResult.java │ │ │ ├── AttachmentResult.java │ │ │ ├── AttachmentResults.java │ │ │ ├── BoardResult.java │ │ │ ├── CardActivitiesResult.java │ │ │ ├── CardResult.java │ │ │ ├── CommentActivityResult.java │ │ │ ├── CreateBoardResult.java │ │ │ ├── CreateTeamResult.java │ │ │ ├── MyDataResult.java │ │ │ └── Result.java │ │ │ ├── socket │ │ │ ├── Action.java │ │ │ ├── ChannelHandler.java │ │ │ ├── ChannelHandlerInvoker.java │ │ │ ├── ChannelHandlerResolver.java │ │ │ ├── ChannelHandlers.java │ │ │ ├── ChannelValue.java │ │ │ ├── IncomingMessage.java │ │ │ ├── Payload.java │ │ │ ├── RealTimeSession.java │ │ │ ├── SubscriptionHub.java │ │ │ ├── WebSocketMessages.java │ │ │ ├── WebSocketRequestDispatcher.java │ │ │ └── handlers │ │ │ │ └── BoardChannelHandler.java │ │ │ └── updater │ │ │ └── CardUpdater.java │ └── resources │ │ ├── application.properties │ │ ├── mail-templates │ │ └── welcome.ftl │ │ └── spy.properties │ └── test │ ├── java │ └── com │ │ └── taskagile │ │ ├── TaskAgileApplicationTests.java │ │ ├── domain │ │ ├── application │ │ │ └── impl │ │ │ │ └── UserServiceImplTests.java │ │ ├── common │ │ │ └── mail │ │ │ │ └── DefaultMailManagerTests.java │ │ └── model │ │ │ └── user │ │ │ └── RegistrationManagementTests.java │ │ ├── infrastructure │ │ ├── mail │ │ │ └── AsyncMailerTests.java │ │ └── repository │ │ │ └── HibernateUserRepositoryTests.java │ │ └── web │ │ ├── apis │ │ ├── RegistrationApiControllerTests.java │ │ └── authenticate │ │ │ └── AuthenticationFilterTests.java │ │ ├── payload │ │ └── RegistrationPayloadTests.java │ │ └── socket │ │ ├── ChannelHandlerInvokerTests.java │ │ └── ChannelHandlerResolverTests.java │ └── resources │ ├── application.properties │ ├── hibernate.properties │ └── mail-templates │ └── test.ftl ├── Chapter14 └── __MACOSX │ └── vuejs.spring-boot.mysql │ ├── front-end │ ├── ._.DS_Store │ └── tests │ │ ├── ._.DS_Store │ │ └── e2e │ │ └── ._.DS_Store │ └── src │ └── ._.DS_Store ├── Chapter15 └── __MACOSX │ └── vuejs.spring-boot.mysql │ ├── ._.DS_Store │ └── front-end │ ├── ._.DS_Store │ └── tests │ ├── ._.DS_Store │ └── e2e │ └── ._.DS_Store ├── LICENSE └── README.md /Chapter01/ES6/05. ES6 Default parameter value.js: -------------------------------------------------------------------------------- 1 | const shoppingCart = []; 2 | function addToCart(item, size = 1) { 3 | shoppingCart.push({item: item, count: size}); 4 | } 5 | addToCart('Apple'); // size is 1 6 | addToCart('Orange', 2); // size is 2 7 | 8 | 9 | // ES5 equivalent 10 | function addToCart(item, size) { 11 | size = (typeof size !== 'undefined') ? size : 1; 12 | shoppingCart.push({item: item, count: size}); 13 | } -------------------------------------------------------------------------------- /Chapter01/ES6/06. ES6 Rest parameters.js: -------------------------------------------------------------------------------- 1 | // Using arguments in ES5 2 | function workout(exercise1) { 3 | var todos = Array.prototype.slice.call(arguments, workout.length); 4 | console.log('Start from ' + exercise1); 5 | console.log(todos.length + ' more to do'); 6 | } 7 | // equivalent to rest parameters in ES6 8 | function workout(exercise1, ...todos) { 9 | console.log('Start from ' + exercise1); // Start from Treadmill 10 | console.log(todos.length + ' more to do'); // 2 more to do 11 | console.log('Args length: ' + workout.length); // Args length: 1 12 | } 13 | workout('Treadmill', 'Pushup', 'Spinning'); -------------------------------------------------------------------------------- /Chapter01/ES6/09. ES6 Template Literals.js: -------------------------------------------------------------------------------- 1 | let user = { 2 | name: 'Ted', 3 | greeting () { 4 | console.log(`Hello, I'm ${this.name}.`); 5 | } 6 | }; 7 | user.greeting(); // Hello, I'm Ted. 8 | 9 | let greeting = `Hello, I'm ${user.name}. 10 | Welcome to the team!`; 11 | console.log(greeting); 12 | 13 | let greeting = `Hello, I'm ${user.name}. 14 | Welcome to the team!`; 15 | console.log(greeting); // Hello, I'm Ted. 16 | // Welcome to the team! -------------------------------------------------------------------------------- /Chapter01/ES6/11. ES6 Modules/app.js: -------------------------------------------------------------------------------- 1 | import User from './user.js'; 2 | import * as Roles from './roles.js'; 3 | import completeTask from './tasks.js'; 4 | import {completedCount} from './tasks.js'; 5 | 6 | let user = new User('Ted', Roles.USER); 7 | completeTask(user); 8 | console.log(`Total completed ${completedCount}`); 9 | // completedCount++; 10 | // Only to show that you can change imported object. 11 | // NOT a good practice to do it though. 12 | User.prototype.walk = function () { 13 | console.log(`${this.name} walks`); 14 | }; 15 | user.walk(); -------------------------------------------------------------------------------- /Chapter01/ES6/11. ES6 Modules/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Chapter01/ES6/11. ES6 Modules/roles.js: -------------------------------------------------------------------------------- 1 | const DEFAULT_ROLE = 'User'; 2 | const ADMIN = 'Admin'; 3 | export {DEFAULT_ROLE as USER, ADMIN}; -------------------------------------------------------------------------------- /Chapter01/ES6/11. ES6 Modules/tasks.js: -------------------------------------------------------------------------------- 1 | console.log('Inside tasks module'); 2 | export default function completeTask(user) { 3 | console.log(`${user.name} completed a task`); 4 | completedCount++; 5 | } 6 | // Keep track of the count of completed task 7 | export let completedCount = 0; -------------------------------------------------------------------------------- /Chapter01/ES6/11. ES6 Modules/user.js: -------------------------------------------------------------------------------- 1 | export default class User { 2 | constructor (name, role) { 3 | this.name = name; 4 | this.role = role; 5 | } 6 | }; -------------------------------------------------------------------------------- /Chapter01/Java devloper's view/06. Hoisting.js: -------------------------------------------------------------------------------- 1 | function workout() { 2 | goToGym(); // What will the output be? 3 | var goToGym = function () { 4 | console.log('Workout in Gym A'); 5 | } 6 | return; 7 | function goToGym() { 8 | console.log('Workout in Gym B'); 9 | } 10 | } 11 | workout(); 12 | 13 | 14 | // Interpreter's view 15 | function workout() { 16 | function goToGym() { 17 | console.log('Workout in Gym B'); 18 | } 19 | var goToGym; 20 | goToGym(); 21 | goToGym = function () { 22 | console.log('Workout in Gym A'); 23 | } 24 | return; 25 | } 26 | workout(); -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage2/components/MessageList.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'MessageList', 3 | template: ``, 7 | props: { 8 | items: { 9 | type: Array, 10 | required: true 11 | } 12 | }, 13 | methods: { 14 | deleteMessage (message) { 15 | this.$emit('delete', message) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage3/components/MessageList.js: -------------------------------------------------------------------------------- 1 | import MessageListItem from './MessageListItem.js' 2 | 3 | export default { 4 | name: 'MessageList', 5 | template: ``, 8 | props: { 9 | items: { 10 | type: Array, 11 | required: true 12 | } 13 | }, 14 | components: { 15 | MessageListItem 16 | }, 17 | methods: { 18 | deleteMessage (message) { 19 | this.$emit('delete', message) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage3/components/MessageListItem.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'MessageListItem', 3 | template: `
  • {{ item.text }} - {{ item.createdAt }} 4 |
  • `, 5 | props: { 6 | item: { 7 | type: Object, 8 | required: true 9 | } 10 | }, 11 | methods: { 12 | deleteClicked () { 13 | this.$emit('delete') 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage4/components/MessageListItem.js: -------------------------------------------------------------------------------- 1 | import lifecyleLogger from '../mixins/lifecycle-logger.mixin.js' 2 | 3 | export default { 4 | name: 'MessageListItem', 5 | mixins: [lifecyleLogger], 6 | template: `
  • {{ item.text }} - {{ item.createdAt | datetime }} 7 |
  • `, 8 | props: { 9 | item: { 10 | type: Object, 11 | required: true 12 | } 13 | }, 14 | methods: { 15 | deleteClicked () { 16 | this.$emit('delete') 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage4/directives/focus.directive.js: -------------------------------------------------------------------------------- 1 | // The following example is borrowed from 2 | // https://vuejs.org/v2/guide/custom-directive.html 3 | 4 | // Register a global custom directive called `v-focus` 5 | Vue.directive('focus', { 6 | // When the bound element is inserted into the DOM... 7 | inserted: function (el) { 8 | // Focus the element 9 | el.focus() 10 | } 11 | }) -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage4/filters/datetime.filter.js: -------------------------------------------------------------------------------- 1 | const formatter = new Intl.DateTimeFormat('en-US', { 2 | year: 'numeric', month: 'long', week: 'long', day: 'numeric', 3 | hour: 'numeric', minute: 'numeric', second: 'numeric' 4 | }) 5 | Vue.filter('datetime', function(value) { 6 | if (!value) return '' 7 | return formatter.format(value) 8 | }) -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage4/mixins/lifecycle-logger.mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | created () { 3 | console.log(`${this.$options.name} created`) 4 | }, 5 | beforeMount () { 6 | console.log(`${this.$options.name} about to mount`) 7 | }, 8 | mounted () { 9 | console.log(`${this.$options.name} mounted`) 10 | }, 11 | destroyed () { 12 | console.log(`${this.$options.name} destroyed`) 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage5/components/MessageList.js: -------------------------------------------------------------------------------- 1 | import MessageListItem from './MessageListItem.js' 2 | 3 | export default { 4 | name: 'MessageList', 5 | template: `
    `, 8 | props: { 9 | items: { 10 | type: Array, 11 | required: true 12 | } 13 | }, 14 | components: { 15 | MessageListItem 16 | }, 17 | methods: { 18 | deleteMessage (message) { 19 | this.$emit('delete', message) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage5/components/MessageListItem.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'MessageListItem', 3 | template: `
  • {{ item.text }} - {{ item.createdAt | datetime }} 4 |
  • `, 5 | props: { 6 | item: { 7 | type: Object, 8 | required: true 9 | } 10 | }, 11 | methods: { 12 | deleteClicked () { 13 | this.$emit('delete'); 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage5/directives/focus.directive.js: -------------------------------------------------------------------------------- 1 | // The following example is borrowed from 2 | // https://vuejs.org/v2/guide/custom-directive.html 3 | 4 | // Register a global custom directive called `v-focus` 5 | Vue.directive('focus', { 6 | // When the bound element is inserted into the DOM... 7 | inserted: function (el) { 8 | // Focus the element 9 | el.focus() 10 | } 11 | }) -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage5/filters/datetime.filter.js: -------------------------------------------------------------------------------- 1 | const formatter = new Intl.DateTimeFormat('en-US', { 2 | year: 'numeric', month: 'long', week: 'long', day: 'numeric', 3 | hour: 'numeric', minute: 'numeric', second: 'numeric' 4 | }) 5 | Vue.filter('datetime', function(value) { 6 | if (!value) return '' 7 | return formatter.format(value) 8 | }) -------------------------------------------------------------------------------- /Chapter02/MessagesApp/stage5/mixins/lifecycle-logger.mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | created () { 3 | console.log(`${this.$options.name} created`) 4 | }, 5 | beforeMount () { 6 | console.log(`${this.$options.name} about to mount`) 7 | }, 8 | mounted () { 9 | console.log(`${this.$options.name} mounted`) 10 | }, 11 | destroyed () { 12 | console.log(`${this.$options.name} destroyed`) 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/src/main/java/app/messages/AppConfig.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | @ComponentScan("app.messages") 9 | public class AppConfig { 10 | 11 | @Bean 12 | public MessageRepository messageRepository() { 13 | return new MessageRepository(); 14 | } 15 | 16 | @Bean 17 | MessageService messageService() { 18 | return new MessageService(messageRepository()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 5 | 6 | public class Application { 7 | public static void main(String[] args) { 8 | ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); 9 | MessageService messageService = context.getBean(MessageService.class); 10 | messageService.save("Hello, Spring!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/src/main/java/app/messages/Message.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class Message { 4 | 5 | private String text; 6 | 7 | public Message(String text) { 8 | this.text = text; 9 | } 10 | 11 | public String getText() { 12 | return text; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/src/main/java/app/messages/MessageRepository.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | 6 | public class MessageRepository { 7 | 8 | private final static Log log = LogFactory.getLog(MessageRepository.class); 9 | 10 | public void saveMessage(Message message) { 11 | // Save message to a database 12 | log.info("Saved message: " + message.getText()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class MessageService { 4 | 5 | private MessageRepository repository; 6 | 7 | public MessageService (MessageRepository repository) { 8 | this.repository = repository; 9 | } 10 | 11 | public void save(String text) { 12 | this.repository.saveMessage(new Message(text)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter03/01.SpinUnContainer/MessagesApp/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/src/main/java/app/messages/AppConfig.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @Configuration 7 | @ComponentScan("app.messages") 8 | public class AppConfig { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 5 | 6 | public class Application { 7 | public static void main(String[] args) { 8 | ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); 9 | MessageService messageService = context.getBean(MessageService.class); 10 | messageService.save("Hello, Spring!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/src/main/java/app/messages/Message.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class Message { 4 | 5 | private String text; 6 | 7 | public Message(String text) { 8 | this.text = text; 9 | } 10 | 11 | public String getText() { 12 | return text; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/src/main/java/app/messages/MessageRepository.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | public class MessageRepository { 9 | 10 | private final static Log log = LogFactory.getLog(MessageRepository.class); 11 | 12 | public void saveMessage(Message message) { 13 | // Save message to a database 14 | log.info("Saved message: " + message.getText()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class MessageService { 7 | 8 | private MessageRepository repository; 9 | 10 | public MessageService (MessageRepository repository) { 11 | this.repository = repository; 12 | } 13 | 14 | public void save(String text) { 15 | this.repository.saveMessage(new Message(text)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter03/02.AnnotationConfiguration/MessagesApp/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/java/app/messages/Message.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class Message { 4 | 5 | private String text; 6 | 7 | public Message(String text) { 8 | this.text = text; 9 | } 10 | 11 | public String getText() { 12 | return text; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/java/app/messages/MessageRepository.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | public class MessageRepository { 9 | 10 | private final static Log log = LogFactory.getLog(MessageRepository.class); 11 | 12 | public void saveMessage(Message message) { 13 | // Save message to a database 14 | log.info("Saved message: " + message.getText()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class MessageService { 7 | 8 | private MessageRepository repository; 9 | 10 | public MessageService(MessageRepository repository) { 11 | this.repository = repository; 12 | } 13 | 14 | public void save(String text) { 15 | this.repository.saveMessage(new Message(text)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.messages.AuditingFilter=DEBUG 2 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter03/03.SpringMVC/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/src/main/java/app/messages/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class MessageService { 7 | 8 | private MessageRepository repository; 9 | 10 | public MessageService(MessageRepository repository) { 11 | this.repository = repository; 12 | } 13 | 14 | public Message save(String text) { 15 | return repository.saveMessage(new Message(text)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.messages.AuditingFilter=DEBUG 2 | 3 | spring.datasource.url=jdbc:mysql://localhost/app_messages?useSSL=false 4 | spring.datasource.username=root 5 | spring.datasource.password=1234 6 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 7 | -------------------------------------------------------------------------------- /Chapter03/04.JDBCDriver/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/src/main/java/app/messages/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class MessageService { 7 | 8 | private MessageRepository repository; 9 | 10 | public MessageService(MessageRepository repository) { 11 | this.repository = repository; 12 | } 13 | 14 | public Message save(String text) { 15 | return repository.saveMessage(new Message(text)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.messages.AuditingFilter=DEBUG 2 | 3 | spring.datasource.url=jdbc:mysql://localhost/app_messages?useSSL=false 4 | spring.datasource.username=root 5 | spring.datasource.password=1234 6 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 7 | -------------------------------------------------------------------------------- /Chapter03/05.SpringJDBC/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/src/main/java/app/messages/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class MessageService { 7 | 8 | private MessageRepository repository; 9 | 10 | public MessageService(MessageRepository repository) { 11 | this.repository = repository; 12 | } 13 | 14 | public Message save(String text) { 15 | return repository.saveMessage(new Message(text)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.messages.AuditingFilter=DEBUG 2 | 3 | spring.datasource.url=jdbc:mysql://localhost/app_messages?useSSL=false 4 | spring.datasource.username=root 5 | spring.datasource.password=1234 6 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 7 | -------------------------------------------------------------------------------- /Chapter03/06.Hibernate/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/src/main/java/app/messages/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/src/main/java/app/messages/MessageService.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class MessageService { 7 | 8 | private MessageRepository repository; 9 | 10 | public MessageService(MessageRepository repository) { 11 | this.repository = repository; 12 | } 13 | 14 | @SecurityCheck 15 | public Message save(String text) { 16 | return repository.saveMessage(new Message(text)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/src/main/java/app/messages/SecurityCheck.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface SecurityCheck { 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.messages.AuditingFilter=DEBUG 2 | logging.level.app.messages.SecurityChecker=DEBUG 3 | 4 | spring.datasource.url=jdbc:mysql://localhost/app_messages?useSSL=false 5 | spring.datasource.username=root 6 | spring.datasource.password=1234 7 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 8 | -------------------------------------------------------------------------------- /Chapter03/07.SpringAOP/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/src/main/java/app/messages/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/src/main/java/app/messages/SecurityCheck.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface SecurityCheck { 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.messages.AuditingFilter=DEBUG 2 | logging.level.app.messages.SecurityChecker=DEBUG 3 | logging.level.app.messages.MessageService=DEBUG 4 | 5 | spring.datasource.url=jdbc:mysql://localhost/app_messages?useSSL=false 6 | spring.datasource.username=root 7 | spring.datasource.password=1234 8 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 9 | 10 | spring.jpa.open-in-view=false 11 | -------------------------------------------------------------------------------- /Chapter03/08.SpringTransaction/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/java/app/messages/security/SecurityCheck.java: -------------------------------------------------------------------------------- 1 | package app.messages.security; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface SecurityCheck { 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/java/app/messages/web/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages.web; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.sample.messages.AuditingFilter=DEBUG 2 | logging.level.app.sample.messages.SecurityChecker=DEBUG 3 | logging.level.app.sample.messages.MessageService=DEBUG 4 | logging.level.org.hibernate.SQL=DEBUG 5 | 6 | spring.datasource.url=jdbc:mysql://localhost/app_messages?useSSL=false 7 | spring.datasource.username=root 8 | spring.datasource.password=1234 9 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 10 | 11 | spring.jpa.open-in-view=false 12 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/static/components/MessageList.js: -------------------------------------------------------------------------------- 1 | import MessageListItem from './MessageListItem.js' 2 | 3 | export default { 4 | name: 'MessageList', 5 | template: `
    `, 8 | props: { 9 | items: { 10 | type: Array, 11 | required: true 12 | } 13 | }, 14 | components: { 15 | MessageListItem 16 | }, 17 | methods: { 18 | deleteMessage (message) { 19 | this.$emit('delete', message) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/static/components/MessageListItem.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'MessageListItem', 3 | template: `
  • {{ item.text }} - {{ item.createdAt | datetime }} 4 |
  • `, 5 | props: { 6 | item: { 7 | type: Object, 8 | required: true 9 | } 10 | }, 11 | methods: { 12 | deleteClicked () { 13 | this.$emit('delete'); 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/static/directives/focus.directive.js: -------------------------------------------------------------------------------- 1 | // The following example is borrowed from 2 | // https://vuejs.org/v2/guide/custom-directive.html 3 | 4 | // Register a global custom directive called `v-focus` 5 | Vue.directive('focus', { 6 | // When the bound element is inserted into the DOM... 7 | inserted: function (el) { 8 | // Focus the element 9 | el.focus() 10 | } 11 | }) -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/static/filters/datetime.filter.js: -------------------------------------------------------------------------------- 1 | const formatter = new Intl.DateTimeFormat('en-US', { 2 | year: 'numeric', month: 'long', week: 'long', day: 'numeric', 3 | hour: 'numeric', minute: 'numeric', second: 'numeric' 4 | }) 5 | Vue.filter('datetime', function(value) { 6 | if (!value) return '' 7 | return formatter.format(value) 8 | }) -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/static/mixins/lifecycle-logger.mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | created () { 3 | console.log(`${this.$options.name} created`) 4 | }, 5 | beforeMount () { 6 | console.log(`${this.$options.name} about to mount`) 7 | }, 8 | mounted () { 9 | console.log(`${this.$options.name} mounted`) 10 | }, 11 | destroyed () { 12 | console.log(`${this.$options.name} destroyed`) 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter03/09.PutItTogether/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter05/TaskAgilePhysicalDataModel.mwb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter05/TaskAgilePhysicalDataModel.mwb -------------------------------------------------------------------------------- /Chapter05/TaskAgilePhysicalDataModel.mwb.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter05/TaskAgilePhysicalDataModel.mwb.bak -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .classpath 3 | .settings 4 | .project 5 | .sts4-cache 6 | 7 | *.iml 8 | .classpath 9 | 10 | /bin 11 | /target 12 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/java/app/messages/Application.java: -------------------------------------------------------------------------------- 1 | package app.messages; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | public static void main(String[] args) { 9 | SpringApplication.run(Application.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/java/app/messages/config/AppServiceConfig.java: -------------------------------------------------------------------------------- 1 | package app.messages.config; 2 | 3 | import app.messages.service.MessageService; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class AppServiceConfig { 9 | @Bean 10 | MessageService createService() { 11 | return new MessageService(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/java/app/messages/security/SecurityCheck.java: -------------------------------------------------------------------------------- 1 | package app.messages.security; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface SecurityCheck { 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/java/app/messages/web/MessageData.java: -------------------------------------------------------------------------------- 1 | package app.messages.web; 2 | 3 | public class MessageData { 4 | private String text; 5 | public String getText() { 6 | return this.text; 7 | } 8 | public void setText(String text) { 9 | this.text = text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.app.sample.messages.AuditingFilter=DEBUG 2 | logging.level.app.sample.messages.SecurityChecker=DEBUG 3 | logging.level.app.sample.messages.MessageService=DEBUG 4 | logging.level.org.hibernate.SQL=DEBUG 5 | 6 | spring.datasource.url=jdbc:mysql://localhost/app_messages 7 | spring.datasource.username=root 8 | spring.datasource.password=1234 9 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 10 | 11 | spring.jpa.open-in-view=false 12 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/static/components/MessageList.js: -------------------------------------------------------------------------------- 1 | import MessageListItem from './MessageListItem.js' 2 | 3 | export default { 4 | name: 'MessageList', 5 | template: `
    `, 8 | props: { 9 | items: { 10 | type: Array, 11 | required: true 12 | } 13 | }, 14 | components: { 15 | MessageListItem 16 | }, 17 | methods: { 18 | deleteMessage (message) { 19 | this.$emit('delete', message) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/static/components/MessageListItem.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'MessageListItem', 3 | template: `
  • {{ item.text }} - {{ item.createdAt | datetime }} 4 |
  • `, 5 | props: { 6 | item: { 7 | type: Object, 8 | required: true 9 | } 10 | }, 11 | methods: { 12 | deleteClicked () { 13 | this.$emit('delete'); 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/static/directives/focus.directive.js: -------------------------------------------------------------------------------- 1 | // The following example is borrowed from 2 | // https://vuejs.org/v2/guide/custom-directive.html 3 | 4 | // Register a global custom directive called `v-focus` 5 | Vue.directive('focus', { 6 | // When the bound element is inserted into the DOM... 7 | inserted: function (el) { 8 | // Focus the element 9 | el.focus() 10 | } 11 | }) -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/static/filters/datetime.filter.js: -------------------------------------------------------------------------------- 1 | const formatter = new Intl.DateTimeFormat('en-US', { 2 | year: 'numeric', month: 'long', week: 'long', day: 'numeric', 3 | hour: 'numeric', minute: 'numeric', second: 'numeric' 4 | }) 5 | Vue.filter('datetime', function(value) { 6 | if (!value) return '' 7 | return formatter.format(value) 8 | }) -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/static/mixins/lifecycle-logger.mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | created () { 3 | console.log(`${this.$options.name} created`) 4 | }, 5 | beforeMount () { 6 | console.log(`${this.$options.name} about to mount`) 7 | }, 8 | mounted () { 9 | console.log(`${this.$options.name} mounted`) 10 | }, 11 | destroyed () { 12 | console.log(`${this.$options.name} destroyed`) 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter07/1.SpringMVCTest/MessagesApp/src/main/resources/templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | 27 | ### Application specific ### 28 | application-dev.properties 29 | src/main/resources/static/css/ 30 | src/main/resources/static/favicon.ico 31 | src/main/resources/static/js/ 32 | src/main/resources/templates/index.html 33 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter08/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/reports/ 6 | selenium-debug.log 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/README.md: -------------------------------------------------------------------------------- 1 | # TaskAgile Front End 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Run your unit tests 24 | ``` 25 | npm run test:unit 26 | ``` 27 | 28 | ### Run your end-to-end tests 29 | ``` 30 | npm run test:e2e 31 | ``` 32 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter08/vuejs.spring-boot.mysql/front-end/public/favicon.ico -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter08/vuejs.spring-boot.mysql/front-end/src/assets/logo.png -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter08/vuejs.spring-boot.mysql/front-end/src/components/.gitkeep -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | 6 | Vue.config.productionTip = false 7 | 8 | new Vue({ 9 | router, 10 | store, 11 | render: h => h(App) 12 | }).$mount('#app') 13 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import LoginPage from '@/views/LoginPage' 4 | 5 | Vue.use(Router) 6 | 7 | export default new Router({ 8 | mode: 'history', 9 | base: process.env.BASE_URL, 10 | routes: [{ 11 | path: '/login', 12 | name: 'LoginPage', 13 | component: LoginPage 14 | }] 15 | }) 16 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | 9 | }, 10 | mutations: { 11 | 12 | }, 13 | actions: { 14 | 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/src/views/LoginPage.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/tests/e2e/specs/login.e2e.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'login test': function (browser) { 3 | browser 4 | .url(process.env.VUE_DEV_SERVER_URL + 'login') 5 | .waitForElementVisible('#app', 5000) 6 | .assert.containsText('h1', 'TaskAgile') 7 | .end() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/tests/unit/LoginPage.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import LoginPage from '@/views/LoginPage' 3 | 4 | describe('LoginPage.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(LoginPage) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('h1').textContent) 9 | .toEqual('TaskAgile') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/front-end/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | proxy: { 5 | '/api/*': { 6 | target: 'http://localhost:8080' 7 | } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/src/main/java/com/taskagile/TaskAgileApplication.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TaskAgileApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TaskAgileApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/pages/MainController.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.pages; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class MainController { 8 | 9 | @GetMapping(value = { "/", "/login" }) 10 | public String entry() { 11 | return "index"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/task_agile?useSSL=false 2 | spring.datasource.username= 3 | spring.datasource.password= 4 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 5 | -------------------------------------------------------------------------------- /Chapter08/vuejs.spring-boot.mysql/src/test/java/com/taskagile/TaskAgileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class TaskAgileApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | 27 | ### Application specific ### 28 | application-dev.properties 29 | src/main/resources/static/css/ 30 | src/main/resources/static/favicon.ico 31 | src/main/resources/static/js/ 32 | src/main/resources/templates/index.html 33 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter09/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/reports/ 6 | selenium-debug.log 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/README.md: -------------------------------------------------------------------------------- 1 | # TaskAgile Front End 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Run your unit tests 24 | ``` 25 | npm run test:unit 26 | ``` 27 | 28 | ### Run your end-to-end tests 29 | ``` 30 | npm run test:e2e 31 | ``` 32 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter09/vuejs.spring-boot.mysql/front-end/public/favicon.ico -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/public/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter09/vuejs.spring-boot.mysql/front-end/public/static/images/logo.png -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter09/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter09/vuejs.spring-boot.mysql/front-end/src/components/.gitkeep -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import LoginPage from '@/views/LoginPage' 4 | import RegisterPage from '@/views/RegisterPage' 5 | 6 | Vue.use(Router) 7 | 8 | export default new Router({ 9 | mode: 'history', 10 | base: process.env.BASE_URL, 11 | routes: [{ 12 | path: '/login', 13 | name: 'LoginPage', 14 | component: LoginPage 15 | }, { 16 | path: '/register', 17 | name: 'RegisterPage', 18 | component: RegisterPage 19 | }] 20 | }) 21 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/services/registration/__mocks__/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | register (detail) { 3 | return new Promise((resolve, reject) => { 4 | detail.emailAddress === 'sunny@taskagile.com' 5 | ? resolve({result: 'success'}) 6 | : reject(new Error('User already exist')) 7 | }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/services/registration/index.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | export default { 4 | /** 5 | * Register a new user 6 | * @param {Object} detail registration detail 7 | */ 8 | register (detail) { 9 | return new Promise((resolve, reject) => { 10 | axios.post('/registrations', detail).then(({data}) => { 11 | resolve(data) 12 | }).catch((error) => { 13 | reject(error) 14 | }) 15 | }) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | 9 | }, 10 | mutations: { 11 | 12 | }, 13 | actions: { 14 | 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/src/views/LoginPage.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/tests/e2e/specs/login.e2e.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'login test': function (browser) { 3 | browser 4 | .url(process.env.VUE_DEV_SERVER_URL + 'login') 5 | .waitForElementVisible('#app', 5000) 6 | .assert.containsText('h1', 'TaskAgile') 7 | .end() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/tests/unit/LoginPage.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import LoginPage from '@/views/LoginPage' 3 | 4 | describe('LoginPage.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(LoginPage) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('h1').textContent) 9 | .toEqual('TaskAgile') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/front-end/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | proxy: { 5 | '/api/*': { 6 | target: 'http://localhost:8080' 7 | } 8 | } 9 | }, 10 | configureWebpack: { 11 | entry: { 12 | app: './src/main.js', 13 | style: [ 14 | 'bootstrap/dist/css/bootstrap.min.css' 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/TaskAgileApplication.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TaskAgileApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TaskAgileApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/DomainEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | public interface DomainEventPublisher { 4 | 5 | /** 6 | * Publish a domain event 7 | */ 8 | void publish(DomainEvent event); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/DefaultMailManager.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class DefaultMailManager implements MailManager { 7 | 8 | @Override 9 | public void send(String emailAddress, String subject, String template, MessageVariable... variables) { 10 | // TODO implement this 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/MailManager.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface MailManager { 4 | 5 | /** 6 | * Send a message to a recipient 7 | * 8 | * @param emailAddress the recipient's email address 9 | * @param subject the subject key of the email 10 | * @param template the template file name of the email 11 | * @param variables message variables in the template file 12 | */ 13 | void send(String emailAddress, String subject, String template, MessageVariable... variables); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/model/AbstractBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractBaseEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -1153931912966528994L; 8 | 9 | public abstract boolean equals(Object obj); 10 | 11 | public abstract int hashCode(); 12 | 13 | public abstract String toString(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/security/PasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.security; 2 | 3 | public interface PasswordEncryptor { 4 | 5 | /** 6 | * Encrypt a raw password 7 | */ 8 | String encrypt(String rawPassword); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/security/PasswordEncryptorDelegator.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.security; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class PasswordEncryptorDelegator implements PasswordEncryptor { 7 | 8 | @Override 9 | public String encrypt(String rawPassword) { 10 | // TODO implement this 11 | return rawPassword; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/EmailAddressExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class EmailAddressExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/RegistrationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class RegistrationException extends Exception { 4 | 5 | private static final long serialVersionUID = -2737904013752279210L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UsernameExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UsernameExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/infrastructure/repository/HibernateSupport.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.infrastructure.repository; 2 | 3 | import org.hibernate.Session; 4 | 5 | import javax.persistence.EntityManager; 6 | 7 | abstract class HibernateSupport { 8 | 9 | EntityManager entityManager; 10 | 11 | HibernateSupport(EntityManager entityManager) { 12 | this.entityManager = entityManager; 13 | } 14 | 15 | Session getSession() { 16 | return entityManager.unwrap(Session.class); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/pages/MainController.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.pages; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class MainController { 8 | 9 | @GetMapping(value = { "/", "/login", "/register" }) 10 | public String entry() { 11 | return "index"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/task_agile?useSSL=false 2 | spring.datasource.username= 3 | spring.datasource.password= 4 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 5 | 6 | logging.level.com.taskagile=DEBUG 7 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/main/resources/static/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter09/vuejs.spring-boot.mysql/src/main/resources/static/static/images/logo.png -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/test/java/com/taskagile/TaskAgileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | @ActiveProfiles("test") 12 | public class TaskAgileApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:h2:mem:taskagile;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE 2 | spring.datasource.username=sa 3 | spring.datasource.password=sa 4 | spring.datasource.driver-class-name=org.h2.Driver 5 | 6 | spring.jpa.open-in-view=false 7 | spring.jpa.hibernate.ddl-auto=create-drop 8 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 9 | 10 | # logging.level.org.springframework=DEBUG 11 | # logging.level.org.springframework.boot=DEBUG 12 | -------------------------------------------------------------------------------- /Chapter09/vuejs.spring-boot.mysql/src/test/resources/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.hbm2ddl.auto=create-drop 2 | hibernate.dialect=org.hibernate.dialect.H2Dialect 3 | hibernate.show_sql=true 4 | hibernate.format_sql=true 5 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | 27 | ### Application specific ### 28 | application-dev.properties 29 | src/main/resources/static/css/ 30 | src/main/resources/static/favicon.ico 31 | src/main/resources/static/js/ 32 | src/main/resources/templates/index.html 33 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter10/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/reports/ 6 | /tests/e2e/data/user.js 7 | selenium-debug.log 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw* 26 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/README.md: -------------------------------------------------------------------------------- 1 | # TaskAgile Front End 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Run your unit tests 24 | ``` 25 | npm run test:unit 26 | ``` 27 | 28 | ### Run your end-to-end tests 29 | ``` 30 | npm run test:e2e 31 | ``` 32 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/nightwatch.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_settings: { 3 | default: { 4 | launch_url: (process.env.LAUNCH_URL || process.env.VUE_DEV_SERVER_URL) 5 | }, 6 | chrome: { 7 | desiredCapabilities: { 8 | browserName: "chrome", 9 | chromeOptions: { 10 | args: ["headless", "no-sandbox", "disable-gpu"] 11 | } 12 | } 13 | } 14 | }, 15 | page_objects_path: 'tests/e2e/page-objects', 16 | } 17 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter10/vuejs.spring-boot.mysql/front-end/public/favicon.ico -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/public/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter10/vuejs.spring-boot.mysql/front-end/public/static/images/logo.png -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter10/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 30 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/authentication.js: -------------------------------------------------------------------------------- 1 | export default { 2 | authenticate (detail) { 3 | return new Promise((resolve, reject) => { 4 | (detail.username === 'sunny' || detail.username === 'sunny@taskagile.com') && 5 | detail.password === 'JestRocks!' 6 | ? resolve({result: 'success'}) 7 | : reject(new Error('Invalid credentials')) 8 | }) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/registration.js: -------------------------------------------------------------------------------- 1 | export default { 2 | register (detail) { 3 | return new Promise((resolve, reject) => { 4 | detail.emailAddress === 'sunny@taskagile.com' 5 | ? resolve({result: 'success'}) 6 | : reject(new Error('User already exist')) 7 | }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/services/authentication.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Authenticate a login request 7 | * @param {Object} detail login detail 8 | */ 9 | authenticate (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/authentications', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/services/registration.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Register a new user 7 | * @param {Object} detail registration detail 8 | */ 9 | register (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/registrations', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | 9 | }, 10 | mutations: { 11 | 12 | }, 13 | actions: { 14 | 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/src/views/HomePage.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter10/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/HomePage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl 4 | }, 5 | elements: { 6 | pageTitle: { 7 | selector: 'h1.page-title' 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/LoginPage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl + 'login' 4 | }, 5 | elements: { 6 | app: '#app', 7 | logoImage: 'img.logo', 8 | usernameInput: '#username', 9 | passwordInput: '#password', 10 | submitButton: 'button[type=submit]', 11 | formError: '.failed' 12 | }, 13 | commands: [{ 14 | login: function (username, password) { 15 | this 16 | .setValue('@usernameInput', username) 17 | .setValue('@passwordInput', password) 18 | .click('@submitButton') 19 | } 20 | }] 21 | } 22 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/front-end/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | proxy: { 5 | '/api/*': { 6 | target: 'http://localhost:8080' 7 | } 8 | } 9 | }, 10 | configureWebpack: { 11 | entry: { 12 | app: './src/main.js', 13 | style: [ 14 | 'bootstrap/dist/css/bootstrap.min.css' 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/TaskAgileApplication.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TaskAgileApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TaskAgileApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/DomainEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | public interface DomainEventPublisher { 4 | 5 | /** 6 | * Publish a domain event 7 | */ 8 | void publish(DomainEvent event); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/MailManager.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface MailManager { 4 | 5 | /** 6 | * Send a message to a recipient 7 | * 8 | * @param emailAddress the recipient's email address 9 | * @param subject the subject key of the email 10 | * @param template the template file name of the email 11 | * @param variables message variables in the template file 12 | */ 13 | void send(String emailAddress, String subject, String template, MessageVariable... variables); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/Mailer.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface Mailer { 4 | 5 | /** 6 | * Send a message 7 | * 8 | * @param message the message instance 9 | */ 10 | void send(Message message); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/model/AbstractBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractBaseEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -1153931912966528994L; 8 | 9 | public abstract boolean equals(Object obj); 10 | 11 | public abstract int hashCode(); 12 | 13 | public abstract String toString(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/security/PasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.security; 2 | 3 | public interface PasswordEncryptor { 4 | 5 | /** 6 | * Encrypt a raw password 7 | */ 8 | String encrypt(String rawPassword); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/EmailAddressExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class EmailAddressExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/RegistrationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class RegistrationException extends Exception { 4 | 5 | private static final long serialVersionUID = -2737904013752279210L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UsernameExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UsernameExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/infrastructure/repository/HibernateSupport.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.infrastructure.repository; 2 | 3 | import org.hibernate.Session; 4 | 5 | import javax.persistence.EntityManager; 6 | 7 | abstract class HibernateSupport { 8 | 9 | EntityManager entityManager; 10 | 11 | HibernateSupport(EntityManager entityManager) { 12 | this.entityManager = entityManager; 13 | } 14 | 15 | Session getSession() { 16 | return entityManager.unwrap(Session.class); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/pages/MainController.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.pages; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class MainController { 8 | 9 | @GetMapping(value = { "/", "/login", "/register" }) 10 | public String entry() { 11 | return "index"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/resources/mail-templates/welcome.ftl: -------------------------------------------------------------------------------- 1 |

    Welcome!

    2 |

    Here is your registration information:

    3 |
      4 |
    • Username: ${user.username}
    • 5 |
    • Email Address: ${user.emailAddress}
    • 6 |
    7 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/main/resources/static/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter10/vuejs.spring-boot.mysql/src/main/resources/static/static/images/logo.png -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/test/java/com/taskagile/TaskAgileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | @ActiveProfiles("test") 12 | public class TaskAgileApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/test/resources/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.hbm2ddl.auto=create-drop 2 | hibernate.dialect=org.hibernate.dialect.H2Dialect 3 | hibernate.show_sql=true 4 | hibernate.format_sql=true 5 | -------------------------------------------------------------------------------- /Chapter10/vuejs.spring-boot.mysql/src/test/resources/mail-templates/test.ftl: -------------------------------------------------------------------------------- 1 | Hello, ${name} 2 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter11/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/reports/ 6 | /tests/e2e/data/user.js 7 | selenium-debug.log 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw* 26 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/README.md: -------------------------------------------------------------------------------- 1 | # TaskAgile Front End 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Run your unit tests 24 | ``` 25 | npm run test:unit 26 | ``` 27 | 28 | ### Run your end-to-end tests 29 | ``` 30 | npm run test:e2e 31 | ``` 32 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/nightwatch.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_settings: { 3 | default: { 4 | launch_url: (process.env.LAUNCH_URL || process.env.VUE_DEV_SERVER_URL) 5 | }, 6 | chrome: { 7 | desiredCapabilities: { 8 | browserName: "chrome", 9 | chromeOptions: { 10 | args: ["headless", "no-sandbox", "disable-gpu"] 11 | } 12 | } 13 | } 14 | }, 15 | page_objects_path: 'tests/e2e/page-objects', 16 | } 17 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter11/vuejs.spring-boot.mysql/front-end/public/favicon.ico -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter11/vuejs.spring-boot.mysql/front-end/public/images/logo.png -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter11/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 30 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import { enUS, zhCN } from './locale' 4 | 5 | Vue.use(VueI18n) 6 | 7 | // Create VueI18n instance with options 8 | export const i18n = new VueI18n({ 9 | locale: 'en_US', 10 | messages: { 11 | 'en_US': enUS, 12 | 'zh_CN': zhCN 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/locale/index.js: -------------------------------------------------------------------------------- 1 | import enUSMessages from './messages/en_US.json' 2 | import zhCNMessages from './messages/zh_CN.json' 3 | 4 | export const enUS = enUSMessages 5 | export const zhCN = zhCNMessages 6 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/locale/messages/zh_CN.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/authentication.js: -------------------------------------------------------------------------------- 1 | export default { 2 | authenticate (detail) { 3 | return new Promise((resolve, reject) => { 4 | (detail.username === 'sunny' || detail.username === 'sunny@taskagile.com') && 5 | detail.password === 'JestRocks!' 6 | ? resolve({result: 'success'}) 7 | : reject(new Error('Invalid credentials')) 8 | }) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/registration.js: -------------------------------------------------------------------------------- 1 | export default { 2 | register (detail) { 3 | return new Promise((resolve, reject) => { 4 | detail.emailAddress === 'sunny@taskagile.com' 5 | ? resolve({result: 'success'}) 6 | : reject(new Error('User already exist')) 7 | }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/authentication.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Authenticate a login request 7 | * @param {Object} detail login detail 8 | */ 9 | authenticate (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/authentications', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/boards.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Create a new board 7 | * @param {*} detail the board detail 8 | */ 9 | create (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/boards', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/me.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Fetch current user's name, boards, and teams 7 | */ 8 | getMyData () { 9 | return new Promise((resolve, reject) => { 10 | axios.get('/me').then(({data}) => { 11 | resolve(data) 12 | }).catch((error) => { 13 | reject(errorParser.parse(error)) 14 | }) 15 | }) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/registration.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Register a new user 7 | * @param {Object} detail registration detail 8 | */ 9 | register (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/registrations', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/services/teams.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Create a team 7 | * @param {*} detail the detail of the team 8 | */ 9 | create (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/teams', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/store/actions.js: -------------------------------------------------------------------------------- 1 | import meService from '@/services/me' 2 | 3 | export const getMyData = ({ commit }) => { 4 | meService.getMyData().then(data => { 5 | commit('updateMyData', data) 6 | }) 7 | } 8 | 9 | export const addTeam = ({commit}, team) => { 10 | commit('addTeam', team) 11 | } 12 | 13 | export const addBoard = ({commit}, board) => { 14 | commit('addBoard', board) 15 | } 16 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/store/getters.js: -------------------------------------------------------------------------------- 1 | export const user = state => state.user 2 | 3 | export const hasBoards = state => { 4 | return state.boards.length > 0 5 | } 6 | 7 | export const personalBoards = state => { 8 | return state.boards.filter(board => board.teamId === 0) 9 | } 10 | 11 | export const teamBoards = state => { 12 | const teams = [] 13 | 14 | state.teams.forEach(team => { 15 | teams.push({ 16 | id: team.id, 17 | name: team.name, 18 | boards: state.boards.filter(board => board.teamId === team.id) 19 | }) 20 | }) 21 | 22 | return teams 23 | } 24 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | updateMyData (state, data) { 3 | state.user.name = data.user.name 4 | state.teams = data.teams 5 | state.boards = data.boards 6 | }, 7 | addTeam (state, team) { 8 | state.teams.push(team) 9 | }, 10 | addBoard (state, board) { 11 | state.boards.push(board) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/src/views/BoardPage.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 20 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter11/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/HomePage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl 4 | }, 5 | elements: { 6 | logoImage: { 7 | selector: '.logo img' 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/LoginPage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl + 'login' 4 | }, 5 | elements: { 6 | app: '#app', 7 | logoImage: 'img.logo', 8 | usernameInput: '#username', 9 | passwordInput: '#password', 10 | submitButton: 'button[type=submit]', 11 | formError: '.failed' 12 | }, 13 | commands: [{ 14 | login: function (username, password) { 15 | this 16 | .setValue('@usernameInput', username) 17 | .setValue('@passwordInput', password) 18 | .click('@submitButton') 19 | } 20 | }] 21 | } 22 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/front-end/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | proxy: { 5 | '/api/*': { 6 | target: 'http://localhost:8080' 7 | } 8 | } 9 | }, 10 | configureWebpack: { 11 | entry: { 12 | app: './src/main.js', 13 | style: [ 14 | 'bootstrap/dist/css/bootstrap.min.css' 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/TaskAgileApplication.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TaskAgileApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TaskAgileApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/application/commands/CreateTeamCommand.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.application.commands; 2 | 3 | import com.taskagile.domain.model.user.UserId; 4 | 5 | public class CreateTeamCommand { 6 | 7 | private UserId userId; 8 | private String name; 9 | 10 | public CreateTeamCommand(UserId userId, String name) { 11 | this.userId = userId; 12 | this.name = name; 13 | } 14 | 15 | public UserId getUserId() { 16 | return userId; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/DomainEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | public interface DomainEventPublisher { 4 | 5 | /** 6 | * Publish a domain event 7 | */ 8 | void publish(DomainEvent event); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/MailManager.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface MailManager { 4 | 5 | /** 6 | * Send a message to a recipient 7 | * 8 | * @param emailAddress the recipient's email address 9 | * @param subject the subject key of the email 10 | * @param template the template file name of the email 11 | * @param variables message variables in the template file 12 | */ 13 | void send(String emailAddress, String subject, String template, MessageVariable... variables); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/Mailer.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface Mailer { 4 | 5 | /** 6 | * Send a message 7 | * 8 | * @param message the message instance 9 | */ 10 | void send(Message message); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/model/AbstractBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractBaseEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -1153931912966528994L; 8 | 9 | public abstract boolean equals(Object obj); 10 | 11 | public abstract int hashCode(); 12 | 13 | public abstract String toString(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/model/AbstractBaseId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractBaseId implements Serializable { 6 | 7 | private static final long serialVersionUID = 3435210296634626689L; 8 | 9 | private long id; 10 | 11 | public AbstractBaseId(long id) { 12 | this.id = id; 13 | } 14 | 15 | public long value() { 16 | return id; 17 | } 18 | 19 | public boolean isValid() { 20 | return id > 0; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/security/PasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.security; 2 | 3 | public interface PasswordEncryptor { 4 | 5 | /** 6 | * Encrypt a raw password 7 | */ 8 | String encrypt(String rawPassword); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/board/BoardId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.board; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class BoardId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 6059316483218660038L; 8 | 9 | public BoardId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/board/BoardMemberRepository.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.board; 2 | 3 | public interface BoardMemberRepository { 4 | 5 | /** 6 | * Save board member 7 | * 8 | * @param boardMember the board member to save 9 | */ 10 | void save(BoardMember boardMember); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/board/events/BoardCreatedEvent.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.board.events; 2 | 3 | import com.taskagile.domain.common.event.DomainEvent; 4 | import com.taskagile.domain.model.board.Board; 5 | 6 | public class BoardCreatedEvent extends DomainEvent { 7 | 8 | private static final long serialVersionUID = -8698981115023240376L; 9 | 10 | private Board board; 11 | 12 | public BoardCreatedEvent(Object source, Board board) { 13 | super(source); 14 | this.board = board; 15 | } 16 | 17 | public Board getBoard() { 18 | return board; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/team/TeamId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.team; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class TeamId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 5572119730009957102L; 8 | 9 | public TeamId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/team/TeamRepository.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.team; 2 | 3 | import com.taskagile.domain.model.user.UserId; 4 | 5 | import java.util.List; 6 | 7 | public interface TeamRepository { 8 | 9 | /** 10 | * Find the teams that created by a user 11 | * 12 | * @param userId the id of the user 13 | * @return a list of teams or an empty list if none found 14 | */ 15 | List findTeamsByUserId(UserId userId); 16 | 17 | /** 18 | * Save a team 19 | * 20 | * @param team the team to save 21 | */ 22 | void save(Team team); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/team/events/TeamCreatedEvent.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.team.events; 2 | 3 | import com.taskagile.domain.common.event.DomainEvent; 4 | import com.taskagile.domain.model.team.Team; 5 | 6 | public class TeamCreatedEvent extends DomainEvent { 7 | 8 | private static final long serialVersionUID = 2714833255396717504L; 9 | 10 | private Team team; 11 | 12 | public TeamCreatedEvent(Object source, Team team) { 13 | super(source); 14 | this.team = team; 15 | } 16 | 17 | public Team getTeam() { 18 | return team; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/EmailAddressExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class EmailAddressExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/RegistrationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class RegistrationException extends Exception { 4 | 5 | private static final long serialVersionUID = -2737904013752279210L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UserId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class UserId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -3316570974935023332L; 8 | 9 | public UserId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UsernameExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UsernameExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/infrastructure/repository/HibernateBoardMemberRepository.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.infrastructure.repository; 2 | 3 | import com.taskagile.domain.model.board.BoardMember; 4 | import com.taskagile.domain.model.board.BoardMemberRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import javax.persistence.EntityManager; 8 | 9 | @Repository 10 | public class HibernateBoardMemberRepository extends HibernateSupport implements BoardMemberRepository { 11 | 12 | HibernateBoardMemberRepository(EntityManager entityManager) { 13 | super(entityManager); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/pages/MainController.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.pages; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class MainController { 8 | 9 | @GetMapping(value = { "/", "/login", "/register" }) 10 | public String entry() { 11 | return "index"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/CreateTeamPayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | import com.taskagile.domain.application.commands.CreateTeamCommand; 4 | import com.taskagile.domain.model.user.UserId; 5 | 6 | public class CreateTeamPayload { 7 | 8 | private String name; 9 | 10 | public CreateTeamCommand toCommand(UserId userId) { 11 | return new CreateTeamCommand(userId, name); 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/CreateBoardResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.board.Board; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class CreateBoardResult { 7 | 8 | public static ResponseEntity build(Board board) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", board.getId().value()) 11 | .add("name", board.getName()) 12 | .add("description", board.getDescription()) 13 | .add("teamId", board.getTeamId().value()); 14 | return Result.ok(apiResult); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/CreateTeamResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.team.Team; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class CreateTeamResult { 7 | 8 | public static ResponseEntity build(Team team) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", team.getId().value()) 11 | .add("name", team.getName()); 12 | return Result.ok(apiResult); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/resources/mail-templates/welcome.ftl: -------------------------------------------------------------------------------- 1 |

    Welcome!

    2 |

    Here is your registration information:

    3 |
      4 |
    • Username: ${user.username}
    • 5 |
    • Email Address: ${user.emailAddress}
    • 6 |
    7 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/main/resources/spy.properties: -------------------------------------------------------------------------------- 1 | driverlist=com.mysql.jdbc.Driver 2 | logfile=spy.log 3 | dateformat=yyyy-MM-dd HH:mm:ss.SS 4 | logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat 5 | customLogMessageFormat=- %(currentTime) | took %(executionTime)ms | connection %(connectionId) \nEXPLAIN %(sql);\n 6 | filter=true 7 | exclude=select 1 from dual 8 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/test/java/com/taskagile/TaskAgileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | @ActiveProfiles("test") 12 | public class TaskAgileApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/test/resources/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.hbm2ddl.auto=create-drop 2 | hibernate.dialect=org.hibernate.dialect.H2Dialect 3 | hibernate.show_sql=true 4 | hibernate.format_sql=true 5 | -------------------------------------------------------------------------------- /Chapter11/vuejs.spring-boot.mysql/src/test/resources/mail-templates/test.ftl: -------------------------------------------------------------------------------- 1 | Hello, ${name} 2 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter12/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/reports/ 6 | /tests/e2e/data/user.js 7 | selenium-debug.log 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw* 26 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/README.md: -------------------------------------------------------------------------------- 1 | # TaskAgile Front End 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Run your unit tests 24 | ``` 25 | npm run test:unit 26 | ``` 27 | 28 | ### Run your end-to-end tests 29 | ``` 30 | npm run test:e2e 31 | ``` 32 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/nightwatch.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_settings: { 3 | default: { 4 | launch_url: (process.env.LAUNCH_URL || process.env.VUE_DEV_SERVER_URL) 5 | }, 6 | chrome: { 7 | desiredCapabilities: { 8 | browserName: "chrome", 9 | chromeOptions: { 10 | args: ["headless", "no-sandbox", "disable-gpu"] 11 | } 12 | } 13 | } 14 | }, 15 | page_objects_path: 'tests/e2e/page-objects', 16 | } 17 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter12/vuejs.spring-boot.mysql/front-end/public/favicon.ico -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter12/vuejs.spring-boot.mysql/front-end/public/images/logo.png -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter12/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 30 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/event-bus.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | const bus = new Vue({}) 4 | 5 | export default bus 6 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import { enUS, zhCN } from './locale' 4 | 5 | Vue.use(VueI18n) 6 | 7 | // Create VueI18n instance with options 8 | export const i18n = new VueI18n({ 9 | locale: 'en_US', 10 | messages: { 11 | 'en_US': enUS, 12 | 'zh_CN': zhCN 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/locale/index.js: -------------------------------------------------------------------------------- 1 | import enUSMessages from './messages/en_US.json' 2 | import zhCNMessages from './messages/zh_CN.json' 3 | 4 | export const enUS = enUSMessages 5 | export const zhCN = zhCNMessages 6 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/locale/messages/zh_CN.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/authentication.js: -------------------------------------------------------------------------------- 1 | export default { 2 | authenticate (detail) { 3 | return new Promise((resolve, reject) => { 4 | (detail.username === 'sunny' || detail.username === 'sunny@taskagile.com') && 5 | detail.password === 'JestRocks!' 6 | ? resolve({result: 'success'}) 7 | : reject(new Error('Invalid credentials')) 8 | }) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/registration.js: -------------------------------------------------------------------------------- 1 | export default { 2 | register (detail) { 3 | return new Promise((resolve, reject) => { 4 | detail.emailAddress === 'sunny@taskagile.com' 5 | ? resolve({result: 'success'}) 6 | : reject(new Error('User already exist')) 7 | }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/services/authentication.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Authenticate a login request 7 | * @param {Object} detail login detail 8 | */ 9 | authenticate (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/authentications', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/services/registration.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Register a new user 7 | * @param {Object} detail registration detail 8 | */ 9 | register (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/registrations', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/services/teams.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Create a team 7 | * @param {*} detail the detail of the team 8 | */ 9 | create (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/teams', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/store/actions.js: -------------------------------------------------------------------------------- 1 | import meService from '@/services/me' 2 | 3 | export const logout = ({ commit }) => { 4 | commit('logout') 5 | } 6 | 7 | export const getMyData = ({ commit }) => { 8 | meService.getMyData().then(data => { 9 | commit('updateMyData', data) 10 | }) 11 | } 12 | 13 | export const addTeam = ({commit}, team) => { 14 | commit('addTeam', team) 15 | } 16 | 17 | export const addBoard = ({commit}, board) => { 18 | commit('addBoard', board) 19 | } 20 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/store/getters.js: -------------------------------------------------------------------------------- 1 | export const user = state => state.user 2 | 3 | export const hasBoards = state => { 4 | return state.boards.length > 0 5 | } 6 | 7 | export const personalBoards = state => { 8 | return state.boards.filter(board => board.teamId === 0) 9 | } 10 | 11 | export const teamBoards = state => { 12 | const teams = [] 13 | 14 | state.teams.forEach(team => { 15 | teams.push({ 16 | id: team.id, 17 | name: team.name, 18 | boards: state.boards.filter(board => board.teamId === team.id) 19 | }) 20 | }) 21 | 22 | return teams 23 | } 24 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | updateMyData (state, data) { 3 | state.user.name = data.user.name 4 | state.user.authenticated = true 5 | state.teams = data.teams 6 | state.boards = data.boards 7 | }, 8 | logout (state) { 9 | state.user.name = '' 10 | state.user.authenticated = false 11 | state.teams = [] 12 | state.boards = [] 13 | }, 14 | addTeam (state, team) { 15 | state.teams.push(team) 16 | }, 17 | addBoard (state, board) { 18 | state.boards.push(board) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/src/utils/notify.js: -------------------------------------------------------------------------------- 1 | import Noty from 'noty' 2 | import 'noty/lib/noty.css' 3 | import 'noty/lib/themes/relax.css' 4 | 5 | const showError = function (errorMessage) { 6 | new Noty({ 7 | type: 'error', 8 | theme: 'relax', 9 | closeWith: ['click', 'button'], 10 | text: errorMessage 11 | }).show() 12 | } 13 | 14 | export default { 15 | error: showError 16 | } 17 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter12/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/HomePage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl 4 | }, 5 | elements: { 6 | logoImage: { 7 | selector: '.logo img' 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/LoginPage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl + 'login' 4 | }, 5 | elements: { 6 | app: '#app', 7 | logoImage: 'img.logo', 8 | usernameInput: '#username', 9 | passwordInput: '#password', 10 | submitButton: 'button[type=submit]', 11 | formError: '.failed' 12 | }, 13 | commands: [{ 14 | login: function (username, password) { 15 | this 16 | .setValue('@usernameInput', username) 17 | .setValue('@passwordInput', password) 18 | .click('@submitButton') 19 | } 20 | }] 21 | } 22 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/front-end/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | proxy: { 5 | '/api/*': { 6 | target: 'http://localhost:8080' 7 | }, 8 | '/rt/*': { 9 | target: 'http://localhost:8080' 10 | } 11 | } 12 | }, 13 | configureWebpack: { 14 | entry: { 15 | app: './src/main.js', 16 | style: [ 17 | 'bootstrap/dist/css/bootstrap.min.css' 18 | ] 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/TaskAgileApplication.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TaskAgileApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TaskAgileApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/application/commands/CreateTeamCommand.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.application.commands; 2 | 3 | import com.taskagile.domain.model.user.UserId; 4 | 5 | public class CreateTeamCommand { 6 | 7 | private UserId userId; 8 | private String name; 9 | 10 | public CreateTeamCommand(UserId userId, String name) { 11 | this.userId = userId; 12 | this.name = name; 13 | } 14 | 15 | public UserId getUserId() { 16 | return userId; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/DomainEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | public interface DomainEventPublisher { 4 | 5 | /** 6 | * Publish a domain event 7 | */ 8 | void publish(DomainEvent event); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/MailManager.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface MailManager { 4 | 5 | /** 6 | * Send a message to a recipient 7 | * 8 | * @param emailAddress the recipient's email address 9 | * @param subject the subject key of the email 10 | * @param template the template file name of the email 11 | * @param variables message variables in the template file 12 | */ 13 | void send(String emailAddress, String subject, String template, MessageVariable... variables); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/Mailer.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface Mailer { 4 | 5 | /** 6 | * Send a message 7 | * 8 | * @param message the message instance 9 | */ 10 | void send(Message message); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/model/AbstractBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractBaseEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -1153931912966528994L; 8 | 9 | public abstract boolean equals(Object obj); 10 | 11 | public abstract int hashCode(); 12 | 13 | public abstract String toString(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/security/PasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.security; 2 | 3 | public interface PasswordEncryptor { 4 | 5 | /** 6 | * Encrypt a raw password 7 | */ 8 | String encrypt(String rawPassword); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/board/BoardId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.board; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class BoardId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 6059316483218660038L; 8 | 9 | public BoardId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/board/events/BoardCreatedEvent.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.board.events; 2 | 3 | import com.taskagile.domain.common.event.DomainEvent; 4 | import com.taskagile.domain.model.board.Board; 5 | 6 | public class BoardCreatedEvent extends DomainEvent { 7 | 8 | private static final long serialVersionUID = -8698981115023240376L; 9 | 10 | private Board board; 11 | 12 | public BoardCreatedEvent(Object source, Board board) { 13 | super(source); 14 | this.board = board; 15 | } 16 | 17 | public Board getBoard() { 18 | return board; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/card/CardId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.card; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class CardId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -6244517408526568385L; 8 | 9 | public CardId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/card/events/CardAddedEvent.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.card.events; 2 | 3 | import com.taskagile.domain.common.event.DomainEvent; 4 | import com.taskagile.domain.model.card.Card; 5 | 6 | public class CardAddedEvent extends DomainEvent { 7 | 8 | private static final long serialVersionUID = 26551114425630902L; 9 | 10 | private Card card; 11 | 12 | public CardAddedEvent(Object source, Card card) { 13 | super(source); 14 | this.card = card; 15 | } 16 | 17 | public Card getCard() { 18 | return card; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/cardlist/CardListId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.cardlist; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class CardListId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -3248111062745994646L; 8 | 9 | public CardListId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/cardlist/CardListPosition.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.cardlist; 2 | 3 | public class CardListPosition { 4 | 5 | private long cardListId; 6 | private int position; 7 | 8 | public CardListId getCardListId() { 9 | return new CardListId(cardListId); 10 | } 11 | 12 | public int getPosition() { 13 | return position; 14 | } 15 | 16 | public void setCardListId(long cardListId) { 17 | this.cardListId = cardListId; 18 | } 19 | 20 | public void setPosition(int position) { 21 | this.position = position; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/team/TeamId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.team; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class TeamId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 5572119730009957102L; 8 | 9 | public TeamId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/team/events/TeamCreatedEvent.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.team.events; 2 | 3 | import com.taskagile.domain.common.event.DomainEvent; 4 | import com.taskagile.domain.model.team.Team; 5 | 6 | public class TeamCreatedEvent extends DomainEvent { 7 | 8 | private static final long serialVersionUID = 2714833255396717504L; 9 | 10 | private Team team; 11 | 12 | public TeamCreatedEvent(Object source, Team team) { 13 | super(source); 14 | this.team = team; 15 | } 16 | 17 | public Team getTeam() { 18 | return team; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/EmailAddressExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class EmailAddressExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/RegistrationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class RegistrationException extends Exception { 4 | 5 | private static final long serialVersionUID = -2737904013752279210L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UserId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class UserId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -3316570974935023332L; 8 | 9 | public UserId(long id) { 10 | super(id); 11 | } 12 | 13 | public String toString() { 14 | return String.valueOf(value()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UserNotFoundException extends Exception { 4 | 5 | private static final long serialVersionUID = -6826272470679025298L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UsernameExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UsernameExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/pages/MainController.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.pages; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class MainController { 8 | 9 | @GetMapping(value = { "/", "/login", "/register" }) 10 | public String entry() { 11 | return "index"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/AddBoardMemberPayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | public class AddBoardMemberPayload { 4 | 5 | private String usernameOrEmailAddress; 6 | 7 | public String getUsernameOrEmailAddress() { 8 | return usernameOrEmailAddress; 9 | } 10 | 11 | public void setUsernameOrEmailAddress(String usernameOrEmailAddress) { 12 | this.usernameOrEmailAddress = usernameOrEmailAddress; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/CreateTeamPayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | import com.taskagile.domain.application.commands.CreateTeamCommand; 4 | import com.taskagile.domain.model.user.UserId; 5 | 6 | public class CreateTeamPayload { 7 | 8 | private String name; 9 | 10 | public CreateTeamCommand toCommand(UserId userId) { 11 | return new CreateTeamCommand(userId, name); 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/AddCardListResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.cardlist.CardList; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class AddCardListResult { 7 | 8 | public static ResponseEntity build(CardList cardList) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", cardList.getId().value()) 11 | .add("name", cardList.getName()); 12 | return Result.ok(apiResult); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/AddCardResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.card.Card; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class AddCardResult { 7 | 8 | public static ResponseEntity build(Card card) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", card.getId().value()) 11 | .add("title", card.getTitle()) 12 | .add("position", card.getPosition()); 13 | return Result.ok(apiResult); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/CreateBoardResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.board.Board; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class CreateBoardResult { 7 | 8 | public static ResponseEntity build(Board board) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", board.getId().value()) 11 | .add("name", board.getName()) 12 | .add("description", board.getDescription()) 13 | .add("teamId", board.getTeamId().value()); 14 | return Result.ok(apiResult); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/CreateTeamResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.team.Team; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class CreateTeamResult { 7 | 8 | public static ResponseEntity build(Team team) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", team.getId().value()) 11 | .add("name", team.getName()); 12 | return Result.ok(apiResult); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/Action.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Target({ElementType.METHOD}) 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Documented 8 | public @interface Action { 9 | 10 | /** 11 | * The action pattern. It needs to be an exact match. 12 | *

    For example, "subscribe" 13 | */ 14 | String value() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/ChannelHandlers.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | public final class ChannelHandlers { 4 | 5 | public static String getPattern(ChannelHandler channelHandler) { 6 | if (!"".equals(channelHandler.pattern())) { 7 | return channelHandler.pattern(); 8 | } 9 | return channelHandler.value(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/ChannelValue.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Mark a parameter as the channel's value 7 | */ 8 | @Target(ElementType.PARAMETER) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface ChannelValue { 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/Payload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Mark a parameter as the payload in an action method of channel handler. 7 | */ 8 | @Target(ElementType.PARAMETER) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface Payload { 12 | } 13 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/resources/mail-templates/welcome.ftl: -------------------------------------------------------------------------------- 1 |

    Welcome!

    2 |

    Here is your registration information:

    3 |
      4 |
    • Username: ${user.username}
    • 5 |
    • Email Address: ${user.emailAddress}
    • 6 |
    7 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/main/resources/spy.properties: -------------------------------------------------------------------------------- 1 | driverlist=com.mysql.jdbc.Driver 2 | logfile=spy.log 3 | dateformat=yyyy-MM-dd HH:mm:ss.SS 4 | logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat 5 | customLogMessageFormat=- %(currentTime) | took %(executionTime)ms | connection %(connectionId) \nEXPLAIN %(sql);\n 6 | filter=true 7 | exclude=select 1 from dual 8 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/test/java/com/taskagile/TaskAgileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | @ActiveProfiles("test") 12 | public class TaskAgileApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/test/resources/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.hbm2ddl.auto=create-drop 2 | hibernate.dialect=org.hibernate.dialect.H2Dialect 3 | hibernate.show_sql=true 4 | hibernate.format_sql=true 5 | -------------------------------------------------------------------------------- /Chapter12/vuejs.spring-boot.mysql/src/test/resources/mail-templates/test.ftl: -------------------------------------------------------------------------------- 1 | Hello, ${name} 2 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter13/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/reports/ 6 | /tests/e2e/data/user.js 7 | selenium-debug.log 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw* 26 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/README.md: -------------------------------------------------------------------------------- 1 | # TaskAgile Front End 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Run your unit tests 24 | ``` 25 | npm run test:unit 26 | ``` 27 | 28 | ### Run your end-to-end tests 29 | ``` 30 | npm run test:e2e 31 | ``` 32 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/nightwatch.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_settings: { 3 | default: { 4 | launch_url: (process.env.LAUNCH_URL || process.env.VUE_DEV_SERVER_URL) 5 | }, 6 | chrome: { 7 | desiredCapabilities: { 8 | browserName: "chrome", 9 | chromeOptions: { 10 | args: ["headless", "no-sandbox", "disable-gpu"] 11 | } 12 | } 13 | } 14 | }, 15 | page_objects_path: 'tests/e2e/page-objects', 16 | } 17 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter13/vuejs.spring-boot.mysql/front-end/public/favicon.ico -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter13/vuejs.spring-boot.mysql/front-end/public/images/logo.png -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter13/vuejs.spring-boot.mysql/front-end/src/assets/.gitkeep -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 30 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/event-bus.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | const bus = new Vue({}) 4 | 5 | export default bus 6 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import { enUS, zhCN } from './locale' 4 | 5 | Vue.use(VueI18n) 6 | 7 | // Create VueI18n instance with options 8 | export const i18n = new VueI18n({ 9 | locale: 'en_US', 10 | messages: { 11 | 'en_US': enUS, 12 | 'zh_CN': zhCN 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/locale/index.js: -------------------------------------------------------------------------------- 1 | import enUSMessages from './messages/en_US.json' 2 | import zhCNMessages from './messages/zh_CN.json' 3 | 4 | export const enUS = enUSMessages 5 | export const zhCN = zhCNMessages 6 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/locale/messages/zh_CN.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/authentication.js: -------------------------------------------------------------------------------- 1 | export default { 2 | authenticate (detail) { 3 | return new Promise((resolve, reject) => { 4 | (detail.username === 'sunny' || detail.username === 'sunny@taskagile.com') && 5 | detail.password === 'JestRocks!' 6 | ? resolve({result: 'success'}) 7 | : reject(new Error('Invalid credentials')) 8 | }) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/services/__mocks__/registration.js: -------------------------------------------------------------------------------- 1 | export default { 2 | register (detail) { 3 | return new Promise((resolve, reject) => { 4 | detail.emailAddress === 'sunny@taskagile.com' 5 | ? resolve({result: 'success'}) 6 | : reject(new Error('User already exist')) 7 | }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/services/authentication.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Authenticate a login request 7 | * @param {Object} detail login detail 8 | */ 9 | authenticate (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/authentications', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/services/registration.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Register a new user 7 | * @param {Object} detail registration detail 8 | */ 9 | register (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/registrations', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/services/teams.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import errorParser from '@/utils/error-parser' 3 | 4 | export default { 5 | /** 6 | * Create a team 7 | * @param {*} detail the detail of the team 8 | */ 9 | create (detail) { 10 | return new Promise((resolve, reject) => { 11 | axios.post('/teams', detail).then(({data}) => { 12 | resolve(data) 13 | }).catch((error) => { 14 | reject(errorParser.parse(error)) 15 | }) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/store/actions.js: -------------------------------------------------------------------------------- 1 | import meService from '@/services/me' 2 | 3 | export const logout = ({ commit }) => { 4 | commit('logout') 5 | } 6 | 7 | export const getMyData = ({ commit }) => { 8 | meService.getMyData().then(data => { 9 | commit('updateMyData', data) 10 | }) 11 | } 12 | 13 | export const addTeam = ({commit}, team) => { 14 | commit('addTeam', team) 15 | } 16 | 17 | export const addBoard = ({commit}, board) => { 18 | commit('addBoard', board) 19 | } 20 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/store/getters.js: -------------------------------------------------------------------------------- 1 | export const user = state => state.user 2 | 3 | export const hasBoards = state => { 4 | return state.boards.length > 0 5 | } 6 | 7 | export const personalBoards = state => { 8 | return state.boards.filter(board => board.teamId === 0) 9 | } 10 | 11 | export const teamBoards = state => { 12 | const teams = [] 13 | 14 | state.teams.forEach(team => { 15 | teams.push({ 16 | id: team.id, 17 | name: team.name, 18 | boards: state.boards.filter(board => board.teamId === team.id) 19 | }) 20 | }) 21 | 22 | return teams 23 | } 24 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/store/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | updateMyData (state, data) { 3 | state.user.name = data.user.name 4 | state.user.authenticated = true 5 | state.teams = data.teams 6 | state.boards = data.boards 7 | }, 8 | logout (state) { 9 | state.user.name = '' 10 | state.user.authenticated = false 11 | state.teams = [] 12 | state.boards = [] 13 | }, 14 | addTeam (state, team) { 15 | state.teams.push(team) 16 | }, 17 | addBoard (state, board) { 18 | state.boards.push(board) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/src/utils/notify.js: -------------------------------------------------------------------------------- 1 | import Noty from 'noty' 2 | 3 | const showError = function (errorMessage) { 4 | new Noty({ 5 | type: 'error', 6 | theme: 'relax', 7 | closeWith: ['click', 'button'], 8 | text: errorMessage 9 | }).show() 10 | } 11 | 12 | const closeAll = function () { 13 | Noty.closeAll() 14 | } 15 | 16 | export default { 17 | error: showError, 18 | closeAll: closeAll 19 | } 20 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/spring-vuejs/4943085e02331cfb8f6278bbd92d16cb4de8f3c7/Chapter13/vuejs.spring-boot.mysql/front-end/tests/e2e/data/.gitkeep -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/HomePage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl 4 | }, 5 | elements: { 6 | logoImage: { 7 | selector: '.logo img' 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/tests/e2e/page-objects/LoginPage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: function () { 3 | return this.api.launchUrl + 'login' 4 | }, 5 | elements: { 6 | app: '#app', 7 | logoImage: 'img.logo', 8 | usernameInput: '#username', 9 | passwordInput: '#password', 10 | submitButton: 'button[type=submit]', 11 | formError: '.failed' 12 | }, 13 | commands: [{ 14 | login: function (username, password) { 15 | this 16 | .setValue('@usernameInput', username) 17 | .setValue('@passwordInput', password) 18 | .click('@submitButton') 19 | } 20 | }] 21 | } 22 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/front-end/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/TaskAgileApplication.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.ServletComponentScan; 6 | 7 | @ServletComponentScan( 8 | basePackages = {"com.taskagile.infrastructure.file.local"} 9 | ) 10 | @SpringBootApplication 11 | public class TaskAgileApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(TaskAgileApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/application/ActivityService.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.application; 2 | 3 | import com.taskagile.domain.model.activity.Activity; 4 | 5 | public interface ActivityService { 6 | 7 | /** 8 | * Save an activity 9 | * 10 | * @param activity the activity instance 11 | */ 12 | void saveActivity(Activity activity); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/application/commands/AddCardCommentCommand.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.application.commands; 2 | 3 | import com.taskagile.domain.model.card.CardId; 4 | 5 | public class AddCardCommentCommand extends UserCommand { 6 | 7 | private CardId cardId; 8 | private String comment; 9 | 10 | public AddCardCommentCommand(CardId cardId, String comment) { 11 | this.cardId = cardId; 12 | this.comment = comment; 13 | } 14 | 15 | public CardId getCardId() { 16 | return cardId; 17 | } 18 | 19 | public String getComment() { 20 | return comment; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/application/commands/ChangeCardTitleCommand.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.application.commands; 2 | 3 | import com.taskagile.domain.model.card.CardId; 4 | 5 | public class ChangeCardTitleCommand extends UserCommand { 6 | 7 | private CardId cardId; 8 | private String title; 9 | 10 | public ChangeCardTitleCommand(CardId cardId, String title) { 11 | this.cardId = cardId; 12 | this.title = title; 13 | } 14 | 15 | public CardId getCardId() { 16 | return cardId; 17 | } 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/application/commands/CreateTeamCommand.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.application.commands; 2 | 3 | public class CreateTeamCommand extends UserCommand { 4 | 5 | private String name; 6 | 7 | public CreateTeamCommand(String name) { 8 | this.name = name; 9 | } 10 | 11 | public String getName() { 12 | return name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/DomainEventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | public interface DomainEventPublisher { 4 | 5 | /** 6 | * Publish a domain event 7 | */ 8 | void publish(DomainEvent event); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/TriggeredBy.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | import com.taskagile.domain.model.user.UserId; 4 | import com.taskagile.utils.IpAddress; 5 | 6 | public interface TriggeredBy { 7 | 8 | /** 9 | * Get the id of the user who triggered this command 10 | * 11 | * @return a user's id 12 | */ 13 | UserId getUserId(); 14 | 15 | /** 16 | * Get the IP address where the request originated from 17 | * 18 | * @return an IP address 19 | */ 20 | IpAddress getIpAddress(); 21 | } 22 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/event/TriggeredFrom.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.event; 2 | 3 | import com.taskagile.utils.IpAddress; 4 | 5 | public interface TriggeredFrom { 6 | 7 | /** 8 | * Get the IP address where the request originated from 9 | * 10 | * @return an IP address 11 | */ 12 | IpAddress getIpAddress(); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/file/FileStorageException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.file; 2 | 3 | public class FileStorageException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = -5546874656158296944L; 6 | 7 | public FileStorageException(String message) { 8 | super(message); 9 | } 10 | 11 | public FileStorageException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/MailManager.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface MailManager { 4 | 5 | /** 6 | * Send a message to a recipient 7 | * 8 | * @param emailAddress the recipient's email address 9 | * @param subject the subject key of the email 10 | * @param template the template file name of the email 11 | * @param variables message variables in the template file 12 | */ 13 | void send(String emailAddress, String subject, String template, MessageVariable... variables); 14 | } 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/mail/Mailer.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.mail; 2 | 3 | public interface Mailer { 4 | 5 | /** 6 | * Send a message 7 | * 8 | * @param message the message instance 9 | */ 10 | void send(Message message); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/model/AbstractBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractBaseEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -1153931912966528994L; 8 | 9 | public abstract boolean equals(Object obj); 10 | 11 | public abstract int hashCode(); 12 | 13 | public abstract String toString(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/common/security/PasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.common.security; 2 | 3 | public interface PasswordEncryptor { 4 | 5 | /** 6 | * Encrypt a raw password 7 | */ 8 | String encrypt(String rawPassword); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/activity/ActivityId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.activity; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class ActivityId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 4553347149349199653L; 8 | 9 | public ActivityId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/activity/ActivityRepository.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.activity; 2 | 3 | import com.taskagile.domain.model.card.CardId; 4 | 5 | import java.util.List; 6 | 7 | public interface ActivityRepository { 8 | 9 | /** 10 | * Save activity 11 | * 12 | * @param activity the activity to save 13 | */ 14 | void save(Activity activity); 15 | 16 | /** 17 | * Get the activities related to a card 18 | * 19 | * @param cardId the id of the card 20 | * @return a list of card activities 21 | */ 22 | List findCardActivities(CardId cardId); 23 | } 24 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/attachment/AttachmentCreationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.attachment; 2 | 3 | public class AttachmentCreationException extends RuntimeException { 4 | private static final long serialVersionUID = 6001139032304387250L; 5 | 6 | public AttachmentCreationException(String message, Throwable cause) { 7 | super(message, cause); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/attachment/AttachmentId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.attachment; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class AttachmentId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -7647280039878145249L; 8 | 9 | public AttachmentId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/attachment/ThumbnailCreationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.attachment; 2 | 3 | public class ThumbnailCreationException extends RuntimeException { 4 | private static final long serialVersionUID = 6259084841233699937L; 5 | 6 | public ThumbnailCreationException(String message) { 7 | super(message); 8 | } 9 | 10 | public ThumbnailCreationException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/board/BoardId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.board; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class BoardId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 6059316483218660038L; 8 | 9 | public BoardId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/card/CardId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.card; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class CardId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -6244517408526568385L; 8 | 9 | public CardId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/cardlist/CardListId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.cardlist; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class CardListId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -3248111062745994646L; 8 | 9 | public CardListId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/cardlist/CardListPosition.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.cardlist; 2 | 3 | public class CardListPosition { 4 | 5 | private long cardListId; 6 | private int position; 7 | 8 | public CardListId getCardListId() { 9 | return new CardListId(cardListId); 10 | } 11 | 12 | public int getPosition() { 13 | return position; 14 | } 15 | 16 | public void setCardListId(long cardListId) { 17 | this.cardListId = cardListId; 18 | } 19 | 20 | public void setPosition(int position) { 21 | this.position = position; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/team/TeamId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.team; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class TeamId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = 5572119730009957102L; 8 | 9 | public TeamId(long id) { 10 | super(id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/EmailAddressExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class EmailAddressExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/RegistrationException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class RegistrationException extends Exception { 4 | 5 | private static final long serialVersionUID = -2737904013752279210L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UserId.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | import com.taskagile.domain.common.model.AbstractBaseId; 4 | 5 | public class UserId extends AbstractBaseId { 6 | 7 | private static final long serialVersionUID = -3316570974935023332L; 8 | 9 | public UserId(long id) { 10 | super(id); 11 | } 12 | 13 | public String toString() { 14 | return String.valueOf(value()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UserNotFoundException extends Exception { 4 | 5 | private static final long serialVersionUID = -6826272470679025298L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/domain/model/user/UsernameExistsException.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.domain.model.user; 2 | 3 | public class UsernameExistsException extends RegistrationException { 4 | 5 | private static final long serialVersionUID = -7856406258381199164L; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/pages/MainController.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.pages; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class MainController { 8 | 9 | @GetMapping(value = { "/", "/login", "/register", "/board/*", "/card/**" }) 10 | public String entry() { 11 | return "index"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/AddCardCommentPayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | import com.taskagile.domain.application.commands.AddCardCommentCommand; 4 | import com.taskagile.domain.model.card.CardId; 5 | 6 | public class AddCardCommentPayload { 7 | 8 | private String comment; 9 | 10 | public AddCardCommentCommand toCommand(CardId cardId) { 11 | return new AddCardCommentCommand(cardId, comment); 12 | } 13 | 14 | public void setComment(String comment) { 15 | this.comment = comment; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/ChangeCardDescriptionPayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | import com.taskagile.domain.application.commands.ChangeCardDescriptionCommand; 4 | import com.taskagile.domain.model.card.CardId; 5 | 6 | public class ChangeCardDescriptionPayload { 7 | 8 | private String description; 9 | 10 | public ChangeCardDescriptionCommand toCommand(long cardId) { 11 | return new ChangeCardDescriptionCommand(new CardId(cardId), description); 12 | } 13 | 14 | public void setDescription(String description) { 15 | this.description = description; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/ChangeCardTitlePayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | import com.taskagile.domain.application.commands.ChangeCardTitleCommand; 4 | import com.taskagile.domain.model.card.CardId; 5 | 6 | public class ChangeCardTitlePayload { 7 | 8 | private String title; 9 | 10 | public ChangeCardTitleCommand toCommand(long cardId) { 11 | return new ChangeCardTitleCommand(new CardId(cardId), title); 12 | } 13 | 14 | public void setTitle(String title) { 15 | this.title = title; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/payload/CreateTeamPayload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.payload; 2 | 3 | import com.taskagile.domain.application.commands.CreateTeamCommand; 4 | 5 | public class CreateTeamPayload { 6 | 7 | private String name; 8 | 9 | public CreateTeamCommand toCommand() { 10 | return new CreateTeamCommand(name); 11 | } 12 | 13 | public void setName(String name) { 14 | this.name = name; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/AddCardListResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.cardlist.CardList; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class AddCardListResult { 7 | 8 | public static ResponseEntity build(CardList cardList) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", cardList.getId().value()) 11 | .add("name", cardList.getName()); 12 | return Result.ok(apiResult); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/AddCardResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.card.Card; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class AddCardResult { 7 | 8 | public static ResponseEntity build(Card card) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", card.getId().value()) 11 | .add("title", card.getTitle()) 12 | .add("position", card.getPosition()); 13 | return Result.ok(apiResult); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/CreateBoardResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.board.Board; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class CreateBoardResult { 7 | 8 | public static ResponseEntity build(Board board) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", board.getId().value()) 11 | .add("name", board.getName()) 12 | .add("description", board.getDescription()) 13 | .add("teamId", board.getTeamId().value()); 14 | return Result.ok(apiResult); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/results/CreateTeamResult.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.results; 2 | 3 | import com.taskagile.domain.model.team.Team; 4 | import org.springframework.http.ResponseEntity; 5 | 6 | public class CreateTeamResult { 7 | 8 | public static ResponseEntity build(Team team) { 9 | ApiResult apiResult = ApiResult.blank() 10 | .add("id", team.getId().value()) 11 | .add("name", team.getName()); 12 | return Result.ok(apiResult); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/Action.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Target({ElementType.METHOD}) 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Documented 8 | public @interface Action { 9 | 10 | /** 11 | * The action pattern. It needs to be an exact match. 12 | *

    For example, "subscribe" 13 | */ 14 | String value() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/ChannelHandlers.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | public final class ChannelHandlers { 4 | 5 | public static String getPattern(ChannelHandler channelHandler) { 6 | if (!"".equals(channelHandler.pattern())) { 7 | return channelHandler.pattern(); 8 | } 9 | return channelHandler.value(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/ChannelValue.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Mark a parameter as the channel's value 7 | */ 8 | @Target(ElementType.PARAMETER) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface ChannelValue { 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/java/com/taskagile/web/socket/Payload.java: -------------------------------------------------------------------------------- 1 | package com.taskagile.web.socket; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Mark a parameter as the payload in an action method of channel handler. 7 | */ 8 | @Target(ElementType.PARAMETER) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface Payload { 12 | } 13 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/resources/mail-templates/welcome.ftl: -------------------------------------------------------------------------------- 1 |

    Welcome!

    2 |

    Here is your registration information:

    3 |
      4 |
    • Username: ${user.username}
    • 5 |
    • Email Address: ${user.emailAddress}
    • 6 |
    7 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/main/resources/spy.properties: -------------------------------------------------------------------------------- 1 | driverlist=com.mysql.jdbc.Driver 2 | logfile=spy.log 3 | dateformat=yyyy-MM-dd HH:mm:ss.SS 4 | logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat 5 | customLogMessageFormat=- %(currentTime) | took %(executionTime)ms | connection %(connectionId) \nEXPLAIN %(sql);\n 6 | filter=true 7 | exclude=select 1 from dual 8 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/test/java/com/taskagile/TaskAgileApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.taskagile; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | @ActiveProfiles("test") 12 | public class TaskAgileApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/test/resources/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.hbm2ddl.auto=create-drop 2 | hibernate.dialect=org.hibernate.dialect.H2Dialect 3 | hibernate.show_sql=true 4 | hibernate.format_sql=true 5 | -------------------------------------------------------------------------------- /Chapter13/vuejs.spring-boot.mysql/src/test/resources/mail-templates/test.ftl: -------------------------------------------------------------------------------- 1 | Hello, ${name} 2 | -------------------------------------------------------------------------------- /Chapter14/__MACOSX/vuejs.spring-boot.mysql/front-end/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter14/__MACOSX/vuejs.spring-boot.mysql/front-end/tests/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter14/__MACOSX/vuejs.spring-boot.mysql/front-end/tests/e2e/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter14/__MACOSX/vuejs.spring-boot.mysql/src/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter15/__MACOSX/vuejs.spring-boot.mysql/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter15/__MACOSX/vuejs.spring-boot.mysql/front-end/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter15/__MACOSX/vuejs.spring-boot.mysql/front-end/tests/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx -------------------------------------------------------------------------------- /Chapter15/__MACOSX/vuejs.spring-boot.mysql/front-end/tests/e2e/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx @ATTRxx --------------------------------------------------------------------------------