From 19f0b8da98265056b2ef6354c80dead9ee6ee433 Mon Sep 17 00:00:00 2001 From: Marcin Ireneusz Trycz Date: Thu, 22 Sep 2016 10:58:44 +0200 Subject: [PATCH] initial import --- Jenkinsfile | 29 + README.md | 78 ++ bower.json | 64 ++ databasechangelog.csv | 1 + gulp/build.js | 51 ++ gulp/config.js | 23 + gulp/copy.js | 102 +++ gulp/handle-errors.js | 22 + gulp/inject.js | 68 ++ gulp/serve.js | 62 ++ gulp/utils.js | 36 + gulpfile.js | 170 +++++ mvnw | 233 ++++++ mvnw.cmd | 145 ++++ package.json | 67 ++ pom.xml | 670 ++++++++++++++++++ src/main/docker/Dockerfile | 13 + src/main/docker/app.yml | 16 + src/main/docker/postgresql.yml | 12 + src/main/docker/sonar.yml | 8 + .../ng/config/ActivitiBeanNameGenerator.java | 17 + .../flows/ng/config/FlowsConfigurations.java | 111 +++ .../si/flows/ng/resource/DiagramResource.java | 124 ++++ .../flows/ng/resource/FlowsTaskResource.java | 353 +++++++++ .../resource/ProcessDefinitionResource.java | 72 ++ src/main/resources/.h2.server.properties | 5 + src/main/resources/banner.txt | 9 + src/main/resources/i18n/messages.properties | 22 + .../resources/i18n/messages_it.properties | 22 + src/main/resources/logback-spring.xml | 60 ++ .../processes/PermessiFerieProcess.bpmn20.xml | 40 ++ src/main/resources/processes/hire.bpmn20.xml | 229 ++++++ src/main/webapp/.gitignore | 1 + src/main/webapp/404.html | 60 ++ src/main/webapp/app/account/account.state.js | 16 + .../account/activate/activate.controller.js | 23 + .../webapp/app/account/activate/activate.html | 16 + .../app/account/activate/activate.state.js | 33 + .../password-strength-bar.directive.js | 95 +++ .../account/password/password.controller.js | 39 + .../webapp/app/account/password/password.html | 63 ++ .../app/account/password/password.state.js | 33 + .../account/register/register.controller.js | 49 ++ .../webapp/app/account/register/register.html | 123 ++++ .../app/account/register/register.state.js | 33 + .../reset/finish/reset.finish.controller.js | 39 + .../account/reset/finish/reset.finish.html | 74 ++ .../reset/finish/reset.finish.state.js | 32 + .../reset/request/reset.request.controller.js | 38 + .../account/reset/request/reset.request.html | 47 ++ .../reset/request/reset.request.state.js | 32 + .../account/settings/settings.controller.js | 54 ++ .../webapp/app/account/settings/settings.html | 85 +++ .../app/account/settings/settings.state.js | 33 + src/main/webapp/app/admin/admin.state.js | 16 + .../app/admin/audits/audits.controller.js | 63 ++ src/main/webapp/app/admin/audits/audits.html | 41 ++ .../webapp/app/admin/audits/audits.service.js | 25 + .../webapp/app/admin/audits/audits.state.js | 33 + .../configuration/configuration.controller.js | 23 + .../admin/configuration/configuration.html | 47 ++ .../configuration/configuration.service.js | 47 ++ .../configuration/configuration.state.js | 33 + src/main/webapp/app/admin/docs/docs.html | 2 + src/main/webapp/app/admin/docs/docs.state.js | 30 + .../app/admin/health/health.controller.js | 63 ++ src/main/webapp/app/admin/health/health.html | 34 + .../admin/health/health.modal.controller.js | 21 + .../webapp/app/admin/health/health.modal.html | 34 + .../webapp/app/admin/health/health.service.js | 130 ++++ .../webapp/app/admin/health/health.state.js | 33 + .../webapp/app/admin/logs/logs.controller.js | 22 + src/main/webapp/app/admin/logs/logs.html | 27 + .../webapp/app/admin/logs/logs.service.js | 18 + src/main/webapp/app/admin/logs/logs.state.js | 33 + .../app/admin/metrics/metrics.controller.js | 76 ++ .../webapp/app/admin/metrics/metrics.html | 213 ++++++ .../admin/metrics/metrics.modal.controller.js | 53 ++ .../app/admin/metrics/metrics.modal.html | 53 ++ .../app/admin/metrics/metrics.service.js | 37 + .../webapp/app/admin/metrics/metrics.state.js | 33 + ...ser-management-delete-dialog.controller.js | 28 + .../user-management-delete-dialog.html | 19 + .../user-management-detail.controller.js | 24 + .../user-management-detail.html | 36 + .../user-management-dialog.controller.js | 46 ++ .../user-management-dialog.html | 113 +++ .../user-management.controller.js | 102 +++ .../user-management/user-management.html | 75 ++ .../user-management/user-management.state.js | 151 ++++ src/main/webapp/app/app.constants.js | 9 + src/main/webapp/app/app.module.js | 29 + src/main/webapp/app/app.state.js | 32 + .../webapp/app/blocks/config/alert.config.js | 14 + .../app/blocks/config/compile.config.js | 22 + .../webapp/app/blocks/config/http.config.js | 32 + .../app/blocks/config/localstorage.config.js | 14 + .../config/translation-storage.provider.js | 28 + .../app/blocks/config/translation.config.js | 25 + .../app/blocks/config/uib-pager.config.js | 15 + .../blocks/config/uib-pagination.config.js | 19 + .../app/blocks/handlers/state.handler.js | 63 ++ .../blocks/handlers/translation.handler.js | 43 ++ .../interceptor/auth-expired.interceptor.js | 31 + .../blocks/interceptor/auth.interceptor.js | 29 + .../interceptor/errorhandler.interceptor.js | 24 + .../interceptor/notification.interceptor.js | 25 + .../components/alert/alert-error.directive.js | 91 +++ .../app/components/alert/alert.directive.js | 27 + .../app/components/alert/alert.service.js | 137 ++++ .../app/components/form/maxbytes.directive.js | 46 ++ .../app/components/form/minbytes.directive.js | 45 ++ .../components/form/pagination.constants.js | 9 + .../form/show-validation.directive.js | 36 + .../components/language/language.constants.js | 17 + .../language/language.controller.js | 25 + .../components/language/language.filter.js | 43 ++ .../components/language/language.service.js | 33 + .../app/components/login/login.controller.js | 73 ++ .../webapp/app/components/login/login.html | 38 + .../app/components/login/login.service.js | 42 ++ .../app/components/util/base64.service.js | 92 +++ .../app/components/util/capitalize.filter.js | 18 + .../app/components/util/data-util.service.js | 74 ++ .../app/components/util/date-util.service.js | 50 ++ .../util/jhi-item-count.directive.js | 20 + .../util/pagination-util.service.js | 42 ++ .../components/util/parse-links.service.js | 46 ++ .../app/components/util/sort-by.directive.js | 24 + .../app/components/util/sort.directive.js | 80 +++ .../util/truncate-characters.filter.js | 37 + .../components/util/truncate-words.filter.js | 28 + src/main/webapp/app/entities/entity.state.js | 16 + .../app/forms/permessiFerieProcess/start.html | 41 ++ src/main/webapp/app/home/home.controller.js | 33 + src/main/webapp/app/home/home.html | 41 ++ src/main/webapp/app/home/home.state.js | 32 + .../app/layouts/error/accessdenied.html | 13 + src/main/webapp/app/layouts/error/error.html | 15 + .../webapp/app/layouts/error/error.state.js | 50 ++ .../layouts/navbar/active-link.directive.js | 30 + .../layouts/navbar/active-menu.directive.js | 33 + .../app/layouts/navbar/navbar.controller.js | 54 ++ .../webapp/app/layouts/navbar/navbar.html | 182 +++++ .../webapp/app/pages/main/main.controller.js | 50 ++ src/main/webapp/app/pages/main/main.html | 45 ++ src/main/webapp/app/pages/main/main.state.js | 32 + .../webapp/app/pages/task/task.controller.js | 30 + src/main/webapp/app/pages/task/task.html | 30 + src/main/webapp/app/pages/task/task.state.js | 32 + .../app/services/auth/account.service.js | 25 + .../app/services/auth/activate.service.js | 17 + .../app/services/auth/auth.oauth2.service.js | 52 ++ .../webapp/app/services/auth/auth.service.js | 183 +++++ .../auth/has-any-authority.directive.js | 52 ++ .../services/auth/has-authority.directive.js | 54 ++ .../auth/password-reset-finish.service.js | 15 + .../auth/password-reset-init.service.js | 15 + .../app/services/auth/password.service.js | 15 + .../app/services/auth/principal.service.js | 99 +++ .../app/services/auth/register.service.js | 13 + src/main/webapp/app/services/cnr/data.js | 38 + src/main/webapp/app/services/cnr/data_old.js | 277 ++++++++ .../profiles/page-ribbon.directive.js | 30 + .../app/services/profiles/profile.service.js | 36 + .../webapp/app/services/user/user.service.js | 27 + src/main/webapp/content/css/documentation.css | 3 + src/main/webapp/content/css/main.css | 342 +++++++++ src/main/webapp/content/images/hipster.png | Bin 0 -> 9499 bytes src/main/webapp/content/images/hipster2x.png | Bin 0 -> 18872 bytes .../webapp/content/images/logo-jhipster.png | Bin 0 -> 4459 bytes src/main/webapp/favicon.ico | Bin 0 -> 5430 bytes src/main/webapp/i18n/angular-locale_en.js | 143 ++++ src/main/webapp/i18n/angular-locale_it.js | 143 ++++ src/main/webapp/i18n/en/activate.json | 9 + src/main/webapp/i18n/en/audits.json | 27 + src/main/webapp/i18n/en/configuration.json | 10 + src/main/webapp/i18n/en/error.json | 6 + src/main/webapp/i18n/en/gateway.json | 15 + src/main/webapp/i18n/en/global.json | 123 ++++ src/main/webapp/i18n/en/health.json | 27 + src/main/webapp/i18n/en/home.json | 19 + src/main/webapp/i18n/en/login.json | 19 + src/main/webapp/i18n/en/logs.json | 11 + src/main/webapp/i18n/en/main.json | 0 src/main/webapp/i18n/en/metrics.json | 95 +++ src/main/webapp/i18n/en/password.json | 12 + src/main/webapp/i18n/en/register.json | 24 + src/main/webapp/i18n/en/reset.json | 30 + src/main/webapp/i18n/en/sessions.json | 15 + src/main/webapp/i18n/en/settings.json | 32 + src/main/webapp/i18n/en/task.json | 0 src/main/webapp/i18n/en/user-management.json | 30 + src/main/webapp/i18n/it/activate.json | 9 + src/main/webapp/i18n/it/audits.json | 27 + src/main/webapp/i18n/it/configuration.json | 10 + src/main/webapp/i18n/it/error.json | 6 + src/main/webapp/i18n/it/gateway.json | 15 + src/main/webapp/i18n/it/global.json | 123 ++++ src/main/webapp/i18n/it/health.json | 27 + src/main/webapp/i18n/it/home.json | 19 + src/main/webapp/i18n/it/login.json | 19 + src/main/webapp/i18n/it/logs.json | 11 + src/main/webapp/i18n/it/main.json | 0 src/main/webapp/i18n/it/metrics.json | 95 +++ src/main/webapp/i18n/it/password.json | 12 + src/main/webapp/i18n/it/register.json | 24 + src/main/webapp/i18n/it/reset.json | 30 + src/main/webapp/i18n/it/sessions.json | 15 + src/main/webapp/i18n/it/settings.json | 33 + src/main/webapp/i18n/it/task.json | 0 src/main/webapp/i18n/it/user-management.json | 30 + src/main/webapp/index.html | 187 +++++ src/main/webapp/robots.txt | 11 + .../webapp/swagger-ui/images/throbber.gif | Bin 0 -> 9257 bytes src/main/webapp/swagger-ui/index.html | 183 +++++ src/test/gatling/conf/gatling.conf | 153 ++++ src/test/resources/config/application.yml | 84 +++ src/test/resources/logback-test.xml | 14 + 219 files changed, 11392 insertions(+) create mode 100644 Jenkinsfile create mode 100644 README.md create mode 100644 bower.json create mode 100644 databasechangelog.csv create mode 100644 gulp/build.js create mode 100644 gulp/config.js create mode 100644 gulp/copy.js create mode 100644 gulp/handle-errors.js create mode 100644 gulp/inject.js create mode 100644 gulp/serve.js create mode 100644 gulp/utils.js create mode 100644 gulpfile.js create mode 100755 mvnw create mode 100644 mvnw.cmd create mode 100644 package.json create mode 100644 pom.xml create mode 100644 src/main/docker/Dockerfile create mode 100644 src/main/docker/app.yml create mode 100644 src/main/docker/postgresql.yml create mode 100644 src/main/docker/sonar.yml create mode 100644 src/main/java/it/cnr/si/flows/ng/config/ActivitiBeanNameGenerator.java create mode 100644 src/main/java/it/cnr/si/flows/ng/config/FlowsConfigurations.java create mode 100644 src/main/java/it/cnr/si/flows/ng/resource/DiagramResource.java create mode 100644 src/main/java/it/cnr/si/flows/ng/resource/FlowsTaskResource.java create mode 100644 src/main/java/it/cnr/si/flows/ng/resource/ProcessDefinitionResource.java create mode 100644 src/main/resources/.h2.server.properties create mode 100644 src/main/resources/banner.txt create mode 100644 src/main/resources/i18n/messages.properties create mode 100644 src/main/resources/i18n/messages_it.properties create mode 100644 src/main/resources/logback-spring.xml create mode 100644 src/main/resources/processes/PermessiFerieProcess.bpmn20.xml create mode 100644 src/main/resources/processes/hire.bpmn20.xml create mode 100644 src/main/webapp/.gitignore create mode 100644 src/main/webapp/404.html create mode 100644 src/main/webapp/app/account/account.state.js create mode 100644 src/main/webapp/app/account/activate/activate.controller.js create mode 100644 src/main/webapp/app/account/activate/activate.html create mode 100644 src/main/webapp/app/account/activate/activate.state.js create mode 100644 src/main/webapp/app/account/password/password-strength-bar.directive.js create mode 100644 src/main/webapp/app/account/password/password.controller.js create mode 100644 src/main/webapp/app/account/password/password.html create mode 100644 src/main/webapp/app/account/password/password.state.js create mode 100644 src/main/webapp/app/account/register/register.controller.js create mode 100644 src/main/webapp/app/account/register/register.html create mode 100644 src/main/webapp/app/account/register/register.state.js create mode 100644 src/main/webapp/app/account/reset/finish/reset.finish.controller.js create mode 100644 src/main/webapp/app/account/reset/finish/reset.finish.html create mode 100644 src/main/webapp/app/account/reset/finish/reset.finish.state.js create mode 100644 src/main/webapp/app/account/reset/request/reset.request.controller.js create mode 100644 src/main/webapp/app/account/reset/request/reset.request.html create mode 100644 src/main/webapp/app/account/reset/request/reset.request.state.js create mode 100644 src/main/webapp/app/account/settings/settings.controller.js create mode 100644 src/main/webapp/app/account/settings/settings.html create mode 100644 src/main/webapp/app/account/settings/settings.state.js create mode 100644 src/main/webapp/app/admin/admin.state.js create mode 100644 src/main/webapp/app/admin/audits/audits.controller.js create mode 100644 src/main/webapp/app/admin/audits/audits.html create mode 100644 src/main/webapp/app/admin/audits/audits.service.js create mode 100644 src/main/webapp/app/admin/audits/audits.state.js create mode 100644 src/main/webapp/app/admin/configuration/configuration.controller.js create mode 100644 src/main/webapp/app/admin/configuration/configuration.html create mode 100644 src/main/webapp/app/admin/configuration/configuration.service.js create mode 100644 src/main/webapp/app/admin/configuration/configuration.state.js create mode 100644 src/main/webapp/app/admin/docs/docs.html create mode 100644 src/main/webapp/app/admin/docs/docs.state.js create mode 100644 src/main/webapp/app/admin/health/health.controller.js create mode 100644 src/main/webapp/app/admin/health/health.html create mode 100644 src/main/webapp/app/admin/health/health.modal.controller.js create mode 100644 src/main/webapp/app/admin/health/health.modal.html create mode 100644 src/main/webapp/app/admin/health/health.service.js create mode 100644 src/main/webapp/app/admin/health/health.state.js create mode 100644 src/main/webapp/app/admin/logs/logs.controller.js create mode 100644 src/main/webapp/app/admin/logs/logs.html create mode 100644 src/main/webapp/app/admin/logs/logs.service.js create mode 100644 src/main/webapp/app/admin/logs/logs.state.js create mode 100644 src/main/webapp/app/admin/metrics/metrics.controller.js create mode 100644 src/main/webapp/app/admin/metrics/metrics.html create mode 100644 src/main/webapp/app/admin/metrics/metrics.modal.controller.js create mode 100644 src/main/webapp/app/admin/metrics/metrics.modal.html create mode 100644 src/main/webapp/app/admin/metrics/metrics.service.js create mode 100644 src/main/webapp/app/admin/metrics/metrics.state.js create mode 100644 src/main/webapp/app/admin/user-management/user-management-delete-dialog.controller.js create mode 100644 src/main/webapp/app/admin/user-management/user-management-delete-dialog.html create mode 100644 src/main/webapp/app/admin/user-management/user-management-detail.controller.js create mode 100644 src/main/webapp/app/admin/user-management/user-management-detail.html create mode 100644 src/main/webapp/app/admin/user-management/user-management-dialog.controller.js create mode 100644 src/main/webapp/app/admin/user-management/user-management-dialog.html create mode 100644 src/main/webapp/app/admin/user-management/user-management.controller.js create mode 100644 src/main/webapp/app/admin/user-management/user-management.html create mode 100644 src/main/webapp/app/admin/user-management/user-management.state.js create mode 100644 src/main/webapp/app/app.constants.js create mode 100644 src/main/webapp/app/app.module.js create mode 100644 src/main/webapp/app/app.state.js create mode 100644 src/main/webapp/app/blocks/config/alert.config.js create mode 100644 src/main/webapp/app/blocks/config/compile.config.js create mode 100644 src/main/webapp/app/blocks/config/http.config.js create mode 100644 src/main/webapp/app/blocks/config/localstorage.config.js create mode 100644 src/main/webapp/app/blocks/config/translation-storage.provider.js create mode 100644 src/main/webapp/app/blocks/config/translation.config.js create mode 100644 src/main/webapp/app/blocks/config/uib-pager.config.js create mode 100644 src/main/webapp/app/blocks/config/uib-pagination.config.js create mode 100644 src/main/webapp/app/blocks/handlers/state.handler.js create mode 100644 src/main/webapp/app/blocks/handlers/translation.handler.js create mode 100644 src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.js create mode 100644 src/main/webapp/app/blocks/interceptor/auth.interceptor.js create mode 100644 src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.js create mode 100644 src/main/webapp/app/blocks/interceptor/notification.interceptor.js create mode 100644 src/main/webapp/app/components/alert/alert-error.directive.js create mode 100644 src/main/webapp/app/components/alert/alert.directive.js create mode 100644 src/main/webapp/app/components/alert/alert.service.js create mode 100644 src/main/webapp/app/components/form/maxbytes.directive.js create mode 100644 src/main/webapp/app/components/form/minbytes.directive.js create mode 100644 src/main/webapp/app/components/form/pagination.constants.js create mode 100644 src/main/webapp/app/components/form/show-validation.directive.js create mode 100644 src/main/webapp/app/components/language/language.constants.js create mode 100644 src/main/webapp/app/components/language/language.controller.js create mode 100644 src/main/webapp/app/components/language/language.filter.js create mode 100644 src/main/webapp/app/components/language/language.service.js create mode 100644 src/main/webapp/app/components/login/login.controller.js create mode 100644 src/main/webapp/app/components/login/login.html create mode 100644 src/main/webapp/app/components/login/login.service.js create mode 100644 src/main/webapp/app/components/util/base64.service.js create mode 100644 src/main/webapp/app/components/util/capitalize.filter.js create mode 100644 src/main/webapp/app/components/util/data-util.service.js create mode 100644 src/main/webapp/app/components/util/date-util.service.js create mode 100644 src/main/webapp/app/components/util/jhi-item-count.directive.js create mode 100644 src/main/webapp/app/components/util/pagination-util.service.js create mode 100644 src/main/webapp/app/components/util/parse-links.service.js create mode 100644 src/main/webapp/app/components/util/sort-by.directive.js create mode 100644 src/main/webapp/app/components/util/sort.directive.js create mode 100644 src/main/webapp/app/components/util/truncate-characters.filter.js create mode 100644 src/main/webapp/app/components/util/truncate-words.filter.js create mode 100644 src/main/webapp/app/entities/entity.state.js create mode 100644 src/main/webapp/app/forms/permessiFerieProcess/start.html create mode 100644 src/main/webapp/app/home/home.controller.js create mode 100644 src/main/webapp/app/home/home.html create mode 100644 src/main/webapp/app/home/home.state.js create mode 100644 src/main/webapp/app/layouts/error/accessdenied.html create mode 100644 src/main/webapp/app/layouts/error/error.html create mode 100644 src/main/webapp/app/layouts/error/error.state.js create mode 100644 src/main/webapp/app/layouts/navbar/active-link.directive.js create mode 100644 src/main/webapp/app/layouts/navbar/active-menu.directive.js create mode 100644 src/main/webapp/app/layouts/navbar/navbar.controller.js create mode 100644 src/main/webapp/app/layouts/navbar/navbar.html create mode 100644 src/main/webapp/app/pages/main/main.controller.js create mode 100644 src/main/webapp/app/pages/main/main.html create mode 100644 src/main/webapp/app/pages/main/main.state.js create mode 100644 src/main/webapp/app/pages/task/task.controller.js create mode 100644 src/main/webapp/app/pages/task/task.html create mode 100644 src/main/webapp/app/pages/task/task.state.js create mode 100644 src/main/webapp/app/services/auth/account.service.js create mode 100644 src/main/webapp/app/services/auth/activate.service.js create mode 100644 src/main/webapp/app/services/auth/auth.oauth2.service.js create mode 100644 src/main/webapp/app/services/auth/auth.service.js create mode 100644 src/main/webapp/app/services/auth/has-any-authority.directive.js create mode 100644 src/main/webapp/app/services/auth/has-authority.directive.js create mode 100644 src/main/webapp/app/services/auth/password-reset-finish.service.js create mode 100644 src/main/webapp/app/services/auth/password-reset-init.service.js create mode 100644 src/main/webapp/app/services/auth/password.service.js create mode 100644 src/main/webapp/app/services/auth/principal.service.js create mode 100644 src/main/webapp/app/services/auth/register.service.js create mode 100644 src/main/webapp/app/services/cnr/data.js create mode 100644 src/main/webapp/app/services/cnr/data_old.js create mode 100644 src/main/webapp/app/services/profiles/page-ribbon.directive.js create mode 100644 src/main/webapp/app/services/profiles/profile.service.js create mode 100644 src/main/webapp/app/services/user/user.service.js create mode 100644 src/main/webapp/content/css/documentation.css create mode 100644 src/main/webapp/content/css/main.css create mode 100644 src/main/webapp/content/images/hipster.png create mode 100644 src/main/webapp/content/images/hipster2x.png create mode 100644 src/main/webapp/content/images/logo-jhipster.png create mode 100644 src/main/webapp/favicon.ico create mode 100644 src/main/webapp/i18n/angular-locale_en.js create mode 100644 src/main/webapp/i18n/angular-locale_it.js create mode 100644 src/main/webapp/i18n/en/activate.json create mode 100644 src/main/webapp/i18n/en/audits.json create mode 100644 src/main/webapp/i18n/en/configuration.json create mode 100644 src/main/webapp/i18n/en/error.json create mode 100644 src/main/webapp/i18n/en/gateway.json create mode 100644 src/main/webapp/i18n/en/global.json create mode 100644 src/main/webapp/i18n/en/health.json create mode 100644 src/main/webapp/i18n/en/home.json create mode 100644 src/main/webapp/i18n/en/login.json create mode 100644 src/main/webapp/i18n/en/logs.json create mode 100644 src/main/webapp/i18n/en/main.json create mode 100644 src/main/webapp/i18n/en/metrics.json create mode 100644 src/main/webapp/i18n/en/password.json create mode 100644 src/main/webapp/i18n/en/register.json create mode 100644 src/main/webapp/i18n/en/reset.json create mode 100644 src/main/webapp/i18n/en/sessions.json create mode 100644 src/main/webapp/i18n/en/settings.json create mode 100644 src/main/webapp/i18n/en/task.json create mode 100644 src/main/webapp/i18n/en/user-management.json create mode 100644 src/main/webapp/i18n/it/activate.json create mode 100644 src/main/webapp/i18n/it/audits.json create mode 100644 src/main/webapp/i18n/it/configuration.json create mode 100644 src/main/webapp/i18n/it/error.json create mode 100644 src/main/webapp/i18n/it/gateway.json create mode 100644 src/main/webapp/i18n/it/global.json create mode 100644 src/main/webapp/i18n/it/health.json create mode 100644 src/main/webapp/i18n/it/home.json create mode 100644 src/main/webapp/i18n/it/login.json create mode 100644 src/main/webapp/i18n/it/logs.json create mode 100644 src/main/webapp/i18n/it/main.json create mode 100644 src/main/webapp/i18n/it/metrics.json create mode 100644 src/main/webapp/i18n/it/password.json create mode 100644 src/main/webapp/i18n/it/register.json create mode 100644 src/main/webapp/i18n/it/reset.json create mode 100644 src/main/webapp/i18n/it/sessions.json create mode 100644 src/main/webapp/i18n/it/settings.json create mode 100644 src/main/webapp/i18n/it/task.json create mode 100644 src/main/webapp/i18n/it/user-management.json create mode 100644 src/main/webapp/index.html create mode 100644 src/main/webapp/robots.txt create mode 100644 src/main/webapp/swagger-ui/images/throbber.gif create mode 100644 src/main/webapp/swagger-ui/index.html create mode 100644 src/test/gatling/conf/gatling.conf create mode 100644 src/test/resources/config/application.yml create mode 100644 src/test/resources/logback-test.xml diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..516df2167 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,29 @@ +node { + // uncomment these 2 lines and edit the name 'node-4.4.7' according to what you choose in configuration + // def nodeHome = tool name: 'node-4.4.7', type: 'jenkins.plugins.nodejs.tools.NodeJSInstallation' + // env.PATH = "${nodeHome}/bin:${env.PATH}" + + stage 'check tools' + sh "node -v" + sh "npm -v" + sh "bower -v" + sh "gulp -v" + + stage 'checkout' + checkout scm + + stage 'npm install' + sh "npm install" + + stage 'clean' + sh "./mvnw clean" + + stage 'backend tests' + sh "./mvnw test" + + stage 'frontend tests' + sh "gulp test" + + stage 'packaging' + sh "./mvnw package -Pprod -DskipTests" +} diff --git a/README.md b/README.md new file mode 100644 index 000000000..b07ed9cfe --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# sprint + +This application was generated using JHipster, you can find documentation and help at [https://jhipster.github.io](https://jhipster.github.io). + +## Development + +Before you can build this project, you must install and configure the following dependencies on your machine: + +1. [Node.js][]: We use Node to run a development web server and build the project. + Depending on your system, you can install Node either from source or as a pre-packaged bundle. + +After installing Node, you should be able to run the following command to install development tools (like +[Bower][] and [BrowserSync][]). You will only need to run this command when dependencies change in package.json. + + npm install + +We use [Gulp][] as our build system. Install the Gulp command-line tool globally with: + + npm install -g gulp + +Run the following commands in two separate terminals to create a blissful development experience where your browser +auto-refreshes when files change on your hard drive. + + ./mvnw + gulp + +Bower is used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by +specifying a newer version in `bower.json`. You can also run `bower update` and `bower install` to manage dependencies. +Add the `-h` flag on any command to see how you can use it. For example, `bower update -h`. + + +## Building for production + +To optimize the sprint client for production, run: + + ./mvnw -Pprod clean package + +This will concatenate and minify CSS and JavaScript files. It will also modify `index.html` so it references +these new files. + +To ensure everything worked, run: + + java -jar target/*.war + +Then navigate to [http://localhost:8080](http://localhost:8080) in your browser. + +## Testing + +Unit tests are run by [Karma][] and written with [Jasmine][]. They're located in `src/test/javascript/` and can be run with: + + gulp test + + + +## Continuous Integration + +To setup this project in Jenkins, use the following configuration: + +* Project name: `sprint` +* Source Code Management + * Git Repository: `git@github.com:xxxx/sprint.git` + * Branches to build: `*/master` + * Additional Behaviours: `Wipe out repository & force clone` +* Build Triggers + * Poll SCM / Schedule: `H/5 * * * *` +* Build + * Invoke Maven / Tasks: `-Pprod clean package` +* Post-build Actions + * Publish JUnit test result report / Test Report XMLs: `build/test-results/*.xml` + +[JHipster]: https://jhipster.github.io/ +[Node.js]: https://nodejs.org/ +[Bower]: http://bower.io/ +[Gulp]: http://gulpjs.com/ +[BrowserSync]: http://www.browsersync.io/ +[Karma]: http://karma-runner.github.io/ +[Jasmine]: http://jasmine.github.io/2.0/introduction.html +[Protractor]: https://angular.github.io/protractor/ diff --git a/bower.json b/bower.json new file mode 100644 index 000000000..bb26918fc --- /dev/null +++ b/bower.json @@ -0,0 +1,64 @@ +{ + "version": "0.0.0", + "name": "sprint", + "appPath": "src/main/webapp/", + "testPath": "src/test/javascript/spec", + "dependencies": { + "angular": "1.5.8", + "angular-aria": "1.5.8", + "angular-bootstrap": "1.3.3", + "angular-cache-buster": "0.4.3", + "angular-cookies": "1.5.8", + "angular-dynamic-locale": "0.1.32", + "angular-i18n": "1.5.8", + "ngstorage": "0.3.10", + "angular-loading-bar": "0.9.0", + "angular-resource": "1.5.8", + "angular-sanitize": "1.5.8", + "angular-translate": "2.11.1", + "angular-translate-interpolation-messageformat": "2.11.1", + "angular-translate-loader-partial": "2.11.1", + "angular-translate-storage-cookie": "2.11.1", + "angular-ui-router": "0.3.1", + "bootstrap": "3.3.6", + "bootstrap-ui-datetime-picker": "2.4.3", + "jquery": "3.1.0", + "json3": "3.3.2", + "messageformat": "0.3.1", + "modernizr": "3.3.1", + "ng-file-upload": "12.0.4", + "ngInfiniteScroll": "1.3.0", + "swagger-ui": "2.1.5", + "angular-underscore-module": "^1.0.3" + }, + "devDependencies": { + "angular-mocks": "1.5.8" + }, + "overrides": { + "angular": { + "dependencies": { + "jquery": "3.1.0" + } + }, + "angular-cache-buster": { + "dependencies": { + "angular": "1.5.8" + } + }, + "angular-dynamic-locale": { + "dependencies": { + "angular": "1.5.8" + } + }, + "bootstrap": { + "main": [ + "dist/css/bootstrap.css" + ] + } + }, + "resolutions": { + "angular": "1.5.8", + "angular-bootstrap": "2.0.0", + "jquery": "3.1.0" + } +} diff --git a/databasechangelog.csv b/databasechangelog.csv new file mode 100644 index 000000000..c1c881853 --- /dev/null +++ b/databasechangelog.csv @@ -0,0 +1 @@ +"ID","AUTHOR","FILENAME","DATEEXECUTED","ORDEREXECUTED","EXECTYPE","MD5SUM","DESCRIPTION","COMMENTS","TAG","LIQUIBASE","CONTEXTS","LABELS" diff --git a/gulp/build.js b/gulp/build.js new file mode 100644 index 000000000..ecb5c362c --- /dev/null +++ b/gulp/build.js @@ -0,0 +1,51 @@ +'use strict'; + +var fs = require('fs'), + gulp = require('gulp'), + lazypipe = require('lazypipe'), + footer = require('gulp-footer'), + sourcemaps = require('gulp-sourcemaps'), + rev = require('gulp-rev'), + htmlmin = require('gulp-htmlmin'), + ngAnnotate = require('gulp-ng-annotate'), + prefix = require('gulp-autoprefixer'), + cssnano = require('gulp-cssnano'), + uglify = require('gulp-uglify'), + useref = require("gulp-useref"), + revReplace = require("gulp-rev-replace"), + plumber = require('gulp-plumber'), + gulpIf = require('gulp-if'), + handleErrors = require('./handle-errors'); + +var config = require('./config'); + +var initTask = lazypipe() + .pipe(sourcemaps.init); +var jsTask = lazypipe() + .pipe(ngAnnotate) + .pipe(uglify); +var cssTask = lazypipe() + .pipe(prefix) + .pipe(cssnano); + +module.exports = function() { + var templates = fs.readFileSync(config.tmp + '/templates.js'); + var manifest = gulp.src(config.revManifest); + + return gulp.src([config.app + '**/*.html', + '!' + config.app + 'app/**/*.html', + '!' + config.app + 'swagger-ui/**/*', + '!' + config.bower + '**/*.html']) + .pipe(plumber({errorHandler: handleErrors})) + //init sourcemaps and prepend semicolon + .pipe(useref({}, initTask)) + //append html templates + .pipe(gulpIf('**/app.js', footer(templates))) + .pipe(gulpIf('*.js', jsTask())) + .pipe(gulpIf('*.css', cssTask())) + .pipe(gulpIf('*.html', htmlmin({collapseWhitespace: true}))) + .pipe(gulpIf('**/*.!(html)', rev())) + .pipe(revReplace({manifest: manifest})) + .pipe(sourcemaps.write('.')) + .pipe(gulp.dest(config.dist)); +}; diff --git a/gulp/config.js b/gulp/config.js new file mode 100644 index 000000000..49df6e6dd --- /dev/null +++ b/gulp/config.js @@ -0,0 +1,23 @@ +'use strict'; + +module.exports = { + app: 'src/main/webapp/', + dist: 'target/www/', + swaggerDist: 'target/www/swagger-ui/', + test: 'src/test/javascript/', + bower: 'src/main/webapp/bower_components/', + tmp: 'target/tmp', + revManifest: 'target/tmp/rev-manifest.json', + port: 9000, + apiPort: 8080, + liveReloadPort: 35729, + uri: 'http://localhost:', + constantTemplate: + '(function () {\n' + + ' \'use strict\';\n' + + ' // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE\n' + + ' angular\n' + + ' .module(\'<%- moduleName %>\')\n' + + '<% constants.forEach(function(constant) { %> .constant(\'<%- constant.name %>\', <%= constant.value %>)\n<% }) %>;\n' + + '})();\n' +}; diff --git a/gulp/copy.js b/gulp/copy.js new file mode 100644 index 000000000..5f202198d --- /dev/null +++ b/gulp/copy.js @@ -0,0 +1,102 @@ +'use strict'; + +var gulp = require('gulp'), + rev = require('gulp-rev'), + plumber = require('gulp-plumber'), + es = require('event-stream'), + flatten = require('gulp-flatten'), + replace = require('gulp-replace'), + bowerFiles = require('main-bower-files'), + changed = require('gulp-changed'); + +var handleErrors = require('./handle-errors'); +var config = require('./config'); + +module.exports = { + i18n: i18n, + languages: languages, + fonts: fonts, + common: common, + swagger: swagger, + images: images +} + +var yorc = require('../.yo-rc.json')['generator-jhipster']; + +function i18n() { + return gulp.src(config.app + 'i18n/**') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.dist + 'i18n/')) + .pipe(gulp.dest(config.dist + 'i18n/')); +} + +function languages() { + var locales = yorc.languages.map(function (locale) { + return config.bower + 'angular-i18n/angular-locale_' + locale + '.js'; + }); + return gulp.src(locales) + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.app + 'i18n/')) + .pipe(gulp.dest(config.app + 'i18n/')); +} + +function fonts() { + return es.merge(gulp.src(config.bower + 'bootstrap/fonts/*.*') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.dist + 'content/fonts/')) + .pipe(rev()) + .pipe(gulp.dest(config.dist + 'content/fonts/')) + .pipe(rev.manifest(config.revManifest, { + base: config.dist, + merge: true + })) + .pipe(gulp.dest(config.dist)), + gulp.src(config.app + 'content/**/*.{woff,woff2,svg,ttf,eot,otf}') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.dist + 'content/fonts/')) + .pipe(flatten()) + .pipe(rev()) + .pipe(gulp.dest(config.dist + 'content/fonts/')) + .pipe(rev.manifest(config.revManifest, { + base: config.dist, + merge: true + })) + .pipe(gulp.dest(config.dist)) + ); +} + +function common() { + return gulp.src([config.app + 'robots.txt', config.app + 'favicon.ico', config.app + '.htaccess'], { dot: true }) + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.dist)) + .pipe(gulp.dest(config.dist)); +} + +function swagger() { + return es.merge( + gulp.src([config.bower + 'swagger-ui/dist/**', + '!' + config.bower + 'swagger-ui/dist/index.html', + '!' + config.bower + 'swagger-ui/dist/swagger-ui.min.js', + '!' + config.bower + 'swagger-ui/dist/swagger-ui.js']) + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.swaggerDist)) + .pipe(gulp.dest(config.swaggerDist)), + gulp.src(config.app + 'swagger-ui/index.html') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.swaggerDist)) + .pipe(replace('../bower_components/swagger-ui/dist/', '')) + .pipe(replace('swagger-ui.js', 'lib/swagger-ui.min.js')) + .pipe(gulp.dest(config.swaggerDist)), + gulp.src(config.bower + 'swagger-ui/dist/swagger-ui.min.js') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.swaggerDist + 'lib/')) + .pipe(gulp.dest(config.swaggerDist + 'lib/')) + ); +} + +function images() { + return gulp.src(bowerFiles({filter: ['**/*.{gif,jpg,png}']}), { base: config.bower }) + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.dist + 'bower_components')) + .pipe(gulp.dest(config.dist + 'bower_components')); +} diff --git a/gulp/handle-errors.js b/gulp/handle-errors.js new file mode 100644 index 000000000..98c4d4a64 --- /dev/null +++ b/gulp/handle-errors.js @@ -0,0 +1,22 @@ +'use strict'; + +var notify = require("gulp-notify"); +var argv = require('yargs').argv; + +module.exports = function() { + + var args = Array.prototype.slice.call(arguments); + var notification = argv.notification === undefined ? true : argv.notification; + // Send error to notification center with gulp-notify + if(notification) { + notify.onError({ + title: "JHipster Gulp Build", + subtitle: "Failure!", + message: "Error: <%= error.message %>", + sound: "Beep" + }).apply(this, args); + } + // Keep gulp from hanging on this task + this.emit('end'); + +}; diff --git a/gulp/inject.js b/gulp/inject.js new file mode 100644 index 000000000..30c575b08 --- /dev/null +++ b/gulp/inject.js @@ -0,0 +1,68 @@ +'use strict'; + +var gulp = require('gulp'), + plumber = require('gulp-plumber'), + inject = require('gulp-inject'), + es = require('event-stream'), + naturalSort = require('gulp-natural-sort'), + angularFilesort = require('gulp-angular-filesort'), + bowerFiles = require('main-bower-files'); + +var handleErrors = require('./handle-errors'); + +var config = require('./config'); + +module.exports = { + app: app, + vendor: vendor, + test: test, + troubleshoot: troubleshoot +} + +function app() { + return gulp.src(config.app + 'index.html') + .pipe(inject(gulp.src(config.app + 'app/**/*.js') + .pipe(naturalSort()) + .pipe(angularFilesort()), {relative: true})) + .pipe(gulp.dest(config.app)); +} + +function vendor() { + var stream = gulp.src(config.app + 'index.html') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(inject(gulp.src(bowerFiles(), {read: false}), { + name: 'bower', + relative: true + })) + .pipe(gulp.dest(config.app)); + + return stream; +} + +function test() { + return gulp.src(config.test + 'karma.conf.js') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(inject(gulp.src(bowerFiles({includeDev: true, filter: ['**/*.js']}), {read: false}), { + starttag: '// bower:js', + endtag: '// endbower', + transform: function (filepath) { + return '\'' + filepath.substring(1, filepath.length) + '\','; + } + })) + .pipe(gulp.dest(config.test)); +} + +function troubleshoot() { + /* this task removes the troubleshooting content from index.html*/ + return gulp.src(config.app + 'index.html') + .pipe(plumber({errorHandler: handleErrors})) + /* having empty src as we dont have to read any files*/ + .pipe(inject(gulp.src('', {read: false}), { + starttag: '', + removeTags: true, + transform: function () { + return ''; + } + })) + .pipe(gulp.dest(config.app)); +} diff --git a/gulp/serve.js b/gulp/serve.js new file mode 100644 index 000000000..243a01784 --- /dev/null +++ b/gulp/serve.js @@ -0,0 +1,62 @@ +'use strict'; + +var gulp = require('gulp'), + util = require('./utils'), + url = require('url'), + browserSync = require('browser-sync'), + proxy = require('proxy-middleware'); + +var config = require('./config'); + +module.exports = function () { + var baseUri = config.uri + config.apiPort; + // Routes to proxy to the backend. Routes ending with a / will setup + // a redirect so that if accessed without a trailing slash, will + // redirect. This is required for some endpoints for proxy-middleware + // to correctly handle them. + var proxyRoutes = [ + '/' + ]; + + var requireTrailingSlash = proxyRoutes.filter(function (r) { + return util.endsWith(r, '/'); + }).map(function (r) { + // Strip trailing slash so we can use the route to match requests + // with non trailing slash + return r.substr(0, r.length - 1); + }); + + var proxies = [ + // Ensure trailing slash in routes that require it + function (req, res, next) { + requireTrailingSlash.forEach(function (route){ + if (url.parse(req.url).path === route) { + res.statusCode = 301; + res.setHeader('Location', route + '/'); + res.end(); + } + }); + + next(); + } + ] + .concat( + // Build a list of proxies for routes: [route1_proxy, route2_proxy, ...] + proxyRoutes.map(function (r) { + var options = url.parse(baseUri + r); + options.route = r; + options.preserveHost = true; + return proxy(options); + })); + + browserSync({ + open: true, + port: config.port, + server: { + baseDir: config.app, + middleware: proxies + } + }); + + gulp.start('watch'); +}; diff --git a/gulp/utils.js b/gulp/utils.js new file mode 100644 index 000000000..abb80d3e3 --- /dev/null +++ b/gulp/utils.js @@ -0,0 +1,36 @@ +'use strict'; + +var fs = require('fs'); + +module.exports = { + endsWith : endsWith, + parseVersion : parseVersion, + isLintFixed : isLintFixed +}; + +function endsWith(str, suffix) { + return str.indexOf('/', str.length - suffix.length) !== -1; +} + +var parseString = require('xml2js').parseString; +// return the version number from `pom.xml` file +function parseVersion() { + var version = null; + var pomXml = fs.readFileSync('pom.xml', 'utf8'); + parseString(pomXml, function (err, result) { + if (result.project.version && result.project.version[0]) { + version = result.project.version[0]; + } else if (result.project.parent && result.project.parent[0] && result.project.parent[0].version && result.project.parent[0].version[0]) { + version = result.project.parent[0].version[0]; + } + }); + if (version === null) { + throw new Error('pom.xml is malformed. No version is defined'); + } + return version; +} + +function isLintFixed(file) { + // Has ESLint fixed the file contents? + return file.eslint !== null && file.eslint.fixed; +} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 000000000..e24c855da --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,170 @@ +// Generated on 2016-09-07 using generator-jhipster 3.6.1 +'use strict'; + +var gulp = require('gulp'), + rev = require('gulp-rev'), + templateCache = require('gulp-angular-templatecache'), + htmlmin = require('gulp-htmlmin'), + imagemin = require('gulp-imagemin'), + ngConstant = require('gulp-ng-constant'), + rename = require('gulp-rename'), + eslint = require('gulp-eslint'), + del = require('del'), + runSequence = require('run-sequence'), + browserSync = require('browser-sync'), + KarmaServer = require('karma').Server, + plumber = require('gulp-plumber'), + changed = require('gulp-changed'), + gulpIf = require('gulp-if'); + +var handleErrors = require('./gulp/handle-errors'), + serve = require('./gulp/serve'), + util = require('./gulp/utils'), + copy = require('./gulp/copy'), + inject = require('./gulp/inject'), + build = require('./gulp/build'); + +var config = require('./gulp/config'); + +gulp.task('clean', function () { + return del([config.dist], { dot: true }); +}); + +gulp.task('copy', ['copy:i18n', 'copy:fonts', 'copy:common']); + +gulp.task('copy:i18n', copy.i18n); + +gulp.task('copy:languages', copy.languages); + +gulp.task('copy:fonts', copy.fonts); + +gulp.task('copy:common', copy.common); + +gulp.task('copy:swagger', copy.swagger); + +gulp.task('copy:images', copy.images); + +gulp.task('images', function () { + return gulp.src(config.app + 'content/images/**') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(changed(config.dist + 'content/images')) + .pipe(imagemin({optimizationLevel: 5, progressive: true, interlaced: true})) + .pipe(rev()) + .pipe(gulp.dest(config.dist + 'content/images')) + .pipe(rev.manifest(config.revManifest, { + base: config.dist, + merge: true + })) + .pipe(gulp.dest(config.dist)) + .pipe(browserSync.reload({stream: true})); +}); + + +gulp.task('styles', [], function () { + return gulp.src(config.app + 'content/css') + .pipe(browserSync.reload({stream: true})); +}); + +gulp.task('inject', function() { + runSequence('inject:dep', 'inject:app'); +}); + +gulp.task('inject:dep', ['inject:test', 'inject:vendor']); + +gulp.task('inject:app', inject.app); + +gulp.task('inject:vendor', inject.vendor); + +gulp.task('inject:test', inject.test); + +gulp.task('inject:troubleshoot', inject.troubleshoot); + +gulp.task('assets:prod', ['images', 'styles', 'html', 'copy:swagger', 'copy:images'], build); + +gulp.task('html', function () { + return gulp.src(config.app + 'app/**/*.html') + .pipe(htmlmin({collapseWhitespace: true})) + .pipe(templateCache({ + module: 'sprintApp', + root: 'app/', + moduleSystem: 'IIFE' + })) + .pipe(gulp.dest(config.tmp)); +}); + +gulp.task('ngconstant:dev', function () { + return ngConstant({ + name: 'sprintApp', + constants: { + VERSION: util.parseVersion(), + DEBUG_INFO_ENABLED: true + }, + template: config.constantTemplate, + stream: true + }) + .pipe(rename('app.constants.js')) + .pipe(gulp.dest(config.app + 'app/')); +}); + +gulp.task('ngconstant:prod', function () { + return ngConstant({ + name: 'sprintApp', + constants: { + VERSION: util.parseVersion(), + DEBUG_INFO_ENABLED: false + }, + template: config.constantTemplate, + stream: true + }) + .pipe(rename('app.constants.js')) + .pipe(gulp.dest(config.app + 'app/')); +}); + +// check app for eslint errors +gulp.task('eslint', function () { + return gulp.src(['gulpfile.js', config.app + 'app/**/*.js']) + .pipe(plumber({errorHandler: handleErrors})) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failOnError()); +}); + +// check app for eslint errors anf fix some of them +gulp.task('eslint:fix', function () { + return gulp.src(config.app + 'app/**/*.js') + .pipe(plumber({errorHandler: handleErrors})) + .pipe(eslint({ + fix: true + })) + .pipe(eslint.format()) + .pipe(gulpIf(util.isLintFixed, gulp.dest(config.app + 'app'))); +}); + +gulp.task('test', ['inject:test', 'ngconstant:dev'], function (done) { + new KarmaServer({ + configFile: __dirname + '/' + config.test + 'karma.conf.js', + singleRun: true + }, done).start(); +}); + + +gulp.task('watch', function () { + gulp.watch('bower.json', ['install']); + gulp.watch(['gulpfile.js', 'pom.xml'], ['ngconstant:dev']); + gulp.watch(config.app + 'content/css/**/*.css', ['styles']); + gulp.watch(config.app + 'content/images/**', ['images']); + gulp.watch(config.app + 'app/**/*.js', ['inject:app']); + gulp.watch([config.app + '*.html', config.app + 'app/**', config.app + 'i18n/**']).on('change', browserSync.reload); +}); + +gulp.task('install', function () { + runSequence(['inject:dep', 'ngconstant:dev'], 'copy:languages', 'inject:app', 'inject:troubleshoot'); +}); + +gulp.task('serve', ['install'], serve); + +gulp.task('build', ['clean'], function (cb) { + runSequence(['copy', 'inject:vendor', 'ngconstant:prod', 'copy:languages'], 'inject:app', 'inject:troubleshoot', 'assets:prod', cb); +}); + +gulp.task('default', ['serve']); diff --git a/mvnw b/mvnw new file mode 100755 index 000000000..a1ba1bf55 --- /dev/null +++ b/mvnw @@ -0,0 +1,233 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 000000000..2b934e89d --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..5ca3f257d --- /dev/null +++ b/package.json @@ -0,0 +1,67 @@ +{ + "name": "sprint", + "version": "0.0.0", + "description": "Description for sprint", + "private": true, + "cacheDirectories": [ + "node_modules", + "src/main/webapp/bower_components" + ], + "devDependencies": { + "bower": "1.7.9", + "browser-sync": "2.13.0", + "del": "2.2.1", + "eslint-config-angular": "0.5.0", + "eslint-plugin-angular": "1.3.1", + "event-stream": "3.3.4", + "generator-jhipster": "3.6.1", + "gulp": "3.9.1", + "gulp-angular-filesort": "1.1.1", + "gulp-angular-templatecache": "2.0.0", + "gulp-autoprefixer": "3.1.0", + "gulp-changed": "1.3.1", + "gulp-cssnano": "2.1.2", + "gulp-eslint": "3.0.1", + "gulp-flatten": "0.3.0", + "gulp-footer": "1.0.5", + "gulp-htmlmin": "2.0.0", + "gulp-if": "2.0.1", + "gulp-imagemin": "3.0.2", + "gulp-inject": "4.1.0", + "gulp-natural-sort": "0.1.1", + "gulp-ng-annotate": "2.0.0", + "gulp-ng-constant": "1.1.0", + "gulp-notify": "2.2.0", + "gulp-plumber": "1.1.0", + "gulp-rename": "1.2.2", + "gulp-replace": "0.5.4", + "gulp-rev": "7.1.0", + "gulp-rev-replace": "0.4.3", + "gulp-sourcemaps": "1.6.0", + "gulp-uglify": "1.5.4", + "gulp-useref": "3.1.0", + "jasmine-core": "2.4.1", + "karma": "1.1.2", + "karma-chrome-launcher": "1.0.1", + "karma-coverage": "1.1.1", + "karma-jasmine": "1.0.2", + "karma-junit-reporter": "1.1.0", + "karma-phantomjs-launcher": "1.0.1", + "karma-script-launcher": "1.0.0", + "lazypipe": "1.0.1", + "lodash": "4.14.0", + "main-bower-files": "2.13.1", + "map-stream": "0.0.6", + "phantomjs-prebuilt": "2.1.8", + "proxy-middleware": "0.15.0", + "run-sequence": "1.2.2", + "xml2js": "0.4.16", + "yargs": "4.8.1" + }, + "engines": { + "node": "^4.3" + }, + "scripts": { + "test": "gulp test" + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..4d788b183 --- /dev/null +++ b/pom.xml @@ -0,0 +1,670 @@ + + + 4.0.0 + + + archetype + it.cnr.si + 1.0.3 + + + it.cnr.si.sprint + sprint-ace + 0.2.0-SNAPSHOT + war + + sprint-ace + + + 3.0.0 + + + + scm:git:ssh://git@git.si.cnr.it/dev/sprint-ace.git + scm:git:ssh://git@git.si.cnr.it/dev/sprint-ace.git + HEAD + + + + 3.5.2 + 2.1.7 + 0.7.7.201606060606 + 2.2.0 + 3.5 + 3.4.2 + 1.0.0.Final + 1.4.1 + 3.0.1 + + yyyyMMddHHmmss + 3.0.2 + 2.5.0 + 1.4.0.RELEASE + 2.0.1 + it.cnr.si.SprintApp + + + + + + + it.cnr.si.sprint + sprint-ldap + ${sprint.version} + + + it.cnr.si.sprint + sprint-core + ${sprint.version} + + + + + + org.activiti + activiti-spring + 5.21.0 + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + + + + + + + org.activiti + activiti-rest + 5.21.0 + + + + + + + + + + + + + + + org.slf4j + slf4j-log4j12 + + + + + + + + + + + spring-boot:run + + + com.github.ekryd.sortpom + sortpom-maven-plugin + ${sortpom-maven-plugin.version} + + + verify + + sort + + + + + true + 4 + groupId,artifactId + groupId,artifactId + true + false + + + + io.gatling + gatling-maven-plugin + ${gatling-maven-plugin.version} + + src/test/gatling/conf + src/test/gatling/data + target/gatling/results + src/test/gatling/bodies + src/test/gatling/simulations + + * + + + + org.apache.maven.plugins + maven-eclipse-plugin + + true + true + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven-enforcer-plugin.version} + + + enforce-versions + + enforce + + + + + + + You are running an older version of Maven. + JHipster requires at least Maven 3.0 + [3.0.0,) + + + You are running an older version of Java. + JHipster requires at least JDK ${java.version} + [${java.version}.0,) + + + + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + default-resources + validate + + copy-resources + + + target/classes + false + + # + + + + src/main/resources/ + true + + **/*.xml + **/*.yml + + + + src/main/resources/ + false + + **/*.xml + **/*.yml + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + ${surefireArgLine} + + alphabetical + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + pre-unit-tests + + prepare-agent + + + + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + + surefireArgLine + + + + + post-unit-test + test + + report + + + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + ${project.testresult.directory}/coverage/jacoco + + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + ${sonar-maven-plugin.version} + + + org.bsc.maven + maven-processor-plugin + 2.2.4 + + + ${project.build.directory}/generated-sources + + + org.mapstruct.ap.MappingProcessor + + + true + spring + + + + + process + generate-sources + + process + + + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + org.liquibase + liquibase-maven-plugin + ${liquibase.version} + + src/main/resources/config/liquibase/master.xml + src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml + + + + sprint + + hibernate:spring:it.cnr.si.domain?dialect=&hibernate.ejb.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy + true + debug + oauth_access_token, oauth_approvals, + oauth_client_details, oauth_client_token, oauth_code, + oauth_refresh_token + + + + org.javassist + javassist + 3.18.2-GA + + + org.liquibase.ext + liquibase-hibernate4 + ${liquibase-hibernate4.version} + + + org.springframework.boot + spring-boot-starter-data-jpa + ${project.parent.version} + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + com.spotify + docker-maven-plugin + 0.4.10 + + sprint + src/main/docker + + + / + ${project.build.directory} + ${project.build.finalName}.war + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + ${start-class} + + + + + ${start-class} + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jacoco + + jacoco-maven-plugin + + + ${jacoco-maven-plugin.version} + + + prepare-agent + + + + + + + + + com.github.eirslett + + frontend-maven-plugin + + + ${frontend-maven-plugin.version} + + + install-node-and-npm + npm + bower + gulp + + + + + + + + + + + + + + + + + no-liquibase + + ,no-liquibase + + + + swagger + + ,swagger + + + + dev + + true + + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring-boot.version} + + + org.springframework.boot + spring-boot-devtools + ${spring-boot.version} + true + + + + + + org.apache.maven.plugins + maven-war-plugin + + src/main/webapp/ + WEB-INF/lib/tomcat-*.jar + + + + + + + DEBUG + + dev,cnr${profile.no-liquibase} + + + + prod + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + com.github.eirslett + frontend-maven-plugin + 1.0 + + + install node and npm + + install-node-and-npm + + + v4.4.7 + 3.10.5 + + + + npm install + + npm + + + install + + + + bower install + + bower + + + install --no-color + + + + gulp build + + gulp + + + build --no-notification + + + + gulp test + + gulp + + test + + test --no-notification + + + + + + maven-clean-plugin + 2.5 + + + + target/www/ + + + + + + org.apache.maven.plugins + maven-war-plugin + + target/www/ + WEB-INF/lib/tomcat-*.jar + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + + + INFO + + prod${profile.swagger}${profile.no-liquibase} + + + + + + + + org.springframework + spring-core + 4.3.2.RELEASE + + + org.springframework + spring-context + 4.3.2.RELEASE + + + org.springframework + spring-tx + 4.3.2.RELEASE + + + org.springframework + spring-web + 4.3.2.RELEASE + + + org.springframework + spring-webmvc + 4.3.2.RELEASE + + + org.slf4j + slf4j-api + 1.7.21 + + + org.springframework.security + spring-security-ldap + 4.1.1.RELEASE + + + org.springframework.security + spring-security-core + 4.1.1.RELEASE + + + org.springframework.security + spring-security-web + 4.1.1.RELEASE + + + org.springframework.security + spring-security-data + 4.1.1.RELEASE + + + org.springframework.security + spring-security-config + 4.1.1.RELEASE + + + + + + + + + + + + + + diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile new file mode 100644 index 000000000..01354228d --- /dev/null +++ b/src/main/docker/Dockerfile @@ -0,0 +1,13 @@ +FROM java:openjdk-8-jre-alpine + +ENV JHIPSTER_SLEEP 0 + +# add directly the war +ADD *.war /app.war + +RUN sh -c 'touch /app.war' +VOLUME /tmp +EXPOSE 8080 5701/udp +CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \ + sleep ${JHIPSTER_SLEEP} && \ + java -Djava.security.egd=file:/dev/./urandom -jar /app.war diff --git a/src/main/docker/app.yml b/src/main/docker/app.yml new file mode 100644 index 000000000..f3f3790e9 --- /dev/null +++ b/src/main/docker/app.yml @@ -0,0 +1,16 @@ +version: '2' +services: + sprint-app: + image: sprint + external_links: + - sprint-postgresql:postgresql + environment: + - SPRING_PROFILES_ACTIVE=prod,swagger + - SPRING_DATASOURCE_URL=jdbc:postgresql://postgresql:5432/sprint + - JHIPSTER_SLEEP=10 # gives time for the database to boot before the application + ports: + - 8080:8080 + sprint-postgresql: + extends: + file: postgresql.yml + service: sprint-postgresql diff --git a/src/main/docker/postgresql.yml b/src/main/docker/postgresql.yml new file mode 100644 index 000000000..697170263 --- /dev/null +++ b/src/main/docker/postgresql.yml @@ -0,0 +1,12 @@ +version: '2' +services: + sprint-postgresql: + container_name: sprint-postgresql + image: postgres:9.5.3 + # volumes: + # - ~/volumes/jhipster/sprint/postgresql/:/var/lib/postgresql/ + environment: + - POSTGRES_USER=sprint + - POSTGRES_PASSWORD= + ports: + - 5432:5432 diff --git a/src/main/docker/sonar.yml b/src/main/docker/sonar.yml new file mode 100644 index 000000000..026933f9a --- /dev/null +++ b/src/main/docker/sonar.yml @@ -0,0 +1,8 @@ +version: '2' +services: + sprint-sonar: + container_name: sprint-sonar + image: sonarqube:5.6-alpine + ports: + - 9000:9000 + - 9092:9092 diff --git a/src/main/java/it/cnr/si/flows/ng/config/ActivitiBeanNameGenerator.java b/src/main/java/it/cnr/si/flows/ng/config/ActivitiBeanNameGenerator.java new file mode 100644 index 000000000..48c999451 --- /dev/null +++ b/src/main/java/it/cnr/si/flows/ng/config/ActivitiBeanNameGenerator.java @@ -0,0 +1,17 @@ +package it.cnr.si.flows.ng.config; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.annotation.AnnotationBeanNameGenerator; + +public class ActivitiBeanNameGenerator extends AnnotationBeanNameGenerator { + + public ActivitiBeanNameGenerator() { + super(); + } + + @Override + public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { + return "activiti"+super.generateBeanName(definition, registry); + } +} diff --git a/src/main/java/it/cnr/si/flows/ng/config/FlowsConfigurations.java b/src/main/java/it/cnr/si/flows/ng/config/FlowsConfigurations.java new file mode 100644 index 000000000..0f9bc4ea5 --- /dev/null +++ b/src/main/java/it/cnr/si/flows/ng/config/FlowsConfigurations.java @@ -0,0 +1,111 @@ +package it.cnr.si.flows.ng.config; + +import javax.annotation.PostConstruct; + +import org.activiti.engine.FormService; +import org.activiti.engine.HistoryService; +import org.activiti.engine.IdentityService; +import org.activiti.engine.ManagementService; +import org.activiti.engine.ProcessEngine; +import org.activiti.engine.ProcessEngineConfiguration; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; +import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.activiti.engine.impl.history.HistoryLevel; +import org.activiti.engine.repository.DeploymentBuilder; +import org.activiti.rest.common.application.ContentTypeResolver; +import org.activiti.rest.service.api.RestResponseFactory; +import org.activiti.spring.ProcessEngineFactoryBean; +import org.activiti.spring.SpringProcessEngineConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.transaction.PlatformTransactionManager; + +import com.zaxxer.hikari.HikariDataSource; + + +@Configuration +@ComponentScan(basePackages = {"org.activiti.rest",}, +// excludeFilters = {@ComponentScan.Filter( +// type = FilterType.ASSIGNABLE_TYPE, +// value = {UserResource.class} +// )} +// , + includeFilters = {@ComponentScan.Filter( + type = FilterType.ASSIGNABLE_TYPE, + value = {RestResponseFactory.class, ContentTypeResolver.class} + ) + }, + nameGenerator = ActivitiBeanNameGenerator.class) +public class FlowsConfigurations { + + + @Autowired + private PlatformTransactionManager transactionManager; + + @Autowired + private HikariDataSource dataSource; + + @Bean + public ProcessEngineConfigurationImpl getProcessEngineConfiguration() { + SpringProcessEngineConfiguration conf = new SpringProcessEngineConfiguration(); + conf.setDataSource(dataSource); + conf.setTransactionManager(transactionManager); + conf.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); + + conf.setHistoryLevel(HistoryLevel.FULL); + + return conf; + } + + @Bean(name= {"processEngine", "engine"}) + public ProcessEngine getProcessEngine() throws Exception { + ProcessEngineFactoryBean bean = new ProcessEngineFactoryBean(); + bean.setProcessEngineConfiguration(getProcessEngineConfiguration()); + return bean.getObject(); + } + + @Bean + public RepositoryService getRepositoryService() throws Exception { + return getProcessEngine().getRepositoryService(); + + } + + + @Bean + public RuntimeService getRuntimeService() throws Exception { + return getProcessEngine().getRuntimeService(); + } + + @Bean FormService getFormService() throws Exception { + return getProcessEngine().getFormService(); + } + + @Bean HistoryService getHistoryService() throws Exception { + return getProcessEngine().getHistoryService(); + } + + @Bean TaskService getTaskService() throws Exception { + return getProcessEngine().getTaskService(); + } + + @Bean IdentityService getIdentityService() throws Exception { + return getProcessEngine().getIdentityService(); + } + + @Bean ManagementService getManagementService() throws Exception { + return getProcessEngine().getManagementService(); + } + + @PostConstruct + public void createDeployments() throws Exception { + DeploymentBuilder builder = getRepositoryService().createDeployment(); + builder.addClasspathResource("processes/PermessiFerieProcess.bpmn20.xml"); + builder.deploy(); + } + +} diff --git a/src/main/java/it/cnr/si/flows/ng/resource/DiagramResource.java b/src/main/java/it/cnr/si/flows/ng/resource/DiagramResource.java new file mode 100644 index 000000000..73624c08d --- /dev/null +++ b/src/main/java/it/cnr/si/flows/ng/resource/DiagramResource.java @@ -0,0 +1,124 @@ +package it.cnr.si.flows.ng.resource; + +import java.io.IOException; +import java.io.InputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.engine.ActivitiIllegalArgumentException; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.RuntimeService; +import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; +import org.activiti.engine.repository.ProcessDefinition; +import org.activiti.engine.runtime.ProcessInstance; +import org.activiti.image.ProcessDiagramGenerator; +import org.activiti.rest.service.api.runtime.task.TaskResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.codahale.metrics.annotation.Timed; + + +@Controller +@RequestMapping("rest") +public class DiagramResource { + + @Autowired + private RepositoryService repositoryService; + @Autowired + private RuntimeService runtimeService; +// @Autowired + private ProcessDiagramGenerator pdg; + + @RequestMapping(value = "/diagram/{id}", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE) + @ResponseBody + @Timed + public void getDiagramForProcess( + @PathVariable String id, + HttpServletRequest request, + HttpServletResponse response + ) throws IOException { + + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .processDefinitionId(id) + .singleResult(); + + String diagramResourceName = processDefinition.getDiagramResourceName(); + InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName()); + + + response.setContentType(MediaType.IMAGE_PNG_VALUE); + org.apache.commons.io.IOUtils.copy(resourceAsStream, response.getOutputStream()); + + } + + @RequestMapping(value = "/diagram", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE) + @ResponseBody + @Timed + public void getDiagram( + HttpServletRequest request, + HttpServletResponse response + ) throws IOException { + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .processDefinitionKey("permessiFerieProcess") + .latestVersion() + .singleResult(); + + String diagramResourceName = processDefinition.getDiagramResourceName(); + InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName()); + + + response.setContentType(MediaType.IMAGE_PNG_VALUE); + org.apache.commons.io.IOUtils.copy(resourceAsStream, response.getOutputStream()); + + } + + @RequestMapping(value = "/diagram2", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE) + @ResponseBody + @Timed + public void getDiagram2( + HttpServletRequest request, + HttpServletResponse response + ) throws IOException { +// ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() +// .processDefinitionKey("permessiFerieProcess") +// .latestVersion() +// .singleResult(); +// +// String diagramResourceName = processDefinition.getDiagramResourceName(); +// InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName()); +// +// +// response.setContentType(MediaType.IMAGE_PNG_VALUE); +// org.apache.commons.io.IOUtils.copy(resourceAsStream, response.getOutputStream()); + + TaskResponse tr; + + ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.createProcessDefinitionQuery() + .processDefinitionKey("permessiFerieProcess") + .latestVersion() + .singleResult(); + + + ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); + + + if (processDefinition != null && processDefinition.isGraphicalNotationDefined()) { + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); + InputStream resource = pdg.generateDiagram(bpmnModel, "png", runtimeService.getActiveActivityIds(processInstance.getId())); + + response.setContentType(MediaType.IMAGE_PNG_VALUE); + org.apache.commons.io.IOUtils.copy(resource, response.getOutputStream()); + + } else { + throw new ActivitiIllegalArgumentException("Process instance with id '" + processInstance.getId() + "' has no graphical notation defined."); + } + } +} diff --git a/src/main/java/it/cnr/si/flows/ng/resource/FlowsTaskResource.java b/src/main/java/it/cnr/si/flows/ng/resource/FlowsTaskResource.java new file mode 100644 index 000000000..ea58866ed --- /dev/null +++ b/src/main/java/it/cnr/si/flows/ng/resource/FlowsTaskResource.java @@ -0,0 +1,353 @@ +package it.cnr.si.flows.ng.resource; + +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.activiti.engine.RepositoryService; +import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; +import org.activiti.engine.task.Task; +import org.activiti.rest.common.api.DataResponse; +import org.activiti.rest.service.api.RestResponseFactory; +import org.activiti.rest.service.api.runtime.task.TaskCollectionResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.codahale.metrics.annotation.Timed; + +import it.cnr.si.repository.UserRepository; +import it.cnr.si.security.AuthoritiesConstants; +import it.cnr.si.security.SecurityUtils; +import it.cnr.si.service.UserService; + + +/** + * @author mtrycz + * + */ +@RestController +@RequestMapping("rest/tasks") +public class FlowsTaskResource { + + @Deprecated + private static final String ERRORE_PERMESSI_TASK = "ERRORE PERMESSI TASK"; + + private static final Logger LOGGER = LoggerFactory.getLogger(FlowsTaskResource.class); + + @Inject + private UserRepository userRepository; + @Inject + private UserService userService; + + @Autowired + protected RestResponseFactory restResponseFactory; + + @Autowired + private RepositoryService repositoryService; + @Autowired + private RuntimeService runtimeService; + + @Autowired + private TaskCollectionResource activitiTaskResource; + + @Autowired + private TaskService taskService; + + @RequestMapping(value = "/mytasks", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @Secured(AuthoritiesConstants.USER) + @Timed + public ResponseEntity getMyTasks(Principal user, + @RequestParam Map params) { + + String username = SecurityUtils.getCurrentUserLogin(); + + List list = taskService.createTaskQuery() + .taskAssignee(username).list(); + + DataResponse response = new DataResponse(); + response.setStart(0); + response.setSize(list.size()); + response.setTotal(list.size()); + response.setData(list); + + return ResponseEntity.ok(response); + } + + @RequestMapping(value = "/mytasksavailable", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @Secured(AuthoritiesConstants.USER) + @Timed + public ResponseEntity getMyTasksAvailable( + @RequestParam Map params) { + + String username = SecurityUtils.getCurrentUserLogin(); + + List list = taskService.createTaskQuery() + .taskCandidateUser(username).list(); + + DataResponse response = new DataResponse(); + response.setStart(0); + response.setSize(list.size()); + response.setTotal(list.size()); + response.setData(list); + + return ResponseEntity.ok(response); + } + + @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @Timed + public ResponseEntity> getTaskInstance( + HttpServletRequest req, + @PathVariable("id") String id, + @RequestParam Map params) { + + return null; +// long taskId = extractId(id); +// +// Task task = taskService.createTaskQuery().taskId(""+taskId).singleResult(); +// List tasks = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); +// ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); +// +// List> tasksMaps = tasks.stream().map(t -> mappaTaskInMap(t)).collect(Collectors.toList()); +// +// Map result = new HashMap<>(); +// Map definition = new HashMap<>(); +// definition.put("id", "cnrdsftm:validaTask"); +// +// Map mappaTaskInMap = mappaTaskInMap(task); +// ((Map) mappaTaskInMap.get("entry")).put("tasks", tasksMaps); +// ((Map) mappaTaskInMap.get("entry")).put("workflowInstance", mappaProcessInstanceInMap(pi)); +// ((Map) mappaTaskInMap.get("entry")).put("definition", definition); +// +// +// result.put("data", mappaTaskInMap.get("entry")); +// +// +// return new ResponseEntity>(result, HttpStatus.OK); + +// // TODO verificare se ci possono essere parametri aggiuntivi utili// boolean detailed = Boolean.parseBoolean(params.get("detailed")); +// long taskId = Utils.extractId(id); +// CMISUser user = cmisService.getCMISUserFromSession(req); +// BindingSession session = cmisService.getCurrentBindingSession(req); +// +// try { +// Map taskInstance = flowsTaskService.getTask(user, session, taskId, detailed); +// return new ResponseEntity>(taskInstance, HttpStatus.OK); +// } catch (PermissionException e) { +// LOGGER.error(e.getMessage(), e); +// return new ResponseEntity>(HttpStatus.FORBIDDEN); +// } catch (IOException e) { +// Map response = new HashMap<>(); +// response.put("error", e.getMessage()); +// return new ResponseEntity>(response, HttpStatus.INTERNAL_SERVER_ERROR); +// } + } + + /** + * Questo metodo serve per assegnare un taskInstance a un'utente o rilasciare il task al pool + * + * TODO Considerare la possibilità di modificare nome e signature Map-data in String-username + * + * @param req + * @param id + * @param params + * @return + */ + // TODO rifattorizzare, il parametro data è confusionario + @RequestMapping(value = "/claim/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) + @Timed + public ResponseEntity> claimTask( + HttpServletRequest req, + @PathVariable("id") String id) { + + return null; +// CMISUser user = cmisService.getCMISUserFromSession(req); +// BindingSession session = cmisService.getCurrentBindingSession(req); +// String cm_owner = user.getUserName(); +// long taskId = Utils.extractId(id); +// +// LOGGER.info("Setting owner of task "+ id +" to "+ cm_owner); +// +// try { +// Map taskInstance = flowsTaskService.claimTask(user, session, taskId); +// +// return new ResponseEntity>(taskInstance, HttpStatus.OK); +// } catch (IOException e) { +// Map response = new HashMap<>(); +// response.put("error", e.getMessage()); +// return new ResponseEntity>(response, HttpStatus.INTERNAL_SERVER_ERROR); +// } + } + + @RequestMapping(value = "/unclaim/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) + @Timed + public ResponseEntity> unclaimTask( + HttpServletRequest req, + @PathVariable("id") String id) { + + return null; +// CMISUser user = cmisService.getCMISUserFromSession(req); +// BindingSession session = cmisService.getCurrentBindingSession(req); +// long taskId = Utils.extractId(id); +// +// LOGGER.info("Unsetting owner of task "+ id); +// +// try { +// Map task = flowsTaskService.getTask(user, session, taskId, true); +// Map data = (Map) task.get("data"); +// Map owner = (Map) data.get("owner"); +// String ownerName = (String) owner.get("userName"); +// +// if( !user.getUserName().equals(ownerName) ) { +// throw new PermissionException("L'utente può solo rinunciare a un task di cui è owner. Utente che ha fatto la richiesta: "+ user.getUserName() +", owner: "+ ownerName); +// } +// +// Map taskInstance = flowsTaskService.unclaimTask(user, session, taskId); +// +// return new ResponseEntity>(taskInstance, HttpStatus.OK); +// +// } catch (PermissionException e) { +// LOGGER.error(e.getMessage(), e); +// return new ResponseEntity>(HttpStatus.FORBIDDEN); +// } catch (IOException e) { +// Map response = new HashMap<>(); +// response.put("error", e.getMessage()); +// return new ResponseEntity>(response, HttpStatus.INTERNAL_SERVER_ERROR); +// } + } + + @RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) + @Timed + public ResponseEntity> assignTask( + HttpServletRequest req, + @PathVariable("id") String id, + @RequestBody Map data) { + + return null; +// CMISUser user = cmisService.getCMISUserFromSession(req); +// BindingSession session = cmisService.getCurrentBindingSession(req); +// String cm_owner = (String) data.get("cm_owner"); +// long taskId = Utils.extractId(id); +// +// LOGGER.info("Setting owner of task "+ id +" to "+ cm_owner); +// +// try { +// Map taskInstance = flowsTaskService.setTaskOwner(user, session, taskId, data); +// +// return new ResponseEntity>(taskInstance, HttpStatus.OK); +// } catch (PermissionException e) { +// LOGGER.error(e.getMessage(), e); +// return new ResponseEntity>(HttpStatus.FORBIDDEN); +// } catch (IOException e) { +// Map response = new HashMap<>(); +// response.put("error", e.getMessage()); +// return new ResponseEntity>(response, HttpStatus.INTERNAL_SERVER_ERROR); +// } + } + + // TODO returns ResponseEntity> + @RequestMapping(value = "variables/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @Timed + public ResponseEntity> getTaskVariables( + HttpServletRequest req, + HttpServletResponse resp, + @PathVariable("id") String id) + throws IOException { + + Map result = new HashMap<>(); + Map list = new HashMap<>(); + List> entries = new ArrayList<>(); + + result.put("list", list); + list.put("entries", entries); + +// taskService.getVariables(id); + + return new ResponseEntity>(result, HttpStatus.OK); + +// CMISUser user = cmisService.getCMISUserFromSession(req); +// LOGGER.debug("getTaskVariables user: "+ user +", id: "+id); +// +// try { +// Map workflowVariables = workflowService.getTaskVariables(user, id); +// JSONObject res = new JSONObject(workflowVariables); +// PrintWriter writer = resp.getWriter(); +// writer.write(res.toString()); +// writer.flush(); +// // return new ResponseEntity>(workflowVariables, HttpStatus.OK); +// } catch (IllegalAccessException e) { +// LOGGER.info(ERRORE_PERMESSI_TASK); +// LOGGER.info("L'utente ha richiesto variabili per un flusso che non deve poter vedere", e); +// getVariablesOldMethod(req, resp, id); +// // return new ResponseEntity>(HttpStatus.FORBIDDEN);// ;resp.sendError(HttpServletResponse.SC_FORBIDDEN); +// } catch (WorkflowException e) { +// LOGGER.info("Errore durante il recupero di un flusso", e); +// resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); +// // return new ResponseEntity>(HttpStatus.INTERNAL_SERVER_ERROR);//resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); +// } + } + + @RequestMapping(value = "complete/{id}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + @Timed + public ResponseEntity> completeTask( + HttpServletRequest req, + @PathVariable("id") String id, + @RequestBody Map data) { + + taskService.complete(id); + + return new ResponseEntity>(HttpStatus.OK); + +// CMISUser user = cmisService.getCMISUserFromSession(req); +// BindingSession session = cmisService.getCurrentBindingSession(req); +// boolean userHasWriteAccessToTask = true; // TODO +// +// if (userHasWriteAccessToTask) { +// try { +// workflowService.completeTask(user, id, data, session); +// } catch (AlfrescoResponseException e) { +// LOGGER.error(e.getMessage() + " " + e.getResponse(), e); +// return new ResponseEntity>(e.getResponse(), HttpStatus.INTERNAL_SERVER_ERROR); +// } catch (PermissionException e) { +// LOGGER.error(e.getMessage(), e); +// return new ResponseEntity>(HttpStatus.FORBIDDEN); +// } catch (IOException e) { +// LOGGER.error(e.getMessage(), e); +// Map response = new HashMap<>(); +// response.put("error", e.getMessage()); +// return new ResponseEntity>(response, HttpStatus.INTERNAL_SERVER_ERROR); +// } +// } +// +// return null; + } + + public static long extractId(String id) throws IllegalArgumentException { + try { + if (id.contains("$")) + id = id.split("\\$")[1]; + return Long.parseLong(id); + + } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { + throw new IllegalArgumentException("L'id dato non è valido", e); + } + } +} diff --git a/src/main/java/it/cnr/si/flows/ng/resource/ProcessDefinitionResource.java b/src/main/java/it/cnr/si/flows/ng/resource/ProcessDefinitionResource.java new file mode 100644 index 000000000..eb3035f5b --- /dev/null +++ b/src/main/java/it/cnr/si/flows/ng/resource/ProcessDefinitionResource.java @@ -0,0 +1,72 @@ +package it.cnr.si.flows.ng.resource; + +import java.util.List; + +import org.activiti.engine.RepositoryService; +import org.activiti.engine.RuntimeService; +import org.activiti.engine.repository.ProcessDefinition; +import org.activiti.rest.common.api.DataResponse; +import org.activiti.rest.service.api.RestResponseFactory; +import org.activiti.rest.service.api.repository.ProcessDefinitionResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.codahale.metrics.annotation.Timed; + +import it.cnr.si.security.AuthoritiesConstants; + +@RestController +@RequestMapping("rest/processdefinitions") +public class ProcessDefinitionResource { + + @Autowired + private RuntimeService runtimeService; + + @Autowired + private RepositoryService repositoryService; + + @Autowired + protected RestResponseFactory restResponseFactory; + + @RequestMapping(value = "/all", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @Secured(AuthoritiesConstants.USER) + @Timed + public Object getAllProcessDefinitions() { + + List listraw = repositoryService.createProcessDefinitionQuery().latestVersion().list(); + + List list = restResponseFactory.createProcessDefinitionResponseList(listraw); + + // Get result and set pagination parameters + DataResponse response = new DataResponse(); + response.setStart(0); + response.setSize(list.size()); + response.setTotal(list.size()); + response.setData(list); + return response; + + + } + + @RequestMapping(value = "/{key}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @Secured(AuthoritiesConstants.USER) + @Timed + public ResponseEntity getProcessDefinitionById(@PathVariable String key) { + + ProcessDefinition definitionraw = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).latestVersion().singleResult(); + + if (definitionraw != null) { + ProcessDefinitionResponse definition = restResponseFactory.createProcessDefinitionResponse(definitionraw); + return ResponseEntity.ok(definition); + } else { + return ResponseEntity.notFound().build(); + } + } + +} diff --git a/src/main/resources/.h2.server.properties b/src/main/resources/.h2.server.properties new file mode 100644 index 000000000..02906e9dd --- /dev/null +++ b/src/main/resources/.h2.server.properties @@ -0,0 +1,5 @@ +#H2 Server Properties +0=JHipster H2 (Memory)|org.h2.Driver|jdbc\:h2\:mem\:sprint|sprint +webAllowOthers=true +webPort=8082 +webSSL=false diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 000000000..1e0423130 --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,9 @@ + + ${AnsiColor.GREEN} ██ ${AnsiColor.RED} ██ ██ ████████ ███████ ██████ ████████ ████████ ███████ + ${AnsiColor.GREEN} ██ ${AnsiColor.RED} ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ + ${AnsiColor.GREEN} ██ ${AnsiColor.RED} ████████ ██ ███████ █████ ██ ██████ ███████ + ${AnsiColor.GREEN}██ ██ ${AnsiColor.RED} ██ ██ ██ ██ ██ ██ ██ ██ ██ + ${AnsiColor.GREEN} ██████ ${AnsiColor.RED} ██ ██ ████████ ██ ██████ ██ ████████ ██ ██ + +${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} :: +:: http://jhipster.github.io ::${AnsiColor.DEFAULT} diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties new file mode 100644 index 000000000..e3b893486 --- /dev/null +++ b/src/main/resources/i18n/messages.properties @@ -0,0 +1,22 @@ +# Error page +error.title=Your request cannot be processed +error.subtitle=Sorry, an error has occurred. +error.status=Status: +error.message=Message: + +# Activation e-mail +email.activation.title=sprint account activation +email.activation.greeting=Dear {0} +email.activation.text1=Your sprint account has been created, please click on the URL below to activate it: +email.activation.text2=Regards, +email.signature=sprint Team. + +# Creation email +email.creation.text1=Your sprint account has been created, please click on the URL below to access it: + +# Reset e-mail +email.reset.title=sprint password reset +email.reset.greeting=Dear {0} +email.reset.text1=For your sprint account a password reset was requested, please click on the URL below to reset it: +email.reset.text2=Regards, + diff --git a/src/main/resources/i18n/messages_it.properties b/src/main/resources/i18n/messages_it.properties new file mode 100644 index 000000000..ca0c2bd27 --- /dev/null +++ b/src/main/resources/i18n/messages_it.properties @@ -0,0 +1,22 @@ +# Error page +error.title=La tua richiesta non può essere processata +error.subtitle= E' stato riscontrato un errore. +error.status=Stato: +error.message=Messaggio: + +# Activation e-mail +email.activation.title=sprint attivazione +email.activation.greeting=Caro {0} +email.activation.text1=Il tuo account sprint è stato creato, clicca sul link qui sotto per attivare: +email.activation.text2=Saluti, +email.signature=sprint. + +# Creation email +email.creation.text1=L'account sprint è stato attivato, clicca sul link qui sotto per accedere: + +# Reset e-mail +email.reset.title=sprint reimpostazione della password +email.reset.greeting=Caro {0} +email.reset.text1=E' stata richiesta una reimpostazione della password per il tuo account sprint, clicca sul seguente URL per ripristinarlo: +email.reset.text2=Saluti, + diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 000000000..3d3661faf --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + diff --git a/src/main/resources/processes/PermessiFerieProcess.bpmn20.xml b/src/main/resources/processes/PermessiFerieProcess.bpmn20.xml new file mode 100644 index 000000000..66a4ded17 --- /dev/null +++ b/src/main/resources/processes/PermessiFerieProcess.bpmn20.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/processes/hire.bpmn20.xml b/src/main/resources/processes/hire.bpmn20.xml new file mode 100644 index 000000000..b34d6ad70 --- /dev/null +++ b/src/main/resources/processes/hire.bpmn20.xml @@ -0,0 +1,229 @@ + + + + + + Conduct a telephone interview with ${applicantName}. Phone number = ${phoneNumber} + + + + + + + + + ${email} + + + test@activiti.org + + + + + + Dear ${applicantName}, + +We're sorry to inform you that your recent application has been rejected. We have stored your information in our data systems and will contact you if in the future a potential matching application is posted on our website. + +Regards, +My Corp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${email} + + + test@activiti.org + + + + + + Dear ${applicantName}, + +We're happy to inform you that your recent application has been accepted. We will contact you soon for more information. + +Regards, +My Corp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/.gitignore b/src/main/webapp/.gitignore new file mode 100644 index 000000000..fbe05fc93 --- /dev/null +++ b/src/main/webapp/.gitignore @@ -0,0 +1 @@ +bower_components/ diff --git a/src/main/webapp/404.html b/src/main/webapp/404.html new file mode 100644 index 000000000..0a55b15b6 --- /dev/null +++ b/src/main/webapp/404.html @@ -0,0 +1,60 @@ + + + + + Page Not Found + + + + +

Page Not Found

+

Sorry, but the page you were trying to view does not exist.

+ + + diff --git a/src/main/webapp/app/account/account.state.js b/src/main/webapp/app/account/account.state.js new file mode 100644 index 000000000..bb08a7a11 --- /dev/null +++ b/src/main/webapp/app/account/account.state.js @@ -0,0 +1,16 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('account', { + abstract: true, + parent: 'app' + }); + } +})(); diff --git a/src/main/webapp/app/account/activate/activate.controller.js b/src/main/webapp/app/account/activate/activate.controller.js new file mode 100644 index 000000000..84a893ab1 --- /dev/null +++ b/src/main/webapp/app/account/activate/activate.controller.js @@ -0,0 +1,23 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('ActivationController', ActivationController); + + ActivationController.$inject = ['$stateParams', 'Auth', 'LoginService']; + + function ActivationController ($stateParams, Auth, LoginService) { + var vm = this; + + Auth.activateAccount({key: $stateParams.key}).then(function () { + vm.error = null; + vm.success = 'OK'; + }).catch(function () { + vm.success = null; + vm.error = 'ERROR'; + }); + + vm.login = LoginService.open; + } +})(); diff --git a/src/main/webapp/app/account/activate/activate.html b/src/main/webapp/app/account/activate/activate.html new file mode 100644 index 000000000..dd5779d3e --- /dev/null +++ b/src/main/webapp/app/account/activate/activate.html @@ -0,0 +1,16 @@ +
+
+
+

