├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .husky └── pre-commit ├── .jhipster ├── BankAccount.json ├── Label.json └── Operation.json ├── .lintstagedrc.cjs ├── .mvn ├── jvm.config └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .prettierignore ├── .prettierrc ├── .yo-rc.json ├── LICENSE.txt ├── README.md ├── angular.json ├── checkstyle.xml ├── cypress-audits.config.ts ├── cypress.config.ts ├── eslint.config.mjs ├── jest.conf.js ├── mvnw ├── mvnw.cmd ├── ngsw-config.json ├── npmw ├── npmw.cmd ├── package.json ├── pom.xml ├── sonar-project.properties ├── src ├── main │ ├── docker │ │ ├── app.yml │ │ ├── config │ │ │ └── mysql │ │ │ │ └── my.cnf │ │ ├── grafana │ │ │ └── provisioning │ │ │ │ ├── dashboards │ │ │ │ ├── JVM.json │ │ │ │ └── dashboard.yml │ │ │ │ └── datasources │ │ │ │ └── datasource.yml │ │ ├── jhipster-control-center.yml │ │ ├── jib │ │ │ └── entrypoint.sh │ │ ├── monitoring.yml │ │ ├── mysql.yml │ │ ├── prometheus │ │ │ └── prometheus.yml │ │ ├── services.yml │ │ └── sonar.yml │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── jhipster │ │ │ └── sample │ │ │ ├── ApplicationWebXml.java │ │ │ ├── GeneratedByJHipster.java │ │ │ ├── JhipsterDtoSampleApplicationApp.java │ │ │ ├── aop │ │ │ └── logging │ │ │ │ ├── LoggingAspect.java │ │ │ │ └── package-info.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ ├── AsyncConfiguration.java │ │ │ ├── CRLFLogConverter.java │ │ │ ├── CacheConfiguration.java │ │ │ ├── Constants.java │ │ │ ├── DatabaseConfiguration.java │ │ │ ├── DateTimeFormatConfiguration.java │ │ │ ├── JacksonConfiguration.java │ │ │ ├── LiquibaseConfiguration.java │ │ │ ├── LoggingAspectConfiguration.java │ │ │ ├── LoggingConfiguration.java │ │ │ ├── SecurityConfiguration.java │ │ │ ├── StaticResourcesWebConfiguration.java │ │ │ ├── WebConfigurer.java │ │ │ └── package-info.java │ │ │ ├── domain │ │ │ ├── AbstractAuditingEntity.java │ │ │ ├── Authority.java │ │ │ ├── BankAccount.java │ │ │ ├── Label.java │ │ │ ├── Operation.java │ │ │ ├── PersistentToken.java │ │ │ ├── User.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ ├── repository │ │ │ ├── AuthorityRepository.java │ │ │ ├── BankAccountRepository.java │ │ │ ├── LabelRepository.java │ │ │ ├── OperationRepository.java │ │ │ ├── OperationRepositoryWithBagRelationships.java │ │ │ ├── OperationRepositoryWithBagRelationshipsImpl.java │ │ │ ├── PersistentTokenRepository.java │ │ │ ├── UserRepository.java │ │ │ └── package-info.java │ │ │ ├── security │ │ │ ├── AuthoritiesConstants.java │ │ │ ├── DomainUserDetailsService.java │ │ │ ├── PersistentTokenRememberMeServices.java │ │ │ ├── SecurityUtils.java │ │ │ ├── SpringSecurityAuditorAware.java │ │ │ ├── UserNotActivatedException.java │ │ │ └── package-info.java │ │ │ ├── service │ │ │ ├── EmailAlreadyUsedException.java │ │ │ ├── InvalidPasswordException.java │ │ │ ├── MailService.java │ │ │ ├── UserService.java │ │ │ ├── UsernameAlreadyUsedException.java │ │ │ ├── dto │ │ │ │ ├── AdminUserDTO.java │ │ │ │ ├── BankAccountDTO.java │ │ │ │ ├── LabelDTO.java │ │ │ │ ├── OperationDTO.java │ │ │ │ ├── PasswordChangeDTO.java │ │ │ │ ├── UserDTO.java │ │ │ │ └── package-info.java │ │ │ ├── mapper │ │ │ │ ├── BankAccountMapper.java │ │ │ │ ├── EntityMapper.java │ │ │ │ ├── LabelMapper.java │ │ │ │ ├── OperationMapper.java │ │ │ │ ├── UserMapper.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ │ └── web │ │ │ ├── filter │ │ │ ├── SpaWebFilter.java │ │ │ └── package-info.java │ │ │ └── rest │ │ │ ├── AccountResource.java │ │ │ ├── AuthorityResource.java │ │ │ ├── BankAccountResource.java │ │ │ ├── LabelResource.java │ │ │ ├── OperationResource.java │ │ │ ├── PublicUserResource.java │ │ │ ├── UserResource.java │ │ │ ├── errors │ │ │ ├── BadRequestAlertException.java │ │ │ ├── EmailAlreadyUsedException.java │ │ │ ├── ErrorConstants.java │ │ │ ├── ExceptionTranslator.java │ │ │ ├── FieldErrorVM.java │ │ │ ├── InvalidPasswordException.java │ │ │ ├── LoginAlreadyUsedException.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ └── vm │ │ │ ├── KeyAndPasswordVM.java │ │ │ ├── ManagedUserVM.java │ │ │ └── package-info.java │ ├── resources │ │ ├── .h2.server.properties │ │ ├── banner.txt │ │ ├── config │ │ │ ├── application-dev.yml │ │ │ ├── application-prod.yml │ │ │ ├── application-tls.yml │ │ │ ├── application.yml │ │ │ ├── liquibase │ │ │ │ ├── changelog │ │ │ │ │ ├── 00000000000000_initial_schema.xml │ │ │ │ │ ├── 20150805124838_added_entity_BankAccount.xml │ │ │ │ │ ├── 20150805124838_added_entity_constraints_BankAccount.xml │ │ │ │ │ ├── 20150805124936_added_entity_Label.xml │ │ │ │ │ ├── 20150805125054_added_entity_Operation.xml │ │ │ │ │ └── 20150805125054_added_entity_constraints_Operation.xml │ │ │ │ ├── data │ │ │ │ │ ├── authority.csv │ │ │ │ │ ├── user.csv │ │ │ │ │ └── user_authority.csv │ │ │ │ ├── fake-data │ │ │ │ │ ├── bank_account.csv │ │ │ │ │ ├── label.csv │ │ │ │ │ └── operation.csv │ │ │ │ └── master.xml │ │ │ └── tls │ │ │ │ └── keystore.p12 │ │ ├── i18n │ │ │ ├── messages.properties │ │ │ └── messages_en.properties │ │ ├── logback-spring.xml │ │ └── templates │ │ │ ├── error.html │ │ │ └── mail │ │ │ ├── activationEmail.html │ │ │ ├── creationEmail.html │ │ │ └── passwordResetEmail.html │ └── webapp │ │ ├── 404.html │ │ ├── WEB-INF │ │ └── web.xml │ │ ├── app │ │ ├── account │ │ │ ├── account.route.ts │ │ │ ├── activate │ │ │ │ ├── activate.component.html │ │ │ │ ├── activate.component.spec.ts │ │ │ │ ├── activate.component.ts │ │ │ │ ├── activate.route.ts │ │ │ │ ├── activate.service.spec.ts │ │ │ │ └── activate.service.ts │ │ │ ├── password-reset │ │ │ │ ├── finish │ │ │ │ │ ├── password-reset-finish.component.html │ │ │ │ │ ├── password-reset-finish.component.spec.ts │ │ │ │ │ ├── password-reset-finish.component.ts │ │ │ │ │ ├── password-reset-finish.route.ts │ │ │ │ │ ├── password-reset-finish.service.spec.ts │ │ │ │ │ └── password-reset-finish.service.ts │ │ │ │ └── init │ │ │ │ │ ├── password-reset-init.component.html │ │ │ │ │ ├── password-reset-init.component.spec.ts │ │ │ │ │ ├── password-reset-init.component.ts │ │ │ │ │ ├── password-reset-init.route.ts │ │ │ │ │ ├── password-reset-init.service.spec.ts │ │ │ │ │ └── password-reset-init.service.ts │ │ │ ├── password │ │ │ │ ├── password-strength-bar │ │ │ │ │ ├── password-strength-bar.component.html │ │ │ │ │ ├── password-strength-bar.component.scss │ │ │ │ │ ├── password-strength-bar.component.spec.ts │ │ │ │ │ └── password-strength-bar.component.ts │ │ │ │ ├── password.component.html │ │ │ │ ├── password.component.spec.ts │ │ │ │ ├── password.component.ts │ │ │ │ ├── password.route.ts │ │ │ │ ├── password.service.spec.ts │ │ │ │ └── password.service.ts │ │ │ ├── register │ │ │ │ ├── register.component.html │ │ │ │ ├── register.component.spec.ts │ │ │ │ ├── register.component.ts │ │ │ │ ├── register.model.ts │ │ │ │ ├── register.route.ts │ │ │ │ ├── register.service.spec.ts │ │ │ │ └── register.service.ts │ │ │ ├── sessions │ │ │ │ ├── session.model.ts │ │ │ │ ├── sessions.component.html │ │ │ │ ├── sessions.component.spec.ts │ │ │ │ ├── sessions.component.ts │ │ │ │ ├── sessions.route.ts │ │ │ │ └── sessions.service.ts │ │ │ └── settings │ │ │ │ ├── settings.component.html │ │ │ │ ├── settings.component.spec.ts │ │ │ │ ├── settings.component.ts │ │ │ │ └── settings.route.ts │ │ ├── admin │ │ │ ├── admin.routes.ts │ │ │ ├── configuration │ │ │ │ ├── configuration.component.html │ │ │ │ ├── configuration.component.spec.ts │ │ │ │ ├── configuration.component.ts │ │ │ │ ├── configuration.model.ts │ │ │ │ ├── configuration.service.spec.ts │ │ │ │ └── configuration.service.ts │ │ │ ├── docs │ │ │ │ ├── docs.component.html │ │ │ │ ├── docs.component.scss │ │ │ │ └── docs.component.ts │ │ │ ├── health │ │ │ │ ├── health.component.html │ │ │ │ ├── health.component.spec.ts │ │ │ │ ├── health.component.ts │ │ │ │ ├── health.model.ts │ │ │ │ ├── health.service.spec.ts │ │ │ │ ├── health.service.ts │ │ │ │ └── modal │ │ │ │ │ ├── health-modal.component.html │ │ │ │ │ ├── health-modal.component.spec.ts │ │ │ │ │ └── health-modal.component.ts │ │ │ ├── logs │ │ │ │ ├── log.model.ts │ │ │ │ ├── logs.component.html │ │ │ │ ├── logs.component.spec.ts │ │ │ │ ├── logs.component.ts │ │ │ │ ├── logs.service.spec.ts │ │ │ │ └── logs.service.ts │ │ │ ├── metrics │ │ │ │ ├── blocks │ │ │ │ │ ├── jvm-memory │ │ │ │ │ │ ├── jvm-memory.component.html │ │ │ │ │ │ └── jvm-memory.component.ts │ │ │ │ │ ├── jvm-threads │ │ │ │ │ │ ├── jvm-threads.component.html │ │ │ │ │ │ └── jvm-threads.component.ts │ │ │ │ │ ├── metrics-cache │ │ │ │ │ │ ├── metrics-cache.component.html │ │ │ │ │ │ └── metrics-cache.component.ts │ │ │ │ │ ├── metrics-datasource │ │ │ │ │ │ ├── metrics-datasource.component.html │ │ │ │ │ │ └── metrics-datasource.component.ts │ │ │ │ │ ├── metrics-endpoints-requests │ │ │ │ │ │ ├── metrics-endpoints-requests.component.html │ │ │ │ │ │ └── metrics-endpoints-requests.component.ts │ │ │ │ │ ├── metrics-garbagecollector │ │ │ │ │ │ ├── metrics-garbagecollector.component.html │ │ │ │ │ │ └── metrics-garbagecollector.component.ts │ │ │ │ │ ├── metrics-modal-threads │ │ │ │ │ │ ├── metrics-modal-threads.component.html │ │ │ │ │ │ ├── metrics-modal-threads.component.spec.ts │ │ │ │ │ │ └── metrics-modal-threads.component.ts │ │ │ │ │ ├── metrics-request │ │ │ │ │ │ ├── metrics-request.component.html │ │ │ │ │ │ └── metrics-request.component.ts │ │ │ │ │ └── metrics-system │ │ │ │ │ │ ├── metrics-system.component.html │ │ │ │ │ │ └── metrics-system.component.ts │ │ │ │ ├── metrics.component.html │ │ │ │ ├── metrics.component.spec.ts │ │ │ │ ├── metrics.component.ts │ │ │ │ ├── metrics.model.ts │ │ │ │ ├── metrics.service.spec.ts │ │ │ │ └── metrics.service.ts │ │ │ └── user-management │ │ │ │ ├── delete │ │ │ │ ├── user-management-delete-dialog.component.html │ │ │ │ ├── user-management-delete-dialog.component.spec.ts │ │ │ │ └── user-management-delete-dialog.component.ts │ │ │ │ ├── detail │ │ │ │ ├── user-management-detail.component.html │ │ │ │ ├── user-management-detail.component.spec.ts │ │ │ │ └── user-management-detail.component.ts │ │ │ │ ├── list │ │ │ │ ├── user-management.component.html │ │ │ │ ├── user-management.component.spec.ts │ │ │ │ └── user-management.component.ts │ │ │ │ ├── service │ │ │ │ ├── user-management.service.spec.ts │ │ │ │ └── user-management.service.ts │ │ │ │ ├── update │ │ │ │ ├── user-management-update.component.html │ │ │ │ ├── user-management-update.component.spec.ts │ │ │ │ └── user-management-update.component.ts │ │ │ │ ├── user-management.model.ts │ │ │ │ └── user-management.route.ts │ │ ├── app-page-title-strategy.ts │ │ ├── app.component.ts │ │ ├── app.config.ts │ │ ├── app.routes.ts │ │ ├── config │ │ │ ├── authority.constants.ts │ │ │ ├── datepicker-adapter.ts │ │ │ ├── dayjs.ts │ │ │ ├── error.constants.ts │ │ │ ├── font-awesome-icons.ts │ │ │ ├── input.constants.ts │ │ │ ├── language.constants.ts │ │ │ ├── navigation.constants.ts │ │ │ ├── pagination.constants.ts │ │ │ ├── translation.config.ts │ │ │ └── uib-pagination.config.ts │ │ ├── core │ │ │ ├── auth │ │ │ │ ├── account.model.ts │ │ │ │ ├── account.service.spec.ts │ │ │ │ ├── account.service.ts │ │ │ │ ├── auth-session.service.ts │ │ │ │ ├── state-storage.service.ts │ │ │ │ └── user-route-access.service.ts │ │ │ ├── config │ │ │ │ ├── application-config.service.spec.ts │ │ │ │ └── application-config.service.ts │ │ │ ├── interceptor │ │ │ │ ├── auth-expired.interceptor.ts │ │ │ │ ├── error-handler.interceptor.ts │ │ │ │ ├── index.ts │ │ │ │ └── notification.interceptor.ts │ │ │ ├── request │ │ │ │ ├── request-util.ts │ │ │ │ └── request.model.ts │ │ │ └── util │ │ │ │ ├── alert.service.spec.ts │ │ │ │ ├── alert.service.ts │ │ │ │ ├── data-util.service.spec.ts │ │ │ │ ├── data-util.service.ts │ │ │ │ ├── event-manager.service.spec.ts │ │ │ │ ├── event-manager.service.ts │ │ │ │ ├── operators.spec.ts │ │ │ │ ├── operators.ts │ │ │ │ ├── parse-links.service.spec.ts │ │ │ │ └── parse-links.service.ts │ │ ├── entities │ │ │ ├── admin │ │ │ │ └── authority │ │ │ │ │ ├── authority.model.ts │ │ │ │ │ ├── authority.routes.ts │ │ │ │ │ ├── authority.test-samples.ts │ │ │ │ │ ├── delete │ │ │ │ │ ├── authority-delete-dialog.component.html │ │ │ │ │ ├── authority-delete-dialog.component.spec.ts │ │ │ │ │ └── authority-delete-dialog.component.ts │ │ │ │ │ ├── detail │ │ │ │ │ ├── authority-detail.component.html │ │ │ │ │ ├── authority-detail.component.spec.ts │ │ │ │ │ └── authority-detail.component.ts │ │ │ │ │ ├── list │ │ │ │ │ ├── authority.component.html │ │ │ │ │ ├── authority.component.spec.ts │ │ │ │ │ └── authority.component.ts │ │ │ │ │ ├── route │ │ │ │ │ ├── authority-routing-resolve.service.spec.ts │ │ │ │ │ └── authority-routing-resolve.service.ts │ │ │ │ │ ├── service │ │ │ │ │ ├── authority.service.spec.ts │ │ │ │ │ └── authority.service.ts │ │ │ │ │ └── update │ │ │ │ │ ├── authority-form.service.spec.ts │ │ │ │ │ ├── authority-form.service.ts │ │ │ │ │ ├── authority-update.component.html │ │ │ │ │ ├── authority-update.component.spec.ts │ │ │ │ │ └── authority-update.component.ts │ │ │ ├── bank-account │ │ │ │ ├── bank-account.model.ts │ │ │ │ ├── bank-account.routes.ts │ │ │ │ ├── bank-account.test-samples.ts │ │ │ │ ├── delete │ │ │ │ │ ├── bank-account-delete-dialog.component.html │ │ │ │ │ ├── bank-account-delete-dialog.component.spec.ts │ │ │ │ │ └── bank-account-delete-dialog.component.ts │ │ │ │ ├── detail │ │ │ │ │ ├── bank-account-detail.component.html │ │ │ │ │ ├── bank-account-detail.component.spec.ts │ │ │ │ │ └── bank-account-detail.component.ts │ │ │ │ ├── list │ │ │ │ │ ├── bank-account.component.html │ │ │ │ │ ├── bank-account.component.spec.ts │ │ │ │ │ └── bank-account.component.ts │ │ │ │ ├── route │ │ │ │ │ ├── bank-account-routing-resolve.service.spec.ts │ │ │ │ │ └── bank-account-routing-resolve.service.ts │ │ │ │ ├── service │ │ │ │ │ ├── bank-account.service.spec.ts │ │ │ │ │ └── bank-account.service.ts │ │ │ │ └── update │ │ │ │ │ ├── bank-account-form.service.spec.ts │ │ │ │ │ ├── bank-account-form.service.ts │ │ │ │ │ ├── bank-account-update.component.html │ │ │ │ │ ├── bank-account-update.component.spec.ts │ │ │ │ │ └── bank-account-update.component.ts │ │ │ ├── entity-navbar-items.ts │ │ │ ├── entity.routes.ts │ │ │ ├── label │ │ │ │ ├── delete │ │ │ │ │ ├── label-delete-dialog.component.html │ │ │ │ │ ├── label-delete-dialog.component.spec.ts │ │ │ │ │ └── label-delete-dialog.component.ts │ │ │ │ ├── detail │ │ │ │ │ ├── label-detail.component.html │ │ │ │ │ ├── label-detail.component.spec.ts │ │ │ │ │ └── label-detail.component.ts │ │ │ │ ├── label.model.ts │ │ │ │ ├── label.routes.ts │ │ │ │ ├── label.test-samples.ts │ │ │ │ ├── list │ │ │ │ │ ├── label.component.html │ │ │ │ │ ├── label.component.spec.ts │ │ │ │ │ └── label.component.ts │ │ │ │ ├── route │ │ │ │ │ ├── label-routing-resolve.service.spec.ts │ │ │ │ │ └── label-routing-resolve.service.ts │ │ │ │ ├── service │ │ │ │ │ ├── label.service.spec.ts │ │ │ │ │ └── label.service.ts │ │ │ │ └── update │ │ │ │ │ ├── label-form.service.spec.ts │ │ │ │ │ ├── label-form.service.ts │ │ │ │ │ ├── label-update.component.html │ │ │ │ │ ├── label-update.component.spec.ts │ │ │ │ │ └── label-update.component.ts │ │ │ ├── operation │ │ │ │ ├── delete │ │ │ │ │ ├── operation-delete-dialog.component.html │ │ │ │ │ ├── operation-delete-dialog.component.spec.ts │ │ │ │ │ └── operation-delete-dialog.component.ts │ │ │ │ ├── detail │ │ │ │ │ ├── operation-detail.component.html │ │ │ │ │ ├── operation-detail.component.spec.ts │ │ │ │ │ └── operation-detail.component.ts │ │ │ │ ├── list │ │ │ │ │ ├── operation.component.html │ │ │ │ │ ├── operation.component.spec.ts │ │ │ │ │ └── operation.component.ts │ │ │ │ ├── operation.model.ts │ │ │ │ ├── operation.routes.ts │ │ │ │ ├── operation.test-samples.ts │ │ │ │ ├── route │ │ │ │ │ ├── operation-routing-resolve.service.spec.ts │ │ │ │ │ └── operation-routing-resolve.service.ts │ │ │ │ ├── service │ │ │ │ │ ├── operation.service.spec.ts │ │ │ │ │ └── operation.service.ts │ │ │ │ └── update │ │ │ │ │ ├── operation-form.service.spec.ts │ │ │ │ │ ├── operation-form.service.ts │ │ │ │ │ ├── operation-update.component.html │ │ │ │ │ ├── operation-update.component.spec.ts │ │ │ │ │ └── operation-update.component.ts │ │ │ └── user │ │ │ │ ├── service │ │ │ │ ├── user.service.spec.ts │ │ │ │ └── user.service.ts │ │ │ │ ├── user.model.ts │ │ │ │ └── user.test-samples.ts │ │ ├── home │ │ │ ├── home.component.html │ │ │ ├── home.component.scss │ │ │ ├── home.component.spec.ts │ │ │ └── home.component.ts │ │ ├── layouts │ │ │ ├── error │ │ │ │ ├── error.component.html │ │ │ │ ├── error.component.ts │ │ │ │ └── error.route.ts │ │ │ ├── footer │ │ │ │ ├── footer.component.html │ │ │ │ └── footer.component.ts │ │ │ ├── main │ │ │ │ ├── main.component.html │ │ │ │ ├── main.component.spec.ts │ │ │ │ └── main.component.ts │ │ │ ├── navbar │ │ │ │ ├── active-menu.directive.ts │ │ │ │ ├── navbar-item.model.d.ts │ │ │ │ ├── navbar.component.html │ │ │ │ ├── navbar.component.scss │ │ │ │ ├── navbar.component.spec.ts │ │ │ │ └── navbar.component.ts │ │ │ └── profiles │ │ │ │ ├── page-ribbon.component.scss │ │ │ │ ├── page-ribbon.component.spec.ts │ │ │ │ ├── page-ribbon.component.ts │ │ │ │ ├── profile-info.model.ts │ │ │ │ └── profile.service.ts │ │ ├── login │ │ │ ├── login.component.html │ │ │ ├── login.component.spec.ts │ │ │ ├── login.component.ts │ │ │ ├── login.model.ts │ │ │ └── login.service.ts │ │ └── shared │ │ │ ├── alert │ │ │ ├── alert-error.component.html │ │ │ ├── alert-error.component.spec.ts │ │ │ ├── alert-error.component.ts │ │ │ ├── alert-error.model.ts │ │ │ ├── alert.component.html │ │ │ ├── alert.component.spec.ts │ │ │ └── alert.component.ts │ │ │ ├── auth │ │ │ ├── has-any-authority.directive.spec.ts │ │ │ └── has-any-authority.directive.ts │ │ │ ├── date │ │ │ ├── duration.pipe.ts │ │ │ ├── format-medium-date.pipe.spec.ts │ │ │ ├── format-medium-date.pipe.ts │ │ │ ├── format-medium-datetime.pipe.spec.ts │ │ │ ├── format-medium-datetime.pipe.ts │ │ │ └── index.ts │ │ │ ├── filter │ │ │ ├── filter.component.html │ │ │ ├── filter.component.ts │ │ │ ├── filter.model.spec.ts │ │ │ ├── filter.model.ts │ │ │ └── index.ts │ │ │ ├── language │ │ │ ├── find-language-from-key.pipe.ts │ │ │ ├── index.ts │ │ │ ├── translate.directive.spec.ts │ │ │ ├── translate.directive.ts │ │ │ └── translation.module.ts │ │ │ ├── pagination │ │ │ ├── index.ts │ │ │ ├── item-count.component.spec.ts │ │ │ └── item-count.component.ts │ │ │ ├── shared.module.ts │ │ │ └── sort │ │ │ ├── index.ts │ │ │ ├── sort-by.directive.spec.ts │ │ │ ├── sort-by.directive.ts │ │ │ ├── sort-state.ts │ │ │ ├── sort.directive.spec.ts │ │ │ ├── sort.directive.ts │ │ │ ├── sort.service.spec.ts │ │ │ └── sort.service.ts │ │ ├── bootstrap.ts │ │ ├── content │ │ ├── css │ │ │ └── loading.css │ │ ├── images │ │ │ ├── jhipster_family_member_0.svg │ │ │ ├── jhipster_family_member_0_head-192.png │ │ │ ├── jhipster_family_member_0_head-256.png │ │ │ ├── jhipster_family_member_0_head-384.png │ │ │ ├── jhipster_family_member_0_head-512.png │ │ │ ├── jhipster_family_member_1.svg │ │ │ ├── jhipster_family_member_1_head-192.png │ │ │ ├── jhipster_family_member_1_head-256.png │ │ │ ├── jhipster_family_member_1_head-384.png │ │ │ ├── jhipster_family_member_1_head-512.png │ │ │ ├── jhipster_family_member_2.svg │ │ │ ├── jhipster_family_member_2_head-192.png │ │ │ ├── jhipster_family_member_2_head-256.png │ │ │ ├── jhipster_family_member_2_head-384.png │ │ │ ├── jhipster_family_member_2_head-512.png │ │ │ ├── jhipster_family_member_3.svg │ │ │ ├── jhipster_family_member_3_head-192.png │ │ │ ├── jhipster_family_member_3_head-256.png │ │ │ ├── jhipster_family_member_3_head-384.png │ │ │ ├── jhipster_family_member_3_head-512.png │ │ │ └── logo-jhipster.png │ │ └── scss │ │ │ ├── _bootstrap-variables.scss │ │ │ ├── global.scss │ │ │ └── vendor.scss │ │ ├── declarations.d.ts │ │ ├── environments │ │ ├── environment.development.ts │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── i18n │ │ └── en │ │ │ ├── activate.json │ │ │ ├── adminAuthority.json │ │ │ ├── bankAccount.json │ │ │ ├── configuration.json │ │ │ ├── error.json │ │ │ ├── global.json │ │ │ ├── health.json │ │ │ ├── home.json │ │ │ ├── label.json │ │ │ ├── login.json │ │ │ ├── logs.json │ │ │ ├── metrics.json │ │ │ ├── operation.json │ │ │ ├── password.json │ │ │ ├── register.json │ │ │ ├── reset.json │ │ │ ├── sessions.json │ │ │ ├── settings.json │ │ │ └── user-management.json │ │ ├── index.html │ │ ├── main.ts │ │ ├── manifest.webapp │ │ ├── robots.txt │ │ └── swagger-ui │ │ └── index.html └── test │ ├── gatling │ └── conf │ │ ├── gatling.conf │ │ └── logback.xml │ ├── java │ ├── gatling │ │ └── simulations │ │ │ ├── BankAccountGatlingTest.java │ │ │ ├── LabelGatlingTest.java │ │ │ └── OperationGatlingTest.java │ └── io │ │ └── github │ │ └── jhipster │ │ └── sample │ │ ├── IntegrationTest.java │ │ ├── TechnicalStructureTest.java │ │ ├── config │ │ ├── AsyncSyncConfiguration.java │ │ ├── CRLFLogConverterTest.java │ │ ├── EmbeddedSQL.java │ │ ├── MysqlTestContainer.java │ │ ├── SpringBootTestClassOrderer.java │ │ ├── SqlTestContainer.java │ │ ├── SqlTestContainersSpringContextCustomizerFactory.java │ │ ├── StaticResourcesWebConfigurerTest.java │ │ ├── WebConfigurerTest.java │ │ ├── WebConfigurerTestController.java │ │ └── timezone │ │ │ └── HibernateTimeZoneIT.java │ │ ├── domain │ │ ├── AssertUtils.java │ │ ├── AuthorityAsserts.java │ │ ├── AuthorityTest.java │ │ ├── AuthorityTestSamples.java │ │ ├── BankAccountAsserts.java │ │ ├── BankAccountTest.java │ │ ├── BankAccountTestSamples.java │ │ ├── LabelAsserts.java │ │ ├── LabelTest.java │ │ ├── LabelTestSamples.java │ │ ├── OperationAsserts.java │ │ ├── OperationTest.java │ │ └── OperationTestSamples.java │ │ ├── repository │ │ └── timezone │ │ │ ├── DateTimeWrapper.java │ │ │ └── DateTimeWrapperRepository.java │ │ ├── security │ │ ├── DomainUserDetailsServiceIT.java │ │ └── SecurityUtilsUnitTest.java │ │ ├── service │ │ ├── MailServiceIT.java │ │ ├── UserServiceIT.java │ │ ├── dto │ │ │ ├── BankAccountDTOTest.java │ │ │ ├── LabelDTOTest.java │ │ │ └── OperationDTOTest.java │ │ └── mapper │ │ │ ├── BankAccountMapperTest.java │ │ │ ├── LabelMapperTest.java │ │ │ ├── OperationMapperTest.java │ │ │ └── UserMapperTest.java │ │ └── web │ │ ├── filter │ │ └── SpaWebFilterIT.java │ │ └── rest │ │ ├── AccountResourceIT.java │ │ ├── AuthorityResourceIT.java │ │ ├── BankAccountResourceIT.java │ │ ├── LabelResourceIT.java │ │ ├── OperationResourceIT.java │ │ ├── PublicUserResourceIT.java │ │ ├── TestUtil.java │ │ ├── UserResourceIT.java │ │ ├── WithUnauthenticatedMockUser.java │ │ └── errors │ │ ├── ExceptionTranslatorIT.java │ │ └── ExceptionTranslatorTestController.java │ ├── javascript │ └── cypress │ │ ├── e2e │ │ ├── account │ │ │ ├── login-page.cy.ts │ │ │ ├── logout.cy.ts │ │ │ ├── password-page.cy.ts │ │ │ ├── register-page.cy.ts │ │ │ ├── reset-password-page.cy.ts │ │ │ └── settings-page.cy.ts │ │ ├── administration │ │ │ └── administration.cy.ts │ │ ├── entity │ │ │ ├── authority.cy.ts │ │ │ ├── bank-account.cy.ts │ │ │ ├── label.cy.ts │ │ │ └── operation.cy.ts │ │ └── lighthouse.audits.ts │ │ ├── fixtures │ │ └── integration-test.png │ │ ├── plugins │ │ └── index.ts │ │ ├── support │ │ ├── account.ts │ │ ├── commands.ts │ │ ├── entity.ts │ │ ├── index.ts │ │ ├── management.ts │ │ └── navbar.ts │ │ └── tsconfig.json │ └── resources │ ├── META-INF │ └── spring.factories │ ├── config │ ├── application-testdev.yml │ ├── application-testprod.yml │ └── application.yml │ ├── i18n │ └── messages_en.properties │ ├── junit-platform.properties │ ├── logback.xml │ └── templates │ └── mail │ ├── activationEmail.html │ ├── creationEmail.html │ ├── passwordResetEmail.html │ └── testEmail.html ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── webpack ├── environment.js ├── logo-jhipster.png ├── proxy.conf.js └── webpack.custom.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # We recommend you to keep these unchanged 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | # Change these settings to your own preference 16 | indent_style = space 17 | indent_size = 2 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | 22 | # Generated by jhipster:java:bootstrap generator 23 | [*.java] 24 | indent_size = 4 25 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | lint-staged 2 | -------------------------------------------------------------------------------- /.jhipster/BankAccount.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "changelogDate": "20150805124838" 4 | }, 5 | "changelogDate": "20150805124838", 6 | "dto": "mapstruct", 7 | "entityTableName": "bank_account", 8 | "fields": [ 9 | { 10 | "fieldId": 1, 11 | "fieldName": "name", 12 | "fieldType": "String", 13 | "fieldValidateRules": ["required"] 14 | }, 15 | { 16 | "fieldId": 2, 17 | "fieldName": "balance", 18 | "fieldType": "BigDecimal", 19 | "fieldValidateRules": ["required"] 20 | } 21 | ], 22 | "name": "BankAccount", 23 | "pagination": "no", 24 | "relationships": [ 25 | { 26 | "otherEntityField": "login", 27 | "otherEntityName": "user", 28 | "relationshipId": 1, 29 | "relationshipName": "user", 30 | "relationshipSide": "left", 31 | "relationshipType": "many-to-one" 32 | }, 33 | { 34 | "otherEntityName": "operation", 35 | "otherEntityRelationshipName": "bankAccount", 36 | "relationshipId": 2, 37 | "relationshipName": "operation", 38 | "relationshipSide": "left", 39 | "relationshipType": "one-to-many" 40 | } 41 | ], 42 | "searchEngine": "no" 43 | } 44 | -------------------------------------------------------------------------------- /.jhipster/Label.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "changelogDate": "20150805124936" 4 | }, 5 | "changelogDate": "20150805124936", 6 | "dto": "mapstruct", 7 | "entityTableName": "label", 8 | "fields": [ 9 | { 10 | "fieldId": 1, 11 | "fieldName": "label", 12 | "fieldType": "String", 13 | "fieldValidateRules": ["required", "minlength"], 14 | "fieldValidateRulesMinlength": "3" 15 | } 16 | ], 17 | "name": "Label", 18 | "pagination": "no", 19 | "relationships": [ 20 | { 21 | "otherEntityName": "operation", 22 | "otherEntityRelationshipName": "label", 23 | "ownerSide": false, 24 | "relationshipId": 1, 25 | "relationshipName": "operation", 26 | "relationshipSide": "right", 27 | "relationshipType": "many-to-many" 28 | } 29 | ], 30 | "searchEngine": "no" 31 | } 32 | -------------------------------------------------------------------------------- /.jhipster/Operation.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "changelogDate": "20150805125054" 4 | }, 5 | "changelogDate": "20150805125054", 6 | "dto": "mapstruct", 7 | "entityTableName": "operation", 8 | "fields": [ 9 | { 10 | "fieldId": 1, 11 | "fieldName": "date", 12 | "fieldType": "Instant", 13 | "fieldValidateRules": ["required"] 14 | }, 15 | { 16 | "fieldId": 2, 17 | "fieldName": "description", 18 | "fieldType": "String" 19 | }, 20 | { 21 | "fieldId": 3, 22 | "fieldName": "amount", 23 | "fieldType": "BigDecimal", 24 | "fieldValidateRules": ["required"] 25 | } 26 | ], 27 | "name": "Operation", 28 | "pagination": "infinite-scroll", 29 | "relationships": [ 30 | { 31 | "otherEntityField": "name", 32 | "otherEntityName": "bankAccount", 33 | "relationshipId": 1, 34 | "relationshipName": "bankAccount", 35 | "relationshipSide": "left", 36 | "relationshipType": "many-to-one" 37 | }, 38 | { 39 | "otherEntityField": "label", 40 | "otherEntityName": "label", 41 | "ownerSide": true, 42 | "relationshipId": 2, 43 | "relationshipName": "label", 44 | "relationshipSide": "left", 45 | "relationshipType": "many-to-many" 46 | } 47 | ], 48 | "searchEngine": "no" 49 | } 50 | -------------------------------------------------------------------------------- /.lintstagedrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '{,**/}*.{md,json,yml,js,cjs,mjs,ts,cts,mts,java,html,css,scss}': ['prettier --write'], 3 | }; 4 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 19 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .git 4 | 5 | # Generated by jhipster:maven 6 | target 7 | .mvn 8 | 9 | # Generated by jhipster:client 10 | target/classes/static/ 11 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | printWidth: 140 2 | singleQuote: true 3 | tabWidth: 2 4 | useTabs: false 5 | arrowParens: avoid 6 | bracketSameLine: false 7 | plugins: 8 | - prettier-plugin-packagejson 9 | - prettier-plugin-java 10 | overrides: 11 | - files: "*.java" 12 | options: 13 | tabWidth: 4 14 | -------------------------------------------------------------------------------- /checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /cypress-audits.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress'; 2 | import defaultConfig from './cypress.config'; 3 | 4 | export default defineConfig({ 5 | ...defaultConfig, 6 | e2e: { 7 | ...defaultConfig.e2e, 8 | specPattern: 'src/test/javascript/cypress/e2e/**/*.audits.ts', 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress'; 2 | 3 | export default defineConfig({ 4 | video: false, 5 | fixturesFolder: 'src/test/javascript/cypress/fixtures', 6 | screenshotsFolder: 'target/cypress/screenshots', 7 | downloadsFolder: 'target/cypress/downloads', 8 | videosFolder: 'target/cypress/videos', 9 | chromeWebSecurity: true, 10 | viewportWidth: 1200, 11 | viewportHeight: 720, 12 | retries: 2, 13 | env: { 14 | authenticationUrl: '/api/authentication', 15 | }, 16 | e2e: { 17 | // We've imported your old cypress plugins here. 18 | // You may want to clean this up later by importing these. 19 | async setupNodeEvents(on, config) { 20 | // eslint-disable-next-line @typescript-eslint/no-unsafe-return 21 | return (await import('./src/test/javascript/cypress/plugins/index')).default(on, config); 22 | }, 23 | baseUrl: 'http://localhost:8080/', 24 | specPattern: 'src/test/javascript/cypress/e2e/**/*.cy.ts', 25 | supportFile: 'src/test/javascript/cypress/support/index.ts', 26 | experimentalRunAllSpecs: true, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /jest.conf.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | 3 | const { 4 | compilerOptions: { paths = {}, baseUrl = './' }, 5 | } = require('./tsconfig.json'); 6 | 7 | module.exports = { 8 | transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$|dayjs/esm)'], 9 | resolver: 'jest-preset-angular/build/resolvers/ng-jest-resolver.js', 10 | globals: { 11 | __VERSION__: 'test', 12 | }, 13 | roots: ['', `/${baseUrl}`], 14 | modulePaths: [`/${baseUrl}`], 15 | setupFiles: ['jest-date-mock'], 16 | cacheDirectory: '/target/jest-cache', 17 | coverageDirectory: '/target/test-results/', 18 | moduleNameMapper: pathsToModuleNameMapper(paths, { prefix: `/${baseUrl}/` }), 19 | reporters: [ 20 | 'default', 21 | ['jest-junit', { outputDirectory: '/target/test-results/', outputName: 'TESTS-results-jest.xml' }], 22 | ['jest-sonar', { outputDirectory: './target/test-results/jest', outputName: 'TESTS-results-sonar.xml' }], 23 | ], 24 | testMatch: ['/src/main/webapp/app/**/@(*.)@(spec.ts)'], 25 | testEnvironmentOptions: { 26 | url: 'https://jhipster.tech', 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /ngsw-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/service-worker/config/schema.json", 3 | "index": "/index.html", 4 | "assetGroups": [ 5 | { 6 | "name": "app", 7 | "installMode": "prefetch", 8 | "resources": { 9 | "files": ["/favicon.ico", "/index.html", "/manifest.webapp", "/*.css", "/*.js"] 10 | } 11 | }, 12 | { 13 | "name": "assets", 14 | "installMode": "lazy", 15 | "updateMode": "prefetch", 16 | "resources": { 17 | "files": ["/content/**", "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"] 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /npmw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | basedir=$(dirname "$0") 4 | 5 | if [ -f "$basedir/mvnw" ]; then 6 | bindir="$basedir/target/node" 7 | repodir="$basedir/target/node/node_modules" 8 | installCommand="$basedir/mvnw --batch-mode -ntp -Pwebapp frontend:install-node-and-npm@install-node-and-npm" 9 | else 10 | echo "Using npm installed globally" 11 | exec npm "$@" 12 | fi 13 | 14 | NPM_EXE="$repodir/npm/bin/npm-cli.js" 15 | NODE_EXE="$bindir/node" 16 | 17 | if [ ! -x "$NPM_EXE" ] || [ ! -x "$NODE_EXE" ]; then 18 | $installCommand || true 19 | fi 20 | 21 | if [ -x "$NODE_EXE" ]; then 22 | echo "Using node installed locally $($NODE_EXE --version)" 23 | PATH="$bindir:$PATH" 24 | else 25 | NODE_EXE='node' 26 | fi 27 | 28 | if [ ! -x "$NPM_EXE" ]; then 29 | echo "Local npm not found, using npm installed globally" 30 | npm "$@" 31 | else 32 | echo "Using npm installed locally $($NODE_EXE $NPM_EXE --version)" 33 | $NODE_EXE $NPM_EXE "$@" 34 | fi 35 | -------------------------------------------------------------------------------- /npmw.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | setlocal 4 | 5 | set NPMW_DIR=%~dp0 6 | 7 | set NODE_EXE=^"^" 8 | set NODE_PATH=%NPMW_DIR%target\node\ 9 | set NPM_EXE=^"%NPMW_DIR%target\node\npm.cmd^" 10 | set INSTALL_NPM_COMMAND=^"%NPMW_DIR%mvnw.cmd^" -Pwebapp frontend:install-node-and-npm@install-node-and-npm 11 | 12 | if not exist %NPM_EXE% ( 13 | call %INSTALL_NPM_COMMAND% 14 | ) 15 | 16 | if exist %NODE_EXE% ( 17 | Rem execute local npm with local node, whilst adding local node location to the PATH for this CMD session 18 | endlocal & echo "%PATH%"|find /i "%NODE_PATH%;">nul || set "PATH=%NODE_PATH%;%PATH%" & call %NODE_EXE% %NPM_EXE% %* 19 | ) else if exist %NPM_EXE% ( 20 | Rem execute local npm, whilst adding local npm location to the PATH for this CMD session 21 | endlocal & echo "%PATH%"|find /i "%NODE_PATH%;">nul || set "PATH=%NODE_PATH%;%PATH%" & call %NPM_EXE% %* 22 | ) else ( 23 | call npm %* 24 | ) 25 | -------------------------------------------------------------------------------- /src/main/docker/app.yml: -------------------------------------------------------------------------------- 1 | # This configuration is intended for development purpose, it's **your** responsibility to harden it for production 2 | name: jhipsterdtosampleapplication 3 | services: 4 | app: 5 | image: jhipsterdtosampleapplication 6 | environment: 7 | - _JAVA_OPTIONS=-Xmx512m -Xms256m 8 | - SPRING_PROFILES_ACTIVE=prod,api-docs 9 | - MANAGEMENT_PROMETHEUS_METRICS_EXPORT_ENABLED=true 10 | - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/jhipsterdtosampleapplication?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&createDatabaseIfNotExist=true 11 | - SPRING_LIQUIBASE_URL=jdbc:mysql://mysql:3306/jhipsterdtosampleapplication?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&createDatabaseIfNotExist=true 12 | ports: 13 | - 127.0.0.1:8080:8080 14 | healthcheck: 15 | test: 16 | - CMD 17 | - curl 18 | - -f 19 | - http://localhost:8080/management/health 20 | interval: 5s 21 | timeout: 5s 22 | retries: 40 23 | depends_on: 24 | mysql: 25 | condition: service_healthy 26 | mysql: 27 | extends: 28 | file: ./mysql.yml 29 | service: mysql 30 | -------------------------------------------------------------------------------- /src/main/docker/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: true 10 | options: 11 | path: /etc/grafana/provisioning/dashboards 12 | -------------------------------------------------------------------------------- /src/main/docker/mysql.yml: -------------------------------------------------------------------------------- 1 | # This configuration is intended for development purpose, it's **your** responsibility to harden it for production 2 | name: jhipsterdtosampleapplication 3 | services: 4 | mysql: 5 | image: mysql:9.2.0 6 | volumes: 7 | - ./config/mysql:/etc/mysql/conf.d 8 | environment: 9 | - MYSQL_ALLOW_EMPTY_PASSWORD=yes 10 | - MYSQL_DATABASE=jhipsterdtosampleapplication 11 | # If you want to expose these ports outside your dev PC, 12 | # remove the "127.0.0.1:" prefix 13 | ports: 14 | - 127.0.0.1:3306:3306 15 | command: mysqld --lower_case_table_names=1 --skip-mysqlx --character_set_server=utf8mb4 --explicit_defaults_for_timestamp 16 | healthcheck: 17 | test: ['CMD-SHELL', 'mysql -e "SHOW DATABASES;" && sleep 5'] 18 | interval: 5s 19 | timeout: 10s 20 | retries: 10 21 | -------------------------------------------------------------------------------- /src/main/docker/services.yml: -------------------------------------------------------------------------------- 1 | # This configuration is intended for development purpose, it's **your** responsibility to harden it for production 2 | name: jhipsterdtosampleapplication 3 | services: 4 | mysql: 5 | extends: 6 | file: ./mysql.yml 7 | service: mysql 8 | profiles: 9 | - '' 10 | - prod 11 | -------------------------------------------------------------------------------- /src/main/docker/sonar.yml: -------------------------------------------------------------------------------- 1 | # This configuration is intended for development purpose, it's **your** responsibility to harden it for production 2 | name: jhipsterdtosampleapplication 3 | services: 4 | sonar: 5 | container_name: sonarqube 6 | image: sonarqube:25.5.0.107428-community 7 | # Forced authentication redirect for UI is turned off for out of the box experience while trying out SonarQube 8 | # For real use cases delete SONAR_FORCEAUTHENTICATION variable or set SONAR_FORCEAUTHENTICATION=true 9 | environment: 10 | - SONAR_FORCEAUTHENTICATION=false 11 | # If you want to expose these ports outside your dev PC, 12 | # remove the "127.0.0.1:" prefix 13 | ports: 14 | - 127.0.0.1:9001:9000 15 | - 127.0.0.1:9000:9000 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/ApplicationWebXml.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample; 2 | 3 | import org.springframework.boot.builder.SpringApplicationBuilder; 4 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 5 | import tech.jhipster.config.DefaultProfileUtil; 6 | 7 | /** 8 | * This is a helper Java class that provides an alternative to creating a {@code web.xml}. 9 | * This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc. 10 | */ 11 | public class ApplicationWebXml extends SpringBootServletInitializer { 12 | 13 | @Override 14 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 15 | // set a default to use when no profile is configured. 16 | DefaultProfileUtil.addDefaultProfile(application.application()); 17 | return application.sources(JhipsterDtoSampleApplicationApp.class); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/GeneratedByJHipster.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample; 2 | 3 | import jakarta.annotation.Generated; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Generated(value = "JHipster", comments = "Generated by JHipster 8.11.0") 10 | @Retention(RetentionPolicy.SOURCE) 11 | @Target({ ElementType.TYPE }) 12 | public @interface GeneratedByJHipster { 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/aop/logging/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Logging aspect. 3 | */ 4 | package io.github.jhipster.sample.aop.logging; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/config/ApplicationProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * Properties specific to Jhipster Dto Sample Application. 7 | *