Activation

+ +
+ Your user has been activated. Please sign in. +
+ +
+ Your user could not be activated. Please use the registration form to sign up. +
+ +
+
+
diff --git a/src/main/webapp/app/account/activate/activate.state.js b/src/main/webapp/app/account/activate/activate.state.js new file mode 100644 index 000000000..90cfa8135 --- /dev/null +++ b/src/main/webapp/app/account/activate/activate.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('activate', { + parent: 'account', + url: '/activate?key', + data: { + authorities: [], + pageTitle: 'activate.title' + }, + views: { + 'content@': { + templateUrl: 'app/account/activate/activate.html', + controller: 'ActivationController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('activate'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/account/password/password-strength-bar.directive.js b/src/main/webapp/app/account/password/password-strength-bar.directive.js new file mode 100644 index 000000000..f9f7f5b78 --- /dev/null +++ b/src/main/webapp/app/account/password/password-strength-bar.directive.js @@ -0,0 +1,95 @@ +/* globals $ */ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .directive('passwordStrengthBar', passwordStrengthBar); + + function passwordStrengthBar () { + var directive = { + replace: true, + restrict: 'E', + template: '
' + + 'Password strength:' + + '
    ' + + '
  • ' + + '
' + + '
', + scope: { + passwordToCheck: '=' + }, + link: linkFunc + }; + + return directive; + + /* private helper methods*/ + + function linkFunc(scope, iElement) { + var strength = { + colors: ['#F00', '#F90', '#FF0', '#9F0', '#0F0'], + mesureStrength: function (p) { + + var _force = 0; + var _regex = /[$-/:-?{-~!"^_`\[\]]/g; // " + + var _lowerLetters = /[a-z]+/.test(p); + var _upperLetters = /[A-Z]+/.test(p); + var _numbers = /[0-9]+/.test(p); + var _symbols = _regex.test(p); + + var _flags = [_lowerLetters, _upperLetters, _numbers, _symbols]; + var _passedMatches = $.grep(_flags, function (el) { + return el === true; + }).length; + + _force += 2 * p.length + ((p.length >= 10) ? 1 : 0); + _force += _passedMatches * 10; + + // penality (short password) + _force = (p.length <= 6) ? Math.min(_force, 10) : _force; + + // penality (poor variety of characters) + _force = (_passedMatches === 1) ? Math.min(_force, 10) : _force; + _force = (_passedMatches === 2) ? Math.min(_force, 20) : _force; + _force = (_passedMatches === 3) ? Math.min(_force, 40) : _force; + + return _force; + + }, + getColor: function (s) { + + var idx = 0; + if (s <= 10) { + idx = 0; + } + else if (s <= 20) { + idx = 1; + } + else if (s <= 30) { + idx = 2; + } + else if (s <= 40) { + idx = 3; + } + else { + idx = 4; + } + + return { idx: idx + 1, col: this.colors[idx] }; + } + }; + scope.$watch('passwordToCheck', function (password) { + if (password) { + var c = strength.getColor(strength.mesureStrength(password)); + iElement.removeClass('ng-hide'); + iElement.find('ul').children('li') + .css({ 'background-color': '#DDD' }) + .slice(0, c.idx) + .css({ 'background-color': c.col }); + } + }); + } + } +})(); diff --git a/src/main/webapp/app/account/password/password.controller.js b/src/main/webapp/app/account/password/password.controller.js new file mode 100644 index 000000000..f29bb338e --- /dev/null +++ b/src/main/webapp/app/account/password/password.controller.js @@ -0,0 +1,39 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('PasswordController', PasswordController); + + PasswordController.$inject = ['Auth', 'Principal']; + + function PasswordController (Auth, Principal) { + var vm = this; + + vm.changePassword = changePassword; + vm.doNotMatch = null; + vm.error = null; + vm.success = null; + + Principal.identity().then(function(account) { + vm.account = account; + }); + + function changePassword () { + if (vm.password !== vm.confirmPassword) { + vm.error = null; + vm.success = null; + vm.doNotMatch = 'ERROR'; + } else { + vm.doNotMatch = null; + Auth.changePassword(vm.password).then(function () { + vm.error = null; + vm.success = 'OK'; + }).catch(function () { + vm.success = null; + vm.error = 'ERROR'; + }); + } + } + } +})(); diff --git a/src/main/webapp/app/account/password/password.html b/src/main/webapp/app/account/password/password.html new file mode 100644 index 000000000..da400acb5 --- /dev/null +++ b/src/main/webapp/app/account/password/password.html @@ -0,0 +1,63 @@ +
+
+
+

Password for [{{vm.account.login}}]

+ +
+ Password changed! +
+
+ An error has occurred! The password could not be changed. +
+ +
+ The password and its confirmation do not match! +
+ +
+ +
+ + +
+

+ Your password is required. +

+

+ Your password is required to be at least 4 characters. +

+

+ Your password cannot be longer than 50 characters. +

+
+ +
+
+ + +
+

+ Your confirmation password is required. +

+

+ Your confirmation password is required to be at least 4 characters. +

+

+ Your confirmation password cannot be longer than 50 characters. +

+
+
+ + +
+
+
+
diff --git a/src/main/webapp/app/account/password/password.state.js b/src/main/webapp/app/account/password/password.state.js new file mode 100644 index 000000000..d5d92450c --- /dev/null +++ b/src/main/webapp/app/account/password/password.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('password', { + parent: 'account', + url: '/password', + data: { + authorities: ['ROLE_USER'], + pageTitle: 'global.menu.account.password' + }, + views: { + 'content@': { + templateUrl: 'app/account/password/password.html', + controller: 'PasswordController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('password'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/account/register/register.controller.js b/src/main/webapp/app/account/register/register.controller.js new file mode 100644 index 000000000..dd2445ddc --- /dev/null +++ b/src/main/webapp/app/account/register/register.controller.js @@ -0,0 +1,49 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('RegisterController', RegisterController); + + + RegisterController.$inject = ['$translate', '$timeout', 'Auth', 'LoginService']; + + function RegisterController ($translate, $timeout, Auth, LoginService) { + var vm = this; + + vm.doNotMatch = null; + vm.error = null; + vm.errorUserExists = null; + vm.login = LoginService.open; + vm.register = register; + vm.registerAccount = {}; + vm.success = null; + + $timeout(function (){angular.element('#login').focus();}); + + function register () { + if (vm.registerAccount.password !== vm.confirmPassword) { + vm.doNotMatch = 'ERROR'; + } else { + vm.registerAccount.langKey = $translate.use(); + vm.doNotMatch = null; + vm.error = null; + vm.errorUserExists = null; + vm.errorEmailExists = null; + + Auth.createAccount(vm.registerAccount).then(function () { + vm.success = 'OK'; + }).catch(function (response) { + vm.success = null; + if (response.status === 400 && response.data === 'login already in use') { + vm.errorUserExists = 'ERROR'; + } else if (response.status === 400 && response.data === 'e-mail address already in use') { + vm.errorEmailExists = 'ERROR'; + } else { + vm.error = 'ERROR'; + } + }); + } + } + } +})(); diff --git a/src/main/webapp/app/account/register/register.html b/src/main/webapp/app/account/register/register.html new file mode 100644 index 000000000..b98190603 --- /dev/null +++ b/src/main/webapp/app/account/register/register.html @@ -0,0 +1,123 @@ +
+
+
+

Registration

+ +
+ Registration saved! Please check your email for confirmation. +
+ +
+ Registration failed! Please try again later. +
+ +
+ Login name already registered! Please choose another one. +
+ +
+ E-mail is already in use! Please choose another one. +
+ +
+ The password and its confirmation do not match! +
+
+
+
+ +
+ + +
+

+ Your username is required. +

+

+ Your username is required to be at least 1 character. +

+

+ Your username cannot be longer than 50 characters. +

+

+ Your username can only contain lower-case letters and digits. +

+
+
+
+ + +
+

+ Your e-mail is required. +

+

+ Your e-mail is invalid. +

+

+ Your e-mail is required to be at least 5 characters. +

+

+ Your e-mail cannot be longer than 100 characters. +

+
+
+
+ + +
+

+ Your password is required. +

+

+ Your password is required to be at least 4 characters. +

+

+ Your password cannot be longer than 50 characters. +

+
+ +
+
+ + +
+

+ Your confirmation password is required. +

+

+ Your confirmation password is required to be at least 4 characters. +

+

+ Your confirmation password cannot be longer than 50 characters. +

+
+
+ + +
+

+
+ If you want to sign in, you can try the default accounts:
- Administrator (login="admin" and password="admin")
- User (login="user" and password="user"). +
+
+
+
diff --git a/src/main/webapp/app/account/register/register.state.js b/src/main/webapp/app/account/register/register.state.js new file mode 100644 index 000000000..c5b916595 --- /dev/null +++ b/src/main/webapp/app/account/register/register.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('register', { + parent: 'account', + url: '/register', + data: { + authorities: [], + pageTitle: 'register.title' + }, + views: { + 'content@': { + templateUrl: 'app/account/register/register.html', + controller: 'RegisterController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('register'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/account/reset/finish/reset.finish.controller.js b/src/main/webapp/app/account/reset/finish/reset.finish.controller.js new file mode 100644 index 000000000..2395a63dc --- /dev/null +++ b/src/main/webapp/app/account/reset/finish/reset.finish.controller.js @@ -0,0 +1,39 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('ResetFinishController', ResetFinishController); + + ResetFinishController.$inject = ['$stateParams', '$timeout', 'Auth', 'LoginService']; + + function ResetFinishController ($stateParams, $timeout, Auth, LoginService) { + var vm = this; + + vm.keyMissing = angular.isUndefined($stateParams.key); + vm.confirmPassword = null; + vm.doNotMatch = null; + vm.error = null; + vm.finishReset = finishReset; + vm.login = LoginService.open; + vm.resetAccount = {}; + vm.success = null; + + $timeout(function (){angular.element('#password').focus();}); + + function finishReset() { + vm.doNotMatch = null; + vm.error = null; + if (vm.resetAccount.password !== vm.confirmPassword) { + vm.doNotMatch = 'ERROR'; + } else { + Auth.resetPasswordFinish({key: $stateParams.key, newPassword: vm.resetAccount.password}).then(function () { + vm.success = 'OK'; + }).catch(function () { + vm.success = null; + vm.error = 'ERROR'; + }); + } + } + } +})(); diff --git a/src/main/webapp/app/account/reset/finish/reset.finish.html b/src/main/webapp/app/account/reset/finish/reset.finish.html new file mode 100644 index 000000000..2c45df7d6 --- /dev/null +++ b/src/main/webapp/app/account/reset/finish/reset.finish.html @@ -0,0 +1,74 @@ +
+
+
+

Reset password

+ +
+ The password reset key is missing. +
+ +
+

Choose a new password

+
+ +
+

Your password couldn't be reset. Remember a password request is only valid for 24 hours.

+
+ +
+

Your password has been reset. Please sign in.

+
+ +
+ The password and its confirmation do not match! +
+ +
+
+
+ + +
+

+ Your password is required. +

+

+ Your password is required to be at least 4 characters. +

+

+ Your password cannot be longer than 50 characters. +

+
+ +
+ +
+ + +
+

+ Your password confirmation is required. +

+

+ Your password confirmation is required to be at least 4 characters. +

+

+ Your password confirmation cannot be longer than 50 characters. +

+
+
+ +
+
+ +
+
+
diff --git a/src/main/webapp/app/account/reset/finish/reset.finish.state.js b/src/main/webapp/app/account/reset/finish/reset.finish.state.js new file mode 100644 index 000000000..84303432f --- /dev/null +++ b/src/main/webapp/app/account/reset/finish/reset.finish.state.js @@ -0,0 +1,32 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('finishReset', { + parent: 'account', + url: '/reset/finish?key', + data: { + authorities: [] + }, + views: { + 'content@': { + templateUrl: 'app/account/reset/finish/reset.finish.html', + controller: 'ResetFinishController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('reset'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/account/reset/request/reset.request.controller.js b/src/main/webapp/app/account/reset/request/reset.request.controller.js new file mode 100644 index 000000000..e29abda5f --- /dev/null +++ b/src/main/webapp/app/account/reset/request/reset.request.controller.js @@ -0,0 +1,38 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('RequestResetController', RequestResetController); + + RequestResetController.$inject = ['$timeout', 'Auth']; + + function RequestResetController ($timeout, Auth) { + var vm = this; + + vm.error = null; + vm.errorEmailNotExists = null; + vm.requestReset = requestReset; + vm.resetAccount = {}; + vm.success = null; + + $timeout(function (){angular.element('#email').focus();}); + + function requestReset () { + + vm.error = null; + vm.errorEmailNotExists = null; + + Auth.resetPasswordInit(vm.resetAccount.email).then(function () { + vm.success = 'OK'; + }).catch(function (response) { + vm.success = null; + if (response.status === 400 && response.data === 'e-mail address not registered') { + vm.errorEmailNotExists = 'ERROR'; + } else { + vm.error = 'ERROR'; + } + }); + } + } +})(); diff --git a/src/main/webapp/app/account/reset/request/reset.request.html b/src/main/webapp/app/account/reset/request/reset.request.html new file mode 100644 index 000000000..95a5c6258 --- /dev/null +++ b/src/main/webapp/app/account/reset/request/reset.request.html @@ -0,0 +1,47 @@ +
+
+
+

Reset your password

+ +
+ E-Mail address isn't registered! Please check and try again. +
+ +
+

Enter the e-mail address you used to register.

+
+ +
+

Check your e-mails for details on how to reset your password.

+
+ +
+
+ + +
+

+ Your e-mail is required. +

+

+ Your e-mail is invalid. +

+

+ Your e-mail is required to be at least 5 characters. +

+

+ Your e-mail cannot be longer than 100 characters. +

+
+
+ +
+ +
+
+
diff --git a/src/main/webapp/app/account/reset/request/reset.request.state.js b/src/main/webapp/app/account/reset/request/reset.request.state.js new file mode 100644 index 000000000..1d587a9aa --- /dev/null +++ b/src/main/webapp/app/account/reset/request/reset.request.state.js @@ -0,0 +1,32 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('requestReset', { + parent: 'account', + url: '/reset/request', + data: { + authorities: [] + }, + views: { + 'content@': { + templateUrl: 'app/account/reset/request/reset.request.html', + controller: 'RequestResetController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('reset'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/account/settings/settings.controller.js b/src/main/webapp/app/account/settings/settings.controller.js new file mode 100644 index 000000000..64f0c80fe --- /dev/null +++ b/src/main/webapp/app/account/settings/settings.controller.js @@ -0,0 +1,54 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('SettingsController', SettingsController); + + SettingsController.$inject = ['Principal', 'Auth', 'JhiLanguageService', '$translate']; + + function SettingsController (Principal, Auth, JhiLanguageService, $translate) { + var vm = this; + + vm.error = null; + vm.save = save; + vm.settingsAccount = null; + vm.success = null; + + /** + * Store the "settings account" in a separate variable, and not in the shared "account" variable. + */ + var copyAccount = function (account) { + return { + activated: account.activated, + email: account.email, + firstName: account.firstName, + langKey: account.langKey, + lastName: account.lastName, + login: account.login + }; + }; + + Principal.identity().then(function(account) { + vm.settingsAccount = copyAccount(account); + }); + + function save () { + Auth.updateAccount(vm.settingsAccount).then(function() { + vm.error = null; + vm.success = 'OK'; + Principal.identity(true).then(function(account) { + vm.settingsAccount = copyAccount(account); + }); + JhiLanguageService.getCurrent().then(function(current) { + if (vm.settingsAccount.langKey !== current) { + $translate.use(vm.settingsAccount.langKey); + } + }); + }).catch(function() { + vm.success = null; + vm.error = 'ERROR'; + }); + } + } +})(); diff --git a/src/main/webapp/app/account/settings/settings.html b/src/main/webapp/app/account/settings/settings.html new file mode 100644 index 000000000..1e9c5daf0 --- /dev/null +++ b/src/main/webapp/app/account/settings/settings.html @@ -0,0 +1,85 @@ +
+
+
+

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

+ +
+ Settings saved! +
+ + + +
+ +
+ + +
+

+ Your first name is required. +

+

+ Your first name is required to be at least 1 character. +

+

+ Your first name cannot be longer than 50 characters. +

+
+
+
+ + +
+

+ Your last name is required. +

+

+ Your last name is required to be at least 1 character. +

+

+ Your last name cannot be longer than 50 characters. +

+
+
+
+ + +
+

+ Your e-mail is required. +

+

+ Your e-mail is invalid. +

+

+ Your e-mail is required to be at least 5 characters. +

+

+ Your e-mail cannot be longer than 100 characters. +

+
+
+
+ + +
+ + +
+
+
+ +
diff --git a/src/main/webapp/app/account/settings/settings.state.js b/src/main/webapp/app/account/settings/settings.state.js new file mode 100644 index 000000000..388b29451 --- /dev/null +++ b/src/main/webapp/app/account/settings/settings.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('settings', { + parent: 'account', + url: '/settings', + data: { + authorities: ['ROLE_USER'], + pageTitle: 'global.menu.account.settings' + }, + views: { + 'content@': { + templateUrl: 'app/account/settings/settings.html', + controller: 'SettingsController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('settings'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/admin.state.js b/src/main/webapp/app/admin/admin.state.js new file mode 100644 index 000000000..5d413ff85 --- /dev/null +++ b/src/main/webapp/app/admin/admin.state.js @@ -0,0 +1,16 @@ +(function () { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig ($stateProvider) { + $stateProvider.state('admin', { + abstract: true, + parent: 'app' + }); + } +})(); diff --git a/src/main/webapp/app/admin/audits/audits.controller.js b/src/main/webapp/app/admin/audits/audits.controller.js new file mode 100644 index 000000000..8fd80e499 --- /dev/null +++ b/src/main/webapp/app/admin/audits/audits.controller.js @@ -0,0 +1,63 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('AuditsController', AuditsController); + + AuditsController.$inject = ['$filter', 'AuditsService', 'ParseLinks']; + + function AuditsController ($filter, AuditsService, ParseLinks) { + var vm = this; + + vm.audits = null; + vm.fromDate = null; + vm.links = null; + vm.loadPage = loadPage; + vm.onChangeDate = onChangeDate; + vm.page = 1; + vm.previousMonth = previousMonth; + vm.toDate = null; + vm.today = today; + vm.totalItems = null; + + vm.today(); + vm.previousMonth(); + vm.onChangeDate(); + + function onChangeDate () { + var dateFormat = 'yyyy-MM-dd'; + var fromDate = $filter('date')(vm.fromDate, dateFormat); + var toDate = $filter('date')(vm.toDate, dateFormat); + + AuditsService.query({page: vm.page -1, size: 20, fromDate: fromDate, toDate: toDate}, function(result, headers){ + vm.audits = result; + vm.links = ParseLinks.parse(headers('link')); + vm.totalItems = headers('X-Total-Count'); + }); + } + + // Date picker configuration + function today () { + // Today + 1 day - needed if the current day must be included + var today = new Date(); + vm.toDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1); + } + + function previousMonth () { + var fromDate = new Date(); + if (fromDate.getMonth() === 0) { + fromDate = new Date(fromDate.getFullYear() - 1, 11, fromDate.getDate()); + } else { + fromDate = new Date(fromDate.getFullYear(), fromDate.getMonth() - 1, fromDate.getDate()); + } + + vm.fromDate = fromDate; + } + + function loadPage (page) { + vm.page = page; + vm.onChangeDate(); + } + } +})(); diff --git a/src/main/webapp/app/admin/audits/audits.html b/src/main/webapp/app/admin/audits/audits.html new file mode 100644 index 000000000..7aa778bb7 --- /dev/null +++ b/src/main/webapp/app/admin/audits/audits.html @@ -0,0 +1,41 @@ +
+

Audits

+ +
+
+

Filter by date

+

+ from + + to + +

+
+
+ + + + + + + + + + + + + + + + + + +
DateUserStateExtra data
{{audit.timestamp| date:'medium'}}{{audit.principal}}{{audit.type}} + {{audit.data.message}} + Remote Address {{audit.data.remoteAddress}} +
+ +
+ +
+
diff --git a/src/main/webapp/app/admin/audits/audits.service.js b/src/main/webapp/app/admin/audits/audits.service.js new file mode 100644 index 000000000..96b46d1ad --- /dev/null +++ b/src/main/webapp/app/admin/audits/audits.service.js @@ -0,0 +1,25 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('AuditsService', AuditsService); + + AuditsService.$inject = ['$resource']; + + function AuditsService ($resource) { + var service = $resource('management/jhipster/audits/:id', {}, { + 'get': { + method: 'GET', + isArray: true + }, + 'query': { + method: 'GET', + isArray: true, + params: {fromDate: null, toDate: null} + } + }); + + return service; + } +})(); diff --git a/src/main/webapp/app/admin/audits/audits.state.js b/src/main/webapp/app/admin/audits/audits.state.js new file mode 100644 index 000000000..4dbbdfdf7 --- /dev/null +++ b/src/main/webapp/app/admin/audits/audits.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('audits', { + parent: 'admin', + url: '/audits', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'audits.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/audits/audits.html', + controller: 'AuditsController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('audits'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/configuration/configuration.controller.js b/src/main/webapp/app/admin/configuration/configuration.controller.js new file mode 100644 index 000000000..1e4d7d928 --- /dev/null +++ b/src/main/webapp/app/admin/configuration/configuration.controller.js @@ -0,0 +1,23 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('JhiConfigurationController', JhiConfigurationController); + + JhiConfigurationController.$inject = ['$filter','JhiConfigurationService']; + + function JhiConfigurationController (filter,JhiConfigurationService) { + var vm = this; + + vm.allConfiguration = null; + vm.configuration = null; + + JhiConfigurationService.get().then(function(configuration) { + vm.configuration = configuration; + }); + JhiConfigurationService.getEnv().then(function (configuration) { + vm.allConfiguration = configuration; + }); + } +})(); diff --git a/src/main/webapp/app/admin/configuration/configuration.html b/src/main/webapp/app/admin/configuration/configuration.html new file mode 100644 index 000000000..705263049 --- /dev/null +++ b/src/main/webapp/app/admin/configuration/configuration.html @@ -0,0 +1,47 @@ +
+

Configuration

+ + Filter (by prefix) + + + + + + + + + + + + + +
PrefixProperties
{{entry.prefix}} +
+
{{key}}
+
+ {{value}} +
+
+
+
+ + + + + + + + + + + + + + +
PropertyValue
{{item.key}} + {{item.val}} +
+
+
diff --git a/src/main/webapp/app/admin/configuration/configuration.service.js b/src/main/webapp/app/admin/configuration/configuration.service.js new file mode 100644 index 000000000..2d1991501 --- /dev/null +++ b/src/main/webapp/app/admin/configuration/configuration.service.js @@ -0,0 +1,47 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('JhiConfigurationService', JhiConfigurationService); + + JhiConfigurationService.$inject = ['$filter', '$http']; + + function JhiConfigurationService ($filter, $http) { + var service = { + get: get, + getEnv: getEnv + }; + + return service; + + function get () { + return $http.get('management/configprops').then(getConfigPropsComplete); + + function getConfigPropsComplete (response) { + var properties = []; + angular.forEach(response.data, function (data) { + properties.push(data); + }); + var orderBy = $filter('orderBy'); + return orderBy(properties, 'prefix'); + } + } + + function getEnv () { + return $http.get('management/env').then(getEnvComplete); + + function getEnvComplete (response) { + var properties = {}; + angular.forEach(response.data, function (val,key) { + var vals = []; + angular.forEach(val, function (v,k) { + vals.push({ key:k, val:v }); + }); + properties[key] = vals; + }); + return properties; + } + } + } +})(); diff --git a/src/main/webapp/app/admin/configuration/configuration.state.js b/src/main/webapp/app/admin/configuration/configuration.state.js new file mode 100644 index 000000000..7c63b7a6e --- /dev/null +++ b/src/main/webapp/app/admin/configuration/configuration.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('jhi-configuration', { + parent: 'admin', + url: '/configuration', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'configuration.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/configuration/configuration.html', + controller: 'JhiConfigurationController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('configuration'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/docs/docs.html b/src/main/webapp/app/admin/docs/docs.html new file mode 100644 index 000000000..24ab028f4 --- /dev/null +++ b/src/main/webapp/app/admin/docs/docs.html @@ -0,0 +1,2 @@ + diff --git a/src/main/webapp/app/admin/docs/docs.state.js b/src/main/webapp/app/admin/docs/docs.state.js new file mode 100644 index 000000000..6fcec93a9 --- /dev/null +++ b/src/main/webapp/app/admin/docs/docs.state.js @@ -0,0 +1,30 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig ($stateProvider) { + $stateProvider.state('docs', { + parent: 'admin', + url: '/docs', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'global.menu.admin.apidocs' + }, + views: { + 'content@': { + templateUrl: 'app/admin/docs/docs.html' + } + }, + resolve: { + translatePartialLoader: ['$translate', function ($translate) { + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/health/health.controller.js b/src/main/webapp/app/admin/health/health.controller.js new file mode 100644 index 000000000..304abe204 --- /dev/null +++ b/src/main/webapp/app/admin/health/health.controller.js @@ -0,0 +1,63 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('JhiHealthCheckController', JhiHealthCheckController); + + JhiHealthCheckController.$inject = ['JhiHealthService', '$uibModal']; + + function JhiHealthCheckController (JhiHealthService, $uibModal) { + var vm = this; + + vm.updatingHealth = true; + vm.getLabelClass = getLabelClass; + vm.refresh = refresh; + vm.showHealth = showHealth; + vm.baseName = JhiHealthService.getBaseName; + vm.subSystemName = JhiHealthService.getSubSystemName; + + vm.refresh(); + + function getLabelClass (statusState) { + if (statusState === 'UP') { + return 'label-success'; + } else { + return 'label-danger'; + } + } + + function refresh () { + vm.updatingHealth = true; + JhiHealthService.checkHealth().then(function (response) { + vm.healthData = JhiHealthService.transformHealthData(response); + vm.updatingHealth = false; + }, function (response) { + vm.healthData = JhiHealthService.transformHealthData(response.data); + vm.updatingHealth = false; + }); + } + + function showHealth (health) { + $uibModal.open({ + templateUrl: 'app/admin/health/health.modal.html', + controller: 'HealthModalController', + controllerAs: 'vm', + size: 'lg', + resolve: { + currentHealth: function() { + return health; + }, + baseName: function() { + return vm.baseName; + }, + subSystemName: function() { + return vm.subSystemName; + } + + } + }); + } + + } +})(); diff --git a/src/main/webapp/app/admin/health/health.html b/src/main/webapp/app/admin/health/health.html new file mode 100644 index 000000000..9040d9ef2 --- /dev/null +++ b/src/main/webapp/app/admin/health/health.html @@ -0,0 +1,34 @@ +
+

Health Checks

+ +

+ +

+ + + + + + + + + + + + + + + + + +
Service NameStatusDetails
{{'health.indicator.' + vm.baseName(health.name) | translate}} {{vm.subSystemName(health.name)}} + + {{'health.status.' + health.status | translate}} + + + + + +
+
diff --git a/src/main/webapp/app/admin/health/health.modal.controller.js b/src/main/webapp/app/admin/health/health.modal.controller.js new file mode 100644 index 000000000..2ab2a2412 --- /dev/null +++ b/src/main/webapp/app/admin/health/health.modal.controller.js @@ -0,0 +1,21 @@ +(function() { + 'use strict'; + + angular.module('sprintApp') + .controller('HealthModalController', HealthModalController); + + HealthModalController.$inject = ['$uibModalInstance', 'currentHealth', 'baseName', 'subSystemName']; + + function HealthModalController ($uibModalInstance, currentHealth, baseName, subSystemName) { + var vm = this; + + vm.cancel = cancel; + vm.currentHealth = currentHealth; + vm.baseName = baseName; + vm.subSystemName = subSystemName; + + function cancel() { + $uibModalInstance.dismiss('cancel'); + } + } +})(); diff --git a/src/main/webapp/app/admin/health/health.modal.html b/src/main/webapp/app/admin/health/health.modal.html new file mode 100644 index 000000000..1b329c2a8 --- /dev/null +++ b/src/main/webapp/app/admin/health/health.modal.html @@ -0,0 +1,34 @@ + + + diff --git a/src/main/webapp/app/admin/health/health.service.js b/src/main/webapp/app/admin/health/health.service.js new file mode 100644 index 000000000..06fa6a3ea --- /dev/null +++ b/src/main/webapp/app/admin/health/health.service.js @@ -0,0 +1,130 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('JhiHealthService', JhiHealthService); + + JhiHealthService.$inject = ['$rootScope', '$http']; + + function JhiHealthService ($rootScope, $http) { + var separator = '.'; + var service = { + checkHealth: checkHealth, + transformHealthData: transformHealthData, + getBaseName: getBaseName, + getSubSystemName: getSubSystemName + }; + + return service; + + function checkHealth () { + return $http.get('management/health').then(function (response) { + return response.data; + }); + } + + function transformHealthData (data) { + var response = []; + flattenHealthData(response, null, data); + return response; + } + + function getBaseName (name) { + if (name) { + var split = name.split('.'); + return split[0]; + } + } + + function getSubSystemName (name) { + if (name) { + var split = name.split('.'); + split.splice(0, 1); + var remainder = split.join('.'); + return remainder ? ' - ' + remainder : ''; + } + } + + /* private methods */ + function flattenHealthData (result, path, data) { + angular.forEach(data, function (value, key) { + if (isHealthObject(value)) { + if (hasSubSystem(value)) { + addHealthObject(result, false, value, getModuleName(path, key)); + flattenHealthData(result, getModuleName(path, key), value); + } else { + addHealthObject(result, true, value, getModuleName(path, key)); + } + } + }); + return result; + } + + function addHealthObject (result, isLeaf, healthObject, name) { + + var healthData = { + 'name': name + }; + var details = {}; + var hasDetails = false; + + angular.forEach(healthObject, function (value, key) { + if (key === 'status' || key === 'error') { + healthData[key] = value; + } else { + if (!isHealthObject(value)) { + details[key] = value; + hasDetails = true; + } + } + }); + + // Add the of the details + if (hasDetails) { + angular.extend(healthData, { 'details': details}); + } + + // Only add nodes if they provide additional information + if (isLeaf || hasDetails || healthData.error) { + result.push(healthData); + } + return healthData; + } + + function getModuleName (path, name) { + var result; + if (path && name) { + result = path + separator + name; + } else if (path) { + result = path; + } else if (name) { + result = name; + } else { + result = ''; + } + return result; + } + + function hasSubSystem (healthObject) { + var result = false; + angular.forEach(healthObject, function (value) { + if (value && value.status) { + result = true; + } + }); + return result; + } + + function isHealthObject (healthObject) { + var result = false; + angular.forEach(healthObject, function (value, key) { + if (key === 'status') { + result = true; + } + }); + return result; + } + + } +})(); diff --git a/src/main/webapp/app/admin/health/health.state.js b/src/main/webapp/app/admin/health/health.state.js new file mode 100644 index 000000000..bedfea4fa --- /dev/null +++ b/src/main/webapp/app/admin/health/health.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('jhi-health', { + parent: 'admin', + url: '/health', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'health.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/health/health.html', + controller: 'JhiHealthCheckController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('health'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/logs/logs.controller.js b/src/main/webapp/app/admin/logs/logs.controller.js new file mode 100644 index 000000000..b95f2f98f --- /dev/null +++ b/src/main/webapp/app/admin/logs/logs.controller.js @@ -0,0 +1,22 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('LogsController', LogsController); + + LogsController.$inject = ['LogsService']; + + function LogsController (LogsService) { + var vm = this; + + vm.changeLevel = changeLevel; + vm.loggers = LogsService.findAll(); + + function changeLevel (name, level) { + LogsService.changeLevel({name: name, level: level}, function () { + vm.loggers = LogsService.findAll(); + }); + } + } +})(); diff --git a/src/main/webapp/app/admin/logs/logs.html b/src/main/webapp/app/admin/logs/logs.html new file mode 100644 index 000000000..e35147b8f --- /dev/null +++ b/src/main/webapp/app/admin/logs/logs.html @@ -0,0 +1,27 @@ +
+

Logs

+ +

There are {{ vm.loggers.length }} loggers.

+ + Filter + + + + + + + + + + + + + +
NameLevel
{{logger.name | characters:140}} + + + + + +
+
diff --git a/src/main/webapp/app/admin/logs/logs.service.js b/src/main/webapp/app/admin/logs/logs.service.js new file mode 100644 index 000000000..037e3dd01 --- /dev/null +++ b/src/main/webapp/app/admin/logs/logs.service.js @@ -0,0 +1,18 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('LogsService', LogsService); + + LogsService.$inject = ['$resource']; + + function LogsService ($resource) { + var service = $resource('management/jhipster/logs', {}, { + 'findAll': { method: 'GET', isArray: true}, + 'changeLevel': { method: 'PUT'} + }); + + return service; + } +})(); diff --git a/src/main/webapp/app/admin/logs/logs.state.js b/src/main/webapp/app/admin/logs/logs.state.js new file mode 100644 index 000000000..c1511d417 --- /dev/null +++ b/src/main/webapp/app/admin/logs/logs.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('logs', { + parent: 'admin', + url: '/logs', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'logs.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/logs/logs.html', + controller: 'LogsController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('logs'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/metrics/metrics.controller.js b/src/main/webapp/app/admin/metrics/metrics.controller.js new file mode 100644 index 000000000..0b433f5d3 --- /dev/null +++ b/src/main/webapp/app/admin/metrics/metrics.controller.js @@ -0,0 +1,76 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('JhiMetricsMonitoringController', JhiMetricsMonitoringController); + + JhiMetricsMonitoringController.$inject = ['$scope','JhiMetricsService', '$uibModal']; + + function JhiMetricsMonitoringController ($scope, JhiMetricsService, $uibModal) { + var vm = this; + + vm.cachesStats = {}; + vm.metrics = {}; + vm.refresh = refresh; + vm.refreshThreadDumpData = refreshThreadDumpData; + vm.servicesStats = {}; + vm.updatingMetrics = true; + vm.refresh(); + + JhiMetricsService.getBeans().then(function (promise) { + vm.beans = promise; + }); + $scope.$watch('vm.metrics', function (newValue) { + vm.servicesStats = {}; + vm.cachesStats = {}; + angular.forEach(newValue.timers, function (value, key) { + if (key.indexOf('web.rest') !== -1 || key.indexOf('service') !== -1) { + vm.servicesStats[key] = value; + } + if (key.indexOf('net.sf.ehcache.Cache') !== -1) { + // remove gets or puts + var index = key.lastIndexOf('.'); + var newKey = key.substr(0, index); + + // Keep the name of the domain + index = newKey.lastIndexOf('.'); + vm.cachesStats[newKey] = { + 'name': newKey.substr(index + 1), + 'value': value + }; + } + }); + }); + + function refresh () { + vm.updatingMetrics = true; + JhiMetricsService.getMetrics().then(function (promise) { + vm.metrics = promise; + vm.updatingMetrics = false; + }, function (promise) { + vm.metrics = promise.data; + vm.updatingMetrics = false; + }); + } + + function refreshThreadDumpData () { + JhiMetricsService.threadDump().then(function(data) { + $uibModal.open({ + templateUrl: 'app/admin/metrics/metrics.modal.html', + controller: 'JhiMetricsMonitoringModalController', + controllerAs: 'vm', + size: 'lg', + resolve: { + threadDump: function() { + return data; + } + + } + }); + }); + } + + + } +})(); diff --git a/src/main/webapp/app/admin/metrics/metrics.html b/src/main/webapp/app/admin/metrics/metrics.html new file mode 100644 index 000000000..88902a29f --- /dev/null +++ b/src/main/webapp/app/admin/metrics/metrics.html @@ -0,0 +1,213 @@ +
+

Application Metrics

+

+ +

+ +

JVM Metrics

+
+
+ Memory +

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

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

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

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

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

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

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

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

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

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

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

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

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

+ + {{vm.metrics.gauges['jvm.threads.blocked.count'].value * 100 / vm.metrics.gauges['jvm.threads.count'].value | number:0}}% + +
+
+ Garbage collections +
+
Mark Sweep count
+
{{vm.metrics.gauges['jvm.garbage.PS-MarkSweep.count'].value}}
+
+
+
Mark Sweep time
+
{{vm.metrics.gauges['jvm.garbage.PS-MarkSweep.time'].value}}ms
+
+
+
Scavenge count
+
{{vm.metrics.gauges['jvm.garbage.PS-Scavenge.count'].value}}
+
+
+
Scavenge time
+
{{vm.metrics.gauges['jvm.garbage.PS-Scavenge.time'].value}}ms
+
+
+
+
Updating...
+ +

HTTP requests (events per second)

+

Active requests {{vm.metrics.counters['com.codahale.metrics.servlet.InstrumentedFilter.activeRequests'].count | number:0}} - Total requests {{vm.metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count | number:0}}

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeCountMeanAverage (1 min)Average (5 min)Average (15 min)
OK + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].count}} + + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].mean_rate | number:2}} + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m1_rate | number:2}} + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m5_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m15_rate | number:2}} +
Not Found + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].count}} + + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].mean_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m1_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m5_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m15_rate | number:2}} +
Server error + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].count}} + + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].mean_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m1_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m5_rate | number:2}} + + {{vm.metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m15_rate | number:2}} +
+
+ +

Services statistics (time in millisecond)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Service nameCountMeanMinp50p75p95p99Max
{{k}}{{v.count}}{{v.mean * 1000 | number:0}}{{v.min * 1000 | number:0}}{{v.p50 * 1000 | number:0}}{{v.p75 * 1000 | number:0}}{{v.p95 * 1000 | number:0}}{{v.p99 * 1000 | number:0}}{{v.max * 1000 | number:0}}
+
+ +

DataSource statistics (time in millisecond)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Usage ({{vm.metrics.gauges['HikariPool-1.pool.ActiveConnections'].value}} / {{vm.metrics.gauges['HikariPool-1.pool.TotalConnections'].value}})CountMeanMinp50p75p95p99Max
+
+ + {{vm.metrics.gauges['HikariPool-1.pool.ActiveConnections'].value * 100 / vm.metrics.gauges['HikariPool-1.pool.TotalConnections'].value | number:0}}% + +
+
{{vm.metrics.histograms['HikariPool-1.pool.Usage'].count}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].mean | number:2}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].min | number:2}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].p50 | number:2}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].p75 | number:2}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].p95 | number:2}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].p99 | number:2}}{{vm.metrics.histograms['HikariPool-1.pool.Usage'].max | number:2}}
+
{{vm.beans | json}}
+ +
+
diff --git a/src/main/webapp/app/admin/metrics/metrics.modal.controller.js b/src/main/webapp/app/admin/metrics/metrics.modal.controller.js new file mode 100644 index 000000000..1cc8e9096 --- /dev/null +++ b/src/main/webapp/app/admin/metrics/metrics.modal.controller.js @@ -0,0 +1,53 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('JhiMetricsMonitoringModalController', JhiMetricsMonitoringModalController); + + JhiMetricsMonitoringModalController.$inject = ['$uibModalInstance', 'threadDump']; + + function JhiMetricsMonitoringModalController ($uibModalInstance, threadDump) { + var vm = this; + + vm.cancel = cancel; + vm.getLabelClass = getLabelClass; + vm.threadDump = threadDump; + vm.threadDumpAll = 0; + vm.threadDumpBlocked = 0; + vm.threadDumpRunnable = 0; + vm.threadDumpTimedWaiting = 0; + vm.threadDumpWaiting = 0; + + angular.forEach(threadDump, function(value) { + if (value.threadState === 'RUNNABLE') { + vm.threadDumpRunnable += 1; + } else if (value.threadState === 'WAITING') { + vm.threadDumpWaiting += 1; + } else if (value.threadState === 'TIMED_WAITING') { + vm.threadDumpTimedWaiting += 1; + } else if (value.threadState === 'BLOCKED') { + vm.threadDumpBlocked += 1; + } + }); + + vm.threadDumpAll = vm.threadDumpRunnable + vm.threadDumpWaiting + + vm.threadDumpTimedWaiting + vm.threadDumpBlocked; + + function cancel () { + $uibModalInstance.dismiss('cancel'); + } + + function getLabelClass (threadState) { + if (threadState === 'RUNNABLE') { + return 'label-success'; + } else if (threadState === 'WAITING') { + return 'label-info'; + } else if (threadState === 'TIMED_WAITING') { + return 'label-warning'; + } else if (threadState === 'BLOCKED') { + return 'label-danger'; + } + } + } +})(); diff --git a/src/main/webapp/app/admin/metrics/metrics.modal.html b/src/main/webapp/app/admin/metrics/metrics.modal.html new file mode 100644 index 000000000..7d07d6aa1 --- /dev/null +++ b/src/main/webapp/app/admin/metrics/metrics.modal.html @@ -0,0 +1,53 @@ + + + + diff --git a/src/main/webapp/app/admin/metrics/metrics.service.js b/src/main/webapp/app/admin/metrics/metrics.service.js new file mode 100644 index 000000000..34bd09abd --- /dev/null +++ b/src/main/webapp/app/admin/metrics/metrics.service.js @@ -0,0 +1,37 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('JhiMetricsService', JhiMetricsService); + + JhiMetricsService.$inject = ['$rootScope', '$http']; + + function JhiMetricsService ($rootScope, $http) { + var service = { + getMetrics: getMetrics, + threadDump: threadDump, + getBeans: getBeans + }; + + return service; + + function getMetrics () { + return $http.get('management/jhipster/metrics').then(function (response) { + return response.data; + }); + } + + function threadDump () { + return $http.get('management/dump').then(function (response) { + return response.data; + }); + } + + function getBeans () { + return $http.get('management/beans').then(function (response) { + return response.data; + }); + } + } +})(); diff --git a/src/main/webapp/app/admin/metrics/metrics.state.js b/src/main/webapp/app/admin/metrics/metrics.state.js new file mode 100644 index 000000000..52a76c87e --- /dev/null +++ b/src/main/webapp/app/admin/metrics/metrics.state.js @@ -0,0 +1,33 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('jhi-metrics', { + parent: 'admin', + url: '/metrics', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'metrics.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/metrics/metrics.html', + controller: 'JhiMetricsMonitoringController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('metrics'); + return $translate.refresh(); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/admin/user-management/user-management-delete-dialog.controller.js b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.controller.js new file mode 100644 index 000000000..1c0eb4504 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.controller.js @@ -0,0 +1,28 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('UserManagementDeleteController', UserManagementDeleteController); + + UserManagementDeleteController.$inject = ['$uibModalInstance', 'entity', 'User']; + + function UserManagementDeleteController ($uibModalInstance, entity, User) { + var vm = this; + + vm.user = entity; + vm.clear = clear; + vm.confirmDelete = confirmDelete; + + function clear () { + $uibModalInstance.dismiss('cancel'); + } + + function confirmDelete (login) { + User.delete({login: login}, + function () { + $uibModalInstance.close(true); + }); + } + } +})(); diff --git a/src/main/webapp/app/admin/user-management/user-management-delete-dialog.html b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.html new file mode 100644 index 000000000..25c6c1a85 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-delete-dialog.html @@ -0,0 +1,19 @@ +
+ + + +
diff --git a/src/main/webapp/app/admin/user-management/user-management-detail.controller.js b/src/main/webapp/app/admin/user-management/user-management-detail.controller.js new file mode 100644 index 000000000..00e37ab83 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-detail.controller.js @@ -0,0 +1,24 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('UserManagementDetailController', UserManagementDetailController); + + UserManagementDetailController.$inject = ['$stateParams', 'User']; + + function UserManagementDetailController ($stateParams, User) { + var vm = this; + + vm.load = load; + vm.user = {}; + + vm.load($stateParams.login); + + function load (login) { + User.get({login: login}, function(result) { + vm.user = result; + }); + } + } +})(); diff --git a/src/main/webapp/app/admin/user-management/user-management-detail.html b/src/main/webapp/app/admin/user-management/user-management-detail.html new file mode 100644 index 000000000..28d02e7b3 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-detail.html @@ -0,0 +1,36 @@ +
+