8 | * Properties are configured in the {@code application.yml} file. 9 | * See {@link tech.jhipster.config.JHipsterProperties} for a good example. 10 | */ 11 | @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) 12 | public class ApplicationProperties { 13 | 14 | private final Liquibase liquibase = new Liquibase(); 15 | 16 | // jhipster-needle-application-properties-property 17 | 18 | public Liquibase getLiquibase() { 19 | return liquibase; 20 | } 21 | 22 | // jhipster-needle-application-properties-property-getter 23 | 24 | public static class Liquibase { 25 | 26 | private Boolean asyncStart = true; 27 | 28 | public Boolean getAsyncStart() { 29 | return asyncStart; 30 | } 31 | 32 | public void setAsyncStart(Boolean asyncStart) { 33 | this.asyncStart = asyncStart; 34 | } 35 | } 36 | // jhipster-needle-application-properties-property-class 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/config/Constants.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | /** 4 | * Application constants. 5 | */ 6 | public final class Constants { 7 | 8 | // Regex for acceptable logins 9 | public static final String LOGIN_REGEX = "^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$"; 10 | 11 | public static final String SYSTEM = "system"; 12 | public static final String DEFAULT_LANGUAGE = "en"; 13 | 14 | private Constants() {} 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/config/DateTimeFormatConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.format.FormatterRegistry; 5 | import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | /** 9 | * Configure the converters to use the ISO format for dates by default. 10 | */ 11 | @Configuration 12 | public class DateTimeFormatConfiguration implements WebMvcConfigurer { 13 | 14 | @Override 15 | public void addFormatters(FormatterRegistry registry) { 16 | DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); 17 | registrar.setUseIsoFormat(true); 18 | registrar.registerFormatters(registry); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/config/LoggingAspectConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import io.github.jhipster.sample.aop.logging.LoggingAspect; 4 | import org.springframework.context.annotation.*; 5 | import org.springframework.core.env.Environment; 6 | import tech.jhipster.config.JHipsterConstants; 7 | 8 | @Configuration 9 | @EnableAspectJAutoProxy 10 | public class LoggingAspectConfiguration { 11 | 12 | @Bean 13 | @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) 14 | public LoggingAspect loggingAspect(Environment env) { 15 | return new LoggingAspect(env); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/config/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Application configuration. 3 | */ 4 | package io.github.jhipster.sample.config; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/domain/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Domain objects. 3 | */ 4 | package io.github.jhipster.sample.domain; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Application root. 3 | */ 4 | package io.github.jhipster.sample; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/repository/AuthorityRepository.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.repository; 2 | 3 | import io.github.jhipster.sample.domain.Authority; 4 | import org.springframework.data.jpa.repository.*; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * Spring Data JPA repository for the Authority entity. 9 | */ 10 | @SuppressWarnings("unused") 11 | @Repository 12 | public interface AuthorityRepository extends JpaRepository {} 13 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/repository/LabelRepository.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.repository; 2 | 3 | import io.github.jhipster.sample.domain.Label; 4 | import org.springframework.data.jpa.repository.*; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * Spring Data JPA repository for the Label entity. 9 | */ 10 | @SuppressWarnings("unused") 11 | @Repository 12 | public interface LabelRepository extends JpaRepository {} 13 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/repository/OperationRepositoryWithBagRelationships.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.repository; 2 | 3 | import io.github.jhipster.sample.domain.Operation; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import org.springframework.data.domain.Page; 7 | 8 | public interface OperationRepositoryWithBagRelationships { 9 | Optional fetchBagRelationships(Optional operation); 10 | 11 | List fetchBagRelationships(List operations); 12 | 13 | Page fetchBagRelationships(Page operations); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/repository/PersistentTokenRepository.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.repository; 2 | 3 | import io.github.jhipster.sample.domain.PersistentToken; 4 | import io.github.jhipster.sample.domain.User; 5 | import java.time.LocalDate; 6 | import java.util.List; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | 9 | /** 10 | * Spring Data JPA repository for the {@link PersistentToken} entity. 11 | */ 12 | public interface PersistentTokenRepository extends JpaRepository { 13 | List findByUser(User user); 14 | 15 | List findByTokenDateBefore(LocalDate localDate); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/repository/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Repository layer. 3 | */ 4 | package io.github.jhipster.sample.repository; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/security/AuthoritiesConstants.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.security; 2 | 3 | /** 4 | * Constants for Spring Security authorities. 5 | */ 6 | public final class AuthoritiesConstants { 7 | 8 | public static final String ADMIN = "ROLE_ADMIN"; 9 | 10 | public static final String USER = "ROLE_USER"; 11 | 12 | public static final String ANONYMOUS = "ROLE_ANONYMOUS"; 13 | 14 | private AuthoritiesConstants() {} 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/security/SpringSecurityAuditorAware.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.security; 2 | 3 | import io.github.jhipster.sample.config.Constants; 4 | import java.util.Optional; 5 | import org.springframework.data.domain.AuditorAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * Implementation of {@link AuditorAware} based on Spring Security. 10 | */ 11 | @Component 12 | public class SpringSecurityAuditorAware implements AuditorAware { 13 | 14 | @Override 15 | public Optional getCurrentAuditor() { 16 | return Optional.of(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/security/UserNotActivatedException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.security; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | /** 6 | * This exception is thrown in case of a not activated user trying to authenticate. 7 | */ 8 | public class UserNotActivatedException extends AuthenticationException { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | public UserNotActivatedException(String message) { 13 | super(message); 14 | } 15 | 16 | public UserNotActivatedException(String message, Throwable t) { 17 | super(message, t); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/security/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Application security utilities. 3 | */ 4 | package io.github.jhipster.sample.security; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/EmailAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service; 2 | 3 | public class EmailAlreadyUsedException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public EmailAlreadyUsedException() { 8 | super("Email is already in use!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/InvalidPasswordException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service; 2 | 3 | public class InvalidPasswordException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public InvalidPasswordException() { 8 | super("Incorrect password"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/UsernameAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service; 2 | 3 | public class UsernameAlreadyUsedException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public UsernameAlreadyUsedException() { 8 | super("Login name already used!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/dto/PasswordChangeDTO.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * A DTO representing a password change required data - current and new password. 7 | */ 8 | public class PasswordChangeDTO implements Serializable { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | private String currentPassword; 13 | private String newPassword; 14 | 15 | public PasswordChangeDTO() { 16 | // Empty constructor needed for Jackson. 17 | } 18 | 19 | public PasswordChangeDTO(String currentPassword, String newPassword) { 20 | this.currentPassword = currentPassword; 21 | this.newPassword = newPassword; 22 | } 23 | 24 | public String getCurrentPassword() { 25 | return currentPassword; 26 | } 27 | 28 | public void setCurrentPassword(String currentPassword) { 29 | this.currentPassword = currentPassword; 30 | } 31 | 32 | public String getNewPassword() { 33 | return newPassword; 34 | } 35 | 36 | public void setNewPassword(String newPassword) { 37 | this.newPassword = newPassword; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/dto/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Data transfer objects for rest mapping. 3 | */ 4 | package io.github.jhipster.sample.service.dto; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/mapper/BankAccountMapper.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.mapper; 2 | 3 | import io.github.jhipster.sample.domain.BankAccount; 4 | import io.github.jhipster.sample.domain.User; 5 | import io.github.jhipster.sample.service.dto.BankAccountDTO; 6 | import io.github.jhipster.sample.service.dto.UserDTO; 7 | import org.mapstruct.*; 8 | 9 | /** 10 | * Mapper for the entity {@link BankAccount} and its DTO {@link BankAccountDTO}. 11 | */ 12 | @Mapper(componentModel = "spring") 13 | public interface BankAccountMapper extends EntityMapper { 14 | @Mapping(target = "user", source = "user", qualifiedByName = "userLogin") 15 | BankAccountDTO toDto(BankAccount s); 16 | 17 | @Named("userLogin") 18 | @BeanMapping(ignoreByDefault = true) 19 | @Mapping(target = "id", source = "id") 20 | @Mapping(target = "login", source = "login") 21 | UserDTO toDtoUserLogin(User user); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/mapper/EntityMapper.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.mapper; 2 | 3 | import java.util.List; 4 | import org.mapstruct.BeanMapping; 5 | import org.mapstruct.MappingTarget; 6 | import org.mapstruct.Named; 7 | import org.mapstruct.NullValuePropertyMappingStrategy; 8 | 9 | /** 10 | * Contract for a generic dto to entity mapper. 11 | * 12 | * @param - DTO type parameter. 13 | * @param - Entity type parameter. 14 | */ 15 | 16 | public interface EntityMapper { 17 | E toEntity(D dto); 18 | 19 | D toDto(E entity); 20 | 21 | List toEntity(List dtoList); 22 | 23 | List toDto(List entityList); 24 | 25 | @Named("partialUpdate") 26 | @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) 27 | void partialUpdate(@MappingTarget E entity, D dto); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/mapper/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Data transfer objects mappers. 3 | */ 4 | package io.github.jhipster.sample.service.mapper; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/service/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Service layer. 3 | */ 4 | package io.github.jhipster.sample.service; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/filter/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Request chain filters. 3 | */ 4 | package io.github.jhipster.sample.web.filter; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/errors/EmailAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.errors; 2 | 3 | @SuppressWarnings("java:S110") // Inheritance tree of classes should not be too deep 4 | public class EmailAlreadyUsedException extends BadRequestAlertException { 5 | 6 | private static final long serialVersionUID = 1L; 7 | 8 | public EmailAlreadyUsedException() { 9 | super(ErrorConstants.EMAIL_ALREADY_USED_TYPE, "Email is already in use!", "userManagement", "emailexists"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/errors/ErrorConstants.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.errors; 2 | 3 | import java.net.URI; 4 | 5 | public final class ErrorConstants { 6 | 7 | public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure"; 8 | public static final String ERR_VALIDATION = "error.validation"; 9 | public static final String PROBLEM_BASE_URL = "https://www.jhipster.tech/problem"; 10 | public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); 11 | public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); 12 | public static final URI INVALID_PASSWORD_TYPE = URI.create(PROBLEM_BASE_URL + "/invalid-password"); 13 | public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used"); 14 | public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used"); 15 | 16 | private ErrorConstants() {} 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/errors/FieldErrorVM.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.errors; 2 | 3 | import java.io.Serializable; 4 | 5 | public class FieldErrorVM implements Serializable { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private final String objectName; 10 | 11 | private final String field; 12 | 13 | private final String message; 14 | 15 | public FieldErrorVM(String dto, String field, String message) { 16 | this.objectName = dto; 17 | this.field = field; 18 | this.message = message; 19 | } 20 | 21 | public String getObjectName() { 22 | return objectName; 23 | } 24 | 25 | public String getField() { 26 | return field; 27 | } 28 | 29 | public String getMessage() { 30 | return message; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/errors/InvalidPasswordException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.errors; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.ErrorResponseException; 5 | import tech.jhipster.web.rest.errors.ProblemDetailWithCause.ProblemDetailWithCauseBuilder; 6 | 7 | @SuppressWarnings("java:S110") // Inheritance tree of classes should not be too deep 8 | public class InvalidPasswordException extends ErrorResponseException { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | public InvalidPasswordException() { 13 | super( 14 | HttpStatus.BAD_REQUEST, 15 | ProblemDetailWithCauseBuilder.instance() 16 | .withStatus(HttpStatus.BAD_REQUEST.value()) 17 | .withType(ErrorConstants.INVALID_PASSWORD_TYPE) 18 | .withTitle("Incorrect password") 19 | .build(), 20 | null 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/errors/LoginAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.errors; 2 | 3 | @SuppressWarnings("java:S110") // Inheritance tree of classes should not be too deep 4 | public class LoginAlreadyUsedException extends BadRequestAlertException { 5 | 6 | private static final long serialVersionUID = 1L; 7 | 8 | public LoginAlreadyUsedException() { 9 | super(ErrorConstants.LOGIN_ALREADY_USED_TYPE, "Login name already used!", "userManagement", "userexists"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/errors/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Rest layer error handling. 3 | */ 4 | package io.github.jhipster.sample.web.rest.errors; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Rest layer. 3 | */ 4 | package io.github.jhipster.sample.web.rest; 5 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/vm/KeyAndPasswordVM.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.vm; 2 | 3 | /** 4 | * View Model object for storing the user's key and password. 5 | */ 6 | public class KeyAndPasswordVM { 7 | 8 | private String key; 9 | 10 | private String newPassword; 11 | 12 | public String getKey() { 13 | return key; 14 | } 15 | 16 | public void setKey(String key) { 17 | this.key = key; 18 | } 19 | 20 | public String getNewPassword() { 21 | return newPassword; 22 | } 23 | 24 | public void setNewPassword(String newPassword) { 25 | this.newPassword = newPassword; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/vm/ManagedUserVM.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest.vm; 2 | 3 | import io.github.jhipster.sample.service.dto.AdminUserDTO; 4 | import jakarta.validation.constraints.Size; 5 | 6 | /** 7 | * View Model extending the AdminUserDTO, which is meant to be used in the user management UI. 8 | */ 9 | public class ManagedUserVM extends AdminUserDTO { 10 | 11 | public static final int PASSWORD_MIN_LENGTH = 4; 12 | 13 | public static final int PASSWORD_MAX_LENGTH = 100; 14 | 15 | @Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH) 16 | private String password; 17 | 18 | public ManagedUserVM() { 19 | // Empty constructor needed for Jackson. 20 | } 21 | 22 | public String getPassword() { 23 | return password; 24 | } 25 | 26 | public void setPassword(String password) { 27 | this.password = password; 28 | } 29 | 30 | // prettier-ignore 31 | @Override 32 | public String toString() { 33 | return "ManagedUserVM{" + super.toString() + "} "; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/github/jhipster/sample/web/rest/vm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Rest layer visual models. 3 | */ 4 | package io.github.jhipster.sample.web.rest.vm; 5 | -------------------------------------------------------------------------------- /src/main/resources/.h2.server.properties: -------------------------------------------------------------------------------- 1 | #H2 Server Properties 2 | 0=JHipster H2 (Memory)|org.h2.Driver|jdbc\:h2\:mem\:jhipsterDtoSampleApplication|jhipsterDtoSampleApplication 3 | webAllowOthers=true 4 | webPort=8092 5 | webSSL=false 6 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ${AnsiColor.GREEN} ██╗${AnsiColor.RED} ██╗ ██╗ ████████╗ ███████╗ ██████╗ ████████╗ ████████╗ ███████╗ 3 | ${AnsiColor.GREEN} ██║${AnsiColor.RED} ██║ ██║ ╚══██╔══╝ ██╔═══██╗ ██╔════╝ ╚══██╔══╝ ██╔═════╝ ██╔═══██╗ 4 | ${AnsiColor.GREEN} ██║${AnsiColor.RED} ████████║ ██║ ███████╔╝ ╚█████╗ ██║ ██████╗ ███████╔╝ 5 | ${AnsiColor.GREEN}██╗ ██║${AnsiColor.RED} ██╔═══██║ ██║ ██╔════╝ ╚═══██╗ ██║ ██╔═══╝ ██╔══██║ 6 | ${AnsiColor.GREEN}╚██████╔╝${AnsiColor.RED} ██║ ██║ ████████╗ ██║ ██████╔╝ ██║ ████████╗ ██║ ╚██╗ 7 | ${AnsiColor.GREEN} ╚═════╝ ${AnsiColor.RED} ╚═╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═╝ 8 | 9 | ${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} :: Startup profile(s) ${spring.profiles.active} :: 10 | :: https://www.jhipster.tech ::${AnsiColor.DEFAULT} 11 | -------------------------------------------------------------------------------- /src/main/resources/config/application-tls.yml: -------------------------------------------------------------------------------- 1 | # =================================================================== 2 | # Activate this profile to enable TLS and HTTP/2. 3 | # 4 | # JHipster has generated a self-signed certificate, which will be used to encrypt traffic. 5 | # As your browser will not understand this certificate, you will need to import it. 6 | # 7 | # Another (easiest) solution with Chrome is to enable the "allow-insecure-localhost" flag 8 | # at chrome://flags/#allow-insecure-localhost 9 | # =================================================================== 10 | server: 11 | ssl: 12 | key-store: classpath:config/tls/keystore.p12 13 | key-store-password: password 14 | key-store-type: PKCS12 15 | key-alias: selfsigned 16 | ciphers: 17 | - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 18 | - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 19 | - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 20 | - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 21 | - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 22 | - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 23 | - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 24 | - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 25 | enabled-protocols: TLSv1.2 26 | http2: 27 | enabled: true 28 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20150805124838_added_entity_constraints_BankAccount.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 12 | 13 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/data/authority.csv: -------------------------------------------------------------------------------- 1 | name 2 | ROLE_ADMIN 3 | ROLE_USER 4 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/data/user.csv: -------------------------------------------------------------------------------- 1 | id;login;password_hash;first_name;last_name;email;image_url;activated;lang_key;created_by;last_modified_by 2 | 1;admin;$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC;Administrator;Administrator;admin@localhost;;true;en;system;system 3 | 2;user;$2a$10$VEjxo0jq2YG9Rbk2HmX9S.k1uZBGYUHdUcid3g/vfiEl7lwWgOH/K;User;User;user@localhost;;true;en;system;system 4 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/data/user_authority.csv: -------------------------------------------------------------------------------- 1 | user_id;authority_name 2 | 1;ROLE_ADMIN 3 | 1;ROLE_USER 4 | 2;ROLE_USER 5 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/bank_account.csv: -------------------------------------------------------------------------------- 1 | id;name;balance 2 | 1;after though;25162.02 3 | 2;ha vary pillow;10257.47 4 | 3;eek;25727.69 5 | 4;spectate whoa;24704.49 6 | 5;fairly unlike immediate;21081.12 7 | 6;physically garage unnecessarily;8717.94 8 | 7;um;5226.56 9 | 8;probable duster within;5020.57 10 | 9;soon;7295.13 11 | 10;yowza seriously;13135.46 12 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/label.csv: -------------------------------------------------------------------------------- 1 | id;label 2 | 1;ack consequently underneath 3 | 2;ewX 4 | 3;nor jiggle 5 | 4;patiently 6 | 5;discontinue lender um 7 | 6;bossy who outlandish 8 | 7;aha stock acidic 9 | 8;inside midst 10 | 9;preregister 11 | 10;astride weakly 12 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/operation.csv: -------------------------------------------------------------------------------- 1 | id;date;description;amount 2 | 1;2015-08-05T11:40:17;aching;6390.05 3 | 2;2015-08-04T17:54:47;whereas;27057.73 4 | 3;2015-08-05T07:43:46;since inferior gah;6668.24 5 | 4;2015-08-04T19:05:07;which pish afore;1511.19 6 | 5;2015-08-05T05:32:11;thick;24902.15 7 | 6;2015-08-05T01:43:24;pushy throughout;3721.31 8 | 7;2015-08-05T02:48:29;harvest above whether;12367.84 9 | 8;2015-08-04T19:31:08;spectacles unfreeze atop;12412.55 10 | 9;2015-08-05T11:39:49;that accompanist;28390.92 11 | 10;2015-08-04T17:31:12;frilly once;23459.53 12 | -------------------------------------------------------------------------------- /src/main/resources/config/tls/keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/resources/config/tls/keystore.p12 -------------------------------------------------------------------------------- /src/main/resources/i18n/messages.properties: -------------------------------------------------------------------------------- 1 | # Error page 2 | error.title=Your request cannot be processed 3 | error.subtitle=Sorry, an error has occurred. 4 | error.status=Status: 5 | error.message=Message: 6 | 7 | # Activation email 8 | email.activation.title=jhipsterDtoSampleApplication account activation is required 9 | email.activation.greeting=Dear {0} 10 | email.activation.text1=Your jhipsterDtoSampleApplication account has been created, please click on the URL below to activate it: 11 | email.activation.text2=Regards, 12 | email.signature=jhipsterDtoSampleApplication Team. 13 | 14 | # Creation email 15 | email.creation.text1=Your jhipsterDtoSampleApplication account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=jhipsterDtoSampleApplication password reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your jhipsterDtoSampleApplication account a password reset was requested, please click on the URL below to reset it: 21 | email.reset.text2=Regards, 22 | -------------------------------------------------------------------------------- /src/main/resources/i18n/messages_en.properties: -------------------------------------------------------------------------------- 1 | # Error page 2 | error.title=Your request cannot be processed 3 | error.subtitle=Sorry, an error has occurred. 4 | error.status=Status: 5 | error.message=Message: 6 | 7 | # Activation email 8 | email.activation.title=jhipsterDtoSampleApplication account activation 9 | email.activation.greeting=Dear {0} 10 | email.activation.text1=Your jhipsterDtoSampleApplication account has been created, please click on the URL below to activate it: 11 | email.activation.text2=Regards, 12 | email.signature=jhipsterDtoSampleApplication Team. 13 | 14 | # Creation email 15 | email.creation.text1=Your jhipsterDtoSampleApplication account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=jhipsterDtoSampleApplication password reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your jhipsterDtoSampleApplication account a password reset was requested, please click on the URL below to reset it: 21 | email.reset.text2=Regards, 22 | -------------------------------------------------------------------------------- /src/main/resources/templates/mail/activationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster activation 5 | 6 | 7 | 8 | 9 |

Dear

10 |

Your JHipster account has been created, please click on the URL below to activate it:

11 |

12 | Activation link 13 |

14 |

15 | Regards, 16 |
17 | JHipster. 18 |

19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/templates/mail/creationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster creation 5 | 6 | 7 | 8 | 9 |

Dear

10 |

Your JHipster account has been created, please click on the URL below to access it:

11 |

12 | Login link 13 |

14 |

15 | Regards, 16 |
17 | JHipster. 18 |

19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/templates/mail/passwordResetEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster password reset 5 | 6 | 7 | 8 | 9 |

Dear

10 |

11 | For your JHipster account a password reset was requested, please click on the URL below to reset it: 12 |

13 |

14 | Login link 15 |

16 |

17 | Regards, 18 |
19 | JHipster. 20 |

21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | html 10 | text/html;charset=utf-8 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/account.route.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | import activateRoute from './activate/activate.route'; 4 | import passwordRoute from './password/password.route'; 5 | import passwordResetFinishRoute from './password-reset/finish/password-reset-finish.route'; 6 | import passwordResetInitRoute from './password-reset/init/password-reset-init.route'; 7 | import registerRoute from './register/register.route'; 8 | import sessionsRoute from './sessions/sessions.route'; 9 | import settingsRoute from './settings/settings.route'; 10 | 11 | const accountRoutes: Routes = [ 12 | activateRoute, 13 | passwordRoute, 14 | passwordResetFinishRoute, 15 | passwordResetInitRoute, 16 | registerRoute, 17 | sessionsRoute, 18 | settingsRoute, 19 | ]; 20 | 21 | export default accountRoutes; 22 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Activation

5 | @if (success()) { 6 |
7 | Your user account has been activated. Please 8 | sign in. 9 |
10 | } 11 | @if (error()) { 12 |
13 | Your user could not be activated. Please use the registration form to sign up. 14 |
15 | } 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, inject, signal } from '@angular/core'; 2 | import { ActivatedRoute, RouterModule } from '@angular/router'; 3 | import { mergeMap } from 'rxjs/operators'; 4 | 5 | import SharedModule from 'app/shared/shared.module'; 6 | import { ActivateService } from './activate.service'; 7 | 8 | @Component({ 9 | selector: 'jhi-activate', 10 | imports: [SharedModule, RouterModule], 11 | templateUrl: './activate.component.html', 12 | }) 13 | export default class ActivateComponent implements OnInit { 14 | error = signal(false); 15 | success = signal(false); 16 | 17 | private readonly activateService = inject(ActivateService); 18 | private readonly route = inject(ActivatedRoute); 19 | 20 | ngOnInit(): void { 21 | this.route.queryParams.pipe(mergeMap(params => this.activateService.get(params.key))).subscribe({ 22 | next: () => this.success.set(true), 23 | error: () => this.error.set(true), 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import ActivateComponent from './activate.component'; 4 | 5 | const activateRoute: Route = { 6 | path: 'activate', 7 | component: ActivateComponent, 8 | title: 'activate.title', 9 | }; 10 | 11 | export default activateRoute; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient, HttpParams } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | 7 | @Injectable({ providedIn: 'root' }) 8 | export class ActivateService { 9 | private readonly http = inject(HttpClient); 10 | private readonly applicationConfigService = inject(ApplicationConfigService); 11 | 12 | get(key: string): Observable<{}> { 13 | return this.http.get(this.applicationConfigService.getEndpointFor('api/activate'), { 14 | params: new HttpParams().set('key', key), 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import PasswordResetFinishComponent from './password-reset-finish.component'; 4 | 5 | const passwordResetFinishRoute: Route = { 6 | path: 'reset/finish', 7 | component: PasswordResetFinishComponent, 8 | title: 'global.menu.account.password', 9 | }; 10 | 11 | export default passwordResetFinishRoute; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | 7 | @Injectable({ providedIn: 'root' }) 8 | export class PasswordResetFinishService { 9 | private readonly http = inject(HttpClient); 10 | private readonly applicationConfigService = inject(ApplicationConfigService); 11 | 12 | save(key: string, newPassword: string): Observable<{}> { 13 | return this.http.post(this.applicationConfigService.getEndpointFor('api/account/reset-password/finish'), { key, newPassword }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import PasswordResetInitComponent from './password-reset-init.component'; 4 | 5 | const passwordResetInitRoute: Route = { 6 | path: 'reset/request', 7 | component: PasswordResetInitComponent, 8 | title: 'global.menu.account.password', 9 | }; 10 | 11 | export default passwordResetInitRoute; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | 7 | @Injectable({ providedIn: 'root' }) 8 | export class PasswordResetInitService { 9 | private readonly http = inject(HttpClient); 10 | private readonly applicationConfigService = inject(ApplicationConfigService); 11 | 12 | save(mail: string): Observable<{}> { 13 | return this.http.post(this.applicationConfigService.getEndpointFor('api/account/reset-password/init'), mail); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password-strength-bar/password-strength-bar.component.html: -------------------------------------------------------------------------------- 1 |
2 | Password strength: 3 |
    4 |
  • 5 |
  • 6 |
  • 7 |
  • 8 |
  • 9 |
10 |
11 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password-strength-bar/password-strength-bar.component.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | start Password strength bar style 3 | ========================================================================== */ 4 | ul#strength { 5 | display: inline; 6 | list-style: none; 7 | margin: 0 0 0 15px; 8 | padding: 0; 9 | vertical-align: 2px; 10 | } 11 | 12 | .point { 13 | background: #ddd; 14 | border-radius: 2px; 15 | display: inline-block; 16 | height: 5px; 17 | margin-right: 1px; 18 | width: 20px; 19 | &:last-child { 20 | margin: 0 !important; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from 'app/core/auth/user-route-access.service'; 4 | import PasswordComponent from './password.component'; 5 | 6 | const passwordRoute: Route = { 7 | path: 'password', 8 | component: PasswordComponent, 9 | title: 'global.menu.account.password', 10 | canActivate: [UserRouteAccessService], 11 | }; 12 | 13 | export default passwordRoute; 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | 7 | @Injectable({ providedIn: 'root' }) 8 | export class PasswordService { 9 | private readonly http = inject(HttpClient); 10 | private readonly applicationConfigService = inject(ApplicationConfigService); 11 | 12 | save(newPassword: string, currentPassword: string): Observable<{}> { 13 | return this.http.post(this.applicationConfigService.getEndpointFor('api/account/change-password'), { currentPassword, newPassword }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/register/register.model.ts: -------------------------------------------------------------------------------- 1 | export class Registration { 2 | constructor( 3 | public login: string, 4 | public email: string, 5 | public password: string, 6 | public langKey: string, 7 | ) {} 8 | } 9 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/register/register.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import RegisterComponent from './register.component'; 4 | 5 | const registerRoute: Route = { 6 | path: 'register', 7 | component: RegisterComponent, 8 | title: 'register.title', 9 | }; 10 | 11 | export default registerRoute; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/register/register.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | import { Registration } from './register.model'; 7 | 8 | @Injectable({ providedIn: 'root' }) 9 | export class RegisterService { 10 | private readonly http = inject(HttpClient); 11 | private readonly applicationConfigService = inject(ApplicationConfigService); 12 | 13 | save(registration: Registration): Observable<{}> { 14 | return this.http.post(this.applicationConfigService.getEndpointFor('api/register'), registration); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/sessions/session.model.ts: -------------------------------------------------------------------------------- 1 | export class Session { 2 | constructor( 3 | public series: string, 4 | public tokenDate: Date, 5 | public ipAddress: string, 6 | public userAgent: string, 7 | ) {} 8 | } 9 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/sessions/sessions.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from 'app/core/auth/user-route-access.service'; 4 | import SessionsComponent from './sessions.component'; 5 | 6 | const sessionsRoute: Route = { 7 | path: 'sessions', 8 | component: SessionsComponent, 9 | title: 'global.menu.account.sessions', 10 | canActivate: [UserRouteAccessService], 11 | }; 12 | 13 | export default sessionsRoute; 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/sessions/sessions.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | import { Session } from './session.model'; 7 | 8 | @Injectable({ providedIn: 'root' }) 9 | export class SessionsService { 10 | private readonly http = inject(HttpClient); 11 | private readonly applicationConfigService = inject(ApplicationConfigService); 12 | 13 | private resourceUrl = this.applicationConfigService.getEndpointFor('api/account/sessions'); 14 | 15 | findAll(): Observable { 16 | return this.http.get(this.resourceUrl); 17 | } 18 | 19 | delete(series: string): Observable<{}> { 20 | return this.http.delete(`${this.resourceUrl}/${series}`); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/settings/settings.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from 'app/core/auth/user-route-access.service'; 4 | import SettingsComponent from './settings.component'; 5 | 6 | const settingsRoute: Route = { 7 | path: 'settings', 8 | component: SettingsComponent, 9 | title: 'global.menu.account.settings', 10 | canActivate: [UserRouteAccessService], 11 | }; 12 | 13 | export default settingsRoute; 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/admin.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | /* jhipster-needle-add-admin-module-import - JHipster will add admin modules imports here */ 3 | 4 | const routes: Routes = [ 5 | { 6 | path: 'user-management', 7 | loadChildren: () => import('./user-management/user-management.route'), 8 | title: 'userManagement.home.title', 9 | }, 10 | { 11 | path: 'docs', 12 | loadComponent: () => import('./docs/docs.component'), 13 | title: 'global.menu.admin.apidocs', 14 | }, 15 | { 16 | path: 'configuration', 17 | loadComponent: () => import('./configuration/configuration.component'), 18 | title: 'configuration.title', 19 | }, 20 | { 21 | path: 'health', 22 | loadComponent: () => import('./health/health.component'), 23 | title: 'health.title', 24 | }, 25 | { 26 | path: 'logs', 27 | loadComponent: () => import('./logs/logs.component'), 28 | title: 'logs.title', 29 | }, 30 | { 31 | path: 'metrics', 32 | loadComponent: () => import('./metrics/metrics.component'), 33 | title: 'metrics.title', 34 | }, 35 | /* jhipster-needle-add-admin-route - JHipster will add admin routes here */ 36 | ]; 37 | 38 | export default routes; 39 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/configuration/configuration.model.ts: -------------------------------------------------------------------------------- 1 | export interface ConfigProps { 2 | contexts: Contexts; 3 | } 4 | 5 | export type Contexts = Record; 6 | 7 | export interface Context { 8 | beans: Beans; 9 | parentId?: any; 10 | } 11 | 12 | export type Beans = Record; 13 | 14 | export interface Bean { 15 | prefix: string; 16 | properties: any; 17 | } 18 | 19 | export interface Env { 20 | activeProfiles?: string[]; 21 | propertySources: PropertySource[]; 22 | } 23 | 24 | export interface PropertySource { 25 | name: string; 26 | properties: Properties; 27 | } 28 | 29 | export type Properties = Record; 30 | 31 | export interface Property { 32 | value: string; 33 | origin?: string; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/configuration/configuration.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | import { map } from 'rxjs/operators'; 5 | 6 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 7 | import { Bean, Beans, ConfigProps, Env, PropertySource } from './configuration.model'; 8 | 9 | @Injectable({ providedIn: 'root' }) 10 | export class ConfigurationService { 11 | private readonly http = inject(HttpClient); 12 | private readonly applicationConfigService = inject(ApplicationConfigService); 13 | 14 | getBeans(): Observable { 15 | return this.http.get(this.applicationConfigService.getEndpointFor('management/configprops')).pipe( 16 | map(configProps => 17 | Object.values( 18 | Object.values(configProps.contexts) 19 | .map(context => context.beans) 20 | .reduce((allBeans: Beans, contextBeans: Beans) => ({ ...allBeans, ...contextBeans }), {}), 21 | ), 22 | ), 23 | ); 24 | } 25 | 26 | getPropertySources(): Observable { 27 | return this.http.get(this.applicationConfigService.getEndpointFor('management/env')).pipe(map(env => env.propertySources)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/docs/docs.component.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/docs/docs.component.scss: -------------------------------------------------------------------------------- 1 | @import 'bootstrap/scss/functions'; 2 | @import 'bootstrap/scss/variables'; 3 | 4 | iframe { 5 | background: white; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/docs/docs.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'jhi-docs', 5 | templateUrl: './docs.component.html', 6 | styleUrl: './docs.component.scss', 7 | }) 8 | export default class DocsComponent {} 9 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/health.model.ts: -------------------------------------------------------------------------------- 1 | export type HealthStatus = 'UP' | 'DOWN' | 'UNKNOWN' | 'OUT_OF_SERVICE'; 2 | 3 | export type HealthKey = 'diskSpace' | 'mail' | 'ping' | 'livenessState' | 'readinessState' | 'db'; 4 | 5 | export interface Health { 6 | status: HealthStatus; 7 | components?: Partial>; 8 | } 9 | 10 | export interface HealthDetails { 11 | status: HealthStatus; 12 | details?: Record; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/health.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | import { Health } from './health.model'; 7 | 8 | @Injectable({ providedIn: 'root' }) 9 | export class HealthService { 10 | private readonly http = inject(HttpClient); 11 | private readonly applicationConfigService = inject(ApplicationConfigService); 12 | 13 | checkHealth(): Observable { 14 | return this.http.get(this.applicationConfigService.getEndpointFor('management/health')); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/modal/health-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 3 | 4 | import SharedModule from 'app/shared/shared.module'; 5 | import { HealthDetails, HealthKey } from '../health.model'; 6 | 7 | @Component({ 8 | selector: 'jhi-health-modal', 9 | templateUrl: './health-modal.component.html', 10 | imports: [SharedModule], 11 | }) 12 | export default class HealthModalComponent { 13 | health?: { key: HealthKey; value: HealthDetails }; 14 | 15 | private readonly activeModal = inject(NgbActiveModal); 16 | 17 | readableValue(value: any): string { 18 | if (this.health?.key === 'diskSpace') { 19 | // should display storage space in a human readable unit 20 | const val = value / 1073741824; 21 | if (val > 1) { 22 | return `${val.toFixed(2)} GB`; 23 | } 24 | return `${(value / 1048576).toFixed(2)} MB`; 25 | } 26 | 27 | if (typeof value === 'object') { 28 | return JSON.stringify(value); 29 | } 30 | return String(value); 31 | } 32 | 33 | dismiss(): void { 34 | this.activeModal.dismiss(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/log.model.ts: -------------------------------------------------------------------------------- 1 | export type Level = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'OFF'; 2 | 3 | export interface Logger { 4 | configuredLevel: Level | null; 5 | effectiveLevel: Level; 6 | } 7 | 8 | export interface LoggersResponse { 9 | levels: Level[]; 10 | loggers: Record; 11 | } 12 | 13 | export class Log { 14 | constructor( 15 | public name: string, 16 | public level: Level, 17 | ) {} 18 | } 19 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/logs.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; 3 | import { provideHttpClient } from '@angular/common/http'; 4 | 5 | import { LogsService } from './logs.service'; 6 | 7 | describe('Logs Service', () => { 8 | let service: LogsService; 9 | let httpMock: HttpTestingController; 10 | 11 | beforeEach(() => { 12 | TestBed.configureTestingModule({ 13 | providers: [provideHttpClient(), provideHttpClientTesting()], 14 | }); 15 | 16 | service = TestBed.inject(LogsService); 17 | httpMock = TestBed.inject(HttpTestingController); 18 | }); 19 | 20 | afterEach(() => { 21 | httpMock.verify(); 22 | }); 23 | 24 | describe('Service methods', () => { 25 | it('should change log level', () => { 26 | service.changeLevel('main', 'ERROR').subscribe(); 27 | 28 | const req = httpMock.expectOne({ method: 'POST' }); 29 | expect(req.request.body).toEqual({ configuredLevel: 'ERROR' }); 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/logs.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | import { Level, LoggersResponse } from './log.model'; 7 | 8 | @Injectable({ providedIn: 'root' }) 9 | export class LogsService { 10 | private readonly http = inject(HttpClient); 11 | private readonly applicationConfigService = inject(ApplicationConfigService); 12 | 13 | changeLevel(name: string, configuredLevel: Level): Observable<{}> { 14 | return this.http.post(this.applicationConfigService.getEndpointFor(`management/loggers/${name}`), { configuredLevel }); 15 | } 16 | 17 | findAll(): Observable { 18 | return this.http.get(this.applicationConfigService.getEndpointFor('management/loggers')); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.html: -------------------------------------------------------------------------------- 1 |

Memory

2 | 3 | @if (!updating() && jvmMemoryMetrics()) { 4 |
5 | @for (entry of jvmMemoryMetrics() | keyvalue; track $index) { 6 |
7 | @if (entry.value.max !== -1) { 8 | 9 | {{ entry.key }} 10 | ({{ entry.value.used / 1048576 | number: '1.0-0' }}M / {{ entry.value.max / 1048576 | number: '1.0-0' }}M) 11 | 12 | 13 |
Committed : {{ entry.value.committed / 1048576 | number: '1.0-0' }}M
14 | 15 | {{ (entry.value.used * 100) / entry.value.max | number: '1.0-0' }}% 16 | 17 | } @else { 18 | {{ entry.key }} {{ entry.value.used / 1048576 | number: '1.0-0' }}M 21 | } 22 |
23 | } 24 |
25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | 3 | import SharedModule from 'app/shared/shared.module'; 4 | import { JvmMetrics } from 'app/admin/metrics/metrics.model'; 5 | 6 | @Component({ 7 | selector: 'jhi-jvm-memory', 8 | templateUrl: './jvm-memory.component.html', 9 | imports: [SharedModule], 10 | }) 11 | export class JvmMemoryComponent { 12 | /** 13 | * object containing all jvm memory metrics 14 | */ 15 | jvmMemoryMetrics = input>(); 16 | 17 | /** 18 | * boolean field saying if the metrics are in the process of being updated 19 | */ 20 | updating = input(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/metrics-cache/metrics-cache.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, input } from '@angular/core'; 2 | 3 | import SharedModule from 'app/shared/shared.module'; 4 | import { CacheMetrics } from 'app/admin/metrics/metrics.model'; 5 | import { filterNaN } from 'app/core/util/operators'; 6 | 7 | @Component({ 8 | selector: 'jhi-metrics-cache', 9 | templateUrl: './metrics-cache.component.html', 10 | changeDetection: ChangeDetectionStrategy.OnPush, 11 | imports: [SharedModule], 12 | }) 13 | export class MetricsCacheComponent { 14 | /** 15 | * object containing all cache related metrics 16 | */ 17 | cacheMetrics = input>(); 18 | 19 | /** 20 | * boolean field saying if the metrics are in the process of being updated 21 | */ 22 | updating = input(); 23 | 24 | filterNaN = (n: number): number => filterNaN(n); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/metrics-datasource/metrics-datasource.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, input } from '@angular/core'; 2 | 3 | import SharedModule from 'app/shared/shared.module'; 4 | import { Databases } from 'app/admin/metrics/metrics.model'; 5 | import { filterNaN } from 'app/core/util/operators'; 6 | 7 | @Component({ 8 | selector: 'jhi-metrics-datasource', 9 | templateUrl: './metrics-datasource.component.html', 10 | changeDetection: ChangeDetectionStrategy.OnPush, 11 | imports: [SharedModule], 12 | }) 13 | export class MetricsDatasourceComponent { 14 | /** 15 | * object containing all datasource related metrics 16 | */ 17 | datasourceMetrics = input(); 18 | 19 | /** 20 | * boolean field saying if the metrics are in the process of being updated 21 | */ 22 | updating = input(); 23 | 24 | filterNaN = (n: number): number => filterNaN(n); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/metrics-endpoints-requests/metrics-endpoints-requests.component.html: -------------------------------------------------------------------------------- 1 |

Endpoints requests (time in millisecond)

2 | 3 | @if (!updating() && endpointsRequestsMetrics()) { 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | @for (entry of endpointsRequestsMetrics() | keyvalue; track entry.key) { 16 | @for (method of entry.value | keyvalue; track method.key) { 17 | 18 | 19 | 20 | 21 | 22 | 23 | } 24 | } 25 | 26 |
MethodEndpoint urlCountMean
{{ method.key }}{{ entry.key }}{{ method.value!.count }}{{ method.value!.mean | number: '1.0-3' }}
27 |
28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/metrics-endpoints-requests/metrics-endpoints-requests.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | 3 | import SharedModule from 'app/shared/shared.module'; 4 | import { Services } from 'app/admin/metrics/metrics.model'; 5 | 6 | @Component({ 7 | selector: 'jhi-metrics-endpoints-requests', 8 | templateUrl: './metrics-endpoints-requests.component.html', 9 | imports: [SharedModule], 10 | }) 11 | export class MetricsEndpointsRequestsComponent { 12 | /** 13 | * object containing service related metrics 14 | */ 15 | endpointsRequestsMetrics = input(); 16 | 17 | /** 18 | * boolean field saying if the metrics are in the process of being updated 19 | */ 20 | updating = input(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | 3 | import SharedModule from 'app/shared/shared.module'; 4 | import { GarbageCollector } from 'app/admin/metrics/metrics.model'; 5 | 6 | @Component({ 7 | selector: 'jhi-metrics-garbagecollector', 8 | templateUrl: './metrics-garbagecollector.component.html', 9 | imports: [SharedModule], 10 | }) 11 | export class MetricsGarbageCollectorComponent { 12 | /** 13 | * object containing garbage collector related metrics 14 | */ 15 | garbageCollectorMetrics = input(); 16 | 17 | /** 18 | * boolean field saying if the metrics are in the process of being updated 19 | */ 20 | updating = input(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/blocks/metrics-request/metrics-request.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, input } from '@angular/core'; 2 | 3 | import SharedModule from 'app/shared/shared.module'; 4 | import { HttpServerRequests } from 'app/admin/metrics/metrics.model'; 5 | import { filterNaN } from 'app/core/util/operators'; 6 | 7 | @Component({ 8 | selector: 'jhi-metrics-request', 9 | templateUrl: './metrics-request.component.html', 10 | changeDetection: ChangeDetectionStrategy.OnPush, 11 | imports: [SharedModule], 12 | }) 13 | export class MetricsRequestComponent { 14 | /** 15 | * object containing http request related metrics 16 | */ 17 | requestMetrics = input(); 18 | 19 | /** 20 | * boolean field saying if the metrics are in the process of being updated 21 | */ 22 | updating = input(); 23 | 24 | filterNaN = (n: number): number => filterNaN(n); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/metrics.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | 5 | import { ApplicationConfigService } from 'app/core/config/application-config.service'; 6 | import { Metrics, ThreadDump } from './metrics.model'; 7 | 8 | @Injectable({ providedIn: 'root' }) 9 | export class MetricsService { 10 | private readonly http = inject(HttpClient); 11 | private readonly applicationConfigService = inject(ApplicationConfigService); 12 | 13 | getMetrics(): Observable { 14 | return this.http.get(this.applicationConfigService.getEndpointFor('management/jhimetrics')); 15 | } 16 | 17 | threadDump(): Observable { 18 | return this.http.get(this.applicationConfigService.getEndpointFor('management/threaddump')); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/delete/user-management-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 | @if (user) { 2 |
3 | 6 | 7 | 14 | 15 | 24 |
25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/delete/user-management-delete-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import SharedModule from 'app/shared/shared.module'; 6 | import { User } from '../user-management.model'; 7 | import { UserManagementService } from '../service/user-management.service'; 8 | 9 | @Component({ 10 | selector: 'jhi-user-mgmt-delete-dialog', 11 | templateUrl: './user-management-delete-dialog.component.html', 12 | imports: [SharedModule, FormsModule], 13 | }) 14 | export default class UserManagementDeleteDialogComponent { 15 | user?: User; 16 | 17 | private readonly userService = inject(UserManagementService); 18 | private readonly activeModal = inject(NgbActiveModal); 19 | 20 | cancel(): void { 21 | this.activeModal.dismiss(); 22 | } 23 | 24 | confirmDelete(login: string): void { 25 | this.userService.delete(login).subscribe(() => { 26 | this.activeModal.close('deleted'); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/detail/user-management-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | import SharedModule from 'app/shared/shared.module'; 4 | 5 | import { User } from '../user-management.model'; 6 | 7 | @Component({ 8 | selector: 'jhi-user-mgmt-detail', 9 | templateUrl: './user-management-detail.component.html', 10 | imports: [RouterModule, SharedModule], 11 | }) 12 | export default class UserManagementDetailComponent { 13 | user = input(null); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/user-management.model.ts: -------------------------------------------------------------------------------- 1 | export interface IUser { 2 | id: number | null; 3 | login?: string; 4 | firstName?: string | null; 5 | lastName?: string | null; 6 | email?: string; 7 | activated?: boolean; 8 | langKey?: string; 9 | authorities?: string[]; 10 | createdBy?: string; 11 | createdDate?: Date; 12 | lastModifiedBy?: string; 13 | lastModifiedDate?: Date; 14 | } 15 | 16 | export class User implements IUser { 17 | constructor( 18 | public id: number | null, 19 | public login?: string, 20 | public firstName?: string | null, 21 | public lastName?: string | null, 22 | public email?: string, 23 | public activated?: boolean, 24 | public langKey?: string, 25 | public authorities?: string[], 26 | public createdBy?: string, 27 | public createdDate?: Date, 28 | public lastModifiedBy?: string, 29 | public lastModifiedDate?: Date, 30 | ) {} 31 | } 32 | -------------------------------------------------------------------------------- /src/main/webapp/app/app-page-title-strategy.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { RouterStateSnapshot, TitleStrategy } from '@angular/router'; 3 | import { TranslateService } from '@ngx-translate/core'; 4 | 5 | @Injectable() 6 | export class AppPageTitleStrategy extends TitleStrategy { 7 | private readonly translateService = inject(TranslateService); 8 | 9 | override updateTitle(routerState: RouterStateSnapshot): void { 10 | let pageTitle = this.buildTitle(routerState); 11 | pageTitle ??= 'global.title'; 12 | this.translateService.get(pageTitle).subscribe(title => { 13 | document.title = title; 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/webapp/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | import { Authority } from 'app/config/authority.constants'; 4 | 5 | import { UserRouteAccessService } from 'app/core/auth/user-route-access.service'; 6 | import { errorRoute } from './layouts/error/error.route'; 7 | 8 | const routes: Routes = [ 9 | { 10 | path: '', 11 | loadComponent: () => import('./home/home.component'), 12 | title: 'home.title', 13 | }, 14 | { 15 | path: '', 16 | loadComponent: () => import('./layouts/navbar/navbar.component'), 17 | outlet: 'navbar', 18 | }, 19 | { 20 | path: 'admin', 21 | data: { 22 | authorities: [Authority.ADMIN], 23 | }, 24 | canActivate: [UserRouteAccessService], 25 | loadChildren: () => import('./admin/admin.routes'), 26 | }, 27 | { 28 | path: 'account', 29 | loadChildren: () => import('./account/account.route'), 30 | }, 31 | { 32 | path: 'login', 33 | loadComponent: () => import('./login/login.component'), 34 | title: 'login.title', 35 | }, 36 | { 37 | path: '', 38 | loadChildren: () => import(`./entities/entity.routes`), 39 | }, 40 | ...errorRoute, 41 | ]; 42 | 43 | export default routes; 44 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/authority.constants.ts: -------------------------------------------------------------------------------- 1 | export enum Authority { 2 | ADMIN = 'ROLE_ADMIN', 3 | USER = 'ROLE_USER', 4 | } 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/datepicker-adapter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Angular bootstrap Date adapter 3 | */ 4 | import { Injectable } from '@angular/core'; 5 | import { NgbDateAdapter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; 6 | import dayjs from 'dayjs/esm'; 7 | 8 | @Injectable() 9 | export class NgbDateDayjsAdapter extends NgbDateAdapter { 10 | fromModel(date: dayjs.Dayjs | null): NgbDateStruct | null { 11 | if (date && dayjs.isDayjs(date) && date.isValid()) { 12 | return { year: date.year(), month: date.month() + 1, day: date.date() }; 13 | } 14 | return null; 15 | } 16 | 17 | toModel(date: NgbDateStruct | null): dayjs.Dayjs | null { 18 | return date ? dayjs(`${date.year}-${date.month}-${date.day}`) : null; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/dayjs.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs/esm'; 2 | import customParseFormat from 'dayjs/esm/plugin/customParseFormat'; 3 | import duration from 'dayjs/esm/plugin/duration'; 4 | import relativeTime from 'dayjs/esm/plugin/relativeTime'; 5 | 6 | // jhipster-needle-i18n-language-dayjs-imports - JHipster will import languages from dayjs here 7 | import 'dayjs/esm/locale/en'; 8 | 9 | // DAYJS CONFIGURATION 10 | dayjs.extend(customParseFormat); 11 | dayjs.extend(duration); 12 | dayjs.extend(relativeTime); 13 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/error.constants.ts: -------------------------------------------------------------------------------- 1 | export const PROBLEM_BASE_URL = 'https://www.jhipster.tech/problem'; 2 | export const EMAIL_ALREADY_USED_TYPE = `${PROBLEM_BASE_URL}/email-already-used`; 3 | export const LOGIN_ALREADY_USED_TYPE = `${PROBLEM_BASE_URL}/login-already-used`; 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/input.constants.ts: -------------------------------------------------------------------------------- 1 | export const DATE_FORMAT = 'YYYY-MM-DD'; 2 | export const DATE_TIME_FORMAT = 'YYYY-MM-DDTHH:mm'; 3 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/language.constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Languages codes are ISO_639-1 codes, see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes 3 | They are written in English to avoid character encoding issues (not a perfect solution) 4 | */ 5 | export const LANGUAGES: string[] = [ 6 | 'en', 7 | // jhipster-needle-i18n-language-constant - JHipster will add/remove languages in this array 8 | ]; 9 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/navigation.constants.ts: -------------------------------------------------------------------------------- 1 | export const ASC = 'asc'; 2 | export const DESC = 'desc'; 3 | export const SORT = 'sort'; 4 | export const ITEM_DELETED_EVENT = 'deleted'; 5 | export const DEFAULT_SORT_DATA = 'defaultSort'; 6 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/pagination.constants.ts: -------------------------------------------------------------------------------- 1 | export const TOTAL_COUNT_RESPONSE_HEADER = 'X-Total-Count'; 2 | export const PAGE_HEADER = 'page'; 3 | export const ITEMS_PER_PAGE = 20; 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/translation.config.ts: -------------------------------------------------------------------------------- 1 | import { MissingTranslationHandler, MissingTranslationHandlerParams, TranslateLoader } from '@ngx-translate/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { TranslateHttpLoader } from '@ngx-translate/http-loader'; 4 | 5 | export const translationNotFoundMessage = 'translation-not-found'; 6 | 7 | export class MissingTranslationHandlerImpl implements MissingTranslationHandler { 8 | handle(params: MissingTranslationHandlerParams): string { 9 | const { key } = params; 10 | return `${translationNotFoundMessage}[${key}]`; 11 | } 12 | } 13 | 14 | export function translatePartialLoader(http: HttpClient): TranslateLoader { 15 | return new TranslateHttpLoader(http, 'i18n/', `.json?_=${I18N_HASH}`); 16 | } 17 | 18 | export function missingTranslationHandler(): MissingTranslationHandler { 19 | return new MissingTranslationHandlerImpl(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/uib-pagination.config.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { NgbPaginationConfig } from '@ng-bootstrap/ng-bootstrap'; 3 | 4 | import { ITEMS_PER_PAGE } from 'app/config/pagination.constants'; 5 | 6 | @Injectable({ providedIn: 'root' }) 7 | export class PaginationConfig { 8 | private readonly config = inject(NgbPaginationConfig); 9 | constructor() { 10 | this.config.boundaryLinks = true; 11 | this.config.maxSize = 5; 12 | this.config.pageSize = ITEMS_PER_PAGE; 13 | this.config.size = 'sm'; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/auth/account.model.ts: -------------------------------------------------------------------------------- 1 | export class Account { 2 | constructor( 3 | public activated: boolean, 4 | public authorities: string[], 5 | public email: string, 6 | public firstName: string | null, 7 | public langKey: string, 8 | public lastName: string | null, 9 | public login: string, 10 | public imageUrl: string | null, 11 | ) {} 12 | } 13 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/auth/user-route-access.service.ts: -------------------------------------------------------------------------------- 1 | import { inject, isDevMode } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router'; 3 | import { map } from 'rxjs/operators'; 4 | 5 | import { AccountService } from 'app/core/auth/account.service'; 6 | import { StateStorageService } from './state-storage.service'; 7 | 8 | export const UserRouteAccessService: CanActivateFn = (next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { 9 | const accountService = inject(AccountService); 10 | const router = inject(Router); 11 | const stateStorageService = inject(StateStorageService); 12 | return accountService.identity().pipe( 13 | map(account => { 14 | if (account) { 15 | const { authorities } = next.data; 16 | 17 | if (!authorities || authorities.length === 0 || accountService.hasAnyAuthority(authorities)) { 18 | return true; 19 | } 20 | 21 | if (isDevMode()) { 22 | console.error('User does not have any of the required authorities:', authorities); 23 | } 24 | router.navigate(['accessdenied']); 25 | return false; 26 | } 27 | 28 | stateStorageService.storeUrl(state.url); 29 | router.navigate(['/login']); 30 | return false; 31 | }), 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/config/application-config.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root', 5 | }) 6 | export class ApplicationConfigService { 7 | private endpointPrefix = ''; 8 | private microfrontend = false; 9 | 10 | setEndpointPrefix(endpointPrefix: string): void { 11 | this.endpointPrefix = endpointPrefix; 12 | } 13 | 14 | setMicrofrontend(microfrontend = true): void { 15 | this.microfrontend = microfrontend; 16 | } 17 | 18 | isMicrofrontend(): boolean { 19 | return this.microfrontend; 20 | } 21 | 22 | getEndpointFor(api: string, microservice?: string): string { 23 | if (microservice) { 24 | return `${this.endpointPrefix}services/${microservice}/${api}`; 25 | } 26 | return `${this.endpointPrefix}${api}`; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/interceptor/error-handler.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, inject } from '@angular/core'; 2 | import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | import { tap } from 'rxjs/operators'; 5 | 6 | import { EventManager, EventWithContent } from 'app/core/util/event-manager.service'; 7 | 8 | @Injectable() 9 | export class ErrorHandlerInterceptor implements HttpInterceptor { 10 | private readonly eventManager = inject(EventManager); 11 | 12 | intercept(request: HttpRequest, next: HttpHandler): Observable> { 13 | return next.handle(request).pipe( 14 | tap({ 15 | error: (err: HttpErrorResponse) => { 16 | if (!(err.status === 401 && (err.message === '' || err.url?.includes('api/account')))) { 17 | this.eventManager.broadcast(new EventWithContent('jhipsterDtoSampleApplicationApp.httpError', err)); 18 | } 19 | }, 20 | }), 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/interceptor/index.ts: -------------------------------------------------------------------------------- 1 | import { HTTP_INTERCEPTORS } from '@angular/common/http'; 2 | 3 | import { AuthExpiredInterceptor } from 'app/core/interceptor/auth-expired.interceptor'; 4 | import { ErrorHandlerInterceptor } from 'app/core/interceptor/error-handler.interceptor'; 5 | import { NotificationInterceptor } from 'app/core/interceptor/notification.interceptor'; 6 | 7 | export const httpInterceptorProviders = [ 8 | { 9 | provide: HTTP_INTERCEPTORS, 10 | useClass: AuthExpiredInterceptor, 11 | multi: true, 12 | }, 13 | { 14 | provide: HTTP_INTERCEPTORS, 15 | useClass: ErrorHandlerInterceptor, 16 | multi: true, 17 | }, 18 | { 19 | provide: HTTP_INTERCEPTORS, 20 | useClass: NotificationInterceptor, 21 | multi: true, 22 | }, 23 | ]; 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/request/request-util.ts: -------------------------------------------------------------------------------- 1 | import { HttpParams } from '@angular/common/http'; 2 | 3 | export const createRequestOption = (req?: any): HttpParams => { 4 | let options: HttpParams = new HttpParams(); 5 | 6 | if (req) { 7 | Object.entries(req).forEach(([key, val]) => { 8 | if (val !== undefined && val !== null) { 9 | for (const value of [].concat(req[key]).filter(v => v !== '')) { 10 | options = options.append(key, value); 11 | } 12 | } 13 | }); 14 | } 15 | 16 | return options; 17 | }; 18 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/request/request.model.ts: -------------------------------------------------------------------------------- 1 | export interface Pagination { 2 | page: number; 3 | size: number; 4 | sort: string[]; 5 | } 6 | 7 | export interface Search { 8 | query: string; 9 | } 10 | 11 | export interface SearchWithPagination extends Search, Pagination {} 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/util/data-util.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { DataUtils } from './data-util.service'; 4 | 5 | describe('Data Utils Service Test', () => { 6 | let service: DataUtils; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({ 10 | providers: [DataUtils], 11 | }); 12 | service = TestBed.inject(DataUtils); 13 | }); 14 | 15 | describe('byteSize', () => { 16 | it('should return the bytesize of the text', () => { 17 | expect(service.byteSize('Hello JHipster')).toBe(`10.5 bytes`); 18 | }); 19 | }); 20 | 21 | describe('openFile', () => { 22 | it('should open the file in the new window', () => { 23 | const newWindow = { ...window }; 24 | window.open = jest.fn(() => newWindow); 25 | window.URL.createObjectURL = jest.fn(); 26 | // 'JHipster' in base64 is 'SkhpcHN0ZXI=' 27 | const data = 'SkhpcHN0ZXI='; 28 | const contentType = 'text/plain'; 29 | service.openFile(data, contentType); 30 | expect(window.open).toHaveBeenCalledTimes(1); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/util/operators.spec.ts: -------------------------------------------------------------------------------- 1 | import { filterNaN, isPresent } from './operators'; 2 | 3 | describe('Operators Test', () => { 4 | describe('isPresent', () => { 5 | it('should remove null and undefined values', () => { 6 | expect([1, null, undefined].filter(isPresent)).toEqual([1]); 7 | }); 8 | }); 9 | 10 | describe('filterNaN', () => { 11 | it('should return 0 for NaN', () => { 12 | expect(filterNaN(NaN)).toBe(0); 13 | }); 14 | it('should return number for a number', () => { 15 | expect(filterNaN(12345)).toBe(12345); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/main/webapp/app/core/util/operators.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Function used to workaround https://github.com/microsoft/TypeScript/issues/16069 3 | * es2019 alternative `const filteredArr = myArr.flatMap((x) => x ? x : []);` 4 | */ 5 | export function isPresent(t: T | undefined | null): t is T { 6 | return t !== undefined && t !== null; 7 | } 8 | 9 | export const filterNaN = (input: number): number => (isNaN(input) ? 0 : input); 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/authority.model.ts: -------------------------------------------------------------------------------- 1 | export interface IAuthority { 2 | name: string; 3 | } 4 | 5 | export type NewAuthority = Omit & { name: null }; 6 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/authority.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from 'app/core/auth/user-route-access.service'; 4 | import AuthorityResolve from './route/authority-routing-resolve.service'; 5 | 6 | const authorityRoute: Routes = [ 7 | { 8 | path: '', 9 | loadComponent: () => import('./list/authority.component').then(m => m.AuthorityComponent), 10 | data: { 11 | authorities: ['ROLE_ADMIN'], 12 | }, 13 | canActivate: [UserRouteAccessService], 14 | }, 15 | { 16 | path: ':name/view', 17 | loadComponent: () => import('./detail/authority-detail.component').then(m => m.AuthorityDetailComponent), 18 | resolve: { 19 | authority: AuthorityResolve, 20 | }, 21 | data: { 22 | authorities: ['ROLE_ADMIN'], 23 | }, 24 | canActivate: [UserRouteAccessService], 25 | }, 26 | { 27 | path: 'new', 28 | loadComponent: () => import('./update/authority-update.component').then(m => m.AuthorityUpdateComponent), 29 | resolve: { 30 | authority: AuthorityResolve, 31 | }, 32 | data: { 33 | authorities: ['ROLE_ADMIN'], 34 | }, 35 | canActivate: [UserRouteAccessService], 36 | }, 37 | ]; 38 | 39 | export default authorityRoute; 40 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/authority.test-samples.ts: -------------------------------------------------------------------------------- 1 | import { IAuthority, NewAuthority } from './authority.model'; 2 | 3 | export const sampleWithRequiredData: IAuthority = { 4 | name: '403e92cf-81b1-401a-9d29-24f9a5b9a4f7', 5 | }; 6 | 7 | export const sampleWithPartialData: IAuthority = { 8 | name: '7bd55631-a2c5-45ca-8628-9d2760e719a6', 9 | }; 10 | 11 | export const sampleWithFullData: IAuthority = { 12 | name: '13e08196-c7f7-4f05-9df5-047fea2afaa7', 13 | }; 14 | 15 | export const sampleWithNewData: NewAuthority = { 16 | name: null, 17 | }; 18 | 19 | Object.freeze(sampleWithNewData); 20 | Object.freeze(sampleWithRequiredData); 21 | Object.freeze(sampleWithPartialData); 22 | Object.freeze(sampleWithFullData); 23 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/delete/authority-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 | @if (authority) { 2 |
3 | 6 | 7 | 17 | 18 | 27 |
28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/delete/authority-delete-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import SharedModule from 'app/shared/shared.module'; 6 | import { ITEM_DELETED_EVENT } from 'app/config/navigation.constants'; 7 | import { IAuthority } from '../authority.model'; 8 | import { AuthorityService } from '../service/authority.service'; 9 | 10 | @Component({ 11 | templateUrl: './authority-delete-dialog.component.html', 12 | imports: [SharedModule, FormsModule], 13 | }) 14 | export class AuthorityDeleteDialogComponent { 15 | authority?: IAuthority; 16 | 17 | protected authorityService = inject(AuthorityService); 18 | protected activeModal = inject(NgbActiveModal); 19 | 20 | cancel(): void { 21 | this.activeModal.dismiss(); 22 | } 23 | 24 | confirmDelete(id: string): void { 25 | this.authorityService.delete(id).subscribe(() => { 26 | this.activeModal.close(ITEM_DELETED_EVENT); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/detail/authority-detail.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | @if (authority(); as authorityRef) { 4 |
5 |

6 | Authority 7 |

8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 |
16 |
Name
17 |
18 | {{ authorityRef.name }} 19 |
20 |
21 | 22 | 25 |
26 | } 27 |
28 |
29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/detail/authority-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import SharedModule from 'app/shared/shared.module'; 5 | import { IAuthority } from '../authority.model'; 6 | 7 | @Component({ 8 | selector: 'jhi-authority-detail', 9 | templateUrl: './authority-detail.component.html', 10 | imports: [SharedModule, RouterModule], 11 | }) 12 | export class AuthorityDetailComponent { 13 | authority = input(null); 14 | 15 | previousState(): void { 16 | window.history.back(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/admin/authority/route/authority-routing-resolve.service.ts: -------------------------------------------------------------------------------- 1 | import { inject } from '@angular/core'; 2 | import { HttpResponse } from '@angular/common/http'; 3 | import { ActivatedRouteSnapshot, Router } from '@angular/router'; 4 | import { EMPTY, Observable, of } from 'rxjs'; 5 | import { mergeMap } from 'rxjs/operators'; 6 | 7 | import { IAuthority } from '../authority.model'; 8 | import { AuthorityService } from '../service/authority.service'; 9 | 10 | const authorityResolve = (route: ActivatedRouteSnapshot): Observable => { 11 | const id = route.params.name; 12 | if (id) { 13 | return inject(AuthorityService) 14 | .find(id) 15 | .pipe( 16 | mergeMap((authority: HttpResponse) => { 17 | if (authority.body) { 18 | return of(authority.body); 19 | } 20 | inject(Router).navigate(['404']); 21 | return EMPTY; 22 | }), 23 | ); 24 | } 25 | return of(null); 26 | }; 27 | 28 | export default authorityResolve; 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/bank-account/bank-account.model.ts: -------------------------------------------------------------------------------- 1 | import { IUser } from 'app/entities/user/user.model'; 2 | 3 | export interface IBankAccount { 4 | id: number; 5 | name?: string | null; 6 | balance?: number | null; 7 | user?: Pick | null; 8 | } 9 | 10 | export type NewBankAccount = Omit & { id: null }; 11 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/bank-account/bank-account.test-samples.ts: -------------------------------------------------------------------------------- 1 | import { IBankAccount, NewBankAccount } from './bank-account.model'; 2 | 3 | export const sampleWithRequiredData: IBankAccount = { 4 | id: 17167, 5 | name: 'um via', 6 | balance: 2293.59, 7 | }; 8 | 9 | export const sampleWithPartialData: IBankAccount = { 10 | id: 18934, 11 | name: 'bright whenever', 12 | balance: 7939.53, 13 | }; 14 | 15 | export const sampleWithFullData: IBankAccount = { 16 | id: 13483, 17 | name: 'gigantic', 18 | balance: 26580.31, 19 | }; 20 | 21 | export const sampleWithNewData: NewBankAccount = { 22 | name: 'clonk porter', 23 | balance: 26302.97, 24 | id: null, 25 | }; 26 | 27 | Object.freeze(sampleWithNewData); 28 | Object.freeze(sampleWithRequiredData); 29 | Object.freeze(sampleWithPartialData); 30 | Object.freeze(sampleWithFullData); 31 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/bank-account/delete/bank-account-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 | @if (bankAccount) { 2 |
3 | 6 | 7 | 17 | 18 | 27 |
28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/bank-account/delete/bank-account-delete-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import SharedModule from 'app/shared/shared.module'; 6 | import { ITEM_DELETED_EVENT } from 'app/config/navigation.constants'; 7 | import { IBankAccount } from '../bank-account.model'; 8 | import { BankAccountService } from '../service/bank-account.service'; 9 | 10 | @Component({ 11 | templateUrl: './bank-account-delete-dialog.component.html', 12 | imports: [SharedModule, FormsModule], 13 | }) 14 | export class BankAccountDeleteDialogComponent { 15 | bankAccount?: IBankAccount; 16 | 17 | protected bankAccountService = inject(BankAccountService); 18 | protected activeModal = inject(NgbActiveModal); 19 | 20 | cancel(): void { 21 | this.activeModal.dismiss(); 22 | } 23 | 24 | confirmDelete(id: number): void { 25 | this.bankAccountService.delete(id).subscribe(() => { 26 | this.activeModal.close(ITEM_DELETED_EVENT); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/bank-account/detail/bank-account-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import SharedModule from 'app/shared/shared.module'; 5 | import { IBankAccount } from '../bank-account.model'; 6 | 7 | @Component({ 8 | selector: 'jhi-bank-account-detail', 9 | templateUrl: './bank-account-detail.component.html', 10 | imports: [SharedModule, RouterModule], 11 | }) 12 | export class BankAccountDetailComponent { 13 | bankAccount = input(null); 14 | 15 | previousState(): void { 16 | window.history.back(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/bank-account/route/bank-account-routing-resolve.service.ts: -------------------------------------------------------------------------------- 1 | import { inject } from '@angular/core'; 2 | import { HttpResponse } from '@angular/common/http'; 3 | import { ActivatedRouteSnapshot, Router } from '@angular/router'; 4 | import { EMPTY, Observable, of } from 'rxjs'; 5 | import { mergeMap } from 'rxjs/operators'; 6 | 7 | import { IBankAccount } from '../bank-account.model'; 8 | import { BankAccountService } from '../service/bank-account.service'; 9 | 10 | const bankAccountResolve = (route: ActivatedRouteSnapshot): Observable => { 11 | const id = route.params.id; 12 | if (id) { 13 | return inject(BankAccountService) 14 | .find(id) 15 | .pipe( 16 | mergeMap((bankAccount: HttpResponse) => { 17 | if (bankAccount.body) { 18 | return of(bankAccount.body); 19 | } 20 | inject(Router).navigate(['404']); 21 | return EMPTY; 22 | }), 23 | ); 24 | } 25 | return of(null); 26 | }; 27 | 28 | export default bankAccountResolve; 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/entity-navbar-items.ts: -------------------------------------------------------------------------------- 1 | import NavbarItem from 'app/layouts/navbar/navbar-item.model'; 2 | 3 | export const EntityNavbarItems: NavbarItem[] = [ 4 | { 5 | name: 'BankAccount', 6 | route: '/bank-account', 7 | translationKey: 'global.menu.entities.bankAccount', 8 | }, 9 | { 10 | name: 'Label', 11 | route: '/label', 12 | translationKey: 'global.menu.entities.label', 13 | }, 14 | { 15 | name: 'Operation', 16 | route: '/operation', 17 | translationKey: 'global.menu.entities.operation', 18 | }, 19 | ]; 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/entity.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | const routes: Routes = [ 4 | { 5 | path: 'authority', 6 | data: { pageTitle: 'jhipsterDtoSampleApplicationApp.adminAuthority.home.title' }, 7 | loadChildren: () => import('./admin/authority/authority.routes'), 8 | }, 9 | { 10 | path: 'bank-account', 11 | data: { pageTitle: 'jhipsterDtoSampleApplicationApp.bankAccount.home.title' }, 12 | loadChildren: () => import('./bank-account/bank-account.routes'), 13 | }, 14 | { 15 | path: 'label', 16 | data: { pageTitle: 'jhipsterDtoSampleApplicationApp.label.home.title' }, 17 | loadChildren: () => import('./label/label.routes'), 18 | }, 19 | { 20 | path: 'operation', 21 | data: { pageTitle: 'jhipsterDtoSampleApplicationApp.operation.home.title' }, 22 | loadChildren: () => import('./operation/operation.routes'), 23 | }, 24 | /* jhipster-needle-add-entity-route - JHipster will add entity modules routes here */ 25 | ]; 26 | 27 | export default routes; 28 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/label/delete/label-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 | @if (label) { 2 |
3 | 6 | 7 | 17 | 18 | 27 |
28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/label/delete/label-delete-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import SharedModule from 'app/shared/shared.module'; 6 | import { ITEM_DELETED_EVENT } from 'app/config/navigation.constants'; 7 | import { ILabel } from '../label.model'; 8 | import { LabelService } from '../service/label.service'; 9 | 10 | @Component({ 11 | templateUrl: './label-delete-dialog.component.html', 12 | imports: [SharedModule, FormsModule], 13 | }) 14 | export class LabelDeleteDialogComponent { 15 | label?: ILabel; 16 | 17 | protected labelService = inject(LabelService); 18 | protected activeModal = inject(NgbActiveModal); 19 | 20 | cancel(): void { 21 | this.activeModal.dismiss(); 22 | } 23 | 24 | confirmDelete(id: number): void { 25 | this.labelService.delete(id).subscribe(() => { 26 | this.activeModal.close(ITEM_DELETED_EVENT); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/label/detail/label-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import SharedModule from 'app/shared/shared.module'; 5 | import { ILabel } from '../label.model'; 6 | 7 | @Component({ 8 | selector: 'jhi-label-detail', 9 | templateUrl: './label-detail.component.html', 10 | imports: [SharedModule, RouterModule], 11 | }) 12 | export class LabelDetailComponent { 13 | label = input(null); 14 | 15 | previousState(): void { 16 | window.history.back(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/label/label.model.ts: -------------------------------------------------------------------------------- 1 | import { IOperation } from 'app/entities/operation/operation.model'; 2 | 3 | export interface ILabel { 4 | id: number; 5 | label?: string | null; 6 | operations?: Pick[] | null; 7 | } 8 | 9 | export type NewLabel = Omit & { id: null }; 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/label/label.test-samples.ts: -------------------------------------------------------------------------------- 1 | import { ILabel, NewLabel } from './label.model'; 2 | 3 | export const sampleWithRequiredData: ILabel = { 4 | id: 28258, 5 | label: 'impressive', 6 | }; 7 | 8 | export const sampleWithPartialData: ILabel = { 9 | id: 5331, 10 | label: 'within helpfully zowie', 11 | }; 12 | 13 | export const sampleWithFullData: ILabel = { 14 | id: 11722, 15 | label: 'gloomy unless sew', 16 | }; 17 | 18 | export const sampleWithNewData: NewLabel = { 19 | label: 'scaly save yum', 20 | id: null, 21 | }; 22 | 23 | Object.freeze(sampleWithNewData); 24 | Object.freeze(sampleWithRequiredData); 25 | Object.freeze(sampleWithPartialData); 26 | Object.freeze(sampleWithFullData); 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/label/route/label-routing-resolve.service.ts: -------------------------------------------------------------------------------- 1 | import { inject } from '@angular/core'; 2 | import { HttpResponse } from '@angular/common/http'; 3 | import { ActivatedRouteSnapshot, Router } from '@angular/router'; 4 | import { EMPTY, Observable, of } from 'rxjs'; 5 | import { mergeMap } from 'rxjs/operators'; 6 | 7 | import { ILabel } from '../label.model'; 8 | import { LabelService } from '../service/label.service'; 9 | 10 | const labelResolve = (route: ActivatedRouteSnapshot): Observable => { 11 | const id = route.params.id; 12 | if (id) { 13 | return inject(LabelService) 14 | .find(id) 15 | .pipe( 16 | mergeMap((label: HttpResponse) => { 17 | if (label.body) { 18 | return of(label.body); 19 | } 20 | inject(Router).navigate(['404']); 21 | return EMPTY; 22 | }), 23 | ); 24 | } 25 | return of(null); 26 | }; 27 | 28 | export default labelResolve; 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/operation/delete/operation-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 | @if (operation) { 2 |
3 | 6 | 7 | 17 | 18 | 27 |
28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/operation/delete/operation-delete-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, inject } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import SharedModule from 'app/shared/shared.module'; 6 | import { ITEM_DELETED_EVENT } from 'app/config/navigation.constants'; 7 | import { IOperation } from '../operation.model'; 8 | import { OperationService } from '../service/operation.service'; 9 | 10 | @Component({ 11 | templateUrl: './operation-delete-dialog.component.html', 12 | imports: [SharedModule, FormsModule], 13 | }) 14 | export class OperationDeleteDialogComponent { 15 | operation?: IOperation; 16 | 17 | protected operationService = inject(OperationService); 18 | protected activeModal = inject(NgbActiveModal); 19 | 20 | cancel(): void { 21 | this.activeModal.dismiss(); 22 | } 23 | 24 | confirmDelete(id: number): void { 25 | this.operationService.delete(id).subscribe(() => { 26 | this.activeModal.close(ITEM_DELETED_EVENT); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/operation/detail/operation-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import SharedModule from 'app/shared/shared.module'; 5 | import { FormatMediumDatetimePipe } from 'app/shared/date'; 6 | import { IOperation } from '../operation.model'; 7 | 8 | @Component({ 9 | selector: 'jhi-operation-detail', 10 | templateUrl: './operation-detail.component.html', 11 | imports: [SharedModule, RouterModule, FormatMediumDatetimePipe], 12 | }) 13 | export class OperationDetailComponent { 14 | operation = input(null); 15 | 16 | previousState(): void { 17 | window.history.back(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/operation/operation.model.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs/esm'; 2 | import { IBankAccount } from 'app/entities/bank-account/bank-account.model'; 3 | import { ILabel } from 'app/entities/label/label.model'; 4 | 5 | export interface IOperation { 6 | id: number; 7 | date?: dayjs.Dayjs | null; 8 | description?: string | null; 9 | amount?: number | null; 10 | bankAccount?: Pick | null; 11 | labels?: Pick[] | null; 12 | } 13 | 14 | export type NewOperation = Omit & { id: null }; 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/operation/operation.test-samples.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs/esm'; 2 | 3 | import { IOperation, NewOperation } from './operation.model'; 4 | 5 | export const sampleWithRequiredData: IOperation = { 6 | id: 6430, 7 | date: dayjs('2015-08-04T16:53'), 8 | amount: 11212.28, 9 | }; 10 | 11 | export const sampleWithPartialData: IOperation = { 12 | id: 1069, 13 | date: dayjs('2015-08-05T05:24'), 14 | description: 'yieldingly than quinoa', 15 | amount: 2488.45, 16 | }; 17 | 18 | export const sampleWithFullData: IOperation = { 19 | id: 13289, 20 | date: dayjs('2015-08-05T04:43'), 21 | description: 'yowza', 22 | amount: 13675.92, 23 | }; 24 | 25 | export const sampleWithNewData: NewOperation = { 26 | date: dayjs('2015-08-05T07:27'), 27 | amount: 5543.31, 28 | id: null, 29 | }; 30 | 31 | Object.freeze(sampleWithNewData); 32 | Object.freeze(sampleWithRequiredData); 33 | Object.freeze(sampleWithPartialData); 34 | Object.freeze(sampleWithFullData); 35 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/operation/route/operation-routing-resolve.service.ts: -------------------------------------------------------------------------------- 1 | import { inject } from '@angular/core'; 2 | import { HttpResponse } from '@angular/common/http'; 3 | import { ActivatedRouteSnapshot, Router } from '@angular/router'; 4 | import { EMPTY, Observable, of } from 'rxjs'; 5 | import { mergeMap } from 'rxjs/operators'; 6 | 7 | import { IOperation } from '../operation.model'; 8 | import { OperationService } from '../service/operation.service'; 9 | 10 | const operationResolve = (route: ActivatedRouteSnapshot): Observable => { 11 | const id = route.params.id; 12 | if (id) { 13 | return inject(OperationService) 14 | .find(id) 15 | .pipe( 16 | mergeMap((operation: HttpResponse) => { 17 | if (operation.body) { 18 | return of(operation.body); 19 | } 20 | inject(Router).navigate(['404']); 21 | return EMPTY; 22 | }), 23 | ); 24 | } 25 | return of(null); 26 | }; 27 | 28 | export default operationResolve; 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/user/user.model.ts: -------------------------------------------------------------------------------- 1 | export interface IUser { 2 | id: number; 3 | login?: string | null; 4 | } 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/user/user.test-samples.ts: -------------------------------------------------------------------------------- 1 | import { IUser } from './user.model'; 2 | 3 | export const sampleWithRequiredData: IUser = { 4 | id: 24814, 5 | login: 'nuGud', 6 | }; 7 | 8 | export const sampleWithPartialData: IUser = { 9 | id: 966, 10 | login: 'a', 11 | }; 12 | 13 | export const sampleWithFullData: IUser = { 14 | id: 5440, 15 | login: 'h', 16 | }; 17 | Object.freeze(sampleWithRequiredData); 18 | Object.freeze(sampleWithPartialData); 19 | Object.freeze(sampleWithFullData); 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/home/home.component.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | Main page styles 3 | ========================================================================== */ 4 | 5 | .hipster { 6 | display: inline-block; 7 | width: 347px; 8 | height: 497px; 9 | background: url('../../content/images/jhipster_family_member_2.svg') no-repeat center top; 10 | background-size: contain; 11 | } 12 | 13 | /* wait autoprefixer update to allow simple generation of high pixel density media query */ 14 | @media only screen and (-webkit-min-device-pixel-ratio: 2), 15 | only screen and (-moz-min-device-pixel-ratio: 2), 16 | only screen and (-o-min-device-pixel-ratio: 2/1), 17 | only screen and (min-resolution: 192dpi), 18 | only screen and (min-resolution: 2dppx) { 19 | .hipster { 20 | background: url('../../content/images/jhipster_family_member_2.svg') no-repeat center top; 21 | background-size: contain; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy, OnInit, inject, signal } from '@angular/core'; 2 | import { Router, RouterModule } from '@angular/router'; 3 | import { Subject } from 'rxjs'; 4 | import { takeUntil } from 'rxjs/operators'; 5 | 6 | import SharedModule from 'app/shared/shared.module'; 7 | import { AccountService } from 'app/core/auth/account.service'; 8 | import { Account } from 'app/core/auth/account.model'; 9 | 10 | @Component({ 11 | selector: 'jhi-home', 12 | templateUrl: './home.component.html', 13 | styleUrl: './home.component.scss', 14 | imports: [SharedModule, RouterModule], 15 | }) 16 | export default class HomeComponent implements OnInit, OnDestroy { 17 | account = signal(null); 18 | 19 | private readonly destroy$ = new Subject(); 20 | 21 | private readonly accountService = inject(AccountService); 22 | private readonly router = inject(Router); 23 | 24 | ngOnInit(): void { 25 | this.accountService 26 | .getAuthenticationState() 27 | .pipe(takeUntil(this.destroy$)) 28 | .subscribe(account => this.account.set(account)); 29 | } 30 | 31 | login(): void { 32 | this.router.navigate(['/login']); 33 | } 34 | 35 | ngOnDestroy(): void { 36 | this.destroy$.next(); 37 | this.destroy$.complete(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/error/error.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 | 7 |
8 |

Error page!

9 | 10 | @if (errorMessage(); as errMessage) { 11 |
{{ errMessage }}
12 | } 13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/error/error.route.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const errorRoute: Routes = [ 4 | { 5 | path: 'error', 6 | loadComponent: () => import('./error.component'), 7 | title: 'error.title', 8 | }, 9 | { 10 | path: 'accessdenied', 11 | loadComponent: () => import('./error.component'), 12 | data: { 13 | errorMessage: 'error.http.403', 14 | }, 15 | title: 'error.title', 16 | }, 17 | { 18 | path: '404', 19 | loadComponent: () => import('./error.component'), 20 | data: { 21 | errorMessage: 'error.http.404', 22 | }, 23 | title: 'error.title', 24 | }, 25 | { 26 | path: '**', 27 | redirectTo: '/404', 28 | }, 29 | ]; 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { TranslateDirective } from 'app/shared/language'; 3 | 4 | @Component({ 5 | selector: 'jhi-footer', 6 | templateUrl: './footer.component.html', 7 | imports: [TranslateDirective], 8 | }) 9 | export default class FooterComponent {} 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/main/main.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 7 |
8 |
9 | 10 |
11 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/navbar/active-menu.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, OnInit, Renderer2, inject, input } from '@angular/core'; 2 | import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; 3 | 4 | @Directive({ 5 | selector: '[jhiActiveMenu]', 6 | }) 7 | export default class ActiveMenuDirective implements OnInit { 8 | jhiActiveMenu = input(); 9 | 10 | private readonly el = inject(ElementRef); 11 | private readonly renderer = inject(Renderer2); 12 | private readonly translateService = inject(TranslateService); 13 | 14 | ngOnInit(): void { 15 | this.translateService.onLangChange.subscribe((event: LangChangeEvent) => { 16 | this.updateActiveFlag(event.lang); 17 | }); 18 | 19 | this.updateActiveFlag(this.translateService.currentLang); 20 | } 21 | 22 | updateActiveFlag(selectedLanguage: string): void { 23 | if (this.jhiActiveMenu() === selectedLanguage) { 24 | this.renderer.addClass(this.el.nativeElement, 'active'); 25 | } else { 26 | this.renderer.removeClass(this.el.nativeElement, 'active'); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/navbar/navbar-item.model.d.ts: -------------------------------------------------------------------------------- 1 | type NavbarItem = { 2 | name: string; 3 | route: string; 4 | translationKey: string; 5 | }; 6 | 7 | export default NavbarItem; 8 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/navbar/navbar.component.scss: -------------------------------------------------------------------------------- 1 | @import 'bootstrap/scss/functions'; 2 | @import 'bootstrap/scss/variables'; 3 | 4 | /* ========================================================================== 5 | Navbar 6 | ========================================================================== */ 7 | 8 | .navbar-version { 9 | font-size: 0.65em; 10 | color: $navbar-dark-color; 11 | } 12 | 13 | .profile-image { 14 | height: 1.75em; 15 | width: 1.75em; 16 | } 17 | 18 | .navbar { 19 | padding: 0.2rem 1rem; 20 | 21 | a.nav-link { 22 | font-weight: 400; 23 | } 24 | } 25 | 26 | /* ========================================================================== 27 | Logo styles 28 | ========================================================================== */ 29 | .logo-img { 30 | height: 45px; 31 | width: 45px; 32 | display: inline-block; 33 | vertical-align: middle; 34 | background: url('/content/images/logo-jhipster.png') no-repeat center center; 35 | background-size: contain; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/page-ribbon.component.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | Development Ribbon 3 | ========================================================================== */ 4 | .ribbon { 5 | background-color: rgba(170, 0, 0, 0.5); 6 | overflow: hidden; 7 | position: absolute; 8 | top: 40px; 9 | white-space: nowrap; 10 | width: 15em; 11 | z-index: 9999; 12 | pointer-events: none; 13 | opacity: 0.75; 14 | a { 15 | color: #fff; 16 | display: block; 17 | font-weight: 400; 18 | margin: 1px 0; 19 | padding: 10px 50px; 20 | text-align: center; 21 | text-decoration: none; 22 | text-shadow: 0 0 5px #444; 23 | pointer-events: none; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/page-ribbon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector, OnInit, Signal, inject } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | import { map } from 'rxjs/operators'; 4 | import { toSignal } from '@angular/core/rxjs-interop'; 5 | 6 | import SharedModule from 'app/shared/shared.module'; 7 | import { ProfileService } from './profile.service'; 8 | 9 | @Component({ 10 | selector: 'jhi-page-ribbon', 11 | template: ` 12 | @if (ribbonEnvSignal; as ribbonEnv) { 13 | 16 | } 17 | `, 18 | styleUrl: './page-ribbon.component.scss', 19 | imports: [SharedModule], 20 | }) 21 | export default class PageRibbonComponent implements OnInit { 22 | ribbonEnvSignal?: Signal; 23 | private readonly injector = inject(Injector); 24 | private readonly profileService = inject(ProfileService); 25 | 26 | ngOnInit(): void { 27 | const ribbonEnv$: Observable = this.profileService.getProfileInfo().pipe(map(profileInfo => profileInfo.ribbonEnv)); 28 | this.ribbonEnvSignal = toSignal(ribbonEnv$, { injector: this.injector }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/profile-info.model.ts: -------------------------------------------------------------------------------- 1 | export interface InfoResponse { 2 | 'display-ribbon-on-profiles'?: string; 3 | git?: any; 4 | build?: any; 5 | activeProfiles?: string[]; 6 | } 7 | 8 | export class ProfileInfo { 9 | constructor( 10 | public activeProfiles?: string[], 11 | public ribbonEnv?: string, 12 | public inProduction?: boolean, 13 | public openAPIEnabled?: boolean, 14 | ) {} 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/login/login.model.ts: -------------------------------------------------------------------------------- 1 | export class Login { 2 | constructor( 3 | public username: string, 4 | public password: string, 5 | public rememberMe: boolean, 6 | ) {} 7 | } 8 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert-error.component.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert-error.model.ts: -------------------------------------------------------------------------------- 1 | export class AlertError { 2 | constructor( 3 | public message: string, 4 | public key?: string, 5 | public params?: Record, 6 | ) {} 7 | } 8 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert.component.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert.component.spec.ts: -------------------------------------------------------------------------------- 1 | jest.mock('app/core/util/alert.service'); 2 | 3 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; 4 | 5 | import { AlertService } from 'app/core/util/alert.service'; 6 | 7 | import { AlertComponent } from './alert.component'; 8 | 9 | describe('Alert Component', () => { 10 | let comp: AlertComponent; 11 | let fixture: ComponentFixture; 12 | let mockAlertService: AlertService; 13 | 14 | beforeEach(waitForAsync(() => { 15 | TestBed.configureTestingModule({ 16 | imports: [AlertComponent], 17 | providers: [AlertService], 18 | }) 19 | .overrideTemplate(AlertComponent, '') 20 | .compileComponents(); 21 | })); 22 | 23 | beforeEach(() => { 24 | fixture = TestBed.createComponent(AlertComponent); 25 | comp = fixture.componentInstance; 26 | mockAlertService = TestBed.inject(AlertService); 27 | }); 28 | 29 | it('should call alertService.get on init', () => { 30 | // WHEN 31 | comp.ngOnInit(); 32 | 33 | // THEN 34 | expect(mockAlertService.get).toHaveBeenCalled(); 35 | }); 36 | 37 | it('should call alertService.clear on destroy', () => { 38 | // WHEN 39 | comp.ngOnDestroy(); 40 | 41 | // THEN 42 | expect(mockAlertService.clear).toHaveBeenCalled(); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy, OnInit, inject, signal } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import { Alert, AlertService } from 'app/core/util/alert.service'; 6 | 7 | @Component({ 8 | selector: 'jhi-alert', 9 | templateUrl: './alert.component.html', 10 | imports: [CommonModule, NgbModule], 11 | }) 12 | export class AlertComponent implements OnInit, OnDestroy { 13 | alerts = signal([]); 14 | 15 | private readonly alertService = inject(AlertService); 16 | 17 | ngOnInit(): void { 18 | this.alerts.set(this.alertService.get()); 19 | } 20 | 21 | setClasses(alert: Alert): Record { 22 | const classes = { 'jhi-toast': Boolean(alert.toast) }; 23 | if (alert.position) { 24 | return { ...classes, [alert.position]: true }; 25 | } 26 | return classes; 27 | } 28 | 29 | ngOnDestroy(): void { 30 | this.alertService.clear(); 31 | } 32 | 33 | close(alert: Alert): void { 34 | alert.close?.(this.alerts()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/date/duration.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | import dayjs from 'dayjs/esm'; 4 | 5 | @Pipe({ 6 | name: 'duration', 7 | }) 8 | export default class DurationPipe implements PipeTransform { 9 | transform(value: any): string { 10 | if (value) { 11 | return dayjs.duration(value).humanize(); 12 | } 13 | return ''; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/date/format-medium-date.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs/esm'; 2 | 3 | import FormatMediumDatePipe from './format-medium-date.pipe'; 4 | 5 | describe('FormatMediumDatePipe', () => { 6 | const formatMediumDatePipe = new FormatMediumDatePipe(); 7 | 8 | it('should return an empty string when receive undefined', () => { 9 | expect(formatMediumDatePipe.transform(undefined)).toBe(''); 10 | }); 11 | 12 | it('should return an empty string when receive null', () => { 13 | expect(formatMediumDatePipe.transform(null)).toBe(''); 14 | }); 15 | 16 | it('should format date like this D MMM YYYY', () => { 17 | expect(formatMediumDatePipe.transform(dayjs('2020-11-16').locale('fr'))).toBe('16 Nov 2020'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/date/format-medium-date.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | import dayjs from 'dayjs/esm'; 4 | 5 | @Pipe({ 6 | name: 'formatMediumDate', 7 | }) 8 | export default class FormatMediumDatePipe implements PipeTransform { 9 | transform(day: dayjs.Dayjs | null | undefined): string { 10 | return day ? day.format('D MMM YYYY') : ''; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/date/format-medium-datetime.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs/esm'; 2 | 3 | import FormatMediumDatetimePipe from './format-medium-datetime.pipe'; 4 | 5 | describe('FormatMediumDatePipe', () => { 6 | const formatMediumDatetimePipe = new FormatMediumDatetimePipe(); 7 | 8 | it('should return an empty string when receive undefined', () => { 9 | expect(formatMediumDatetimePipe.transform(undefined)).toBe(''); 10 | }); 11 | 12 | it('should return an empty string when receive null', () => { 13 | expect(formatMediumDatetimePipe.transform(null)).toBe(''); 14 | }); 15 | 16 | it('should format date like this D MMM YYYY', () => { 17 | expect(formatMediumDatetimePipe.transform(dayjs('2020-11-16').locale('fr'))).toBe('16 Nov 2020 00:00:00'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/date/format-medium-datetime.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | import dayjs from 'dayjs/esm'; 4 | 5 | @Pipe({ 6 | name: 'formatMediumDatetime', 7 | }) 8 | export default class FormatMediumDatetimePipe implements PipeTransform { 9 | transform(day: dayjs.Dayjs | null | undefined): string { 10 | return day ? day.format('D MMM YYYY HH:mm:ss') : ''; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/date/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DurationPipe } from './duration.pipe'; 2 | export { default as FormatMediumDatePipe } from './format-medium-date.pipe'; 3 | export { default as FormatMediumDatetimePipe } from './format-medium-datetime.pipe'; 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/filter/filter.component.html: -------------------------------------------------------------------------------- 1 | @if (filters().hasAnyFilterSet()) { 2 |
3 | Following filters are set 4 | 7 |
    8 | @for (filterOption of filters().filterOptions; track filterOption.name) { 9 | @for (value of filterOption.values; track value) { 10 |
  • 11 | {{ filterOption.name }}: {{ value }} 12 | 15 |
  • 16 | } 17 | } 18 |
19 |
20 | } 21 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/filter/filter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, input } from '@angular/core'; 2 | import SharedModule from '../shared.module'; 3 | import { IFilterOptions } from './filter.model'; 4 | 5 | @Component({ 6 | selector: 'jhi-filter', 7 | imports: [SharedModule], 8 | templateUrl: './filter.component.html', 9 | }) 10 | export default class FilterComponent { 11 | readonly filters = input.required(); 12 | 13 | clearAllFilters(): void { 14 | this.filters().clear(); 15 | } 16 | 17 | clearFilter(filterName: string, value: string): void { 18 | this.filters().removeFilter(filterName, value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/filter/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FilterComponent } from './filter.component'; 2 | export * from './filter.model'; 3 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/language/find-language-from-key.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'findLanguageFromKey', 5 | }) 6 | export default class FindLanguageFromKeyPipe implements PipeTransform { 7 | private readonly languages: Record = { 8 | en: { name: 'English' }, 9 | // jhipster-needle-i18n-language-key-pipe - JHipster will add/remove languages in this object 10 | }; 11 | 12 | transform(lang: string): string { 13 | return this.languages[lang].name; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/language/index.ts: -------------------------------------------------------------------------------- 1 | export { default as TranslateDirective } from './translate.directive'; 2 | export { default as FindLanguageFromKeyPipe } from './find-language-from-key.pipe'; 3 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/language/translate.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; 3 | import { TranslateModule, TranslateService } from '@ngx-translate/core'; 4 | 5 | import TranslateDirective from './translate.directive'; 6 | 7 | @Component({ 8 | imports: [TranslateDirective], 9 | template: `
`, 10 | }) 11 | class TestTranslateDirectiveComponent {} 12 | 13 | describe('TranslateDirective Tests', () => { 14 | let fixture: ComponentFixture; 15 | let translateService: TranslateService; 16 | 17 | beforeEach(waitForAsync(() => { 18 | TestBed.configureTestingModule({ 19 | imports: [TranslateModule.forRoot(), TestTranslateDirectiveComponent], 20 | }); 21 | })); 22 | 23 | beforeEach(() => { 24 | translateService = TestBed.inject(TranslateService); 25 | fixture = TestBed.createComponent(TestTranslateDirectiveComponent); 26 | }); 27 | 28 | it('should change HTML', () => { 29 | const spy = jest.spyOn(translateService, 'get'); 30 | 31 | fixture.detectChanges(); 32 | 33 | expect(spy).toHaveBeenCalled(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/pagination/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ItemCountComponent } from './item-count.component'; 2 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 4 | import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; 5 | import { TranslateModule } from '@ngx-translate/core'; 6 | 7 | import FindLanguageFromKeyPipe from './language/find-language-from-key.pipe'; 8 | import TranslateDirective from './language/translate.directive'; 9 | import { AlertComponent } from './alert/alert.component'; 10 | import { AlertErrorComponent } from './alert/alert-error.component'; 11 | 12 | /** 13 | * Application wide Module 14 | */ 15 | @NgModule({ 16 | imports: [AlertComponent, AlertErrorComponent, FindLanguageFromKeyPipe, TranslateDirective], 17 | exports: [ 18 | CommonModule, 19 | NgbModule, 20 | FontAwesomeModule, 21 | AlertComponent, 22 | AlertErrorComponent, 23 | TranslateModule, 24 | FindLanguageFromKeyPipe, 25 | TranslateDirective, 26 | ], 27 | }) 28 | export default class SharedModule {} 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/sort/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sort-by.directive'; 2 | export * from './sort-state'; 3 | export * from './sort.directive'; 4 | export * from './sort.service'; 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/sort/sort-state.ts: -------------------------------------------------------------------------------- 1 | import { WritableSignal, signal } from '@angular/core'; 2 | 3 | export type SortOrder = 'asc' | 'desc'; 4 | 5 | export type SortState = { predicate?: string; order?: SortOrder }; 6 | 7 | export const sortStateSignal = (state: SortState): WritableSignal => 8 | signal(state, { 9 | equal: (a, b) => a.predicate === b.predicate && a.order === b.order, 10 | }); 11 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/sort/sort.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, model, output } from '@angular/core'; 2 | import { SortOrder, SortState } from './sort-state'; 3 | 4 | @Directive({ 5 | selector: '[jhiSort]', 6 | }) 7 | export class SortDirective { 8 | readonly sortState = model.required(); 9 | 10 | readonly sortChange = output(); 11 | 12 | sort(field: string): void { 13 | const { predicate, order } = this.sortState(); 14 | const toggle = (): SortOrder => (order === 'asc' ? 'desc' : 'asc'); 15 | const newSortState = { predicate: field, order: field !== predicate ? 'asc' : toggle() }; 16 | this.sortState.update(() => newSortState); 17 | this.sortChange.emit(newSortState); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/bootstrap.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { bootstrapApplication } from '@angular/platform-browser'; 3 | import { appConfig } from './app/app.config'; 4 | import AppComponent from './app/app.component'; 5 | 6 | import { environment } from './environments/environment'; 7 | 8 | // disable debug data on prod profile to improve performance 9 | if (!environment.DEBUG_INFO_ENABLED) { 10 | enableProdMode(); 11 | } 12 | 13 | bootstrapApplication(AppComponent, appConfig) 14 | // eslint-disable-next-line no-console 15 | .then(() => console.log('Application started')) 16 | .catch((err: unknown) => console.error(err)); 17 | -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_0_head-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_0_head-192.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_0_head-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_0_head-256.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_0_head-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_0_head-384.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_0_head-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_0_head-512.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_1_head-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_1_head-192.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_1_head-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_1_head-256.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_1_head-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_1_head-384.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_1_head-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_1_head-512.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_2_head-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_2_head-192.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_2_head-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_2_head-256.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_2_head-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_2_head-384.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_2_head-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_2_head-512.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_3_head-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_3_head-192.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_3_head-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_3_head-256.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_3_head-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_3_head-384.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/jhipster_family_member_3_head-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/jhipster_family_member_3_head-512.png -------------------------------------------------------------------------------- /src/main/webapp/content/images/logo-jhipster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/content/images/logo-jhipster.png -------------------------------------------------------------------------------- /src/main/webapp/content/scss/_bootstrap-variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Bootstrap overrides https://getbootstrap.com/docs/5.1/customize/sass/ 3 | * All values defined in bootstrap source 4 | * https://github.com/twbs/bootstrap/blob/v5.1.3/scss/_variables.scss can be overwritten here 5 | * Make sure not to add !default to values here 6 | */ 7 | 8 | // Options: 9 | // Quickly modify global styling by enabling or disabling optional features. 10 | $enable-rounded: true; 11 | $enable-shadows: false; 12 | $enable-gradients: false; 13 | $enable-transitions: true; 14 | $enable-hover-media-query: false; 15 | $enable-grid-classes: true; 16 | $enable-print-styles: true; 17 | 18 | // Components: 19 | // Define common padding and border radius sizes and more. 20 | 21 | $border-radius: 0.15rem; 22 | $border-radius-lg: 0.125rem; 23 | $border-radius-sm: 0.1rem; 24 | 25 | // Body: 26 | // Settings for the `` element. 27 | 28 | $body-bg: #ffffff; 29 | 30 | // Typography: 31 | // Font, line-height, and color for body text, headings, and more. 32 | 33 | $font-size-base: 1rem; 34 | 35 | $dropdown-link-hover-color: white; 36 | $dropdown-link-hover-bg: #343a40; 37 | -------------------------------------------------------------------------------- /src/main/webapp/content/scss/vendor.scss: -------------------------------------------------------------------------------- 1 | /* after changing this file run 'npm run webapp:build' */ 2 | 3 | /*************************** 4 | put Sass variables here: 5 | eg $input-color: red; 6 | ****************************/ 7 | // Override Bootstrap variables 8 | @import 'bootstrap-variables'; 9 | // Import Bootstrap source files from node_modules 10 | @import 'bootstrap/scss/bootstrap'; 11 | 12 | /* jhipster-needle-scss-add-vendor JHipster will add new css style */ 13 | -------------------------------------------------------------------------------- /src/main/webapp/declarations.d.ts: -------------------------------------------------------------------------------- 1 | // These constants are injected via webpack DefinePlugin variables. 2 | // You can add more variables in webpack.common.js or in profile specific webpack..js files. 3 | // If you change the values in the webpack config files, you need to re run webpack to update the application 4 | 5 | declare const __VERSION__: string; 6 | declare const SERVER_API_URL: string; 7 | declare const I18N_HASH: string; 8 | -------------------------------------------------------------------------------- /src/main/webapp/environments/environment.development.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | VERSION: 'DEV', 3 | DEBUG_INFO_ENABLED: true, 4 | }; 5 | -------------------------------------------------------------------------------- /src/main/webapp/environments/environment.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | VERSION: __VERSION__, 3 | DEBUG_INFO_ENABLED: false, 4 | }; 5 | -------------------------------------------------------------------------------- /src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/activate.json: -------------------------------------------------------------------------------- 1 | { 2 | "activate": { 3 | "title": "Activation", 4 | "messages": { 5 | "success": "Your user account has been activated. Please ", 6 | "error": "Your user could not be activated. Please use the registration form to sign up." 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/adminAuthority.json: -------------------------------------------------------------------------------- 1 | { 2 | "jhipsterDtoSampleApplicationApp": { 3 | "adminAuthority": { 4 | "home": { 5 | "title": "Authorities", 6 | "refreshListLabel": "Refresh list", 7 | "createLabel": "Create a new Authority", 8 | "createOrEditLabel": "Create or edit a Authority", 9 | "notFound": "No Authorities found" 10 | }, 11 | "created": "A new Authority is created with identifier {{ param }}", 12 | "updated": "A Authority is updated with identifier {{ param }}", 13 | "deleted": "A Authority is deleted with identifier {{ param }}", 14 | "delete": { 15 | "question": "Are you sure you want to delete Authority {{ id }}?" 16 | }, 17 | "detail": { 18 | "title": "Authority" 19 | }, 20 | "name": "Name" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/bankAccount.json: -------------------------------------------------------------------------------- 1 | { 2 | "jhipsterDtoSampleApplicationApp": { 3 | "bankAccount": { 4 | "home": { 5 | "title": "Bank Accounts", 6 | "refreshListLabel": "Refresh list", 7 | "createLabel": "Create a new Bank Account", 8 | "createOrEditLabel": "Create or edit a Bank Account", 9 | "notFound": "No Bank Accounts found" 10 | }, 11 | "created": "A new Bank Account is created with identifier {{ param }}", 12 | "updated": "A Bank Account is updated with identifier {{ param }}", 13 | "deleted": "A Bank Account is deleted with identifier {{ param }}", 14 | "delete": { 15 | "question": "Are you sure you want to delete Bank Account {{ id }}?" 16 | }, 17 | "detail": { 18 | "title": "Bank Account" 19 | }, 20 | "id": "ID", 21 | "name": "Name", 22 | "balance": "Balance", 23 | "user": "User", 24 | "operation": "Operation" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": { 3 | "title": "Configuration", 4 | "filter": "Filter (by prefix)", 5 | "table": { 6 | "prefix": "Prefix", 7 | "properties": "Properties" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": { 3 | "title": "Error page!", 4 | "http": { 5 | "400": "Bad request.", 6 | "403": "You are not authorized to access this page.", 7 | "404": "The page does not exist.", 8 | "405": "The HTTP verb you used is not supported for this URL.", 9 | "500": "Internal server error." 10 | }, 11 | "concurrencyFailure": "Another user modified this data at the same time as you. Your changes were rejected.", 12 | "validation": "Validation error on the server." 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/health.json: -------------------------------------------------------------------------------- 1 | { 2 | "health": { 3 | "title": "Health Checks", 4 | "refresh.button": "Refresh", 5 | "stacktrace": "Stacktrace", 6 | "details": { 7 | "details": "Details", 8 | "properties": "Properties", 9 | "name": "Name", 10 | "value": "Value", 11 | "error": "Error" 12 | }, 13 | "indicator": { 14 | "diskSpace": "Disk space", 15 | "mail": "Email", 16 | "livenessState": "Liveness state", 17 | "readinessState": "Readiness state", 18 | "ping": "Application", 19 | "db": "Database" 20 | }, 21 | "table": { 22 | "service": "Service name", 23 | "status": "Status" 24 | }, 25 | "status": { 26 | "UNKNOWN": "UNKNOWN", 27 | "UP": "UP", 28 | "OUT_OF_SERVICE": "OUT_OF_SERVICE", 29 | "DOWN": "DOWN" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/home.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": { 3 | "title": "Welcome, Java Hipster!", 4 | "subtitle": "This is your homepage", 5 | "logged": { 6 | "message": "You are logged in as user \"{{username}}\"." 7 | }, 8 | "question": "If you have any question on JHipster:", 9 | "link": { 10 | "homepage": "JHipster homepage", 11 | "stackoverflow": "JHipster on Stack Overflow", 12 | "bugtracker": "JHipster bug tracker", 13 | "chat": "JHipster public chat room", 14 | "follow": "follow @jhipster on Twitter" 15 | }, 16 | "like": "If you like JHipster, don't forget to give us a star on", 17 | "github": "GitHub" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/label.json: -------------------------------------------------------------------------------- 1 | { 2 | "jhipsterDtoSampleApplicationApp": { 3 | "label": { 4 | "home": { 5 | "title": "Labels", 6 | "refreshListLabel": "Refresh list", 7 | "createLabel": "Create a new Label", 8 | "createOrEditLabel": "Create or edit a Label", 9 | "notFound": "No Labels found" 10 | }, 11 | "created": "A new Label is created with identifier {{ param }}", 12 | "updated": "A Label is updated with identifier {{ param }}", 13 | "deleted": "A Label is deleted with identifier {{ param }}", 14 | "delete": { 15 | "question": "Are you sure you want to delete Label {{ id }}?" 16 | }, 17 | "detail": { 18 | "title": "Label" 19 | }, 20 | "id": "ID", 21 | "label": "Label", 22 | "operation": "Operation" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "login": { 3 | "title": "Sign in", 4 | "form": { 5 | "password": "Password", 6 | "password.placeholder": "Your password", 7 | "rememberme": "Remember me", 8 | "button": "Sign in" 9 | }, 10 | "messages": { 11 | "error": { 12 | "authentication": "Failed to sign in! Please check your credentials and try again." 13 | } 14 | }, 15 | "password": { 16 | "forgot": "Did you forget your password?" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "logs": { 3 | "title": "Logs", 4 | "nbloggers": "There are {{ total }} loggers.", 5 | "filter": "Filter", 6 | "table": { 7 | "name": "Name", 8 | "level": "Level" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/operation.json: -------------------------------------------------------------------------------- 1 | { 2 | "jhipsterDtoSampleApplicationApp": { 3 | "operation": { 4 | "home": { 5 | "title": "Operations", 6 | "refreshListLabel": "Refresh list", 7 | "createLabel": "Create a new Operation", 8 | "createOrEditLabel": "Create or edit a Operation", 9 | "notFound": "No Operations found" 10 | }, 11 | "created": "A new Operation is created with identifier {{ param }}", 12 | "updated": "A Operation is updated with identifier {{ param }}", 13 | "deleted": "A Operation is deleted with identifier {{ param }}", 14 | "delete": { 15 | "question": "Are you sure you want to delete Operation {{ id }}?" 16 | }, 17 | "detail": { 18 | "title": "Operation" 19 | }, 20 | "id": "ID", 21 | "date": "Date", 22 | "description": "Description", 23 | "amount": "Amount", 24 | "bankAccount": "Bank Account", 25 | "label": "Label" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/password.json: -------------------------------------------------------------------------------- 1 | { 2 | "password": { 3 | "title": "Password for [{{username}}]", 4 | "form": { 5 | "button": "Save" 6 | }, 7 | "messages": { 8 | "error": "An error has occurred! The password could not be changed.", 9 | "success": "Password changed!" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "register": { 3 | "title": "Registration", 4 | "form": { 5 | "button": "Register" 6 | }, 7 | "messages": { 8 | "validate": { 9 | "login": { 10 | "required": "Your username is required.", 11 | "minlength": "Your username is required to be at least 1 character.", 12 | "maxlength": "Your username cannot be longer than 50 characters.", 13 | "pattern": "Your username is invalid." 14 | } 15 | }, 16 | "success": "Registration saved! Please check your email for confirmation.", 17 | "error": { 18 | "fail": "Registration failed! Please try again later.", 19 | "userexists": "Login name already registered! Please choose another one.", 20 | "emailexists": "Email is already in use! Please choose another one." 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "reset": { 3 | "request": { 4 | "title": "Reset your password", 5 | "form": { 6 | "button": "Reset password" 7 | }, 8 | "messages": { 9 | "info": "Enter the email address you used to register", 10 | "success": "Check your email for details on how to reset your password." 11 | } 12 | }, 13 | "finish": { 14 | "title": "Reset password", 15 | "form": { 16 | "button": "Validate new password" 17 | }, 18 | "messages": { 19 | "info": "Choose a new password", 20 | "success": "Your password has been reset. Please ", 21 | "keymissing": "The reset key is missing.", 22 | "error": "Your password couldn't be reset. Remember a password request is only valid for 24 hours." 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/sessions.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessions": { 3 | "title": "Active sessions for [{{username}}]", 4 | "table": { 5 | "ipaddress": "IP address", 6 | "useragent": "User Agent", 7 | "date": "Date", 8 | "button": "Invalidate" 9 | }, 10 | "messages": { 11 | "success": "Session invalidated!", 12 | "error": "An error has occurred! The session could not be invalidated." 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "title": "User settings for [{{username}}]", 4 | "form": { 5 | "firstname": "First Name", 6 | "firstname.placeholder": "Your first name", 7 | "lastname": "Last Name", 8 | "lastname.placeholder": "Your last name", 9 | "language": "Language", 10 | "button": "Save" 11 | }, 12 | "messages": { 13 | "error": { 14 | "fail": "An error has occurred! Settings could not be saved.", 15 | "emailexists": "Email is already in use! Please choose another one." 16 | }, 17 | "success": "Settings saved!", 18 | "validate": { 19 | "firstname": { 20 | "required": "Your first name is required.", 21 | "minlength": "Your first name is required to be at least 1 character", 22 | "maxlength": "Your first name cannot be longer than 50 characters" 23 | }, 24 | "lastname": { 25 | "required": "Your last name is required.", 26 | "minlength": "Your last name is required to be at least 1 character", 27 | "maxlength": "Your last name cannot be longer than 50 characters" 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/user-management.json: -------------------------------------------------------------------------------- 1 | { 2 | "userManagement": { 3 | "home": { 4 | "title": "Users", 5 | "refreshListLabel": "Refresh list", 6 | "createLabel": "Create a new user", 7 | "createOrEditLabel": "Create or edit a user" 8 | }, 9 | "created": "A new user is created with identifier {{ param }}", 10 | "updated": "A user is updated with identifier {{ param }}", 11 | "deleted": "A user is deleted with identifier {{ param }}", 12 | "delete": { 13 | "question": "Are you sure you want to delete user {{ login }}?" 14 | }, 15 | "detail": { 16 | "title": "User" 17 | }, 18 | "login": "Login", 19 | "firstName": "First name", 20 | "lastName": "Last name", 21 | "email": "Email", 22 | "activated": "Activated", 23 | "deactivated": "Deactivated", 24 | "profiles": "Profiles", 25 | "langKey": "Language", 26 | "createdBy": "Created by", 27 | "createdDate": "Created date", 28 | "lastModifiedBy": "Modified by", 29 | "lastModifiedDate": "Modified date" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/webapp/main.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap').catch((err: unknown) => console.error(err)); 2 | -------------------------------------------------------------------------------- /src/main/webapp/manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JhipsterDtoSampleApplication", 3 | "short_name": "JhipsterDtoSampleApplication", 4 | "icons": [ 5 | { 6 | "src": "./content/images/jhipster_family_member_2_head-192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./content/images/jhipster_family_member_2_head-256.png", 12 | "sizes": "256x256", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "./content/images/jhipster_family_member_2_head-384.png", 17 | "sizes": "384x384", 18 | "type": "image/png" 19 | }, 20 | { 21 | "src": "./content/images/jhipster_family_member_2_head-512.png", 22 | "sizes": "512x512", 23 | "type": "image/png" 24 | } 25 | ], 26 | "theme_color": "#000000", 27 | "background_color": "#e0e0e0", 28 | "start_url": ".", 29 | "display": "standalone", 30 | "orientation": "portrait" 31 | } 32 | -------------------------------------------------------------------------------- /src/main/webapp/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org/ 2 | 3 | User-agent: * 4 | Disallow: /api/account 5 | Disallow: /api/account/change-password 6 | Disallow: /api/account/sessions 7 | Disallow: /api/logs/ 8 | Disallow: /api/users/ 9 | Disallow: /management/ 10 | Disallow: /v3/api-docs/ 11 | -------------------------------------------------------------------------------- /src/test/gatling/conf/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/IntegrationTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample; 2 | 3 | import io.github.jhipster.sample.config.AsyncSyncConfiguration; 4 | import io.github.jhipster.sample.config.EmbeddedSQL; 5 | import io.github.jhipster.sample.config.JacksonConfiguration; 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | 12 | /** 13 | * Base composite annotation for integration tests. 14 | */ 15 | @Target(ElementType.TYPE) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @SpringBootTest(classes = { JhipsterDtoSampleApplicationApp.class, JacksonConfiguration.class, AsyncSyncConfiguration.class }) 18 | @EmbeddedSQL 19 | public @interface IntegrationTest { 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/config/AsyncSyncConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import java.util.concurrent.Executor; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.task.SyncTaskExecutor; 7 | 8 | @Configuration 9 | public class AsyncSyncConfiguration { 10 | 11 | @Bean(name = "taskExecutor") 12 | public Executor taskExecutor() { 13 | return new SyncTaskExecutor(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/config/EmbeddedSQL.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 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.TYPE) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface EmbeddedSQL { 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/config/SpringBootTestClassOrderer.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import io.github.jhipster.sample.IntegrationTest; 4 | import java.util.Comparator; 5 | import org.junit.jupiter.api.ClassDescriptor; 6 | import org.junit.jupiter.api.ClassOrderer; 7 | import org.junit.jupiter.api.ClassOrdererContext; 8 | 9 | public class SpringBootTestClassOrderer implements ClassOrderer { 10 | 11 | @Override 12 | public void orderClasses(ClassOrdererContext context) { 13 | context.getClassDescriptors().sort(Comparator.comparingInt(SpringBootTestClassOrderer::getOrder)); 14 | } 15 | 16 | private static int getOrder(ClassDescriptor classDescriptor) { 17 | if (classDescriptor.findAnnotation(IntegrationTest.class).isPresent()) { 18 | return 2; 19 | } 20 | return 1; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/config/SqlTestContainer.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import org.springframework.beans.factory.DisposableBean; 4 | import org.springframework.beans.factory.InitializingBean; 5 | import org.testcontainers.containers.JdbcDatabaseContainer; 6 | 7 | public interface SqlTestContainer extends InitializingBean, DisposableBean { 8 | JdbcDatabaseContainer getTestContainer(); 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/config/WebConfigurerTestController.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.config; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class WebConfigurerTestController { 8 | 9 | @GetMapping("/api/test-cors") 10 | public void testCorsOnApiPath() { 11 | // empty method 12 | } 13 | 14 | @GetMapping("/test/test-cors") 15 | public void testCorsOnOtherPath() { 16 | // empty method 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/domain/AssertUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.domain; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.ZoneOffset; 5 | import java.time.ZonedDateTime; 6 | import java.util.Comparator; 7 | 8 | public class AssertUtils { 9 | 10 | public static Comparator zonedDataTimeSameInstant = Comparator.nullsFirst((e1, a2) -> 11 | e1.withZoneSameInstant(ZoneOffset.UTC).compareTo(a2.withZoneSameInstant(ZoneOffset.UTC)) 12 | ); 13 | 14 | public static Comparator bigDecimalCompareTo = Comparator.nullsFirst(BigDecimal::compareTo); 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/domain/AuthorityTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.domain; 2 | 3 | import static io.github.jhipster.sample.domain.AuthorityTestSamples.*; 4 | import static org.assertj.core.api.Assertions.assertThat; 5 | 6 | import io.github.jhipster.sample.web.rest.TestUtil; 7 | import org.junit.jupiter.api.Test; 8 | 9 | class AuthorityTest { 10 | 11 | @Test 12 | void equalsVerifier() throws Exception { 13 | TestUtil.equalsVerifier(Authority.class); 14 | Authority authority1 = getAuthoritySample1(); 15 | Authority authority2 = new Authority(); 16 | assertThat(authority1).isNotEqualTo(authority2); 17 | 18 | authority2.setName(authority1.getName()); 19 | assertThat(authority1).isEqualTo(authority2); 20 | 21 | authority2 = getAuthoritySample2(); 22 | assertThat(authority1).isNotEqualTo(authority2); 23 | } 24 | 25 | @Test 26 | void hashCodeVerifier() { 27 | Authority authority = new Authority(); 28 | assertThat(authority.hashCode()).isZero(); 29 | 30 | Authority authority1 = getAuthoritySample1(); 31 | authority.setName(authority1.getName()); 32 | assertThat(authority).hasSameHashCodeAs(authority1); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/domain/AuthorityTestSamples.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.domain; 2 | 3 | import java.util.UUID; 4 | 5 | public class AuthorityTestSamples { 6 | 7 | public static Authority getAuthoritySample1() { 8 | return new Authority().name("name1"); 9 | } 10 | 11 | public static Authority getAuthoritySample2() { 12 | return new Authority().name("name2"); 13 | } 14 | 15 | public static Authority getAuthorityRandomSampleGenerator() { 16 | return new Authority().name(UUID.randomUUID().toString()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/domain/BankAccountTestSamples.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.domain; 2 | 3 | import java.util.Random; 4 | import java.util.UUID; 5 | import java.util.concurrent.atomic.AtomicLong; 6 | 7 | public class BankAccountTestSamples { 8 | 9 | private static final Random random = new Random(); 10 | private static final AtomicLong longCount = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); 11 | 12 | public static BankAccount getBankAccountSample1() { 13 | return new BankAccount().id(1L).name("name1"); 14 | } 15 | 16 | public static BankAccount getBankAccountSample2() { 17 | return new BankAccount().id(2L).name("name2"); 18 | } 19 | 20 | public static BankAccount getBankAccountRandomSampleGenerator() { 21 | return new BankAccount().id(longCount.incrementAndGet()).name(UUID.randomUUID().toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/domain/LabelTestSamples.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.domain; 2 | 3 | import java.util.Random; 4 | import java.util.UUID; 5 | import java.util.concurrent.atomic.AtomicLong; 6 | 7 | public class LabelTestSamples { 8 | 9 | private static final Random random = new Random(); 10 | private static final AtomicLong longCount = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); 11 | 12 | public static Label getLabelSample1() { 13 | return new Label().id(1L).label("label1"); 14 | } 15 | 16 | public static Label getLabelSample2() { 17 | return new Label().id(2L).label("label2"); 18 | } 19 | 20 | public static Label getLabelRandomSampleGenerator() { 21 | return new Label().id(longCount.incrementAndGet()).label(UUID.randomUUID().toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/domain/OperationTestSamples.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.domain; 2 | 3 | import java.util.Random; 4 | import java.util.UUID; 5 | import java.util.concurrent.atomic.AtomicLong; 6 | 7 | public class OperationTestSamples { 8 | 9 | private static final Random random = new Random(); 10 | private static final AtomicLong longCount = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); 11 | 12 | public static Operation getOperationSample1() { 13 | return new Operation().id(1L).description("description1"); 14 | } 15 | 16 | public static Operation getOperationSample2() { 17 | return new Operation().id(2L).description("description2"); 18 | } 19 | 20 | public static Operation getOperationRandomSampleGenerator() { 21 | return new Operation().id(longCount.incrementAndGet()).description(UUID.randomUUID().toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/repository/timezone/DateTimeWrapperRepository.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.repository.timezone; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | /** 7 | * Spring Data JPA repository for the {@link DateTimeWrapper} entity. 8 | */ 9 | @Repository 10 | public interface DateTimeWrapperRepository extends JpaRepository {} 11 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/service/dto/BankAccountDTOTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.dto; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import io.github.jhipster.sample.web.rest.TestUtil; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class BankAccountDTOTest { 9 | 10 | @Test 11 | void dtoEqualsVerifier() throws Exception { 12 | TestUtil.equalsVerifier(BankAccountDTO.class); 13 | BankAccountDTO bankAccountDTO1 = new BankAccountDTO(); 14 | bankAccountDTO1.setId(1L); 15 | BankAccountDTO bankAccountDTO2 = new BankAccountDTO(); 16 | assertThat(bankAccountDTO1).isNotEqualTo(bankAccountDTO2); 17 | bankAccountDTO2.setId(bankAccountDTO1.getId()); 18 | assertThat(bankAccountDTO1).isEqualTo(bankAccountDTO2); 19 | bankAccountDTO2.setId(2L); 20 | assertThat(bankAccountDTO1).isNotEqualTo(bankAccountDTO2); 21 | bankAccountDTO1.setId(null); 22 | assertThat(bankAccountDTO1).isNotEqualTo(bankAccountDTO2); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/service/dto/LabelDTOTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.dto; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import io.github.jhipster.sample.web.rest.TestUtil; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class LabelDTOTest { 9 | 10 | @Test 11 | void dtoEqualsVerifier() throws Exception { 12 | TestUtil.equalsVerifier(LabelDTO.class); 13 | LabelDTO labelDTO1 = new LabelDTO(); 14 | labelDTO1.setId(1L); 15 | LabelDTO labelDTO2 = new LabelDTO(); 16 | assertThat(labelDTO1).isNotEqualTo(labelDTO2); 17 | labelDTO2.setId(labelDTO1.getId()); 18 | assertThat(labelDTO1).isEqualTo(labelDTO2); 19 | labelDTO2.setId(2L); 20 | assertThat(labelDTO1).isNotEqualTo(labelDTO2); 21 | labelDTO1.setId(null); 22 | assertThat(labelDTO1).isNotEqualTo(labelDTO2); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/service/dto/OperationDTOTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.dto; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import io.github.jhipster.sample.web.rest.TestUtil; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class OperationDTOTest { 9 | 10 | @Test 11 | void dtoEqualsVerifier() throws Exception { 12 | TestUtil.equalsVerifier(OperationDTO.class); 13 | OperationDTO operationDTO1 = new OperationDTO(); 14 | operationDTO1.setId(1L); 15 | OperationDTO operationDTO2 = new OperationDTO(); 16 | assertThat(operationDTO1).isNotEqualTo(operationDTO2); 17 | operationDTO2.setId(operationDTO1.getId()); 18 | assertThat(operationDTO1).isEqualTo(operationDTO2); 19 | operationDTO2.setId(2L); 20 | assertThat(operationDTO1).isNotEqualTo(operationDTO2); 21 | operationDTO1.setId(null); 22 | assertThat(operationDTO1).isNotEqualTo(operationDTO2); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/service/mapper/BankAccountMapperTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.mapper; 2 | 3 | import static io.github.jhipster.sample.domain.BankAccountAsserts.*; 4 | import static io.github.jhipster.sample.domain.BankAccountTestSamples.*; 5 | 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | 9 | class BankAccountMapperTest { 10 | 11 | private BankAccountMapper bankAccountMapper; 12 | 13 | @BeforeEach 14 | void setUp() { 15 | bankAccountMapper = new BankAccountMapperImpl(); 16 | } 17 | 18 | @Test 19 | void shouldConvertToDtoAndBack() { 20 | var expected = getBankAccountSample1(); 21 | var actual = bankAccountMapper.toEntity(bankAccountMapper.toDto(expected)); 22 | assertBankAccountAllPropertiesEquals(expected, actual); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/service/mapper/LabelMapperTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.mapper; 2 | 3 | import static io.github.jhipster.sample.domain.LabelAsserts.*; 4 | import static io.github.jhipster.sample.domain.LabelTestSamples.*; 5 | 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | 9 | class LabelMapperTest { 10 | 11 | private LabelMapper labelMapper; 12 | 13 | @BeforeEach 14 | void setUp() { 15 | labelMapper = new LabelMapperImpl(); 16 | } 17 | 18 | @Test 19 | void shouldConvertToDtoAndBack() { 20 | var expected = getLabelSample1(); 21 | var actual = labelMapper.toEntity(labelMapper.toDto(expected)); 22 | assertLabelAllPropertiesEquals(expected, actual); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/service/mapper/OperationMapperTest.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.service.mapper; 2 | 3 | import static io.github.jhipster.sample.domain.OperationAsserts.*; 4 | import static io.github.jhipster.sample.domain.OperationTestSamples.*; 5 | 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | 9 | class OperationMapperTest { 10 | 11 | private OperationMapper operationMapper; 12 | 13 | @BeforeEach 14 | void setUp() { 15 | operationMapper = new OperationMapperImpl(); 16 | } 17 | 18 | @Test 19 | void shouldConvertToDtoAndBack() { 20 | var expected = getOperationSample1(); 21 | var actual = operationMapper.toEntity(operationMapper.toDto(expected)); 22 | assertOperationAllPropertiesEquals(expected, actual); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/github/jhipster/sample/web/rest/WithUnauthenticatedMockUser.java: -------------------------------------------------------------------------------- 1 | package io.github.jhipster.sample.web.rest; 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 | import org.springframework.security.core.context.SecurityContext; 8 | import org.springframework.security.core.context.SecurityContextHolder; 9 | import org.springframework.security.test.context.support.WithSecurityContext; 10 | import org.springframework.security.test.context.support.WithSecurityContextFactory; 11 | 12 | @Target({ ElementType.METHOD, ElementType.TYPE }) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @WithSecurityContext(factory = WithUnauthenticatedMockUser.Factory.class) 15 | public @interface WithUnauthenticatedMockUser { 16 | class Factory implements WithSecurityContextFactory { 17 | 18 | @Override 19 | public SecurityContext createSecurityContext(WithUnauthenticatedMockUser annotation) { 20 | return SecurityContextHolder.createEmptyContext(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/e2e/account/logout.cy.ts: -------------------------------------------------------------------------------- 1 | import { accountMenuSelector, loginItemSelector, navbarSelector } from '../../support/commands'; 2 | 3 | describe('logout', () => { 4 | const username = Cypress.env('E2E_USERNAME') ?? 'user'; 5 | const password = Cypress.env('E2E_PASSWORD') ?? 'user'; 6 | 7 | beforeEach(() => { 8 | cy.intercept('POST', '/api/logout').as('logout'); 9 | }); 10 | 11 | it('go to home page when successfully logs out', () => { 12 | cy.login(username, password); 13 | cy.visit(''); 14 | 15 | cy.clickOnLogoutItem(); 16 | 17 | cy.wait('@logout'); 18 | cy.get(navbarSelector).get(accountMenuSelector).click(); 19 | cy.get(navbarSelector).get(accountMenuSelector).get(loginItemSelector).should('be.visible'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/e2e/account/reset-password-page.cy.ts: -------------------------------------------------------------------------------- 1 | import { 2 | classInvalid, 3 | classValid, 4 | emailResetPasswordSelector, 5 | forgetYourPasswordSelector, 6 | submitInitResetPasswordSelector, 7 | usernameLoginSelector, 8 | } from '../../support/commands'; 9 | 10 | describe('forgot your password', () => { 11 | const username = Cypress.env('E2E_USERNAME') ?? 'user'; 12 | 13 | beforeEach(() => { 14 | cy.visit(''); 15 | cy.clickOnLoginItem(); 16 | cy.get(usernameLoginSelector).type(username); 17 | cy.get(forgetYourPasswordSelector).click(); 18 | }); 19 | 20 | beforeEach(() => { 21 | cy.intercept('POST', '/api/account/reset-password/init').as('initResetPassword'); 22 | }); 23 | 24 | it('requires email', () => { 25 | cy.get(emailResetPasswordSelector).should('have.class', classInvalid); 26 | cy.get(emailResetPasswordSelector).type('user@gmail.com'); 27 | cy.get(emailResetPasswordSelector).should('have.class', classValid); 28 | }); 29 | 30 | it('should be able to init reset password', () => { 31 | cy.get(emailResetPasswordSelector).type('user@gmail.com'); 32 | cy.get(submitInitResetPasswordSelector).click({ force: true }); 33 | cy.wait('@initResetPassword').then(({ response }) => expect(response?.statusCode).to.equal(200)); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/e2e/lighthouse.audits.ts: -------------------------------------------------------------------------------- 1 | describe('Lighthouse Audits', () => { 2 | beforeEach(() => { 3 | cy.visit('/'); 4 | }); 5 | 6 | it('homepage', () => { 7 | const customThresholds = { 8 | performance: 80, 9 | accessibility: 90, 10 | seo: 90, 11 | 'best-practices': 90, 12 | // If you have enabled PWA you should set this threshold to 100 13 | pwa: 0, 14 | }; 15 | 16 | const desktopConfig = { 17 | extends: 'lighthouse:default', 18 | formFactor: 'desktop', 19 | // Change the CPU slowdown multiplier to emulate different kind of devices 20 | // See https://github.com/GoogleChrome/lighthouse/blob/master/docs/throttling.md#cpu-throttling for details 21 | throttling: { 22 | cpuSlowdownMultiplier: 1, 23 | }, 24 | screenEmulation: { disabled: true }, 25 | }; 26 | cy.lighthouse(customThresholds, desktopConfig); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/fixtures/integration-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/src/test/javascript/cypress/fixtures/integration-test.png -------------------------------------------------------------------------------- /src/test/javascript/cypress/support/account.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-namespace */ 2 | export type Account = Record; 3 | 4 | Cypress.Commands.add('getAccount', () => { 5 | return cy 6 | .authenticatedRequest({ 7 | method: 'GET', 8 | url: '/api/account', 9 | }) 10 | .then(response => response.body as Account); 11 | }); 12 | 13 | Cypress.Commands.add('saveAccount', (account: Account) => { 14 | return cy.authenticatedRequest({ 15 | method: 'POST', 16 | url: '/api/account', 17 | body: account, 18 | }); 19 | }); 20 | 21 | declare global { 22 | namespace Cypress { 23 | interface Chainable { 24 | getAccount(): Cypress.Chainable; 25 | saveAccount(account: Account): Cypress.Chainable>; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/support/index.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | import './account'; 17 | import './commands'; 18 | import './navbar'; 19 | import './entity'; 20 | import './management'; 21 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/support/management.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-namespace */ 2 | /* eslint-disable @typescript-eslint/no-unsafe-return */ 3 | 4 | Cypress.Commands.add('getManagementInfo', () => { 5 | return cy 6 | .request({ 7 | method: 'GET', 8 | url: '/management/info', 9 | }) 10 | .then(response => response.body); 11 | }); 12 | 13 | declare global { 14 | namespace Cypress { 15 | interface Chainable { 16 | getManagementInfo(): Cypress.Chainable; 17 | } 18 | } 19 | } 20 | 21 | // Convert this to a module instead of a script (allows import/export) 22 | export {}; 23 | -------------------------------------------------------------------------------- /src/test/javascript/cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "sourceMap": false, 6 | "outDir": "../../../../target/cypress/tsc", 7 | "target": "es2018", 8 | "types": ["cypress", "node"] 9 | }, 10 | "include": ["./../../../../cypress*.config.ts", "./**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.test.context.ContextCustomizerFactory = \ 2 | io.github.jhipster.sample.config.\ 3 | SqlTestContainersSpringContextCustomizerFactory -------------------------------------------------------------------------------- /src/test/resources/i18n/messages_en.properties: -------------------------------------------------------------------------------- 1 | email.test.title=test title 2 | # Value used for English locale unit test in MailServiceIT 3 | # as this file is loaded instead of real file 4 | email.activation.title=jhipsterDtoSampleApplication account activation 5 | -------------------------------------------------------------------------------- /src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.execution.timeout.default = 15 s 2 | junit.jupiter.execution.timeout.testable.method.default = 15 s 3 | junit.jupiter.execution.timeout.beforeall.method.default = 60 s 4 | junit.jupiter.testclass.order.default=io.github.jhipster.sample.config.SpringBootTestClassOrderer 5 | -------------------------------------------------------------------------------- /src/test/resources/templates/mail/activationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster activation 5 | 6 | 7 | 8 |

Dear

9 |

Your JHipster account has been created, please click on the URL below to activate it:

10 |

11 | Activation link 12 |

13 |

14 | Regards, 15 |
16 | JHipster. 17 |

18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/templates/mail/creationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster creation 5 | 6 | 7 | 8 |

Dear

9 |

Your JHipster account has been created, please click on the URL below to access it:

10 |

11 | Login link 12 |

13 |

14 | Regards, 15 |
16 | JHipster. 17 |

18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/templates/mail/passwordResetEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster password reset 5 | 6 | 7 | 8 |

Dear

9 |

10 | For your JHipster account a password reset was requested, please click on the URL below to reset it: 11 |

12 |

13 | Login link 14 |

15 |

16 | Regards, 17 |
18 | JHipster. 19 |

20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/templates/mail/testEmail.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./target/out-tsc/app", 5 | "types": ["@angular/localize"] 6 | }, 7 | "files": ["src/main/webapp/main.ts"], 8 | "include": ["src/main/webapp/**/*.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src/main/webapp/", 4 | "outDir": "./target/out-tsc/root", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "strictNullChecks": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true, 10 | "sourceMap": true, 11 | "declaration": false, 12 | "downlevelIteration": true, 13 | "experimentalDecorators": true, 14 | "moduleResolution": "node", 15 | "importHelpers": true, 16 | "esModuleInterop": true, 17 | "allowSyntheticDefaultImports": true, 18 | "useDefineForClassFields": false, 19 | "target": "es2022", 20 | "module": "es2020", 21 | "types": [], 22 | "lib": ["es2018", "es2020", "dom"] 23 | }, 24 | "references": [ 25 | { 26 | "path": "tsconfig.spec.json" 27 | } 28 | ], 29 | "angularCompilerOptions": { 30 | "strictInjectionParameters": true, 31 | "strictInputAccessModifiers": true, 32 | "strictTemplates": true, 33 | "preserveWhitespaces": true 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/main/webapp/**/*.ts"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "outDir": "target/out-tsc/spec", 7 | "types": ["jest", "node"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /webpack/environment.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | I18N_HASH: 'generated_hash', 3 | SERVER_API_URL: '', 4 | __VERSION__: process.env.APP_VERSION || 'DEV', 5 | }; 6 | -------------------------------------------------------------------------------- /webpack/logo-jhipster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhipster/jhipster-sample-app-dto/4e9153a7ceb1c70458e34523213f708b818d9260/webpack/logo-jhipster.png -------------------------------------------------------------------------------- /webpack/proxy.conf.js: -------------------------------------------------------------------------------- 1 | function setupProxy({ tls }) { 2 | const serverResources = ['/api', '/services', '/management', '/v3/api-docs', '/h2-console', '/health']; 3 | return [ 4 | { 5 | context: serverResources, 6 | target: `http${tls ? 's' : ''}://localhost:8080`, 7 | secure: false, 8 | changeOrigin: tls, 9 | }, 10 | ]; 11 | } 12 | 13 | module.exports = setupProxy; 14 | --------------------------------------------------------------------------------