User "{{vm.user.login}}"

+
+
Login
+
{{vm.user.login}}
+
First Name
+
{{vm.user.firstName}}
+
Last Name
+
{{vm.user.lastName}}
+
Email
+
{{vm.user.email}}
+
Activated
+
{{vm.user.activated}}
+
Lang Key
+
{{vm.user.langKey}}
+
Created By
+
{{vm.user.createdBy}}
+
Created Date
+
{{vm.user.createdDate | date:'dd/MM/yy HH:mm' }}
+
Last Modified By
+
{{vm.user.lastModifiedBy}}
+
Last Modified Date
+
{{vm.user.lastModifiedDate | date:'dd/MM/yy HH:mm'}}
+
Profiles
+
+
    +
  • {{authority}}
  • +
+
+
+ +
diff --git a/src/main/webapp/app/admin/user-management/user-management-dialog.controller.js b/src/main/webapp/app/admin/user-management/user-management-dialog.controller.js new file mode 100644 index 000000000..4d58aa87e --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-dialog.controller.js @@ -0,0 +1,46 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('UserManagementDialogController',UserManagementDialogController); + + UserManagementDialogController.$inject = ['$stateParams', '$uibModalInstance', 'entity', 'User', 'JhiLanguageService']; + + function UserManagementDialogController ($stateParams, $uibModalInstance, entity, User, JhiLanguageService) { + var vm = this; + + vm.authorities = ['ROLE_USER', 'ROLE_ADMIN']; + vm.clear = clear; + vm.languages = null; + vm.save = save; + vm.user = entity; + + + JhiLanguageService.getAll().then(function (languages) { + vm.languages = languages; + }); + + function clear () { + $uibModalInstance.dismiss('cancel'); + } + + function onSaveSuccess (result) { + vm.isSaving = false; + $uibModalInstance.close(result); + } + + function onSaveError () { + vm.isSaving = false; + } + + function save () { + vm.isSaving = true; + if (vm.user.id !== null) { + User.update(vm.user, onSaveSuccess, onSaveError); + } else { + User.save(vm.user, onSaveSuccess, onSaveError); + } + } + } +})(); diff --git a/src/main/webapp/app/admin/user-management/user-management-dialog.html b/src/main/webapp/app/admin/user-management/user-management-dialog.html new file mode 100644 index 000000000..6a194d64f --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management-dialog.html @@ -0,0 +1,113 @@ +
+ + + + +
diff --git a/src/main/webapp/app/admin/user-management/user-management.controller.js b/src/main/webapp/app/admin/user-management/user-management.controller.js new file mode 100644 index 000000000..159b52399 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management.controller.js @@ -0,0 +1,102 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('UserManagementController', UserManagementController); + + UserManagementController.$inject = ['Principal', 'User', 'ParseLinks', 'AlertService', '$state', 'pagingParams', 'paginationConstants', 'JhiLanguageService']; + + function UserManagementController(Principal, User, ParseLinks, AlertService, $state, pagingParams, paginationConstants, JhiLanguageService) { + var vm = this; + + vm.authorities = ['ROLE_USER', 'ROLE_ADMIN']; + vm.currentAccount = null; + vm.languages = null; + vm.loadAll = loadAll; + vm.setActive = setActive; + vm.users = []; + vm.page = 1; + vm.totalItems = null; + vm.clear = clear; + vm.links = null; + vm.loadPage = loadPage; + vm.predicate = pagingParams.predicate; + vm.reverse = pagingParams.ascending; + vm.itemsPerPage = paginationConstants.itemsPerPage; + vm.transition = transition; + + vm.loadAll(); + + JhiLanguageService.getAll().then(function (languages) { + vm.languages = languages; + }); + Principal.identity().then(function(account) { + vm.currentAccount = account; + }); + + function setActive (user, isActivated) { + user.activated = isActivated; + User.update(user, function () { + vm.loadAll(); + vm.clear(); + }); + } + + function loadAll () { + User.query({ + page: pagingParams.page - 1, + size: vm.itemsPerPage, + sort: sort() + }, onSuccess, onError); + } + + function onSuccess(data, headers) { + //hide anonymous user from user management: it's a required user for Spring Security + for (var i in data) { + if (data[i]['login'] === 'anonymoususer') { + data.splice(i, 1); + } + } + vm.links = ParseLinks.parse(headers('link')); + vm.totalItems = headers('X-Total-Count'); + vm.queryCount = vm.totalItems; + vm.page = pagingParams.page; + vm.users = data; + } + + function onError(error) { + AlertService.error(error.data.message); + } + + function clear () { + vm.user = { + id: null, login: null, firstName: null, lastName: null, email: null, + activated: null, langKey: null, createdBy: null, createdDate: null, + lastModifiedBy: null, lastModifiedDate: null, resetDate: null, + resetKey: null, authorities: null + }; + } + + function sort () { + var result = [vm.predicate + ',' + (vm.reverse ? 'asc' : 'desc')]; + if (vm.predicate !== 'id') { + result.push('id'); + } + return result; + } + + function loadPage (page) { + vm.page = page; + vm.transition(); + } + + function transition () { + $state.transitionTo($state.$current, { + page: vm.page, + sort: vm.predicate + ',' + (vm.reverse ? 'asc' : 'desc'), + search: vm.currentSearch + }); + } + } +})(); diff --git a/src/main/webapp/app/admin/user-management/user-management.html b/src/main/webapp/app/admin/user-management/user-management.html new file mode 100644 index 000000000..c24432834 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management.html @@ -0,0 +1,75 @@ +
+

Users

+ +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDLogin Email Lang Key Profiles Created Date Last Modified By Last Modified Date
{{user.id}}{{user.login}}{{user.email}} + Deactivated + Activated + {{user.langKey}} +
+ {{ authority }} +
+
{{user.createdDate | date:'dd/MM/yy HH:mm'}}{{user.lastModifiedBy}}{{user.lastModifiedDate | date:'dd/MM/yy HH:mm'}} +
+ + + +
+
+
+
+ + +
+
diff --git a/src/main/webapp/app/admin/user-management/user-management.state.js b/src/main/webapp/app/admin/user-management/user-management.state.js new file mode 100644 index 000000000..df3b1e807 --- /dev/null +++ b/src/main/webapp/app/admin/user-management/user-management.state.js @@ -0,0 +1,151 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider + .state('user-management', { + parent: 'admin', + url: '/user-management?page&sort', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'userManagement.home.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/user-management/user-management.html', + controller: 'UserManagementController', + controllerAs: 'vm' + } + }, params: { + page: { + value: '1', + squash: true + }, + sort: { + value: 'id,asc', + squash: true + } + }, + resolve: { + pagingParams: ['$stateParams', 'PaginationUtil', function ($stateParams, PaginationUtil) { + return { + page: PaginationUtil.parsePage($stateParams.page), + sort: $stateParams.sort, + predicate: PaginationUtil.parsePredicate($stateParams.sort), + ascending: PaginationUtil.parseAscending($stateParams.sort) + }; + }], + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('user-management'); + return $translate.refresh(); + }] + + } }) + .state('user-management-detail', { + parent: 'admin', + url: '/user/:login', + data: { + authorities: ['ROLE_ADMIN'], + pageTitle: 'user-management.detail.title' + }, + views: { + 'content@': { + templateUrl: 'app/admin/user-management/user-management-detail.html', + controller: 'UserManagementDetailController', + controllerAs: 'vm' + } + }, + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('user-management'); + return $translate.refresh(); + }] + } + }) + .state('user-management.new', { + parent: 'user-management', + url: '/new', + data: { + authorities: ['ROLE_ADMIN'] + }, + onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) { + $uibModal.open({ + templateUrl: 'app/admin/user-management/user-management-dialog.html', + controller: 'UserManagementDialogController', + controllerAs: 'vm', + backdrop: 'static', + size: 'lg', + resolve: { + entity: function () { + return { + id: null, login: null, firstName: null, lastName: null, email: null, + activated: true, langKey: null, createdBy: null, createdDate: null, + lastModifiedBy: null, lastModifiedDate: null, resetDate: null, + resetKey: null, authorities: null + }; + } + } + }).result.then(function() { + $state.go('user-management', null, { reload: true }); + }, function() { + $state.go('user-management'); + }); + }] + }) + .state('user-management.edit', { + parent: 'user-management', + url: '/{login}/edit', + data: { + authorities: ['ROLE_ADMIN'] + }, + onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) { + $uibModal.open({ + templateUrl: 'app/admin/user-management/user-management-dialog.html', + controller: 'UserManagementDialogController', + controllerAs: 'vm', + backdrop: 'static', + size: 'lg', + resolve: { + entity: ['User', function(User) { + return User.get({login : $stateParams.login}); + }] + } + }).result.then(function() { + $state.go('user-management', null, { reload: true }); + }, function() { + $state.go('^'); + }); + }] + }) + .state('user-management.delete', { + parent: 'user-management', + url: '/{login}/delete', + data: { + authorities: ['ROLE_ADMIN'] + }, + onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) { + $uibModal.open({ + templateUrl: 'app/admin/user-management/user-management-delete-dialog.html', + controller: 'UserManagementDeleteController', + controllerAs: 'vm', + size: 'md', + resolve: { + entity: ['User', function(User) { + return User.get({login : $stateParams.login}); + }] + } + }).result.then(function() { + $state.go('user-management', null, { reload: true }); + }, function() { + $state.go('^'); + }); + }] + }); + } +})(); diff --git a/src/main/webapp/app/app.constants.js b/src/main/webapp/app/app.constants.js new file mode 100644 index 000000000..0f117e66a --- /dev/null +++ b/src/main/webapp/app/app.constants.js @@ -0,0 +1,9 @@ +(function () { + 'use strict'; + // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE + angular + .module('sprintApp') + .constant('VERSION', "0.2.0-SNAPSHOT") + .constant('DEBUG_INFO_ENABLED', true) +; +})(); diff --git a/src/main/webapp/app/app.module.js b/src/main/webapp/app/app.module.js new file mode 100644 index 000000000..66213dacd --- /dev/null +++ b/src/main/webapp/app/app.module.js @@ -0,0 +1,29 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp', [ + 'ngStorage', + 'tmh.dynamicLocale', + 'pascalprecht.translate', + 'ngResource', + 'ngCookies', + 'ngAria', + 'ngCacheBuster', + 'ngFileUpload', + 'ui.bootstrap', + 'ui.bootstrap.datetimepicker', + 'ui.router', + 'infinite-scroll', + // jhipster-needle-angularjs-add-module JHipster will add new module here + 'angular-loading-bar' + ]) + .run(run); + + run.$inject = ['stateHandler', 'translationHandler']; + + function run(stateHandler, translationHandler) { + stateHandler.initialize(); + translationHandler.initialize(); + } +})(); diff --git a/src/main/webapp/app/app.state.js b/src/main/webapp/app/app.state.js new file mode 100644 index 000000000..109e17f4f --- /dev/null +++ b/src/main/webapp/app/app.state.js @@ -0,0 +1,32 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('app', { + abstract: true, + views: { + 'navbar@': { + templateUrl: 'app/layouts/navbar/navbar.html', + controller: 'NavbarController', + controllerAs: 'vm' + } + }, + resolve: { + authorize: ['Auth', + function (Auth) { + return Auth.authorize(); + } + ], + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('global'); + }] + } + }); + } +})(); diff --git a/src/main/webapp/app/blocks/config/alert.config.js b/src/main/webapp/app/blocks/config/alert.config.js new file mode 100644 index 000000000..71821bbb4 --- /dev/null +++ b/src/main/webapp/app/blocks/config/alert.config.js @@ -0,0 +1,14 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(alertServiceConfig); + + alertServiceConfig.$inject = ['AlertServiceProvider']; + + function alertServiceConfig(AlertServiceProvider) { + // set below to true to make alerts look like toast + AlertServiceProvider.showAsToast(false); + } +})(); diff --git a/src/main/webapp/app/blocks/config/compile.config.js b/src/main/webapp/app/blocks/config/compile.config.js new file mode 100644 index 000000000..8c0aa3f45 --- /dev/null +++ b/src/main/webapp/app/blocks/config/compile.config.js @@ -0,0 +1,22 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(compileServiceConfig); + + compileServiceConfig.$inject = ['$compileProvider','DEBUG_INFO_ENABLED']; + + function compileServiceConfig($compileProvider,DEBUG_INFO_ENABLED) { + // disable debug data on prod profile to improve performance + $compileProvider.debugInfoEnabled(DEBUG_INFO_ENABLED); + + /* + If you wish to debug an application with this information + then you should open up a debug console in the browser + then call this method directly in this console: + + angular.reloadWithDebugInfo(); + */ + } +})(); diff --git a/src/main/webapp/app/blocks/config/http.config.js b/src/main/webapp/app/blocks/config/http.config.js new file mode 100644 index 000000000..9ab905a7a --- /dev/null +++ b/src/main/webapp/app/blocks/config/http.config.js @@ -0,0 +1,32 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(httpConfig); + + httpConfig.$inject = ['$urlRouterProvider', '$httpProvider', 'httpRequestInterceptorCacheBusterProvider', '$urlMatcherFactoryProvider']; + + function httpConfig($urlRouterProvider, $httpProvider, httpRequestInterceptorCacheBusterProvider, $urlMatcherFactoryProvider) { + + //Cache everything except rest api requests + httpRequestInterceptorCacheBusterProvider.setMatchlist([/.*api.*/, /.*protected.*/], true); + + $urlRouterProvider.otherwise('/'); + + $httpProvider.interceptors.push('errorHandlerInterceptor'); + $httpProvider.interceptors.push('authExpiredInterceptor'); + $httpProvider.interceptors.push('authInterceptor'); + $httpProvider.interceptors.push('notificationInterceptor'); + // jhipster-needle-angularjs-add-interceptor JHipster will add new application http interceptor here + + $urlMatcherFactoryProvider.type('boolean', { + name : 'boolean', + decode: function(val) { return val === true || val === 'true'; }, + encode: function(val) { return val ? 1 : 0; }, + equals: function(a, b) { return this.is(a) && a === b; }, + is: function(val) { return [true,false,0,1].indexOf(val) >= 0; }, + pattern: /bool|true|0|1/ + }); + } +})(); diff --git a/src/main/webapp/app/blocks/config/localstorage.config.js b/src/main/webapp/app/blocks/config/localstorage.config.js new file mode 100644 index 000000000..599bc20fc --- /dev/null +++ b/src/main/webapp/app/blocks/config/localstorage.config.js @@ -0,0 +1,14 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(localStorageConfig); + + localStorageConfig.$inject = ['$localStorageProvider', '$sessionStorageProvider']; + + function localStorageConfig($localStorageProvider, $sessionStorageProvider) { + $localStorageProvider.setKeyPrefix('jhi-'); + $sessionStorageProvider.setKeyPrefix('jhi-'); + } +})(); diff --git a/src/main/webapp/app/blocks/config/translation-storage.provider.js b/src/main/webapp/app/blocks/config/translation-storage.provider.js new file mode 100644 index 000000000..0f4d0bbb2 --- /dev/null +++ b/src/main/webapp/app/blocks/config/translation-storage.provider.js @@ -0,0 +1,28 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('translationStorageProvider', translationStorageProvider); + + translationStorageProvider.$inject = ['$cookies', '$log', 'LANGUAGES']; + + function translationStorageProvider($cookies, $log, LANGUAGES) { + return { + get: get, + put: put + }; + + function get(name) { + if (LANGUAGES.indexOf($cookies.getObject(name)) === -1) { + $log.info('Resetting invalid cookie language "' + $cookies.getObject(name) + '" to prefered language "it"'); + $cookies.putObject(name, 'it'); + } + return $cookies.getObject(name); + } + + function put(name, value) { + $cookies.putObject(name, value); + } + } +})(); diff --git a/src/main/webapp/app/blocks/config/translation.config.js b/src/main/webapp/app/blocks/config/translation.config.js new file mode 100644 index 000000000..63fea09ef --- /dev/null +++ b/src/main/webapp/app/blocks/config/translation.config.js @@ -0,0 +1,25 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(translationConfig); + + translationConfig.$inject = ['$translateProvider', 'tmhDynamicLocaleProvider']; + + function translationConfig($translateProvider, tmhDynamicLocaleProvider) { + // Initialize angular-translate + $translateProvider.useLoader('$translatePartialLoader', { + urlTemplate: 'i18n/{lang}/{part}.json' + }); + + $translateProvider.preferredLanguage('it'); + $translateProvider.useStorage('translationStorageProvider'); + $translateProvider.useSanitizeValueStrategy('escaped'); + $translateProvider.addInterpolation('$translateMessageFormatInterpolation'); + + tmhDynamicLocaleProvider.localeLocationPattern('i18n/angular-locale_{{locale}}.js'); + tmhDynamicLocaleProvider.useCookieStorage(); + tmhDynamicLocaleProvider.storageKey('NG_TRANSLATE_LANG_KEY'); + } +})(); diff --git a/src/main/webapp/app/blocks/config/uib-pager.config.js b/src/main/webapp/app/blocks/config/uib-pager.config.js new file mode 100644 index 000000000..b04bc12a9 --- /dev/null +++ b/src/main/webapp/app/blocks/config/uib-pager.config.js @@ -0,0 +1,15 @@ +(function () { + 'use strict'; + + angular + .module('sprintApp') + .config(pagerConfig); + + pagerConfig.$inject = ['uibPagerConfig', 'paginationConstants']; + + function pagerConfig(uibPagerConfig, paginationConstants) { + uibPagerConfig.itemsPerPage = paginationConstants.itemsPerPage; + uibPagerConfig.previousText = '«'; + uibPagerConfig.nextText = '»'; + } +})(); diff --git a/src/main/webapp/app/blocks/config/uib-pagination.config.js b/src/main/webapp/app/blocks/config/uib-pagination.config.js new file mode 100644 index 000000000..1443b867c --- /dev/null +++ b/src/main/webapp/app/blocks/config/uib-pagination.config.js @@ -0,0 +1,19 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(paginationConfig); + + paginationConfig.$inject = ['uibPaginationConfig', 'paginationConstants']; + + function paginationConfig(uibPaginationConfig, paginationConstants) { + uibPaginationConfig.itemsPerPage = paginationConstants.itemsPerPage; + uibPaginationConfig.maxSize = 5; + uibPaginationConfig.boundaryLinks = true; + uibPaginationConfig.firstText = '«'; + uibPaginationConfig.previousText = '‹'; + uibPaginationConfig.nextText = '›'; + uibPaginationConfig.lastText = '»'; + } +})(); diff --git a/src/main/webapp/app/blocks/handlers/state.handler.js b/src/main/webapp/app/blocks/handlers/state.handler.js new file mode 100644 index 000000000..6748e0ea4 --- /dev/null +++ b/src/main/webapp/app/blocks/handlers/state.handler.js @@ -0,0 +1,63 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('stateHandler', stateHandler); + + stateHandler.$inject = ['$rootScope', '$state', '$sessionStorage', '$translate', 'JhiLanguageService', 'translationHandler', '$window', + 'Auth', 'Principal', 'VERSION']; + + function stateHandler($rootScope, $state, $sessionStorage, $translate, JhiLanguageService, translationHandler, $window, + Auth, Principal, VERSION) { + return { + initialize: initialize + }; + + function initialize() { + $rootScope.VERSION = VERSION; + + var stateChangeStart = $rootScope.$on('$stateChangeStart', function (event, toState, toStateParams, fromState) { + $rootScope.toState = toState; + $rootScope.toStateParams = toStateParams; + $rootScope.fromState = fromState; + + // Redirect to a state with an external URL (http://stackoverflow.com/a/30221248/1098564) + if (toState.external) { + event.preventDefault(); + $window.open(toState.url, '_self'); + } + + if (Principal.isIdentityResolved()) { + Auth.authorize(); + } + + + // Update the language + JhiLanguageService.getCurrent().then(function (language) { + $translate.use(language); + }); + + }); + + var stateChangeSuccess = $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { + var titleKey = 'global.title' ; + + // Set the page title key to the one configured in state or use default one + if (toState.data.pageTitle) { + titleKey = toState.data.pageTitle; + } + translationHandler.updateTitle(titleKey); + }); + + $rootScope.$on('$destroy', function () { + if(angular.isDefined(stateChangeStart) && stateChangeStart !== null){ + stateChangeStart(); + } + if(angular.isDefined(stateChangeSuccess) && stateChangeSuccess !== null){ + stateChangeSuccess(); + } + }); + } + } +})(); diff --git a/src/main/webapp/app/blocks/handlers/translation.handler.js b/src/main/webapp/app/blocks/handlers/translation.handler.js new file mode 100644 index 000000000..77d4c8694 --- /dev/null +++ b/src/main/webapp/app/blocks/handlers/translation.handler.js @@ -0,0 +1,43 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('translationHandler', translationHandler); + + translationHandler.$inject = ['$rootScope', '$window', '$state', '$translate']; + + function translationHandler($rootScope, $window, $state, $translate) { + return { + initialize: initialize, + updateTitle: updateTitle + }; + + function initialize() { + // if the current translation changes, update the window title + var translateChangeSuccess = $rootScope.$on('$translateChangeSuccess', function() { + updateTitle(); + }); + + $rootScope.$on('$destroy', function () { + if(angular.isDefined(translateChangeSuccess) && translateChangeSuccess !== null){ + translateChangeSuccess(); + } + }); + } + + // update the window title using params in the following + // precendence + // 1. titleKey parameter + // 2. $state.$current.data.pageTitle (current state page title) + // 3. 'global.title' + function updateTitle(titleKey) { + if (!titleKey && $state.$current.data && $state.$current.data.pageTitle) { + titleKey = $state.$current.data.pageTitle; + } + $translate(titleKey || 'global.title').then(function (title) { + $window.document.title = title; + }); + } + } +})(); diff --git a/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.js b/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.js new file mode 100644 index 000000000..d3dafe8e9 --- /dev/null +++ b/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.js @@ -0,0 +1,31 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('authExpiredInterceptor', authExpiredInterceptor); + + + authExpiredInterceptor.$inject = ['$rootScope', '$q', '$injector', '$localStorage', '$sessionStorage']; + + function authExpiredInterceptor($rootScope, $q, $injector, $localStorage, $sessionStorage) { + var service = { + responseError: responseError + }; + + return service; + + function responseError(response) { + if (response.status === 401) { + delete $localStorage.authenticationToken; + delete $sessionStorage.authenticationToken; + var Principal = $injector.get('Principal'); + if (Principal.isAuthenticated()) { + var Auth = $injector.get('Auth'); + Auth.authorize(true); + } + } + return $q.reject(response); + } + } +})(); diff --git a/src/main/webapp/app/blocks/interceptor/auth.interceptor.js b/src/main/webapp/app/blocks/interceptor/auth.interceptor.js new file mode 100644 index 000000000..f658c16df --- /dev/null +++ b/src/main/webapp/app/blocks/interceptor/auth.interceptor.js @@ -0,0 +1,29 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('authInterceptor', authInterceptor); + + authInterceptor.$inject = ['$rootScope', '$q', '$location', '$localStorage', '$sessionStorage']; + + function authInterceptor ($rootScope, $q, $location, $localStorage, $sessionStorage) { + var service = { + request: request + }; + + return service; + + function request (config) { + /*jshint camelcase: false */ + config.headers = config.headers || {}; + var token = $localStorage.authenticationToken || $sessionStorage.authenticationToken; + + if (token && token.expires_at && token.expires_at > new Date().getTime()) { + config.headers.Authorization = 'Bearer ' + token.access_token; + } + + return config; + } + } +})(); diff --git a/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.js b/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.js new file mode 100644 index 000000000..60622bcfd --- /dev/null +++ b/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.js @@ -0,0 +1,24 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('errorHandlerInterceptor', errorHandlerInterceptor); + + errorHandlerInterceptor.$inject = ['$q', '$rootScope']; + + function errorHandlerInterceptor ($q, $rootScope) { + var service = { + responseError: responseError + }; + + return service; + + function responseError (response) { + if (!(response.status === 401 && (response.data === '' || (response.data.path && response.data.path.indexOf('/api/account') === 0 )))) { + $rootScope.$emit('sprintApp.httpError', response); + } + return $q.reject(response); + } + } +})(); diff --git a/src/main/webapp/app/blocks/interceptor/notification.interceptor.js b/src/main/webapp/app/blocks/interceptor/notification.interceptor.js new file mode 100644 index 000000000..3c96c06c8 --- /dev/null +++ b/src/main/webapp/app/blocks/interceptor/notification.interceptor.js @@ -0,0 +1,25 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('notificationInterceptor', notificationInterceptor); + + notificationInterceptor.$inject = ['$q', 'AlertService']; + + function notificationInterceptor ($q, AlertService) { + var service = { + response: response + }; + + return service; + + function response (response) { + var alertKey = response.headers('X-sprintApp-alert'); + if (angular.isString(alertKey)) { + AlertService.success(alertKey, { param : response.headers('X-sprintApp-params')}); + } + return response; + } + } +})(); diff --git a/src/main/webapp/app/components/alert/alert-error.directive.js b/src/main/webapp/app/components/alert/alert-error.directive.js new file mode 100644 index 000000000..5ea0d23c4 --- /dev/null +++ b/src/main/webapp/app/components/alert/alert-error.directive.js @@ -0,0 +1,91 @@ +(function() { + 'use strict'; + + var jhiAlertError = { + template: '
' + + '
' + + '
{{ alert.msg }}
' + + '
' + + '
', + controller: jhiAlertErrorController + }; + + angular + .module('sprintApp') + .component('jhiAlertError', jhiAlertError); + + jhiAlertErrorController.$inject = ['$scope', 'AlertService', '$rootScope', '$translate']; + + function jhiAlertErrorController ($scope, AlertService, $rootScope, $translate) { + var vm = this; + + vm.alerts = []; + + function addErrorAlert (message, key, data) { + key = key && key !== null ? key : message; + vm.alerts.push( + AlertService.add( + { + type: 'danger', + msg: key, + params: data, + timeout: 5000, + toast: AlertService.isToast(), + scoped: true + }, + vm.alerts + ) + ); + } + + var cleanHttpErrorListener = $rootScope.$on('sprintApp.httpError', function (event, httpResponse) { + var i; + event.stopPropagation(); + switch (httpResponse.status) { + // connection refused, server not reachable + case 0: + addErrorAlert('Server not reachable','error.server.not.reachable'); + break; + + case 400: + var errorHeader = httpResponse.headers('X-sprintApp-error'); + var entityKey = httpResponse.headers('X-sprintApp-params'); + if (errorHeader) { + var entityName = $translate.instant('global.menu.entities.' + entityKey); + addErrorAlert(errorHeader, errorHeader, {entityName: entityName}); + } else if (httpResponse.data && httpResponse.data.fieldErrors) { + for (i = 0; i < httpResponse.data.fieldErrors.length; i++) { + var fieldError = httpResponse.data.fieldErrors[i]; + // convert 'something[14].other[4].id' to 'something[].other[].id' so translations can be written to it + var convertedField = fieldError.field.replace(/\[\d*\]/g, '[]'); + var fieldName = $translate.instant('sprintApp.' + fieldError.objectName + '.' + convertedField); + addErrorAlert('Field ' + fieldName + ' cannot be empty', 'error.' + fieldError.message, {fieldName: fieldName}); + } + } else if (httpResponse.data && httpResponse.data.message) { + addErrorAlert(httpResponse.data.message, httpResponse.data.message, httpResponse.data); + } else { + addErrorAlert(httpResponse.data); + } + break; + + case 404: + addErrorAlert('Not found','error.url.not.found'); + break; + + default: + if (httpResponse.data && httpResponse.data.message) { + addErrorAlert(httpResponse.data.message); + } else { + addErrorAlert(angular.toJson(httpResponse)); + } + } + }); + + $scope.$on('$destroy', function () { + if(angular.isDefined(cleanHttpErrorListener) && cleanHttpErrorListener !== null){ + cleanHttpErrorListener(); + vm.alerts = []; + } + }); + } +})(); diff --git a/src/main/webapp/app/components/alert/alert.directive.js b/src/main/webapp/app/components/alert/alert.directive.js new file mode 100644 index 000000000..950a8a951 --- /dev/null +++ b/src/main/webapp/app/components/alert/alert.directive.js @@ -0,0 +1,27 @@ +(function() { + 'use strict'; + + var jhiAlert = { + template: '
' + + '
' + + '
' + + '
' + + '
', + controller: jhiAlertController + }; + + angular + .module('sprintApp') + .component('jhiAlert', jhiAlert); + + jhiAlertController.$inject = ['$scope', 'AlertService']; + + function jhiAlertController($scope, AlertService) { + var vm = this; + + vm.alerts = AlertService.get(); + $scope.$on('$destroy', function () { + vm.alerts = []; + }); + } +})(); diff --git a/src/main/webapp/app/components/alert/alert.service.js b/src/main/webapp/app/components/alert/alert.service.js new file mode 100644 index 000000000..ab5df7699 --- /dev/null +++ b/src/main/webapp/app/components/alert/alert.service.js @@ -0,0 +1,137 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .provider('AlertService', AlertService); + + function AlertService () { + this.toast = false; + /*jshint validthis: true */ + this.$get = getService; + + this.showAsToast = function(isToast) { + this.toast = isToast; + }; + + getService.$inject = ['$timeout', '$sce', '$translate']; + + function getService ($timeout, $sce,$translate) { + var toast = this.toast, + alertId = 0, // unique id for each alert. Starts from 0. + alerts = [], + timeout = 5000; // default timeout + + return { + factory: factory, + isToast: isToast, + add: addAlert, + closeAlert: closeAlert, + closeAlertByIndex: closeAlertByIndex, + clear: clear, + get: get, + success: success, + error: error, + info: info, + warning : warning + }; + + function isToast() { + return toast; + } + + function clear() { + alerts = []; + } + + function get() { + return alerts; + } + + function success(msg, params, position) { + return this.add({ + type: 'success', + msg: msg, + params: params, + timeout: timeout, + toast: toast, + position: position + }); + } + + function error(msg, params, position) { + return this.add({ + type: 'danger', + msg: msg, + params: params, + timeout: timeout, + toast: toast, + position: position + }); + } + + function warning(msg, params, position) { + return this.add({ + type: 'warning', + msg: msg, + params: params, + timeout: timeout, + toast: toast, + position: position + }); + } + + function info(msg, params, position) { + return this.add({ + type: 'info', + msg: msg, + params: params, + timeout: timeout, + toast: toast, + position: position + }); + } + + function factory(alertOptions) { + var alert = { + type: alertOptions.type, + msg: $sce.trustAsHtml(alertOptions.msg), + id: alertOptions.alertId, + timeout: alertOptions.timeout, + toast: alertOptions.toast, + position: alertOptions.position ? alertOptions.position : 'top right', + scoped: alertOptions.scoped, + close: function (alerts) { + return closeAlert(this.id, alerts); + } + }; + if(!alert.scoped) { + alerts.push(alert); + } + return alert; + } + + function addAlert(alertOptions, extAlerts) { + alertOptions.alertId = alertId++; + alertOptions.msg = $translate.instant(alertOptions.msg, alertOptions.params); + var that = this; + var alert = this.factory(alertOptions); + if (alertOptions.timeout && alertOptions.timeout > 0) { + $timeout(function () { + that.closeAlert(alertOptions.alertId, extAlerts); + }, alertOptions.timeout); + } + return alert; + } + + function closeAlert(id, extAlerts) { + var thisAlerts = extAlerts ? extAlerts : alerts; + return closeAlertByIndex(thisAlerts.map(function(e) { return e.id; }).indexOf(id), thisAlerts); + } + + function closeAlertByIndex(index, thisAlerts) { + return thisAlerts.splice(index, 1); + } + } + } +})(); diff --git a/src/main/webapp/app/components/form/maxbytes.directive.js b/src/main/webapp/app/components/form/maxbytes.directive.js new file mode 100644 index 000000000..2cbfa8fe2 --- /dev/null +++ b/src/main/webapp/app/components/form/maxbytes.directive.js @@ -0,0 +1,46 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .directive('maxbytes', maxbytes); + + function maxbytes () { + var directive = { + restrict: 'A', + require: '?ngModel', + link: linkFunc + }; + + return directive; + + function linkFunc (scope, element, attrs, ngModel) { + if (!ngModel) { + return; + } + + ngModel.$validators.maxbytes = function (modelValue) { + return ngModel.$isEmpty(modelValue) || numberOfBytes(modelValue) <= attrs.maxbytes; + }; + } + + function endsWith(suffix, str) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + function paddingSize(base64String) { + if (endsWith('==', base64String)) { + return 2; + } + if (endsWith('=', base64String)) { + return 1; + } + return 0; + } + + function numberOfBytes(base64String) { + return base64String.length / 4 * 3 - paddingSize(base64String); + } + } + +})(); diff --git a/src/main/webapp/app/components/form/minbytes.directive.js b/src/main/webapp/app/components/form/minbytes.directive.js new file mode 100644 index 000000000..07009d4e8 --- /dev/null +++ b/src/main/webapp/app/components/form/minbytes.directive.js @@ -0,0 +1,45 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .directive('minbytes', minbytes); + + function minbytes () { + var directive = { + restrict: 'A', + require: '?ngModel', + link: linkFunc + }; + + return directive; + + function linkFunc (scope, element, attrs, ngModel) { + if (!ngModel) { + return; + } + + ngModel.$validators.minbytes = function (modelValue) { + return ngModel.$isEmpty(modelValue) || numberOfBytes(modelValue) >= attrs.minbytes; + }; + } + + function endsWith(suffix, str) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + function paddingSize(base64String) { + if (endsWith('==', base64String)) { + return 2; + } + if (endsWith('=', base64String)) { + return 1; + } + return 0; + } + + function numberOfBytes(base64String) { + return base64String.length / 4 * 3 - paddingSize(base64String); + } + } +})(); diff --git a/src/main/webapp/app/components/form/pagination.constants.js b/src/main/webapp/app/components/form/pagination.constants.js new file mode 100644 index 000000000..dac1b4c29 --- /dev/null +++ b/src/main/webapp/app/components/form/pagination.constants.js @@ -0,0 +1,9 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .constant('paginationConstants', { + 'itemsPerPage': 20 + }); +})(); diff --git a/src/main/webapp/app/components/form/show-validation.directive.js b/src/main/webapp/app/components/form/show-validation.directive.js new file mode 100644 index 000000000..8eb6ad62a --- /dev/null +++ b/src/main/webapp/app/components/form/show-validation.directive.js @@ -0,0 +1,36 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .directive('showValidation', showValidation); + + function showValidation () { + var directive = { + restrict: 'A', + require: 'form', + link: linkFunc + }; + + return directive; + + function linkFunc (scope, element, attrs, formCtrl) { + element.find('.form-group').each(function() { + var $formGroup = angular.element(this); + var $inputs = $formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]'); + + if ($inputs.length > 0) { + $inputs.each(function() { + var $input = angular.element(this); + var inputName = $input.attr('name'); + scope.$watch(function() { + return formCtrl[inputName].$invalid && formCtrl[inputName].$dirty; + }, function(isInvalid) { + $formGroup.toggleClass('has-error', isInvalid); + }); + }); + } + }); + } + } +})(); diff --git a/src/main/webapp/app/components/language/language.constants.js b/src/main/webapp/app/components/language/language.constants.js new file mode 100644 index 000000000..4ab96cfd4 --- /dev/null +++ b/src/main/webapp/app/components/language/language.constants.js @@ -0,0 +1,17 @@ +(function () { + 'use strict'; + + angular + .module('sprintApp') + + /* + Languages codes are ISO_639-1 codes, see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes + They are written in English to avoid character encoding issues (not a perfect solution) + */ + .constant('LANGUAGES', [ + 'it', + 'en' + // jhipster-needle-i18n-language-constant - JHipster will add/remove languages in this array + ] + ); +})(); diff --git a/src/main/webapp/app/components/language/language.controller.js b/src/main/webapp/app/components/language/language.controller.js new file mode 100644 index 000000000..0c16a0e6d --- /dev/null +++ b/src/main/webapp/app/components/language/language.controller.js @@ -0,0 +1,25 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('JhiLanguageController', JhiLanguageController); + + JhiLanguageController.$inject = ['$translate', 'JhiLanguageService', 'tmhDynamicLocale']; + + function JhiLanguageController ($translate, JhiLanguageService, tmhDynamicLocale) { + var vm = this; + + vm.changeLanguage = changeLanguage; + vm.languages = null; + + JhiLanguageService.getAll().then(function (languages) { + vm.languages = languages; + }); + + function changeLanguage (languageKey) { + $translate.use(languageKey); + tmhDynamicLocale.set(languageKey); + } + } +})(); diff --git a/src/main/webapp/app/components/language/language.filter.js b/src/main/webapp/app/components/language/language.filter.js new file mode 100644 index 000000000..38ce49208 --- /dev/null +++ b/src/main/webapp/app/components/language/language.filter.js @@ -0,0 +1,43 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .filter('findLanguageFromKey', findLanguageFromKey); + + function findLanguageFromKey() { + return findLanguageFromKeyFilter; + + function findLanguageFromKeyFilter(lang) { + return { + 'ca': 'Català', + 'cs': 'Český', + 'da': 'Dansk', + 'de': 'Deutsch', + 'el': 'Ελληνικά', + 'en': 'English', + 'es': 'Español', + 'fr': 'Français', + 'gl': 'Galego', + 'hu': 'Magyar', + 'hi': 'हिंदी', + 'it': 'Italiano', + 'ja': '日本語', + 'ko': '한국어', + 'mr': 'मराठी', + 'nl': 'Nederlands', + 'pl': 'Polski', + 'pt-br': 'Português (Brasil)', + 'pt-pt': 'Português', + 'ro': 'Română', + 'ru': 'Русский', + 'sk': 'Slovenský', + 'sv': 'Svenska', + 'ta': 'தமிழ்', + 'tr': 'Türkçe', + 'zh-cn': '中文(简体)', + 'zh-tw': '繁體中文' + }[lang]; + } + } +})(); diff --git a/src/main/webapp/app/components/language/language.service.js b/src/main/webapp/app/components/language/language.service.js new file mode 100644 index 000000000..0f17c32c2 --- /dev/null +++ b/src/main/webapp/app/components/language/language.service.js @@ -0,0 +1,33 @@ +(function () { + 'use strict'; + + angular + .module('sprintApp') + .factory('JhiLanguageService', JhiLanguageService); + + JhiLanguageService.$inject = ['$q', '$http', '$translate', 'LANGUAGES']; + + function JhiLanguageService ($q, $http, $translate, LANGUAGES) { + var service = { + getAll: getAll, + getCurrent: getCurrent + }; + + return service; + + function getAll () { + var deferred = $q.defer(); + deferred.resolve(LANGUAGES); + return deferred.promise; + } + + function getCurrent () { + var deferred = $q.defer(); + var language = $translate.storage().get('NG_TRANSLATE_LANG_KEY'); + + deferred.resolve(language); + + return deferred.promise; + } + } +})(); diff --git a/src/main/webapp/app/components/login/login.controller.js b/src/main/webapp/app/components/login/login.controller.js new file mode 100644 index 000000000..c5af4408c --- /dev/null +++ b/src/main/webapp/app/components/login/login.controller.js @@ -0,0 +1,73 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .controller('LoginController', LoginController); + + LoginController.$inject = ['$rootScope', '$state', '$timeout', 'Auth', '$uibModalInstance']; + + function LoginController ($rootScope, $state, $timeout, Auth, $uibModalInstance) { + var vm = this; + + vm.authenticationError = false; + vm.cancel = cancel; + vm.credentials = {}; + vm.login = login; + vm.password = null; + vm.register = register; + vm.rememberMe = true; + vm.requestResetPassword = requestResetPassword; + vm.username = null; + + $timeout(function (){angular.element('#username').focus();}); + + function cancel () { + vm.credentials = { + username: null, + password: null, + rememberMe: true + }; + vm.authenticationError = false; + $uibModalInstance.dismiss('cancel'); + } + + function login (event) { + event.preventDefault(); + Auth.login({ + username: vm.username, + password: vm.password, + rememberMe: vm.rememberMe + }).then(function () { + vm.authenticationError = false; + $uibModalInstance.close(); + if ($state.current.name === 'register' || $state.current.name === 'activate' || + $state.current.name === 'finishReset' || $state.current.name === 'requestReset') { + $state.go('home'); + } + + $rootScope.$broadcast('authenticationSuccess'); + + // previousState was set in the authExpiredInterceptor before being redirected to login modal. + // since login is succesful, go to stored previousState and clear previousState + if (Auth.getPreviousState()) { + var previousState = Auth.getPreviousState(); + Auth.resetPreviousState(); + $state.go(previousState.name, previousState.params); + } + }).catch(function () { + vm.authenticationError = true; + }); + } + + function register () { + $uibModalInstance.dismiss('cancel'); + $state.go('register'); + } + + function requestResetPassword () { + $uibModalInstance.dismiss('cancel'); + $state.go('requestReset'); + } + } +})(); diff --git a/src/main/webapp/app/components/login/login.html b/src/main/webapp/app/components/login/login.html new file mode 100644 index 000000000..6ee0e9d79 --- /dev/null +++ b/src/main/webapp/app/components/login/login.html @@ -0,0 +1,38 @@ + + diff --git a/src/main/webapp/app/components/login/login.service.js b/src/main/webapp/app/components/login/login.service.js new file mode 100644 index 000000000..f3bdc61c9 --- /dev/null +++ b/src/main/webapp/app/components/login/login.service.js @@ -0,0 +1,42 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('LoginService', LoginService); + + LoginService.$inject = ['$uibModal']; + + function LoginService ($uibModal) { + var service = { + open: open + }; + + var modalInstance = null; + var resetModal = function () { + modalInstance = null; + }; + + return service; + + function open () { + if (modalInstance !== null) return; + modalInstance = $uibModal.open({ + animation: true, + templateUrl: 'app/components/login/login.html', + controller: 'LoginController', + controllerAs: 'vm', + resolve: { + translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { + $translatePartialLoader.addPart('login'); + return $translate.refresh(); + }] + } + }); + modalInstance.result.then( + resetModal, + resetModal + ); + } + } +})(); diff --git a/src/main/webapp/app/components/util/base64.service.js b/src/main/webapp/app/components/util/base64.service.js new file mode 100644 index 000000000..cb1acc40d --- /dev/null +++ b/src/main/webapp/app/components/util/base64.service.js @@ -0,0 +1,92 @@ +(function() { + /*jshint bitwise: false*/ + 'use strict'; + + angular + .module('sprintApp') + .factory('Base64', Base64); + + function Base64 () { + var keyStr = 'ABCDEFGHIJKLMNOP' + + 'QRSTUVWXYZabcdef' + + 'ghijklmnopqrstuv' + + 'wxyz0123456789+/' + + '='; + + var service = { + decode : decode, + encode : encode + }; + + return service; + + function encode (input) { + var output = '', + chr1, chr2, chr3 = '', + enc1, enc2, enc3, enc4 = '', + i = 0; + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + keyStr.charAt(enc1) + + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + + keyStr.charAt(enc4); + chr1 = chr2 = chr3 = ''; + enc1 = enc2 = enc3 = enc4 = ''; + } + + return output; + } + + function decode (input) { + var output = '', + chr1, chr2, chr3 = '', + enc1, enc2, enc3, enc4 = '', + i = 0; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); + + while (i < input.length) { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + + chr1 = chr2 = chr3 = ''; + enc1 = enc2 = enc3 = enc4 = ''; + } + + return output; + } + } +})(); diff --git a/src/main/webapp/app/components/util/capitalize.filter.js b/src/main/webapp/app/components/util/capitalize.filter.js new file mode 100644 index 000000000..e5cbb2860 --- /dev/null +++ b/src/main/webapp/app/components/util/capitalize.filter.js @@ -0,0 +1,18 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .filter('capitalize', capitalize); + + function capitalize() { + return capitalizeFilter; + + function capitalizeFilter (input) { + if (input !== null) { + input = input.toLowerCase(); + } + return input.substring(0, 1).toUpperCase() + input.substring(1); + } + } +})(); diff --git a/src/main/webapp/app/components/util/data-util.service.js b/src/main/webapp/app/components/util/data-util.service.js new file mode 100644 index 000000000..166e369e1 --- /dev/null +++ b/src/main/webapp/app/components/util/data-util.service.js @@ -0,0 +1,74 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('DataUtils', DataUtils); + + DataUtils.$inject = ['$window']; + + function DataUtils ($window) { + + var service = { + abbreviate: abbreviate, + byteSize: byteSize, + openFile: openFile, + toBase64: toBase64 + }; + + return service; + + function abbreviate (text) { + if (!angular.isString(text)) { + return ''; + } + if (text.length < 30) { + return text; + } + return text ? (text.substring(0, 15) + '...' + text.slice(-10)) : ''; + } + + function byteSize (base64String) { + if (!angular.isString(base64String)) { + return ''; + } + + function endsWith(suffix, str) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + function paddingSize(base64String) { + if (endsWith('==', base64String)) { + return 2; + } + if (endsWith('=', base64String)) { + return 1; + } + return 0; + } + + function size(base64String) { + return base64String.length / 4 * 3 - paddingSize(base64String); + } + + function formatAsBytes(size) { + return size.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ') + ' bytes'; + } + + return formatAsBytes(size(base64String)); + } + + function openFile (type, data) { + $window.open('data:' + type + ';base64,' + data, '_blank', 'height=300,width=400'); + } + + function toBase64 (file, cb) { + var fileReader = new FileReader(); + fileReader.readAsDataURL(file); + fileReader.onload = function (e) { + var base64Data = e.target.result.substr(e.target.result.indexOf('base64,') + 'base64,'.length); + cb(base64Data); + }; + } + } +})(); diff --git a/src/main/webapp/app/components/util/date-util.service.js b/src/main/webapp/app/components/util/date-util.service.js new file mode 100644 index 000000000..983e6f2b3 --- /dev/null +++ b/src/main/webapp/app/components/util/date-util.service.js @@ -0,0 +1,50 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .factory('DateUtils', DateUtils); + + DateUtils.$inject = ['$filter']; + + function DateUtils ($filter) { + + var service = { + convertDateTimeFromServer : convertDateTimeFromServer, + convertLocalDateFromServer : convertLocalDateFromServer, + convertLocalDateToServer : convertLocalDateToServer, + dateformat : dateformat + }; + + return service; + + function convertDateTimeFromServer (date) { + if (date) { + return new Date(date); + } else { + return null; + } + } + + function convertLocalDateFromServer (date) { + if (date) { + var dateString = date.split('-'); + return new Date(dateString[0], dateString[1] - 1, dateString[2]); + } + return null; + } + + function convertLocalDateToServer (date) { + if (date) { + return $filter('date')(date, 'yyyy-MM-dd'); + } else { + return null; + } + } + + function dateformat () { + return 'yyyy-MM-dd'; + } + } + +})(); diff --git a/src/main/webapp/app/components/util/jhi-item-count.directive.js b/src/main/webapp/app/components/util/jhi-item-count.directive.js new file mode 100644 index 000000000..d54169cf3 --- /dev/null +++ b/src/main/webapp/app/components/util/jhi-item-count.directive.js @@ -0,0 +1,20 @@ +(function() { + 'use strict'; + + var jhiItemCount = { + template: '
' + + 'Showing {{(($ctrl.page - 1) * $ctrl.itemsPerPage) == 0 ? 1 : (($ctrl.page - 1) * $ctrl.itemsPerPage + 1)}} - ' + + '{{($ctrl.page * $ctrl.itemsPerPage) < $ctrl.queryCount ? ($ctrl.page * $ctrl.itemsPerPage) : $ctrl.queryCount}} ' + + 'of {{$ctrl.queryCount}} items.' + + '
', + bindings: { + page: '<', + queryCount: ' 1){ + return sort.split(',').slice(-1)[0] === 'asc'; + } else { + // default to true if no sort defined + return true; + } + } + + // query params are strings, and need to be parsed + function parsePage (page) { + return parseInt(page); + } + + // sort can be in the format `id,asc` or `id` + function parsePredicate (sort) { + var sortArray = sort.split(','); + if (sortArray.length > 1){ + sortArray.pop(); + } + return sortArray.join(','); + } + } +})(); diff --git a/src/main/webapp/app/components/util/parse-links.service.js b/src/main/webapp/app/components/util/parse-links.service.js new file mode 100644 index 000000000..63463d623 --- /dev/null +++ b/src/main/webapp/app/components/util/parse-links.service.js @@ -0,0 +1,46 @@ +(function(){ + 'use strict'; + + angular + .module('sprintApp') + .factory('ParseLinks', ParseLinks); + + function ParseLinks () { + + var service = { + parse : parse + }; + + return service; + + function parse(header) { + if (header.length === 0) { + throw new Error('input must not be of zero length'); + } + + // Split parts by comma + var parts = header.split(','); + var links = {}; + // Parse each part into a named link + angular.forEach(parts, function(p) { + var section = p.split(';'); + if (section.length !== 2) { + throw new Error('section could not be split on ";"'); + } + var url = section[0].replace(/<(.*)>/, '$1').trim(); + var queryString = {}; + url.replace( + new RegExp('([^?=&]+)(=([^&]*))?', 'g'), + function($0, $1, $2, $3) { queryString[$1] = $3; } + ); + var page = queryString.page; + if (angular.isString(page)) { + page = parseInt(page); + } + var name = section[1].replace(/rel="(.*)"/, '$1').trim(); + links[name] = page; + }); + return links; + } + } +})(); diff --git a/src/main/webapp/app/components/util/sort-by.directive.js b/src/main/webapp/app/components/util/sort-by.directive.js new file mode 100644 index 000000000..1e80fe02d --- /dev/null +++ b/src/main/webapp/app/components/util/sort-by.directive.js @@ -0,0 +1,24 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .directive('jhSortBy', jhSortBy); + + function jhSortBy() { + var directive = { + restrict: 'A', + scope: false, + require: '^jhSort', + link: linkFunc + }; + + return directive; + + function linkFunc(scope, element, attrs, parentCtrl) { + element.bind('click', function () { + parentCtrl.sort(attrs.jhSortBy); + }); + } + } +})(); diff --git a/src/main/webapp/app/components/util/sort.directive.js b/src/main/webapp/app/components/util/sort.directive.js new file mode 100644 index 000000000..7f47996ab --- /dev/null +++ b/src/main/webapp/app/components/util/sort.directive.js @@ -0,0 +1,80 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .directive('jhSort', jhSort); + + function jhSort () { + var directive = { + restrict: 'A', + scope: { + predicate: '=jhSort', + ascending: '=', + callback: '&' + }, + controller: SortController, + controllerAs: 'vm', + bindToController: true + }; + + return directive; + } + + SortController.$inject = ['$scope', '$element']; + + function SortController ($scope, $element) { + var vm = this; + + vm.applyClass = applyClass; + vm.resetClasses = resetClasses; + vm.sort = sort; + vm.triggerApply = triggerApply; + + $scope.$watchGroup(['vm.predicate', 'vm.ascending'], vm.triggerApply); + vm.triggerApply(); + + function applyClass (element) { + var thisIcon = element.find('span.glyphicon'), + sortIcon = 'glyphicon-sort', + sortAsc = 'glyphicon-sort-by-attributes', + sortDesc = 'glyphicon-sort-by-attributes-alt', + remove = sortIcon + ' ' + sortDesc, + add = sortAsc; + if (!vm.ascending) { + remove = sortIcon + ' ' + sortAsc; + add = sortDesc; + } + vm.resetClasses(); + thisIcon.removeClass(remove); + thisIcon.addClass(add); + } + + function resetClasses () { + var allThIcons = $element.find('span.glyphicon'), + sortIcon = 'glyphicon-sort', + sortAsc = 'glyphicon-sort-by-attributes', + sortDesc = 'glyphicon-sort-by-attributes-alt'; + allThIcons.removeClass(sortAsc + ' ' + sortDesc); + allThIcons.addClass(sortIcon); + } + + function sort (field) { + if (field !== vm.predicate) { + vm.ascending = true; + } else { + vm.ascending = !vm.ascending; + } + vm.predicate = field; + $scope.$apply(); + vm.callback(); + } + + function triggerApply (values) { + vm.resetClasses(); + if (values && values[0] !== '_score') { + vm.applyClass($element.find('th[jh-sort-by=\'' + values[0] + '\']')); + } + } + } +})(); diff --git a/src/main/webapp/app/components/util/truncate-characters.filter.js b/src/main/webapp/app/components/util/truncate-characters.filter.js new file mode 100644 index 000000000..c41573ca7 --- /dev/null +++ b/src/main/webapp/app/components/util/truncate-characters.filter.js @@ -0,0 +1,37 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .filter('characters', characters); + + function characters () { + return charactersFilter; + + function charactersFilter(input, chars, breakOnWord) { + if (isNaN(chars)) { + return input; + } + if (chars <= 0) { + return ''; + } + if (input && input.length > chars) { + input = input.substring(0, chars); + + if (!breakOnWord) { + var lastspace = input.lastIndexOf(' '); + // Get last space + if (lastspace !== -1) { + input = input.substr(0, lastspace); + } + } else { + while (input.charAt(input.length-1) === ' ') { + input = input.substr(0, input.length - 1); + } + } + return input + '...'; + } + return input; + } + } +})(); diff --git a/src/main/webapp/app/components/util/truncate-words.filter.js b/src/main/webapp/app/components/util/truncate-words.filter.js new file mode 100644 index 000000000..b6c708227 --- /dev/null +++ b/src/main/webapp/app/components/util/truncate-words.filter.js @@ -0,0 +1,28 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .filter('words', words); + + function words() { + return wordsFilter; + + function wordsFilter(input, words) { + if (isNaN(words)) { + return input; + } + if (words <= 0) { + return ''; + } + if (input) { + var inputWords = input.split(/\s+/); + if (inputWords.length > words) { + input = inputWords.slice(0, words).join(' ') + '...'; + } + } + + return input; + } + } +})(); diff --git a/src/main/webapp/app/entities/entity.state.js b/src/main/webapp/app/entities/entity.state.js new file mode 100644 index 000000000..d441fc51b --- /dev/null +++ b/src/main/webapp/app/entities/entity.state.js @@ -0,0 +1,16 @@ +(function() { + 'use strict'; + + angular + .module('sprintApp') + .config(stateConfig); + + stateConfig.$inject = ['$stateProvider']; + + function stateConfig($stateProvider) { + $stateProvider.state('entity', { + abstract: true, + parent: 'app' + }); + } +})(); diff --git a/src/main/webapp/app/forms/permessiFerieProcess/start.html b/src/main/webapp/app/forms/permessiFerieProcess/start.html new file mode 100644 index 000000000..8e95c69aa --- /dev/null +++ b/src/main/webapp/app/forms/permessiFerieProcess/start.html @@ -0,0 +1,41 @@ + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +