From 4aa0627451f424ff533b6fa715fc370ac3095c19 Mon Sep 17 00:00:00 2001 From: Miroslav Blasko Date: Sat, 2 Mar 2024 23:54:31 +0100 Subject: [PATCH] [Upd] Reformat with prettier --- .docker/error.html | 33 +- .github/workflows/merge-to-protected.yml | 4 +- .github/workflows/publish-docker-image.yml | 4 +- babel.config.js | 39 +- config/index.js | 6 +- deploy/internal-auth/docker-compose.yml | 12 +- deploy/internal-auth/nginx/error.html | 33 +- deploy/keycloak-auth/docker-compose.yml | 10 +- .../keycloak-auth/keycloak/realm-export.json | 277 +--- deploy/keycloak-auth/nginx/error.html | 33 +- doc/development.md | 16 +- doc/setup.md | 17 +- index.html | 9 +- jest.config.js | 26 +- public/config.js | 3 +- src/App.jsx | 62 +- src/Footer.jsx | 4 +- src/actions/AsyncActionUtils.js | 20 +- src/actions/AuthActions.js | 233 +-- src/actions/FormTemplatesActions.js | 47 +- src/actions/HistoryActions.js | 102 +- src/actions/InstitutionActions.js | 230 +-- src/actions/InstitutionsActions.js | 51 +- src/actions/MessageActions.js | 18 +- src/actions/RecordActions.js | 257 ++-- src/actions/RecordsActions.js | 166 ++- src/actions/RouterActions.js | 22 +- src/actions/StatisticsActions.js | 31 +- src/actions/UserActions.js | 480 +++--- src/actions/UsersActions.js | 49 +- src/actions/index.js | 57 +- src/components/AlertMessage.jsx | 20 +- src/components/DeleteItemDialog.jsx | 58 +- src/components/HelpIcon.jsx | 61 +- src/components/HorizontalInput.jsx | 330 +++-- src/components/ImpersonatorBadge.jsx | 24 +- src/components/Input.jsx | 160 +- src/components/Loader.jsx | 50 +- src/components/MainView.jsx | 292 ++-- src/components/dashboard/Dashboard.jsx | 278 ++-- .../dashboard/DashboardController.jsx | 169 +-- src/components/dashboard/DashboardTile.jsx | 13 +- src/components/history/HistoryDetail.jsx | 166 ++- src/components/history/HistoryList.jsx | 166 ++- src/components/history/HistoryRow.jsx | 43 +- src/components/history/HistorySearch.jsx | 72 +- src/components/history/HistoryTable.jsx | 59 +- src/components/institution/Institution.jsx | 253 ++-- .../institution/InstitutionController.jsx | 409 +++--- .../institution/InstitutionMembers.jsx | 224 +-- .../institution/InstitutionPatients.jsx | 58 +- src/components/institution/InstitutionRow.jsx | 68 +- .../institution/InstitutionTable.jsx | 145 +- src/components/institution/Institutions.jsx | 56 +- .../institution/InstitutionsController.jsx | 118 +- src/components/login/Login.jsx | 243 ++-- src/components/login/Logout.jsx | 36 +- src/components/login/PasswordReset.jsx | 187 +-- src/components/login/PasswordToken.jsx | 231 +-- src/components/message/Message.jsx | 45 +- src/components/message/Messages.jsx | 27 +- src/components/misc/FilterIndicator.jsx | 16 +- src/components/misc/Pagination.jsx | 96 +- src/components/misc/PromiseTrackingMask.jsx | 21 +- src/components/misc/SortIndicator.jsx | 44 +- src/components/misc/hoc/RequireAuth.jsx | 48 +- src/components/misc/oidc/IfInternalAuth.jsx | 2 +- src/components/misc/oidc/OidcAuthWrapper.jsx | 57 +- src/components/pages/OidcSignInCallback.jsx | 36 +- src/components/pages/OidcSilentCallback.jsx | 20 +- .../record/ExportRecordsDropdown.jsx | 41 +- src/components/record/ImportRecordsDialog.jsx | 94 +- src/components/record/Record.jsx | 369 +++-- src/components/record/RecordController.jsx | 381 ++--- src/components/record/RecordForm.jsx | 212 +-- src/components/record/RecordProvenance.jsx | 55 +- src/components/record/RecordRow.jsx | 129 +- src/components/record/RecordTable.jsx | 336 +++-- src/components/record/Records.jsx | 230 +-- src/components/record/RecordsController.jsx | 313 ++-- src/components/record/RequiredAttributes.jsx | 118 +- src/components/record/TypeaheadAnswer.jsx | 112 +- .../record/filter/DateIntervalFilter.jsx | 155 +- .../record/filter/InstitutionFilter.jsx | 97 +- src/components/record/filter/PhaseFilter.jsx | 89 +- src/components/statistics/Statistics.jsx | 63 +- src/components/user/PasswordChange.jsx | 213 +-- .../user/PasswordChangeController.jsx | 129 +- src/components/user/User.jsx | 596 ++++---- src/components/user/UserController.jsx | 404 +++--- src/components/user/UserRow.jsx | 70 +- src/components/user/UserTable.jsx | 134 +- src/components/user/Users.jsx | 49 +- src/components/user/UsersController.jsx | 124 +- src/constants/ActionConstants.js | 10 +- src/constants/DefaultConstants.js | 114 +- src/constants/ExportType.js | 18 +- src/constants/RoutesConstants.js | 38 +- src/constants/SupportedDevices.js | 56 +- src/constants/Vocabulary.js | 12 +- src/hooks/useI18n.jsx | 27 +- src/i18n/localization.js | 26 +- src/i18n/withI18n.jsx | 46 +- src/index.jsx | 31 +- src/model/Message.js | 93 +- src/model/RecordState.js | 46 +- src/reducers/AuthReducer.js | 224 +-- src/reducers/FormTemplatesReducer.js | 64 +- src/reducers/HistoryReducer.js | 122 +- src/reducers/InstitutionReducer.js | 204 +-- src/reducers/InstitutionsReducer.js | 64 +- src/reducers/IntlReducer.js | 4 +- src/reducers/MessageReducer.js | 39 +- src/reducers/RecordReducer.js | 266 ++-- src/reducers/RecordsReducer.js | 66 +- src/reducers/RouterReducer.js | 42 +- src/reducers/StatisticsReducer.js | 54 +- src/reducers/UserReducer.js | 492 +++---- src/reducers/UsersReducer.js | 64 +- src/reducers/index.js | 40 +- src/stores/I18nStore.js | 10 +- src/styles/record-manager.css | 996 ++++++------- src/utils/BrowserCompatibilityModal.jsx | 17 +- src/utils/BrowserStorage.js | 20 +- src/utils/DataFilter.js | 57 +- src/utils/EntityFactory.js | 58 +- src/utils/HistoryLogger.js | 50 +- src/utils/Logger.js | 28 +- src/utils/OidcUtils.js | 14 +- src/utils/Routes.jsx | 111 +- src/utils/Routing.js | 79 +- src/utils/RoutingRules.js | 12 +- src/utils/SecurityUtils.js | 22 +- src/utils/Utils.js | 397 ++--- src/utils/injectIntl.js | 30 +- src/validation/InstitutionValidator.jsx | 8 +- src/validation/RecordValidator.jsx | 22 +- src/validation/UserValidator.jsx | 14 +- tests/__mocks__/styleMock.js | 2 +- tests/__tests__/actions/AuthActions.spec.js | 515 ++++--- .../__tests__/actions/HistoryActions.spec.js | 187 +-- .../actions/InstitutionActions.spec.js | 600 ++++---- .../actions/InstitutionsActions.spec.js | 182 +-- tests/__tests__/actions/RecordActions.spec.js | 554 ++++--- .../__tests__/actions/RecordsActions.spec.js | 270 ++-- tests/__tests__/actions/RouterActions.spec.js | 44 +- .../actions/StatisticsActions.spec.js | 98 +- tests/__tests__/actions/UserActions.spec.js | 1084 +++++++------- tests/__tests__/actions/UsersActions.spec.js | 147 +- tests/__tests__/components/Dashboard.spec.js | 236 +-- tests/__tests__/components/HistoryRow.spec.js | 76 +- .../components/HistorySearch.spec.js | 53 +- .../__tests__/components/HistoryTable.spec.js | 54 +- .../__tests__/components/Institution.spec.js | 346 +++-- .../components/InstitutionMembers.spec.js | 341 +++-- .../components/InstitutionPatients.spec.js | 78 +- .../components/InstitutionRow.spec.js | 176 ++- .../components/InstitutionTable.spec.js | 90 +- .../__tests__/components/Institutions.spec.js | 209 +-- tests/__tests__/components/Loader.spec.js | 77 +- tests/__tests__/components/Pagination.spec.js | 37 +- .../components/PasswordChange.spec.js | 277 ++-- tests/__tests__/components/Record.spec.js | 384 +++-- .../components/RecordProvenance.spec.js | 117 +- tests/__tests__/components/RecordRow.spec.js | 186 +-- .../__tests__/components/RecordTable.spec.js | 129 +- tests/__tests__/components/Records.spec.js | 198 +-- .../components/RequiredAttributes.spec.js | 78 +- tests/__tests__/components/User.spec.js | 865 ++++++----- tests/__tests__/components/UserRow.spec.js | 178 +-- tests/__tests__/components/UserTable.spec.js | 96 +- tests/__tests__/components/Users.spec.js | 139 +- tests/__tests__/reducers/AuthReducer.spec.js | 568 ++++---- .../__tests__/reducers/HistoryReducer.spec.js | 309 ++-- .../reducers/InstitutionReducer.spec.js | 490 +++---- .../reducers/InstitutionsReducer.spec.js | 131 +- .../__tests__/reducers/RecordReducer.spec.js | 500 ++++--- .../__tests__/reducers/RecordsReducer.spec.js | 131 +- .../__tests__/reducers/RouterReducer.spec.js | 119 +- .../reducers/StatisticsReducer.spec.js | 128 +- tests/__tests__/reducers/UserReducer.spec.js | 1285 ++++++++--------- tests/__tests__/reducers/UsersReducer.spec.js | 144 +- tests/__tests__/utils/Utils.spec.js | 122 +- tests/environment/Environment.js | 4 +- tests/setup.js | 16 +- vite.config.js | 6 +- 186 files changed, 14322 insertions(+), 13206 deletions(-) diff --git a/.docker/error.html b/.docker/error.html index 7132ec71..bbd98b5a 100644 --- a/.docker/error.html +++ b/.docker/error.html @@ -1,19 +1,19 @@ - + - + - <!--# echo var="status" default="" --> <!--# echo var="status_text" default="Something goes wrong" --> - | SGoV Data Management + <!--# echo var="status" default="" --> <!--# echo var="status_text" default="Something goes wrong" --> | SGoV Data + Management - + - + - - -

We are updating our website

+ + +

We are updating our website

This is only for a few seconds, you will be redirected.

- -

- - - \ No newline at end of file + +

+ + +

+ + + diff --git a/.github/workflows/merge-to-protected.yml b/.github/workflows/merge-to-protected.yml index 5f68b915..281ec119 100644 --- a/.github/workflows/merge-to-protected.yml +++ b/.github/workflows/merge-to-protected.yml @@ -6,9 +6,9 @@ name: CI # events but only for the master branch on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml index 341e12c0..610c5c68 100644 --- a/.github/workflows/publish-docker-image.yml +++ b/.github/workflows/publish-docker-image.yml @@ -2,9 +2,9 @@ name: Publish Docker Image on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] workflow_dispatch: env: # Last fragment of identifier of the docker image diff --git a/babel.config.js b/babel.config.js index 9bda500b..103afa45 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,33 +1,28 @@ module.exports = { - "plugins": [ + plugins: [ "lodash", "@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime", "@babel/plugin-transform-nullish-coalescing-operator", - "@babel/plugin-transform-modules-commonjs" + "@babel/plugin-transform-modules-commonjs", ], - "presets": [ + presets: [ [ "@babel/preset-env", { - "modules": false, - "useBuiltIns": "usage", - "corejs": { - "version": 3, - "proposals": true - } - } + modules: false, + useBuiltIns: "usage", + corejs: { + version: 3, + proposals: true, + }, + }, ], - "@babel/preset-react" + "@babel/preset-react", ], - "env": { - "test": { - "presets": [ - [ - "@babel/preset-env" - ], - "@babel/preset-react" - ] - } - } -} + env: { + test: { + presets: [["@babel/preset-env"], "@babel/preset-react"], + }, + }, +}; diff --git a/config/index.js b/config/index.js index 4d451e63..f20e8c67 100644 --- a/config/index.js +++ b/config/index.js @@ -29,9 +29,7 @@ export const getEnv = (name, defaultValue) => { export const API_URL = getEnv("API_URL"); export const APP_TITLE = getEnv("APP_TITLE", "Record Manager"); export const LANGUAGE = getEnv("LANGUAGE", "en"); -export const NAVIGATOR_LANGUAGE = JSON.parse( - getEnv("NAVIGATOR_LANGUAGE", "true") -); +export const NAVIGATOR_LANGUAGE = JSON.parse(getEnv("NAVIGATOR_LANGUAGE", "true")); export const BASENAME = getEnv("BASENAME", ""); export const EXTENSIONS = getEnv("EXTENSIONS", ""); -export const APP_INFO = getEnv("APP_INFO", "© KBSS at FEE CTU in Prague, 2024"); \ No newline at end of file +export const APP_INFO = getEnv("APP_INFO", "© KBSS at FEE CTU in Prague, 2024"); diff --git a/deploy/internal-auth/docker-compose.yml b/deploy/internal-auth/docker-compose.yml index 06dbe9b8..4095f903 100644 --- a/deploy/internal-auth/docker-compose.yml +++ b/deploy/internal-auth/docker-compose.yml @@ -1,8 +1,8 @@ -version: '3.9' +version: "3.9" # Provide access to record-manager-ui that runs locally in dev mode x-access-for-local-development: &local-dev-env - cors.allowedOrigins: "http://localhost:4173,http://localhost:5173" + cors.allowedOrigins: "http://localhost:4173,http://localhost:5173" services: nginx: @@ -45,7 +45,7 @@ services: image: ghcr.io/kbss-cvut/kbss-cvut/record-manager:latest container_name: ${RECORD_SET_NAME:-rm}-record-manager-server expose: - - "8080" + - "8080" restart: always depends_on: - s-pipes-engine @@ -61,7 +61,7 @@ services: image: ghcr.io/kbss-cvut/s-pipes/s-pipes-engine:latest container_name: ${RECORD_SET_NAME:-rm}-s-pipes-engine expose: - - "8080" + - "8080" restart: always depends_on: - db-server @@ -78,11 +78,11 @@ services: environment: GDB_JAVA_OPTS: "-Dgraphdb.external-url=${PUBLIC_ORIGIN:-http://localhost:${INTERNAL_HOST_PORT:-1235}}${RECORD_MANAGER_ROOT_PATH:-/record-manager}/services/db-server" expose: - - "7200" + - "7200" restart: always volumes: - ../shared/db-server/init-data/forms:/root/graphdb-import/forms:ro - db-server:/opt/graphdb/home volumes: - db-server: + db-server: diff --git a/deploy/internal-auth/nginx/error.html b/deploy/internal-auth/nginx/error.html index 3c7fce07..d1f35ad0 100644 --- a/deploy/internal-auth/nginx/error.html +++ b/deploy/internal-auth/nginx/error.html @@ -1,20 +1,17 @@ - + - - - <!--# echo var="status" default="" --> - | Record manager - - + + <!--# echo var="status" default="" --> | Record manager + - + - - -

The application is currently being updated

-

You will be redirected to the new version in a few seconds.

-

If you see this message for more than a minute, something has gone wrong.

- -

Sorry, something went wrong.

+ + +

The application is currently being updated

+

You will be redirected to the new version in a few seconds.

+

If you see this message for more than a minute, something has gone wrong.

+ +

Sorry, something went wrong.

- - + + diff --git a/deploy/keycloak-auth/docker-compose.yml b/deploy/keycloak-auth/docker-compose.yml index 3bf53888..415673dc 100644 --- a/deploy/keycloak-auth/docker-compose.yml +++ b/deploy/keycloak-auth/docker-compose.yml @@ -1,8 +1,8 @@ -version: '3.9' +version: "3.9" # Provide access to record-manager-ui that runs locally in dev mode x-access-for-local-development: &local-dev-env - cors.allowedOrigins: "http://localhost:3000" + cors.allowedOrigins: "http://localhost:3000" services: nginx: @@ -48,7 +48,7 @@ services: image: ghcr.io/kbss-cvut/kbss-cvut/record-manager:latest container_name: ${RECORD_SET_NAME:-rm}-record-manager-server expose: - - "8080" + - "8080" restart: always depends_on: - s-pipes-engine @@ -67,7 +67,7 @@ services: image: ghcr.io/kbss-cvut/s-pipes/s-pipes-engine:latest container_name: ${RECORD_SET_NAME:-rm}-s-pipes-engine expose: - - "8080" + - "8080" restart: always depends_on: - db-server @@ -84,7 +84,7 @@ services: environment: GDB_JAVA_OPTS: "-Dgraphdb.external-url=${PUBLIC_ORIGIN:-http://localhost:${INTERNAL_HOST_PORT:-1235}}${RECORD_MANAGER_ROOT_PATH:-/record-manager}/services/db-server" expose: - - "7200" + - "7200" restart: always volumes: - ../shared/db-server/init-data/forms:/root/graphdb-import/forms:ro diff --git a/deploy/keycloak-auth/keycloak/realm-export.json b/deploy/keycloak-auth/keycloak/realm-export.json index 62243669..fe3afb7f 100644 --- a/deploy/keycloak-auth/keycloak/realm-export.json +++ b/deploy/keycloak-auth/keycloak/realm-export.json @@ -87,15 +87,9 @@ "description": "${role_default-roles}", "composite": true, "composites": { - "realm": [ - "offline_access", - "uma_authorization" - ], + "realm": ["offline_access", "uma_authorization"], "client": { - "account": [ - "view-profile", - "manage-account" - ] + "account": ["view-profile", "manage-account"] } }, "clientRole": false, @@ -244,10 +238,7 @@ "composite": true, "composites": { "client": { - "realm-management": [ - "query-groups", - "query-users" - ] + "realm-management": ["query-groups", "query-users"] } }, "clientRole": true, @@ -306,9 +297,7 @@ "composite": true, "composites": { "client": { - "realm-management": [ - "query-clients" - ] + "realm-management": ["query-clients"] } }, "clientRole": true, @@ -383,9 +372,7 @@ "composite": true, "composites": { "client": { - "account": [ - "view-consent" - ] + "account": ["view-consent"] } }, "clientRole": true, @@ -399,9 +386,7 @@ "composite": true, "composites": { "client": { - "account": [ - "manage-account-links" - ] + "account": ["manage-account-links"] } }, "clientRole": true, @@ -431,9 +416,7 @@ "clientRole": false, "containerId": "7647bef1-9609-47ff-9547-1071b1d6379b" }, - "requiredCredentials": [ - "password" - ], + "requiredCredentials": ["password"], "otpPolicyType": "totp", "otpPolicyAlgorithm": "HmacSHA1", "otpPolicyInitialCounter": 0, @@ -441,15 +424,9 @@ "otpPolicyLookAheadWindow": 1, "otpPolicyPeriod": 30, "otpPolicyCodeReusable": false, - "otpSupportedApplications": [ - "totpAppFreeOTPName", - "totpAppMicrosoftAuthenticatorName", - "totpAppGoogleName" - ], + "otpSupportedApplications": ["totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName"], "webAuthnPolicyRpEntityName": "keycloak", - "webAuthnPolicySignatureAlgorithms": [ - "ES256" - ], + "webAuthnPolicySignatureAlgorithms": ["ES256"], "webAuthnPolicyRpId": "", "webAuthnPolicyAttestationConveyancePreference": "not specified", "webAuthnPolicyAuthenticatorAttachment": "not specified", @@ -459,9 +436,7 @@ "webAuthnPolicyAvoidSameAuthenticatorRegister": false, "webAuthnPolicyAcceptableAaguids": [], "webAuthnPolicyPasswordlessRpEntityName": "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms": [ - "ES256" - ], + "webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"], "webAuthnPolicyPasswordlessRpId": "", "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", @@ -473,19 +448,14 @@ "scopeMappings": [ { "clientScope": "offline_access", - "roles": [ - "offline_access" - ] + "roles": ["offline_access"] } ], "clientScopeMappings": { "account": [ { "client": "account-console", - "roles": [ - "manage-account", - "view-groups" - ] + "roles": ["manage-account", "view-groups"] } ] }, @@ -500,9 +470,7 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/realms/record-manager/account/*" - ], + "redirectUris": ["/realms/record-manager/account/*"], "webOrigins": [], "notBefore": 0, "bearerOnly": false, @@ -520,19 +488,8 @@ "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "2a5379d5-735e-4a49-92db-826d82f95f22", @@ -544,12 +501,8 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/realms/record-manager/account/*" - ], - "webOrigins": [ - "http://localhost" - ], + "redirectUris": ["/realms/record-manager/account/*"], + "webOrigins": ["http://localhost"], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -577,19 +530,8 @@ "config": {} } ], - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "84973a1b-f155-44a6-852f-1e346ce0c75b", @@ -615,19 +557,8 @@ "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "d104f818-edcf-4a57-89b7-fd5706fa6a30", @@ -653,19 +584,8 @@ "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "f3d0cdb7-e994-44a7-9f3d-8a2f9d26c3e0", @@ -691,19 +611,8 @@ "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "34eebec0-1e19-4eab-af04-8729a1de47f4", @@ -718,12 +627,8 @@ "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "secret": "**********", - "redirectUris": [ - "/*" - ], - "webOrigins": [ - "/*" - ], + "redirectUris": ["/*"], + "webOrigins": ["/*"], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -744,19 +649,8 @@ "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": true, "nodeReRegistrationTimeout": -1, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "d6e815c8-6fd6-4ef6-acf7-2c099b5010fc", @@ -770,12 +664,8 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "http://localhost/*" - ], - "webOrigins": [ - "http://localhost" - ], + "redirectUris": ["http://localhost/*"], + "webOrigins": ["http://localhost"], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -796,19 +686,8 @@ "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": true, "nodeReRegistrationTimeout": -1, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] }, { "id": "ef60d6bd-1c86-4aef-8acb-9311f581b186", @@ -820,12 +699,8 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/admin/record-manager/console/*" - ], - "webOrigins": [ - "+" - ], + "redirectUris": ["/admin/record-manager/console/*"], + "webOrigins": ["+"], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -860,19 +735,8 @@ } } ], - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] + "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] } ], "clientScopes": [ @@ -1383,20 +1247,8 @@ ] } ], - "defaultDefaultClientScopes": [ - "role_list", - "profile", - "email", - "roles", - "web-origins", - "acr" - ], - "defaultOptionalClientScopes": [ - "offline_access", - "address", - "phone", - "microprofile-jwt" - ], + "defaultDefaultClientScopes": ["role_list", "profile", "email", "roles", "web-origins", "acr"], + "defaultOptionalClientScopes": ["offline_access", "address", "phone", "microprofile-jwt"], "browserSecurityHeaders": { "contentSecurityPolicyReportOnly": "", "xContentTypeOptions": "nosniff", @@ -1409,10 +1261,7 @@ }, "smtpServer": {}, "eventsEnabled": false, - "eventsListeners": [ - "keycloak-graphdb-user-replicator", - "jboss-logging" - ], + "eventsListeners": ["keycloak-graphdb-user-replicator", "jboss-logging"], "enabledEventTypes": [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", @@ -1526,9 +1375,7 @@ "subType": "anonymous", "subComponents": {}, "config": { - "allow-default-scopes": [ - "true" - ] + "allow-default-scopes": ["true"] } }, { @@ -1546,9 +1393,7 @@ "subType": "anonymous", "subComponents": {}, "config": { - "max-clients": [ - "200" - ] + "max-clients": ["200"] } }, { @@ -1566,9 +1411,7 @@ "subType": "authenticated", "subComponents": {}, "config": { - "allow-default-scopes": [ - "true" - ] + "allow-default-scopes": ["true"] } }, { @@ -1578,12 +1421,8 @@ "subType": "anonymous", "subComponents": {}, "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] + "host-sending-registration-request-must-match": ["true"], + "client-uris-must-match": ["true"] } }, { @@ -1613,12 +1452,8 @@ "providerId": "hmac-generated", "subComponents": {}, "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] + "priority": ["100"], + "algorithm": ["HS256"] } }, { @@ -1627,9 +1462,7 @@ "providerId": "rsa-generated", "subComponents": {}, "config": { - "priority": [ - "100" - ] + "priority": ["100"] } }, { @@ -1638,12 +1471,8 @@ "providerId": "rsa-enc-generated", "subComponents": {}, "config": { - "priority": [ - "100" - ], - "algorithm": [ - "RSA-OAEP" - ] + "priority": ["100"], + "algorithm": ["RSA-OAEP"] } }, { @@ -1652,9 +1481,7 @@ "providerId": "aes-generated", "subComponents": {}, "config": { - "priority": [ - "100" - ] + "priority": ["100"] } } ] @@ -2305,4 +2132,4 @@ "clientPolicies": { "policies": [] } -} \ No newline at end of file +} diff --git a/deploy/keycloak-auth/nginx/error.html b/deploy/keycloak-auth/nginx/error.html index 3c7fce07..d1f35ad0 100644 --- a/deploy/keycloak-auth/nginx/error.html +++ b/deploy/keycloak-auth/nginx/error.html @@ -1,20 +1,17 @@ - + - - - <!--# echo var="status" default="" --> - | Record manager - - + + <!--# echo var="status" default="" --> | Record manager + - + - - -

The application is currently being updated

-

You will be redirected to the new version in a few seconds.

-

If you see this message for more than a minute, something has gone wrong.

- -

Sorry, something went wrong.

+ + +

The application is currently being updated

+

You will be redirected to the new version in a few seconds.

+

If you see this message for more than a minute, something has gone wrong.

+ +

Sorry, something went wrong.

- - + + diff --git a/doc/development.md b/doc/development.md index fd9bf310..5511ddd5 100644 --- a/doc/development.md +++ b/doc/development.md @@ -5,33 +5,33 @@ This file contains info for contributors to the Record Manager UI codebase. ## Running in Development Mode To configure the application use [Setup Guide](./setup.md). -To run the application in development mode use `npm run dev`. +To run the application in development mode use `npm run dev`. By default, the application is accessible from http://localhost:3000. ### Running with Dockerized Services and Internal Authorization -This section describes the development scenario when developer uses +This section describes the development scenario when developer uses [dockerized services with internal authorization](../deploy/internal-auth/docker-compose.yml) to develop. All the services, including dockerized record-manager-ui, run by default at URL starting with `http://localhost:1235/record-manager`. -To attach simultaneously frontend for the development use setup from [.env.internal-auth](../.env.internal-auth), +To attach simultaneously frontend for the development use setup from [.env.internal-auth](../.env.internal-auth), e.g., by running `ln -s .env.internal-auth .env; npm run dev`. ### Running with Dockerized Services and Keycloak Authorization -This section describes the development scenario when developer uses +This section describes the development scenario when developer uses [dockerized services with keycloak authorization](../deploy/keycloak-auth/docker-compose.yml) to develop. All the services, including dockerized record-manager-ui, run by default at URL starting with `http://localhost:1235/record-manager`. -To attach simultaneously frontend for the development use setup from [.env.keyclaok-auth](../.env.keyclaok-auth), +To attach simultaneously frontend for the development use setup from [.env.keyclaok-auth](../.env.keyclaok-auth), e.g., by running `ln -s .env.keycloak-auth .env; npm run dev`. -`npm run dev` starts developement version of record-manager-ui at `http://localhost:3000`. In order to login to through keycloak `record-manager` realm needs to be configured: open the `record-manager` realm, under _Clients_ open the `record-manager` client and set +`npm run dev` starts developement version of record-manager-ui at `http://localhost:3000`. In order to login to through keycloak `record-manager` realm needs to be configured: open the `record-manager` realm, under _Clients_ open the `record-manager` client and set _Valid redirect URIs_ (by default it should be `http://localhost:3000/*`) and _Web Origins_ (by default it should be `http://localhost:3000`). ### Running with all Services in Development Mode This section describes the development scenario when the developer runs all dependent services in development mode. -By default, Record Manager UI runs at `http://localhost:3000` while Record Manager Server runs at different port. -This requires setting up the CORS policy of the server appropriately, i.e., configuring `config.properties` +By default, Record Manager UI runs at `http://localhost:3000` while Record Manager Server runs at different port. +This requires setting up the CORS policy of the server appropriately, i.e., configuring `config.properties` to contain `security.sameSite=None` and set up also `cors.allowedOrigin` if needed. ## Adding Configuration Parameters diff --git a/doc/setup.md b/doc/setup.md index 64291c1c..2e55ba79 100644 --- a/doc/setup.md +++ b/doc/setup.md @@ -11,6 +11,7 @@ This guide provides information on how to build and deploy Record Manager UI. ### Setup Uses `.env` to configure options like: + - url of backend - application title in browser - internationalization settings @@ -32,16 +33,21 @@ By default, if no `.env` is provided the application runs at `http://locahost:12 #### Set up behind reverse proxy It is possible to set up Record Manager behind reverse proxy using variables: + - `PUBLIC_ORIGIN` -- Public origin of URL where Record Manager UI will run, e.g. `https://kbss.fel.cvut.cz`, `http://kbss.fel.cvut.cz:8080`, `http://localhost`. - `RECORD_MANAGER_ROOT_PATH` - Path to Record Manager UI (by default it is set to "/record-manager"). Example set up with reverse proxy: -1) create `.env` file with following variables: + +1. create `.env` file with following variables: + ``` PUBLIC_ORIGIN=http://localhost RECORD_MANAGER_ROOT_PATH=/record-manager-example ``` -2) set up apache2 reverse proxy on the host computer: + +2. set up apache2 reverse proxy on the host computer: + ``` @@ -50,13 +56,14 @@ RECORD_MANAGER_ROOT_PATH=/record-manager-example ``` -3) run the Record Manager UI at http://localhost/record-manager-example + +3. run the Record Manager UI at http://localhost/record-manager-example ### Set up with Keycloak Authorization The deployment is pretty much self-contained based on [docker-compose.yml](../deploy/keycloak-auth-no-proxy/docker-compose.yml). It sets up the corresponding repositories, imports a realm where clients -are configured for both the Record Manager backend and frontend. All the services (except PostgreSQL used by Keycloak) -in the deployment export their ports to the host system, so ensure the following ports are available on your system: +are configured for both the Record Manager backend and frontend. All the services (except PostgreSQL used by Keycloak) +in the deployment export their ports to the host system, so ensure the following ports are available on your system: 3000, 8080, 8081, 8088. To run the deployment for the first time, follow these steps: diff --git a/index.html b/index.html index ba01acdf..a4207409 100644 --- a/index.html +++ b/index.html @@ -1,16 +1,13 @@ - + - +
- \ No newline at end of file + diff --git a/jest.config.js b/jest.config.js index 46d50275..e6209459 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,15 +1,15 @@ module.exports = { - roots: [''], - moduleFileExtensions: ['js', 'jsx', 'json'], - setupFiles: ['/tests/setup.js'], - testEnvironment: 'jsdom', - testURL: 'http://localhost:8080/record-manager', - transform: { - '^.+\\.(js|jsx)$': 'babel-jest' - }, - transformIgnorePatterns: ["node_modules/(?!@kbss-cvut)/"], - reporters: ['default'], - "moduleNameMapper": { - "\\.(css)$": "/tests/__mocks__/styleMock.js" - } + roots: [""], + moduleFileExtensions: ["js", "jsx", "json"], + setupFiles: ["/tests/setup.js"], + testEnvironment: "jsdom", + testURL: "http://localhost:8080/record-manager", + transform: { + "^.+\\.(js|jsx)$": "babel-jest", + }, + transformIgnorePatterns: ["node_modules/(?!@kbss-cvut)/"], + reporters: ["default"], + moduleNameMapper: { + "\\.(css)$": "/tests/__mocks__/styleMock.js", + }, }; diff --git a/public/config.js b/public/config.js index 26de3d32..5045f68f 100644 --- a/public/config.js +++ b/public/config.js @@ -1,3 +1,2 @@ // This file gets replaced when run within Docker -window.__config__ = { -} \ No newline at end of file +window.__config__ = {}; diff --git a/src/App.jsx b/src/App.jsx index cdce2ebd..b524abaa 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,42 +1,46 @@ import React, { useEffect } from "react"; -import {IntlProvider} from "react-intl"; -import {Route, Router, Switch} from "react-router-dom"; +import { IntlProvider } from "react-intl"; +import { Route, Router, Switch } from "react-router-dom"; import MainView from "./components/MainView"; -import {connect} from "react-redux"; -import {history} from "./utils/Routing"; -import {APP_TITLE, BASENAME} from "../config"; +import { connect } from "react-redux"; +import { history } from "./utils/Routing"; +import { APP_TITLE, BASENAME } from "../config"; import OidcAuthWrapper from "./components/misc/oidc/OidcAuthWrapper"; import OidcSignInCallback from "./components/pages/OidcSignInCallback"; import OidcSilentCallback from "./components/pages/OidcSilentCallback"; -import {isUsingOidcAuth} from "./utils/OidcUtils"; -import 'bootstrap/dist/css/bootstrap.min.css'; -import "./styles/record-manager.css" -import "@kbss-cvut/s-forms/css" +import { isUsingOidcAuth } from "./utils/OidcUtils"; +import "bootstrap/dist/css/bootstrap.min.css"; +import "./styles/record-manager.css"; +import "@kbss-cvut/s-forms/css"; import { BrowserCompatibilityModal } from "./utils/BrowserCompatibilityModal"; const App = (props) => { - useEffect(() => { - document.title = APP_TITLE; - }, [APP_TITLE]); - - return - - - - - - - - - ; -} + useEffect(() => { + document.title = APP_TITLE; + }, [APP_TITLE]); + + return ( + + + + + + + + + + + ); +}; const OidcMainView = () => { - return - - ; -} + return ( + + + + ); +}; export default connect((state) => { - return {intl: state.intl} + return { intl: state.intl }; })(App); diff --git a/src/Footer.jsx b/src/Footer.jsx index 2a1a7b19..23395447 100644 --- a/src/Footer.jsx +++ b/src/Footer.jsx @@ -1,6 +1,6 @@ import React from "react"; -import packageJson from '../package.json'; -import { APP_INFO } from '../config'; +import packageJson from "../package.json"; +import { APP_INFO } from "../config"; export const Footer = () => { return ( diff --git a/src/actions/AsyncActionUtils.js b/src/actions/AsyncActionUtils.js index 60746069..9bccd2b2 100644 --- a/src/actions/AsyncActionUtils.js +++ b/src/actions/AsyncActionUtils.js @@ -1,21 +1,21 @@ -import {publishMessage} from "./MessageActions"; -import {errorMessage} from "../model/Message"; +import { publishMessage } from "./MessageActions"; +import { errorMessage } from "../model/Message"; export function asyncRequest(type) { - return {type}; + return { type }; } export function asyncError(type, error) { - return { - type, - error - }; + return { + type, + error, + }; } export function asyncSuccess(type) { - return {type}; + return { type }; } export function showServerResponseErrorMessage(error, i18nMessageId) { - return publishMessage(errorMessage(i18nMessageId, {error: error.response.data.message})) -} \ No newline at end of file + return publishMessage(errorMessage(i18nMessageId, { error: error.response.data.message })); +} diff --git a/src/actions/AuthActions.js b/src/actions/AuthActions.js index 3f4ccb73..dec7f352 100644 --- a/src/actions/AuthActions.js +++ b/src/actions/AuthActions.js @@ -1,151 +1,168 @@ -import {axiosBackend} from "./index"; -import {transitionToHome} from "../utils/Routing"; +import { axiosBackend } from "./index"; +import { transitionToHome } from "../utils/Routing"; import * as ActionConstants from "../constants/ActionConstants"; -import {API_URL} from '../../config'; -import {IMPERSONATOR_TYPE} from "../constants/Vocabulary"; -import {IMPERSONATE_LOGOUT_SUCCESS, IMPERSONATE_PENDING} from "../constants/ActionConstants"; -import {MediaType} from "../constants/DefaultConstants"; +import { API_URL } from "../../config"; +import { IMPERSONATOR_TYPE } from "../constants/Vocabulary"; +import { IMPERSONATE_LOGOUT_SUCCESS, IMPERSONATE_PENDING } from "../constants/ActionConstants"; +import { MediaType } from "../constants/DefaultConstants"; export function login(username, password) { - return function (dispatch) { - dispatch(userAuthPending()); - axiosBackend.post(`${API_URL}/j_spring_security_check`, `username=${username}&password=${password}`, - { - headers: {'Content-Type': MediaType.FORM_URLENCODED} - }).then((response) => { - const data = response.data; - if (!data.success || !data.loggedIn) { - response.data.username = username; - dispatch(userAuthError(response.data)); - return; - } - dispatch(userAuthSuccess(username)); - dispatch(loadUserProfile()); - try { - transitionToHome(); - } catch (e) {/* caused test warning */ - } - }).catch((error) => { - dispatch(userAuthError(error?.response?.data)); - }); - } + return function (dispatch) { + dispatch(userAuthPending()); + axiosBackend + .post(`${API_URL}/j_spring_security_check`, `username=${username}&password=${password}`, { + headers: { "Content-Type": MediaType.FORM_URLENCODED }, + }) + .then((response) => { + const data = response.data; + if (!data.success || !data.loggedIn) { + response.data.username = username; + dispatch(userAuthError(response.data)); + return; + } + dispatch(userAuthSuccess(username)); + dispatch(loadUserProfile()); + try { + transitionToHome(); + } catch (e) { + /* caused test warning */ + } + }) + .catch((error) => { + dispatch(userAuthError(error?.response?.data)); + }); + }; } export function userAuthPending() { - return { - type: ActionConstants.AUTH_USER_PENDING - } + return { + type: ActionConstants.AUTH_USER_PENDING, + }; } export function userAuthSuccess(username) { - return { - type: ActionConstants.AUTH_USER_SUCCESS, - username - } + return { + type: ActionConstants.AUTH_USER_SUCCESS, + username, + }; } export function userAuthError(error) { - return { - type: ActionConstants.AUTH_USER_ERROR, - error - } + return { + type: ActionConstants.AUTH_USER_ERROR, + error, + }; } export function logout() { - return function (dispatch, getState) { - if (getState().auth.user.types.indexOf(IMPERSONATOR_TYPE) !== -1) { - return logoutImpersonator(dispatch); - } - return axiosBackend.post(`${API_URL}/j_spring_security_logout`).then(() => { - dispatch(unauthUser()); - }).catch((error) => { - dispatch(userAuthError(error?.response?.data)); - }); + return function (dispatch, getState) { + if (getState().auth.user.types.indexOf(IMPERSONATOR_TYPE) !== -1) { + return logoutImpersonator(dispatch); } + return axiosBackend + .post(`${API_URL}/j_spring_security_logout`) + .then(() => { + dispatch(unauthUser()); + }) + .catch((error) => { + dispatch(userAuthError(error?.response?.data)); + }); + }; } function logoutImpersonator(dispatch) { - dispatch({type: IMPERSONATE_PENDING}); - return axiosBackend.post(`${API_URL}/rest/users/impersonate/logout`) - .then(() => { - dispatch({type: IMPERSONATE_LOGOUT_SUCCESS}); - transitionToHome(); - window.location.reload(); - }) - .catch((error) => { - dispatch(userAuthError(error.response.data)); - }); + dispatch({ type: IMPERSONATE_PENDING }); + return axiosBackend + .post(`${API_URL}/rest/users/impersonate/logout`) + .then(() => { + dispatch({ type: IMPERSONATE_LOGOUT_SUCCESS }); + transitionToHome(); + window.location.reload(); + }) + .catch((error) => { + dispatch(userAuthError(error.response.data)); + }); } export function unauthUser() { - return { - type: ActionConstants.UNAUTH_USER - } + return { + type: ActionConstants.UNAUTH_USER, + }; } export function loadUserProfile() { - //console.log("Loading user profile"); - return function (dispatch) { - dispatch(loadUserProfilePending()); - axiosBackend.get(`${API_URL}/rest/users/current`).then((response) => { - dispatch(loadUserProfileSuccess(response.data)); - }).catch((error) => { - dispatch(loadUserProfileError(error && error.response ? error.response.data : error)); - }); - } + //console.log("Loading user profile"); + return function (dispatch) { + dispatch(loadUserProfilePending()); + axiosBackend + .get(`${API_URL}/rest/users/current`) + .then((response) => { + dispatch(loadUserProfileSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadUserProfileError(error && error.response ? error.response.data : error)); + }); + }; } export function loadUserProfilePending() { - return { - type: ActionConstants.LOAD_USER_PROFILE_PENDING - } + return { + type: ActionConstants.LOAD_USER_PROFILE_PENDING, + }; } export function loadUserProfileSuccess(user) { - return { - type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, - user - } + return { + type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, + user, + }; } export function loadUserProfileError(error) { - return { - type: ActionConstants.LOAD_USER_PROFILE_ERROR, - error - } + return { + type: ActionConstants.LOAD_USER_PROFILE_ERROR, + error, + }; } export function passwordReset(email) { - return function (dispatch) { - dispatch({type: ActionConstants.PASSWORD_RESET_PENDING}); - axiosBackend.post(`${API_URL}/rest/users/password-reset`, email, {headers: {"Content-Type": "text/plain"}}) - .then(() => { - dispatch({type: ActionConstants.PASSWORD_RESET_SUCCESS, email}); - }).catch(() => { - dispatch({type: ActionConstants.PASSWORD_RESET_ERROR}); - }); - } + return function (dispatch) { + dispatch({ type: ActionConstants.PASSWORD_RESET_PENDING }); + axiosBackend + .post(`${API_URL}/rest/users/password-reset`, email, { headers: { "Content-Type": "text/plain" } }) + .then(() => { + dispatch({ type: ActionConstants.PASSWORD_RESET_SUCCESS, email }); + }) + .catch(() => { + dispatch({ type: ActionConstants.PASSWORD_RESET_ERROR }); + }); + }; } export function validateToken(token) { - return function (dispatch) { - dispatch({type: ActionConstants.VALIDATE_TOKEN_PENDING}); - axiosBackend.post(`${API_URL}/rest/users/validate-token`, token, {headers: {"Content-Type": "text/plain"}}) - .then(() => { - dispatch({type: ActionConstants.VALIDATE_TOKEN_SUCCESS}); - }).catch(() => { - dispatch({type: ActionConstants.VALIDATE_TOKEN_ERROR}); - }); - } + return function (dispatch) { + dispatch({ type: ActionConstants.VALIDATE_TOKEN_PENDING }); + axiosBackend + .post(`${API_URL}/rest/users/validate-token`, token, { headers: { "Content-Type": "text/plain" } }) + .then(() => { + dispatch({ type: ActionConstants.VALIDATE_TOKEN_SUCCESS }); + }) + .catch(() => { + dispatch({ type: ActionConstants.VALIDATE_TOKEN_ERROR }); + }); + }; } export function changePasswordToken(password, token) { - return function (dispatch) { - dispatch({type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING}); - axiosBackend.put(`${API_URL}/rest/users/password-change-token`, {token, password}).then(() => { - dispatch({type: ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS}); - }).catch(() => { - dispatch({type: ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR}); - }); - } -} \ No newline at end of file + return function (dispatch) { + dispatch({ type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING }); + axiosBackend + .put(`${API_URL}/rest/users/password-change-token`, { token, password }) + .then(() => { + dispatch({ type: ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS }); + }) + .catch(() => { + dispatch({ type: ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR }); + }); + }; +} diff --git a/src/actions/FormTemplatesActions.js b/src/actions/FormTemplatesActions.js index 85ba4248..d5710cf3 100644 --- a/src/actions/FormTemplatesActions.js +++ b/src/actions/FormTemplatesActions.js @@ -1,34 +1,37 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {axiosBackend} from "./index"; -import {API_URL} from '../../config'; +import { axiosBackend } from "./index"; +import { API_URL } from "../../config"; export function loadFormTemplates() { - return function (dispatch) { - dispatch(loadFormTemplatesPending()); - axiosBackend.get(`${API_URL}/rest/formGen/formTemplates`).then((response) => { - dispatch(loadFormTemplatesSuccess(response.data)); - }).catch((error) => { - dispatch(loadFormTemplatesError(error.response.data)); - }); - } + return function (dispatch) { + dispatch(loadFormTemplatesPending()); + axiosBackend + .get(`${API_URL}/rest/formGen/formTemplates`) + .then((response) => { + dispatch(loadFormTemplatesSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadFormTemplatesError(error.response.data)); + }); + }; } export function loadFormTemplatesPending() { - return { - type: ActionConstants.LOAD_FORM_TEMPLATES_PENDING - } + return { + type: ActionConstants.LOAD_FORM_TEMPLATES_PENDING, + }; } export function loadFormTemplatesSuccess(formTemplates) { - return { - type: ActionConstants.LOAD_FORM_TEMPLATES_SUCCESS, - formTemplates - } + return { + type: ActionConstants.LOAD_FORM_TEMPLATES_SUCCESS, + formTemplates, + }; } export function loadFormTemplatesError(error) { - return { - type: ActionConstants.LOAD_FORM_TEMPLATES_ERROR, - error - } -} \ No newline at end of file + return { + type: ActionConstants.LOAD_FORM_TEMPLATES_ERROR, + error, + }; +} diff --git a/src/actions/HistoryActions.js b/src/actions/HistoryActions.js index 3d8949da..2e402d3c 100644 --- a/src/actions/HistoryActions.js +++ b/src/actions/HistoryActions.js @@ -1,58 +1,66 @@ -import {axiosBackend} from "./index"; +import { axiosBackend } from "./index"; import * as ActionConstants from "../constants/ActionConstants"; -import {endsWith, omit, startsWith} from 'lodash'; -import {API_URL} from '../../config'; -import {showServerResponseErrorMessage} from "./AsyncActionUtils"; -import {DEFAULT_PAGE_SIZE, STORAGE_TABLE_PAGE_SIZE_KEY} from "../constants/DefaultConstants"; +import { endsWith, omit, startsWith } from "lodash"; +import { API_URL } from "../../config"; +import { showServerResponseErrorMessage } from "./AsyncActionUtils"; +import { DEFAULT_PAGE_SIZE, STORAGE_TABLE_PAGE_SIZE_KEY } from "../constants/DefaultConstants"; import BrowserStorage from "../utils/BrowserStorage"; -const URL_PREFIX = 'rest/history'; +const URL_PREFIX = "rest/history"; export function logAction(action, author, timestamp) { - if ((startsWith(action.type, 'LOAD') && !endsWith(action.type, 'ERROR')) || - endsWith(action.type, 'PENDING') || - startsWith(action.type, 'SET') || - startsWith(action.type, 'UNLOAD') || - action.type.includes('USER_PROFILE')) { - return; - } - const payload = JSON.stringify(omit(action, 'type')); - axiosBackend.post(`${API_URL}/${URL_PREFIX}`, { - author, - timestamp, - type: action.type, - payload: payload !== '{}' ? payload : null - }); + if ( + (startsWith(action.type, "LOAD") && !endsWith(action.type, "ERROR")) || + endsWith(action.type, "PENDING") || + startsWith(action.type, "SET") || + startsWith(action.type, "UNLOAD") || + action.type.includes("USER_PROFILE") + ) { + return; + } + const payload = JSON.stringify(omit(action, "type")); + axiosBackend.post(`${API_URL}/${URL_PREFIX}`, { + author, + timestamp, + type: action.type, + payload: payload !== "{}" ? payload : null, + }); } export function loadActions(pageNumber, searchData) { - let urlSuffix = `?page=${pageNumber}&size=${BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY, DEFAULT_PAGE_SIZE)}`; - if (searchData && searchData.author && searchData.action) { - urlSuffix = `${urlSuffix}&author=${searchData.author}&type=${searchData.action}`; - } else if (searchData && searchData.author) { - urlSuffix = `${urlSuffix}&author=${searchData.author}`; - } else if (searchData && searchData.action) { - urlSuffix = `${urlSuffix}&type=${searchData.action}`; - } - return function (dispatch) { - dispatch({type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING}); - return axiosBackend.get(`${API_URL}/${URL_PREFIX}${urlSuffix}`).then((response) => { - dispatch({type: ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS, actionsHistory: response.data}); - }).catch((error) => { - dispatch({type: ActionConstants.LOAD_ACTIONS_HISTORY_ERROR, error: error.response.data}); - dispatch(showServerResponseErrorMessage(error, 'history.loading-error')); - }); - } + let urlSuffix = `?page=${pageNumber}&size=${BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY, DEFAULT_PAGE_SIZE)}`; + if (searchData && searchData.author && searchData.action) { + urlSuffix = `${urlSuffix}&author=${searchData.author}&type=${searchData.action}`; + } else if (searchData && searchData.author) { + urlSuffix = `${urlSuffix}&author=${searchData.author}`; + } else if (searchData && searchData.action) { + urlSuffix = `${urlSuffix}&type=${searchData.action}`; + } + return function (dispatch) { + dispatch({ type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING }); + return axiosBackend + .get(`${API_URL}/${URL_PREFIX}${urlSuffix}`) + .then((response) => { + dispatch({ type: ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS, actionsHistory: response.data }); + }) + .catch((error) => { + dispatch({ type: ActionConstants.LOAD_ACTIONS_HISTORY_ERROR, error: error.response.data }); + dispatch(showServerResponseErrorMessage(error, "history.loading-error")); + }); + }; } export function loadActionByKey(key) { - return function (dispatch) { - dispatch({type: ActionConstants.LOAD_ACTION_HISTORY_PENDING}); - return axiosBackend.get(`${API_URL}/${URL_PREFIX}/${key}`).then((response) => { - dispatch({type: ActionConstants.LOAD_ACTION_HISTORY_SUCCESS, actionHistory: response.data}); - }).catch((error) => { - dispatch({type: ActionConstants.LOAD_ACTION_HISTORY_ERROR, error: error.response.data}); - dispatch(showServerResponseErrorMessage(error, 'history.load-error')); - }); - } -} \ No newline at end of file + return function (dispatch) { + dispatch({ type: ActionConstants.LOAD_ACTION_HISTORY_PENDING }); + return axiosBackend + .get(`${API_URL}/${URL_PREFIX}/${key}`) + .then((response) => { + dispatch({ type: ActionConstants.LOAD_ACTION_HISTORY_SUCCESS, actionHistory: response.data }); + }) + .catch((error) => { + dispatch({ type: ActionConstants.LOAD_ACTION_HISTORY_ERROR, error: error.response.data }); + dispatch(showServerResponseErrorMessage(error, "history.load-error")); + }); + }; +} diff --git a/src/actions/InstitutionActions.js b/src/actions/InstitutionActions.js index 147ea3b6..5716725a 100644 --- a/src/actions/InstitutionActions.js +++ b/src/actions/InstitutionActions.js @@ -1,152 +1,170 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {axiosBackend} from "./index"; -import {ACTION_FLAG} from "../constants/DefaultConstants"; +import { axiosBackend } from "./index"; +import { ACTION_FLAG } from "../constants/DefaultConstants"; import * as Utils from "../utils/Utils"; -import {loadInstitutions} from "./InstitutionsActions"; -import {API_URL} from '../../config'; -import {publishMessage} from "./MessageActions"; -import {errorMessage, successMessage} from "../model/Message"; -import {showServerResponseErrorMessage} from "./AsyncActionUtils"; +import { loadInstitutions } from "./InstitutionsActions"; +import { API_URL } from "../../config"; +import { publishMessage } from "./MessageActions"; +import { errorMessage, successMessage } from "../model/Message"; +import { showServerResponseErrorMessage } from "./AsyncActionUtils"; export function deleteInstitution(institution) { - return function (dispatch, getState) { - dispatch(deleteInstitutionPending(institution.key)); - return axiosBackend.delete(`${API_URL}/rest/institutions/${institution.key}`, { - ...institution - }).then(() => { - dispatch(loadInstitutions()); - dispatch(deleteInstitutionSuccess(institution)); - dispatch(publishMessage(successMessage('institution.delete-success'))); - }).catch((error) => { - dispatch(deleteInstitutionError(error.response.data, institution)); - dispatch(publishMessage(errorMessage('institution.delete-error', {error: getState().intl.messages[error.response.data.messageId]}))); - }); - } + return function (dispatch, getState) { + dispatch(deleteInstitutionPending(institution.key)); + return axiosBackend + .delete(`${API_URL}/rest/institutions/${institution.key}`, { + ...institution, + }) + .then(() => { + dispatch(loadInstitutions()); + dispatch(deleteInstitutionSuccess(institution)); + dispatch(publishMessage(successMessage("institution.delete-success"))); + }) + .catch((error) => { + dispatch(deleteInstitutionError(error.response.data, institution)); + dispatch( + publishMessage( + errorMessage("institution.delete-error", { + error: getState().intl.messages[error.response.data.messageId], + }), + ), + ); + }); + }; } export function deleteInstitutionPending(key) { - return { - type: ActionConstants.DELETE_INSTITUTION_PENDING, - key - } + return { + type: ActionConstants.DELETE_INSTITUTION_PENDING, + key, + }; } export function deleteInstitutionSuccess(institution) { - return { - type: ActionConstants.DELETE_INSTITUTION_SUCCESS, - institution - } + return { + type: ActionConstants.DELETE_INSTITUTION_SUCCESS, + institution, + }; } export function deleteInstitutionError(error, institution) { - return { - type: ActionConstants.DELETE_INSTITUTION_ERROR, - error, - institution - } + return { + type: ActionConstants.DELETE_INSTITUTION_ERROR, + error, + institution, + }; } export function loadInstitution(key) { - //console.log("Loading institution with key: ", key); - return function (dispatch) { - dispatch(loadInstitutionPending()); - return axiosBackend.get(`${API_URL}/rest/institutions/${key}`).then((response) => { - dispatch(loadInstitutionSuccess(response.data)); - }).catch((error) => { - dispatch(loadInstitutionError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'institution.load-error')); - }); - } + //console.log("Loading institution with key: ", key); + return function (dispatch) { + dispatch(loadInstitutionPending()); + return axiosBackend + .get(`${API_URL}/rest/institutions/${key}`) + .then((response) => { + dispatch(loadInstitutionSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadInstitutionError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "institution.load-error")); + }); + }; } export function loadInstitutionPending() { - return { - type: ActionConstants.LOAD_INSTITUTION_PENDING - } + return { + type: ActionConstants.LOAD_INSTITUTION_PENDING, + }; } export function loadInstitutionSuccess(institution) { - return { - type: ActionConstants.LOAD_INSTITUTION_SUCCESS, - institution - } + return { + type: ActionConstants.LOAD_INSTITUTION_SUCCESS, + institution, + }; } export function loadInstitutionError(error) { - return { - type: ActionConstants.LOAD_INSTITUTION_ERROR, - error - } + return { + type: ActionConstants.LOAD_INSTITUTION_ERROR, + error, + }; } export function unloadInstitution() { - return { - type: ActionConstants.UNLOAD_INSTITUTION - } + return { + type: ActionConstants.UNLOAD_INSTITUTION, + }; } export function createInstitution(institution) { - //console.log("Creating institution: ", institution); - return function (dispatch) { - dispatch(saveInstitutionPending(ACTION_FLAG.CREATE_ENTITY)); - return axiosBackend.post(`${API_URL}/rest/institutions`, { - ...institution - }).then((response) => { - const key = Utils.extractKeyFromLocationHeader(response); - dispatch(saveInstitutionSuccess(institution, key, ACTION_FLAG.CREATE_ENTITY)); - dispatch(loadInstitutions()); - dispatch(publishMessage(successMessage('institution.save-success'))); - }).catch((error) => { - dispatch(saveInstitutionError(error.response.data, institution, ACTION_FLAG.CREATE_ENTITY)); - dispatch(showServerResponseErrorMessage(error, 'institution.save-error')); - }); - } + //console.log("Creating institution: ", institution); + return function (dispatch) { + dispatch(saveInstitutionPending(ACTION_FLAG.CREATE_ENTITY)); + return axiosBackend + .post(`${API_URL}/rest/institutions`, { + ...institution, + }) + .then((response) => { + const key = Utils.extractKeyFromLocationHeader(response); + dispatch(saveInstitutionSuccess(institution, key, ACTION_FLAG.CREATE_ENTITY)); + dispatch(loadInstitutions()); + dispatch(publishMessage(successMessage("institution.save-success"))); + }) + .catch((error) => { + dispatch(saveInstitutionError(error.response.data, institution, ACTION_FLAG.CREATE_ENTITY)); + dispatch(showServerResponseErrorMessage(error, "institution.save-error")); + }); + }; } export function updateInstitution(institution) { - //console.log("Updating institution: ", institution); - return function (dispatch) { - dispatch(saveInstitutionPending(ACTION_FLAG.UPDATE_ENTITY)); - return axiosBackend.put(`${API_URL}/rest/institutions/${institution.key}`, { - ...institution - }).then(() => { - dispatch(saveInstitutionSuccess(institution, null, ACTION_FLAG.UPDATE_ENTITY)); - dispatch(loadInstitutions()); - dispatch(publishMessage(successMessage('institution.save-success'))); - }).catch((error) => { - dispatch(saveInstitutionError(error.response.data, institution, ACTION_FLAG.UPDATE_ENTITY)); - dispatch(showServerResponseErrorMessage(error, 'institution.save-error')); - }); - } + //console.log("Updating institution: ", institution); + return function (dispatch) { + dispatch(saveInstitutionPending(ACTION_FLAG.UPDATE_ENTITY)); + return axiosBackend + .put(`${API_URL}/rest/institutions/${institution.key}`, { + ...institution, + }) + .then(() => { + dispatch(saveInstitutionSuccess(institution, null, ACTION_FLAG.UPDATE_ENTITY)); + dispatch(loadInstitutions()); + dispatch(publishMessage(successMessage("institution.save-success"))); + }) + .catch((error) => { + dispatch(saveInstitutionError(error.response.data, institution, ACTION_FLAG.UPDATE_ENTITY)); + dispatch(showServerResponseErrorMessage(error, "institution.save-error")); + }); + }; } export function saveInstitutionPending(actionFlag) { - return { - type: ActionConstants.SAVE_INSTITUTION_PENDING, - actionFlag - } + return { + type: ActionConstants.SAVE_INSTITUTION_PENDING, + actionFlag, + }; } export function saveInstitutionSuccess(institution, key, actionFlag) { - return { - type: ActionConstants.SAVE_INSTITUTION_SUCCESS, - institution, - key, - actionFlag - } + return { + type: ActionConstants.SAVE_INSTITUTION_SUCCESS, + institution, + key, + actionFlag, + }; } export function saveInstitutionError(error, institution, actionFlag) { - return { - type: ActionConstants.SAVE_INSTITUTION_ERROR, - error, - institution, - actionFlag - } + return { + type: ActionConstants.SAVE_INSTITUTION_ERROR, + error, + institution, + actionFlag, + }; } export function unloadSavedInstitution() { - return { - type: ActionConstants.UNLOAD_SAVED_INSTITUTION - } -} \ No newline at end of file + return { + type: ActionConstants.UNLOAD_SAVED_INSTITUTION, + }; +} diff --git a/src/actions/InstitutionsActions.js b/src/actions/InstitutionsActions.js index c3bf0b54..07b195a9 100644 --- a/src/actions/InstitutionsActions.js +++ b/src/actions/InstitutionsActions.js @@ -1,36 +1,39 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {axiosBackend} from "./index"; -import {API_URL} from '../../config'; -import {showServerResponseErrorMessage} from "./AsyncActionUtils"; +import { axiosBackend } from "./index"; +import { API_URL } from "../../config"; +import { showServerResponseErrorMessage } from "./AsyncActionUtils"; export function loadInstitutions() { - return function (dispatch) { - dispatch(loadInstitutionsPending()); - return axiosBackend.get(`${API_URL}/rest/institutions`).then((response) => { - dispatch(loadInstitutionsSuccess(response.data)); - }).catch((error) => { - dispatch(loadInstitutionsError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'institutions.loading-error')); - }); - } + return function (dispatch) { + dispatch(loadInstitutionsPending()); + return axiosBackend + .get(`${API_URL}/rest/institutions`) + .then((response) => { + dispatch(loadInstitutionsSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadInstitutionsError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "institutions.loading-error")); + }); + }; } export function loadInstitutionsPending() { - return { - type: ActionConstants.LOAD_INSTITUTIONS_PENDING - } + return { + type: ActionConstants.LOAD_INSTITUTIONS_PENDING, + }; } export function loadInstitutionsSuccess(institutions) { - return { - type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, - institutions - } + return { + type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, + institutions, + }; } export function loadInstitutionsError(error) { - return { - type: ActionConstants.LOAD_INSTITUTIONS_ERROR, - error - } -} \ No newline at end of file + return { + type: ActionConstants.LOAD_INSTITUTIONS_ERROR, + error, + }; +} diff --git a/src/actions/MessageActions.js b/src/actions/MessageActions.js index 8b1112a2..e3dfaf40 100644 --- a/src/actions/MessageActions.js +++ b/src/actions/MessageActions.js @@ -1,15 +1,15 @@ -import {DISMISS_MESSAGE, PUBLISH_MESSAGE} from "../constants/ActionConstants"; +import { DISMISS_MESSAGE, PUBLISH_MESSAGE } from "../constants/ActionConstants"; export function publishMessage(message) { - return { - type: PUBLISH_MESSAGE, - message, - }; + return { + type: PUBLISH_MESSAGE, + message, + }; } export function dismissMessage(message) { - return { - type: DISMISS_MESSAGE, - message, - }; + return { + type: DISMISS_MESSAGE, + message, + }; } diff --git a/src/actions/RecordActions.js b/src/actions/RecordActions.js index 8b500241..48202201 100644 --- a/src/actions/RecordActions.js +++ b/src/actions/RecordActions.js @@ -1,167 +1,188 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_FLAG} from "../constants/DefaultConstants"; -import {axiosBackend} from "./index"; +import { ACTION_FLAG } from "../constants/DefaultConstants"; +import { axiosBackend } from "./index"; import * as Utils from "../utils/Utils"; -import {loadRecords} from "./RecordsActions"; -import {API_URL} from '../../config'; -import {publishMessage} from "./MessageActions"; -import {errorMessage, successMessage} from "../model/Message"; -import {asyncError, asyncRequest, asyncSuccess, showServerResponseErrorMessage} from "./AsyncActionUtils"; +import { loadRecords } from "./RecordsActions"; +import { API_URL } from "../../config"; +import { publishMessage } from "./MessageActions"; +import { errorMessage, successMessage } from "../model/Message"; +import { asyncError, asyncRequest, asyncSuccess, showServerResponseErrorMessage } from "./AsyncActionUtils"; export function deleteRecord(record) { - return function (dispatch) { - dispatch(deleteRecordPending(record.key)); - return axiosBackend.delete(`${API_URL}/rest/records/${record.key}`, { - ...record - }).then(() => { - dispatch(loadRecords()); - dispatch(deleteRecordSuccess(record, record.key)); - dispatch(publishMessage(successMessage("record.delete-success"))); - }).catch((error) => { - dispatch(deleteRecordError(error.response.data, record, record.key)); - dispatch(showServerResponseErrorMessage(error, 'record.delete-error')); - }); - } + return function (dispatch) { + dispatch(deleteRecordPending(record.key)); + return axiosBackend + .delete(`${API_URL}/rest/records/${record.key}`, { + ...record, + }) + .then(() => { + dispatch(loadRecords()); + dispatch(deleteRecordSuccess(record, record.key)); + dispatch(publishMessage(successMessage("record.delete-success"))); + }) + .catch((error) => { + dispatch(deleteRecordError(error.response.data, record, record.key)); + dispatch(showServerResponseErrorMessage(error, "record.delete-error")); + }); + }; } export function deleteRecordPending(key) { - return { - type: ActionConstants.DELETE_RECORD_PENDING, - key - } + return { + type: ActionConstants.DELETE_RECORD_PENDING, + key, + }; } export function deleteRecordSuccess(record, key) { - return { - type: ActionConstants.DELETE_RECORD_SUCCESS, - record, - key - } + return { + type: ActionConstants.DELETE_RECORD_SUCCESS, + record, + key, + }; } export function deleteRecordError(error, record, key) { - return { - type: ActionConstants.DELETE_RECORD_ERROR, - error, - record, - key - } + return { + type: ActionConstants.DELETE_RECORD_ERROR, + error, + record, + key, + }; } export function loadRecord(key) { - return function (dispatch) { - dispatch(loadRecordPending()); - return axiosBackend.get(`${API_URL}/rest/records/${key}`).then((response) => { - dispatch(loadRecordSuccess(response.data)); - }).catch((error) => { - dispatch(loadRecordError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'record.load-error')); - }); - } + return function (dispatch) { + dispatch(loadRecordPending()); + return axiosBackend + .get(`${API_URL}/rest/records/${key}`) + .then((response) => { + dispatch(loadRecordSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadRecordError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "record.load-error")); + }); + }; } export function loadRecordPending() { - return { - type: ActionConstants.LOAD_RECORD_PENDING - } + return { + type: ActionConstants.LOAD_RECORD_PENDING, + }; } export function loadRecordSuccess(record) { - return { - type: ActionConstants.LOAD_RECORD_SUCCESS, - record - } + return { + type: ActionConstants.LOAD_RECORD_SUCCESS, + record, + }; } export function loadRecordError(error) { - return { - type: ActionConstants.LOAD_RECORD_ERROR, - error - } + return { + type: ActionConstants.LOAD_RECORD_ERROR, + error, + }; } export function unloadRecord() { - return { - type: ActionConstants.UNLOAD_RECORD - } + return { + type: ActionConstants.UNLOAD_RECORD, + }; } export function createRecord(record) { - return function (dispatch, getState) { - dispatch(saveRecordPending(ACTION_FLAG.CREATE_ENTITY)); - return axiosBackend.post(`${API_URL}/rest/records`, { - ...record - }).then((response) => { - const key = Utils.extractKeyFromLocationHeader(response); - dispatch(saveRecordSuccess(record, key, ACTION_FLAG.CREATE_ENTITY)); - dispatch(loadRecords()); - dispatch(publishMessage(successMessage("record.save-success"))); - }).catch((error) => { - dispatch(saveRecordError(error.response.data, record, ACTION_FLAG.CREATE_ENTITY)); - dispatch(publishMessage(errorMessage('record.save-error', {error: getState().intl.messages[error.response.data.messageId]}))); - }); - } + return function (dispatch, getState) { + dispatch(saveRecordPending(ACTION_FLAG.CREATE_ENTITY)); + return axiosBackend + .post(`${API_URL}/rest/records`, { + ...record, + }) + .then((response) => { + const key = Utils.extractKeyFromLocationHeader(response); + dispatch(saveRecordSuccess(record, key, ACTION_FLAG.CREATE_ENTITY)); + dispatch(loadRecords()); + dispatch(publishMessage(successMessage("record.save-success"))); + }) + .catch((error) => { + dispatch(saveRecordError(error.response.data, record, ACTION_FLAG.CREATE_ENTITY)); + dispatch( + publishMessage( + errorMessage("record.save-error", { error: getState().intl.messages[error.response.data.messageId] }), + ), + ); + }); + }; } export function updateRecord(record) { - return function (dispatch, getState) { - dispatch(saveRecordPending(ACTION_FLAG.UPDATE_ENTITY)); - return axiosBackend.put(`${API_URL}/rest/records/${record.key}`, { - ...record - }).then(() => { - dispatch(saveRecordSuccess(record, null, ACTION_FLAG.UPDATE_ENTITY)); - dispatch(loadRecords()); - dispatch(publishMessage(successMessage("record.save-success"))); - }).catch((error) => { - dispatch(saveRecordError(error.response.data, record, ACTION_FLAG.UPDATE_ENTITY)); - dispatch(publishMessage(errorMessage('record.save-error', {error: getState().intl.messages[error.response.data.messageId]}))); - }); - } + return function (dispatch, getState) { + dispatch(saveRecordPending(ACTION_FLAG.UPDATE_ENTITY)); + return axiosBackend + .put(`${API_URL}/rest/records/${record.key}`, { + ...record, + }) + .then(() => { + dispatch(saveRecordSuccess(record, null, ACTION_FLAG.UPDATE_ENTITY)); + dispatch(loadRecords()); + dispatch(publishMessage(successMessage("record.save-success"))); + }) + .catch((error) => { + dispatch(saveRecordError(error.response.data, record, ACTION_FLAG.UPDATE_ENTITY)); + dispatch( + publishMessage( + errorMessage("record.save-error", { error: getState().intl.messages[error.response.data.messageId] }), + ), + ); + }); + }; } export function saveRecordPending(actionFlag) { - return { - type: ActionConstants.SAVE_RECORD_PENDING, - actionFlag - } + return { + type: ActionConstants.SAVE_RECORD_PENDING, + actionFlag, + }; } export function saveRecordSuccess(record, key, actionFlag) { - return { - type: ActionConstants.SAVE_RECORD_SUCCESS, - record, - key, - actionFlag - } + return { + type: ActionConstants.SAVE_RECORD_SUCCESS, + record, + key, + actionFlag, + }; } export function saveRecordError(error, record, actionFlag) { - return { - type: ActionConstants.SAVE_RECORD_ERROR, - error, - record, - actionFlag - } + return { + type: ActionConstants.SAVE_RECORD_ERROR, + error, + record, + actionFlag, + }; } export function unloadSavedRecord() { - return { - type: ActionConstants.UNLOAD_SAVED_RECORD - } + return { + type: ActionConstants.UNLOAD_SAVED_RECORD, + }; } export function loadFormgen(record) { - return dispatch => { - dispatch(asyncRequest(ActionConstants.LOAD_FORMGEN_PENDING)); - return axiosBackend.post(`${API_URL}/rest/formGen`, record) - .then(resp => { - dispatch(asyncSuccess(ActionConstants.LOAD_FORMGEN_SUCCESS)); - return Promise.resolve(resp.data); - }) - .catch(error => { - dispatch(asyncError(ActionConstants.LOAD_FORMGEN_ERROR, error)); - dispatch(showServerResponseErrorMessage(error, 'record.load-form-error')); - return Promise.reject(error); - }) - } -} \ No newline at end of file + return (dispatch) => { + dispatch(asyncRequest(ActionConstants.LOAD_FORMGEN_PENDING)); + return axiosBackend + .post(`${API_URL}/rest/formGen`, record) + .then((resp) => { + dispatch(asyncSuccess(ActionConstants.LOAD_FORMGEN_SUCCESS)); + return Promise.resolve(resp.data); + }) + .catch((error) => { + dispatch(asyncError(ActionConstants.LOAD_FORMGEN_ERROR, error)); + dispatch(showServerResponseErrorMessage(error, "record.load-form-error")); + return Promise.reject(error); + }); + }; +} diff --git a/src/actions/RecordsActions.js b/src/actions/RecordsActions.js index 4c49690c..22a77a0d 100644 --- a/src/actions/RecordsActions.js +++ b/src/actions/RecordsActions.js @@ -1,99 +1,115 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {HttpHeaders} from "../constants/DefaultConstants"; -import {axiosBackend} from "./index"; -import {API_URL} from '../../config'; -import {asyncError, asyncRequest, asyncSuccess, showServerResponseErrorMessage} from "./AsyncActionUtils"; -import {extractLastPageNumber, fileDownload, paramsSerializer} from "../utils/Utils"; -import {publishMessage} from "./MessageActions"; -import {infoMessage, successMessage} from "../model/Message"; -import {isAdmin} from "../utils/SecurityUtils"; +import { HttpHeaders } from "../constants/DefaultConstants"; +import { axiosBackend } from "./index"; +import { API_URL } from "../../config"; +import { asyncError, asyncRequest, asyncSuccess, showServerResponseErrorMessage } from "./AsyncActionUtils"; +import { extractLastPageNumber, fileDownload, paramsSerializer } from "../utils/Utils"; +import { publishMessage } from "./MessageActions"; +import { infoMessage, successMessage } from "../model/Message"; +import { isAdmin } from "../utils/SecurityUtils"; export function loadRecordsByInstitution(institutionKey) { - return loadRecords({institution: institutionKey}); + return loadRecords({ institution: institutionKey }); } export function loadRecords(params = {}) { - return function (dispatch, getState) { - const currentUser = getState().auth.user; - if (currentUser && !isAdmin(currentUser) && currentUser.institution) { - params.institution = currentUser.institution.key; - } - dispatch(loadRecordsPending()); - return axiosBackend.get(`${API_URL}/rest/records`, { - params, - paramsSerializer - }).then((response) => { - dispatch(loadRecordsSuccess(response.data, extractLastPageNumber(response))); - }).catch((error) => { - dispatch(loadRecordsError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'records.loading-error')); - }); + return function (dispatch, getState) { + const currentUser = getState().auth.user; + if (currentUser && !isAdmin(currentUser) && currentUser.institution) { + params.institution = currentUser.institution.key; } + dispatch(loadRecordsPending()); + return axiosBackend + .get(`${API_URL}/rest/records`, { + params, + paramsSerializer, + }) + .then((response) => { + dispatch(loadRecordsSuccess(response.data, extractLastPageNumber(response))); + }) + .catch((error) => { + dispatch(loadRecordsError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "records.loading-error")); + }); + }; } export function loadRecordsPending() { - return asyncRequest(ActionConstants.LOAD_RECORDS_PENDING); + return asyncRequest(ActionConstants.LOAD_RECORDS_PENDING); } export function loadRecordsSuccess(records, pageCount) { - return { - type: ActionConstants.LOAD_RECORDS_SUCCESS, - records, - pageCount - } + return { + type: ActionConstants.LOAD_RECORDS_SUCCESS, + records, + pageCount, + }; } export function loadRecordsError(error) { - return asyncError(ActionConstants.LOAD_RECORDS_ERROR, error); + return asyncError(ActionConstants.LOAD_RECORDS_ERROR, error); } export function exportRecords(exportType, params = {}) { - return (dispatch, getState) => { - dispatch(asyncRequest(ActionConstants.EXPORT_RECORDS_PENDING)); - const currentUser = getState().auth.user; - if (currentUser && !isAdmin(currentUser) && currentUser.institution) { - params.institution = currentUser.institution.key; - } - return axiosBackend.get(`${API_URL}/rest/records/export`, { - params, - paramsSerializer, - headers: { - accept: exportType.mediaType - }, - responseType: 'arraybuffer' - }).then((resp) => { - const disposition = resp.headers[HttpHeaders.CONTENT_DISPOSITION]; - const filenameMatch = disposition - ? disposition.match(/filename="(.+\..+)"/) - : null; - const fileName = filenameMatch ? filenameMatch[1] : "records" + exportType.fileExtension; - fileDownload(resp.data, fileName, exportType.mediaType); - return dispatch(asyncSuccess(ActionConstants.EXPORT_RECORDS_SUCCESS)); - }).catch((error) => { - dispatch(asyncError(ActionConstants.EXPORT_RECORDS_ERROR, error.response.data)); - }); + return (dispatch, getState) => { + dispatch(asyncRequest(ActionConstants.EXPORT_RECORDS_PENDING)); + const currentUser = getState().auth.user; + if (currentUser && !isAdmin(currentUser) && currentUser.institution) { + params.institution = currentUser.institution.key; } + return axiosBackend + .get(`${API_URL}/rest/records/export`, { + params, + paramsSerializer, + headers: { + accept: exportType.mediaType, + }, + responseType: "arraybuffer", + }) + .then((resp) => { + const disposition = resp.headers[HttpHeaders.CONTENT_DISPOSITION]; + const filenameMatch = disposition ? disposition.match(/filename="(.+\..+)"/) : null; + const fileName = filenameMatch ? filenameMatch[1] : "records" + exportType.fileExtension; + fileDownload(resp.data, fileName, exportType.mediaType); + return dispatch(asyncSuccess(ActionConstants.EXPORT_RECORDS_SUCCESS)); + }) + .catch((error) => { + dispatch(asyncError(ActionConstants.EXPORT_RECORDS_ERROR, error.response.data)); + }); + }; } export function importRecords(file) { - return (dispatch) => { - dispatch(asyncRequest(ActionConstants.IMPORT_RECORDS_PENDING)); - return file.text().then(content => { - return axiosBackend.post(`${API_URL}/rest/records/import`, JSON.parse(content)) - }).then((resp) => { - dispatch(asyncSuccess(ActionConstants.IMPORT_RECORDS_SUCCESS)); - dispatch(loadRecords()); - if (resp.data.importedCount < resp.data.totalCount) { - dispatch(publishMessage(infoMessage("records.import.partialSuccess.message", { - importedCount: resp.data.importedCount, - totalCount: resp.data.totalCount - }))); - } else { - dispatch(publishMessage(successMessage("records.import.success.message", {importedCount: resp.data.importedCount}))); - } - }).catch(error => { - dispatch(asyncError(ActionConstants.IMPORT_RECORDS_ERROR, error.response.data)); - dispatch(showServerResponseErrorMessage(error, "records.import.error.message")); - }); - }; + return (dispatch) => { + dispatch(asyncRequest(ActionConstants.IMPORT_RECORDS_PENDING)); + return file + .text() + .then((content) => { + return axiosBackend.post(`${API_URL}/rest/records/import`, JSON.parse(content)); + }) + .then((resp) => { + dispatch(asyncSuccess(ActionConstants.IMPORT_RECORDS_SUCCESS)); + dispatch(loadRecords()); + if (resp.data.importedCount < resp.data.totalCount) { + dispatch( + publishMessage( + infoMessage("records.import.partialSuccess.message", { + importedCount: resp.data.importedCount, + totalCount: resp.data.totalCount, + }), + ), + ); + } else { + dispatch( + publishMessage( + successMessage("records.import.success.message", { importedCount: resp.data.importedCount }), + ), + ); + } + }) + .catch((error) => { + dispatch(asyncError(ActionConstants.IMPORT_RECORDS_ERROR, error.response.data)); + dispatch(showServerResponseErrorMessage(error, "records.import.error.message")); + }); + }; } diff --git a/src/actions/RouterActions.js b/src/actions/RouterActions.js index 796408cf..6dc49da8 100644 --- a/src/actions/RouterActions.js +++ b/src/actions/RouterActions.js @@ -1,17 +1,17 @@ import * as ActionConstants from "../constants/ActionConstants"; export function setViewHandlers(routeName, handlers) { - return { - type: ActionConstants.SET_VIEW_HANDLERS, - routeName, - handlers - } + return { + type: ActionConstants.SET_VIEW_HANDLERS, + routeName, + handlers, + }; } export function setTransitionPayload(routeName, payload) { - return { - type: ActionConstants.SET_TRANSITION_PAYLOAD, - routeName, - payload - } -} \ No newline at end of file + return { + type: ActionConstants.SET_TRANSITION_PAYLOAD, + routeName, + payload, + }; +} diff --git a/src/actions/StatisticsActions.js b/src/actions/StatisticsActions.js index b91846f1..4d74b832 100644 --- a/src/actions/StatisticsActions.js +++ b/src/actions/StatisticsActions.js @@ -1,16 +1,19 @@ -import {axiosBackend} from "./index"; -import {LOAD_STATISTICS_ERROR, LOAD_STATISTICS_PENDING, LOAD_STATISTICS_SUCCESS} from "../constants/ActionConstants"; -import {API_URL} from '../../config'; -import {showServerResponseErrorMessage} from "./AsyncActionUtils"; +import { axiosBackend } from "./index"; +import { LOAD_STATISTICS_ERROR, LOAD_STATISTICS_PENDING, LOAD_STATISTICS_SUCCESS } from "../constants/ActionConstants"; +import { API_URL } from "../../config"; +import { showServerResponseErrorMessage } from "./AsyncActionUtils"; export function loadStatistics() { - return function (dispatch) { - dispatch({type: LOAD_STATISTICS_PENDING}); - return axiosBackend.get(`${API_URL}/rest/statistics`).then((response) => { - dispatch({type: LOAD_STATISTICS_SUCCESS, payload: response.data}); - }).catch((error) => { - dispatch({type: LOAD_STATISTICS_ERROR, error: error.response.data}); - dispatch(showServerResponseErrorMessage(error, 'history.loading-error')); - }); - } -} \ No newline at end of file + return function (dispatch) { + dispatch({ type: LOAD_STATISTICS_PENDING }); + return axiosBackend + .get(`${API_URL}/rest/statistics`) + .then((response) => { + dispatch({ type: LOAD_STATISTICS_SUCCESS, payload: response.data }); + }) + .catch((error) => { + dispatch({ type: LOAD_STATISTICS_ERROR, error: error.response.data }); + dispatch(showServerResponseErrorMessage(error, "history.loading-error")); + }); + }; +} diff --git a/src/actions/UserActions.js b/src/actions/UserActions.js index c6681b25..2d9964a2 100644 --- a/src/actions/UserActions.js +++ b/src/actions/UserActions.js @@ -1,305 +1,349 @@ -import {ACTION_FLAG, MediaType} from "../constants/DefaultConstants"; -import {axiosBackend} from "./index"; +import { ACTION_FLAG, MediaType } from "../constants/DefaultConstants"; +import { axiosBackend } from "./index"; import * as ActionConstants from "../constants/ActionConstants"; -import {loadUsers} from "./UsersActions"; -import {API_URL, getEnv} from '../../config'; -import {transitionToHome} from "../utils/Routing"; -import {getOidcToken, isAdmin, saveOidcToken} from "../utils/SecurityUtils"; -import {publishMessage} from "./MessageActions"; -import {errorMessage, successMessage} from "../model/Message"; -import {showServerResponseErrorMessage} from "./AsyncActionUtils"; +import { loadUsers } from "./UsersActions"; +import { API_URL, getEnv } from "../../config"; +import { transitionToHome } from "../utils/Routing"; +import { getOidcToken, isAdmin, saveOidcToken } from "../utils/SecurityUtils"; +import { publishMessage } from "./MessageActions"; +import { errorMessage, successMessage } from "../model/Message"; +import { showServerResponseErrorMessage } from "./AsyncActionUtils"; export function createUser(user) { - return function (dispatch) { - dispatch(saveUserPending(ACTION_FLAG.CREATE_ENTITY)); - axiosBackend.post(`${API_URL}/rest/users`, { - ...user - }).then(() => { - dispatch(saveUserSuccess(user, ACTION_FLAG.CREATE_ENTITY)); - dispatch(loadUsers()); - }).catch((error) => { - dispatch(saveUserError(error.response.data, user, ACTION_FLAG.CREATE_ENTITY)); - }); - } + return function (dispatch) { + dispatch(saveUserPending(ACTION_FLAG.CREATE_ENTITY)); + axiosBackend + .post(`${API_URL}/rest/users`, { + ...user, + }) + .then(() => { + dispatch(saveUserSuccess(user, ACTION_FLAG.CREATE_ENTITY)); + dispatch(loadUsers()); + }) + .catch((error) => { + dispatch(saveUserError(error.response.data, user, ACTION_FLAG.CREATE_ENTITY)); + }); + }; } export function updateUser(user, currentUser, sendEmail = true) { - return function (dispatch) { - dispatch(saveUserPending(ACTION_FLAG.UPDATE_ENTITY)); - axiosBackend.put(`${API_URL}/rest/users/${user.username}${!sendEmail ? '?email=false' : ''}`, { - ...user - }).then(() => { - dispatch(saveUserSuccess(user, ACTION_FLAG.UPDATE_ENTITY)); - if (isAdmin(currentUser)) { - dispatch(loadUsers()); - } - dispatch(publishMessage(successMessage(sendEmail ? 'user.save-success-with-email' : 'user.save-success'))); - }).catch((error) => { - dispatch(saveUserError(error.response.data, user, ACTION_FLAG.UPDATE_ENTITY)); - dispatch(showServerResponseErrorMessage(error, 'user.save-error')); - }); - } + return function (dispatch) { + dispatch(saveUserPending(ACTION_FLAG.UPDATE_ENTITY)); + axiosBackend + .put(`${API_URL}/rest/users/${user.username}${!sendEmail ? "?email=false" : ""}`, { + ...user, + }) + .then(() => { + dispatch(saveUserSuccess(user, ACTION_FLAG.UPDATE_ENTITY)); + if (isAdmin(currentUser)) { + dispatch(loadUsers()); + } + dispatch(publishMessage(successMessage(sendEmail ? "user.save-success-with-email" : "user.save-success"))); + }) + .catch((error) => { + dispatch(saveUserError(error.response.data, user, ACTION_FLAG.UPDATE_ENTITY)); + dispatch(showServerResponseErrorMessage(error, "user.save-error")); + }); + }; } export function saveUserPending(actionFlag) { - return { - type: ActionConstants.SAVE_USER_PENDING, - actionFlag - } + return { + type: ActionConstants.SAVE_USER_PENDING, + actionFlag, + }; } export function saveUserSuccess(user, actionFlag) { - return { - type: ActionConstants.SAVE_USER_SUCCESS, - user, - actionFlag - } + return { + type: ActionConstants.SAVE_USER_SUCCESS, + user, + actionFlag, + }; } export function saveUserError(error, user, actionFlag) { - return { - type: ActionConstants.SAVE_USER_ERROR, - error, - user, - actionFlag - } + return { + type: ActionConstants.SAVE_USER_ERROR, + error, + user, + actionFlag, + }; } export function unloadSavedUser() { - return { - type: ActionConstants.UNLOAD_SAVED_USER - } + return { + type: ActionConstants.UNLOAD_SAVED_USER, + }; } export function deleteUser(user, institution = null) { - return function (dispatch) { - dispatch(deleteUserPending(user.username)); - return axiosBackend.delete(`${API_URL}/rest/users/${user.username}`, { - ...user - }).then(() => { - if (institution) { - dispatch(loadInstitutionMembers(institution.key)) - } else { - dispatch(loadUsers()); - } - dispatch(deleteUserSuccess(user)); - dispatch(publishMessage(successMessage("user.delete-success"))); - }).catch((error) => { - dispatch(deleteUserError(error.response.data, user)); - dispatch(showServerResponseErrorMessage(error, "user.delete-error")); - }); - } + return function (dispatch) { + dispatch(deleteUserPending(user.username)); + return axiosBackend + .delete(`${API_URL}/rest/users/${user.username}`, { + ...user, + }) + .then(() => { + if (institution) { + dispatch(loadInstitutionMembers(institution.key)); + } else { + dispatch(loadUsers()); + } + dispatch(deleteUserSuccess(user)); + dispatch(publishMessage(successMessage("user.delete-success"))); + }) + .catch((error) => { + dispatch(deleteUserError(error.response.data, user)); + dispatch(showServerResponseErrorMessage(error, "user.delete-error")); + }); + }; } export function deleteUserPending(username) { - return { - type: ActionConstants.DELETE_USER_PENDING, - username - } + return { + type: ActionConstants.DELETE_USER_PENDING, + username, + }; } export function deleteUserSuccess(user) { - return { - type: ActionConstants.DELETE_USER_SUCCESS, - user - } + return { + type: ActionConstants.DELETE_USER_SUCCESS, + user, + }; } export function deleteUserError(error, user) { - return { - type: ActionConstants.DELETE_USER_ERROR, - error, - user, - } + return { + type: ActionConstants.DELETE_USER_ERROR, + error, + user, + }; } export function loadUser(username) { - //console.log("Loading user with username: ", username); - return function (dispatch) { - dispatch(loadUserPending()); - return axiosBackend.get(`${API_URL}/rest/users/${username}`).then((response) => { - dispatch(loadUserSuccess(response.data)); - }).catch((error) => { - dispatch(loadUserError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'user.load-error')); - }); - } + //console.log("Loading user with username: ", username); + return function (dispatch) { + dispatch(loadUserPending()); + return axiosBackend + .get(`${API_URL}/rest/users/${username}`) + .then((response) => { + dispatch(loadUserSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadUserError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "user.load-error")); + }); + }; } export function loadUserPending() { - return { - type: ActionConstants.LOAD_USER_PENDING - } + return { + type: ActionConstants.LOAD_USER_PENDING, + }; } export function loadUserSuccess(user) { - return { - type: ActionConstants.LOAD_USER_SUCCESS, - user - } + return { + type: ActionConstants.LOAD_USER_SUCCESS, + user, + }; } export function loadUserError(error) { - return { - type: ActionConstants.LOAD_USER_ERROR, - error - } + return { + type: ActionConstants.LOAD_USER_ERROR, + error, + }; } export function unloadUser() { - return { - type: ActionConstants.UNLOAD_USER - } + return { + type: ActionConstants.UNLOAD_USER, + }; } export function loadInstitutionMembers(key) { - //console.log("Loading members of institution", key); - return function (dispatch) { - dispatch(loadInstitutionMembersPending()); - return axiosBackend.get(`${API_URL}/rest/users?institution=${key}`).then((response) => { - dispatch(loadInstitutionMembersSuccess(response.data)); - }).catch((error) => { - dispatch(loadInstitutionMembersError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'institution.members.loading-error')); - }); - } + //console.log("Loading members of institution", key); + return function (dispatch) { + dispatch(loadInstitutionMembersPending()); + return axiosBackend + .get(`${API_URL}/rest/users?institution=${key}`) + .then((response) => { + dispatch(loadInstitutionMembersSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadInstitutionMembersError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "institution.members.loading-error")); + }); + }; } export function loadInstitutionMembersPending() { - return { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING - } + return { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING, + }; } export function loadInstitutionMembersSuccess(members) { - return { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, - members - } + return { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, + members, + }; } export function loadInstitutionMembersError(error) { - return { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, - error - } + return { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, + error, + }; } export function unloadInstitutionMembers() { - return { - type: ActionConstants.UNLOAD_INSTITUTION_MEMBERS, - } + return { + type: ActionConstants.UNLOAD_INSTITUTION_MEMBERS, + }; } export function changePassword(username, password, sendEmail = true) { - return function (dispatch, getState) { - dispatch(changePasswordPending()); - axiosBackend.put(`${API_URL}/rest/users/${username}/password-change${!sendEmail ? '?email=false' : ''}`, { - ...password - }).then(() => { - dispatch(changePasswordSuccess()); - dispatch(publishMessage(successMessage(sendEmail ? 'user.password-change-success-with-email' : 'user.password-change-success'))); - }).catch((error) => { - dispatch(changePasswordError(error.response.data)); - dispatch(publishMessage(errorMessage('user.password-change-error', {error: getState().intl.messages[error.response.data.messageId]}))); - }); - } + return function (dispatch, getState) { + dispatch(changePasswordPending()); + axiosBackend + .put(`${API_URL}/rest/users/${username}/password-change${!sendEmail ? "?email=false" : ""}`, { + ...password, + }) + .then(() => { + dispatch(changePasswordSuccess()); + dispatch( + publishMessage( + successMessage(sendEmail ? "user.password-change-success-with-email" : "user.password-change-success"), + ), + ); + }) + .catch((error) => { + dispatch(changePasswordError(error.response.data)); + dispatch( + publishMessage( + errorMessage("user.password-change-error", { + error: getState().intl.messages[error.response.data.messageId], + }), + ), + ); + }); + }; } export function changePasswordPending() { - return { - type: ActionConstants.PASSWORD_CHANGE_PENDING - } + return { + type: ActionConstants.PASSWORD_CHANGE_PENDING, + }; } export function changePasswordSuccess() { - return { - type: ActionConstants.PASSWORD_CHANGE_SUCCESS, - } + return { + type: ActionConstants.PASSWORD_CHANGE_SUCCESS, + }; } export function changePasswordError(error) { - return { - type: ActionConstants.PASSWORD_CHANGE_ERROR, - error - } + return { + type: ActionConstants.PASSWORD_CHANGE_ERROR, + error, + }; } export function generateUsername(usernamePrefix) { - return function (dispatch) { - dispatch({type: ActionConstants.GENERATE_USERNAME_PENDING}); - axiosBackend.get(`${API_URL}/rest/users/generate-username/${usernamePrefix}`).then((response) => { - dispatch({type: ActionConstants.GENERATE_USERNAME_SUCCESS, generatedUsername: response.data}); - }) - } + return function (dispatch) { + dispatch({ type: ActionConstants.GENERATE_USERNAME_PENDING }); + axiosBackend.get(`${API_URL}/rest/users/generate-username/${usernamePrefix}`).then((response) => { + dispatch({ type: ActionConstants.GENERATE_USERNAME_SUCCESS, generatedUsername: response.data }); + }); + }; } export function sendInvitation(username) { - return function (dispatch) { - dispatch({type: ActionConstants.SEND_INVITATION_PENDING, username}); - axiosBackend.put(`${API_URL}/rest/users/send-invitation/${username}`).then(() => { - dispatch({type: ActionConstants.SEND_INVITATION_SUCCESS, username}); - dispatch(loadUser(username)); - dispatch(publishMessage(successMessage("user.send-invitation-success"))); - }).catch((error) => { - dispatch({type: ActionConstants.SEND_INVITATION_ERROR, error: error.response.data}); - dispatch(loadUser(username)); - dispatch(showServerResponseErrorMessage(error, 'user.send-invitation-error')); - }); - } + return function (dispatch) { + dispatch({ type: ActionConstants.SEND_INVITATION_PENDING, username }); + axiosBackend + .put(`${API_URL}/rest/users/send-invitation/${username}`) + .then(() => { + dispatch({ type: ActionConstants.SEND_INVITATION_SUCCESS, username }); + dispatch(loadUser(username)); + dispatch(publishMessage(successMessage("user.send-invitation-success"))); + }) + .catch((error) => { + dispatch({ type: ActionConstants.SEND_INVITATION_ERROR, error: error.response.data }); + dispatch(loadUser(username)); + dispatch(showServerResponseErrorMessage(error, "user.send-invitation-error")); + }); + }; } export function deleteInvitationOption(username) { - return function (dispatch) { - dispatch({type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, username}); - axiosBackend.post(`${API_URL}/rest/users/send-invitation/delete`, username, {headers: {"Content-Type": "text/plain"}}).then(() => { - dispatch({type: ActionConstants.INVITATION_OPTION_DELETE_SUCCESS, username}); - dispatch(loadUser(username)); - dispatch(publishMessage(successMessage("user.delete-invitation-option-success"))); - }).catch((error) => { - dispatch({type: ActionConstants.INVITATION_OPTION_DELETE_ERROR, error: error.response.data}); - dispatch(loadUser(username)); - dispatch(showServerResponseErrorMessage(error, 'user.delete-invitation-option-error')); - }); - } + return function (dispatch) { + dispatch({ type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, username }); + axiosBackend + .post(`${API_URL}/rest/users/send-invitation/delete`, username, { headers: { "Content-Type": "text/plain" } }) + .then(() => { + dispatch({ type: ActionConstants.INVITATION_OPTION_DELETE_SUCCESS, username }); + dispatch(loadUser(username)); + dispatch(publishMessage(successMessage("user.delete-invitation-option-success"))); + }) + .catch((error) => { + dispatch({ type: ActionConstants.INVITATION_OPTION_DELETE_ERROR, error: error.response.data }); + dispatch(loadUser(username)); + dispatch(showServerResponseErrorMessage(error, "user.delete-invitation-option-error")); + }); + }; } export function impersonate(username) { - return function (dispatch) { - dispatch({type: ActionConstants.IMPERSONATE_PENDING}); - axiosBackend.post(`${API_URL}/rest/users/impersonate`, `username=${username}`, { - headers: {'Content-Type': MediaType.FORM_URLENCODED} - }).then(() => { - dispatch({type: ActionConstants.IMPERSONATE_SUCCESS, username}); - transitionToHome(); - window.location.reload(); - }).catch((error) => { - dispatch({type: ActionConstants.IMPERSONATE_ERROR, error: error.response.data}); - dispatch(showServerResponseErrorMessage(error, 'user.impersonate-error')); - }); - } + return function (dispatch) { + dispatch({ type: ActionConstants.IMPERSONATE_PENDING }); + axiosBackend + .post(`${API_URL}/rest/users/impersonate`, `username=${username}`, { + headers: { "Content-Type": MediaType.FORM_URLENCODED }, + }) + .then(() => { + dispatch({ type: ActionConstants.IMPERSONATE_SUCCESS, username }); + transitionToHome(); + window.location.reload(); + }) + .catch((error) => { + dispatch({ type: ActionConstants.IMPERSONATE_ERROR, error: error.response.data }); + dispatch(showServerResponseErrorMessage(error, "user.impersonate-error")); + }); + }; } export function oidcImpersonate(username) { - return function (dispatch) { - dispatch({type: ActionConstants.IMPERSONATE_PENDING}); - axiosBackend.post(`${getEnv("AUTH_SERVER_URL")}/protocol/openid-connect/token`, new URLSearchParams({ - client_id: getEnv("AUTH_CLIENT_ID"), - grant_type: "urn:ietf:params:oauth:grant-type:token-exchange", - requested_subject: username, - subject_token: getOidcToken().access_token - }), { - headers: {'Content-Type': MediaType.FORM_URLENCODED} - }).then((resp) => { - dispatch({type: ActionConstants.IMPERSONATE_SUCCESS, username}); - // Store the current user (impersonator)'s id token for later logout - const impersonatorIdToken = getOidcToken().id_token; - const impersonatorData = Object.assign({}, resp.data, {impersonatorIdToken: impersonatorIdToken}); - saveOidcToken(impersonatorData); - transitionToHome(); - window.location.reload(); - }).catch((error) => { - dispatch({type: ActionConstants.IMPERSONATE_ERROR, error: error.response.data}); - }); - } -} \ No newline at end of file + return function (dispatch) { + dispatch({ type: ActionConstants.IMPERSONATE_PENDING }); + axiosBackend + .post( + `${getEnv("AUTH_SERVER_URL")}/protocol/openid-connect/token`, + new URLSearchParams({ + client_id: getEnv("AUTH_CLIENT_ID"), + grant_type: "urn:ietf:params:oauth:grant-type:token-exchange", + requested_subject: username, + subject_token: getOidcToken().access_token, + }), + { + headers: { "Content-Type": MediaType.FORM_URLENCODED }, + }, + ) + .then((resp) => { + dispatch({ type: ActionConstants.IMPERSONATE_SUCCESS, username }); + // Store the current user (impersonator)'s id token for later logout + const impersonatorIdToken = getOidcToken().id_token; + const impersonatorData = Object.assign({}, resp.data, { impersonatorIdToken: impersonatorIdToken }); + saveOidcToken(impersonatorData); + transitionToHome(); + window.location.reload(); + }) + .catch((error) => { + dispatch({ type: ActionConstants.IMPERSONATE_ERROR, error: error.response.data }); + }); + }; +} diff --git a/src/actions/UsersActions.js b/src/actions/UsersActions.js index f949c2a6..159554bb 100644 --- a/src/actions/UsersActions.js +++ b/src/actions/UsersActions.js @@ -1,36 +1,39 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {axiosBackend} from "./index"; -import {API_URL} from '../../config'; -import {showServerResponseErrorMessage} from "./AsyncActionUtils"; +import { axiosBackend } from "./index"; +import { API_URL } from "../../config"; +import { showServerResponseErrorMessage } from "./AsyncActionUtils"; export function loadUsers() { - return function (dispatch) { - dispatch(loadUsersPending()); - return axiosBackend.get(`${API_URL}/rest/users`).then((response) => { - dispatch(loadUsersSuccess(response.data)); - }).catch((error) => { - dispatch(loadUsersError(error.response.data)); - dispatch(showServerResponseErrorMessage(error, 'users.loading-error')); - }); - } + return function (dispatch) { + dispatch(loadUsersPending()); + return axiosBackend + .get(`${API_URL}/rest/users`) + .then((response) => { + dispatch(loadUsersSuccess(response.data)); + }) + .catch((error) => { + dispatch(loadUsersError(error.response.data)); + dispatch(showServerResponseErrorMessage(error, "users.loading-error")); + }); + }; } export function loadUsersPending() { - return { - type: ActionConstants.LOAD_USERS_PENDING - } + return { + type: ActionConstants.LOAD_USERS_PENDING, + }; } export function loadUsersSuccess(users) { - return { - type: ActionConstants.LOAD_USERS_SUCCESS, - users - } + return { + type: ActionConstants.LOAD_USERS_SUCCESS, + users, + }; } export function loadUsersError(error) { - return { - type: ActionConstants.LOAD_USERS_ERROR, - error - } + return { + type: ActionConstants.LOAD_USERS_ERROR, + error, + }; } diff --git a/src/actions/index.js b/src/actions/index.js index b2d5c603..cf8ef2b4 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,39 +1,41 @@ -import axios from 'axios'; +import axios from "axios"; import Routes from "../constants/RoutesConstants"; -import {transitionTo} from "../utils/Routing"; -import {HttpHeaders} from "../constants/DefaultConstants"; -import {getOidcToken} from "../utils/SecurityUtils"; -import {isUsingOidcAuth} from "../utils/OidcUtils"; +import { transitionTo } from "../utils/Routing"; +import { HttpHeaders } from "../constants/DefaultConstants"; +import { getOidcToken } from "../utils/SecurityUtils"; +import { isUsingOidcAuth } from "../utils/OidcUtils"; // Axios instance for communicating with Backend export let axiosBackend = axios.create({ - withCredentials: true + withCredentials: true, }); axiosBackend.interceptors.request.use((reqConfig) => { - if (!isUsingOidcAuth()) { - return reqConfig; - } - if (!reqConfig.headers) { - reqConfig.headers = {}; - } - reqConfig.headers[HttpHeaders.AUTHORIZATION] = `Bearer ${getOidcToken().access_token}`; + if (!isUsingOidcAuth()) { return reqConfig; + } + if (!reqConfig.headers) { + reqConfig.headers = {}; + } + reqConfig.headers[HttpHeaders.AUTHORIZATION] = `Bearer ${getOidcToken().access_token}`; + return reqConfig; }); axiosBackend.interceptors.response.use( - response => response, - error => { - const {status} = error.response; - if (status === 401) { // non-logged - if (!window.location.pathname.includes('/login')) { - transitionTo(Routes.login); - } - } - if (status === 403) { // non-authorized - transitionTo(Routes.dashboard); - } - /* + (response) => response, + (error) => { + const { status } = error.response; + if (status === 401) { + // non-logged + if (!window.location.pathname.includes("/login")) { + transitionTo(Routes.login); + } + } + if (status === 403) { + // non-authorized + transitionTo(Routes.dashboard); + } + /* if (status === 500) { // server error error = { response: { @@ -43,7 +45,6 @@ axiosBackend.interceptors.response.use( } } }*/ - return Promise.reject(error); - } + return Promise.reject(error); + }, ); - diff --git a/src/components/AlertMessage.jsx b/src/components/AlertMessage.jsx index 40523eab..cf1ec0d1 100644 --- a/src/components/AlertMessage.jsx +++ b/src/components/AlertMessage.jsx @@ -1,19 +1,19 @@ -import React from 'react'; -import {Alert} from "react-bootstrap"; +import React from "react"; +import { Alert } from "react-bootstrap"; import PropTypes from "prop-types"; const AlertMessage = (props) => ( -
- - {props.message} - -
+
+ + {props.message} + +
); AlertMessage.propTypes = { - type: PropTypes.string.isRequired, - message: PropTypes.string.isRequired, - alertPosition: PropTypes.string + type: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + alertPosition: PropTypes.string, }; export default AlertMessage; diff --git a/src/components/DeleteItemDialog.jsx b/src/components/DeleteItemDialog.jsx index ef4797b7..afad9020 100644 --- a/src/components/DeleteItemDialog.jsx +++ b/src/components/DeleteItemDialog.jsx @@ -1,38 +1,40 @@ -import React from 'react'; -import {FormattedMessage} from "react-intl"; -import {Button, Modal} from 'react-bootstrap'; +import React from "react"; +import { FormattedMessage } from "react-intl"; +import { Button, Modal } from "react-bootstrap"; import PropTypes from "prop-types"; -import {useI18n} from "../hooks/useI18n"; +import { useI18n } from "../hooks/useI18n"; const DeleteItemDialog = (props) => { - const {i18n} = useI18n(); - if (!props.item) { - return null; - } - return - - - {i18n('delete.dialog-title')} - - - - - - - - - + const { i18n } = useI18n(); + if (!props.item) { + return null; + } + return ( + + + {i18n("delete.dialog-title")} + + + + + + + + + ); }; DeleteItemDialog.propTypes = { - onClose: PropTypes.func.isRequired, - onSubmit: PropTypes.func.isRequired, - show: PropTypes.bool.isRequired, - item: PropTypes.object, - itemLabel: PropTypes.string + onClose: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + show: PropTypes.bool.isRequired, + item: PropTypes.object, + itemLabel: PropTypes.string, }; export default DeleteItemDialog; diff --git a/src/components/HelpIcon.jsx b/src/components/HelpIcon.jsx index c1a60031..dcc1b08b 100644 --- a/src/components/HelpIcon.jsx +++ b/src/components/HelpIcon.jsx @@ -1,45 +1,46 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {OverlayTrigger, Tooltip} from 'react-bootstrap'; +import React from "react"; +import { OverlayTrigger, Tooltip } from "react-bootstrap"; import PropTypes from "prop-types"; -import {FaEnvelope, FaQuestionCircle} from 'react-icons/fa'; -import {FaCheck} from 'react-icons/fa'; -import {FaTimes} from 'react-icons/fa'; -import {FaTasks} from "react-icons/fa"; +import { FaEnvelope, FaQuestionCircle } from "react-icons/fa"; +import { FaCheck } from "react-icons/fa"; +import { FaTimes } from "react-icons/fa"; +import { FaTasks } from "react-icons/fa"; const HelpIcon = (props) => { - const tooltip = {props.text}; - - const icon = () => { - switch (props.glyph) { - case "ok": - return ; - case "remove": - return ; - case "to-do": - return ; - case "envelope": - return - default: - return ; - } + const tooltip = {props.text}; + + const icon = () => { + switch (props.glyph) { + case "ok": + return ; + case "remove": + return ; + case "to-do": + return ; + case "envelope": + return ; + default: + return ; } + }; - - return - {icon()} - ; + return ( + + {icon()} + + ); }; HelpIcon.propTypes = { - text: PropTypes.string.isRequired, - className: PropTypes.string, - glyph: PropTypes.string + text: PropTypes.string.isRequired, + className: PropTypes.string, + glyph: PropTypes.string, }; HelpIcon.defaultProps = { - glyph: "help" + glyph: "help", }; export default HelpIcon; diff --git a/src/components/HorizontalInput.jsx b/src/components/HorizontalInput.jsx index 9c8fb5f6..0f955b08 100644 --- a/src/components/HorizontalInput.jsx +++ b/src/components/HorizontalInput.jsx @@ -1,164 +1,184 @@ -'use strict'; +"use strict"; import React from "react"; import ReactDOM from "react-dom"; -import {Col, FormCheck, FormControl, FormGroup, FormLabel, FormText, InputGroup} from "react-bootstrap"; +import { Col, FormCheck, FormControl, FormGroup, FormLabel, FormText, InputGroup } from "react-bootstrap"; import PropTypes from "prop-types"; -import Row from 'react-bootstrap/Row'; +import Row from "react-bootstrap/Row"; import TypeaheadAnswer from "./record/TypeaheadAnswer"; export default class HorizontalInput extends React.Component { - static propTypes = { - type: PropTypes.string, - label: PropTypes.string, - value: PropTypes.any, - onChange: PropTypes.func, - help: PropTypes.string, - validation: PropTypes.oneOf(['success', 'warning', 'error']), - labelWidth: PropTypes.number, // Width of the label - inputWidth: PropTypes.number, // Width of the input component container - inputOffset: PropTypes.number, // Offset to put before the input component. Applicable only for - possibleValueQuery: PropTypes.string, - // checkboxes and radios - iconRight: PropTypes.object - }; - - static defaultProps = { - type: 'text', - labelWidth: 4, - inputWidth: 9, - inputOffset: 4 - }; - - constructor(props) { - super(props); - } - - focus() { - ReactDOM.findDOMNode(this.input).focus(); - } - - getInputDOMNode() { - return ReactDOM.findDOMNode(this.input); - } - - render() { - switch (this.props.type) { - case 'radio': - return this._renderRadio(); - case 'checkbox': - return this._renderCheckbox(); - case 'select': - return this._renderSelect(); - case 'textarea': - return this._renderTextArea(); - case 'autocomplete': - return this._renderAutocomplete(); - default: - return this._renderInput(); - } - } - - _getInputProps() { - let props = {...this.props}; - delete props.inputOffset; - delete props.inputWidth; - delete props.labelWidth; - delete props.help; - delete props.validation; - delete props.iconRight; - - return props; - } - - _renderCheckbox() { - return - - this.input = c} {...this._getInputProps()}>{this.props.label} - - ; - } - - _renderRadio() { - return - - this.input = c} {...this._getInputProps()}>{this.props.label} - - ; - } - - _renderSelect() { - // TODO validation - return - {this._renderLabel()} - - this.input = c} {...this._getInputProps()}> - {this.props.children} - - {this.props.validation && } - {this._renderHelp()} - - ; - } - - _renderAutocomplete() { - // TODO validation - return - {this._renderLabel()} - - - {this.props.validation && } - {this._renderHelp()} - - - } - - _renderLabel() { - return this.props.label ? - {this.props.label} - : null; - } - - _renderTextArea() { - // TODO validation - return - {this._renderLabel()} - - this.input = c} {...this._getInputProps()}/> - {this.props.validation && } - {this._renderHelp()} - - ; - } - - _renderHelp() { - return this.props.help ? {this.props.help} : null; - } - - _renderInput() { - // TODO validation - const formControl = this.input = c} as='input' {...this._getInputProps()}/>; - return - {this._renderLabel()} - - {this.props.iconRight ? - - {formControl} - {this.props.iconRight} - - : -
- {formControl} - {this.props.validation && } - {this._renderHelp()} -
- } - -
; + static propTypes = { + type: PropTypes.string, + label: PropTypes.string, + value: PropTypes.any, + onChange: PropTypes.func, + help: PropTypes.string, + validation: PropTypes.oneOf(["success", "warning", "error"]), + labelWidth: PropTypes.number, // Width of the label + inputWidth: PropTypes.number, // Width of the input component container + inputOffset: PropTypes.number, // Offset to put before the input component. Applicable only for + possibleValueQuery: PropTypes.string, + // checkboxes and radios + iconRight: PropTypes.object, + }; + + static defaultProps = { + type: "text", + labelWidth: 4, + inputWidth: 9, + inputOffset: 4, + }; + + constructor(props) { + super(props); + } + + focus() { + ReactDOM.findDOMNode(this.input).focus(); + } + + getInputDOMNode() { + return ReactDOM.findDOMNode(this.input); + } + + render() { + switch (this.props.type) { + case "radio": + return this._renderRadio(); + case "checkbox": + return this._renderCheckbox(); + case "select": + return this._renderSelect(); + case "textarea": + return this._renderTextArea(); + case "autocomplete": + return this._renderAutocomplete(); + default: + return this._renderInput(); } + } + + _getInputProps() { + let props = { ...this.props }; + delete props.inputOffset; + delete props.inputWidth; + delete props.labelWidth; + delete props.help; + delete props.validation; + delete props.iconRight; + + return props; + } + + _renderCheckbox() { + return ( + + + (this.input = c)} {...this._getInputProps()}> + {this.props.label} + + + + ); + } + + _renderRadio() { + return ( + + + (this.input = c)} {...this._getInputProps()}> + {this.props.label} + + + + ); + } + + _renderSelect() { + // TODO validation + return ( + + {this._renderLabel()} + + (this.input = c)} {...this._getInputProps()}> + {this.props.children} + + {this.props.validation && } + {this._renderHelp()} + + + ); + } + + _renderAutocomplete() { + // TODO validation + return ( + + {this._renderLabel()} + + + {this.props.validation && } + {this._renderHelp()} + + + ); + } + + _renderLabel() { + return this.props.label ? ( + + {this.props.label} + + ) : null; + } + + _renderTextArea() { + // TODO validation + return ( + + {this._renderLabel()} + + (this.input = c)} + {...this._getInputProps()} + /> + {this.props.validation && } + {this._renderHelp()} + + + ); + } + + _renderHelp() { + return this.props.help ? {this.props.help} : null; + } + + _renderInput() { + // TODO validation + const formControl = (this.input = c)} as="input" {...this._getInputProps()} />; + return ( + + {this._renderLabel()} + + {this.props.iconRight ? ( + + {formControl} + + {this.props.iconRight} + + + ) : ( +
+ {formControl} + {this.props.validation && } + {this._renderHelp()} +
+ )} + +
+ ); + } } diff --git a/src/components/ImpersonatorBadge.jsx b/src/components/ImpersonatorBadge.jsx index d5477123..21366b42 100644 --- a/src/components/ImpersonatorBadge.jsx +++ b/src/components/ImpersonatorBadge.jsx @@ -1,16 +1,20 @@ import React from "react"; -import {useSelector} from "react-redux"; -import {Badge} from "react-bootstrap"; -import {useI18n} from "../hooks/useI18n"; -import {isImpersonator} from "../utils/SecurityUtils"; +import { useSelector } from "react-redux"; +import { Badge } from "react-bootstrap"; +import { useI18n } from "../hooks/useI18n"; +import { isImpersonator } from "../utils/SecurityUtils"; const ImpersonatorBadge = () => { - const {i18n} = useI18n(); - const user = useSelector(state => state.auth.user); - if (isImpersonator(user)) { - return {i18n("main.impersonating")}; - } - return null; + const { i18n } = useI18n(); + const user = useSelector((state) => state.auth.user); + if (isImpersonator(user)) { + return ( + + {i18n("main.impersonating")} + + ); + } + return null; }; export default ImpersonatorBadge; diff --git a/src/components/Input.jsx b/src/components/Input.jsx index 20c78132..d5f2eab2 100644 --- a/src/components/Input.jsx +++ b/src/components/Input.jsx @@ -1,93 +1,107 @@ -'use strict'; +"use strict"; import React from "react"; import ReactDOM from "react-dom"; -import {FormLabel, FormGroup, FormControl, FormText, FormCheck} from "react-bootstrap"; +import { FormLabel, FormGroup, FormControl, FormText, FormCheck } from "react-bootstrap"; import PropTypes from "prop-types"; export default class Input extends React.Component { - static propTypes = { - type: PropTypes.string, - label: PropTypes.string, - value: PropTypes.any, - onChange: PropTypes.func, - help: PropTypes.string, - validation: PropTypes.oneOf(['success', 'warning', 'error']) - }; + static propTypes = { + type: PropTypes.string, + label: PropTypes.string, + value: PropTypes.any, + onChange: PropTypes.func, + help: PropTypes.string, + validation: PropTypes.oneOf(["success", "warning", "error"]), + }; - static defaultProps = { - type: 'text' - }; + static defaultProps = { + type: "text", + }; - constructor(props) { - super(props); - } + constructor(props) { + super(props); + } - focus() { - ReactDOM.findDOMNode(this.input).focus(); - } + focus() { + ReactDOM.findDOMNode(this.input).focus(); + } - getInputDOMNode() { - return ReactDOM.findDOMNode(this.input); - } + getInputDOMNode() { + return ReactDOM.findDOMNode(this.input); + } - render() { - switch (this.props.type) { - case 'radio': - return this._renderRadio(); - case 'checkbox': - return this._renderCheckbox(); - case 'select': - return this._renderSelect(); - case 'textarea': - return this._renderTextArea(); - default: - return this._renderInput(); - } + render() { + switch (this.props.type) { + case "radio": + return this._renderRadio(); + case "checkbox": + return this._renderCheckbox(); + case "select": + return this._renderSelect(); + case "textarea": + return this._renderTextArea(); + default: + return this._renderInput(); } + } - _renderCheckbox() { - return this.input = c} {...this.props}>{this.props.label}; - } + _renderCheckbox() { + return ( + (this.input = c)} {...this.props}> + {this.props.label} + + ); + } - _renderRadio() { - return this.input = c} {...this.props}>{this.props.label}; - } + _renderRadio() { + return ( + (this.input = c)} {...this.props}> + {this.props.label} + + ); + } - _renderSelect() { - return - {this._renderLabel()} - this.input = c} {...this.props}> - {this.props.children} - - {this.props.validation && } - {this._renderHelp()} - ; - } + _renderSelect() { + return ( + + {this._renderLabel()} + (this.input = c)} {...this.props}> + {this.props.children} + + {this.props.validation && } + {this._renderHelp()} + + ); + } - _renderLabel() { - return this.props.label ? {this.props.label} : null; - } + _renderLabel() { + return this.props.label ? {this.props.label} : null; + } - _renderTextArea() { - return - {this._renderLabel()} - this.input = c} {...this.props}/> - {this.props.validation && } - {this._renderHelp()} - ; - } + _renderTextArea() { + return ( + + {this._renderLabel()} + (this.input = c)} {...this.props} /> + {this.props.validation && } + {this._renderHelp()} + + ); + } - _renderHelp() { - return this.props.help ? {this.props.help} : null; - } + _renderHelp() { + return this.props.help ? {this.props.help} : null; + } - _renderInput() { - return - {this._renderLabel()} - this.input = c} as='input' {...this.props}/> - {this.props.validation && } - {this._renderHelp()} - ; - } + _renderInput() { + return ( + + {this._renderLabel()} + (this.input = c)} as="input" {...this.props} /> + {this.props.validation && } + {this._renderHelp()} + + ); + } } diff --git a/src/components/Loader.jsx b/src/components/Loader.jsx index a57549e6..a11a4c0f 100644 --- a/src/components/Loader.jsx +++ b/src/components/Loader.jsx @@ -1,42 +1,44 @@ -import React from 'react'; -import {Card} from "react-bootstrap"; +import React from "react"; +import { Card } from "react-bootstrap"; const Loader = () => ( -
-
-
-
-
-
-
+
+
+
+
+
+
+
); export default Loader; export const LoaderMask = () => ( -
-
- -
+
+
+
+
); export const ContainerLoaderMask = () => ( -
-
- -
+
+
+
+
); export const LoaderCard = (props) => ( - - {props.header} - - + + + {props.header} + + + + + ); -export const LoaderSmall = () => ( -
-); \ No newline at end of file +export const LoaderSmall = () =>
; diff --git a/src/components/MainView.jsx b/src/components/MainView.jsx index bfbc29cb..8f985bff 100644 --- a/src/components/MainView.jsx +++ b/src/components/MainView.jsx @@ -1,166 +1,186 @@ import React from "react"; import * as I18nStore from "../stores/I18nStore"; -import {Container, Nav, Navbar, NavDropdown, NavItem} from "react-bootstrap"; -import {authRoutes, unauthRoutes} from "../utils/Routes"; +import { Container, Nav, Navbar, NavDropdown, NavItem } from "react-bootstrap"; +import { authRoutes, unauthRoutes } from "../utils/Routes"; import Routes from "../constants/RoutesConstants"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../i18n/withI18n"; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; -import {ACTION_STATUS, ROLE} from "../constants/DefaultConstants"; -import {loadUserProfile} from "../actions/AuthActions"; +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; +import { ACTION_STATUS, ROLE } from "../constants/DefaultConstants"; +import { loadUserProfile } from "../actions/AuthActions"; import * as Constants from "../constants/DefaultConstants"; -import {LoaderMask} from "./Loader"; -import {NavLink, withRouter} from 'react-router-dom'; -import {IfGranted} from "react-authorization"; -import {transitionTo, transitionToWithOpts} from "../utils/Routing"; -import {isUsingOidcAuth, userProfileLink} from "../utils/OidcUtils"; +import { LoaderMask } from "./Loader"; +import { NavLink, withRouter } from "react-router-dom"; +import { IfGranted } from "react-authorization"; +import { transitionTo, transitionToWithOpts } from "../utils/Routing"; +import { isUsingOidcAuth, userProfileLink } from "../utils/OidcUtils"; import ImpersonatorBadge from "./ImpersonatorBadge"; -import {isAdmin} from "../utils/SecurityUtils"; +import { isAdmin } from "../utils/SecurityUtils"; import Messages from "./message/Messages"; import Footer from "../Footer"; class MainView extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - } + constructor(props) { + super(props); + this.i18n = this.props.i18n; + } - componentDidMount() { - this.props.loadUserProfile(); - I18nStore.setIntl(this.props.intl); - } + componentDidMount() { + this.props.loadUserProfile(); + I18nStore.setIntl(this.props.intl); + } - _renderUsers() { - const path = this.props.location.pathname; + _renderUsers() { + const path = this.props.location.pathname; - return - - path.startsWith(Routes.users.path)} - className="nav-link">{this.i18n('main.users-nav')} - - ; - } + return ( + + + path.startsWith(Routes.users.path)} className="nav-link"> + {this.i18n("main.users-nav")} + + + + ); + } - removeUnsupportedBrowserWarning() { - const unsupportedBrowserElem = document.getElementById("unsupported-browser"); - if (unsupportedBrowserElem) { - unsupportedBrowserElem.remove(); - } + removeUnsupportedBrowserWarning() { + const unsupportedBrowserElem = document.getElementById("unsupported-browser"); + if (unsupportedBrowserElem) { + unsupportedBrowserElem.remove(); } + } - onProfileClick() { - if (isUsingOidcAuth()) { - window.location = userProfileLink(); - } else { - this.props.transitionToWithOpts(Routes.editUser, {params: {username: this.props.user.username}}); - } + onProfileClick() { + if (isUsingOidcAuth()) { + window.location = userProfileLink(); + } else { + this.props.transitionToWithOpts(Routes.editUser, { params: { username: this.props.user.username } }); } + } - render() { - if (this.props.status === ACTION_STATUS.PENDING) { - return ; - } - - this.removeUnsupportedBrowserWarning() + render() { + if (this.props.status === ACTION_STATUS.PENDING) { + return ; + } - if (!this.props.isLoaded) { - return (
{unauthRoutes}
); - } - const user = this.props.user; - const name = user.firstName.substring(0, 1) + '. ' + user.lastName; - const path = this.props.location.pathname; + this.removeUnsupportedBrowserWarning(); - return ( -
-
- - - this.props.history.push(Routes.dashboard.path)}> - {Constants.APP_NAME} - - - - + if (!this.props.isLoaded) { + return
{unauthRoutes}
; + } + const user = this.props.user; + const name = user.firstName.substring(0, 1) + ". " + user.lastName; + const path = this.props.location.pathname; - -
-
-
-
-
- - {authRoutes} -
-
-
- ); - } + + + + + +
+ + {authRoutes} +
+
+
+ ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(withRouter(MainView)))); function mapStateToProps(state) { - return { - user: state.auth.user, - isLoaded: state.auth.isLoaded, - status: state.auth.status, - intl: state.intl - }; + return { + user: state.auth.user, + isLoaded: state.auth.isLoaded, + status: state.auth.status, + intl: state.intl, + }; } function mapDispatchToProps(dispatch) { - return { - loadUserProfile: bindActionCreators(loadUserProfile, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch) - } -} \ No newline at end of file + return { + loadUserProfile: bindActionCreators(loadUserProfile, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + }; +} diff --git a/src/components/dashboard/Dashboard.jsx b/src/components/dashboard/Dashboard.jsx index f0a02378..a10e2aff 100644 --- a/src/components/dashboard/Dashboard.jsx +++ b/src/components/dashboard/Dashboard.jsx @@ -1,147 +1,169 @@ import React from "react"; import withI18n from "../../i18n/withI18n"; -import {FormattedMessage, injectIntl} from "react-intl"; -import {Col, Container, Jumbotron, Row} from "react-bootstrap"; +import { FormattedMessage, injectIntl } from "react-intl"; +import { Col, Container, Jumbotron, Row } from "react-bootstrap"; import DashboardTile from "./DashboardTile"; import PropTypes from "prop-types"; -import {processTypeaheadOptions} from "../record/TypeaheadAnswer"; +import { processTypeaheadOptions } from "../record/TypeaheadAnswer"; import ImportRecordsDialog from "../record/ImportRecordsDialog"; -import {isAdmin} from "../../utils/SecurityUtils"; -import {trackPromise} from "react-promise-tracker"; +import { isAdmin } from "../../utils/SecurityUtils"; +import { trackPromise } from "react-promise-tracker"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; class Dashboard extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - importDialogOpen: false - }; - } - - onImportRecords = (file) => { - trackPromise(this.props.handlers.importRecords(file), "dashboard"); - this.setState({importDialogOpen: false}); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + importDialogOpen: false, }; - - renderTitle() { - return
- {this.props.currentUser.firstName}}}/> -
; - } - - _renderMainDashboard() { - return -
- - {this._renderCreateRecordTile()} - {this._renderImportRecordsTile()} - {this._renderShowRecordsTiles()} - - - {this._renderUsersTile()} - {this._renderInstitutionsTile()} - {this._renderStatisticsTile()} - -
-
; - } - - _renderCreateRecordTile() { - return this._isAdmin() - ? - {this.i18n('dashboard.create-tile')} - - : ""; + } + + onImportRecords = (file) => { + trackPromise(this.props.handlers.importRecords(file), "dashboard"); + this.setState({ importDialogOpen: false }); + }; + + renderTitle() { + return ( +
+ {this.props.currentUser.firstName} }} + /> +
+ ); + } + + _renderMainDashboard() { + return ( + +
+ + {this._renderCreateRecordTile()} + {this._renderImportRecordsTile()} + {this._renderShowRecordsTiles()} + + + {this._renderUsersTile()} + {this._renderInstitutionsTile()} + {this._renderStatisticsTile()} + +
+
+ ); + } + + _renderCreateRecordTile() { + return this._isAdmin() ? ( + + {this.i18n("dashboard.create-tile")} + + ) : ( + "" + ); + } + + _renderImportRecordsTile() { + return ( + + this.setState({ importDialogOpen: true })}> + {this.i18n("records.import.dialog.title")} + + + ); + } + + _renderShowRecordsTiles() { + if (this._isAdmin()) { + return this._renderShowRecordTile(); + } else { + const formTemplates = this.props.formTemplatesLoaded.formTemplates; + if (formTemplates) { + return processTypeaheadOptions(formTemplates, this.props.intl).map((ft, i) => + this._renderShowRecordTile(ft, i.toString()), + ); + } } - - _renderImportRecordsTile() { - return - this.setState({importDialogOpen: true})}>{this.i18n('records.import.dialog.title')} + } + + _renderShowRecordTile(formTemplate, key) { + if (!formTemplate) { + return ( + + this.props.handlers.showRecords()}> + {this.i18n("dashboard.records-tile")} + + ); } + const showRecordsOfTemplate = () => { + return this.props.handlers.showRecords(formTemplate.id); + }; - _renderShowRecordsTiles() { - if (this._isAdmin()) { - return this._renderShowRecordTile(); - } else { - const formTemplates = this.props.formTemplatesLoaded.formTemplates; - if (formTemplates) { - - return processTypeaheadOptions(formTemplates, this.props.intl) - .map((ft, i) => this._renderShowRecordTile(ft, i.toString())) - } - } - } - - _renderShowRecordTile(formTemplate, key) { - if (!formTemplate) { - return - this.props.handlers.showRecords()}>{this.i18n('dashboard.records-tile')} - - } - const showRecordsOfTemplate = () => { - return this.props.handlers.showRecords(formTemplate.id) - } - - return - {formTemplate.name} - - } - - _renderUsersTile() { - return this._isAdmin() ? - - {this.i18n('dashboard.users-tile')} - - : ""; - } - - _renderInstitutionsTile() { - return this._isAdmin() ? - - {this.i18n('dashboard.institutions-tile')} - - : ""; - } - - _renderStatisticsTile() { - return this._isAdmin() ? - - {this.i18n('dashboard.statistics-tile')} - : null; - } - - _isAdmin() { - return isAdmin(this.props.currentUser); - } - - render() { - return ( - - - this.setState({importDialogOpen: false})} - onSubmit={this.onImportRecords}/> - {this.renderTitle()} - {this._renderMainDashboard()} - - ); - } + return ( + + {formTemplate.name} + + ); + } + + _renderUsersTile() { + return this._isAdmin() ? ( + + {this.i18n("dashboard.users-tile")} + + ) : ( + "" + ); + } + + _renderInstitutionsTile() { + return this._isAdmin() ? ( + + + {this.i18n("dashboard.institutions-tile")} + + + ) : ( + "" + ); + } + + _renderStatisticsTile() { + return this._isAdmin() ? ( + + + {this.i18n("dashboard.statistics-tile")} + + + ) : null; + } + + _isAdmin() { + return isAdmin(this.props.currentUser); + } + + render() { + return ( + + + this.setState({ importDialogOpen: false })} + onSubmit={this.onImportRecords} + /> + {this.renderTitle()} + {this._renderMainDashboard()} + + ); + } } Dashboard.propTypes = { - currentUser: PropTypes.object.isRequired, - handlers: PropTypes.object.isRequired, - formTemplatesLoaded: PropTypes.object.isRequired + currentUser: PropTypes.object.isRequired, + handlers: PropTypes.object.isRequired, + formTemplatesLoaded: PropTypes.object.isRequired, }; export default injectIntl(withI18n(Dashboard)); diff --git a/src/components/dashboard/DashboardController.jsx b/src/components/dashboard/DashboardController.jsx index 8959387d..c54b1c9b 100644 --- a/src/components/dashboard/DashboardController.jsx +++ b/src/components/dashboard/DashboardController.jsx @@ -1,106 +1,109 @@ -'use strict'; +"use strict"; import Dashboard from "./Dashboard"; -import React from 'react'; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; -import {injectIntl} from "react-intl"; -import Routes from '../../constants/RoutesConstants'; -import {transitionTo, transitionToWithOpts} from '../../utils/Routing'; +import React from "react"; +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; +import { injectIntl } from "react-intl"; +import Routes from "../../constants/RoutesConstants"; +import { transitionTo, transitionToWithOpts } from "../../utils/Routing"; import withI18n from "../../i18n/withI18n"; -import {loadFormTemplates} from "../../actions/FormTemplatesActions"; -import {importRecords} from "../../actions/RecordsActions"; +import { loadFormTemplates } from "../../actions/FormTemplatesActions"; +import { importRecords } from "../../actions/RecordsActions"; class DashboardController extends React.Component { - constructor(props) { - super(props); - } + constructor(props) { + super(props); + } - _showUsers = () => { - transitionTo(Routes.users); - }; + _showUsers = () => { + transitionTo(Routes.users); + }; - _showMyProfile = () => { - this.props.transitionToWithOpts(Routes.editUser, { - params: {username: this.props.currentUser.username} - }); - }; + _showMyProfile = () => { + this.props.transitionToWithOpts(Routes.editUser, { + params: { username: this.props.currentUser.username }, + }); + }; - _showInstitutions = () => { - transitionTo(Routes.institutions); - }; + _showInstitutions = () => { + transitionTo(Routes.institutions); + }; - _showMyInstitution = () => { - this.props.transitionToWithOpts(Routes.editInstitution, { - params: {key: this.props.currentUser.institution.key} - }); - }; + _showMyInstitution = () => { + this.props.transitionToWithOpts(Routes.editInstitution, { + params: { key: this.props.currentUser.institution.key }, + }); + }; - _showRecords = (formTemplate) => { - const opts = {}; - if (formTemplate) { - opts.query = new Map([["formTemplate", formTemplate]]); - } - this.props.transitionToWithOpts(Routes.records, opts); - }; + _showRecords = (formTemplate) => { + const opts = {}; + if (formTemplate) { + opts.query = new Map([["formTemplate", formTemplate]]); + } + this.props.transitionToWithOpts(Routes.records, opts); + }; - _showStatistics = () => { - transitionTo(Routes.statistics); - }; + _showStatistics = () => { + transitionTo(Routes.statistics); + }; - _createRecord = () => { - {/*TODO bug on cancel it doesnt return to dashboard but to patient records */ - } - this.props.transitionToWithOpts(Routes.createRecord, { - handlers: { - onSuccess: Routes.records, - onCancel: Routes.dashboard - } - }); - }; - - _importRecords = (file) => { - return this.props.importRecords(file); + _createRecord = () => { + { + /*TODO bug on cancel it doesnt return to dashboard but to patient records */ } + this.props.transitionToWithOpts(Routes.createRecord, { + handlers: { + onSuccess: Routes.records, + onCancel: Routes.dashboard, + }, + }); + }; - componentDidMount() { - this.props.loadFormTemplates(); - } + _importRecords = (file) => { + return this.props.importRecords(file); + }; - render() { - const handlers = { - showUsers: this._showUsers, - showInstitutions: this._showInstitutions, - showRecords: this._showRecords, - createRecord: this._createRecord, - importRecords: this._importRecords, - showMyInstitution: this._showMyInstitution, - showMyProfile: this._showMyProfile, - showStatistics: this._showStatistics - }; - return ( -
- -
- ); - } + componentDidMount() { + this.props.loadFormTemplates(); + } + + render() { + const handlers = { + showUsers: this._showUsers, + showInstitutions: this._showInstitutions, + showRecords: this._showRecords, + createRecord: this._createRecord, + importRecords: this._importRecords, + showMyInstitution: this._showMyInstitution, + showMyProfile: this._showMyProfile, + showStatistics: this._showStatistics, + }; + return ( +
+ +
+ ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(DashboardController))); function mapStateToProps(state) { - return { - currentUser: state.auth.user, - formTemplatesLoaded: state.formTemplates.formTemplatesLoaded - }; + return { + currentUser: state.auth.user, + formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, + }; } function mapDispatchToProps(dispatch) { - return { - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), - loadFormTemplates: bindActionCreators(loadFormTemplates, dispatch), - importRecords: bindActionCreators(importRecords, dispatch) - } -} \ No newline at end of file + return { + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + loadFormTemplates: bindActionCreators(loadFormTemplates, dispatch), + importRecords: bindActionCreators(importRecords, dispatch), + }; +} diff --git a/src/components/dashboard/DashboardTile.jsx b/src/components/dashboard/DashboardTile.jsx index f99797bd..ac5d167c 100644 --- a/src/components/dashboard/DashboardTile.jsx +++ b/src/components/dashboard/DashboardTile.jsx @@ -1,16 +1,19 @@ -'use strict'; +"use strict"; import React from "react"; import PropTypes from "prop-types"; const DashboardTile = (props) => { - return ; + return ( + + ); }; DashboardTile.propTypes = { - onClick: PropTypes.func.isRequired, - disabled: PropTypes.bool + onClick: PropTypes.func.isRequired, + disabled: PropTypes.bool, }; export default DashboardTile; diff --git a/src/components/history/HistoryDetail.jsx b/src/components/history/HistoryDetail.jsx index fc6777f0..83cb5361 100644 --- a/src/components/history/HistoryDetail.jsx +++ b/src/components/history/HistoryDetail.jsx @@ -1,84 +1,100 @@ -import React from 'react'; -import {useDispatch, useSelector} from "react-redux"; -import {Button, Card} from "react-bootstrap"; -import {ROLE} from "../../constants/DefaultConstants"; -import {transitionTo} from "../../utils/Routing"; +import React from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, Card } from "react-bootstrap"; +import { ROLE } from "../../constants/DefaultConstants"; +import { transitionTo } from "../../utils/Routing"; import Routes from "../../constants/RoutesConstants"; -import {loadActionByKey} from "../../actions/HistoryActions"; +import { loadActionByKey } from "../../actions/HistoryActions"; import HorizontalInput from "../HorizontalInput"; -import {formatDateWithMilliseconds} from "../../utils/Utils"; -import {useI18n} from "../../hooks/useI18n"; -import {useParams} from "react-router-dom"; -import {trackPromise} from "react-promise-tracker"; -import {IfGranted} from "react-authorization"; +import { formatDateWithMilliseconds } from "../../utils/Utils"; +import { useI18n } from "../../hooks/useI18n"; +import { useParams } from "react-router-dom"; +import { trackPromise } from "react-promise-tracker"; +import { IfGranted } from "react-authorization"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; const HistoryDetail = () => { - const {i18n} = useI18n(); - const {key} = useParams(); - const dispatch = useDispatch(); - const action = useSelector(state => state.history.actionLoaded.action); - const currentUser = useSelector(state => state.auth.user); - React.useEffect(() => { - trackPromise(dispatch(loadActionByKey(key)), "history-detail"); - }, [dispatch, key]); + const { i18n } = useI18n(); + const { key } = useParams(); + const dispatch = useDispatch(); + const action = useSelector((state) => state.history.actionLoaded.action); + const currentUser = useSelector((state) => state.auth.user); + React.useEffect(() => { + trackPromise(dispatch(loadActionByKey(key)), "history-detail"); + }, [dispatch, key]); - return - - - {i18n('history.panel-title')} - - - - {action && -
-
-
- -
-
- -
-
- {action.author && -
-
- -
-
- } - {action.payload && -
-
- -
-
- } -
- -
-
- } -
-
-
; + return ( + + + + {i18n("history.panel-title")} + + + + {action && ( +
+
+
+ +
+
+ +
+
+ {action.author && ( +
+
+ +
+
+ )} + {action.payload && ( +
+
+ +
+
+ )} +
+ +
+
+ )} +
+
+
+ ); }; export default HistoryDetail; diff --git a/src/components/history/HistoryList.jsx b/src/components/history/HistoryList.jsx index 3bb853a2..6353ac4b 100644 --- a/src/components/history/HistoryList.jsx +++ b/src/components/history/HistoryList.jsx @@ -1,102 +1,110 @@ -import React from 'react'; -import {connect} from "react-redux"; -import {injectIntl} from "react-intl"; +import React from "react"; +import { connect } from "react-redux"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; -import {Card} from "react-bootstrap"; -import {loadActions} from "../../actions/HistoryActions"; -import {bindActionCreators} from "redux"; +import { Card } from "react-bootstrap"; +import { loadActions } from "../../actions/HistoryActions"; +import { bindActionCreators } from "redux"; import HistoryTable from "./HistoryTable"; import Routes from "../../constants/RoutesConstants"; -import {transitionToWithOpts} from "../../utils/Routing"; -import Pagination, {INITIAL_PAGE} from "../misc/Pagination"; +import { transitionToWithOpts } from "../../utils/Routing"; +import Pagination, { INITIAL_PAGE } from "../misc/Pagination"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; -import {trackPromise} from "react-promise-tracker"; +import { trackPromise } from "react-promise-tracker"; class HistoryList extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - searchData: {}, - pageNumber: INITIAL_PAGE - } - } + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + searchData: {}, + pageNumber: INITIAL_PAGE, + }; + } - componentDidMount() { - trackPromise(this.props.loadActions(INITIAL_PAGE), "history"); - } + componentDidMount() { + trackPromise(this.props.loadActions(INITIAL_PAGE), "history"); + } - _onOpen = (key) => { - this.props.transitionToWithOpts(Routes.historyAction, { - params: {key} - }); - }; + _onOpen = (key) => { + this.props.transitionToWithOpts(Routes.historyAction, { + params: { key }, + }); + }; - _handleChange = (e) => { - let change = {}; - change[e.target.name] = e.target.value; - this.setState({searchData: {...this.state.searchData, ...change}, pageNumber: 1}); - }; + _handleChange = (e) => { + let change = {}; + change[e.target.name] = e.target.value; + this.setState({ searchData: { ...this.state.searchData, ...change }, pageNumber: 1 }); + }; - _onKeyPress = (e) => { - if (e.key === 'Enter') { - this._handleSearch(); - } - }; + _onKeyPress = (e) => { + if (e.key === "Enter") { + this._handleSearch(); + } + }; - _handleSearch = (newPageNumber = INITIAL_PAGE) => { - trackPromise(this.props.loadActions(newPageNumber, this.state.searchData), "history"); - }; + _handleSearch = (newPageNumber = INITIAL_PAGE) => { + trackPromise(this.props.loadActions(newPageNumber, this.state.searchData), "history"); + }; - _handleReset = () => { - this.setState({searchData: {}, pageNumber: INITIAL_PAGE}, () => this._handleSearch()); - }; + _handleReset = () => { + this.setState({ searchData: {}, pageNumber: INITIAL_PAGE }, () => this._handleSearch()); + }; - _handlePagination = (pageNumber) => { - this.setState({pageNumber: pageNumber}); - this._handleSearch(pageNumber); - }; + _handlePagination = (pageNumber) => { + this.setState({ pageNumber: pageNumber }); + this._handleSearch(pageNumber); + }; - render() { - const {actionsLoaded} = this.props; - const handlers = { - handleSearch: this._handleSearch, - handleReset: this._handleReset, - handleChange: this._handleChange, - onKeyPress: this._onKeyPress, - onOpen: this._onOpen - }; - return - - {this.i18n('main.history')} - - - - {actionsLoaded.actions && - <> - - - - } - - - } + render() { + const { actionsLoaded } = this.props; + const handlers = { + handleSearch: this._handleSearch, + handleReset: this._handleReset, + handleChange: this._handleChange, + onKeyPress: this._onKeyPress, + onOpen: this._onOpen, + }; + return ( + + + {this.i18n("main.history")} + + + + {actionsLoaded.actions && ( + <> + + + + )} + + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(HistoryList))); function mapStateToProps(state) { - return { - actionsLoaded: state.history.actionsLoaded - }; + return { + actionsLoaded: state.history.actionsLoaded, + }; } function mapDispatchToProps(dispatch) { - return { - loadActions: bindActionCreators(loadActions, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch) - } + return { + loadActions: bindActionCreators(loadActions, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + }; } diff --git a/src/components/history/HistoryRow.jsx b/src/components/history/HistoryRow.jsx index 32bca9d7..001e3489 100644 --- a/src/components/history/HistoryRow.jsx +++ b/src/components/history/HistoryRow.jsx @@ -1,28 +1,35 @@ import React from "react"; -import {Button} from "react-bootstrap"; +import { Button } from "react-bootstrap"; import PropTypes from "prop-types"; -import {formatDateWithMilliseconds} from "../../utils/Utils"; -import {useI18n} from "../../hooks/useI18n"; +import { formatDateWithMilliseconds } from "../../utils/Utils"; +import { useI18n } from "../../hooks/useI18n"; let HistoryRow = (props) => { - const {i18n} = useI18n(); - const action = props.action; - const username = action.author ? action.author.username : i18n('history.non-logged'); - return - {action.type} - {username} - {formatDateWithMilliseconds(action.timestamp)} - - - - ; + const { i18n } = useI18n(); + const action = props.action; + const username = action.author ? action.author.username : i18n("history.non-logged"); + return ( + + {action.type} + {username} + {formatDateWithMilliseconds(action.timestamp)} + + + + + ); }; HistoryRow.propTypes = { - action: PropTypes.object.isRequired, - onOpen: PropTypes.func.isRequired + action: PropTypes.object.isRequired, + onOpen: PropTypes.func.isRequired, }; export default HistoryRow; - diff --git a/src/components/history/HistorySearch.jsx b/src/components/history/HistorySearch.jsx index cf94f68f..a29bee88 100644 --- a/src/components/history/HistorySearch.jsx +++ b/src/components/history/HistorySearch.jsx @@ -1,34 +1,58 @@ import React from "react"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; -import {Button} from "react-bootstrap"; +import { Button } from "react-bootstrap"; import PropTypes from "prop-types"; let HistorySearch = (props) => ( - - - - - - - - - - - - - - - ); + + + + + + + + + + + + + + + +); HistorySearch.propTypes = { - handlers: PropTypes.object.isRequired, - searchData: PropTypes.object.isRequired + handlers: PropTypes.object.isRequired, + searchData: PropTypes.object.isRequired, }; export default injectIntl(withI18n(HistorySearch)); - diff --git a/src/components/history/HistoryTable.jsx b/src/components/history/HistoryTable.jsx index a2c31cbf..ce991c8a 100644 --- a/src/components/history/HistoryTable.jsx +++ b/src/components/history/HistoryTable.jsx @@ -1,40 +1,43 @@ import React from "react"; -import {Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import HistoryRow from "./HistoryRow"; import HistorySearch from "./HistorySearch"; import PropTypes from "prop-types"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; -const HistoryTable = ({actions, handlers, searchData}) => { - const {i18n} = useI18n(); +const HistoryTable = ({ actions, handlers, searchData }) => { + const { i18n } = useI18n(); - return
- - - - - - - + return ( +
+
{i18n('history.action-type')}{i18n('history.author')}{i18n('history.time')}{i18n('actions')}
+ + + + + + + + + + + {actions.length > 0 ? ( + actions.map((a) => ) + ) : ( + + - - - - {actions.length > 0 ? actions.map(a => ) - : - - - } - -
{i18n("history.action-type")}{i18n("history.author")}{i18n("history.time")}{i18n("actions")}
{i18n("history.not-found")}
{i18n('history.not-found')}
-
; -} + )} + + +
+ ); +}; HistoryTable.propTypes = { - actions: PropTypes.array.isRequired, - handlers: PropTypes.object.isRequired, - searchData: PropTypes.object.isRequired + actions: PropTypes.array.isRequired, + handlers: PropTypes.object.isRequired, + searchData: PropTypes.object.isRequired, }; - export default HistoryTable; diff --git a/src/components/institution/Institution.jsx b/src/components/institution/Institution.jsx index 9de517ce..8e4e0eed 100644 --- a/src/components/institution/Institution.jsx +++ b/src/components/institution/Institution.jsx @@ -1,15 +1,15 @@ import React from "react"; -import {Button, Card} from "react-bootstrap"; -import {FormattedMessage, injectIntl} from "react-intl"; +import { Button, Card } from "react-bootstrap"; +import { FormattedMessage, injectIntl } from "react-intl"; import InstitutionMembers from "./InstitutionMembers"; import InstitutionPatients from "./InstitutionPatients"; import withI18n from "../../i18n/withI18n"; import HorizontalInput from "../HorizontalInput"; import PropTypes from "prop-types"; -import {ACTION_STATUS, ROLE} from "../../constants/DefaultConstants"; -import {formatDate} from "../../utils/Utils"; -import {LoaderSmall} from "../Loader"; +import { ACTION_STATUS, ROLE } from "../../constants/DefaultConstants"; +import { formatDate } from "../../utils/Utils"; +import { LoaderSmall } from "../Loader"; import InstitutionValidator from "../../validation/InstitutionValidator"; import HelpIcon from "../HelpIcon"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; @@ -18,116 +18,159 @@ import PromiseTrackingMask from "../misc/PromiseTrackingMask"; * Institution detail. Editable only for admins. */ class Institution extends React.Component { - static propTypes = { - institution: PropTypes.object, - institutionLoaded: PropTypes.object, - institutionSaved: PropTypes.object, - institutionMembers: PropTypes.object, - recordsLoaded: PropTypes.object, - formTemplatesLoaded: PropTypes.object, - handlers: PropTypes.object.isRequired, - currentUser: PropTypes.object.isRequired, - filterAndSort: PropTypes.object.isRequired, - userDeleted: PropTypes.object - }; + static propTypes = { + institution: PropTypes.object, + institutionLoaded: PropTypes.object, + institutionSaved: PropTypes.object, + institutionMembers: PropTypes.object, + recordsLoaded: PropTypes.object, + formTemplatesLoaded: PropTypes.object, + handlers: PropTypes.object.isRequired, + currentUser: PropTypes.object.isRequired, + filterAndSort: PropTypes.object.isRequired, + userDeleted: PropTypes.object, + }; - constructor(props) { - super(props); - this.i18n = this.props.i18n; - } + constructor(props) { + super(props); + this.i18n = this.props.i18n; + } + + _onChange = (e) => { + let change = {}; + change[e.target.name] = e.target.value; + this.props.handlers.onChange(change); + }; - _onChange = (e) => { - let change = {}; - change[e.target.name] = e.target.value; - this.props.handlers.onChange(change); - }; + render() { + const { currentUser, institution, recordsLoaded, formTemplatesLoaded } = this.props; - render() { - const { - currentUser, - institution, - recordsLoaded, - formTemplatesLoaded - } = this.props; + return ( + + + {this.i18n("institution.panel-title")} + + + + {institution && ( + <> +
+
+
+ +
+
+ +
+
+ {this._renderAddedDate()} + {this._renderButtons()} +
+ {!institution.isNew && this._renderMembers()} + {!institution.isNew && ( + + )} + + )} +
+
+ ); + } - return - {this.i18n('institution.panel-title')} - - - {institution && <> -
-
-
- -
-
- -
-
- {this._renderAddedDate()} - {this._renderButtons()} -
- {!institution.isNew && this._renderMembers()} - {!institution.isNew && - } - - } -
-
; + _renderAddedDate() { + const { institution } = this.props; + if (institution.isNew || !institution.dateCreated) { + return null; } + const created = formatDate(institution.dateCreated); + return ( +
+
+
+ +
+
+
+ ); + } - _renderAddedDate() { - const {institution} = this.props; - if (institution.isNew || !institution.dateCreated) { - return null; - } - const created = formatDate(institution.dateCreated); - return
-
-
- -
-
+ _renderButtons() { + const { currentUser, handlers, institutionSaved } = this.props; + if (currentUser.role !== ROLE.ADMIN) { + return ( +
+
+ ); } - _renderButtons() { - const {currentUser, handlers, institutionSaved} = this.props; - if (currentUser.role !== ROLE.ADMIN) { - return
- -
; - } + return ( +
+ + +
+ ); + } - return
- - -
; - - } - - _renderMembers() { - const {institution, handlers, currentUser, institutionMembers, userDeleted} = this.props; - return - } + _renderMembers() { + const { institution, handlers, currentUser, institutionMembers, userDeleted } = this.props; + return ( + + ); + } } export default injectIntl(withI18n(Institution)); diff --git a/src/components/institution/InstitutionController.jsx b/src/components/institution/InstitutionController.jsx index dd5bd929..474b6a95 100644 --- a/src/components/institution/InstitutionController.jsx +++ b/src/components/institution/InstitutionController.jsx @@ -1,231 +1,258 @@ import React from "react"; import Institution from "./Institution"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; import Routes from "../../constants/RoutesConstants"; -import {transitionTo, transitionToWithOpts} from "../../utils/Routing"; -import {connect} from "react-redux"; +import { transitionTo, transitionToWithOpts } from "../../utils/Routing"; +import { connect } from "react-redux"; import { - ACTION_FLAG, - ACTION_STATUS, - DEFAULT_PAGE_SIZE, - SortDirection, - STORAGE_TABLE_PAGE_SIZE_KEY + ACTION_FLAG, + ACTION_STATUS, + DEFAULT_PAGE_SIZE, + SortDirection, + STORAGE_TABLE_PAGE_SIZE_KEY, } from "../../constants/DefaultConstants"; -import {bindActionCreators} from "redux"; +import { bindActionCreators } from "redux"; import { - createInstitution, - loadInstitution, - unloadInstitution, - unloadSavedInstitution, - updateInstitution + createInstitution, + loadInstitution, + unloadInstitution, + unloadSavedInstitution, + updateInstitution, } from "../../actions/InstitutionActions"; -import {canLoadInstitutionsPatients, sortToParams} from "../../utils/Utils"; -import {deleteUser, loadInstitutionMembers, unloadInstitutionMembers} from "../../actions/UserActions"; +import { canLoadInstitutionsPatients, sortToParams } from "../../utils/Utils"; +import { deleteUser, loadInstitutionMembers, unloadInstitutionMembers } from "../../actions/UserActions"; import * as EntityFactory from "../../utils/EntityFactory"; -import {exportRecords, loadRecords} from "../../actions/RecordsActions"; -import omit from 'lodash/omit'; -import {loadFormTemplates} from "../../actions/FormTemplatesActions"; -import {isAdmin} from "../../utils/SecurityUtils"; -import {trackPromise} from "react-promise-tracker"; -import {INITIAL_PAGE} from "../misc/Pagination"; +import { exportRecords, loadRecords } from "../../actions/RecordsActions"; +import omit from "lodash/omit"; +import { loadFormTemplates } from "../../actions/FormTemplatesActions"; +import { isAdmin } from "../../utils/SecurityUtils"; +import { trackPromise } from "react-promise-tracker"; +import { INITIAL_PAGE } from "../misc/Pagination"; import BrowserStorage from "../../utils/BrowserStorage"; class InstitutionController extends React.Component { - constructor(props) { - super(props); - this.state = { - institution: this._isNew() ? EntityFactory.initNewInstitution() : null, - saved: false, - pageNumber: INITIAL_PAGE, - filters: {}, - sort: { - date: SortDirection.DESC - } - }; + constructor(props) { + super(props); + this.state = { + institution: this._isNew() ? EntityFactory.initNewInstitution() : null, + saved: false, + pageNumber: INITIAL_PAGE, + filters: {}, + sort: { + date: SortDirection.DESC, + }, + }; + } + + componentDidMount() { + const institutionKey = this.props.match.params.key; + + if (!this.state.institution) { + trackPromise(this.props.loadInstitution(institutionKey), "institution"); + } + if (institutionKey) { + trackPromise(this.props.loadInstitutionMembers(institutionKey), "institution-members"); + if ( + this.props.status === ACTION_STATUS.SUCCESS && + canLoadInstitutionsPatients(institutionKey, this.props.currentUser) + ) { + this._loadRecords(); + } } + if ( + this.props.institutionSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY && + this.props.institutionSaved.status === ACTION_STATUS.SUCCESS + ) { + this.props.unloadSavedInstitution(); + } + this.props.loadFormTemplates(); + } + + _loadRecords() { + const institutionKey = this.props.match.params.key; + this.props.loadRecords({ + institution: institutionKey, + page: this.state.pageNumber, + size: BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY, DEFAULT_PAGE_SIZE), + sort: sortToParams(this.state.sort), + }); + } + + componentDidUpdate(prevProps) { + const { institutionLoaded, institutionSaved, transitionToWithOpts } = this.props; - componentDidMount() { - const institutionKey = this.props.match.params.key; - - if (!this.state.institution) { - trackPromise(this.props.loadInstitution(institutionKey), "institution"); - } - if (institutionKey) { - trackPromise(this.props.loadInstitutionMembers(institutionKey), "institution-members"); - if (this.props.status === ACTION_STATUS.SUCCESS && canLoadInstitutionsPatients(institutionKey, this.props.currentUser)) { - this._loadRecords(); - } - } - if (this.props.institutionSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY && this.props.institutionSaved.status === ACTION_STATUS.SUCCESS) { - this.props.unloadSavedInstitution(); - } - this.props.loadFormTemplates(); + if ( + prevProps.institutionLoaded.status === ACTION_STATUS.PENDING && + institutionLoaded.status === ACTION_STATUS.SUCCESS + ) { + this.setState({ institution: institutionLoaded.institution }); } - _loadRecords() { - const institutionKey = this.props.match.params.key; - this.props.loadRecords({ - institution: institutionKey, - page: this.state.pageNumber, - size: BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY, DEFAULT_PAGE_SIZE), - sort: sortToParams(this.state.sort) + if ( + this.state.saved && + institutionLoaded.status !== ACTION_STATUS.PENDING && + institutionSaved.status === ACTION_STATUS.SUCCESS + ) { + if (institutionSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY) { + transitionToWithOpts(Routes.editInstitution, { + params: { key: institutionSaved.institution.key }, + handlers: { + onCancel: Routes.institutions, + }, }); + } else { + this.setState({ saved: false }); + this.props.loadInstitution(this.state.institution.key); + } } + } - componentDidUpdate(prevProps) { - const {institutionLoaded, institutionSaved, transitionToWithOpts} = this.props; - - if (prevProps.institutionLoaded.status === ACTION_STATUS.PENDING && institutionLoaded.status === ACTION_STATUS.SUCCESS) { - this.setState({institution: institutionLoaded.institution}); - } - - if (this.state.saved && institutionLoaded.status !== ACTION_STATUS.PENDING - && institutionSaved.status === ACTION_STATUS.SUCCESS) { - if (institutionSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY) { - transitionToWithOpts(Routes.editInstitution, { - params: {key: institutionSaved.institution.key}, - handlers: { - onCancel: Routes.institutions - } - }); - } else { - this.setState({saved: false}); - this.props.loadInstitution(this.state.institution.key); - } - } - } + componentWillUnmount() { + this.props.unloadInstitution(); + this.props.unloadInstitutionMembers(); + } + + _isNew() { + return !this.props.match.params.key; + } - componentWillUnmount() { - this.props.unloadInstitution(); - this.props.unloadInstitutionMembers(); + _onSave = () => { + const institution = this.state.institution; + this.setState({ saved: true }); + if (institution.isNew || (this._isNew() && this.props.institutionSaved.status === ACTION_STATUS.ERROR)) { + trackPromise(this.props.createInstitution(omit(institution, "isNew")), "institution"); + } else { + trackPromise(this.props.updateInstitution(institution), "institution"); } + }; - _isNew() { - return !this.props.match.params.key; + _onCancel = () => { + const handlers = this.props.viewHandlers[Routes.editInstitution.name]; + if (handlers) { + transitionTo(handlers.onCancel); + } else if (isAdmin(this.props.currentUser)) { + transitionTo(Routes.institutions); + } else { + transitionTo(Routes.dashboard); } + }; - _onSave = () => { - const institution = this.state.institution; - this.setState({saved: true}); - if (institution.isNew || (this._isNew() && this.props.institutionSaved.status === ACTION_STATUS.ERROR)) { - trackPromise(this.props.createInstitution(omit(institution, 'isNew')), "institution"); - } else { - trackPromise(this.props.updateInstitution(institution), "institution"); - } - }; + _onChange = (change) => { + const update = { ...this.state.institution, ...change }; + this.setState({ institution: update }); + }; - _onCancel = () => { - const handlers = this.props.viewHandlers[Routes.editInstitution.name]; - if (handlers) { - transitionTo(handlers.onCancel); - } else if (isAdmin(this.props.currentUser)) { - transitionTo(Routes.institutions); - } else { - transitionTo(Routes.dashboard); - } - }; + _onDeleteUser = (user) => { + trackPromise(this.props.deleteUser(user, this.state.institution), "institution-members"); + }; - _onChange = (change) => { - const update = {...this.state.institution, ...change}; - this.setState({institution: update}); - }; + _onEditUser = (user, institution) => { + this.props.transitionToWithOpts(Routes.editUser, { + params: { username: user.username }, + payload: { institution: institution }, + }); + }; - _onDeleteUser = (user) => { - trackPromise(this.props.deleteUser(user, this.state.institution), "institution-members"); - }; + _onEditPatient = (patient) => { + this.props.transitionToWithOpts(Routes.editRecord, { params: { key: patient.key } }); + }; - _onEditUser = (user, institution) => { - this.props.transitionToWithOpts(Routes.editUser, { - params: {username: user.username}, - payload: {institution: institution} - }); - }; + _onExportRecords = (exportType) => { + const institutionKey = this.state.institution.key; + this.props.exportRecords(exportType, { institution: institutionKey, sort: sortToParams(this.state.sort) }); + }; - _onEditPatient = (patient) => { - this.props.transitionToWithOpts(Routes.editRecord, {params: {key: patient.key}}); - }; + _onAddNewUser = (institution) => { + this.props.transitionToWithOpts(Routes.createUser, { + payload: { institution: institution }, + }); + }; - _onExportRecords = (exportType) => { - const institutionKey = this.state.institution.key; - this.props.exportRecords(exportType, {institution: institutionKey, sort: sortToParams(this.state.sort)}); - }; + onFilterAndSort = (filterChange, sortChange) => { + this.setState( + { + filters: Object.assign({}, this.state.filters, filterChange), + sort: Object.assign({}, this.state.sort, sortChange), + }, + this._loadRecords, + ); + }; - _onAddNewUser = (institution) => { - this.props.transitionToWithOpts(Routes.createUser, { - payload: {institution: institution} - }); - }; - - onFilterAndSort = (filterChange, sortChange) => { - this.setState({ - filters: Object.assign({}, this.state.filters, filterChange), - sort: Object.assign({}, this.state.sort, sortChange) - }, this._loadRecords); - } - - render() { - const { - currentUser, institutionLoaded, institutionSaved, institutionMembers, - recordsLoaded, formTemplatesLoaded, userDeleted - } = this.props; - if (!currentUser) { - return null; - } - const handlers = { - onSave: this._onSave, - onCancel: this._onCancel, - onChange: this._onChange, - onEditUser: this._onEditUser, - onAddNewUser: this._onAddNewUser, - onEditPatient: this._onEditPatient, - onExportRecords: this._onExportRecords, - onDelete: this._onDeleteUser - }; - const filterAndSort = { - filters: this.state.filters, - sort: this.state.sort, - onChange: this.onFilterAndSort - }; - return ; + render() { + const { + currentUser, + institutionLoaded, + institutionSaved, + institutionMembers, + recordsLoaded, + formTemplatesLoaded, + userDeleted, + } = this.props; + if (!currentUser) { + return null; } + const handlers = { + onSave: this._onSave, + onCancel: this._onCancel, + onChange: this._onChange, + onEditUser: this._onEditUser, + onAddNewUser: this._onAddNewUser, + onEditPatient: this._onEditPatient, + onExportRecords: this._onExportRecords, + onDelete: this._onDeleteUser, + }; + const filterAndSort = { + filters: this.state.filters, + sort: this.state.sort, + onChange: this.onFilterAndSort, + }; + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(InstitutionController))); function mapStateToProps(state) { - return { - currentUser: state.auth.user, - status: state.auth.status, - institutionLoaded: state.institution.institutionLoaded, - institutionSaved: state.institution.institutionSaved, - institutionMembers: state.user.institutionMembers, - recordsLoaded: state.records.recordsLoaded, - formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, - viewHandlers: state.router.viewHandlers, - userDeleted: state.user.userDeleted - }; + return { + currentUser: state.auth.user, + status: state.auth.status, + institutionLoaded: state.institution.institutionLoaded, + institutionSaved: state.institution.institutionSaved, + institutionMembers: state.user.institutionMembers, + recordsLoaded: state.records.recordsLoaded, + formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, + viewHandlers: state.router.viewHandlers, + userDeleted: state.user.userDeleted, + }; } function mapDispatchToProps(dispatch) { - return { - loadInstitution: bindActionCreators(loadInstitution, dispatch), - unloadInstitution: bindActionCreators(unloadInstitution, dispatch), - unloadSavedInstitution: bindActionCreators(unloadSavedInstitution, dispatch), - createInstitution: bindActionCreators(createInstitution, dispatch), - updateInstitution: bindActionCreators(updateInstitution, dispatch), - loadInstitutionMembers: bindActionCreators(loadInstitutionMembers, dispatch), - loadRecords: bindActionCreators(loadRecords, dispatch), - loadFormTemplates: bindActionCreators(loadFormTemplates, dispatch), - deleteUser: bindActionCreators(deleteUser, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), - unloadInstitutionMembers: bindActionCreators(unloadInstitutionMembers, dispatch), - exportRecords: bindActionCreators(exportRecords, dispatch) - } -} \ No newline at end of file + return { + loadInstitution: bindActionCreators(loadInstitution, dispatch), + unloadInstitution: bindActionCreators(unloadInstitution, dispatch), + unloadSavedInstitution: bindActionCreators(unloadSavedInstitution, dispatch), + createInstitution: bindActionCreators(createInstitution, dispatch), + updateInstitution: bindActionCreators(updateInstitution, dispatch), + loadInstitutionMembers: bindActionCreators(loadInstitutionMembers, dispatch), + loadRecords: bindActionCreators(loadRecords, dispatch), + loadFormTemplates: bindActionCreators(loadFormTemplates, dispatch), + deleteUser: bindActionCreators(deleteUser, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + unloadInstitutionMembers: bindActionCreators(unloadInstitutionMembers, dispatch), + exportRecords: bindActionCreators(exportRecords, dispatch), + }; +} diff --git a/src/components/institution/InstitutionMembers.jsx b/src/components/institution/InstitutionMembers.jsx index 07564359..beaef786 100644 --- a/src/components/institution/InstitutionMembers.jsx +++ b/src/components/institution/InstitutionMembers.jsx @@ -1,120 +1,144 @@ -import React from 'react'; -import {Button, Card, Table} from 'react-bootstrap'; -import {injectIntl} from "react-intl"; -import withI18n from '../../i18n/withI18n'; +import React from "react"; +import { Button, Card, Table } from "react-bootstrap"; +import { injectIntl } from "react-intl"; +import withI18n from "../../i18n/withI18n"; import DeleteItemDialog from "../DeleteItemDialog"; -import {ACTION_STATUS} from "../../constants/DefaultConstants"; -import Loader, {LoaderSmall} from "../Loader"; +import { ACTION_STATUS } from "../../constants/DefaultConstants"; +import Loader, { LoaderSmall } from "../Loader"; import PropTypes from "prop-types"; -import {isAdmin} from "../../utils/SecurityUtils"; +import { isAdmin } from "../../utils/SecurityUtils"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; class InstitutionMembers extends React.Component { - constructor(props) { - super(props); - this.state = { - showDialog: false, - selectedUser: null - }; - this.i18n = this.props.i18n; - } - - _onDelete = (user) => { - this.setState({showDialog: true, selectedUser: user}); + constructor(props) { + super(props); + this.state = { + showDialog: false, + selectedUser: null, }; + this.i18n = this.props.i18n; + } - _onCancelDelete = () => { - this.setState({showDialog: false, selectedUser: null}); - }; + _onDelete = (user) => { + this.setState({ showDialog: true, selectedUser: user }); + }; - _onSubmitDelete = () => { - this.props.onDelete(this.state.selectedUser); - this.setState({showDialog: false, selectedUser: null, showAlert: true}); - }; + _onCancelDelete = () => { + this.setState({ showDialog: false, selectedUser: null }); + }; - _getDeleteLabel() { - const user = this.state.selectedUser; - return user ? user.username : ''; - } + _onSubmitDelete = () => { + this.props.onDelete(this.state.selectedUser); + this.setState({ showDialog: false, selectedUser: null, showAlert: true }); + }; - render() { - const {institutionMembers, institution, currentUser, onAddNewUser} = this.props; - if (!institutionMembers.members && (!institutionMembers.status || institutionMembers.status === ACTION_STATUS.PENDING)) { - return - } + _getDeleteLabel() { + const user = this.state.selectedUser; + return user ? user.username : ""; + } - return - {this.i18n('institution.members.panel-title')} - - - - {institutionMembers.members.length > 0 ? - - - - - - - - - - - {this._renderRows()} - -
{this.i18n('name')}{this.i18n('login.username')}{this.i18n('users.email')}{this.i18n('table-actions')}
- : -

{this.i18n('institution.members.not-found')}

- } - {isAdmin(currentUser) && -
- -
- } -
-
; + render() { + const { institutionMembers, institution, currentUser, onAddNewUser } = this.props; + if ( + !institutionMembers.members && + (!institutionMembers.status || institutionMembers.status === ACTION_STATUS.PENDING) + ) { + return ; } - _renderRows() { - const {institution, onEditUser, currentUser, userDeleted} = this.props; - let rows = []; - const members = this.props.institutionMembers.members; - for (let i = 0, len = members.length; i < len; i++) { - const deletionLoading = !!(userDeleted.status === ACTION_STATUS.PENDING && userDeleted.username === members[i].username); - const member = members[i]; - rows.push( - {member.firstName + ' ' + member.lastName} - {member.username} - {member.emailAddress} - - - {isAdmin(currentUser) && - } - - ); - } - return rows; + return ( + + + {this.i18n("institution.members.panel-title")} + + + + + {institutionMembers.members.length > 0 ? ( + + + + + + + + + + {this._renderRows()} +
{this.i18n("name")}{this.i18n("login.username")}{this.i18n("users.email")}{this.i18n("table-actions")}
+ ) : ( +

{this.i18n("institution.members.not-found")}

+ )} + {isAdmin(currentUser) && ( +
+ +
+ )} +
+
+ ); + } + + _renderRows() { + const { institution, onEditUser, currentUser, userDeleted } = this.props; + let rows = []; + const members = this.props.institutionMembers.members; + for (let i = 0, len = members.length; i < len; i++) { + const deletionLoading = !!( + userDeleted.status === ACTION_STATUS.PENDING && userDeleted.username === members[i].username + ); + const member = members[i]; + rows.push( + + {member.firstName + " " + member.lastName} + {member.username} + {member.emailAddress} + + + {isAdmin(currentUser) && ( + + )} + + , + ); } + return rows; + } } InstitutionMembers.propTypes = { - institutionMembers: PropTypes.object.isRequired, - institution: PropTypes.object.isRequired, - onEditUser: PropTypes.func.isRequired, - onAddNewUser: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, - currentUser: PropTypes.object.isRequired, - userDeleted: PropTypes.object + institutionMembers: PropTypes.object.isRequired, + institution: PropTypes.object.isRequired, + onEditUser: PropTypes.func.isRequired, + onAddNewUser: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, + currentUser: PropTypes.object.isRequired, + userDeleted: PropTypes.object, }; export default injectIntl(withI18n(InstitutionMembers)); diff --git a/src/components/institution/InstitutionPatients.jsx b/src/components/institution/InstitutionPatients.jsx index 185a8a24..cb1d68ac 100644 --- a/src/components/institution/InstitutionPatients.jsx +++ b/src/components/institution/InstitutionPatients.jsx @@ -1,37 +1,43 @@ -import React from 'react'; -import {Card} from 'react-bootstrap'; -import RecordTable from '../record/RecordTable'; +import React from "react"; +import { Card } from "react-bootstrap"; +import RecordTable from "../record/RecordTable"; import PropTypes from "prop-types"; import ExportRecordsDropdown from "../record/ExportRecordsDropdown"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; const InstitutionPatients = (props) => { - const {recordsLoaded, formTemplatesLoaded, onEdit, onExport, currentUser, filterAndSort} = props; - const {i18n} = useI18n(); + const { recordsLoaded, formTemplatesLoaded, onEdit, onExport, currentUser, filterAndSort } = props; + const { i18n } = useI18n(); - return - {i18n('institution.patients.panel-title')} - - -
- -
-
-
; + return ( + + + {i18n("institution.patients.panel-title")} + + + +
+ +
+
+
+ ); }; InstitutionPatients.propTypes = { - recordsLoaded: PropTypes.object.isRequired, - formTemplatesLoaded: PropTypes.object.isRequired, - onEdit: PropTypes.func.isRequired, - onExport: PropTypes.func.isRequired, - currentUser: PropTypes.object.isRequired, - filterAndSort: PropTypes.object.isRequired + recordsLoaded: PropTypes.object.isRequired, + formTemplatesLoaded: PropTypes.object.isRequired, + onEdit: PropTypes.func.isRequired, + onExport: PropTypes.func.isRequired, + currentUser: PropTypes.object.isRequired, + filterAndSort: PropTypes.object.isRequired, }; export default InstitutionPatients; diff --git a/src/components/institution/InstitutionRow.jsx b/src/components/institution/InstitutionRow.jsx index 48a425c7..34cdeec5 100644 --- a/src/components/institution/InstitutionRow.jsx +++ b/src/components/institution/InstitutionRow.jsx @@ -1,36 +1,54 @@ import React from "react"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; -import {Button} from "react-bootstrap"; -import {LoaderSmall} from "../Loader"; +import { Button } from "react-bootstrap"; +import { LoaderSmall } from "../Loader"; import PropTypes from "prop-types"; let InstitutionRow = (props) => { - const institution = props.institution; - return - - - - {institution.emailAddress} - - - - - ; + const institution = props.institution; + return ( + + + + + {institution.emailAddress} + + + + + + ); }; InstitutionRow.propTypes = { - institution: PropTypes.object.isRequired, - onEdit: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, - deletionLoading: PropTypes.bool.isRequired, - i18n: PropTypes.func.isRequired, + institution: PropTypes.object.isRequired, + onEdit: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, + deletionLoading: PropTypes.bool.isRequired, + i18n: PropTypes.func.isRequired, }; export default injectIntl(withI18n(InstitutionRow)); - diff --git a/src/components/institution/InstitutionTable.jsx b/src/components/institution/InstitutionTable.jsx index 10bc05c7..c6bdff0a 100644 --- a/src/components/institution/InstitutionTable.jsx +++ b/src/components/institution/InstitutionTable.jsx @@ -1,89 +1,102 @@ -'use strict'; +"use strict"; import React from "react"; -import {Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import DeleteItemDialog from "../DeleteItemDialog"; -import {ACTION_STATUS} from "../../constants/DefaultConstants"; +import { ACTION_STATUS } from "../../constants/DefaultConstants"; import InstitutionRow from "./InstitutionRow"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; import PropTypes from "prop-types"; class InstitutionTable extends React.Component { - static propTypes = { - institutions: PropTypes.array.isRequired, - handlers: PropTypes.object.isRequired, - institutionDeleted: PropTypes.object - }; - - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - showDialog: false, - selectedItem: null - } - } + static propTypes = { + institutions: PropTypes.array.isRequired, + handlers: PropTypes.object.isRequired, + institutionDeleted: PropTypes.object, + }; - _onDelete = (item) => { - this.setState({showDialog: true, selectedItem: item}); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + showDialog: false, + selectedItem: null, }; + } - _onCancelDelete = () => { - this.setState({showDialog: false, selectedItem: null}); - }; + _onDelete = (item) => { + this.setState({ showDialog: true, selectedItem: item }); + }; - _onSubmitDelete = () => { - this.props.handlers.onDelete(this.state.selectedItem); - this.setState({showDialog: false, selectedItem: null}); - }; + _onCancelDelete = () => { + this.setState({ showDialog: false, selectedItem: null }); + }; - render() { - return
- - {this.props.institutions.length > 0 ? - - {this._renderHeader()} - - {this._renderRows()} - -
- : -

{this.i18n('institutions.not-found')}

- } -
; - } + _onSubmitDelete = () => { + this.props.handlers.onDelete(this.state.selectedItem); + this.setState({ showDialog: false, selectedItem: null }); + }; - _getDeleteLabel() { - const institution = this.state.selectedItem; - return institution ? institution.name : ''; - } + render() { + return ( +
+ + {this.props.institutions.length > 0 ? ( + + {this._renderHeader()} + {this._renderRows()} +
+ ) : ( +

{this.i18n("institutions.not-found")}

+ )} +
+ ); + } - _renderHeader() { - return + _getDeleteLabel() { + const institution = this.state.selectedItem; + return institution ? institution.name : ""; + } + + _renderHeader() { + return ( + - {this.i18n('name')} - {this.i18n('institution.email')} - {this.i18n('actions')} + {this.i18n("name")} + {this.i18n("institution.email")} + {this.i18n("actions")} - ; - } + + ); + } - _renderRows() { - const {institutions, institutionDeleted} = this.props; - const onEdit = this.props.handlers.onEdit; - let rows = []; - for (let i = 0, len = institutions.length; i < len; i++) { - rows.push(); - } - return rows; + _renderRows() { + const { institutions, institutionDeleted } = this.props; + const onEdit = this.props.handlers.onEdit; + let rows = []; + for (let i = 0, len = institutions.length; i < len; i++) { + rows.push( + , + ); } + return rows; + } } export default injectIntl(withI18n(InstitutionTable)); diff --git a/src/components/institution/Institutions.jsx b/src/components/institution/Institutions.jsx index 293d41b0..12061a1d 100644 --- a/src/components/institution/Institutions.jsx +++ b/src/components/institution/Institutions.jsx @@ -1,36 +1,42 @@ -import React from 'react'; -import {Button, Card} from 'react-bootstrap'; -import InstitutionTable from './InstitutionTable'; -import {ACTION_STATUS} from "../../constants/DefaultConstants"; -import {LoaderSmall} from "../Loader"; +import React from "react"; +import { Button, Card } from "react-bootstrap"; +import InstitutionTable from "./InstitutionTable"; +import { ACTION_STATUS } from "../../constants/DefaultConstants"; +import { LoaderSmall } from "../Loader"; import PropTypes from "prop-types"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; -const Institutions = ({institutionsLoaded, handlers, institutionDeleted}) => { - const {i18n} = useI18n(); +const Institutions = ({ institutionsLoaded, handlers, institutionDeleted }) => { + const { i18n } = useI18n(); - return - - {i18n('institutions.panel-title')} - {institutionsLoaded.status === ACTION_STATUS.PENDING && } - - - - -
- -
-
+ return ( + + + {i18n("institutions.panel-title")} + {institutionsLoaded.status === ACTION_STATUS.PENDING && } + + + + +
+ +
+
+ ); }; Institutions.propTypes = { - institutionsLoaded: PropTypes.object, - handlers: PropTypes.object.isRequired, - institutionDeleted: PropTypes.object + institutionsLoaded: PropTypes.object, + handlers: PropTypes.object.isRequired, + institutionDeleted: PropTypes.object, }; export default Institutions; diff --git a/src/components/institution/InstitutionsController.jsx b/src/components/institution/InstitutionsController.jsx index f3b5fa75..fbded3f1 100644 --- a/src/components/institution/InstitutionsController.jsx +++ b/src/components/institution/InstitutionsController.jsx @@ -1,77 +1,83 @@ -'use strict'; +"use strict"; import React from "react"; import Routes from "../../constants/RoutesConstants"; -import {transitionToWithOpts} from "../../utils/Routing"; +import { transitionToWithOpts } from "../../utils/Routing"; import Institutions from "./Institutions"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; -import {connect} from "react-redux"; -import {ROLE} from "../../constants/DefaultConstants"; -import {loadInstitutions} from "../../actions/InstitutionsActions"; -import {bindActionCreators} from "redux"; -import {deleteInstitution} from "../../actions/InstitutionActions"; -import {trackPromise} from "react-promise-tracker"; +import { connect } from "react-redux"; +import { ROLE } from "../../constants/DefaultConstants"; +import { loadInstitutions } from "../../actions/InstitutionsActions"; +import { bindActionCreators } from "redux"; +import { deleteInstitution } from "../../actions/InstitutionActions"; +import { trackPromise } from "react-promise-tracker"; class InstitutionsController extends React.Component { - constructor(props) { - super(props); - } + constructor(props) { + super(props); + } - componentDidMount() { - trackPromise(this.props.loadInstitutions(), "institutions"); - } + componentDidMount() { + trackPromise(this.props.loadInstitutions(), "institutions"); + } - _onEditInstitution = (institution) => { - this.props.transitionToWithOpts(Routes.editInstitution, { - params: {key: institution.key}, - handlers: { - onCancel: Routes.institutions - } - }); - }; + _onEditInstitution = (institution) => { + this.props.transitionToWithOpts(Routes.editInstitution, { + params: { key: institution.key }, + handlers: { + onCancel: Routes.institutions, + }, + }); + }; - _onAddInstitution = () => { - this.props.transitionToWithOpts(Routes.createInstitution, { - handlers: { - onSuccess: Routes.institutions, - onCancel: Routes.institutions - } - }); - }; + _onAddInstitution = () => { + this.props.transitionToWithOpts(Routes.createInstitution, { + handlers: { + onSuccess: Routes.institutions, + onCancel: Routes.institutions, + }, + }); + }; - _onDeleteInstitution = (institution) => { - trackPromise(this.props.deleteInstitution(institution), "institutions"); - }; + _onDeleteInstitution = (institution) => { + trackPromise(this.props.deleteInstitution(institution), "institutions"); + }; - render() { - const {currentUser, institutionsLoaded, institutionDeleted} = this.props; - if (!currentUser || currentUser.role !== ROLE.ADMIN) { - return null; - } - const handlers = { - onEdit: this._onEditInstitution, - onCreate: this._onAddInstitution, - onDelete: this._onDeleteInstitution - }; - return ; + render() { + const { currentUser, institutionsLoaded, institutionDeleted } = this.props; + if (!currentUser || currentUser.role !== ROLE.ADMIN) { + return null; } + const handlers = { + onEdit: this._onEditInstitution, + onCreate: this._onAddInstitution, + onDelete: this._onDeleteInstitution, + }; + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(InstitutionsController))); function mapStateToProps(state) { - return { - institutionsLoaded: state.institutions.institutionsLoaded, - institutionDeleted: state.institution.institutionDeleted, - currentUser: state.auth.user - }; + return { + institutionsLoaded: state.institutions.institutionsLoaded, + institutionDeleted: state.institution.institutionDeleted, + currentUser: state.auth.user, + }; } function mapDispatchToProps(dispatch) { - return { - deleteInstitution: bindActionCreators(deleteInstitution, dispatch), - loadInstitutions: bindActionCreators(loadInstitutions, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch) - } -} \ No newline at end of file + return { + deleteInstitution: bindActionCreators(deleteInstitution, dispatch), + loadInstitutions: bindActionCreators(loadInstitutions, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + }; +} diff --git a/src/components/login/Login.jsx b/src/components/login/Login.jsx index 80912844..5992a929 100644 --- a/src/components/login/Login.jsx +++ b/src/components/login/Login.jsx @@ -1,131 +1,160 @@ -'use strict'; +"use strict"; import React from "react"; -import {Alert, Button, Form, Card} from "react-bootstrap"; +import { Alert, Button, Form, Card } from "react-bootstrap"; import HorizontalInput from "../HorizontalInput"; import withI18n from "../../i18n/withI18n"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import Routes from "../../constants/RoutesConstants"; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; -import {ALERT_TYPES} from "../../constants/DefaultConstants"; +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; +import { ALERT_TYPES } from "../../constants/DefaultConstants"; import AlertMessage from "../AlertMessage"; -import {transitionTo} from "../../utils/Routing"; -import {login} from "../../actions/AuthActions"; -import {LoaderSmall} from "../Loader"; -import {deviceIsMobile, deviceIsSupported} from "../../utils/Utils"; +import { transitionTo } from "../../utils/Routing"; +import { login } from "../../actions/AuthActions"; +import { LoaderSmall } from "../Loader"; +import { deviceIsMobile, deviceIsSupported } from "../../utils/Utils"; import * as SupportedDevices from "../../constants/SupportedDevices"; class Login extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - username: '', - password: '', - showAlert: false, - } - } - - componentDidMount() { - this.usernameField.focus(); - this.setState({deviceSupported: deviceIsSupported()}); - } - - onChange = (e) => { - let state = this.state; - state[e.target.name] = e.target.value; - state.alertVisible = false; - this.setState(state); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + username: "", + password: "", + showAlert: false, }; + } - onKeyPress = (e) => { - if (e.key === 'Enter') { - this.login(); - } - }; - - login = () => { - this.props.login(this.state.username, this.state.password); - this.setState({showAlert: true}); - }; + componentDidMount() { + this.usernameField.focus(); + this.setState({ deviceSupported: deviceIsSupported() }); + } - onForgotPassword = () => { - transitionTo(Routes.passwordReset) - }; + onChange = (e) => { + let state = this.state; + state[e.target.name] = e.target.value; + state.alertVisible = false; + this.setState(state); + }; - getSupportedBrowsersLinks() { - return SupportedDevices.SUPPORTED_BROWSERS_LINKS.map((browser, index) => { - return - {browser.linkMobile && browser.linkDesktop ? - {browser.name} : {browser.name}} - {index <= SupportedDevices.SUPPORTED_BROWSERS_LINKS.length - 3 && , } - {index === SupportedDevices.SUPPORTED_BROWSERS_LINKS.length - 2 && {this.i18n('or')} } - {index === SupportedDevices.SUPPORTED_BROWSERS_LINKS.length - 1 && .} - - }); + onKeyPress = (e) => { + if (e.key === "Enter") { + this.login(); } + }; - render() { - return ( - - {this.i18n('login.title')} - - {!this.state.deviceSupported && -
- - {this.i18n('Your browser is not fully supported! Some parts of web may not work properly.')}
- {this.i18n('We recommend using the latest version of ')} - {this.getSupportedBrowsersLinks()} -
-
} - {this.state.showAlert && this.props.error && -
- + login = () => { + this.props.login(this.state.username, this.state.password); + this.setState({ showAlert: true }); + }; -
} -
- { - this.usernameField = input; - }} - label={this.i18n('login.username')} value={this.state.username} - onChange={this.onChange} labelWidth={4} onKeyPress={this.onKeyPress} - inputWidth={8}/> - -
- -
-
- -
- -
-
- ) - } + onForgotPassword = () => { + transitionTo(Routes.passwordReset); + }; + + getSupportedBrowsersLinks() { + return SupportedDevices.SUPPORTED_BROWSERS_LINKS.map((browser, index) => { + return ( + + {browser.linkMobile && browser.linkDesktop ? ( + + {browser.name} + + ) : ( + {browser.name} + )} + {index <= SupportedDevices.SUPPORTED_BROWSERS_LINKS.length - 3 && , } + {index === SupportedDevices.SUPPORTED_BROWSERS_LINKS.length - 2 && {this.i18n("or")} } + {index === SupportedDevices.SUPPORTED_BROWSERS_LINKS.length - 1 && .} + + ); + }); + } + + render() { + return ( + + + {this.i18n("login.title")} + + + {!this.state.deviceSupported && ( +
+ + {this.i18n("Your browser is not fully supported! Some parts of web may not work properly.")} +
+ {this.i18n("We recommend using the latest version of ")} + {this.getSupportedBrowsersLinks()} +
+
+ )} + {this.state.showAlert && this.props.error && ( +
+ +
+ )} +
+ { + this.usernameField = input; + }} + label={this.i18n("login.username")} + value={this.state.username} + onChange={this.onChange} + labelWidth={4} + onKeyPress={this.onKeyPress} + inputWidth={8} + /> + +
+ +
+
+ +
+ +
+
+ ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(Login))); function mapStateToProps(state) { - return { - isLogging: state.auth.isLogging, - status: state.auth.status, - error: state.auth.error - }; + return { + isLogging: state.auth.isLogging, + status: state.auth.status, + error: state.auth.error, + }; } function mapDispatchToProps(dispatch) { - return { - login: bindActionCreators(login, dispatch), - } -} \ No newline at end of file + return { + login: bindActionCreators(login, dispatch), + }; +} diff --git a/src/components/login/Logout.jsx b/src/components/login/Logout.jsx index 18014313..d6ca81d2 100644 --- a/src/components/login/Logout.jsx +++ b/src/components/login/Logout.jsx @@ -1,24 +1,24 @@ -import React, {useContext} from "react"; -import {useDispatch} from "react-redux"; -import {logout} from "../../actions/AuthActions"; -import {transitionTo} from "../../utils/Routing"; +import React, { useContext } from "react"; +import { useDispatch } from "react-redux"; +import { logout } from "../../actions/AuthActions"; +import { transitionTo } from "../../utils/Routing"; import Routes from "../../constants/RoutesConstants"; -import {isUsingOidcAuth} from "../../utils/OidcUtils"; -import {AuthContext} from "../misc/oidc/OidcAuthWrapper"; +import { isUsingOidcAuth } from "../../utils/OidcUtils"; +import { AuthContext } from "../misc/oidc/OidcAuthWrapper"; const Logout = () => { - const dispatch = useDispatch(); - const authCtx = useContext(AuthContext); - React.useEffect(() => { - if (isUsingOidcAuth()) { - authCtx.logout(); - } - dispatch(logout()).then(() => { - transitionTo(Routes.login); - }); + const dispatch = useDispatch(); + const authCtx = useContext(AuthContext); + React.useEffect(() => { + if (isUsingOidcAuth()) { + authCtx.logout(); + } + dispatch(logout()).then(() => { + transitionTo(Routes.login); }); + }); - return null; -} + return null; +}; -export default Logout; \ No newline at end of file +export default Logout; diff --git a/src/components/login/PasswordReset.jsx b/src/components/login/PasswordReset.jsx index 3117f28f..ad5ad5d7 100644 --- a/src/components/login/PasswordReset.jsx +++ b/src/components/login/PasswordReset.jsx @@ -1,107 +1,128 @@ -'use strict'; +"use strict"; import React from "react"; -import {Button, Form, Card} from "react-bootstrap"; +import { Button, Form, Card } from "react-bootstrap"; import HorizontalInput from "../HorizontalInput"; import withI18n from "../../i18n/withI18n"; -import {injectIntl} from "react-intl"; -import {transitionTo} from "../../utils/Routing"; +import { injectIntl } from "react-intl"; +import { transitionTo } from "../../utils/Routing"; import Routes from "../../constants/RoutesConstants"; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; -import {passwordReset} from "../../actions/AuthActions"; -import {ACTION_STATUS, ALERT_TYPES} from "../../constants/DefaultConstants"; -import {LoaderSmall} from "../Loader"; +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; +import { passwordReset } from "../../actions/AuthActions"; +import { ACTION_STATUS, ALERT_TYPES } from "../../constants/DefaultConstants"; +import { LoaderSmall } from "../Loader"; import * as Utils from "../../utils/Utils"; import AlertMessage from "../AlertMessage"; class PasswordReset extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - email: '', - showAlert: false - } - } - - componentDidMount() { - this.emailField.focus(); - } - - onChange = (e) => { - let state = this.state; - state[e.target.name] = e.target.value; - this.setState(state); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + email: "", + showAlert: false, }; + } - onKeyPress = (e) => { - if (e.key === 'Enter') { - this.resetPassword(); - } - }; + componentDidMount() { + this.emailField.focus(); + } - resetPassword = () => { - this.setState({showAlert: true}); - this.props.passwordReset(this.state.email); - }; + onChange = (e) => { + let state = this.state; + state[e.target.name] = e.target.value; + this.setState(state); + }; - renderAlert() { - if (this.state.showAlert) { - switch (this.props.status) { - case ACTION_STATUS.SUCCESS: - return ; - case ACTION_STATUS.ERROR: - return ; - } - } - return null; + onKeyPress = (e) => { + if (e.key === "Enter") { + this.resetPassword(); } + }; - render() { - return ( - {this.i18n('login.forgot-your-password')} - -
- {this.renderAlert()} - { - this.emailField = input; - }} - label={this.i18n('login.email')} value={this.state.email} - onChange={this.onChange} onKeyPress={this.onKeyPress} - /> -
- - -
- -
-
- ) + resetPassword = () => { + this.setState({ showAlert: true }); + this.props.passwordReset(this.state.email); + }; + + renderAlert() { + if (this.state.showAlert) { + switch (this.props.status) { + case ACTION_STATUS.SUCCESS: + return ( + + ); + case ACTION_STATUS.ERROR: + return ( + + ); + } } + return null; + } + + render() { + return ( + + + {this.i18n("login.forgot-your-password")} + + +
+ {this.renderAlert()} + { + this.emailField = input; + }} + label={this.i18n("login.email")} + value={this.state.email} + onChange={this.onChange} + onKeyPress={this.onKeyPress} + /> +
+ + +
+ +
+
+ ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(PasswordReset))); function mapStateToProps(state) { - return { - status: state.auth.passwordResetStatus - }; + return { + status: state.auth.passwordResetStatus, + }; } function mapDispatchToProps(dispatch) { - return { - passwordReset: bindActionCreators(passwordReset, dispatch) - } -} \ No newline at end of file + return { + passwordReset: bindActionCreators(passwordReset, dispatch), + }; +} diff --git a/src/components/login/PasswordToken.jsx b/src/components/login/PasswordToken.jsx index 37701a08..fca62ca3 100644 --- a/src/components/login/PasswordToken.jsx +++ b/src/components/login/PasswordToken.jsx @@ -1,124 +1,159 @@ -'use strict'; +"use strict"; import React from "react"; -import {Alert, Button, Form, Card} from "react-bootstrap"; +import { Alert, Button, Form, Card } from "react-bootstrap"; import HorizontalInput from "../HorizontalInput"; import withI18n from "../../i18n/withI18n"; -import {injectIntl} from "react-intl"; -import {connect} from "react-redux"; -import {ACTION_STATUS, ALERT_TYPES} from "../../constants/DefaultConstants"; -import {LoaderSmall} from "../Loader"; -import {bindActionCreators} from "redux"; -import {changePasswordToken, validateToken} from "../../actions/AuthActions"; -import {transitionTo} from "../../utils/Routing"; +import { injectIntl } from "react-intl"; +import { connect } from "react-redux"; +import { ACTION_STATUS, ALERT_TYPES } from "../../constants/DefaultConstants"; +import { LoaderSmall } from "../Loader"; +import { bindActionCreators } from "redux"; +import { changePasswordToken, validateToken } from "../../actions/AuthActions"; +import { transitionTo } from "../../utils/Routing"; import Routes from "../../constants/RoutesConstants"; import AlertMessage from "../AlertMessage"; class PasswordReset extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - newPassword: '', - confirmPassword: '', - valid: true, - showAlert: false - } - } + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + newPassword: "", + confirmPassword: "", + valid: true, + showAlert: false, + }; + } - componentDidMount() { - this.props.validateToken(this.props.match.params.token); - } + componentDidMount() { + this.props.validateToken(this.props.match.params.token); + } - componentDidUpdate(prevProps, prevState, snapshot) { - if (this.props.validTokenStatus === ACTION_STATUS.ERROR) { - transitionTo(Routes.login); - } + componentDidUpdate(prevProps, prevState, snapshot) { + if (this.props.validTokenStatus === ACTION_STATUS.ERROR) { + transitionTo(Routes.login); } + } - onChange = (e) => { - let state = this.state; - state[e.target.name] = e.target.value; - this.setState(state); - }; + onChange = (e) => { + let state = this.state; + state[e.target.name] = e.target.value; + this.setState(state); + }; - onKeyPress = (e) => { - if (e.key === 'Enter') { - this.onSave(); - } - }; + onKeyPress = (e) => { + if (e.key === "Enter") { + this.onSave(); + } + }; - onSave = () => { - if (this._passwordValid()) { - this.setState({showAlert: true, newPassword: '', confirmPassword: ''}); - this.props.changePasswordToken(this.state.newPassword, this.props.match.params.token); - } - }; + onSave = () => { + if (this._passwordValid()) { + this.setState({ showAlert: true, newPassword: "", confirmPassword: "" }); + this.props.changePasswordToken(this.state.newPassword, this.props.match.params.token); + } + }; - _passwordValid() { - if (this.state.newPassword.length >= 4 - && this.state.newPassword === this.state.confirmPassword) { - this.setState({valid: true}); - return true; - } - this.setState({valid: false, showAlert: false}); - return false; + _passwordValid() { + if (this.state.newPassword.length >= 4 && this.state.newPassword === this.state.confirmPassword) { + this.setState({ valid: true }); + return true; } + this.setState({ valid: false, showAlert: false }); + return false; + } - render() { - const {validTokenStatus, passwordChange} = this.props; - if (!validTokenStatus || validTokenStatus === ACTION_STATUS.PENDING) { - return null; - } - return - {this.i18n('login.reset-password')} - -
- {!this.state.valid && - } - {this.state.showAlert && passwordChange.status === ACTION_STATUS.ERROR && - } - {this.state.showAlert && passwordChange.status === ACTION_STATUS.SUCCESS && - } - - -
- - -
- -
-
+ render() { + const { validTokenStatus, passwordChange } = this.props; + if (!validTokenStatus || validTokenStatus === ACTION_STATUS.PENDING) { + return null; } + return ( + + + {this.i18n("login.reset-password")} + + +
+ {!this.state.valid && ( + + )} + {this.state.showAlert && passwordChange.status === ACTION_STATUS.ERROR && ( + + )} + {this.state.showAlert && passwordChange.status === ACTION_STATUS.SUCCESS && ( + + )} + + +
+ + +
+ +
+
+ ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(PasswordReset))); function mapStateToProps(state) { - return { - validTokenStatus: state.auth.validTokenStatus, - passwordChange: state.auth.passwordChange - }; + return { + validTokenStatus: state.auth.validTokenStatus, + passwordChange: state.auth.passwordChange, + }; } function mapDispatchToProps(dispatch) { - return { - validateToken: bindActionCreators(validateToken, dispatch), - changePasswordToken: bindActionCreators(changePasswordToken, dispatch) - } -} \ No newline at end of file + return { + validateToken: bindActionCreators(validateToken, dispatch), + changePasswordToken: bindActionCreators(changePasswordToken, dispatch), + }; +} diff --git a/src/components/message/Message.jsx b/src/components/message/Message.jsx index 4a6083c2..79c8b334 100644 --- a/src/components/message/Message.jsx +++ b/src/components/message/Message.jsx @@ -1,31 +1,26 @@ import * as React from "react"; -import {Alert} from "react-bootstrap"; -import {useDispatch} from "react-redux"; -import {dismissMessage} from "../../actions/MessageActions"; -import {useI18n} from "../../hooks/useI18n"; -import {MESSAGE_DURATION} from "../../constants/DefaultConstants"; +import { Alert } from "react-bootstrap"; +import { useDispatch } from "react-redux"; +import { dismissMessage } from "../../actions/MessageActions"; +import { useI18n } from "../../hooks/useI18n"; +import { MESSAGE_DURATION } from "../../constants/DefaultConstants"; -export const Message = ({message}) => { - const {formatMessage} = useI18n(); - const dispatch = useDispatch(); - const dismiss = React.useCallback( - () => dispatch(dismissMessage(message)), - [message, dispatch] - ); - React.useEffect(() => { - const timer = setTimeout(() => { - dismiss(); - }, MESSAGE_DURATION); - return () => clearTimeout(timer); - }, [dismiss, message]); +export const Message = ({ message }) => { + const { formatMessage } = useI18n(); + const dispatch = useDispatch(); + const dismiss = React.useCallback(() => dispatch(dismissMessage(message)), [message, dispatch]); + React.useEffect(() => { + const timer = setTimeout(() => { + dismiss(); + }, MESSAGE_DURATION); + return () => clearTimeout(timer); + }, [dismiss, message]); - return ( - - {message.messageId - ? formatMessage(message.messageId, message.values) - : message.message} - - ); + return ( + + {message.messageId ? formatMessage(message.messageId, message.values) : message.message} + + ); }; export default Message; diff --git a/src/components/message/Messages.jsx b/src/components/message/Messages.jsx index 2f58a4f0..91e4f702 100644 --- a/src/components/message/Messages.jsx +++ b/src/components/message/Messages.jsx @@ -1,22 +1,19 @@ import * as React from "react"; -import {useSelector} from "react-redux"; +import { useSelector } from "react-redux"; import Message from "./Message"; -import {MESSAGE_DISPLAY_COUNT} from "../../constants/DefaultConstants"; +import { MESSAGE_DISPLAY_COUNT } from "../../constants/DefaultConstants"; export const Messages = () => { - const messages = useSelector((state) => state.messages); - const count = - messages.length < MESSAGE_DISPLAY_COUNT - ? messages.length - : MESSAGE_DISPLAY_COUNT; - const toRender = messages.slice(0, count); - return ( -
- {toRender.map((m) => ( - - ))} -
- ); + const messages = useSelector((state) => state.messages); + const count = messages.length < MESSAGE_DISPLAY_COUNT ? messages.length : MESSAGE_DISPLAY_COUNT; + const toRender = messages.slice(0, count); + return ( +
+ {toRender.map((m) => ( + + ))} +
+ ); }; export default Messages; diff --git a/src/components/misc/FilterIndicator.jsx b/src/components/misc/FilterIndicator.jsx index 26f1677f..058880eb 100644 --- a/src/components/misc/FilterIndicator.jsx +++ b/src/components/misc/FilterIndicator.jsx @@ -1,13 +1,13 @@ import React from "react"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; import classNames from "classnames"; -import {FaFilter} from "react-icons/fa"; -import {sanitizeArray} from "../../utils/Utils"; +import { FaFilter } from "react-icons/fa"; +import { sanitizeArray } from "../../utils/Utils"; -const FilterIndicator = ({filterValue}) => { - const {i18n} = useI18n(); - const classes = classNames("ml-1", {invisible: sanitizeArray(filterValue).length === 0}); - return ; -} +const FilterIndicator = ({ filterValue }) => { + const { i18n } = useI18n(); + const classes = classNames("ml-1", { invisible: sanitizeArray(filterValue).length === 0 }); + return ; +}; export default FilterIndicator; diff --git a/src/components/misc/Pagination.jsx b/src/components/misc/Pagination.jsx index b0c41c70..15b293d8 100644 --- a/src/components/misc/Pagination.jsx +++ b/src/components/misc/Pagination.jsx @@ -1,9 +1,9 @@ import React from "react"; import PropTypes from "prop-types"; -import {Pagination as BSPagination} from "react-bootstrap"; -import {DEFAULT_PAGE_SIZE, STORAGE_TABLE_PAGE_SIZE_KEY} from "../../constants/DefaultConstants"; +import { Pagination as BSPagination } from "react-bootstrap"; +import { DEFAULT_PAGE_SIZE, STORAGE_TABLE_PAGE_SIZE_KEY } from "../../constants/DefaultConstants"; import Input from "../Input"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; import BrowserStorage from "../../utils/BrowserStorage"; /** @@ -14,55 +14,63 @@ export const INITIAL_PAGE = 0; const PAGE_SIZES = [10, 20, 30, 50]; const INFINITE_PAGE_SIZE = Math.pow(2, 31) - 1; -const Pagination = ({pageNumber, handlePagination, itemCount, pageCount, allowSizeChange}) => { - const {i18n, formatMessage} = useI18n(); - const [pageSize, setPageSize] = React.useState(DEFAULT_PAGE_SIZE); - React.useEffect(() => { - const storedPageSize = BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY); - if (storedPageSize) { - setPageSize(Number(storedPageSize)); - } - }, [setPageSize]); - const onPageSizeSelect = (e) => { - const value = Number(e.currentTarget.value); - setPageSize(value); - BrowserStorage.set(STORAGE_TABLE_PAGE_SIZE_KEY, value); - handlePagination(INITIAL_PAGE); - }; +const Pagination = ({ pageNumber, handlePagination, itemCount, pageCount, allowSizeChange }) => { + const { i18n, formatMessage } = useI18n(); + const [pageSize, setPageSize] = React.useState(DEFAULT_PAGE_SIZE); + React.useEffect(() => { + const storedPageSize = BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY); + if (storedPageSize) { + setPageSize(Number(storedPageSize)); + } + }, [setPageSize]); + const onPageSizeSelect = (e) => { + const value = Number(e.currentTarget.value); + setPageSize(value); + BrowserStorage.set(STORAGE_TABLE_PAGE_SIZE_KEY, value); + handlePagination(INITIAL_PAGE); + }; - return <> + return ( + <> +
+ + handlePagination(INITIAL_PAGE)} /> + handlePagination(pageNumber - 1)} /> + {pageNumber + 1} + handlePagination(pageNumber + 1)} /> + {pageCount !== undefined && ( + handlePagination(pageCount)} /> + )} + +
+ {allowSizeChange && (
- - handlePagination(INITIAL_PAGE)}/> - handlePagination(pageNumber - 1)}/> - {pageNumber + 1} - handlePagination(pageNumber + 1)}/> - {pageCount !== undefined && - handlePagination(pageCount)}/>} - + + {PAGE_SIZES.map((ps) => ( + + ))} + +
- {allowSizeChange &&
- - {PAGE_SIZES.map(ps => )} - - -
} + )} -} + ); +}; Pagination.propTypes = { - pageNumber: PropTypes.number.isRequired, - handlePagination: PropTypes.func.isRequired, - itemCount: PropTypes.number.isRequired, - pageCount: PropTypes.number, - allowSizeChange: PropTypes.bool + pageNumber: PropTypes.number.isRequired, + handlePagination: PropTypes.func.isRequired, + itemCount: PropTypes.number.isRequired, + pageCount: PropTypes.number, + allowSizeChange: PropTypes.bool, }; Pagination.defaultProps = { - allowSizeChange: true -} + allowSizeChange: true, +}; export default Pagination; - diff --git a/src/components/misc/PromiseTrackingMask.jsx b/src/components/misc/PromiseTrackingMask.jsx index 0572b033..c7c8624b 100644 --- a/src/components/misc/PromiseTrackingMask.jsx +++ b/src/components/misc/PromiseTrackingMask.jsx @@ -1,24 +1,15 @@ import React from "react"; -import {usePromiseTracker} from "react-promise-tracker"; -import {ContainerLoaderMask, LoaderMask} from "../Loader"; +import { usePromiseTracker } from "react-promise-tracker"; +import { ContainerLoaderMask, LoaderMask } from "../Loader"; -const PromiseTrackingMask = ({area, coverViewport}) => { - const {promiseInProgress} = usePromiseTracker({area}); +const PromiseTrackingMask = ({ area, coverViewport }) => { + const { promiseInProgress } = usePromiseTracker({ area }); - return ( - <> - {promiseInProgress && - (area && !coverViewport ? ( - - ) : ( - - ))} - - ); + return <>{promiseInProgress && (area && !coverViewport ? : )}; }; PromiseTrackingMask.defaultProps = { - coverViewport: false, + coverViewport: false, }; export default PromiseTrackingMask; diff --git a/src/components/misc/SortIndicator.jsx b/src/components/misc/SortIndicator.jsx index 575f516d..455cdcda 100644 --- a/src/components/misc/SortIndicator.jsx +++ b/src/components/misc/SortIndicator.jsx @@ -1,30 +1,32 @@ import React from "react"; import PropTypes from "prop-types"; -import {SortDirection} from "../../constants/DefaultConstants"; -import {useI18n} from "../../hooks/useI18n"; -import {FaArrowDownShortWide, FaArrowDownUpAcrossLine, FaArrowDownWideShort} from "react-icons/fa6"; +import { SortDirection } from "../../constants/DefaultConstants"; +import { useI18n } from "../../hooks/useI18n"; +import { FaArrowDownShortWide, FaArrowDownUpAcrossLine, FaArrowDownWideShort } from "react-icons/fa6"; -const SortIndicator = ({direction}) => { - const {i18n} = useI18n(); - let Glyph; - switch (direction) { - case SortDirection.ASC: - Glyph = FaArrowDownShortWide; - break; - case SortDirection.DESC: - Glyph = FaArrowDownWideShort; - break; - default: - Glyph = FaArrowDownUpAcrossLine; - break; - } - return - - ; +const SortIndicator = ({ direction }) => { + const { i18n } = useI18n(); + let Glyph; + switch (direction) { + case SortDirection.ASC: + Glyph = FaArrowDownShortWide; + break; + case SortDirection.DESC: + Glyph = FaArrowDownWideShort; + break; + default: + Glyph = FaArrowDownUpAcrossLine; + break; + } + return ( + + + + ); }; SortIndicator.propTypes = { - direction: PropTypes.string + direction: PropTypes.string, }; export default SortIndicator; diff --git a/src/components/misc/hoc/RequireAuth.jsx b/src/components/misc/hoc/RequireAuth.jsx index d1491116..9952302f 100644 --- a/src/components/misc/hoc/RequireAuth.jsx +++ b/src/components/misc/hoc/RequireAuth.jsx @@ -1,34 +1,34 @@ -import React, {useEffect} from 'react'; -import {connect} from 'react-redux'; -import PropTypes from 'prop-types'; +import React, { useEffect } from "react"; +import { connect } from "react-redux"; +import PropTypes from "prop-types"; import * as Routing from "../../../utils/Routing"; import Routes from "../../../constants/RoutesConstants"; export default function (ComposedComponent) { - const Authentication = ({authenticated, history, location, match}) => { - useEffect(() => { - if (authenticated === false) { - Routing.transitionTo(Routes.login); - } - }, [authenticated]); + const Authentication = ({ authenticated, history, location, match }) => { + useEffect(() => { + if (authenticated === false) { + Routing.transitionTo(Routes.login); + } + }, [authenticated]); - if (!authenticated) { - return null; - } + if (!authenticated) { + return null; + } - return ; - }; + return ; + }; - Authentication.propTypes = { - authenticated: PropTypes.bool, - location: PropTypes.object.isRequired, - match: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, - }; + Authentication.propTypes = { + authenticated: PropTypes.bool, + location: PropTypes.object.isRequired, + match: PropTypes.object.isRequired, + history: PropTypes.object.isRequired, + }; - const mapStateToProps = state => ({ - authenticated: state.auth.authenticated, - }); + const mapStateToProps = (state) => ({ + authenticated: state.auth.authenticated, + }); - return connect(mapStateToProps)(Authentication); + return connect(mapStateToProps)(Authentication); } diff --git a/src/components/misc/oidc/IfInternalAuth.jsx b/src/components/misc/oidc/IfInternalAuth.jsx index 64c23bd8..2b6f46bb 100644 --- a/src/components/misc/oidc/IfInternalAuth.jsx +++ b/src/components/misc/oidc/IfInternalAuth.jsx @@ -1,5 +1,5 @@ import React from "react"; -import {isUsingOidcAuth} from "../../../utils/OidcUtils"; +import { isUsingOidcAuth } from "../../../utils/OidcUtils"; const IfInternalAuth = ({ children }) => { if (isUsingOidcAuth()) { diff --git a/src/components/misc/oidc/OidcAuthWrapper.jsx b/src/components/misc/oidc/OidcAuthWrapper.jsx index 8fe18353..4706219c 100644 --- a/src/components/misc/oidc/OidcAuthWrapper.jsx +++ b/src/components/misc/oidc/OidcAuthWrapper.jsx @@ -1,6 +1,6 @@ -import React, {useCallback, useEffect, useState,} from "react"; -import {generateRedirectUri, getUserManager} from "../../../utils/OidcUtils"; -import {getOidcToken} from "../../../utils/SecurityUtils"; +import React, { useCallback, useEffect, useState } from "react"; +import { generateRedirectUri, getUserManager } from "../../../utils/OidcUtils"; +import { getOidcToken } from "../../../utils/SecurityUtils"; // Taken from https://github.com/datagov-cz/assembly-line-shared but using a different config processing mechanism @@ -11,7 +11,7 @@ const useThrow = () => { setState(() => { throw error; }), - [setState] + [setState], ); }; @@ -20,31 +20,31 @@ const useThrow = () => { */ export const AuthContext = React.createContext(null); -const OidcAuthWrapper = ({ - children, - location = window.location, -}) => { +const OidcAuthWrapper = ({ children, location = window.location }) => { const userManager = getUserManager(); const throwError = useThrow(); const [user, setUser] = useState(null); useEffect(() => { - userManager.getUser().then(u => { - if (u && u.access_token && !u.expired) { - // User authenticated - // NOTE: the oidc-client-js library never returns null if the user is not authenticated - // Checking for existence of BOTH access_token and expired field seems OK - // Checking only for expired field is not enough - setUser(u); - } else { - // User not authenticated -> trigger auth flow - return userManager.signinRedirect({ - redirect_uri: generateRedirectUri(location.href), - }); - } - }).catch(error => { - throwError(error); - }) + userManager + .getUser() + .then((u) => { + if (u && u.access_token && !u.expired) { + // User authenticated + // NOTE: the oidc-client-js library never returns null if the user is not authenticated + // Checking for existence of BOTH access_token and expired field seems OK + // Checking only for expired field is not enough + setUser(u); + } else { + // User not authenticated -> trigger auth flow + return userManager.signinRedirect({ + redirect_uri: generateRedirectUri(location.href), + }); + } + }) + .catch((error) => { + throwError(error); + }); }, [location, throwError, setUser, userManager]); useEffect(() => { @@ -79,8 +79,7 @@ const OidcAuthWrapper = ({ userManager.events.addSilentRenewError(handleSilentRenewError); // Unsubscribe on component unmount - return () => - userManager.events.removeSilentRenewError(handleSilentRenewError); + return () => userManager.events.removeSilentRenewError(handleSilentRenewError); }, [location, throwError, setUser, userManager]); const logout = useCallback(() => { @@ -100,11 +99,7 @@ const OidcAuthWrapper = ({ return null; } - return ( - - {children} - - ); + return {children}; }; export default OidcAuthWrapper; diff --git a/src/components/pages/OidcSignInCallback.jsx b/src/components/pages/OidcSignInCallback.jsx index 595a0f9a..bd4ef016 100644 --- a/src/components/pages/OidcSignInCallback.jsx +++ b/src/components/pages/OidcSignInCallback.jsx @@ -1,23 +1,25 @@ import React from "react"; -import {getUserManager} from "../../utils/OidcUtils"; +import { getUserManager } from "../../utils/OidcUtils"; export default class AuthenticationCallback extends React.Component { - constructor(props) { - super(props); - } + constructor(props) { + super(props); + } - componentDidMount() { - getUserManager().signinRedirectCallback().then(() => { - const searchParams = new URLSearchParams(location.search); - if (!searchParams.has("forward_uri")) { - throw Error("Missing parameter forward_uri"); - } - const forwardUri = window.atob(searchParams.get("forward_uri")); - window.location.replace(forwardUri); - }); - } + componentDidMount() { + getUserManager() + .signinRedirectCallback() + .then(() => { + const searchParams = new URLSearchParams(location.search); + if (!searchParams.has("forward_uri")) { + throw Error("Missing parameter forward_uri"); + } + const forwardUri = window.atob(searchParams.get("forward_uri")); + window.location.replace(forwardUri); + }); + } - render() { - return

Redirecting...

; - } + render() { + return

Redirecting...

; + } } diff --git a/src/components/pages/OidcSilentCallback.jsx b/src/components/pages/OidcSilentCallback.jsx index 9b5d8a59..3ecf1fe2 100644 --- a/src/components/pages/OidcSilentCallback.jsx +++ b/src/components/pages/OidcSilentCallback.jsx @@ -1,16 +1,16 @@ import React from "react"; -import {getUserManager} from "../../utils/OidcUtils"; +import { getUserManager } from "../../utils/OidcUtils"; export default class AuthenticationSilentCallback extends React.Component { - constructor(props) { - super(props); - } + constructor(props) { + super(props); + } - componentDidMount() { - getUserManager().signinSilentCallback(); - } + componentDidMount() { + getUserManager().signinSilentCallback(); + } - render() { - return

; - } + render() { + return

; + } } diff --git a/src/components/record/ExportRecordsDropdown.jsx b/src/components/record/ExportRecordsDropdown.jsx index a6e988d9..25a5d56c 100644 --- a/src/components/record/ExportRecordsDropdown.jsx +++ b/src/components/record/ExportRecordsDropdown.jsx @@ -1,26 +1,33 @@ import React from "react"; import PropTypes from "prop-types"; -import {sanitizeArray} from "../../utils/Utils"; -import {Dropdown, DropdownButton} from "react-bootstrap"; -import {ExportType} from "../../constants/ExportType"; -import {useI18n} from "../../hooks/useI18n"; +import { sanitizeArray } from "../../utils/Utils"; +import { Dropdown, DropdownButton } from "react-bootstrap"; +import { ExportType } from "../../constants/ExportType"; +import { useI18n } from "../../hooks/useI18n"; -const ExportRecordsDropdown = ({records, onExport}) => { - const {i18n} = useI18n(); - if (sanitizeArray(records).length === 0) { - return null; - } - return - {/* Excel export is currently not supported by the backend +const ExportRecordsDropdown = ({ records, onExport }) => { + const { i18n } = useI18n(); + if (sanitizeArray(records).length === 0) { + return null; + } + return ( + + {/* Excel export is currently not supported by the backend onExport(ExportType.EXCEL)}>{i18n("records.export.excel")}*/} - onExport(ExportType.JSON)}>{i18n("records.export.json")} - ; -} + onExport(ExportType.JSON)}>{i18n("records.export.json")} + + ); +}; ExportRecordsDropdown.propTypes = { - records: PropTypes.array, - onExport: PropTypes.func.isRequired + records: PropTypes.array, + onExport: PropTypes.func.isRequired, }; export default ExportRecordsDropdown; diff --git a/src/components/record/ImportRecordsDialog.jsx b/src/components/record/ImportRecordsDialog.jsx index 96a9c65b..74e016f2 100644 --- a/src/components/record/ImportRecordsDialog.jsx +++ b/src/components/record/ImportRecordsDialog.jsx @@ -1,54 +1,56 @@ import React from "react"; -import {Form, Modal} from "react-bootstrap"; +import { Form, Modal } from "react-bootstrap"; import classNames from "classnames"; import Dropzone from "react-dropzone"; -import {FaUpload} from "react-icons/fa"; -import {useI18n} from "../../hooks/useI18n"; +import { FaUpload } from "react-icons/fa"; +import { useI18n } from "../../hooks/useI18n"; -const ImportRecordsDialog = ({onSubmit, onCancel, show}) => { - const {i18n} = useI18n(); - const [dragActive, setDragActive] = React.useState(false); - const onFileSelected = (files) => { - const file = files[0]; - setDragActive(false); - if (file) { - onSubmit(file); - } - }; +const ImportRecordsDialog = ({ onSubmit, onCancel, show }) => { + const { i18n } = useI18n(); + const [dragActive, setDragActive] = React.useState(false); + const onFileSelected = (files) => { + const file = files[0]; + setDragActive(false); + if (file) { + onSubmit(file); + } + }; - const containerClasses = classNames("file-upload-dropzone", { - active: dragActive, - }); + const containerClasses = classNames("file-upload-dropzone", { + active: dragActive, + }); - return - - {i18n("records.import.dialog.title")} - - - setDragActive(true)} - onDragLeave={() => setDragActive(false)} - multiple={false} - > - {({getRootProps, getInputProps}) => ( - <> -

- -
- - {i18n("records.import.dropzone.label")} - -
-
- -
-
- - )} - - - ; -} + return ( + + + {i18n("records.import.dialog.title")} + + + setDragActive(true)} + onDragLeave={() => setDragActive(false)} + multiple={false} + > + {({ getRootProps, getInputProps }) => ( + <> +
+ +
+ + {i18n("records.import.dropzone.label")} + +
+
+ +
+
+ + )} +
+
+
+ ); +}; export default ImportRecordsDialog; diff --git a/src/components/record/Record.jsx b/src/components/record/Record.jsx index 143ee60b..f2434177 100644 --- a/src/components/record/Record.jsx +++ b/src/components/record/Record.jsx @@ -1,187 +1,240 @@ import React from "react"; -import {Button} from "react-bootstrap"; +import { Button } from "react-bootstrap"; import PropTypes from "prop-types"; -import {FormattedMessage, injectIntl} from "react-intl"; +import { FormattedMessage, injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; import HorizontalInput from "../HorizontalInput"; import RecordForm from "./RecordForm"; import RecordProvenance from "./RecordProvenance"; import RequiredAttributes from "./RequiredAttributes"; -import {ACTION_STATUS, EXTENSION_CONSTANTS, RECORD_PHASE} from "../../constants/DefaultConstants"; -import {LoaderCard, LoaderSmall} from "../Loader"; -import {processTypeaheadOptions} from "./TypeaheadAnswer"; -import {EXTENSIONS} from "../../../config"; -import {isAdmin} from "../../utils/SecurityUtils"; +import { ACTION_STATUS, EXTENSION_CONSTANTS, RECORD_PHASE } from "../../constants/DefaultConstants"; +import { LoaderCard, LoaderSmall } from "../Loader"; +import { processTypeaheadOptions } from "./TypeaheadAnswer"; +import { EXTENSIONS } from "../../../config"; +import { isAdmin } from "../../utils/SecurityUtils"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; class Record extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.recordForm = React.createRef(); - this.state = { - isFormValid: false - } - } - - _onChange = (e) => { - const change = {}; - change[e.target.name] = e.target.value; - this.props.handlers.onChange(change); - }; - - getFormData = () => { - return this.recordForm.current.getFormData(); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.recordForm = React.createRef(); + this.state = { + isFormValid: false, }; + } - isFormValid = (isFormValid) => { - this.setState({isFormValid}) - } + _onChange = (e) => { + const change = {}; + change[e.target.name] = e.target.value; + this.props.handlers.onChange(change); + }; - render() { - const {record, formTemplate, currentUser} = this.props; - - if (!record?.formTemplate) { - if (formTemplate) { - record.formTemplate = formTemplate; - } - } - - if (!record) { - return ; - } - - return
- -
- - {this._showInstitution() && this._renderInstitution()} - - - {this._renderForm()} - {this._renderButtons()} -
; - } + getFormData = () => { + return this.recordForm.current.getFormData(); + }; - _renderHeader() { - const identifier = this.props.record && this.props.record.localName ? this.props.record.localName : ''; - const formTemplateName = this._getFormTemplateName(); - return { - (formTemplateName) - ? formTemplateName + ' ' + identifier - : - } - } + isFormValid = (isFormValid) => { + this.setState({ isFormValid }); + }; - _renderForm() { - const {record, loadFormgen, formgen} = this.props; - - return !record.state.isInitial() ? - - : null; - } + render() { + const { record, formTemplate, currentUser } = this.props; - _renderButtons() { - const {record, recordSaved, formgen} = this.props; - - return
- {EXTENSIONS === EXTENSION_CONSTANTS.SUPPLIER - && (!record.isNew) && (record.phase === RECORD_PHASE.OPEN || this._isAdmin()) - && } - - {(EXTENSIONS === EXTENSION_CONSTANTS.SUPPLIER || EXTENSIONS === EXTENSION_CONSTANTS.OPERATOR) - && (!record.isNew) && (record.phase === RECORD_PHASE.OPEN || this._isAdmin()) - && } - - - -
+ if (!record?.formTemplate) { + if (formTemplate) { + record.formTemplate = formTemplate; + } } - _renderInstitution() { - const record = this.props.record; - if (!record.institution) { - return null; - } - return
-
- -
-
; + if (!record) { + return ; } - _getFormTemplateName() { - const {formTemplatesLoaded, record, intl} = this.props; - const formTemplate = this.props.formTemplate || record?.formTemplate; - if (formTemplate) { - const formTemplateOptions = - formTemplatesLoaded.formTemplates - ? processTypeaheadOptions(formTemplatesLoaded.formTemplates, intl) - : []; - return formTemplateOptions.find(r => r.id === formTemplate)?.name; - } + return ( +
+ +
+ + {this._showInstitution() && this._renderInstitution()} + + + {this._renderForm()} + {this._renderButtons()} +
+ ); + } + + _renderHeader() { + const identifier = this.props.record && this.props.record.localName ? this.props.record.localName : ""; + const formTemplateName = this._getFormTemplateName(); + return ( + + {formTemplateName ? ( + formTemplateName + " " + identifier + ) : ( + + )} + + ); + } + + _renderForm() { + const { record, loadFormgen, formgen } = this.props; + + return !record.state.isInitial() ? ( + + ) : null; + } + + _renderButtons() { + const { record, recordSaved, formgen } = this.props; + + return ( +
+ {EXTENSIONS === EXTENSION_CONSTANTS.SUPPLIER && + !record.isNew && + (record.phase === RECORD_PHASE.OPEN || this._isAdmin()) && ( + + )} + + {(EXTENSIONS === EXTENSION_CONSTANTS.SUPPLIER || EXTENSIONS === EXTENSION_CONSTANTS.OPERATOR) && + !record.isNew && + (record.phase === RECORD_PHASE.OPEN || this._isAdmin()) && ( + + )} + + + +
+ ); + } + + _renderInstitution() { + const record = this.props.record; + if (!record.institution) { + return null; } - - _showInstitution() { - return this._isAdmin(); + return ( +
+
+ +
+
+ ); + } + + _getFormTemplateName() { + const { formTemplatesLoaded, record, intl } = this.props; + const formTemplate = this.props.formTemplate || record?.formTemplate; + if (formTemplate) { + const formTemplateOptions = formTemplatesLoaded.formTemplates + ? processTypeaheadOptions(formTemplatesLoaded.formTemplates, intl) + : []; + return formTemplateOptions.find((r) => r.id === formTemplate)?.name; } - - _getPanelTitle() { - if (!this._isAdmin() && this.props.formTemplate) { - const formTemplateName = this._getFormTemplateName(); - if (formTemplateName) { - return formTemplateName; - } - } - return this.i18n('record.panel-title'); + } + + _showInstitution() { + return this._isAdmin(); + } + + _getPanelTitle() { + if (!this._isAdmin() && this.props.formTemplate) { + const formTemplateName = this._getFormTemplateName(); + if (formTemplateName) { + return formTemplateName; + } } + return this.i18n("record.panel-title"); + } - _isAdmin() { - return isAdmin(this.props.currentUser); - } + _isAdmin() { + return isAdmin(this.props.currentUser); + } } Record.propTypes = { - record: PropTypes.object, - handlers: PropTypes.object.isRequired, - recordSaved: PropTypes.object, - recordLoaded: PropTypes.object, - formgen: PropTypes.object, - loadFormgen: PropTypes.func, - showAlert: PropTypes.bool, - formTemplatesLoaded: PropTypes.object.isRequired, - currentUser: PropTypes.object.isRequired, - formTemplate: PropTypes.string + record: PropTypes.object, + handlers: PropTypes.object.isRequired, + recordSaved: PropTypes.object, + recordLoaded: PropTypes.object, + formgen: PropTypes.object, + loadFormgen: PropTypes.func, + showAlert: PropTypes.bool, + formTemplatesLoaded: PropTypes.object.isRequired, + currentUser: PropTypes.object.isRequired, + formTemplate: PropTypes.string, }; -export default injectIntl(withI18n(Record, {forwardRef: true}), {forwardRef: true}); +export default injectIntl(withI18n(Record, { forwardRef: true }), { forwardRef: true }); diff --git a/src/components/record/RecordController.jsx b/src/components/record/RecordController.jsx index d34cd1d1..4852699f 100644 --- a/src/components/record/RecordController.jsx +++ b/src/components/record/RecordController.jsx @@ -1,224 +1,229 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {injectIntl} from "react-intl"; -import withI18n from '../../i18n/withI18n'; -import Record from './Record'; +import React from "react"; +import { injectIntl } from "react-intl"; +import withI18n from "../../i18n/withI18n"; +import Record from "./Record"; import Routes from "../../constants/RoutesConstants"; -import {transitionToWithOpts} from '../../utils/Routing'; -import {ACTION_FLAG, ACTION_STATUS, RECORD_PHASE} from "../../constants/DefaultConstants"; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; +import { transitionToWithOpts } from "../../utils/Routing"; +import { ACTION_FLAG, ACTION_STATUS, RECORD_PHASE } from "../../constants/DefaultConstants"; +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; import { - createRecord, - loadFormgen, - loadRecord, - unloadRecord, - unloadSavedRecord, - updateRecord + createRecord, + loadFormgen, + loadRecord, + unloadRecord, + unloadSavedRecord, + updateRecord, } from "../../actions/RecordActions"; import * as EntityFactory from "../../utils/EntityFactory"; import RecordValidator from "../../validation/RecordValidator"; import * as RecordState from "../../model/RecordState"; -import omit from 'lodash/omit'; -import {extractQueryParam} from "../../utils/Utils"; -import {withRouter} from "react-router-dom"; -import {EXTENSIONS} from "../../../config"; -import {trackPromise} from "react-promise-tracker"; +import omit from "lodash/omit"; +import { extractQueryParam } from "../../utils/Utils"; +import { withRouter } from "react-router-dom"; +import { EXTENSIONS } from "../../../config"; +import { trackPromise } from "react-promise-tracker"; class RecordController extends React.Component { - constructor(props) { - super(props); - this.state = { - record: this._isNew() ? EntityFactory.initNewPatientRecord() : null, - saved: false, - showAlert: false - }; - this.recordComponent = React.createRef(); - - } + constructor(props) { + super(props); + this.state = { + record: this._isNew() ? EntityFactory.initNewPatientRecord() : null, + saved: false, + showAlert: false, + }; + this.recordComponent = React.createRef(); + } - componentDidMount() { - const recordKey = this.props.match.params.key; + componentDidMount() { + const recordKey = this.props.match.params.key; - if (!this.state.record) { - this.props.loadRecord(recordKey); - } - if (this.props.recordSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY && this.props.recordSaved.status === ACTION_STATUS.SUCCESS) { - this.setState({showAlert: true}); - this.props.unloadSavedRecord(); - } + if (!this.state.record) { + this.props.loadRecord(recordKey); } - - componentDidUpdate(prevProps, prevState, snapshot) { - const {recordLoaded, recordSaved} = this.props; - - if (prevProps.recordSaved.status === ACTION_STATUS.PENDING - && recordSaved.status === ACTION_STATUS.SUCCESS) - { // just saved - - if (recordSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY) - { // first time saved - this.props.transitionToWithOpts(Routes.editRecord, { - params: {key: recordSaved.record.key}, - handlers: { - onCancel: Routes.records - } - }); - this.props.loadRecord(recordSaved.record.key); - } else - { // at least second time saved - this.props.loadRecord(this.state.record.key); - } - } else if (prevProps.recordLoaded.status === ACTION_STATUS.PENDING - && recordLoaded.status === ACTION_STATUS.SUCCESS) - { // just loaded - - const record = recordLoaded.record; - record.state = RecordState.createRecordState(); - this.setState({record: record}); - } + if ( + this.props.recordSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY && + this.props.recordSaved.status === ACTION_STATUS.SUCCESS + ) { + this.setState({ showAlert: true }); + this.props.unloadSavedRecord(); } - - componentWillUnmount() { - this.props.unloadRecord(); + } + + componentDidUpdate(prevProps, prevState, snapshot) { + const { recordLoaded, recordSaved } = this.props; + + if (prevProps.recordSaved.status === ACTION_STATUS.PENDING && recordSaved.status === ACTION_STATUS.SUCCESS) { + // just saved + + if (recordSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY) { + // first time saved + this.props.transitionToWithOpts(Routes.editRecord, { + params: { key: recordSaved.record.key }, + handlers: { + onCancel: Routes.records, + }, + }); + this.props.loadRecord(recordSaved.record.key); + } else { + // at least second time saved + this.props.loadRecord(this.state.record.key); + } + } else if ( + prevProps.recordLoaded.status === ACTION_STATUS.PENDING && + recordLoaded.status === ACTION_STATUS.SUCCESS + ) { + // just loaded + + const record = recordLoaded.record; + record.state = RecordState.createRecordState(); + this.setState({ record: record }); } - - _isNew() { - return !this.props.match.params.key; + } + + componentWillUnmount() { + this.props.unloadRecord(); + } + + _isNew() { + return !this.props.match.params.key; + } + + _onSave = () => { + const currentUser = this.props.currentUser; + const record = this.state.record; + this.setState({ saved: true, showAlert: true }); + + record.question = this.recordComponent.current.getFormData(); + record.localName = record.localName ? record.localName : this._getLocalName(); + if (record.isNew) { + trackPromise(this.props.createRecord(omit(record, "isNew"), currentUser), "record"); + } else { + trackPromise(this.props.updateRecord(record, currentUser), "record"); } + }; - _onSave = () => { - const currentUser = this.props.currentUser; - const record = this.state.record; - this.setState({saved: true, showAlert: true}); - - record.question = this.recordComponent.current.getFormData(); - record.localName = record.localName ? record.localName : this._getLocalName(); - if (record.isNew) { - trackPromise(this.props.createRecord(omit(record, 'isNew'), currentUser), "record"); - } else { - trackPromise(this.props.updateRecord(record, currentUser), "record"); - } - }; - - _onCancel = () => { - this._transitionToRecords(); - }; + _onCancel = () => { + this._transitionToRecords(); + }; - _transitionToRecords() { - const opts = {}; - const formTemplate = this.state.record?.formTemplate - if (formTemplate) { - opts.query = new Map([["formTemplate", formTemplate]]); - } - this.props.transitionToWithOpts(Routes.records, opts); + _transitionToRecords() { + const opts = {}; + const formTemplate = this.state.record?.formTemplate; + if (formTemplate) { + opts.query = new Map([["formTemplate", formTemplate]]); } + this.props.transitionToWithOpts(Routes.records, opts); + } + + _onChange = (change) => { + const update = { ...this.state.record, ...change }; + if (RecordValidator.isComplete(update)) { + update.state.recordComplete(); + } else { + update.state.recordIncomplete(); + } + this.setState({ record: update }); + }; - _onChange = (change) => { - const update = {...this.state.record, ...change}; - if (RecordValidator.isComplete(update)) { - update.state.recordComplete(); - } else { - update.state.recordIncomplete(); - } - this.setState({record: update}); - }; - - _onComplete = () => { - this._handlePhaseChange(RECORD_PHASE.COMPLETED); - this._transitionToRecords(); - }; - - _onReject = () => { - this._handlePhaseChange(RECORD_PHASE.REJECTED); - this._transitionToRecords(); - }; + _onComplete = () => { + this._handlePhaseChange(RECORD_PHASE.COMPLETED); + this._transitionToRecords(); + }; - _handlePhaseChange = (newPhase) => { - const currentUser = this.props.currentUser; - const update = {...this.state.record, phase: newPhase}; + _onReject = () => { + this._handlePhaseChange(RECORD_PHASE.REJECTED); + this._transitionToRecords(); + }; - this.setState({ record: update }); + _handlePhaseChange = (newPhase) => { + const currentUser = this.props.currentUser; + const update = { ...this.state.record, phase: newPhase }; - this.props.updateRecord(update, currentUser); - }; + this.setState({ record: update }); - _getLocalName() { - if (EXTENSIONS.split(",").includes("kodi")) { // return name of the record based on answer of specific question - return this._getKodiLocaLName(); - } - return "record-" + Date.now(); - } + this.props.updateRecord(update, currentUser); + }; - _getKodiLocaLName() { - return this.state.record?.question?.subQuestions?.[0] - ?.subQuestions?.find(q => q.origin.includes("věci/pojem/název")) - ?.subQuestions?.find(q => q.origin.includes("language-czech")) - ?.answers?.[0]?.textValue + _getLocalName() { + if (EXTENSIONS.split(",").includes("kodi")) { + // return name of the record based on answer of specific question + return this._getKodiLocaLName(); } - - _getKodiMainEntityName() { - const entityName = this.state.record?.question - ?.subQuestions?.[0]?.origin - .replace(/^.*pojem./, "").replace(/-[^-]*-q-qo/, "").replace("-", " "); - - return entityName.charAt(0).toUpperCase() + entityName.slice(1); + return "record-" + Date.now(); + } + + _getKodiLocaLName() { + return this.state.record?.question?.subQuestions?.[0]?.subQuestions + ?.find((q) => q.origin.includes("věci/pojem/název")) + ?.subQuestions?.find((q) => q.origin.includes("language-czech"))?.answers?.[0]?.textValue; + } + + _getKodiMainEntityName() { + const entityName = this.state.record?.question?.subQuestions?.[0]?.origin + .replace(/^.*pojem./, "") + .replace(/-[^-]*-q-qo/, "") + .replace("-", " "); + + return entityName.charAt(0).toUpperCase() + entityName.slice(1); + } + + render() { + const { recordLoaded, recordSaved, currentUser, formgen, loadFormgen, formTemplatesLoaded } = this.props; + const formTemplate = extractQueryParam(this.props.location.search, "formTemplate"); + if (!currentUser) { + return null; } + const handlers = { + onSave: this._onSave, + onCancel: this._onCancel, + onChange: this._onChange, + onComplete: this._onComplete, + onReject: this._onReject, + }; - - render() { - const {recordLoaded, recordSaved, currentUser, formgen, loadFormgen, formTemplatesLoaded} = this.props; - const formTemplate = extractQueryParam(this.props.location.search, "formTemplate"); - if (!currentUser) { - return null; - } - const handlers = { - onSave: this._onSave, - onCancel: this._onCancel, - onChange: this._onChange, - onComplete: this._onComplete, - onReject: this._onReject - }; - - return ; - } + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(withRouter(RecordController)))); function mapStateToProps(state) { - return { - status: state.auth.status, - currentUser: state.auth.user, - recordLoaded: state.record.recordLoaded, - recordSaved: state.record.recordSaved, - viewHandlers: state.router.viewHandlers, - formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, - formgen: state.record.formgen - }; + return { + status: state.auth.status, + currentUser: state.auth.user, + recordLoaded: state.record.recordLoaded, + recordSaved: state.record.recordSaved, + viewHandlers: state.router.viewHandlers, + formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, + formgen: state.record.formgen, + }; } function mapDispatchToProps(dispatch) { - return { - loadRecord: bindActionCreators(loadRecord, dispatch), - unloadRecord: bindActionCreators(unloadRecord, dispatch), - createRecord: bindActionCreators(createRecord, dispatch), - updateRecord: bindActionCreators(updateRecord, dispatch), - unloadSavedRecord: bindActionCreators(unloadSavedRecord, dispatch), - loadFormgen: bindActionCreators(loadFormgen, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch) - } + return { + loadRecord: bindActionCreators(loadRecord, dispatch), + unloadRecord: bindActionCreators(unloadRecord, dispatch), + createRecord: bindActionCreators(createRecord, dispatch), + updateRecord: bindActionCreators(updateRecord, dispatch), + unloadSavedRecord: bindActionCreators(unloadSavedRecord, dispatch), + loadFormgen: bindActionCreators(loadFormgen, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + }; } diff --git a/src/components/record/RecordForm.jsx b/src/components/record/RecordForm.jsx index 1342f552..089e0917 100644 --- a/src/components/record/RecordForm.jsx +++ b/src/components/record/RecordForm.jsx @@ -1,133 +1,133 @@ -'use strict'; +"use strict"; -import React from 'react'; -import SForms, {Constants} from '@kbss-cvut/s-forms'; +import React from "react"; +import SForms, { Constants } from "@kbss-cvut/s-forms"; import PropTypes from "prop-types"; -import {injectIntl} from "react-intl"; -import withI18n from '../../i18n/withI18n'; +import { injectIntl } from "react-intl"; +import withI18n from "../../i18n/withI18n"; import Loader from "../Loader"; -import {axiosBackend} from "../../actions"; -import {API_URL} from "../../../config"; +import { axiosBackend } from "../../actions"; +import { API_URL } from "../../../config"; import * as Logger from "../../utils/Logger"; import * as I18nStore from "../../stores/I18nStore"; // TODO enable s-forms-components // import SmartComponents from "s-forms-components"; -import 'react-datepicker/dist/react-datepicker.css'; +import "react-datepicker/dist/react-datepicker.css"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; -import {trackPromise} from "react-promise-tracker"; +import { trackPromise } from "react-promise-tracker"; // import "intelligent-tree-select/lib/styles.css" // const componentMapping = SmartComponents.getComponentMapping(); class RecordForm extends React.Component { - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - form: null - } - this.refForm = React.createRef(); - } - - componentDidMount() { - if (this.props.record.formTemplate) { - this.loadWizard(); - } - } - - componentDidUpdate(prevProps, prevState, snapshot) { - const {record} = this.props; - if (record.formTemplate && record.formTemplate !== prevProps.record.formTemplate) { - this.loadWizard(); - } - } - - loadWizard() { - trackPromise(this.props.loadFormgen(this.props.record), "sform") - .then(data => this.setState({form: data})).catch(() => Logger.error('Received no valid wizard.')); - } - - getFormData = () => { - return this.refForm.current.getFormData(); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + form: null, }; + this.refForm = React.createRef(); + } - fetchTypeAheadValues = async (query) => { - const FORM_GEN_POSSIBLE_VALUES_URL = `${API_URL}/rest/formGen/possibleValues`; - - const result = await axiosBackend.get(`${FORM_GEN_POSSIBLE_VALUES_URL}?query=${encodeURIComponent(query)}`); - return result.data; + componentDidMount() { + if (this.props.record.formTemplate) { + this.loadWizard(); } + } - _getUsersOptions() { - const currentUser = this.props.currentUser; - return { - users: [ - {id: currentUser.uri, label: currentUser.firstName + " " + currentUser.lastName} - ], - currentUser: currentUser.uri - }; + componentDidUpdate(prevProps, prevState, snapshot) { + const { record } = this.props; + if (record.formTemplate && record.formTemplate !== prevProps.record.formTemplate) { + this.loadWizard(); } - - _isDevGroupUser() { - return this.props.currentUser.emailAddress.includes("devgroup"); - } - - _getIconsOptions() { - if (this._isDevGroupUser()) { - return { - icons: [ - {id: Constants.ICONS.QUESTION_HELP, behavior: Constants.ICON_BEHAVIOR.ON_HOVER}, - {id: Constants.ICONS.QUESTION_LINK, behavior: Constants.ICON_BEHAVIOR.ON_HOVER}, - {id: Constants.ICONS.QUESTION_COMMENTS, behavior: Constants.ICON_BEHAVIOR.ON_HOVER} - ] - }; - } - - return { - icons: [ - {id: Constants.ICONS.QUESTION_HELP, behavior: Constants.ICON_BEHAVIOR.ON_HOVER} - ] - }; + } + + loadWizard() { + trackPromise(this.props.loadFormgen(this.props.record), "sform") + .then((data) => this.setState({ form: data })) + .catch(() => Logger.error("Received no valid wizard.")); + } + + getFormData = () => { + return this.refForm.current.getFormData(); + }; + + fetchTypeAheadValues = async (query) => { + const FORM_GEN_POSSIBLE_VALUES_URL = `${API_URL}/rest/formGen/possibleValues`; + + const result = await axiosBackend.get(`${FORM_GEN_POSSIBLE_VALUES_URL}?query=${encodeURIComponent(query)}`); + return result.data; + }; + + _getUsersOptions() { + const currentUser = this.props.currentUser; + return { + users: [{ id: currentUser.uri, label: currentUser.firstName + " " + currentUser.lastName }], + currentUser: currentUser.uri, + }; + } + + _isDevGroupUser() { + return this.props.currentUser.emailAddress.includes("devgroup"); + } + + _getIconsOptions() { + if (this._isDevGroupUser()) { + return { + icons: [ + { id: Constants.ICONS.QUESTION_HELP, behavior: Constants.ICON_BEHAVIOR.ON_HOVER }, + { id: Constants.ICONS.QUESTION_LINK, behavior: Constants.ICON_BEHAVIOR.ON_HOVER }, + { id: Constants.ICONS.QUESTION_COMMENTS, behavior: Constants.ICON_BEHAVIOR.ON_HOVER }, + ], + }; } + return { + icons: [{ id: Constants.ICONS.QUESTION_HELP, behavior: Constants.ICON_BEHAVIOR.ON_HOVER }], + }; + } + + render() { + const i18n = { + "wizard.next": this.i18n("wizard.next"), + "wizard.previous": this.i18n("wizard.previous"), + "section.expand": this.i18n("section.expand"), + "section.collapse": this.i18n("section.collapse"), + }; + const options = { + i18n, + intl: I18nStore.getIntl(), + ...this._getUsersOptions(), + ...this._getIconsOptions(), + }; - render() { - const i18n = { - 'wizard.next': this.i18n('wizard.next'), - 'wizard.previous': this.i18n('wizard.previous'), - "section.expand": this.i18n('section.expand'), - "section.collapse": this.i18n('section.collapse'), - } - const options = { - i18n, - intl: I18nStore.getIntl(), - ...this._getUsersOptions(), - ...this._getIconsOptions() - } - - return <> - - {!!this.state.form && } - />} - ; - } + return ( + <> + + {!!this.state.form && ( + } + /> + )} + + ); + } } RecordForm.propTypes = { - record: PropTypes.object.isRequired, - currentUser: PropTypes.object.isRequired, - loadFormgen: PropTypes.func, - formgen: PropTypes.object, - isFormValid: PropTypes.func + record: PropTypes.object.isRequired, + currentUser: PropTypes.object.isRequired, + loadFormgen: PropTypes.func, + formgen: PropTypes.object, + isFormValid: PropTypes.func, }; -export default injectIntl(withI18n(RecordForm, {forwardRef: true}), {forwardRef: true}); +export default injectIntl(withI18n(RecordForm, { forwardRef: true }), { forwardRef: true }); diff --git a/src/components/record/RecordProvenance.jsx b/src/components/record/RecordProvenance.jsx index c0248450..87e79443 100644 --- a/src/components/record/RecordProvenance.jsx +++ b/src/components/record/RecordProvenance.jsx @@ -1,36 +1,39 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {FormattedMessage} from 'react-intl'; -import {formatDate} from "../../utils/Utils"; +import React from "react"; +import { FormattedMessage } from "react-intl"; +import { formatDate } from "../../utils/Utils"; import PropTypes from "prop-types"; const RecordProvenance = (props) => { - const record = props.record; - if (record.isNew) { - return null; - } - const author = record.author ? record.author.firstName + ' ' + record.author.lastName : '', - created = formatDate(new Date(record.dateCreated)); - if (!record.lastModified) { - return
- {author}}}/> -
; - } - const lastEditor = record.lastModifiedBy ? record.lastModifiedBy.firstName + ' ' + record.lastModifiedBy.lastName : '', - lastModified = formatDate(new Date(record.lastModified)); - return
- {author}}}/> -
- {lastEditor}}}/> -
; + const record = props.record; + if (record.isNew) { + return null; + } + const author = record.author ? record.author.firstName + " " + record.author.lastName : "", + created = formatDate(new Date(record.dateCreated)); + if (!record.lastModified) { + return ( +
+ {author} }} /> +
+ ); + } + const lastEditor = record.lastModifiedBy + ? record.lastModifiedBy.firstName + " " + record.lastModifiedBy.lastName + : "", + lastModified = formatDate(new Date(record.lastModified)); + return ( +
+ {author} }} /> +
+ {lastEditor} }} /> +
+ ); }; RecordProvenance.propTypes = { - record: PropTypes.object + record: PropTypes.object, }; export default RecordProvenance; diff --git a/src/components/record/RecordRow.jsx b/src/components/record/RecordRow.jsx index 97552548..45e8d2d7 100644 --- a/src/components/record/RecordRow.jsx +++ b/src/components/record/RecordRow.jsx @@ -1,89 +1,96 @@ import React from "react"; -import {formatDate} from "../../utils/Utils"; +import { formatDate } from "../../utils/Utils"; import HelpIcon from "../HelpIcon"; -import {Button} from "react-bootstrap"; -import {LoaderSmall} from "../Loader"; +import { Button } from "react-bootstrap"; +import { LoaderSmall } from "../Loader"; import PropTypes from "prop-types"; -import {RECORD_PHASE, ROLE} from "../../constants/DefaultConstants"; -import {useI18n} from "../../hooks/useI18n"; -import {IfGranted} from "react-authorization"; +import { RECORD_PHASE, ROLE } from "../../constants/DefaultConstants"; +import { useI18n } from "../../hooks/useI18n"; +import { IfGranted } from "react-authorization"; const StatusInfo = {}; StatusInfo[RECORD_PHASE.OPEN] = { - glyph: 'to-do', - tooltip: 'records.completion-status-tooltip.incomplete' + glyph: "to-do", + tooltip: "records.completion-status-tooltip.incomplete", }; StatusInfo[RECORD_PHASE.COMPLETED] = { - glyph: 'ok', - tooltip: 'records.completion-status-tooltip.complete' + glyph: "ok", + tooltip: "records.completion-status-tooltip.complete", }; StatusInfo[RECORD_PHASE.PUBLISHED] = { - glyph: 'envelope', - tooltip: 'records.completion-status-tooltip.published' + glyph: "envelope", + tooltip: "records.completion-status-tooltip.published", }; StatusInfo[RECORD_PHASE.REJECTED] = { - glyph: 'remove', - tooltip: 'records.completion-status-tooltip.rejected' + glyph: "remove", + tooltip: "records.completion-status-tooltip.rejected", }; let RecordRow = (props) => { - const {i18n} = useI18n(); - const record = props.record, - formTemplateOptions = props.formTemplateOptions, - deleteButton = props.disableDelete ? null : - ; - const statusInfo = StatusInfo[record.phase]; + const { i18n } = useI18n(); + const record = props.record, + formTemplateOptions = props.formTemplateOptions, + deleteButton = props.disableDelete ? null : ( + + ); + const statusInfo = StatusInfo[record.phase]; - return - - - - - - - + return ( + + + + - - {record.institution.name} - - {getFormTemplateOptionName(record.formTemplate, formTemplateOptions)} - - - - {formatDate(new Date(record.lastModified ? record.lastModified : record.dateCreated))} - - - {statusInfo ? : "N/A"} + + + + + + {record.institution.name} + + {getFormTemplateOptionName(record.formTemplate, formTemplateOptions)} + + + {formatDate(new Date(record.lastModified ? record.lastModified : record.dateCreated))} + + + {statusInfo ? : "N/A"} + - - - {deleteButton} - + + + {deleteButton} + + ); }; const getFormTemplateOptionName = (formTemplate, formTemplatesOptions) => { - if (!formTemplate) { - return ""; - } - const label = formTemplatesOptions.find(e => e.id === formTemplate)?.name; - return label ? label : formTemplate; -} + if (!formTemplate) { + return ""; + } + const label = formTemplatesOptions.find((e) => e.id === formTemplate)?.name; + return label ? label : formTemplate; +}; RecordRow.propTypes = { - record: PropTypes.object.isRequired, - formTemplateOptions: PropTypes.array.isRequired, - onEdit: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, - disableDelete: PropTypes.bool.isRequired, - deletionLoading: PropTypes.bool.isRequired, - currentUser: PropTypes.object.isRequired + record: PropTypes.object.isRequired, + formTemplateOptions: PropTypes.array.isRequired, + onEdit: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, + disableDelete: PropTypes.bool.isRequired, + deletionLoading: PropTypes.bool.isRequired, + currentUser: PropTypes.object.isRequired, }; export default RecordRow; diff --git a/src/components/record/RecordTable.jsx b/src/components/record/RecordTable.jsx index cc77d6dc..a435cfd8 100644 --- a/src/components/record/RecordTable.jsx +++ b/src/components/record/RecordTable.jsx @@ -1,172 +1,218 @@ import React from "react"; -import {OverlayTrigger, Popover, Table} from "react-bootstrap"; +import { OverlayTrigger, Popover, Table } from "react-bootstrap"; import DeleteItemDialog from "../DeleteItemDialog"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; import RecordRow from "./RecordRow"; import PropTypes from "prop-types"; -import {processTypeaheadOptions} from "./TypeaheadAnswer"; -import {IfGranted} from "react-authorization"; -import {ROLE} from "../../constants/DefaultConstants"; +import { processTypeaheadOptions } from "./TypeaheadAnswer"; +import { IfGranted } from "react-authorization"; +import { ROLE } from "../../constants/DefaultConstants"; import DateIntervalFilter from "./filter/DateIntervalFilter"; import PhaseFilter from "./filter/PhaseFilter"; import InstitutionFilter from "./filter/InstitutionFilter"; import SortIndicator from "../misc/SortIndicator"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; import FilterIndicator from "../misc/FilterIndicator"; -import {sanitizeArray} from "../../utils/Utils"; +import { sanitizeArray } from "../../utils/Utils"; class RecordTable extends React.Component { - static propTypes = { - recordsLoaded: PropTypes.object.isRequired, - formTemplate: PropTypes.string, - formTemplatesLoaded: PropTypes.object.isRequired, - handlers: PropTypes.object.isRequired, - recordDeleted: PropTypes.object, - disableDelete: PropTypes.bool, - recordsDeleting: PropTypes.array, - currentUser: PropTypes.object.isRequired, - filterAndSort: PropTypes.object.isRequired + static propTypes = { + recordsLoaded: PropTypes.object.isRequired, + formTemplate: PropTypes.string, + formTemplatesLoaded: PropTypes.object.isRequired, + handlers: PropTypes.object.isRequired, + recordDeleted: PropTypes.object, + disableDelete: PropTypes.bool, + recordsDeleting: PropTypes.array, + currentUser: PropTypes.object.isRequired, + filterAndSort: PropTypes.object.isRequired, + }; + + static defaultProps = { + disableDelete: false, + }; + + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + showDialog: false, }; - - static defaultProps = { - disableDelete: false - }; - - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - showDialog: false, - }; - } - - _onDelete = (record) => { - this.setState({selectedRecord: record}); - }; - - _onCancelDelete = () => { - this.setState({selectedRecord: null}); - }; - - _onSubmitDelete = () => { - this.props.handlers.onDelete(this.state.selectedRecord); - this.setState({selectedRecord: null}); - }; - - render() { - const filteredRecords = this._getFormTemplateRecords(); - return
- - - {this._renderHeader()} - - {this._renderRows(filteredRecords)} - -
-
; - } - - _getDeleteLabel() { - return this.state.selectedRecord ? this.state.selectedRecord.localName : ''; - } - - _renderHeader() { - const {filters, sort, onChange} = this.props.filterAndSort; - return + } + + _onDelete = (record) => { + this.setState({ selectedRecord: record }); + }; + + _onCancelDelete = () => { + this.setState({ selectedRecord: null }); + }; + + _onSubmitDelete = () => { + this.props.handlers.onDelete(this.state.selectedRecord); + this.setState({ selectedRecord: null }); + }; + + render() { + const filteredRecords = this._getFormTemplateRecords(); + return ( +
+ + + {this._renderHeader()} + {this._renderRows(filteredRecords)} +
+
+ ); + } + + _getDeleteLabel() { + return this.state.selectedRecord ? this.state.selectedRecord.localName : ""; + } + + _renderHeader() { + const { filters, sort, onChange } = this.props.filterAndSort; + return ( + - - {this.i18n('records.id')} - - {this.i18n('records.local-name')} - - - {this.i18n('records.form-template')} - - - - {this.i18n('actions')} + + {this.i18n("records.id")} + + {this.i18n("records.local-name")} + + + {this.i18n("records.form-template")} + + + + {this.i18n("actions")} - + + ); + } + + _renderRows(filteredRecords) { + const { formTemplatesLoaded, handlers, recordsDeleting, intl } = this.props; + const formTemplateOptions = formTemplatesLoaded.formTemplates + ? processTypeaheadOptions(formTemplatesLoaded.formTemplates, intl) + : []; + let rows = []; + for (let i = 0, len = filteredRecords.length; i < len; i++) { + rows.push( + , + ); } + return rows; + } - _renderRows(filteredRecords) { - const {formTemplatesLoaded, handlers, recordsDeleting, intl} = this.props; - const formTemplateOptions = - formTemplatesLoaded.formTemplates ? processTypeaheadOptions(formTemplatesLoaded.formTemplates, intl) : []; - let rows = []; - for (let i = 0, len = filteredRecords.length; i < len; i++) { - rows.push(); - } - return rows; - } - - _getFormTemplateRecords() { - const records = sanitizeArray(this.props.recordsLoaded.records), - formTemplate = this.props.formTemplate; + _getFormTemplateRecords() { + const records = sanitizeArray(this.props.recordsLoaded.records), + formTemplate = this.props.formTemplate; - if (!formTemplate) { - return records; - } - return records.filter((r) => (r.formTemplate === formTemplate)) + if (!formTemplate) { + return records; } + return records.filter((r) => r.formTemplate === formTemplate); + } } -const FilterableInstitutionHeader = ({filters, onFilterChange}) => { - const {i18n} = useI18n(); - return - - - - }> - - {i18n('institution.panel-title')} - - - ; +const FilterableInstitutionHeader = ({ filters, onFilterChange }) => { + const { i18n } = useI18n(); + return ( + + + + + + } + > + + {i18n("institution.panel-title")} + + + + ); }; -const FilterableLastModifiedHeader = ({filters, sort, onFilterAndSortChange}) => { - const {i18n} = useI18n(); - return - - - - }> - - {i18n('records.last-modified')} - - - - ; +const FilterableLastModifiedHeader = ({ filters, sort, onFilterAndSortChange }) => { + const { i18n } = useI18n(); + return ( + + + + + + } + > + + {i18n("records.last-modified")} + + + + + ); }; -const FilterablePhaseHeader = ({filters, onFilterChange}) => { - const {i18n} = useI18n(); - return - - - - }> - - {i18n('records.completion-status')} - - - ; -} +const FilterablePhaseHeader = ({ filters, onFilterChange }) => { + const { i18n } = useI18n(); + return ( + + + + + + } + > + + {i18n("records.completion-status")} + + + + ); +}; export default injectIntl(withI18n(RecordTable)); diff --git a/src/components/record/Records.jsx b/src/components/record/Records.jsx index 05a76653..f94830c6 100644 --- a/src/components/record/Records.jsx +++ b/src/components/record/Records.jsx @@ -1,16 +1,16 @@ import React from "react"; -import {Button, Card} from "react-bootstrap"; -import {injectIntl} from "react-intl"; +import { Button, Card } from "react-bootstrap"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; -import {EXTENSION_CONSTANTS} from "../../constants/DefaultConstants"; +import { EXTENSION_CONSTANTS } from "../../constants/DefaultConstants"; import PropTypes from "prop-types"; -import {processTypeaheadOptions} from "./TypeaheadAnswer"; -import {EXTENSIONS} from "../../../config"; +import { processTypeaheadOptions } from "./TypeaheadAnswer"; +import { EXTENSIONS } from "../../../config"; import ExportRecordsDropdown from "./ExportRecordsDropdown"; -import {isAdmin} from "../../utils/SecurityUtils"; +import { isAdmin } from "../../utils/SecurityUtils"; import ImportRecordsDialog from "./ImportRecordsDialog"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; -import {trackPromise} from "react-promise-tracker"; +import { trackPromise } from "react-promise-tracker"; import RecordTable from "./RecordTable"; import Pagination from "../misc/Pagination"; @@ -18,112 +18,134 @@ const STUDY_CLOSED_FOR_ADDITION = false; const STUDY_CREATE_AT_MOST_ONE_RECORD = false; class Records extends React.Component { - static propTypes = { - recordsLoaded: PropTypes.object, - recordDeleted: PropTypes.object, - recordsDeleting: PropTypes.array, - handlers: PropTypes.object.isRequired, - currentUser: PropTypes.object.isRequired, - formTemplatesLoaded: PropTypes.object.isRequired, - pagination: PropTypes.object.isRequired, - filterAndSort: PropTypes.object.isRequired, - formTemplate: PropTypes.string + static propTypes = { + recordsLoaded: PropTypes.object, + recordDeleted: PropTypes.object, + recordsDeleting: PropTypes.array, + handlers: PropTypes.object.isRequired, + currentUser: PropTypes.object.isRequired, + formTemplatesLoaded: PropTypes.object.isRequired, + pagination: PropTypes.object.isRequired, + filterAndSort: PropTypes.object.isRequired, + formTemplate: PropTypes.string, + }; + + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + showImportDialog: false, }; + } - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - showImportDialog: false - }; - } + openImportDialog = () => { + this.setState({ showImportDialog: true }); + }; - openImportDialog = () => { - this.setState({showImportDialog: true}); - } + closeImportDialog = () => { + this.setState({ showImportDialog: false }); + }; - closeImportDialog = () => { - this.setState({showImportDialog: false}); - } + onImport = (file) => { + trackPromise(this.props.handlers.onImport(file), "records"); + this.closeImportDialog(); + }; - onImport = (file) => { - trackPromise(this.props.handlers.onImport(file), "records"); - this.closeImportDialog(); - } - - render() { - const {formTemplate, recordsLoaded, pagination} = this.props; - const showCreateButton = STUDY_CREATE_AT_MOST_ONE_RECORD - ? (!recordsLoaded.records || (recordsLoaded.records.length < 1)) - : true; - const showPublishButton = - isAdmin(this.props.currentUser) - && EXTENSIONS === EXTENSION_CONSTANTS.OPERATOR; - const createRecordDisabled = - STUDY_CLOSED_FOR_ADDITION - && (!isAdmin(this.props.currentUser)); - const createRecordTooltip = this.i18n( - createRecordDisabled - ? 'records.closed-study.create-tooltip' - : 'records.opened-study.create-tooltip' - ); - const onCreateWithFormTemplate = () => this.props.handlers.onCreate(formTemplate); - return - - - {this._getPanelTitle()} - - - {recordsLoaded.records && <> - - - } - -
-
- {showCreateButton - ? - : null} - - {showPublishButton ? - - : null} -
- -
-
-
; - } + render() { + const { formTemplate, recordsLoaded, pagination } = this.props; + const showCreateButton = STUDY_CREATE_AT_MOST_ONE_RECORD + ? !recordsLoaded.records || recordsLoaded.records.length < 1 + : true; + const showPublishButton = isAdmin(this.props.currentUser) && EXTENSIONS === EXTENSION_CONSTANTS.OPERATOR; + const createRecordDisabled = STUDY_CLOSED_FOR_ADDITION && !isAdmin(this.props.currentUser); + const createRecordTooltip = this.i18n( + createRecordDisabled ? "records.closed-study.create-tooltip" : "records.opened-study.create-tooltip", + ); + const onCreateWithFormTemplate = () => this.props.handlers.onCreate(formTemplate); + return ( + + + + {this._getPanelTitle()} + + + {recordsLoaded.records && ( + <> + + + + )} + +
+
+ {showCreateButton ? ( + + ) : null} + + {showPublishButton ? ( + + ) : null} +
+ +
+
+
+ ); + } - _getFormTemplateName() { - const {formTemplatesLoaded, formTemplate, intl} = this.props; - if (formTemplate) { - const formTemplateOptions = - formTemplatesLoaded.formTemplates - ? processTypeaheadOptions(formTemplatesLoaded.formTemplates, intl) - : []; - return formTemplateOptions.find(r => r.id === formTemplate)?.name; - } + _getFormTemplateName() { + const { formTemplatesLoaded, formTemplate, intl } = this.props; + if (formTemplate) { + const formTemplateOptions = formTemplatesLoaded.formTemplates + ? processTypeaheadOptions(formTemplatesLoaded.formTemplates, intl) + : []; + return formTemplateOptions.find((r) => r.id === formTemplate)?.name; } + } - _getPanelTitle() { - if (!isAdmin(this.props.currentUser) && this.props.formTemplate) { - const formTemplateName = this._getFormTemplateName(); - if (formTemplateName) { - return formTemplateName; - } - } - return this.i18n('records.panel-title'); + _getPanelTitle() { + if (!isAdmin(this.props.currentUser) && this.props.formTemplate) { + const formTemplateName = this._getFormTemplateName(); + if (formTemplateName) { + return formTemplateName; + } } + return this.i18n("records.panel-title"); + } } export default injectIntl(withI18n(Records)); diff --git a/src/components/record/RecordsController.jsx b/src/components/record/RecordsController.jsx index ae8c8c9e..25a6dd37 100644 --- a/src/components/record/RecordsController.jsx +++ b/src/components/record/RecordsController.jsx @@ -1,170 +1,189 @@ -import React from 'react'; +import React from "react"; import Records from "./Records"; import Routes from "../../constants/RoutesConstants"; -import {transitionToWithOpts} from "../../utils/Routing"; -import {exportRecords, importRecords, loadRecords} from "../../actions/RecordsActions"; -import {injectIntl} from "react-intl"; +import { transitionToWithOpts } from "../../utils/Routing"; +import { exportRecords, importRecords, loadRecords } from "../../actions/RecordsActions"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; -import {deleteRecord, updateRecord} from "../../actions/RecordActions"; -import {loadFormTemplates} from "../../actions/FormTemplatesActions"; -import {extractQueryParam, sortToParams} from "../../utils/Utils" +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; +import { deleteRecord, updateRecord } from "../../actions/RecordActions"; +import { loadFormTemplates } from "../../actions/FormTemplatesActions"; +import { extractQueryParam, sortToParams } from "../../utils/Utils"; import { - DEFAULT_PAGE_SIZE, - RECORD_PHASE, - SortDirection, - STORAGE_TABLE_PAGE_SIZE_KEY + DEFAULT_PAGE_SIZE, + RECORD_PHASE, + SortDirection, + STORAGE_TABLE_PAGE_SIZE_KEY, } from "../../constants/DefaultConstants"; -import {trackPromise} from "react-promise-tracker"; -import {INITIAL_PAGE} from "../misc/Pagination"; +import { trackPromise } from "react-promise-tracker"; +import { INITIAL_PAGE } from "../misc/Pagination"; import BrowserStorage from "../../utils/BrowserStorage"; class RecordsController extends React.Component { - constructor(props) { - super(props); - this.state = { - pageNumber: INITIAL_PAGE, - sort: { - date: SortDirection.DESC - }, - filters: {} - }; - } - - componentDidMount() { - this._loadRecords(); - this.props.loadFormTemplates(); - } - - _loadRecords() { - trackPromise(this.props.loadRecords({ - page: this.state.pageNumber, - size: BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY, DEFAULT_PAGE_SIZE), - ...this.state.filters, - sort: sortToParams(this.state.sort) - }), "records"); - } - - _onEditRecord = (record) => { - this.props.transitionToWithOpts(Routes.editRecord, { - params: {key: record.key}, - handlers: { - onCancel: Routes.records - } - }); + constructor(props) { + super(props); + this.state = { + pageNumber: INITIAL_PAGE, + sort: { + date: SortDirection.DESC, + }, + filters: {}, }; - - _onAddRecord = (formTemplate) => { - const opts = {}; - if (formTemplate) { - opts.query = new Map([["formTemplate", formTemplate]]); - } - opts.handlers = { - onSuccess: Routes.records, - onCancel: Routes.records - } - this.props.transitionToWithOpts(Routes.createRecord, opts); - }; - - _onDeleteRecord = (record) => { - trackPromise(this.props.deleteRecord(record), "records"); + } + + componentDidMount() { + this._loadRecords(); + this.props.loadFormTemplates(); + } + + _loadRecords() { + trackPromise( + this.props.loadRecords({ + page: this.state.pageNumber, + size: BrowserStorage.get(STORAGE_TABLE_PAGE_SIZE_KEY, DEFAULT_PAGE_SIZE), + ...this.state.filters, + sort: sortToParams(this.state.sort), + }), + "records", + ); + } + + _onEditRecord = (record) => { + this.props.transitionToWithOpts(Routes.editRecord, { + params: { key: record.key }, + handlers: { + onCancel: Routes.records, + }, + }); + }; + + _onAddRecord = (formTemplate) => { + const opts = {}; + if (formTemplate) { + opts.query = new Map([["formTemplate", formTemplate]]); + } + opts.handlers = { + onSuccess: Routes.records, + onCancel: Routes.records, }; + this.props.transitionToWithOpts(Routes.createRecord, opts); + }; + + _onDeleteRecord = (record) => { + trackPromise(this.props.deleteRecord(record), "records"); + }; + + _onPublishRecords = async () => { + this.setState( + { + records: this.props.recordsLoaded.records, + }, + async () => { + const updatedRecords = this.state.records.map(async (record) => { + if (record.phase === RECORD_PHASE.COMPLETED) { + const updatedRecord = { ...record, phase: RECORD_PHASE.PUBLISHED }; + await this.props.updateRecord(updatedRecord); + return updatedRecord; + } + }); - _onPublishRecords = async () => { - - this.setState({ - records: this.props.recordsLoaded.records - }, async () => { - const updatedRecords = this.state.records.map(async (record) => { - if (record.phase === RECORD_PHASE.COMPLETED) { - const updatedRecord = {...record, phase: RECORD_PHASE.PUBLISHED}; - await this.props.updateRecord(updatedRecord); - return updatedRecord; - } - }); - - return await Promise.all(updatedRecords); - }) - + return await Promise.all(updatedRecords); + }, + ); + }; + + _onExportRecords = (exportType) => { + trackPromise( + this.props.exportRecords(exportType, { + ...this.state.filters, + sort: sortToParams(this.state.sort), + }), + "records", + ); + }; + + _onImportRecords = (file) => { + trackPromise(this.props.importRecords(file), "records"); + }; + + onPagination = (pageNumber) => { + this.setState({ pageNumber }, this._loadRecords); + }; + + onFilterAndSort = (filterChange, sortChange) => { + this.setState( + { + filters: Object.assign({}, this.state.filters, filterChange), + sort: Object.assign({}, this.state.sort, sortChange), + pageNumber: INITIAL_PAGE, + }, + this._loadRecords, + ); + }; + + render() { + const { formTemplatesLoaded, recordsLoaded, recordDeleted, recordsDeleting, currentUser } = this.props; + const formTemplate = extractQueryParam(this.props.location.search, "formTemplate"); + if (!currentUser) { + return null; + } + const handlers = { + onEdit: this._onEditRecord, + onCreate: this._onAddRecord, + onDelete: this._onDeleteRecord, + onPublish: this._onPublishRecords, + onExport: this._onExportRecords, + onImport: this._onImportRecords, }; - - _onExportRecords = (exportType) => { - trackPromise(this.props.exportRecords(exportType, { - ...this.state.filters, - sort: sortToParams(this.state.sort) - }), "records"); + const pagination = { + handlePagination: this.onPagination, + pageNumber: this.state.pageNumber, + itemCount: recordsLoaded.records?.length, + pageCount: recordsLoaded.pageCount, }; - - _onImportRecords = (file) => { - trackPromise(this.props.importRecords(file), "records"); + const filterAndSort = { + filters: this.state.filters, + sort: this.state.sort, + onChange: this.onFilterAndSort, }; - - onPagination = (pageNumber) => { - this.setState({pageNumber}, this._loadRecords); - } - - onFilterAndSort = (filterChange, sortChange) => { - this.setState({ - filters: Object.assign({}, this.state.filters, filterChange), - sort: Object.assign({}, this.state.sort, sortChange), - pageNumber: INITIAL_PAGE - }, this._loadRecords); - } - - render() { - const {formTemplatesLoaded, recordsLoaded, recordDeleted, recordsDeleting, currentUser} = this.props; - const formTemplate = extractQueryParam(this.props.location.search, "formTemplate"); - if (!currentUser) { - return null; - } - const handlers = { - onEdit: this._onEditRecord, - onCreate: this._onAddRecord, - onDelete: this._onDeleteRecord, - onPublish: this._onPublishRecords, - onExport: this._onExportRecords, - onImport: this._onImportRecords, - }; - const pagination = { - handlePagination: this.onPagination, - pageNumber: this.state.pageNumber, - itemCount: recordsLoaded.records?.length, - pageCount: recordsLoaded.pageCount - }; - const filterAndSort = { - filters: this.state.filters, - sort: this.state.sort, - onChange: this.onFilterAndSort - } - return ; - } + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(RecordsController))); function mapStateToProps(state) { - return { - recordDeleted: state.record.recordDeleted, - recordsLoaded: state.records.recordsLoaded, - formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, - recordsDeleting: state.record.recordsDeleting, - currentUser: state.auth.user - }; + return { + recordDeleted: state.record.recordDeleted, + recordsLoaded: state.records.recordsLoaded, + formTemplatesLoaded: state.formTemplates.formTemplatesLoaded, + recordsDeleting: state.record.recordsDeleting, + currentUser: state.auth.user, + }; } function mapDispatchToProps(dispatch) { - return { - deleteRecord: bindActionCreators(deleteRecord, dispatch), - updateRecord: bindActionCreators(updateRecord, dispatch), - loadRecords: bindActionCreators(loadRecords, dispatch), - exportRecords: bindActionCreators(exportRecords, dispatch), - importRecords: bindActionCreators(importRecords, dispatch), - loadFormTemplates: bindActionCreators(loadFormTemplates, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch) - } -} \ No newline at end of file + return { + deleteRecord: bindActionCreators(deleteRecord, dispatch), + updateRecord: bindActionCreators(updateRecord, dispatch), + loadRecords: bindActionCreators(loadRecords, dispatch), + exportRecords: bindActionCreators(exportRecords, dispatch), + importRecords: bindActionCreators(importRecords, dispatch), + loadFormTemplates: bindActionCreators(loadFormTemplates, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + }; +} diff --git a/src/components/record/RequiredAttributes.jsx b/src/components/record/RequiredAttributes.jsx index 63cf2eaf..de2735b2 100644 --- a/src/components/record/RequiredAttributes.jsx +++ b/src/components/record/RequiredAttributes.jsx @@ -1,68 +1,80 @@ -'use strict'; +"use strict"; -import React from 'react'; +import React from "react"; -import HelpIcon from '../HelpIcon'; -import withI18n from '../../i18n/withI18n'; -import {injectIntl} from "react-intl"; -import HorizontalInput from '../HorizontalInput'; +import HelpIcon from "../HelpIcon"; +import withI18n from "../../i18n/withI18n"; +import { injectIntl } from "react-intl"; +import HorizontalInput from "../HorizontalInput"; import PropTypes from "prop-types"; -import {API_URL} from "../../../config"; -import {isAdmin} from "../../utils/SecurityUtils"; +import { API_URL } from "../../../config"; +import { isAdmin } from "../../utils/SecurityUtils"; class RequiredAttributes extends React.Component { - static propTypes = { - record: PropTypes.object.isRequired, - onChange: PropTypes.func.isRequired, - completed: PropTypes.bool.isRequired, - currentUser: PropTypes.object.isRequired, - formTemplate: PropTypes.string - }; + static propTypes = { + record: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired, + completed: PropTypes.bool.isRequired, + currentUser: PropTypes.object.isRequired, + formTemplate: PropTypes.string, + }; - constructor(props) { - super(props); - this.i18n = this.props.i18n; - } + constructor(props) { + super(props); + this.i18n = this.props.i18n; + } - render() { - const {record, formTemplate} = this.props; - const possibleValuesEndpoint = `${API_URL}/rest/formGen/formTemplates`; + render() { + const { record, formTemplate } = this.props; + const possibleValuesEndpoint = `${API_URL}/rest/formGen/formTemplates`; - // If the 'completed' prop is true, the attributes (except for the name) should be read only - return
- {this._showFormTemplateSelection() &&
-
- -
+ // If the 'completed' prop is true, the attributes (except for the name) should be read only + return ( +
+ {this._showFormTemplateSelection() && ( +
+
+
- } - {this._showLocalNameEntry() &&
-
- -
- +
+ )} + {this._showLocalNameEntry() && ( +
+
+
- } -
- } + +
+ )} +
+ ); + } - _showLocalNameEntry() { - return isAdmin(this.props.currentUser); - } + _showLocalNameEntry() { + return isAdmin(this.props.currentUser); + } - _showFormTemplateSelection() { - return isAdmin(this.props.currentUser) || !(this.props.record.formTemplate || this.props.formTemplate) - } + _showFormTemplateSelection() { + return isAdmin(this.props.currentUser) || !(this.props.record.formTemplate || this.props.formTemplate); + } } export default injectIntl(withI18n(RequiredAttributes)); diff --git a/src/components/record/TypeaheadAnswer.jsx b/src/components/record/TypeaheadAnswer.jsx index 4bced211..52e35e53 100644 --- a/src/components/record/TypeaheadAnswer.jsx +++ b/src/components/record/TypeaheadAnswer.jsx @@ -1,80 +1,76 @@ -import React, {useEffect, useState} from "react"; -import {Constants, JsonLdObjectUtils} from "@kbss-cvut/s-forms"; +import React, { useEffect, useState } from "react"; +import { Constants, JsonLdObjectUtils } from "@kbss-cvut/s-forms"; import * as JsonLdUtils from "jsonld-utils"; -import Select from 'react-select'; -import {axiosBackend} from "../../actions"; +import Select from "react-select"; +import { axiosBackend } from "../../actions"; import PropTypes from "prop-types"; const fetchTypeAheadValues = async (endpointURL) => { - const result = await axiosBackend.get(endpointURL); - return result.data; + const result = await axiosBackend.get(endpointURL); + return result.data; }; export const processTypeaheadOptions = (options, intl) => { - if (!options) { - return []; - } + if (!options) { + return []; + } - // sort by label - options.sort(JsonLdObjectUtils.getCompareLocalizedLabelFunction(intl)); + // sort by label + options.sort(JsonLdObjectUtils.getCompareLocalizedLabelFunction(intl)); - // sort by property - JsonLdObjectUtils.orderPreservingToplogicalSort(options, Constants.HAS_PRECEDING_VALUE); + // sort by property + JsonLdObjectUtils.orderPreservingToplogicalSort(options, Constants.HAS_PRECEDING_VALUE); - return JsonLdUtils.processTypeaheadOptions(options, intl); + return JsonLdUtils.processTypeaheadOptions(options, intl); }; - const TypeaheadAnswer = (props) => { + // TODO + const intl = { locale: "cs" }; - // TODO - const intl = {locale: 'cs'}; - - const [isLoading, setLoading] = useState(true); - const [options, setOptions] = useState(processTypeaheadOptions(props.options, intl)); + const [isLoading, setLoading] = useState(true); + const [options, setOptions] = useState(processTypeaheadOptions(props.options, intl)); - useEffect(() => { - if (options.length === 0) { - fetchTypeAheadValues(props.possibleValuesEndpoint).then( - d => { - setLoading(false); - setOptions(processTypeaheadOptions(d, intl)); - } - ); - } - }, []); + useEffect(() => { + if (options.length === 0) { + fetchTypeAheadValues(props.possibleValuesEndpoint).then((d) => { + setLoading(false); + setOptions(processTypeaheadOptions(d, intl)); + }); + } + }, []); - const onOptionSelected = (option) => { - const e = {target: {name: props.name, value: null}} - if (option) { - e.target.value = option.id; - } - props.onChange(e); - }; + const onOptionSelected = (option) => { + const e = { target: { name: props.name, value: null } }; + if (option) { + e.target.value = option.id; + } + props.onChange(e); + }; - return ( - option.id === props.value)} + placeholder={""} + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + onChange={onOptionSelected} + // components={{ Option: DescriptionOption }} + /> + ); }; TypeaheadAnswer.propTypes = { - possibleValuesEndpoint: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - value: PropTypes.string, - onChange: PropTypes.func.isRequired, - isDisabled: PropTypes.bool + possibleValuesEndpoint: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + value: PropTypes.string, + onChange: PropTypes.func.isRequired, + isDisabled: PropTypes.bool, }; -export default TypeaheadAnswer; \ No newline at end of file +export default TypeaheadAnswer; diff --git a/src/components/record/filter/DateIntervalFilter.jsx b/src/components/record/filter/DateIntervalFilter.jsx index b7a9323d..f7cb6191 100644 --- a/src/components/record/filter/DateIntervalFilter.jsx +++ b/src/components/record/filter/DateIntervalFilter.jsx @@ -1,69 +1,106 @@ import React from "react"; import DatePicker from "react-datepicker"; -import {Button, Col, Form, Row} from "react-bootstrap"; +import { Button, Col, Form, Row } from "react-bootstrap"; import "react-datepicker/dist/react-datepicker.css"; -import {useI18n} from "../../../hooks/useI18n"; -import {SortDirection} from "../../../constants/DefaultConstants"; -import {FaCheck} from "react-icons/fa"; +import { useI18n } from "../../../hooks/useI18n"; +import { SortDirection } from "../../../constants/DefaultConstants"; +import { FaCheck } from "react-icons/fa"; function toIsoDate(date) { - // Work around timezones - https://github.com/Hacker0x01/react-datepicker/issues/1787 - return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())).toISOString().substring(0, 10); + // Work around timezones - https://github.com/Hacker0x01/react-datepicker/issues/1787 + return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())).toISOString().substring(0, 10); } -const DateIntervalFilter = ({minDate, maxDate, sort, onChange}) => { - const {i18n} = useI18n(); - const startDate = minDate ? Date.parse(minDate) : undefined; - const endDate = maxDate ? Date.parse(maxDate) : new Date(); - return
- - {i18n("filters.date.from")} - - onChange({minDate: toIsoDate(v)}, {})}/> - - - - {i18n("filters.date.to")} - - onChange({maxDate: toIsoDate(v)}, {})}/> - - -
- - - - - - - - - - -
- - -
- -
- -
-
; +const DateIntervalFilter = ({ minDate, maxDate, sort, onChange }) => { + const { i18n } = useI18n(); + const startDate = minDate ? Date.parse(minDate) : undefined; + const endDate = maxDate ? Date.parse(maxDate) : new Date(); + return ( +
+ + + {i18n("filters.date.from")} + + + onChange({ minDate: toIsoDate(v) }, {})} + /> + + + + + {i18n("filters.date.to")} + + + onChange({ maxDate: toIsoDate(v) }, {})} + /> + + +
+ + + + + + + + + + +
+ + +
+ +
+ +
+
+ ); }; export default DateIntervalFilter; diff --git a/src/components/record/filter/InstitutionFilter.jsx b/src/components/record/filter/InstitutionFilter.jsx index f35ba130..978da1b9 100644 --- a/src/components/record/filter/InstitutionFilter.jsx +++ b/src/components/record/filter/InstitutionFilter.jsx @@ -1,43 +1,64 @@ import React from "react"; -import {useDispatch, useSelector} from "react-redux"; -import {Button, Col, Form, Row} from "react-bootstrap"; -import {loadInstitutions} from "../../../actions/InstitutionsActions"; -import {sanitizeArray} from "../../../utils/Utils"; -import {useI18n} from "../../../hooks/useI18n"; -import {IntelligentTreeSelect} from "intelligent-tree-select"; +import { useDispatch, useSelector } from "react-redux"; +import { Button, Col, Form, Row } from "react-bootstrap"; +import { loadInstitutions } from "../../../actions/InstitutionsActions"; +import { sanitizeArray } from "../../../utils/Utils"; +import { useI18n } from "../../../hooks/useI18n"; +import { IntelligentTreeSelect } from "intelligent-tree-select"; -const InstitutionFilter = ({value, onChange}) => { - const {i18n} = useI18n(); - const dispatch = useDispatch(); - const institutions = useSelector(state => state.institutions.institutionsLoaded.institutions); - React.useEffect(() => { - if (!institutions) { - dispatch(loadInstitutions()); - } - }, [dispatch, institutions]); - const selected = sanitizeArray(institutions).find(o => o.key === value); - return
- - {i18n("institution.panel-title")} - - onChange({institution: o !== null ? o.key : undefined}, {})} - value={selected} - placeholder={i18n("select.placeholder")} isClearable={false}/> - - -
- - -
- -
- -
-
; +const InstitutionFilter = ({ value, onChange }) => { + const { i18n } = useI18n(); + const dispatch = useDispatch(); + const institutions = useSelector((state) => state.institutions.institutionsLoaded.institutions); + React.useEffect(() => { + if (!institutions) { + dispatch(loadInstitutions()); + } + }, [dispatch, institutions]); + const selected = sanitizeArray(institutions).find((o) => o.key === value); + return ( +
+ + + {i18n("institution.panel-title")} + + + onChange({ institution: o !== null ? o.key : undefined }, {})} + value={selected} + placeholder={i18n("select.placeholder")} + isClearable={false} + /> + + +
+ + +
+ +
+ +
+
+ ); }; export default InstitutionFilter; diff --git a/src/components/record/filter/PhaseFilter.jsx b/src/components/record/filter/PhaseFilter.jsx index 23fcab24..ad8149f6 100644 --- a/src/components/record/filter/PhaseFilter.jsx +++ b/src/components/record/filter/PhaseFilter.jsx @@ -1,38 +1,63 @@ import React from "react"; -import {Button, Col, Form, Row} from "react-bootstrap"; -import {IntelligentTreeSelect} from "intelligent-tree-select"; -import {RECORD_PHASE} from "../../../constants/DefaultConstants"; -import {useI18n} from "../../../hooks/useI18n"; -import {sanitizeArray} from "../../../utils/Utils"; +import { Button, Col, Form, Row } from "react-bootstrap"; +import { IntelligentTreeSelect } from "intelligent-tree-select"; +import { RECORD_PHASE } from "../../../constants/DefaultConstants"; +import { useI18n } from "../../../hooks/useI18n"; +import { sanitizeArray } from "../../../utils/Utils"; -const PhaseFilter = ({value, onChange}) => { - const {i18n} = useI18n(); - const options = React.useMemo(() => Object.keys(RECORD_PHASE).map(phase => ({ +const PhaseFilter = ({ value, onChange }) => { + const { i18n } = useI18n(); + const options = React.useMemo( + () => + Object.keys(RECORD_PHASE).map((phase) => ({ label: i18n("records.completion-status." + RECORD_PHASE[phase]), - value: phase - })), [i18n]); - const values = sanitizeArray(value); - const selected = options.filter(o => values.indexOf(o.value) !== -1); - return
- - {i18n("records.completion-status")} - - onChange({phase: o.map(o => o.value)}, {})} value={selected} - placeholder={i18n("select.placeholder")} isClearable={false}/> - - -
- - -
- -
- -
-
; + value: phase, + })), + [i18n], + ); + const values = sanitizeArray(value); + const selected = options.filter((o) => values.indexOf(o.value) !== -1); + return ( +
+ + + {i18n("records.completion-status")} + + + onChange({ phase: o.map((o) => o.value) }, {})} + value={selected} + placeholder={i18n("select.placeholder")} + isClearable={false} + /> + + +
+ + +
+ +
+ +
+
+ ); }; export default PhaseFilter; diff --git a/src/components/statistics/Statistics.jsx b/src/components/statistics/Statistics.jsx index 5079cf73..ab378531 100644 --- a/src/components/statistics/Statistics.jsx +++ b/src/components/statistics/Statistics.jsx @@ -1,37 +1,42 @@ -import React from 'react'; -import {useDispatch, useSelector} from "react-redux"; -import {Card, Table} from "react-bootstrap"; -import {loadStatistics} from "../../actions/StatisticsActions"; -import {useI18n} from "../../hooks/useI18n"; -import {trackPromise} from "react-promise-tracker"; +import React from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { Card, Table } from "react-bootstrap"; +import { loadStatistics } from "../../actions/StatisticsActions"; +import { useI18n } from "../../hooks/useI18n"; +import { trackPromise } from "react-promise-tracker"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; const Statistics = () => { - const {i18n} = useI18n(); - const statistics = useSelector(state => state.statistics.data); - const dispatch = useDispatch(); - React.useEffect(() => { - trackPromise(dispatch(loadStatistics()), "statistics"); - }, [dispatch]); + const { i18n } = useI18n(); + const statistics = useSelector((state) => state.statistics.data); + const dispatch = useDispatch(); + React.useEffect(() => { + trackPromise(dispatch(loadStatistics()), "statistics"); + }, [dispatch]); - return - - {i18n('statistics.panel-title')} - - - - - - {statistics && Object.keys(statistics).map((key, index) => { - return - - - ; - })} - -
{i18n(`statistics.${key}`)}{statistics[key]}
-
+ return ( + + + {i18n("statistics.panel-title")} + + + + + + {statistics && + Object.keys(statistics).map((key, index) => { + return ( + + + + + ); + })} + +
{i18n(`statistics.${key}`)}{statistics[key]}
+
+ ); }; export default Statistics; diff --git a/src/components/user/PasswordChange.jsx b/src/components/user/PasswordChange.jsx index 9c0be75f..efc30e61 100644 --- a/src/components/user/PasswordChange.jsx +++ b/src/components/user/PasswordChange.jsx @@ -1,112 +1,137 @@ import React from "react"; -import {Button, Card} from "react-bootstrap"; +import { Button, Card } from "react-bootstrap"; import withI18n from "../../i18n/withI18n"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import HorizontalInput from "../HorizontalInput"; -import {ACTION_STATUS, ALERT_TYPES} from "../../constants/DefaultConstants"; +import { ACTION_STATUS, ALERT_TYPES } from "../../constants/DefaultConstants"; import AlertMessage from "../AlertMessage"; import UserValidator from "../../validation/UserValidator"; -import {LoaderSmall} from "../Loader"; +import { LoaderSmall } from "../Loader"; import HelpIcon from "../HelpIcon"; import PropTypes from "prop-types"; -import {isAdmin} from "../../utils/SecurityUtils"; +import { isAdmin } from "../../utils/SecurityUtils"; class PasswordChange extends React.Component { - static propTypes = { - handlers: PropTypes.object.isRequired, - currentUser: PropTypes.object.isRequired, - passwordChange: PropTypes.object.isRequired, - match: PropTypes.object.isRequired, - password: PropTypes.object.isRequired - }; + static propTypes = { + handlers: PropTypes.object.isRequired, + currentUser: PropTypes.object.isRequired, + passwordChange: PropTypes.object.isRequired, + match: PropTypes.object.isRequired, + password: PropTypes.object.isRequired, + }; - constructor(props) { - super(props); - this.i18n = this.props.i18n; - } + constructor(props) { + super(props); + this.i18n = this.props.i18n; + } - _onChange = (e) => { - let change = {}; - change[e.target.name] = e.target.value; - this.props.handlers.onChange(change); - }; + _onChange = (e) => { + let change = {}; + change[e.target.name] = e.target.value; + this.props.handlers.onChange(change); + }; - _onSave() { - this.props.handlers.onSave(this.props.currentUser.username === this.props.match.params.username); - } + _onSave() { + this.props.handlers.onSave(this.props.currentUser.username === this.props.match.params.username); + } - _onSaveWithEmail() { - this.props.handlers.onSave(); - } + _onSaveWithEmail() { + this.props.handlers.onSave(); + } - render() { - const {handlers, currentUser, valid, passwordChange, match, password} = this.props; + render() { + const { handlers, currentUser, valid, passwordChange, match, password } = this.props; - return - {this.i18n('user.password-change')} - -
- {currentUser.username === match.params.username && -
-
- -
-
- } -
-
- -
-
-
-
- -
-
-
- {isAdmin(currentUser) && - - } - - -
- {!valid && - } - -
-
; - } + return ( + + + {this.i18n("user.password-change")} + + +
+ {currentUser.username === match.params.username && ( +
+
+ +
+
+ )} +
+
+ +
+
+
+
+ +
+
+
+ {isAdmin(currentUser) && ( + + )} + + +
+ {!valid && } + +
+
+ ); + } } export default injectIntl(withI18n(PasswordChange)); diff --git a/src/components/user/PasswordChangeController.jsx b/src/components/user/PasswordChangeController.jsx index c302fe58..3c53fd9a 100644 --- a/src/components/user/PasswordChangeController.jsx +++ b/src/components/user/PasswordChangeController.jsx @@ -1,79 +1,88 @@ -import React from 'react'; -import {injectIntl} from "react-intl"; -import withI18n from '../../i18n/withI18n'; -import {connect} from "react-redux"; +import React from "react"; +import { injectIntl } from "react-intl"; +import withI18n from "../../i18n/withI18n"; +import { connect } from "react-redux"; import PasswordChange from "./PasswordChange"; import Routes from "../../constants/RoutesConstants"; -import {transitionToWithOpts} from "../../utils/Routing"; -import {bindActionCreators} from "redux"; -import {ROLE} from "../../constants/DefaultConstants"; -import {changePassword} from "../../actions/UserActions"; +import { transitionToWithOpts } from "../../utils/Routing"; +import { bindActionCreators } from "redux"; +import { ROLE } from "../../constants/DefaultConstants"; +import { changePassword } from "../../actions/UserActions"; import * as UserFactory from "../../utils/EntityFactory"; class PasswordChangeController extends React.Component { - constructor(props) { - super(props); - this.state = { - password: UserFactory.initNewPassword(), - valid: true - }; - } - - _onChange = (change) => { - const update = {...this.state.password, ...change}; - this.setState({password: update}); + constructor(props) { + super(props); + this.state = { + password: UserFactory.initNewPassword(), + valid: true, }; + } - _onSave = (sendEmail = true) => { - if (this._passwordValid()) { - delete this.state.password.confirmPassword; - this.props.changePassword(this.props.match.params.username, this.state.password, sendEmail); - this.setState({password: UserFactory.initNewPassword()}); - } - }; + _onChange = (change) => { + const update = { ...this.state.password, ...change }; + this.setState({ password: update }); + }; - _onCancel = () => { - this.props.transitionToWithOpts(Routes.editUser, {params: {username: this.props.match.params.username}}); - }; + _onSave = (sendEmail = true) => { + if (this._passwordValid()) { + delete this.state.password.confirmPassword; + this.props.changePassword(this.props.match.params.username, this.state.password, sendEmail); + this.setState({ password: UserFactory.initNewPassword() }); + } + }; - _passwordValid = () => { - if (this.state.password.newPassword.length >= 4 - && this.state.password.newPassword === this.state.password.confirmPassword) { - this.setState({valid: true}); - return true; - } - this.setState({valid: false}); - return false; - }; + _onCancel = () => { + this.props.transitionToWithOpts(Routes.editUser, { params: { username: this.props.match.params.username } }); + }; - render() { - const {currentUser, passwordChange, match} = this.props; - if (!currentUser || currentUser.role !== ROLE.ADMIN && currentUser.username !== match.params.username) { - return null; - } - const handlers = { - onCancel: this._onCancel, - onSave: this._onSave, - onChange: this._onChange - }; - return ; + _passwordValid = () => { + if ( + this.state.password.newPassword.length >= 4 && + this.state.password.newPassword === this.state.password.confirmPassword + ) { + this.setState({ valid: true }); + return true; } + this.setState({ valid: false }); + return false; + }; + + render() { + const { currentUser, passwordChange, match } = this.props; + if (!currentUser || (currentUser.role !== ROLE.ADMIN && currentUser.username !== match.params.username)) { + return null; + } + const handlers = { + onCancel: this._onCancel, + onSave: this._onSave, + onChange: this._onChange, + }; + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(PasswordChangeController))); function mapStateToProps(state) { - return { - currentUser: state.auth.user, - passwordChange: state.user.passwordChange - }; + return { + currentUser: state.auth.user, + passwordChange: state.user.passwordChange, + }; } function mapDispatchToProps(dispatch) { - return { - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), - changePassword: bindActionCreators(changePassword, dispatch), - } -} \ No newline at end of file + return { + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + changePassword: bindActionCreators(changePassword, dispatch), + }; +} diff --git a/src/components/user/User.jsx b/src/components/user/User.jsx index d5c35fac..ac9c3b96 100644 --- a/src/components/user/User.jsx +++ b/src/components/user/User.jsx @@ -1,281 +1,383 @@ import React from "react"; -import {Button, Card} from "react-bootstrap"; +import { Button, Card } from "react-bootstrap"; import withI18n from "../../i18n/withI18n"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import HorizontalInput from "../HorizontalInput"; import UserValidator from "../../validation/UserValidator"; -import {ACTION_STATUS, ROLE} from "../../constants/DefaultConstants"; -import {getRole, processInstitutions} from "../../utils/Utils"; +import { ACTION_STATUS, ROLE } from "../../constants/DefaultConstants"; +import { getRole, processInstitutions } from "../../utils/Utils"; import * as Vocabulary from "../../constants/Vocabulary"; -import {LoaderCard, LoaderSmall} from "../Loader"; +import { LoaderCard, LoaderSmall } from "../Loader"; import HelpIcon from "../HelpIcon"; import PropTypes from "prop-types"; -import {FaRandom} from 'react-icons/fa'; -import {isUsingOidcAuth} from "../../utils/OidcUtils"; -import {isAdmin} from "../../utils/SecurityUtils"; +import { FaRandom } from "react-icons/fa"; +import { isUsingOidcAuth } from "../../utils/OidcUtils"; +import { isAdmin } from "../../utils/SecurityUtils"; class User extends React.Component { - static propTypes = { - user: PropTypes.object, - handlers: PropTypes.object.isRequired, - backToInstitution: PropTypes.bool, - userSaved: PropTypes.object, - userLoaded: PropTypes.object, - currentUser: PropTypes.object, - institutions: PropTypes.array, - invitationSent: PropTypes.object, - invitationDelete: PropTypes.object, - invited: PropTypes.bool, - impersonation: PropTypes.object, - impersonated: PropTypes.bool, - deletedInvitation: PropTypes.bool, - i18n: PropTypes.func.isRequired - }; + static propTypes = { + user: PropTypes.object, + handlers: PropTypes.object.isRequired, + backToInstitution: PropTypes.bool, + userSaved: PropTypes.object, + userLoaded: PropTypes.object, + currentUser: PropTypes.object, + institutions: PropTypes.array, + invitationSent: PropTypes.object, + invitationDelete: PropTypes.object, + invited: PropTypes.bool, + impersonation: PropTypes.object, + impersonated: PropTypes.bool, + deletedInvitation: PropTypes.bool, + i18n: PropTypes.func.isRequired, + }; - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.formatMessage = this.props.formatMessage; - this.state = {savedWithEmail: false}; - } - - _onChange = (e) => { - let change = {}; - change[e.target.name] = e.target.value; - this.props.handlers.onChange(change); - }; - - _onInstitutionSelected = (e) => { - const value = e.target.value, - institution = this.props.institutions.find((item) => item.uri === value), - change = { - institution: institution - }; - this.props.handlers.onChange(change); - }; + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.formatMessage = this.props.formatMessage; + this.state = { savedWithEmail: false }; + } - _onAdminStatusChange = (e) => { - const role = e.target.value; - let types = this.props.user.types.slice(); - if (role === ROLE.ADMIN) { - types.push(Vocabulary.ADMIN_TYPE); - } else { - types.splice(types.indexOf(Vocabulary.ADMIN_TYPE), 1); - } - this.props.handlers.onChange({types: types}); - }; + _onChange = (e) => { + let change = {}; + change[e.target.name] = e.target.value; + this.props.handlers.onChange(change); + }; - _generateInstitutionsOptions = () => { - let options = []; - const institutions = processInstitutions(this.props.institutions); - const len = institutions.length; - for (let i = 0; i < len; i++) { - let option = institutions[i]; - options.push(); - } - options.unshift(); - return options; - }; + _onInstitutionSelected = (e) => { + const value = e.target.value, + institution = this.props.institutions.find((item) => item.uri === value), + change = { + institution: institution, + }; + this.props.handlers.onChange(change); + }; - _generateRolesOptions = () => { - const roles = ROLE; - return Object.keys(roles).map(key => { - return - }); - }; - - _passwordChangeButton() { - const {user, currentUser, handlers} = this.props; - if (user.isNew || (currentUser.username !== user.username && !isAdmin(currentUser))) { - return null; - } else { - return ; - } + _onAdminStatusChange = (e) => { + const role = e.target.value; + let types = this.props.user.types.slice(); + if (role === ROLE.ADMIN) { + types.push(Vocabulary.ADMIN_TYPE); + } else { + types.splice(types.indexOf(Vocabulary.ADMIN_TYPE), 1); } + this.props.handlers.onChange({ types: types }); + }; - _redirectToKeycloakButton() { - const {user, currentUser, handlers} = this.props; - if (user.isNew || (currentUser.username !== user.username)) { - return null; - } else { - return ; - } + _generateInstitutionsOptions = () => { + let options = []; + const institutions = processInstitutions(this.props.institutions); + const len = institutions.length; + for (let i = 0; i < len; i++) { + let option = institutions[i]; + options.push( + , + ); } + options.unshift( + , + ); + return options; + }; - _sendInvitationButton() { - const {user, handlers, currentUser, invitationSent, invitationDelete} = this.props; - if (user.isInvited === false && isAdmin(currentUser)) { - return

{this.i18n('user.invite-to-study-text')} - - -

; - } else { - return null; - } + _generateRolesOptions = () => { + const roles = ROLE; + return Object.keys(roles).map((key) => { + return ( + + ); + }); + }; + + _passwordChangeButton() { + const { user, currentUser, handlers } = this.props; + if (user.isNew || (currentUser.username !== user.username && !isAdmin(currentUser))) { + return null; + } else { + return ( + + ); } + } - _impersonateButton() { - const {user, currentUser, handlers, impersonation} = this.props; - if (!user.isNew && isAdmin(currentUser) && getRole(user) !== ROLE.ADMIN) { - return ; - } else { - return null; - } + _redirectToKeycloakButton() { + const { user, currentUser, handlers } = this.props; + if (user.isNew || currentUser.username !== user.username) { + return null; + } else { + return ( + + ); } + } - _saveAndSendEmailButton() { - const {user, currentUser, userSaved} = this.props; - if (!user.isNew && isAdmin(currentUser) && currentUser.username !== user.username) { - return - } else { - return null; - } + _sendInvitationButton() { + const { user, handlers, currentUser, invitationSent, invitationDelete } = this.props; + if (user.isInvited === false && isAdmin(currentUser)) { + return ( +

+ {this.i18n("user.invite-to-study-text")} + + +

+ ); + } else { + return null; } + } - _onSaveAndSendEmail() { - this.props.handlers.onSave(); - this.setState({savedWithEmail: true}); + _impersonateButton() { + const { user, currentUser, handlers, impersonation } = this.props; + if (!user.isNew && isAdmin(currentUser) && getRole(user) !== ROLE.ADMIN) { + return ( + + ); + } else { + return null; } + } - _onSave() { - this.props.handlers.onSave(this.props.currentUser.username === this.props.user.username); - this.setState({savedWithEmail: false}); + _saveAndSendEmailButton() { + const { user, currentUser, userSaved } = this.props; + if (!user.isNew && isAdmin(currentUser) && currentUser.username !== user.username) { + return ( + + ); + } else { + return null; } + } - render() { - const {userSaved, currentUser, user, handlers} = this.props; + _onSaveAndSendEmail() { + this.props.handlers.onSave(); + this.setState({ savedWithEmail: true }); + } - if (!user) { - return {this.i18n('user.panel-title')}}/>; - } + _onSave() { + this.props.handlers.onSave(this.props.currentUser.username === this.props.user.username); + this.setState({ savedWithEmail: false }); + } - const generateButton = user.isNew && - ; + render() { + const { userSaved, currentUser, user, handlers } = this.props; - return - {this.i18n('user.panel-title')} - -
- {this._sendInvitationButton()} -
-
- -
-
- -
-
-
-
- -
-
- -
-
-
- {isAdmin(currentUser) && -
- - {this._generateInstitutionsOptions()} - -
- } -
- - {this._generateRolesOptions()} - -
-
- {user.isNew && -
-
- -
-
- } -
- {this._impersonateButton()} - {isUsingOidcAuth() ? - this._redirectToKeycloakButton() : - this._passwordChangeButton()} - {this._saveAndSendEmailButton()} - {(isAdmin(currentUser) || currentUser.username === user.username) && - - } - -
-
-
-
; + if (!user) { + return {this.i18n("user.panel-title")}} />; } + + const generateButton = user.isNew && ( + + ); + + return ( + + + {this.i18n("user.panel-title")} + + +
+ {this._sendInvitationButton()} +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ {isAdmin(currentUser) && ( +
+ + {this._generateInstitutionsOptions()} + +
+ )} +
+ + {this._generateRolesOptions()} + +
+
+ {user.isNew && ( +
+
+ +
+
+ )} +
+ {this._impersonateButton()} + {isUsingOidcAuth() ? this._redirectToKeycloakButton() : this._passwordChangeButton()} + {this._saveAndSendEmailButton()} + {(isAdmin(currentUser) || currentUser.username === user.username) && ( + + )} + +
+
+
+
+ ); + } } export default injectIntl(withI18n(User)); diff --git a/src/components/user/UserController.jsx b/src/components/user/UserController.jsx index 75c3d59d..73e52cfa 100644 --- a/src/components/user/UserController.jsx +++ b/src/components/user/UserController.jsx @@ -1,225 +1,241 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {injectIntl} from "react-intl"; -import withI18n from '../../i18n/withI18n'; -import User from './User'; +import React from "react"; +import { injectIntl } from "react-intl"; +import withI18n from "../../i18n/withI18n"; +import User from "./User"; import Routes from "../../constants/RoutesConstants"; -import {transitionTo, transitionToWithOpts} from '../../utils/Routing'; -import {loadInstitutions} from "../../actions/InstitutionsActions"; -import {connect} from "react-redux"; -import {bindActionCreators} from "redux"; -import {ACTION_FLAG, ACTION_STATUS} from "../../constants/DefaultConstants"; -import {setTransitionPayload} from "../../actions/RouterActions"; +import { transitionTo, transitionToWithOpts } from "../../utils/Routing"; +import { loadInstitutions } from "../../actions/InstitutionsActions"; +import { connect } from "react-redux"; +import { bindActionCreators } from "redux"; +import { ACTION_FLAG, ACTION_STATUS } from "../../constants/DefaultConstants"; +import { setTransitionPayload } from "../../actions/RouterActions"; import { - createUser, - deleteInvitationOption, - generateUsername, - impersonate, - loadUser, - oidcImpersonate, - sendInvitation, - unloadSavedUser, - unloadUser, - updateUser + createUser, + deleteInvitationOption, + generateUsername, + impersonate, + loadUser, + oidcImpersonate, + sendInvitation, + unloadSavedUser, + unloadUser, + updateUser, } from "../../actions/UserActions"; import * as UserFactory from "../../utils/EntityFactory"; -import omit from 'lodash/omit'; -import {getRole} from "../../utils/Utils"; -import {isUsingOidcAuth, userProfileLink} from "../../utils/OidcUtils"; -import {isAdmin} from "../../utils/SecurityUtils"; +import omit from "lodash/omit"; +import { getRole } from "../../utils/Utils"; +import { isUsingOidcAuth, userProfileLink } from "../../utils/OidcUtils"; +import { isAdmin } from "../../utils/SecurityUtils"; class UserController extends React.Component { - constructor(props) { - super(props); - this.state = { - user: this._isNew() ? UserFactory.initNewUser() : null, - saved: false - }; - this.institution = this._getPayload(); - } + constructor(props) { + super(props); + this.state = { + user: this._isNew() ? UserFactory.initNewUser() : null, + saved: false, + }; + this.institution = this._getPayload(); + } - componentDidMount() { - if (isAdmin(this.props.currentUser) && !this.props.institutionsLoaded.institutions) { - this.props.loadInstitutions(); - } - if (!this.state.user) { - this.props.loadUser(this.props.match.params.username); - } - if (this.state.user && this.state.user.isNew && this.institution) { - this._onChange({institution: this.institution}); - } - if (this.props.userSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY && this.props.userSaved.status === ACTION_STATUS.SUCCESS) { - this.props.unloadSavedUser(); - } + componentDidMount() { + if (isAdmin(this.props.currentUser) && !this.props.institutionsLoaded.institutions) { + this.props.loadInstitutions(); } - - componentDidUpdate(prevProps, prevState, snapshot) { - const {userLoaded, userSaved, transitionToWithOpts, match, loadUser, generatedUsername} = this.props; - - if (this.state.saved && userLoaded.status !== ACTION_STATUS.PENDING - && userSaved.status === ACTION_STATUS.SUCCESS) { - if (userSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY) { - transitionToWithOpts(Routes.editUser, { - params: {username: userSaved.user.username}, - payload: {institution: this.institution} - }); - } else { - this.setState({saved: false}); - this.props.loadUser(userSaved.user.username); - } - } - - if (prevProps.userLoaded.status === ACTION_STATUS.PENDING && userLoaded.status === ACTION_STATUS.SUCCESS) { - this.setState({user: userLoaded.user}); - } - - if (prevProps.generatedUsername.status === ACTION_STATUS.PENDING && generatedUsername.status === ACTION_STATUS.SUCCESS) { - this._onChange({username: generatedUsername.username}); - } - - if (prevProps.match.params.username !== match.params.username) { - loadUser(match.params.username); - this.setState({saved: false, invited: false, impersonated: false}); - } + if (!this.state.user) { + this.props.loadUser(this.props.match.params.username); } - - componentWillUnmount() { - this.props.unloadUser(); + if (this.state.user && this.state.user.isNew && this.institution) { + this._onChange({ institution: this.institution }); } - - _isNew() { - return !this.props.match.params.username; + if ( + this.props.userSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY && + this.props.userSaved.status === ACTION_STATUS.SUCCESS + ) { + this.props.unloadSavedUser(); } + } - _onSave = (sendEmail = true) => { - let user = this.state.user; - this.setState({saved: true, invited: false}); - if (user.isNew || (this._isNew() && this.props.userSaved.status === ACTION_STATUS.ERROR)) { - this.props.createUser(omit(user, 'isNew')); - } else { - this.props.updateUser(user, this.props.currentUser, sendEmail); - } - }; - - _onCancel = () => { - const handlers = this.props.viewHandlers[Routes.editUser.name]; - if (handlers && !this.institution) { - transitionTo(handlers.onCancel); - } else if (this.institution) { - this.props.transitionToWithOpts(Routes.editInstitution, {params: {key: this.institution.key}}); - } else { - transitionTo(isAdmin(this.props.currentUser) ? Routes.users : Routes.dashboard); - } - }; - - _onChange = (change) => { - const update = {...this.state.user, ...change}; - this.setState({user: update}); - }; + componentDidUpdate(prevProps, prevState, snapshot) { + const { userLoaded, userSaved, transitionToWithOpts, match, loadUser, generatedUsername } = this.props; - _onPasswordChange = () => { - this.props.transitionToWithOpts(Routes.passwordChange, { - params: {username: this.props.match.params.username} + if (this.state.saved && userLoaded.status !== ACTION_STATUS.PENDING && userSaved.status === ACTION_STATUS.SUCCESS) { + if (userSaved.actionFlag === ACTION_FLAG.CREATE_ENTITY) { + transitionToWithOpts(Routes.editUser, { + params: { username: userSaved.user.username }, + payload: { institution: this.institution }, }); - }; - - _generateUsername = () => { - this.props.generateUsername(getRole(this.state.user).toLowerCase()); - }; - - _getPayload() { - let payload = this._isNew() ? this.props.transitionPayload[Routes.createUser.name] : - this.props.transitionPayload[Routes.editUser.name]; - this._isNew() ? this.props.setTransitionPayload(Routes.createUser.name, null) : - this.props.setTransitionPayload(Routes.editUser.name, null); - return payload ? payload.institution : null; + } else { + this.setState({ saved: false }); + this.props.loadUser(userSaved.user.username); + } } - _sendInvitation = () => { - this.setState({deletedInvitation: false, invited: true}); - this.props.sendInvitation(this.state.user.username); - }; + if (prevProps.userLoaded.status === ACTION_STATUS.PENDING && userLoaded.status === ACTION_STATUS.SUCCESS) { + this.setState({ user: userLoaded.user }); + } - _deleteInvitationOption = () => { - this.setState({deletedInvitation: true, invited: false}); - this.props.deleteInvitationOption(this.state.user.username); - }; + if ( + prevProps.generatedUsername.status === ACTION_STATUS.PENDING && + generatedUsername.status === ACTION_STATUS.SUCCESS + ) { + this._onChange({ username: generatedUsername.username }); + } - _impersonate = () => { - this.setState({impersonated: true}); - if (isUsingOidcAuth()) { - this.props.oidcImpersonate(this.state.user.username); - } else { - this.props.impersonate(this.state.user.username); - } - }; + if (prevProps.match.params.username !== match.params.username) { + loadUser(match.params.username); + this.setState({ saved: false, invited: false, impersonated: false }); + } + } + + componentWillUnmount() { + this.props.unloadUser(); + } + + _isNew() { + return !this.props.match.params.username; + } + + _onSave = (sendEmail = true) => { + let user = this.state.user; + this.setState({ saved: true, invited: false }); + if (user.isNew || (this._isNew() && this.props.userSaved.status === ACTION_STATUS.ERROR)) { + this.props.createUser(omit(user, "isNew")); + } else { + this.props.updateUser(user, this.props.currentUser, sendEmail); + } + }; + + _onCancel = () => { + const handlers = this.props.viewHandlers[Routes.editUser.name]; + if (handlers && !this.institution) { + transitionTo(handlers.onCancel); + } else if (this.institution) { + this.props.transitionToWithOpts(Routes.editInstitution, { params: { key: this.institution.key } }); + } else { + transitionTo(isAdmin(this.props.currentUser) ? Routes.users : Routes.dashboard); + } + }; + + _onChange = (change) => { + const update = { ...this.state.user, ...change }; + this.setState({ user: update }); + }; + + _onPasswordChange = () => { + this.props.transitionToWithOpts(Routes.passwordChange, { + params: { username: this.props.match.params.username }, + }); + }; + + _generateUsername = () => { + this.props.generateUsername(getRole(this.state.user).toLowerCase()); + }; + + _getPayload() { + let payload = this._isNew() + ? this.props.transitionPayload[Routes.createUser.name] + : this.props.transitionPayload[Routes.editUser.name]; + this._isNew() + ? this.props.setTransitionPayload(Routes.createUser.name, null) + : this.props.setTransitionPayload(Routes.editUser.name, null); + return payload ? payload.institution : null; + } + + _sendInvitation = () => { + this.setState({ deletedInvitation: false, invited: true }); + this.props.sendInvitation(this.state.user.username); + }; + + _deleteInvitationOption = () => { + this.setState({ deletedInvitation: true, invited: false }); + this.props.deleteInvitationOption(this.state.user.username); + }; + + _impersonate = () => { + this.setState({ impersonated: true }); + if (isUsingOidcAuth()) { + this.props.oidcImpersonate(this.state.user.username); + } else { + this.props.impersonate(this.state.user.username); + } + }; - _onRedirect = () => { - if (isUsingOidcAuth()) { - window.location = userProfileLink(); - } + _onRedirect = () => { + if (isUsingOidcAuth()) { + window.location = userProfileLink(); } + }; - render() { - const { - currentUser, userSaved, userLoaded, institutionsLoaded, - invitationSent, impersonation, invitationDelete - } = this.props; - if (!currentUser) { - return null; - } - const handlers = { - onSave: this._onSave, - onCancel: this._onCancel, - onChange: this._onChange, - onPasswordChange: this._onPasswordChange, - onKeycloakRedirect: this._onRedirect, - generateUsername: this._generateUsername, - sendInvitation: this._sendInvitation, - impersonate: this._impersonate, - deleteInvitationOption: this._deleteInvitationOption - }; - return ; + render() { + const { currentUser, userSaved, userLoaded, institutionsLoaded, invitationSent, impersonation, invitationDelete } = + this.props; + if (!currentUser) { + return null; } + const handlers = { + onSave: this._onSave, + onCancel: this._onCancel, + onChange: this._onChange, + onPasswordChange: this._onPasswordChange, + onKeycloakRedirect: this._onRedirect, + generateUsername: this._generateUsername, + sendInvitation: this._sendInvitation, + impersonate: this._impersonate, + deleteInvitationOption: this._deleteInvitationOption, + }; + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(UserController))); function mapStateToProps(state) { - return { - userSaved: state.user.userSaved, - userLoaded: state.user.userLoaded, - currentUser: state.auth.user, - institutionsLoaded: state.institutions.institutionsLoaded, - transitionPayload: state.router.transitionPayload, - viewHandlers: state.router.viewHandlers, - generatedUsername: state.user.generatedUsername, - invitationSent: state.user.invitationSent, - invitationDelete: state.user.invitationDelete, - impersonation: state.user.impersonation - }; + return { + userSaved: state.user.userSaved, + userLoaded: state.user.userLoaded, + currentUser: state.auth.user, + institutionsLoaded: state.institutions.institutionsLoaded, + transitionPayload: state.router.transitionPayload, + viewHandlers: state.router.viewHandlers, + generatedUsername: state.user.generatedUsername, + invitationSent: state.user.invitationSent, + invitationDelete: state.user.invitationDelete, + impersonation: state.user.impersonation, + }; } function mapDispatchToProps(dispatch) { - return { - createUser: bindActionCreators(createUser, dispatch), - updateUser: bindActionCreators(updateUser, dispatch), - loadUser: bindActionCreators(loadUser, dispatch), - unloadUser: bindActionCreators(unloadUser, dispatch), - unloadSavedUser: bindActionCreators(unloadSavedUser, dispatch), - loadInstitutions: bindActionCreators(loadInstitutions, dispatch), - setTransitionPayload: bindActionCreators(setTransitionPayload, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), - generateUsername: bindActionCreators(generateUsername, dispatch), - sendInvitation: bindActionCreators(sendInvitation, dispatch), - deleteInvitationOption: bindActionCreators(deleteInvitationOption, dispatch), - impersonate: bindActionCreators(impersonate, dispatch), - oidcImpersonate: bindActionCreators(oidcImpersonate, dispatch), - } -} \ No newline at end of file + return { + createUser: bindActionCreators(createUser, dispatch), + updateUser: bindActionCreators(updateUser, dispatch), + loadUser: bindActionCreators(loadUser, dispatch), + unloadUser: bindActionCreators(unloadUser, dispatch), + unloadSavedUser: bindActionCreators(unloadSavedUser, dispatch), + loadInstitutions: bindActionCreators(loadInstitutions, dispatch), + setTransitionPayload: bindActionCreators(setTransitionPayload, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + generateUsername: bindActionCreators(generateUsername, dispatch), + sendInvitation: bindActionCreators(sendInvitation, dispatch), + deleteInvitationOption: bindActionCreators(deleteInvitationOption, dispatch), + impersonate: bindActionCreators(impersonate, dispatch), + oidcImpersonate: bindActionCreators(oidcImpersonate, dispatch), + }; +} diff --git a/src/components/user/UserRow.jsx b/src/components/user/UserRow.jsx index 9799061f..0cf2d036 100644 --- a/src/components/user/UserRow.jsx +++ b/src/components/user/UserRow.jsx @@ -1,38 +1,56 @@ import React from "react"; -import {Button} from "react-bootstrap"; +import { Button } from "react-bootstrap"; import PropTypes from "prop-types"; import IfInternalAuth from "../misc/oidc/IfInternalAuth"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; let UserRow = (props) => { - const user = props.user; - const {i18n} = useI18n(); - return - - + const user = props.user; + const { i18n } = useI18n(); + return ( + + + + + {user.username} + {user.institution ? user.institution.name : ""} + {user.emailAddress} + + + + - {user.username} - {user.institution ? user.institution.name : ''} - {user.emailAddress} - - - - - - - ; + + + ); }; UserRow.propTypes = { - user: PropTypes.object.isRequired, - onEdit: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, + user: PropTypes.object.isRequired, + onEdit: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, }; export default UserRow; diff --git a/src/components/user/UserTable.jsx b/src/components/user/UserTable.jsx index b8bddebe..6362dfa1 100644 --- a/src/components/user/UserTable.jsx +++ b/src/components/user/UserTable.jsx @@ -1,86 +1,92 @@ import React from "react"; -import {Table} from "react-bootstrap"; +import { Table } from "react-bootstrap"; import DeleteItemDialog from "../DeleteItemDialog"; -import {injectIntl} from "react-intl"; +import { injectIntl } from "react-intl"; import withI18n from "../../i18n/withI18n"; import UserRow from "./UserRow"; import PropTypes from "prop-types"; import IfInternalAuth from "../misc/oidc/IfInternalAuth"; class UserTable extends React.Component { - static propTypes = { - users: PropTypes.array.isRequired, - handlers: PropTypes.object.isRequired - }; - - constructor(props) { - super(props); - this.i18n = this.props.i18n; - this.state = { - showDialog: false, - selectedUser: null - } - } + static propTypes = { + users: PropTypes.array.isRequired, + handlers: PropTypes.object.isRequired, + }; - _onDelete = (user) => { - this.setState({showDialog: true, selectedUser: user}); + constructor(props) { + super(props); + this.i18n = this.props.i18n; + this.state = { + showDialog: false, + selectedUser: null, }; + } - _onCancelDelete = () => { - this.setState({showDialog: false, selectedUser: null}); - }; + _onDelete = (user) => { + this.setState({ showDialog: true, selectedUser: user }); + }; - _onSubmitDelete = () => { - this.props.handlers.onDelete(this.state.selectedUser); - this.setState({showDialog: false, selectedUser: null}); - }; + _onCancelDelete = () => { + this.setState({ showDialog: false, selectedUser: null }); + }; - render() { - return
- - {this.props.users.length > 0 ? - - {this._renderHeader()} - - {this._renderUsers()} - -
- : -

{this.i18n('users.not-found')}

- } -
; - } + _onSubmitDelete = () => { + this.props.handlers.onDelete(this.state.selectedUser); + this.setState({ showDialog: false, selectedUser: null }); + }; - _getDeleteLabel() { - const user = this.state.selectedUser; - return user ? user.firstName + ' ' + user.lastName : ''; - } + render() { + return ( +
+ + {this.props.users.length > 0 ? ( + + {this._renderHeader()} + {this._renderUsers()} +
+ ) : ( +

{this.i18n("users.not-found")}

+ )} +
+ ); + } - _renderHeader() { - return + _getDeleteLabel() { + const user = this.state.selectedUser; + return user ? user.firstName + " " + user.lastName : ""; + } + + _renderHeader() { + return ( + - {this.i18n('name')} - {this.i18n('login.username')} - {this.i18n('institution.name')} - {this.i18n('users.email')} - - {this.i18n('actions')} - + {this.i18n("name")} + {this.i18n("login.username")} + {this.i18n("institution.name")} + {this.i18n("users.email")} + + {this.i18n("actions")} + - ; - } + + ); + } - _renderUsers() { - const {users} = this.props; - const onEdit = this.props.handlers.onEdit; - let rows = []; - for (let i = 0, len = users.length; i < len; i++) { - rows.push(); - } - return rows; + _renderUsers() { + const { users } = this.props; + const onEdit = this.props.handlers.onEdit; + let rows = []; + for (let i = 0, len = users.length; i < len; i++) { + rows.push(); } + return rows; + } } export default injectIntl(withI18n(UserTable)); diff --git a/src/components/user/Users.jsx b/src/components/user/Users.jsx index 36e97594..14f8d5c2 100644 --- a/src/components/user/Users.jsx +++ b/src/components/user/Users.jsx @@ -1,33 +1,36 @@ -import React from 'react'; -import {Button, Card} from 'react-bootstrap'; -import UserTable from './UserTable'; +import React from "react"; +import { Button, Card } from "react-bootstrap"; +import UserTable from "./UserTable"; import PropTypes from "prop-types"; import IfInternalAuth from "../misc/oidc/IfInternalAuth"; import PromiseTrackingMask from "../misc/PromiseTrackingMask"; -import {useI18n} from "../../hooks/useI18n"; +import { useI18n } from "../../hooks/useI18n"; -const Users = ({usersLoaded, handlers}) => { - const {i18n} = useI18n(); - return - - {i18n('users.panel-title')} - - - - {usersLoaded.users && } - -
- -
-
-
-
; +const Users = ({ usersLoaded, handlers }) => { + const { i18n } = useI18n(); + return ( + + + {i18n("users.panel-title")} + + + + {usersLoaded.users && } + +
+ +
+
+
+
+ ); }; Users.propTypes = { - usersLoaded: PropTypes.object, - handlers: PropTypes.object.isRequired + usersLoaded: PropTypes.object, + handlers: PropTypes.object.isRequired, }; export default Users; diff --git a/src/components/user/UsersController.jsx b/src/components/user/UsersController.jsx index ab0b1024..ac51f2df 100644 --- a/src/components/user/UsersController.jsx +++ b/src/components/user/UsersController.jsx @@ -1,83 +1,83 @@ -'use strict'; +"use strict"; import React from "react"; import Routes from "../../constants/RoutesConstants"; -import {transitionToWithOpts} from "../../utils/Routing"; +import { transitionToWithOpts } from "../../utils/Routing"; import Users from "./Users"; -import {connect} from "react-redux"; +import { connect } from "react-redux"; import withI18n from "../../i18n/withI18n"; -import {injectIntl} from "react-intl"; -import {bindActionCreators} from "redux"; -import {loadUsers} from "../../actions/UsersActions"; -import {ROLE} from "../../constants/DefaultConstants"; -import {deleteUser} from "../../actions/UserActions"; -import {trackPromise} from "react-promise-tracker"; +import { injectIntl } from "react-intl"; +import { bindActionCreators } from "redux"; +import { loadUsers } from "../../actions/UsersActions"; +import { ROLE } from "../../constants/DefaultConstants"; +import { deleteUser } from "../../actions/UserActions"; +import { trackPromise } from "react-promise-tracker"; class UsersController extends React.Component { - constructor(props) { - super(props); - this.state = { - showAlert: false - }; - } - - componentDidMount() { - trackPromise(this.props.loadUsers(), "users"); - } - - _onEditUser = (user) => { - this.props.transitionToWithOpts(Routes.editUser, { - params: {username: user.username}, - handlers: { - onCancel: Routes.users - } - }); + constructor(props) { + super(props); + this.state = { + showAlert: false, }; + } - _onAddUser = () => { - this.props.transitionToWithOpts(Routes.createUser, { - handlers: { - onSuccess: Routes.users, - onCancel: Routes.users - } - }); - }; + componentDidMount() { + trackPromise(this.props.loadUsers(), "users"); + } - _onDeleteUser = (user) => { - this.props.deleteUser(user); - this.setState({showAlert: true}); - }; + _onEditUser = (user) => { + this.props.transitionToWithOpts(Routes.editUser, { + params: { username: user.username }, + handlers: { + onCancel: Routes.users, + }, + }); + }; - render() { - const {currentUser, usersLoaded, userDeleted} = this.props; - if (!currentUser || currentUser.role !== ROLE.ADMIN) { - return null; - } - const handlers = { - onEdit: this._onEditUser, - onCreate: this._onAddUser, - onDelete: this._onDeleteUser, - }; - return ; + _onAddUser = () => { + this.props.transitionToWithOpts(Routes.createUser, { + handlers: { + onSuccess: Routes.users, + onCancel: Routes.users, + }, + }); + }; + _onDeleteUser = (user) => { + this.props.deleteUser(user); + this.setState({ showAlert: true }); + }; + + render() { + const { currentUser, usersLoaded, userDeleted } = this.props; + if (!currentUser || currentUser.role !== ROLE.ADMIN) { + return null; } + const handlers = { + onEdit: this._onEditUser, + onCreate: this._onAddUser, + onDelete: this._onDeleteUser, + }; + return ( + + ); + } } export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(withI18n(UsersController))); function mapStateToProps(state) { - return { - userDeleted: state.user.userDeleted, - usersLoaded: state.users.usersLoaded, - currentUser: state.auth.user - }; + return { + userDeleted: state.user.userDeleted, + usersLoaded: state.users.usersLoaded, + currentUser: state.auth.user, + }; } function mapDispatchToProps(dispatch) { - return { - deleteUser: bindActionCreators(deleteUser, dispatch), - loadUsers: bindActionCreators(loadUsers, dispatch), - transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch) - } -} \ No newline at end of file + return { + deleteUser: bindActionCreators(deleteUser, dispatch), + loadUsers: bindActionCreators(loadUsers, dispatch), + transitionToWithOpts: bindActionCreators(transitionToWithOpts, dispatch), + }; +} diff --git a/src/constants/ActionConstants.js b/src/constants/ActionConstants.js index 307d4b75..29809f17 100644 --- a/src/constants/ActionConstants.js +++ b/src/constants/ActionConstants.js @@ -20,10 +20,10 @@ export const LOAD_USER_PROFILE_PENDING = "LOAD_USER_PROFILE_PENDING"; export const LOAD_USER_PROFILE_SUCCESS = "LOAD_USER_PROFILE_SUCCESS"; export const LOAD_USER_PROFILE_ERROR = "LOAD_USER_PROFILE_ERROR"; -export const AUTH_USER_PENDING = 'AUTH_USER_PENDING'; -export const AUTH_USER_SUCCESS = 'AUTH_USER_SUCCESS'; -export const AUTH_USER_ERROR = 'AUTH_USER_ERROR'; -export const UNAUTH_USER = 'UNAUTH_USER'; +export const AUTH_USER_PENDING = "AUTH_USER_PENDING"; +export const AUTH_USER_SUCCESS = "AUTH_USER_SUCCESS"; +export const AUTH_USER_ERROR = "AUTH_USER_ERROR"; +export const UNAUTH_USER = "UNAUTH_USER"; export const LOAD_INSTITUTIONS_PENDING = "LOAD_INSTITUTIONS_PENDING"; export const LOAD_INSTITUTIONS_SUCCESS = "LOAD_INSTITUTIONS_SUCCESS"; @@ -131,4 +131,4 @@ export const IMPERSONATE_LOGOUT_PENDING = "IMPERSONATE_LOGOUT_PENDING"; export const IMPERSONATE_LOGOUT_SUCCESS = "IMPERSONATE_LOGOUT_SUCCESS"; export const PUBLISH_MESSAGE = "PUBLISH_MESSAGE"; -export const DISMISS_MESSAGE = "DISMISS_MESSAGE"; \ No newline at end of file +export const DISMISS_MESSAGE = "DISMISS_MESSAGE"; diff --git a/src/constants/DefaultConstants.js b/src/constants/DefaultConstants.js index c693b3e8..f0131ad8 100644 --- a/src/constants/DefaultConstants.js +++ b/src/constants/DefaultConstants.js @@ -1,7 +1,7 @@ import Routes from "./RoutesConstants"; -import {APP_TITLE} from '../../config'; +import { APP_TITLE } from "../../config"; -export const WEB_LANG = 'en'; +export const WEB_LANG = "en"; export const APP_NAME = APP_TITLE; export const HOME_ROUTE = Routes.dashboard; @@ -16,40 +16,40 @@ export const MESSAGE_DISPLAY_COUNT = 5; * Sorting glyph icons */ export const SORTING = { - NO: {glyph: 'sort', title: 'sort.no'}, - ASC: {glyph: 'chevron-up', title: 'sort.asc'}, - DESC: {glyph: 'chevron-down', title: 'sort.desc'} + NO: { glyph: "sort", title: "sort.no" }, + ASC: { glyph: "chevron-up", title: "sort.asc" }, + DESC: { glyph: "chevron-down", title: "sort.desc" }, }; -export const UNAUTHORIZED_USER = {name: 'unauthorized'}; +export const UNAUTHORIZED_USER = { name: "unauthorized" }; -export const FILTER_DEFAULT = 'all'; +export const FILTER_DEFAULT = "all"; export const DASHBOARDS = { - MAIN: { - id: 'main', - title: 'dashboard.welcome' - }, - CREATE_REPORT: { - id: 'createReport', - title: 'dashboard.create-tile' - }, - IMPORT_REPORT: { - id: 'importReport', - title: 'dashboard.create-import-tile' - } + MAIN: { + id: "main", + title: "dashboard.welcome", + }, + CREATE_REPORT: { + id: "createReport", + title: "dashboard.create-tile", + }, + IMPORT_REPORT: { + id: "importReport", + title: "dashboard.create-import-tile", + }, }; /** * Navigation between dashboards. Key is the current dashboard, value is the target to navigate to on goBack */ export const DASHBOARD_GO_BACK = { - 'main': 'main', - 'createReport': 'main', - 'importReport': 'createReport' + main: "main", + createReport: "main", + importReport: "createReport", }; -export const MINUTE = 60 * 1000; // Minute in milliseconds +export const MINUTE = 60 * 1000; // Minute in milliseconds // Maximum number of columns supported by Bootstrap export const COLUMN_COUNT = 12; @@ -62,65 +62,65 @@ export const PASSWORD_LENGTH = 4; export const RECORD_REQUIRED_FIELDS = []; export const ALERT_TYPES = { - INFO: 'info', - SUCCESS: 'success', - WARNING: 'warning', - DANGER: 'danger' + INFO: "info", + SUCCESS: "success", + WARNING: "warning", + DANGER: "danger", }; export const ACTION_FLAG = { - CREATE_ENTITY: 'CREATE_ENTITY', - UPDATE_ENTITY: 'UPDATE_ENTITY' + CREATE_ENTITY: "CREATE_ENTITY", + UPDATE_ENTITY: "UPDATE_ENTITY", }; export const ACTION_STATUS = { - PENDING: 'PENDING', - SUCCESS: 'SUCCESS', - ERROR: 'ERROR' + PENDING: "PENDING", + SUCCESS: "SUCCESS", + ERROR: "ERROR", }; export const ROLE = { - ADMIN: 'Admin', - DOCTOR: 'Regular User' + ADMIN: "Admin", + DOCTOR: "Regular User", }; // Default number of table elements per page. export const DEFAULT_PAGE_SIZE = 10; export const SortDirection = { - ASC: "+", - DESC: "-" -} + ASC: "+", + DESC: "-", +}; export const STATISTICS_TYPE = { - NUMBER_OF_INVESTIGATORS: 'statistics.number-of-investigators', - NUMBER_OF_PROCESSED_RECORDS: 'statistics.number-of-processed-records' + NUMBER_OF_INVESTIGATORS: "statistics.number-of-investigators", + NUMBER_OF_PROCESSED_RECORDS: "statistics.number-of-processed-records", }; -export const SCRIPT_ERROR = 'SCRIPT_ERROR'; +export const SCRIPT_ERROR = "SCRIPT_ERROR"; export const HttpHeaders = { - AUTHORIZATION: "Authorization", - CONTENT_DISPOSITION: "content-disposition", - LINK: "link" -} + AUTHORIZATION: "Authorization", + CONTENT_DISPOSITION: "content-disposition", + LINK: "link", +}; export const MediaType = { - FORM_URLENCODED: "application/x-www-form-urlencoded", - EXCEL: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - JSON: "application/json" -} + FORM_URLENCODED: "application/x-www-form-urlencoded", + EXCEL: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + JSON: "application/json", +}; export const EXTENSION_CONSTANTS = { - SUPPLIER: "supplier", - OPERATOR: "operator" -} + SUPPLIER: "supplier", + OPERATOR: "operator", +}; export const RECORD_PHASE = { - OPEN: 'open', - VALID: 'valid', - COMPLETED: 'completed', - PUBLISHED: 'published', - REJECTED: 'rejected' -} + OPEN: "open", + VALID: "valid", + COMPLETED: "completed", + PUBLISHED: "published", + REJECTED: "rejected", +}; export const STORAGE_TABLE_PAGE_SIZE_KEY = `${APP_TITLE}_TABLE_PAGE_SIZE`; diff --git a/src/constants/ExportType.js b/src/constants/ExportType.js index 62a15ef9..31a9a33f 100644 --- a/src/constants/ExportType.js +++ b/src/constants/ExportType.js @@ -1,12 +1,12 @@ -import {MediaType} from "./DefaultConstants"; +import { MediaType } from "./DefaultConstants"; export const ExportType = { - EXCEL: { - mediaType: MediaType.EXCEL, - fileExtension: ".xslx" - }, - JSON: { - mediaType: MediaType.JSON, - fileExtension: ".json" - } + EXCEL: { + mediaType: MediaType.EXCEL, + fileExtension: ".xslx", + }, + JSON: { + mediaType: MediaType.JSON, + fileExtension: ".json", + }, }; diff --git a/src/constants/RoutesConstants.js b/src/constants/RoutesConstants.js index 12254b2c..cd95eaa7 100644 --- a/src/constants/RoutesConstants.js +++ b/src/constants/RoutesConstants.js @@ -1,22 +1,22 @@ const Routes = { - login: {name: 'login', path: '/login'}, - logout: {name: 'logout', path: '/logout'}, - passwordToken: {name: 'passwordToken', path: '/login/password-reset/:token'}, - passwordReset: {name: 'passwordReset', path: '/login/password-reset'}, - dashboard: {name: 'dashboard', path: '/'}, - users: {name: 'users', path: '/users'}, - createUser: {name: 'createUser', path: '/users/create'}, - editUser: {name: 'editUser', path: '/users/:username'}, - passwordChange: {name: 'passwordChange', path: '/users/:username/password-change'}, - institutions: {name: 'institutions', path: '/institutions'}, - createInstitution: {name: 'createInstitution', path: '/institutions/create'}, - editInstitution: {name: 'editInstitution', path: '/institutions/:key'}, - records: {name: 'records', path: '/records'}, - createRecord: {name: 'createRecord', path: '/records/create'}, - editRecord: {name: 'editRecord', path: '/records/:key'}, - historyActions: {name: 'historyActions', path: '/history'}, - historyAction: {name: 'historyAction', path: '/history/:key'}, - statistics: {name: 'statistics', path: '/statistics'} + login: { name: "login", path: "/login" }, + logout: { name: "logout", path: "/logout" }, + passwordToken: { name: "passwordToken", path: "/login/password-reset/:token" }, + passwordReset: { name: "passwordReset", path: "/login/password-reset" }, + dashboard: { name: "dashboard", path: "/" }, + users: { name: "users", path: "/users" }, + createUser: { name: "createUser", path: "/users/create" }, + editUser: { name: "editUser", path: "/users/:username" }, + passwordChange: { name: "passwordChange", path: "/users/:username/password-change" }, + institutions: { name: "institutions", path: "/institutions" }, + createInstitution: { name: "createInstitution", path: "/institutions/create" }, + editInstitution: { name: "editInstitution", path: "/institutions/:key" }, + records: { name: "records", path: "/records" }, + createRecord: { name: "createRecord", path: "/records/create" }, + editRecord: { name: "editRecord", path: "/records/:key" }, + historyActions: { name: "historyActions", path: "/history" }, + historyAction: { name: "historyAction", path: "/history/:key" }, + statistics: { name: "statistics", path: "/statistics" }, }; -export default Routes; \ No newline at end of file +export default Routes; diff --git a/src/constants/SupportedDevices.js b/src/constants/SupportedDevices.js index bc866b55..01f7c89c 100644 --- a/src/constants/SupportedDevices.js +++ b/src/constants/SupportedDevices.js @@ -1,36 +1,36 @@ export const SUPPORTED_BROWSERS = { - edge: '>=14', - chrome: '>=48', - chromium: '>=48', - opera: '>=35', - safari: '>=10.1', - firefox: '>=44', - ie: '>=11', - samsung_internet: '>=6.2', + edge: ">=14", + chrome: ">=48", + chromium: ">=48", + opera: ">=35", + safari: ">=10.1", + firefox: ">=44", + ie: ">=11", + samsung_internet: ">=6.2", }; export const WEB_BROWSERS = { - EDGE: 'Edge', - SAFARI: 'Safari', - CHROME: 'Chrome', - FIREFOX: 'Firefox', + EDGE: "Edge", + SAFARI: "Safari", + CHROME: "Chrome", + FIREFOX: "Firefox", }; export const SUPPORTED_BROWSERS_LINKS = [ - { - name: WEB_BROWSERS.CHROME, - linkMobile: 'https://www.google.com/chrome/', - linkDesktop: 'https://www.google.com/chrome/', - }, - { - name: WEB_BROWSERS.FIREFOX, - linkMobile: 'https://www.mozilla.org/en-US/firefox/mobile/', - linkDesktop: 'https://www.mozilla.org/en-US/firefox/', - }, - { - name: WEB_BROWSERS.SAFARI, - }, - { - name: WEB_BROWSERS.EDGE, - }, + { + name: WEB_BROWSERS.CHROME, + linkMobile: "https://www.google.com/chrome/", + linkDesktop: "https://www.google.com/chrome/", + }, + { + name: WEB_BROWSERS.FIREFOX, + linkMobile: "https://www.mozilla.org/en-US/firefox/mobile/", + linkDesktop: "https://www.mozilla.org/en-US/firefox/", + }, + { + name: WEB_BROWSERS.SAFARI, + }, + { + name: WEB_BROWSERS.EDGE, + }, ]; diff --git a/src/constants/Vocabulary.js b/src/constants/Vocabulary.js index f37f05f7..170763a5 100644 --- a/src/constants/Vocabulary.js +++ b/src/constants/Vocabulary.js @@ -1,10 +1,10 @@ -'use strict'; +"use strict"; /** * Ontological vocabulary used by JSON-LD responses we get. */ -export const RDFS_LABEL = 'http://www.w3.org/2000/01/rdf-schema#label'; -export const RDFS_COMMENT = 'http://www.w3.org/2000/01/rdf-schema#comment'; -export const ADMIN_TYPE = 'http://onto.fel.cvut.cz/ontologies/record-manager/administrator'; -export const DOCTOR_TYPE = 'http://onto.fel.cvut.cz/ontologies/record-manager/doctor'; -export const IMPERSONATOR_TYPE = 'http://onto.fel.cvut.cz/ontologies/record-manager/impersonator'; +export const RDFS_LABEL = "http://www.w3.org/2000/01/rdf-schema#label"; +export const RDFS_COMMENT = "http://www.w3.org/2000/01/rdf-schema#comment"; +export const ADMIN_TYPE = "http://onto.fel.cvut.cz/ontologies/record-manager/administrator"; +export const DOCTOR_TYPE = "http://onto.fel.cvut.cz/ontologies/record-manager/doctor"; +export const IMPERSONATOR_TYPE = "http://onto.fel.cvut.cz/ontologies/record-manager/impersonator"; diff --git a/src/hooks/useI18n.jsx b/src/hooks/useI18n.jsx index 41e2e532..f5a48747 100644 --- a/src/hooks/useI18n.jsx +++ b/src/hooks/useI18n.jsx @@ -5,21 +5,14 @@ import { useIntl } from "react-intl"; * React Hook providing basic i18n functions. */ export function useI18n() { - const intl = useIntl(); - const i18n = useCallback( - (msgId) => (intl.messages[msgId]) || "{" + msgId + "}", - [intl] -); - const formatMessage = useCallback( - (msgId, values = {}) => - intl.formatMessage({ id: msgId }, values), - [intl] - ); - return { - i18n, - formatMessage, - formatDate: intl.formatDate, - formatTime: intl.formatTime, - locale: intl.locale, - }; + const intl = useIntl(); + const i18n = useCallback((msgId) => intl.messages[msgId] || "{" + msgId + "}", [intl]); + const formatMessage = useCallback((msgId, values = {}) => intl.formatMessage({ id: msgId }, values), [intl]); + return { + i18n, + formatMessage, + formatDate: intl.formatDate, + formatTime: intl.formatTime, + locale: intl.locale, + }; } diff --git a/src/i18n/localization.js b/src/i18n/localization.js index cd702a7f..606b22fd 100644 --- a/src/i18n/localization.js +++ b/src/i18n/localization.js @@ -1,21 +1,21 @@ -import * as config from '../../config'; -import enLang from './en'; -import csLang from './cs'; -import * as I18nStore from '../stores/I18nStore'; +import * as config from "../../config"; +import enLang from "./en"; +import csLang from "./cs"; +import * as I18nStore from "../stores/I18nStore"; function selectNavigatorLocalization() { - const lang = navigator.language; - if (lang && lang === "cs" || lang === "cs-CZ" || lang === "sk" || lang === "sk-SK") { - return csLang; - } - return enLang; + const lang = navigator.language; + if ((lang && lang === "cs") || lang === "cs-CZ" || lang === "sk" || lang === "sk-SK") { + return csLang; + } + return enLang; } function selectEnvLocalization() { - if (config.LANGUAGE === 'cs') { - return csLang; - } - return enLang; + if (config.LANGUAGE === "cs") { + return csLang; + } + return enLang; } export const intlData = config.NAVIGATOR_LANGUAGE ? selectNavigatorLocalization() : selectEnvLocalization(); diff --git a/src/i18n/withI18n.jsx b/src/i18n/withI18n.jsx index 7d7f1e4e..697c4e13 100644 --- a/src/i18n/withI18n.jsx +++ b/src/i18n/withI18n.jsx @@ -1,33 +1,33 @@ import * as React from "react"; export default function withI18n(Component, options) { - const {forwardRef = false} = options || {}; + const { forwardRef = false } = options || {}; - class Wrapper extends React.Component { - i18n = (id) => { - return this.props.intl.messages[id] || ("{" + id + "}"); - }; + class Wrapper extends React.Component { + i18n = (id) => { + return this.props.intl.messages[id] || "{" + id + "}"; + }; - formatMessage = (msgId, values = {}) => { - return this.props.intl.formatMessage({id: msgId}, values); - }; + formatMessage = (msgId, values = {}) => { + return this.props.intl.formatMessage({ id: msgId }, values); + }; - render() { - return ; - } + render() { + return ( + + ); } + } - if (forwardRef) { - return React.forwardRef((props, ref) => - - ) - } + if (forwardRef) { + return React.forwardRef((props, ref) => ); + } - return Wrapper; + return Wrapper; } diff --git a/src/index.jsx b/src/index.jsx index 231bc82a..b7da3a27 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,31 +1,28 @@ -'use strict'; +"use strict"; import React from "react"; -import {createRoot} from "react-dom/client"; -import {Provider} from "react-redux"; +import { createRoot } from "react-dom/client"; +import { Provider } from "react-redux"; import reduxThunk from "redux-thunk"; -import {applyMiddleware, createStore} from 'redux'; -import {composeWithDevTools} from 'redux-devtools-extension/developmentOnly'; +import { applyMiddleware, createStore } from "redux"; +import { composeWithDevTools } from "redux-devtools-extension/developmentOnly"; import rootReducer from "./reducers"; -import {errorLogger, historyLogger} from "./utils/HistoryLogger"; -import App from './App'; - +import { errorLogger, historyLogger } from "./utils/HistoryLogger"; +import App from "./App"; // store initialization -const createStoreWithMiddleware = composeWithDevTools( - applyMiddleware(reduxThunk, historyLogger), -)(createStore); +const createStoreWithMiddleware = composeWithDevTools(applyMiddleware(reduxThunk, historyLogger))(createStore); export const store = createStoreWithMiddleware(rootReducer); window.onerror = (msg, source, line) => { - errorLogger(msg, line, store); - return false; + errorLogger(msg, line, store); + return false; }; -const app = document.getElementById('root'); +const app = document.getElementById("root"); const root = createRoot(app); root.render( - - - + + + , ); diff --git a/src/model/Message.js b/src/model/Message.js index 9ffa716a..38a2d072 100644 --- a/src/model/Message.js +++ b/src/model/Message.js @@ -1,61 +1,60 @@ export const MessageType = { - SUCCESS: "success", - INFO: "info", - WARNING: "warning", - ERROR: "danger" + SUCCESS: "success", + INFO: "info", + WARNING: "warning", + ERROR: "danger", }; export default class Message { - - constructor(data) { - this.mMessage = data.message; - this.mMessageId = data.messageId; - this.mValues = data.values; - this.mType = data.type || MessageType.INFO; - this.mTimetamp = Date.now(); - } - - get message() { - return this.mMessage; - } - - get messageId() { - return this.mMessageId; - } - - get values() { - return this.mValues; - } - - get type() { - return this.mType; - } - - get timestamp() { - return this.mTimetamp; - } + constructor(data) { + this.mMessage = data.message; + this.mMessageId = data.messageId; + this.mValues = data.values; + this.mType = data.type || MessageType.INFO; + this.mTimetamp = Date.now(); + } + + get message() { + return this.mMessage; + } + + get messageId() { + return this.mMessageId; + } + + get values() { + return this.mValues; + } + + get type() { + return this.mType; + } + + get timestamp() { + return this.mTimetamp; + } } export function successMessage(messageId, values) { - return new Message({ - messageId, - values, - type: MessageType.SUCCESS - }); + return new Message({ + messageId, + values, + type: MessageType.SUCCESS, + }); } export function infoMessage(messageId, values) { - return new Message({ - messageId, - values, - type: MessageType.INFO - }); + return new Message({ + messageId, + values, + type: MessageType.INFO, + }); } export function errorMessage(messageId, values) { - return new Message({ - messageId, - values, - type: MessageType.ERROR - }); + return new Message({ + messageId, + values, + type: MessageType.ERROR, + }); } diff --git a/src/model/RecordState.js b/src/model/RecordState.js index 3b944e16..1deb41d4 100644 --- a/src/model/RecordState.js +++ b/src/model/RecordState.js @@ -1,38 +1,38 @@ const States = { - INITIAL: 0, - COMPLETE: 1, - INCOMPLETE: 2 + INITIAL: 0, + COMPLETE: 1, + INCOMPLETE: 2, }; class RecordState { - constructor(initialState = States.INITIAL) { - this.state = initialState; - } + constructor(initialState = States.INITIAL) { + this.state = initialState; + } - recordComplete = () => { - this.state = States.COMPLETE; - }; + recordComplete = () => { + this.state = States.COMPLETE; + }; - recordIncomplete = () => { - if (this.state === States.INITIAL) { - return; - } - this.state = States.INCOMPLETE; - }; + recordIncomplete = () => { + if (this.state === States.INITIAL) { + return; + } + this.state = States.INCOMPLETE; + }; - isComplete = () => { - return this.state === States.COMPLETE; - }; + isComplete = () => { + return this.state === States.COMPLETE; + }; - isInitial = () => { - return this.state === States.INITIAL; - } + isInitial = () => { + return this.state === States.INITIAL; + }; } export function createInitialState() { - return new RecordState(); + return new RecordState(); } export function createRecordState() { - return new RecordState(States.COMPLETE); + return new RecordState(States.COMPLETE); } diff --git a/src/reducers/AuthReducer.js b/src/reducers/AuthReducer.js index 9e3da9e3..7803a66f 100644 --- a/src/reducers/AuthReducer.js +++ b/src/reducers/AuthReducer.js @@ -1,118 +1,118 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {getRole} from "../utils/Utils"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { getRole } from "../utils/Utils"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - authenticated: false, - isLogging: false, - isLoaded: false, - user: {}, - passwordResetStatus: null, - validTokenStatus: null, - passwordChange: {} + authenticated: false, + isLogging: false, + isLoaded: false, + user: {}, + passwordResetStatus: null, + validTokenStatus: null, + passwordChange: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.AUTH_USER_PENDING: - return { - ...state, - isLogging: true - }; - case ActionConstants.AUTH_USER_SUCCESS: - return { - ...state, - error: '', - authenticated: true, - isLogging: false - }; - case ActionConstants.AUTH_USER_ERROR: - return { - ...state, - error: action.error, - isLogging: false - }; - case ActionConstants.LOAD_USER_PROFILE_PENDING: - return { - ...state, - isLoaded: false, - authenticated: false, - status: ACTION_STATUS.PENDING - }; - case ActionConstants.LOAD_USER_PROFILE_SUCCESS: - return { - ...state, - isLoaded: true, - authenticated: true, - status: ACTION_STATUS.SUCCESS, - user: { - ...action.user, - role: getRole(action.user) - } - }; - case ActionConstants.LOAD_USER_PROFILE_ERROR: - return { - ...state, - isLoaded: false, - authenticated: false, - status: ACTION_STATUS.ERROR, - user: { - error: action.error - } - }; - case ActionConstants.PASSWORD_RESET_PENDING: - return { - ...state, - passwordResetStatus: ACTION_STATUS.PENDING - }; - case ActionConstants.PASSWORD_RESET_SUCCESS: - return { - ...state, - passwordResetStatus: ACTION_STATUS.SUCCESS - }; - case ActionConstants.PASSWORD_RESET_ERROR: - return { - ...state, - passwordResetStatus: ACTION_STATUS.ERROR - }; - case ActionConstants.VALIDATE_TOKEN_PENDING: - return { - ...state, - validTokenStatus: ACTION_STATUS.PENDING - }; - case ActionConstants.VALIDATE_TOKEN_SUCCESS: - return { - ...state, - validTokenStatus: ACTION_STATUS.SUCCESS - }; - case ActionConstants.VALIDATE_TOKEN_ERROR: - return { - ...state, - validTokenStatus: ACTION_STATUS.ERROR - }; - case ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING: - return { - ...state, - passwordChange: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS: - return { - ...state, - passwordChange: { - status: ACTION_STATUS.SUCCESS - } - }; - case ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR: - return { - ...state, - passwordChange: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.AUTH_USER_PENDING: + return { + ...state, + isLogging: true, + }; + case ActionConstants.AUTH_USER_SUCCESS: + return { + ...state, + error: "", + authenticated: true, + isLogging: false, + }; + case ActionConstants.AUTH_USER_ERROR: + return { + ...state, + error: action.error, + isLogging: false, + }; + case ActionConstants.LOAD_USER_PROFILE_PENDING: + return { + ...state, + isLoaded: false, + authenticated: false, + status: ACTION_STATUS.PENDING, + }; + case ActionConstants.LOAD_USER_PROFILE_SUCCESS: + return { + ...state, + isLoaded: true, + authenticated: true, + status: ACTION_STATUS.SUCCESS, + user: { + ...action.user, + role: getRole(action.user), + }, + }; + case ActionConstants.LOAD_USER_PROFILE_ERROR: + return { + ...state, + isLoaded: false, + authenticated: false, + status: ACTION_STATUS.ERROR, + user: { + error: action.error, + }, + }; + case ActionConstants.PASSWORD_RESET_PENDING: + return { + ...state, + passwordResetStatus: ACTION_STATUS.PENDING, + }; + case ActionConstants.PASSWORD_RESET_SUCCESS: + return { + ...state, + passwordResetStatus: ACTION_STATUS.SUCCESS, + }; + case ActionConstants.PASSWORD_RESET_ERROR: + return { + ...state, + passwordResetStatus: ACTION_STATUS.ERROR, + }; + case ActionConstants.VALIDATE_TOKEN_PENDING: + return { + ...state, + validTokenStatus: ACTION_STATUS.PENDING, + }; + case ActionConstants.VALIDATE_TOKEN_SUCCESS: + return { + ...state, + validTokenStatus: ACTION_STATUS.SUCCESS, + }; + case ActionConstants.VALIDATE_TOKEN_ERROR: + return { + ...state, + validTokenStatus: ACTION_STATUS.ERROR, + }; + case ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING: + return { + ...state, + passwordChange: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS: + return { + ...state, + passwordChange: { + status: ACTION_STATUS.SUCCESS, + }, + }; + case ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR: + return { + ...state, + passwordChange: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/FormTemplatesReducer.js b/src/reducers/FormTemplatesReducer.js index f3fd00f1..ffb5f24c 100644 --- a/src/reducers/FormTemplatesReducer.js +++ b/src/reducers/FormTemplatesReducer.js @@ -1,38 +1,38 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - formTemplatesLoaded: {} + formTemplatesLoaded: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.LOAD_FORM_TEMPLATES_PENDING: - return { - ...state, - formTemplatesLoaded: { - ...state.formTemplatesLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_FORM_TEMPLATES_SUCCESS: - return { - ...state, - formTemplatesLoaded: { - status: ACTION_STATUS.SUCCESS, - formTemplates: action.formTemplates, - error: '' - } - }; - case ActionConstants.LOAD_FORM_TEMPLATES_ERROR: - return { - ...state, - formTemplatesLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.LOAD_FORM_TEMPLATES_PENDING: + return { + ...state, + formTemplatesLoaded: { + ...state.formTemplatesLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_FORM_TEMPLATES_SUCCESS: + return { + ...state, + formTemplatesLoaded: { + status: ACTION_STATUS.SUCCESS, + formTemplates: action.formTemplates, + error: "", + }, + }; + case ActionConstants.LOAD_FORM_TEMPLATES_ERROR: + return { + ...state, + formTemplatesLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/HistoryReducer.js b/src/reducers/HistoryReducer.js index 0e0556c8..eade7f4b 100644 --- a/src/reducers/HistoryReducer.js +++ b/src/reducers/HistoryReducer.js @@ -1,67 +1,67 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - actionsLoaded: {}, - actionLoaded: {} + actionsLoaded: {}, + actionLoaded: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.LOAD_ACTIONS_HISTORY_PENDING: - return { - ...state, - actionsLoaded: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS: - return { - ...state, - actionsLoaded: { - status: ACTION_STATUS.SUCCESS, - actions: action.actionsHistory, - error: '' - } - }; - case ActionConstants.LOAD_ACTIONS_HISTORY_ERROR: - return { - ...state, - actionsLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.LOAD_ACTION_HISTORY_PENDING: - return { - ...state, - actionLoaded: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_ACTION_HISTORY_SUCCESS: - return { - ...state, - actionLoaded: { - status: ACTION_STATUS.SUCCESS, - action: action.actionHistory, - error: '' - } - }; - case ActionConstants.LOAD_ACTION_HISTORY_ERROR: - return { - ...state, - actionLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.UNLOAD_ACTION_HISTORY: - return { - ...state, - actionLoaded: {} - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.LOAD_ACTIONS_HISTORY_PENDING: + return { + ...state, + actionsLoaded: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS: + return { + ...state, + actionsLoaded: { + status: ACTION_STATUS.SUCCESS, + actions: action.actionsHistory, + error: "", + }, + }; + case ActionConstants.LOAD_ACTIONS_HISTORY_ERROR: + return { + ...state, + actionsLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.LOAD_ACTION_HISTORY_PENDING: + return { + ...state, + actionLoaded: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_ACTION_HISTORY_SUCCESS: + return { + ...state, + actionLoaded: { + status: ACTION_STATUS.SUCCESS, + action: action.actionHistory, + error: "", + }, + }; + case ActionConstants.LOAD_ACTION_HISTORY_ERROR: + return { + ...state, + actionLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_ACTION_HISTORY: + return { + ...state, + actionLoaded: {}, + }; + default: + return state; + } +} diff --git a/src/reducers/InstitutionReducer.js b/src/reducers/InstitutionReducer.js index 1d9458c3..75f77478 100644 --- a/src/reducers/InstitutionReducer.js +++ b/src/reducers/InstitutionReducer.js @@ -1,108 +1,108 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - institutionDeleted: {}, - institutionLoaded: {}, - institutionSaved: {} + institutionDeleted: {}, + institutionLoaded: {}, + institutionSaved: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.SAVE_INSTITUTION_PENDING: - return { - ...state, - institutionSaved: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.SAVE_INSTITUTION_SUCCESS: - return { - ...state, - institutionSaved: { - actionFlag: action.actionFlag, - status: ACTION_STATUS.SUCCESS, - institution: { - ...action.institution, - key: action.key - }, - error: '' - } - }; - case ActionConstants.SAVE_INSTITUTION_ERROR: - return { - ...state, - institutionSaved: { - actionFlag: action.actionFlag, - status: ACTION_STATUS.ERROR, - institution: action.institution, - error: action.error - } - }; - case ActionConstants.UNLOAD_SAVED_INSTITUTION: - return { - ...state, - institutionSaved: { - status: state.institutionSaved.status - } - }; - case ActionConstants.DELETE_INSTITUTION_PENDING: - return { - ...state, - institutionDeleted: { - status: ACTION_STATUS.PENDING, - key: action.key - } - }; - case ActionConstants.DELETE_INSTITUTION_SUCCESS: - return { - ...state, - institutionDeleted: { - status: ACTION_STATUS.SUCCESS, - institution: action.institution, - error: '' - } - }; - case ActionConstants.DELETE_INSTITUTION_ERROR: - return { - ...state, - institutionDeleted: { - status: ACTION_STATUS.ERROR, - institution: action.institution, - error: action.error - } - }; - case ActionConstants.LOAD_INSTITUTION_PENDING: - return { - ...state, - institutionLoaded: { - ...state.institutionLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_INSTITUTION_SUCCESS: - return { - ...state, - institutionLoaded: { - status: ACTION_STATUS.SUCCESS, - institution: action.institution, - error: '' - } - }; - case ActionConstants.LOAD_INSTITUTION_ERROR: - return { - ...state, - institutionLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.UNLOAD_INSTITUTION: - return { - ...state, - institutionLoaded: {} - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.SAVE_INSTITUTION_PENDING: + return { + ...state, + institutionSaved: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.SAVE_INSTITUTION_SUCCESS: + return { + ...state, + institutionSaved: { + actionFlag: action.actionFlag, + status: ACTION_STATUS.SUCCESS, + institution: { + ...action.institution, + key: action.key, + }, + error: "", + }, + }; + case ActionConstants.SAVE_INSTITUTION_ERROR: + return { + ...state, + institutionSaved: { + actionFlag: action.actionFlag, + status: ACTION_STATUS.ERROR, + institution: action.institution, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_SAVED_INSTITUTION: + return { + ...state, + institutionSaved: { + status: state.institutionSaved.status, + }, + }; + case ActionConstants.DELETE_INSTITUTION_PENDING: + return { + ...state, + institutionDeleted: { + status: ACTION_STATUS.PENDING, + key: action.key, + }, + }; + case ActionConstants.DELETE_INSTITUTION_SUCCESS: + return { + ...state, + institutionDeleted: { + status: ACTION_STATUS.SUCCESS, + institution: action.institution, + error: "", + }, + }; + case ActionConstants.DELETE_INSTITUTION_ERROR: + return { + ...state, + institutionDeleted: { + status: ACTION_STATUS.ERROR, + institution: action.institution, + error: action.error, + }, + }; + case ActionConstants.LOAD_INSTITUTION_PENDING: + return { + ...state, + institutionLoaded: { + ...state.institutionLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_INSTITUTION_SUCCESS: + return { + ...state, + institutionLoaded: { + status: ACTION_STATUS.SUCCESS, + institution: action.institution, + error: "", + }, + }; + case ActionConstants.LOAD_INSTITUTION_ERROR: + return { + ...state, + institutionLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_INSTITUTION: + return { + ...state, + institutionLoaded: {}, + }; + default: + return state; + } +} diff --git a/src/reducers/InstitutionsReducer.js b/src/reducers/InstitutionsReducer.js index ca00e3e4..e9da5eec 100644 --- a/src/reducers/InstitutionsReducer.js +++ b/src/reducers/InstitutionsReducer.js @@ -1,38 +1,38 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - institutionsLoaded: {} + institutionsLoaded: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.LOAD_INSTITUTIONS_PENDING: - return { - ...state, - institutionsLoaded: { - ...state.institutionsLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_INSTITUTIONS_SUCCESS: - return { - ...state, - institutionsLoaded: { - status: ACTION_STATUS.SUCCESS, - institutions: action.institutions, - error: '' - } - }; - case ActionConstants.LOAD_INSTITUTIONS_ERROR: - return { - ...state, - institutionsLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.LOAD_INSTITUTIONS_PENDING: + return { + ...state, + institutionsLoaded: { + ...state.institutionsLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_INSTITUTIONS_SUCCESS: + return { + ...state, + institutionsLoaded: { + status: ACTION_STATUS.SUCCESS, + institutions: action.institutions, + error: "", + }, + }; + case ActionConstants.LOAD_INSTITUTIONS_ERROR: + return { + ...state, + institutionsLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/IntlReducer.js b/src/reducers/IntlReducer.js index e9bd2d59..b6283257 100644 --- a/src/reducers/IntlReducer.js +++ b/src/reducers/IntlReducer.js @@ -1,5 +1,5 @@ -import {intlData} from '../i18n/localization'; +import { intlData } from "../i18n/localization"; const IntlReducer = (state = intlData) => state; -export default IntlReducer; \ No newline at end of file +export default IntlReducer; diff --git a/src/reducers/MessageReducer.js b/src/reducers/MessageReducer.js index d927c75d..4844f1f3 100644 --- a/src/reducers/MessageReducer.js +++ b/src/reducers/MessageReducer.js @@ -1,20 +1,25 @@ -import {DISMISS_MESSAGE, IMPERSONATE_LOGOUT_SUCCESS, PUBLISH_MESSAGE, UNAUTH_USER} from "../constants/ActionConstants"; -import {userAuthPending} from "../actions/AuthActions"; +import { + DISMISS_MESSAGE, + IMPERSONATE_LOGOUT_SUCCESS, + PUBLISH_MESSAGE, + UNAUTH_USER, +} from "../constants/ActionConstants"; +import { userAuthPending } from "../actions/AuthActions"; export default function messages(state = [], action) { - switch (action.type) { - case PUBLISH_MESSAGE: - return [...state, action.message]; - case DISMISS_MESSAGE: { - const newArr = state.slice(0); - newArr.splice(newArr.indexOf(action.message), 1); - return newArr; - } - case userAuthPending: - case UNAUTH_USER: // Intentional fall-through - case IMPERSONATE_LOGOUT_SUCCESS: // Intentional fall-through - return []; - default: - return state; + switch (action.type) { + case PUBLISH_MESSAGE: + return [...state, action.message]; + case DISMISS_MESSAGE: { + const newArr = state.slice(0); + newArr.splice(newArr.indexOf(action.message), 1); + return newArr; } -} \ No newline at end of file + case userAuthPending: + case UNAUTH_USER: // Intentional fall-through + case IMPERSONATE_LOGOUT_SUCCESS: // Intentional fall-through + return []; + default: + return state; + } +} diff --git a/src/reducers/RecordReducer.js b/src/reducers/RecordReducer.js index 55467f54..0e7c9ff7 100644 --- a/src/reducers/RecordReducer.js +++ b/src/reducers/RecordReducer.js @@ -1,139 +1,139 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; -import without from 'lodash/without'; +import { ACTION_STATUS } from "../constants/DefaultConstants"; +import without from "lodash/without"; const initialState = { - institutionPatients: {}, - recordDeleted: {}, - recordLoaded: {}, - recordSaved: {}, - recordsDeleting: [], - formgen: {} + institutionPatients: {}, + recordDeleted: {}, + recordLoaded: {}, + recordSaved: {}, + recordsDeleting: [], + formgen: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.SAVE_RECORD_PENDING: - return { - ...state, - recordSaved: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.SAVE_RECORD_SUCCESS: - return { - ...state, - recordSaved: { - actionFlag: action.actionFlag, - status: ACTION_STATUS.SUCCESS, - record: { - ...action.record, - key: action.key - }, - error: '' - } - }; - case ActionConstants.SAVE_RECORD_ERROR: - return { - ...state, - recordSaved: { - actionFlag: action.actionFlag, - status: ACTION_STATUS.ERROR, - record: action.record, - error: action.error - } - }; - case ActionConstants.UNLOAD_SAVED_RECORD: - return { - ...state, - recordSaved: { - status: state.recordSaved.status - } - }; - case ActionConstants.LOAD_RECORD_PENDING: - return { - ...state, - recordLoaded: { - ...state.recordLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_RECORD_SUCCESS: - return { - ...state, - recordLoaded: { - status: ACTION_STATUS.SUCCESS, - record: action.record, - error: '' - } - }; - case ActionConstants.LOAD_RECORD_ERROR: - return { - ...state, - recordLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.UNLOAD_RECORD: - return { - ...state, - recordLoaded: {} - }; - case ActionConstants.DELETE_RECORD_PENDING: - return { - ...state, - recordDeleted: { - status: ACTION_STATUS.PENDING, - key: action.key - }, - recordsDeleting: state.recordsDeleting.concat(action.key) - }; - case ActionConstants.DELETE_RECORD_SUCCESS: - return { - ...state, - recordDeleted: { - status: ACTION_STATUS.SUCCESS, - record: action.record, - error: '' - }, - recordsDeleting: without(state.recordsDeleting, action.key) - }; - case ActionConstants.DELETE_RECORD_ERROR: - return { - ...state, - recordDeleted: { - status: ACTION_STATUS.ERROR, - record: action.record, - error: action.error - }, - recordsDeleting: without(state.recordsDeleting, action.key) - }; - case ActionConstants.LOAD_FORMGEN_PENDING: - return { - ...state, - formgen: { - status: ACTION_STATUS.PENDING, - error: '' - } - }; - case ActionConstants.LOAD_FORMGEN_SUCCESS: - return { - ...state, - formgen: { - status: ACTION_STATUS.SUCCESS, - error: '' - } - }; - case ActionConstants.LOAD_FORMGEN_ERROR: - return { - ...state, - formgen: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.SAVE_RECORD_PENDING: + return { + ...state, + recordSaved: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.SAVE_RECORD_SUCCESS: + return { + ...state, + recordSaved: { + actionFlag: action.actionFlag, + status: ACTION_STATUS.SUCCESS, + record: { + ...action.record, + key: action.key, + }, + error: "", + }, + }; + case ActionConstants.SAVE_RECORD_ERROR: + return { + ...state, + recordSaved: { + actionFlag: action.actionFlag, + status: ACTION_STATUS.ERROR, + record: action.record, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_SAVED_RECORD: + return { + ...state, + recordSaved: { + status: state.recordSaved.status, + }, + }; + case ActionConstants.LOAD_RECORD_PENDING: + return { + ...state, + recordLoaded: { + ...state.recordLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_RECORD_SUCCESS: + return { + ...state, + recordLoaded: { + status: ACTION_STATUS.SUCCESS, + record: action.record, + error: "", + }, + }; + case ActionConstants.LOAD_RECORD_ERROR: + return { + ...state, + recordLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_RECORD: + return { + ...state, + recordLoaded: {}, + }; + case ActionConstants.DELETE_RECORD_PENDING: + return { + ...state, + recordDeleted: { + status: ACTION_STATUS.PENDING, + key: action.key, + }, + recordsDeleting: state.recordsDeleting.concat(action.key), + }; + case ActionConstants.DELETE_RECORD_SUCCESS: + return { + ...state, + recordDeleted: { + status: ACTION_STATUS.SUCCESS, + record: action.record, + error: "", + }, + recordsDeleting: without(state.recordsDeleting, action.key), + }; + case ActionConstants.DELETE_RECORD_ERROR: + return { + ...state, + recordDeleted: { + status: ACTION_STATUS.ERROR, + record: action.record, + error: action.error, + }, + recordsDeleting: without(state.recordsDeleting, action.key), + }; + case ActionConstants.LOAD_FORMGEN_PENDING: + return { + ...state, + formgen: { + status: ACTION_STATUS.PENDING, + error: "", + }, + }; + case ActionConstants.LOAD_FORMGEN_SUCCESS: + return { + ...state, + formgen: { + status: ACTION_STATUS.SUCCESS, + error: "", + }, + }; + case ActionConstants.LOAD_FORMGEN_ERROR: + return { + ...state, + formgen: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/RecordsReducer.js b/src/reducers/RecordsReducer.js index 8a888af7..3e022f69 100644 --- a/src/reducers/RecordsReducer.js +++ b/src/reducers/RecordsReducer.js @@ -1,39 +1,39 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - recordsLoaded: {} + recordsLoaded: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.LOAD_RECORDS_PENDING: - return { - ...state, - recordsLoaded: { - ...state.recordsLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_RECORDS_SUCCESS: - return { - ...state, - recordsLoaded: { - status: ACTION_STATUS.SUCCESS, - records: action.records, - pageCount: action.pageCount, - error: '' - } - }; - case ActionConstants.LOAD_RECORDS_ERROR: - return { - ...state, - recordsLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.LOAD_RECORDS_PENDING: + return { + ...state, + recordsLoaded: { + ...state.recordsLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_RECORDS_SUCCESS: + return { + ...state, + recordsLoaded: { + status: ACTION_STATUS.SUCCESS, + records: action.records, + pageCount: action.pageCount, + error: "", + }, + }; + case ActionConstants.LOAD_RECORDS_ERROR: + return { + ...state, + recordsLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/RouterReducer.js b/src/reducers/RouterReducer.js index 67884628..aef84468 100644 --- a/src/reducers/RouterReducer.js +++ b/src/reducers/RouterReducer.js @@ -1,27 +1,27 @@ import * as ActionConstants from "../constants/ActionConstants"; const initialState = { - transitionPayload: {}, - viewHandlers: {} + transitionPayload: {}, + viewHandlers: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.SET_TRANSITION_PAYLOAD: - return { - ...state, - transitionPayload: { - [action.routeName]: action.payload - } - }; - case ActionConstants.SET_VIEW_HANDLERS: - return { - ...state, - viewHandlers: { - [action.routeName]: action.handlers - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.SET_TRANSITION_PAYLOAD: + return { + ...state, + transitionPayload: { + [action.routeName]: action.payload, + }, + }; + case ActionConstants.SET_VIEW_HANDLERS: + return { + ...state, + viewHandlers: { + [action.routeName]: action.handlers, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/StatisticsReducer.js b/src/reducers/StatisticsReducer.js index 643fb6b7..37db55a8 100644 --- a/src/reducers/StatisticsReducer.js +++ b/src/reducers/StatisticsReducer.js @@ -1,30 +1,30 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; -export default function (state = {data: undefined}, action) { - switch (action.type) { - case ActionConstants.LOAD_STATISTICS_PENDING: - return { - ...state, - status: ACTION_STATUS.PENDING, - error: undefined, - data: undefined - }; - case ActionConstants.LOAD_STATISTICS_SUCCESS: - return { - ...state, - status: ACTION_STATUS.SUCCESS, - error: undefined, - data: action.payload, - }; - case ActionConstants.LOAD_STATISTICS_ERROR: - return { - ...state, - status: ACTION_STATUS.ERROR, - error: action.error, - data: undefined - }; - default: - return state; - } +export default function (state = { data: undefined }, action) { + switch (action.type) { + case ActionConstants.LOAD_STATISTICS_PENDING: + return { + ...state, + status: ACTION_STATUS.PENDING, + error: undefined, + data: undefined, + }; + case ActionConstants.LOAD_STATISTICS_SUCCESS: + return { + ...state, + status: ACTION_STATUS.SUCCESS, + error: undefined, + data: action.payload, + }; + case ActionConstants.LOAD_STATISTICS_ERROR: + return { + ...state, + status: ACTION_STATUS.ERROR, + error: action.error, + data: undefined, + }; + default: + return state; + } } diff --git a/src/reducers/UserReducer.js b/src/reducers/UserReducer.js index 809f60b0..e95ee9d2 100644 --- a/src/reducers/UserReducer.js +++ b/src/reducers/UserReducer.js @@ -1,252 +1,252 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - userSaved: {}, - userDeleted: {}, - userLoaded: {}, - institutionMembers: {}, - passwordChange: {}, - generatedUsername: {}, - invitationSent: {}, - impersonation: {}, - invitationDelete: {} + userSaved: {}, + userDeleted: {}, + userLoaded: {}, + institutionMembers: {}, + passwordChange: {}, + generatedUsername: {}, + invitationSent: {}, + impersonation: {}, + invitationDelete: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.SAVE_USER_PENDING: - return { - ...state, - userSaved: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.SAVE_USER_SUCCESS: - return { - ...state, - userSaved: { - actionFlag: action.actionFlag, - status: ACTION_STATUS.SUCCESS, - user: action.user, - error: '' - } - }; - case ActionConstants.SAVE_USER_ERROR: - return { - ...state, - userSaved: { - actionFlag: action.actionFlag, - status: ACTION_STATUS.ERROR, - user: action.user, - error: action.error - } - }; - case ActionConstants.UNLOAD_SAVED_USER: - return { - ...state, - userSaved: { - status: state.userSaved.status - } - }; - case ActionConstants.DELETE_USER_PENDING: - return { - ...state, - userDeleted: { - status: ACTION_STATUS.PENDING, - username: action.username - } - }; - case ActionConstants.DELETE_USER_SUCCESS: - return { - ...state, - userDeleted: { - status: ACTION_STATUS.SUCCESS, - user: action.user, - error: '' - } - }; - case ActionConstants.DELETE_USER_ERROR: - return { - ...state, - userDeleted: { - status: ACTION_STATUS.ERROR, - user: action.user, - error: action.error - } - }; - case ActionConstants.LOAD_USER_PENDING: - return { - ...state, - userLoaded: { - ...state.userLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_USER_SUCCESS: - return { - ...state, - userLoaded: { - status: ACTION_STATUS.SUCCESS, - user: action.user, - error: '' - } - }; - case ActionConstants.LOAD_USER_ERROR: - return { - ...state, - userLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.UNLOAD_USER: - return { - ...state, - userLoaded: {} - }; - case ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING: - return { - ...state, - institutionMembers: { - ...state.institutionMembers, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS: - return { - ...state, - institutionMembers: { - status: ACTION_STATUS.SUCCESS, - members: action.members, - error: '' - } - }; - case ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR: - return { - ...state, - institutionMembers: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.UNLOAD_INSTITUTION_MEMBERS: - return { - ...state, - institutionMembers: {} - }; - case ActionConstants.PASSWORD_CHANGE_PENDING: - return { - ...state, - passwordChange: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.PASSWORD_CHANGE_SUCCESS: - return { - ...state, - passwordChange: { - status: ACTION_STATUS.SUCCESS, - error: '' - } - }; - case ActionConstants.PASSWORD_CHANGE_ERROR: - return { - ...state, - passwordChange: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.GENERATE_USERNAME_PENDING: - return { - ...state, - generatedUsername: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.GENERATE_USERNAME_SUCCESS: - return { - ...state, - generatedUsername: { - status: ACTION_STATUS.SUCCESS, - username: action.generatedUsername - } - }; - case ActionConstants.SEND_INVITATION_PENDING: - return { - ...state, - invitationSent: { - status: ACTION_STATUS.PENDING, - username: action.username - } - }; - case ActionConstants.SEND_INVITATION_SUCCESS: - return { - ...state, - invitationSent: { - status: ACTION_STATUS.SUCCESS, - username: action.username, - error: '' - } - }; - case ActionConstants.SEND_INVITATION_ERROR: - return { - ...state, - invitationSent: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.INVITATION_OPTION_DELETE_PENDING: - return { - ...state, - invitationDelete: { - status: ACTION_STATUS.PENDING, - username: action.username - } - }; - case ActionConstants.INVITATION_OPTION_DELETE_SUCCESS: - return { - ...state, - invitationDelete: { - status: ACTION_STATUS.SUCCESS, - username: action.username, - error: '' - } - }; - case ActionConstants.INVITATION_OPTION_DELETE_ERROR: - return { - ...state, - invitationDelete: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - case ActionConstants.IMPERSONATE_PENDING: - return { - ...state, - impersonation: { - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.IMPERSONATE_SUCCESS: - return { - ...state, - impersonation: { - status: ACTION_STATUS.SUCCESS, - username: action.username - } - }; - case ActionConstants.IMPERSONATE_ERROR: - return { - ...state, - impersonation: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.SAVE_USER_PENDING: + return { + ...state, + userSaved: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.SAVE_USER_SUCCESS: + return { + ...state, + userSaved: { + actionFlag: action.actionFlag, + status: ACTION_STATUS.SUCCESS, + user: action.user, + error: "", + }, + }; + case ActionConstants.SAVE_USER_ERROR: + return { + ...state, + userSaved: { + actionFlag: action.actionFlag, + status: ACTION_STATUS.ERROR, + user: action.user, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_SAVED_USER: + return { + ...state, + userSaved: { + status: state.userSaved.status, + }, + }; + case ActionConstants.DELETE_USER_PENDING: + return { + ...state, + userDeleted: { + status: ACTION_STATUS.PENDING, + username: action.username, + }, + }; + case ActionConstants.DELETE_USER_SUCCESS: + return { + ...state, + userDeleted: { + status: ACTION_STATUS.SUCCESS, + user: action.user, + error: "", + }, + }; + case ActionConstants.DELETE_USER_ERROR: + return { + ...state, + userDeleted: { + status: ACTION_STATUS.ERROR, + user: action.user, + error: action.error, + }, + }; + case ActionConstants.LOAD_USER_PENDING: + return { + ...state, + userLoaded: { + ...state.userLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_USER_SUCCESS: + return { + ...state, + userLoaded: { + status: ACTION_STATUS.SUCCESS, + user: action.user, + error: "", + }, + }; + case ActionConstants.LOAD_USER_ERROR: + return { + ...state, + userLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_USER: + return { + ...state, + userLoaded: {}, + }; + case ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING: + return { + ...state, + institutionMembers: { + ...state.institutionMembers, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS: + return { + ...state, + institutionMembers: { + status: ACTION_STATUS.SUCCESS, + members: action.members, + error: "", + }, + }; + case ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR: + return { + ...state, + institutionMembers: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.UNLOAD_INSTITUTION_MEMBERS: + return { + ...state, + institutionMembers: {}, + }; + case ActionConstants.PASSWORD_CHANGE_PENDING: + return { + ...state, + passwordChange: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.PASSWORD_CHANGE_SUCCESS: + return { + ...state, + passwordChange: { + status: ACTION_STATUS.SUCCESS, + error: "", + }, + }; + case ActionConstants.PASSWORD_CHANGE_ERROR: + return { + ...state, + passwordChange: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.GENERATE_USERNAME_PENDING: + return { + ...state, + generatedUsername: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.GENERATE_USERNAME_SUCCESS: + return { + ...state, + generatedUsername: { + status: ACTION_STATUS.SUCCESS, + username: action.generatedUsername, + }, + }; + case ActionConstants.SEND_INVITATION_PENDING: + return { + ...state, + invitationSent: { + status: ACTION_STATUS.PENDING, + username: action.username, + }, + }; + case ActionConstants.SEND_INVITATION_SUCCESS: + return { + ...state, + invitationSent: { + status: ACTION_STATUS.SUCCESS, + username: action.username, + error: "", + }, + }; + case ActionConstants.SEND_INVITATION_ERROR: + return { + ...state, + invitationSent: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.INVITATION_OPTION_DELETE_PENDING: + return { + ...state, + invitationDelete: { + status: ACTION_STATUS.PENDING, + username: action.username, + }, + }; + case ActionConstants.INVITATION_OPTION_DELETE_SUCCESS: + return { + ...state, + invitationDelete: { + status: ACTION_STATUS.SUCCESS, + username: action.username, + error: "", + }, + }; + case ActionConstants.INVITATION_OPTION_DELETE_ERROR: + return { + ...state, + invitationDelete: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + case ActionConstants.IMPERSONATE_PENDING: + return { + ...state, + impersonation: { + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.IMPERSONATE_SUCCESS: + return { + ...state, + impersonation: { + status: ACTION_STATUS.SUCCESS, + username: action.username, + }, + }; + case ActionConstants.IMPERSONATE_ERROR: + return { + ...state, + impersonation: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/UsersReducer.js b/src/reducers/UsersReducer.js index 8cc391ce..de0dc7b7 100644 --- a/src/reducers/UsersReducer.js +++ b/src/reducers/UsersReducer.js @@ -1,38 +1,38 @@ import * as ActionConstants from "../constants/ActionConstants"; -import {ACTION_STATUS} from "../constants/DefaultConstants"; +import { ACTION_STATUS } from "../constants/DefaultConstants"; const initialState = { - usersLoaded: {} + usersLoaded: {}, }; export default function (state = initialState, action) { - switch (action.type) { - case ActionConstants.LOAD_USERS_PENDING: - return { - ...state, - usersLoaded: { - ...state.usersLoaded, - status: ACTION_STATUS.PENDING - } - }; - case ActionConstants.LOAD_USERS_SUCCESS: - return { - ...state, - usersLoaded: { - status: ACTION_STATUS.SUCCESS, - users: action.users, - error: '' - } - }; - case ActionConstants.LOAD_USERS_ERROR: - return { - ...state, - usersLoaded: { - status: ACTION_STATUS.ERROR, - error: action.error - } - }; - default: - return state; - } -} \ No newline at end of file + switch (action.type) { + case ActionConstants.LOAD_USERS_PENDING: + return { + ...state, + usersLoaded: { + ...state.usersLoaded, + status: ACTION_STATUS.PENDING, + }, + }; + case ActionConstants.LOAD_USERS_SUCCESS: + return { + ...state, + usersLoaded: { + status: ACTION_STATUS.SUCCESS, + users: action.users, + error: "", + }, + }; + case ActionConstants.LOAD_USERS_ERROR: + return { + ...state, + usersLoaded: { + status: ACTION_STATUS.ERROR, + error: action.error, + }, + }; + default: + return state; + } +} diff --git a/src/reducers/index.js b/src/reducers/index.js index 8c944201..2e127f34 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,4 +1,4 @@ -import {combineReducers} from "redux"; +import { combineReducers } from "redux"; import UserReducer from "./UserReducer"; import UsersReducer from "./UsersReducer"; import AuthReducer from "./AuthReducer"; @@ -10,31 +10,31 @@ import RouterReducer from "./RouterReducer"; import HistoryReducer from "./HistoryReducer"; import * as ActionConstants from "../constants/ActionConstants"; import StatisticsReducer from "./StatisticsReducer"; -import IntlReducer from './IntlReducer'; +import IntlReducer from "./IntlReducer"; import FormTemplatesReducer from "./FormTemplatesReducer"; import MessageReducer from "./MessageReducer"; const rootReducer = (state, action) => { - if (action.type === ActionConstants.UNAUTH_USER) { - state = undefined - } - return appReducer(state, action); + if (action.type === ActionConstants.UNAUTH_USER) { + state = undefined; + } + return appReducer(state, action); }; const appReducer = combineReducers({ - intl: IntlReducer, - auth: AuthReducer, - user: UserReducer, - users: UsersReducer, - record: RecordReducer, - router: RouterReducer, - records: RecordsReducer, - formTemplates: FormTemplatesReducer, - history: HistoryReducer, - messages: MessageReducer, - statistics: StatisticsReducer, - institution: InstitutionReducer, - institutions: InstitutionsReducer + intl: IntlReducer, + auth: AuthReducer, + user: UserReducer, + users: UsersReducer, + record: RecordReducer, + router: RouterReducer, + records: RecordsReducer, + formTemplates: FormTemplatesReducer, + history: HistoryReducer, + messages: MessageReducer, + statistics: StatisticsReducer, + institution: InstitutionReducer, + institutions: InstitutionsReducer, }); -export default rootReducer; \ No newline at end of file +export default rootReducer; diff --git a/src/stores/I18nStore.js b/src/stores/I18nStore.js index 65913243..ba0aa6d6 100644 --- a/src/stores/I18nStore.js +++ b/src/stores/I18nStore.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Internationalization store for access from non-react components and objects. @@ -8,17 +8,17 @@ let _messages = []; let _intl = {}; export const setMessages = (messages) => { - _messages = messages; + _messages = messages; }; export const setIntl = (intl) => { - _intl = intl; + _intl = intl; }; export const i18n = (messageId) => { - return _messages[messageId]; + return _messages[messageId]; }; export const getIntl = () => { - return _intl; + return _intl; }; diff --git a/src/styles/record-manager.css b/src/styles/record-manager.css index 9ecb8995..52f088e5 100644 --- a/src/styles/record-manager.css +++ b/src/styles/record-manager.css @@ -1,878 +1,880 @@ @font-face { - font-family: 'glyphicons'; - src: url('../assets/fonts/glyphicons-halflings-regular.eot'); - src: url('../assets/fonts/glyphicons-halflings-regular.eot') format('embedded-opentype'), - url('../assets/fonts/glyphicons-halflings-regular.woff2') format('woff2'), - url('../assets/fonts/glyphicons-halflings-regular.woff') format('woff'), - url('../assets/fonts/glyphicons-halflings-regular.ttf') format('truetype'); - font-weight: normal; - font-style: normal; + font-family: "glyphicons"; + src: url("../assets/fonts/glyphicons-halflings-regular.eot"); + src: + url("../assets/fonts/glyphicons-halflings-regular.eot") format("embedded-opentype"), + url("../assets/fonts/glyphicons-halflings-regular.woff2") format("woff2"), + url("../assets/fonts/glyphicons-halflings-regular.woff") format("woff"), + url("../assets/fonts/glyphicons-halflings-regular.ttf") format("truetype"); + font-weight: normal; + font-style: normal; } html { - height: 100%; - margin: 0; - padding: 0; + height: 100%; + margin: 0; + padding: 0; } body { - height: 100%; - font-size: 0.8125rem; + height: 100%; + font-size: 0.8125rem; } /* TODO workaround for body rule */ .type-answer-group { - font-size: 1rem; + font-size: 1rem; } /* TODO workaround for body rule */ .form-label .question-header { - font-weight: 400; + font-weight: 400; } #root { - min-height: 100%; - height: 100%; + min-height: 100%; + height: 100%; } #footer { - height: 60px; - background-color: #f5f5f5; + height: 60px; + background-color: #f5f5f5; } .main-view-wrapper { - display: flex; - flex-direction: column; - min-height: 100%; + display: flex; + flex-direction: column; + min-height: 100%; } .page-wrapper { - flex: 1; - flex-shrink: 0; + flex: 1; + flex-shrink: 0; } .italics { - font-style: italic; + font-style: italic; } .bold { - font-weight: bold; + font-weight: bold; } .underline { - text-decoration: underline; + text-decoration: underline; } .container-fluid { - display: flex; - align-items: center; - justify-content: space-between; + display: flex; + align-items: center; + justify-content: space-between; } .container-fluid .text-muted { - margin: 20px 0 20px 15px; - vertical-align: middle; + margin: 20px 0 20px 15px; + vertical-align: middle; } .picker-container { - position: relative; + position: relative; } .unselectable { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; } .actions { - padding-left: 0.5em; - padding-right: 0.5em; + padding-left: 0.5em; + padding-right: 0.5em; } .large-modal { - width: 80%; - height: 80%; - max-height: 90%; + width: 80%; + height: 80%; + max-height: 90%; } .centered { - margin-left: auto; - margin-right: auto; + margin-left: auto; + margin-right: auto; } .content-center { - text-align: center; + text-align: center; } td.report-row { - vertical-align: middle !important; /* Use important to override bootstrap */ + vertical-align: middle !important; /* Use important to override bootstrap */ } .vertical-middle { - vertical-align: middle; + vertical-align: middle; } td.actions { - vertical-align: middle; - text-align: center; + vertical-align: middle; + text-align: center; } td.actions button { - margin: 5px; - min-width: 4.5rem; + margin: 5px; + min-width: 4.5rem; } .action-button { - min-width: 4.5rem; + min-width: 4.5rem; } .login-panel { - width: 400px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); + width: 400px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } .login-buttons { - display: table; - margin: 0 auto; + display: table; + margin: 0 auto; } .login-forgot-password-block { - text-align: right; - width: 100%; + text-align: right; + width: 100%; } .login-forgot-password { - margin-top: -25px; - position: relative; - border: none; + margin-top: -25px; + position: relative; + border: none; } @media screen and (max-width: 480px) { - .login-panel { - width: 300px; - } + .login-panel { + width: 300px; + } - .container-fluid .text-muted { - margin: 20px 0 0 0; - } + .container-fluid .text-muted { + margin: 20px 0 0 0; + } } .register-panel { - width: 800px; - height: 275px; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; + width: 800px; + height: 275px; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; } .register-panel.expanded { - height: 345px; + height: 345px; } .mask { - position: fixed; - padding: 0; - margin: 0; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(245, 245, 245, 0.6); - z-index: 101; + position: fixed; + padding: 0; + margin: 0; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(245, 245, 245, 0.6); + z-index: 101; } /* This mask covers a container instead of the whole viewport */ .mask-container { - position: absolute; - padding: 0; - margin: 0; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(245, 245, 245, 0.6); - z-index: 101; + position: absolute; + padding: 0; + margin: 0; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(245, 245, 245, 0.6); + z-index: 101; } .spinner-container { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - height: 50px; - text-align: center; - vertical-align: middle; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + height: 50px; + text-align: center; + vertical-align: middle; } .spinner-container .spinner-message { - color: #337ab7; - font-size: 11px; + color: #337ab7; + font-size: 11px; } .dashboard-sector { - text-align: center; - vertical-align: middle; - padding: 0.5em; - float: left; + text-align: center; + vertical-align: middle; + padding: 0.5em; + float: left; } .dashboard-sector-search { - text-align: center; - vertical-align: top; - margin-top: -2.8em; - padding-left: 0.5em; - padding-right: 0.5em; + text-align: center; + vertical-align: top; + margin-top: -2.8em; + padding-left: 0.5em; + padding-right: 0.5em; } .dashboard-tile { - min-height: 7em; - width: 100%; - max-width: 15em; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3; - border-radius: 6px; - white-space: normal; + min-height: 7em; + width: 100%; + max-width: 15em; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3; + border-radius: 6px; + white-space: normal; } @media screen and (min-width: 576px) and (max-width: 992px) { - .container { - width: 100%; - max-width: initial; - } + .container { + width: 100%; + max-width: initial; + } } @media screen and (max-width: 768px) { - .dashboard-tile { - min-height: 5em; - } + .dashboard-tile { + min-height: 5em; + } - .formatted-message-size { - font-size: 150%; - } + .formatted-message-size { + font-size: 150%; + } } @media screen and (max-width: 576px) { - .dashboard-tile { - min-height: 3em; - } + .dashboard-tile { + min-height: 3em; + } - .formatted-message-size { - font-size: 130%; - } + .formatted-message-size { + font-size: 130%; + } } @media screen and (max-width: 400px) { - .navbar-brand { - font-size: 14px; - } + .navbar-brand { + font-size: 14px; + } } @media screen and (min-width: 768px) and (max-width: 850px) { - .navbar-brand { - padding-right: 10px; - padding-left: 10px; - font-size: 15px; - } - - #logout { - padding-right: 12px; - padding-left: 12px; - width: 120px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } + .navbar-brand { + padding-right: 10px; + padding-left: 10px; + font-size: 15px; + } + + #logout { + padding-right: 12px; + padding-left: 12px; + width: 120px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } } .dashboard-report-search { - width: 350px; - margin: 0 auto; + width: 350px; + margin: 0 auto; } .dashboard-report-search-results { - text-align: left; - width: 350px; - margin-left: auto; - margin-right: auto; - left: 0; - right: 0; + text-align: left; + width: 350px; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; } /* Overriding bootstrap primary panel border color */ .panel-primary { - border-color: #bce8f1; + border-color: #bce8f1; } .factor-root-event { - font-size: 110%; - font-weight: bold; - background-color: #286090; - border: 1px solid #204d74; + font-size: 110%; + font-weight: bold; + background-color: #286090; + border: 1px solid #204d74; } .factor-event-type { - background-color: #777; - border: 1px solid #666; + background-color: #777; + border: 1px solid #666; } .factor-descriptive-factor { - background-color: #449d44; - border: 1px solid #398439; + background-color: #449d44; + border: 1px solid #398439; } ul.event-type { - list-style-type: none; + list-style-type: none; } .event-type-label { - display: inline-block; - margin-top: 0.8em; + display: inline-block; + margin-top: 0.8em; } .notice-small { - font-size: 86%; - font-style: italic; - margin-bottom: 0.5em; + font-size: 86%; + font-style: italic; + margin-bottom: 0.5em; } @media screen and (min-width: 1199px) { - .notice-small { - margin-left: 4.7%; - } + .notice-small { + margin-left: 4.7%; + } } .report-type-icon { - width: 24px; - height: 24px; + width: 24px; + height: 24px; } .selected-revision { - text-decoration: underline; - font-weight: bold; - color: #337ab7; + text-decoration: underline; + font-weight: bold; + color: #337ab7; } .filter td { - color: #31708f; - background-color: #d9edf7; - margin-left: auto; - margin-right: auto; - border: 1px solid #bce8f1; - border-radius: 3px 3px 0 0; - padding: 3px 3px 3px 3px !important; - text-align: center; + color: #31708f; + background-color: #d9edf7; + margin-left: auto; + margin-right: auto; + border: 1px solid #bce8f1; + border-radius: 3px 3px 0 0; + padding: 3px 3px 3px 3px !important; + text-align: center; } .filter-label { - margin-top: 6px; - margin-right: 0.5em; + margin-top: 6px; + margin-right: 0.5em; } .no-reports-notice { - margin-top: 1em; + margin-top: 1em; } button.reset-filters { - margin-left: 0.5em; - margin-right: 0.5em; + margin-left: 0.5em; + margin-right: 0.5em; } .filter td select { - margin-bottom: -15px !important; + margin-bottom: -15px !important; } .external-link { - display: block; - content: url('../assets/icons/external.png'); - width: 16px; - height: 16px; - margin-top: 28px; - margin-left: -20px; - vertical-align: bottom; + display: block; + content: url("../assets/icons/external.png"); + width: 16px; + height: 16px; + margin-top: 28px; + margin-left: -20px; + vertical-align: bottom; } .external-link-factor-detail { - margin-top: 7px; + margin-top: 7px; } .external-link-gantt { - content: url('../assets/icons/external.png'); - width: 16px; - height: 16px; - margin-top: 0.7em; + content: url("../assets/icons/external.png"); + width: 16px; + height: 16px; + margin-top: 0.7em; } .table-sorter-wrapper { - position: relative !important; + position: relative !important; } .dropzone { - border-radius: 6px; - color: #fff; - background-color: #337ab7; - border: 2px dashed #adadad; - min-height: 7.5em; - width: 100%; - max-width: 20em; - padding: 10px 16px; - line-height: 1.3; - cursor: pointer; - display: inline-block; + border-radius: 6px; + color: #fff; + background-color: #337ab7; + border: 2px dashed #adadad; + min-height: 7.5em; + width: 100%; + max-width: 20em; + padding: 10px 16px; + line-height: 1.3; + cursor: pointer; + display: inline-block; } .dropzone-active { - border-radius: 6px; - color: #fff; - background-color: #337ab7; - border: 2px solid #adadad; - min-height: 7.5em; - width: 100%; - max-width: 20em; - padding: 10px 16px; - line-height: 1.3; - cursor: pointer; - display: inline-block; + border-radius: 6px; + color: #fff; + background-color: #337ab7; + border: 2px solid #adadad; + min-height: 7.5em; + width: 100%; + max-width: 20em; + padding: 10px 16px; + line-height: 1.3; + cursor: pointer; + display: inline-block; } .dropzone .message { - margin: 2em 0 1.3em 0; - vertical-align: bottom; + margin: 2em 0 1.3em 0; + vertical-align: bottom; } .import-error { - margin: 15px 15px -35px 15px; + margin: 15px 15px -35px 15px; } .paging-item-count-info { - margin-top: -1.2em; - margin-bottom: 1.2em; + margin-top: -1.2em; + margin-bottom: 1.2em; } .buttons-right { - margin-top: 1em; - margin-bottom: 0.5em; + margin-top: 1em; + margin-bottom: 0.5em; } .help-icon { - margin-top: 7px + margin-top: 7px; } button .help-icon { - color: black; - margin-left: 5px; - margin-top: 0px; + color: black; + margin-left: 5px; + margin-top: 0px; } @media screen and (max-width: 992px) { - .help-icon { - margin-top: 35px - } + .help-icon { + margin-top: 35px; + } } .font-italic { - font-style: italic; + font-style: italic; } .loader { - border: 2px solid #f3f3f3; - border-radius: 50%; - border-top: 2px solid #3498db; - width: 12px; - height: 12px; - -webkit-animation: spin 2s linear infinite; /* Safari */ - animation: spin 2s linear infinite; - display: inline-block; - margin-left: 4px; + border: 2px solid #f3f3f3; + border-radius: 50%; + border-top: 2px solid #3498db; + width: 12px; + height: 12px; + -webkit-animation: spin 2s linear infinite; /* Safari */ + animation: spin 2s linear infinite; + display: inline-block; + margin-left: 4px; } /* Safari */ @-webkit-keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - } + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } } @keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } .alert-position-down { - margin-top: 18px; - margin-bottom: 4px; + margin-top: 18px; + margin-bottom: 4px; } @media screen and (max-width: 1199px) { - .alert-position-top { - margin-bottom: 0px; - } + .alert-position-top { + margin-bottom: 0px; + } } .loader-spin { - overflow: hidden; - margin: 0 auto; - height: 60px; - width: 108px; - position: relative; + overflow: hidden; + margin: 0 auto; + height: 60px; + width: 108px; + position: relative; } .circle { - border-radius: 50%; - height: 25px; - width: 25px; - float: left; - margin-right: 12.5px; + border-radius: 50%; + height: 25px; + width: 25px; + float: left; + margin-right: 12.5px; } .loading-icon { - width: 150px; /* 4*size + 4*space */ - height: 25px; - display: inline-flex; + width: 150px; /* 4*size + 4*space */ + height: 25px; + display: inline-flex; } @keyframes circleOneAnimation { - 0% { - transform: translate(0px) scale(1); - opacity: 1 - } - 12.5% { - transform: translate(0px); - } - 25% { - transform: translate(37.5px); - } - 37.5% { - transform: translate(37.5px); - } - 50% { - transform: translate(75px); - } - 62.5% { - transform: translate(75px); - } - 68% { - transform: translate(75px) scale(0.1); - opacity: 1 - } - 68.1% { - opacity: 0 - } - 87.5% { - transform: translate(0px) scale(0.1); - opacity: 0 - } + 0% { + transform: translate(0px) scale(1); + opacity: 1; + } + 12.5% { + transform: translate(0px); + } + 25% { + transform: translate(37.5px); + } + 37.5% { + transform: translate(37.5px); + } + 50% { + transform: translate(75px); + } + 62.5% { + transform: translate(75px); + } + 68% { + transform: translate(75px) scale(0.1); + opacity: 1; + } + 68.1% { + opacity: 0; + } + 87.5% { + transform: translate(0px) scale(0.1); + opacity: 0; + } } @keyframes circleTwoAnimation { - 0% { - transform: translate(0px); - } - 12.5% { - transform: translate(0px); - } - 25% { - transform: translate(37.5px); - } - 37.5% { - transform: translate(37.5px); - } - 43% { - transform: translate(37.5px) scale(0.1); - opacity: 1; - } - 43.1% { - opacity: 0; - } - 62.5% { - transform: translate(-37.5px) scale(0.1); - opacity: 0 - } - 75% { - transform: translate(-37.5px) scale(1); - opacity: 1 - } - 87.5% { - transform: translate(-37.5px); - } + 0% { + transform: translate(0px); + } + 12.5% { + transform: translate(0px); + } + 25% { + transform: translate(37.5px); + } + 37.5% { + transform: translate(37.5px); + } + 43% { + transform: translate(37.5px) scale(0.1); + opacity: 1; + } + 43.1% { + opacity: 0; + } + 62.5% { + transform: translate(-37.5px) scale(0.1); + opacity: 0; + } + 75% { + transform: translate(-37.5px) scale(1); + opacity: 1; + } + 87.5% { + transform: translate(-37.5px); + } } @keyframes circleThreeAnimation { - 0% { - transform: translate(0px); - } - 12.5% { - transform: translate(0px); - } - 18% { - transform: translate(0px, 0px) scale(0.1); - opacity: 1; - } - 18.1% { - opacity: 0; - } - 37.5% { - transform: translate(-75px) scale(0.1); - opacity: 0 - } - 50% { - transform: translate(-75px) scale(1); - opacity: 1 - } - 62.5% { - transform: translate(-75px); - } - 75% { - transform: translate(-37.5px); - } - 87.5% { - transform: translate(-37.5px); - } - 100% { - transform: translate(0px); - } + 0% { + transform: translate(0px); + } + 12.5% { + transform: translate(0px); + } + 18% { + transform: translate(0px, 0px) scale(0.1); + opacity: 1; + } + 18.1% { + opacity: 0; + } + 37.5% { + transform: translate(-75px) scale(0.1); + opacity: 0; + } + 50% { + transform: translate(-75px) scale(1); + opacity: 1; + } + 62.5% { + transform: translate(-75px); + } + 75% { + transform: translate(-37.5px); + } + 87.5% { + transform: translate(-37.5px); + } + 100% { + transform: translate(0px); + } } @keyframes circleFourAnimation { - 0% { - transform: translate(-112.5px); - opacity: 0; - } - 12.5% { - transform: translate(-112.5px) scale(0.1);; - opacity: 0; - } - 25% { - transform: translate(-112.5px) scale(1); - opacity: 1; - } - 37.5% { - transform: translate(-112.5px); - } - 50% { - transform: translate(-75px); - } - 62.5% { - transform: translate(-75px); - } - 75% { - transform: translate(-37.5px); - } - 87.5% { - transform: translate(-37.5px); - } - 92.5% { - transform: translate(-37.5px) scale(0.1); - opacity: 1; - } - 92.51% { - transform: translate(-37.5px) scale(0.1); - opacity: 0; - } - 100% { - opacity: 0; - } + 0% { + transform: translate(-112.5px); + opacity: 0; + } + 12.5% { + transform: translate(-112.5px) scale(0.1); + opacity: 0; + } + 25% { + transform: translate(-112.5px) scale(1); + opacity: 1; + } + 37.5% { + transform: translate(-112.5px); + } + 50% { + transform: translate(-75px); + } + 62.5% { + transform: translate(-75px); + } + 75% { + transform: translate(-37.5px); + } + 87.5% { + transform: translate(-37.5px); + } + 92.5% { + transform: translate(-37.5px) scale(0.1); + opacity: 1; + } + 92.51% { + transform: translate(-37.5px) scale(0.1); + opacity: 0; + } + 100% { + opacity: 0; + } } .loader-spin .circle1 { - background-color: #007bff; - animation: circleOneAnimation 3s infinite; + background-color: #007bff; + animation: circleOneAnimation 3s infinite; } .loader-spin .circle2 { - background-color: #d9edf7; - animation: circleTwoAnimation 3s infinite; + background-color: #d9edf7; + animation: circleTwoAnimation 3s infinite; } .loader-spin .circle3 { - background-color: #007bff; - animation: circleThreeAnimation 3s infinite; + background-color: #007bff; + animation: circleThreeAnimation 3s infinite; } .loader-spin .circle4 { - background-color: #d9edf7; - animation: circleFourAnimation 3s infinite; + background-color: #d9edf7; + animation: circleFourAnimation 3s infinite; } .input-group-addon { - padding: 0; + padding: 0; } .history-search { - width: 400px; - margin: 0 auto 15px; + width: 400px; + margin: 0 auto 15px; } @media screen and (max-width: 600px) { - .history-search { - width: 300px; - margin: 0 auto 15px; - } + .history-search { + width: 300px; + margin: 0 auto 15px; + } } .invite-to-study-text { - line-height: 1.8; + line-height: 1.8; } .buttons-line-height { - line-height: 2.6; + line-height: 2.6; } .navbar-brand { - cursor: pointer; + cursor: pointer; } .w-15 { - width: 10%; + width: 10%; } .w-20 { - width: 20%; + width: 20%; } .w-26 { - width: 26.66%; + width: 26.66%; } .w-30 { - width: 30%; + width: 30%; } .w-33 { - width: 33.33%; + width: 33.33%; } .w-40 { - width: 40%; + width: 40%; } header { - background-color: #F8F8F8; + background-color: #f8f8f8; } .nav-item { - font-size: 0.875rem; - padding: 0 0.5rem; + font-size: 0.875rem; + padding: 0 0.5rem; } .navbar-brand { - font-size: 1.125rem + font-size: 1.125rem; } -.form-control, .dropdown-menu { - font-size: 0.8125rem; +.form-control, +.dropdown-menu { + font-size: 0.8125rem; } .list-group-item { - cursor: pointer; + cursor: pointer; } .answerable-section .form-group .form-check-label { - font-size: 1rem; + font-size: 1rem; } .nav-badge { - height: fit-content; - padding: 0.25rem; - margin-top: auto; - margin-bottom: auto; + height: fit-content; + padding: 0.25rem; + margin-top: auto; + margin-bottom: auto; } .file-upload-dropzone { - min-height: calc(4em + 0.75rem + 2px); - border: 1px solid #ced4da; - border-radius: 0.2rem; - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - padding-top: 0.5rem; + min-height: calc(4em + 0.75rem + 2px); + border: 1px solid #ced4da; + border-radius: 0.2rem; + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + padding-top: 0.5rem; } .file-upload-dropzone.active { - min-height: calc(4em + 0.75rem + 2px); - border-radius: 0.2rem; - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - padding-top: 0.5rem; - border: 1px solid #007bff; + min-height: calc(4em + 0.75rem + 2px); + border-radius: 0.2rem; + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + padding-top: 0.5rem; + border: 1px solid #007bff; } .file-upload-dropzone .placeholder-text { - color: #6c757d; + color: #6c757d; } .file-upload-dropzone.active .placeholder-text { - color: #007bff; + color: #007bff; } .file-upload-dropzone .icon-container { - margin-top: -0.5rem; + margin-top: -0.5rem; } .message-container { - width: 25%; - min-width: 220px; - height: 25%; - position: fixed; - top: 60px; - right: 10px; - margin: auto; - z-index: 1030; + width: 25%; + min-width: 220px; + height: 25%; + position: fixed; + top: 60px; + right: 10px; + margin: auto; + z-index: 1030; } @media screen and (min-width: 768px) { - .message-container { - top: 50px; - right: 20px; - } + .message-container { + top: 50px; + right: 20px; + } } .messages-0 { - height: 0; + height: 0; } .messages-1 { - height: 4.125rem; + height: 4.125rem; } .messages-2 { - height: 8.25rem; + height: 8.25rem; } .messages-3 { - height: 12.375rem; + height: 12.375rem; } .messages-4 { - height: 16.5rem; + height: 16.5rem; } .messages-5 { - height: 20.625rem; + height: 20.625rem; } .record-filters-popup { - min-width: 300px; + min-width: 300px; } .filter-datetimepicker { - max-width: 120px; + max-width: 120px; } diff --git a/src/utils/BrowserCompatibilityModal.jsx b/src/utils/BrowserCompatibilityModal.jsx index 248dd508..30b60b70 100644 --- a/src/utils/BrowserCompatibilityModal.jsx +++ b/src/utils/BrowserCompatibilityModal.jsx @@ -17,13 +17,11 @@ export const BrowserCompatibilityModal = () => { setIsSupported(supported); }, []); - const supportedBrowserList = Object.entries(SUPPORTED_BROWSERS).map( - ([browserName, minVersion]) => ( -
  • - {browserName}: {minVersion} -
  • - ) - ); + const supportedBrowserList = Object.entries(SUPPORTED_BROWSERS).map(([browserName, minVersion]) => ( +
  • + {browserName}: {minVersion} +
  • + )); return ( @@ -32,9 +30,8 @@ export const BrowserCompatibilityModal = () => {

    - Your browser is not fully supported! Some parts of the web may not - work properly. We recommend using the latest version of Chrome, - Firefox, Safari, or Edge. + Your browser is not fully supported! Some parts of the web may not work properly. We recommend using the + latest version of Chrome, Firefox, Safari, or Edge.

    List of supported browsers:

      {supportedBrowserList}
    diff --git a/src/utils/BrowserStorage.js b/src/utils/BrowserStorage.js index b5f7777b..12f0f5db 100644 --- a/src/utils/BrowserStorage.js +++ b/src/utils/BrowserStorage.js @@ -2,18 +2,18 @@ * Represent an interface to the browser-based storage */ const BrowserStorage = { - set(key, value) { - localStorage.setItem(key, value); - }, + set(key, value) { + localStorage.setItem(key, value); + }, - get(key, defaultValue = null) { - const result = localStorage.getItem(key); - return result != null ? result : defaultValue; - }, + get(key, defaultValue = null) { + const result = localStorage.getItem(key); + return result != null ? result : defaultValue; + }, - remove(key) { - localStorage.removeItem(key); - }, + remove(key) { + localStorage.removeItem(key); + }, }; export default BrowserStorage; diff --git a/src/utils/DataFilter.js b/src/utils/DataFilter.js index a0b57071..6bb29c25 100644 --- a/src/utils/DataFilter.js +++ b/src/utils/DataFilter.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Filters data according to specified filter(s). @@ -9,35 +9,38 @@ */ const filterData = (data, filter) => { - if (this._canSkipFilter(filter)) { - return data; + if (this._canSkipFilter(filter)) { + return data; + } + return data.filter(function (item) { + for (let key in filter) { + if (filter[key] === "all") { + continue; + } + const path = key.split("."); + let value = item; + for (let i = 0, len = path.length; i < len; i++) { + value = value[path[i]]; + } + if ( + (Array.isArray(value) && value.indexOf(filter[key]) === -1) || + (!Array.isArray(value) && value !== filter[key]) + ) { + return false; + } } - return data.filter(function (item) { - for (let key in filter) { - if (filter[key] === 'all') { - continue; - } - const path = key.split('.'); - let value = item; - for (let i = 0, len = path.length; i < len; i++) { - value = value[path[i]]; - } - if ((Array.isArray(value) && value.indexOf(filter[key]) === -1) || (!Array.isArray(value) && value !== filter[key])) { - return false; - } - } - return true; - }); + return true; + }); }; const _canSkipFilter = (filter) => { - if (!filter) { - return true; - } - for (let key in filter) { - if (filter[key] !== 'all') { - return false; - } - } + if (!filter) { return true; + } + for (let key in filter) { + if (filter[key] !== "all") { + return false; + } + } + return true; }; diff --git a/src/utils/EntityFactory.js b/src/utils/EntityFactory.js index 63184492..50cb95f7 100644 --- a/src/utils/EntityFactory.js +++ b/src/utils/EntityFactory.js @@ -1,45 +1,45 @@ -'use strict'; +"use strict"; import * as Utils from "./Utils"; import * as RecordState from "../model/RecordState"; import * as Vocabulary from "../constants/Vocabulary"; -import {RECORD_PHASE} from "../constants/DefaultConstants"; +import { RECORD_PHASE } from "../constants/DefaultConstants"; export function initNewUser() { - return { - firstName: '', - lastName: '', - username: '', - emailAddress: '', - password: Utils.generatePassword(), - types: [Vocabulary.DOCTOR_TYPE], - isNew: true - }; + return { + firstName: "", + lastName: "", + username: "", + emailAddress: "", + password: Utils.generatePassword(), + types: [Vocabulary.DOCTOR_TYPE], + isNew: true, + }; } export function initNewInstitution() { - return { - name: '', - emailAddress: '', - isNew: true - } + return { + name: "", + emailAddress: "", + isNew: true, + }; } export function initNewPatientRecord() { - return { - localName: '', - formTemplate: '', - complete: false, - isNew: true, - state: RecordState.createRecordState(), - phase: RECORD_PHASE.OPEN - } + return { + localName: "", + formTemplate: "", + complete: false, + isNew: true, + state: RecordState.createRecordState(), + phase: RECORD_PHASE.OPEN, + }; } export function initNewPassword() { - return { - currentPassword: '', - newPassword: '', - confirmPassword: '' - } + return { + currentPassword: "", + newPassword: "", + confirmPassword: "", + }; } diff --git a/src/utils/HistoryLogger.js b/src/utils/HistoryLogger.js index 5dd2a1d7..d853c252 100644 --- a/src/utils/HistoryLogger.js +++ b/src/utils/HistoryLogger.js @@ -1,29 +1,29 @@ -import {logAction} from "../actions/HistoryActions"; -import {SCRIPT_ERROR} from "../constants/DefaultConstants"; +import { logAction } from "../actions/HistoryActions"; +import { SCRIPT_ERROR } from "../constants/DefaultConstants"; -export const historyLogger = store => next => action => { - if (store.getState().auth.isLoaded) { - logAction(action, store.getState().auth.user, Date.now()); - } else { - logAction(action, null, Date.now()); - } - return next(action) +export const historyLogger = (store) => (next) => (action) => { + if (store.getState().auth.isLoaded) { + logAction(action, store.getState().auth.user, Date.now()); + } else { + logAction(action, null, Date.now()); + } + return next(action); }; export function errorLogger(message, line, store) { - const height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; - const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; - const error = { - type: SCRIPT_ERROR, - message, - line, - url: window.location.href, - viewport: `${width}x${height}`, - userAgent: window.navigator.userAgent - }; - if (store.getState().auth.isLoaded) { - logAction(error, store.getState().auth.user, Date.now()); - } else { - logAction(error, null, Date.now()); - } -} \ No newline at end of file + const height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; + const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; + const error = { + type: SCRIPT_ERROR, + message, + line, + url: window.location.href, + viewport: `${width}x${height}`, + userAgent: window.navigator.userAgent, + }; + if (store.getState().auth.isLoaded) { + logAction(error, store.getState().auth.user, Date.now()); + } else { + logAction(error, null, Date.now()); + } +} diff --git a/src/utils/Logger.js b/src/utils/Logger.js index 8e06d8b9..387f05b6 100644 --- a/src/utils/Logger.js +++ b/src/utils/Logger.js @@ -1,23 +1,21 @@ -'use strict'; +"use strict"; export function log(msg) { - console.log(msg); + console.log(msg); } export function warn(msg) { - if (console.warn) { - console.warn(msg); - } else { - console.log('WARNING: ' + msg); - } + if (console.warn) { + console.warn(msg); + } else { + console.log("WARNING: " + msg); + } } -export function error (msg) { - if (console.error) { - console.error(msg); - } else { - console.log('ERROR: ' + msg); - } +export function error(msg) { + if (console.error) { + console.error(msg); + } else { + console.log("ERROR: " + msg); + } } - - diff --git a/src/utils/OidcUtils.js b/src/utils/OidcUtils.js index f98396f8..678ae245 100644 --- a/src/utils/OidcUtils.js +++ b/src/utils/OidcUtils.js @@ -1,8 +1,8 @@ // Taken from https://github.com/datagov-cz/assembly-line-shared but using a different config processing mechanism -import {getEnv} from "../../config"; +import { getEnv } from "../../config"; import Routes from "../constants/RoutesConstants"; -import {UserManager} from "oidc-client"; +import { UserManager } from "oidc-client"; // Singleton UserManager instance let userManager; @@ -34,9 +34,7 @@ export const getOidcConfig = () => { return { authority: getEnv("AUTH_SERVER_URL"), client_id: clientId, - redirect_uri: `${baseUrl}/oidc-signin-callback?forward_uri=${encodeForwardUri( - baseUrl - )}`, + redirect_uri: `${baseUrl}/oidc-signin-callback?forward_uri=${encodeForwardUri(baseUrl)}`, silent_redirect_uri: `${baseUrl}/oidc-silent-callback`, post_logout_redirect_uri: `${baseUrl}/${Routes.dashboard.path}`, response_type: "code", @@ -58,15 +56,13 @@ function resolveUrl() { export const userProfileLink = () => { return `${getEnv("AUTH_SERVER_URL")}/account`; -} +}; /** * Helper to generate redirect Uri */ export const generateRedirectUri = (forwardUri) => { - return `${resolveUrl()}/oidc-signin-callback?forward_uri=${encodeForwardUri( - forwardUri - )}`; + return `${resolveUrl()}/oidc-signin-callback?forward_uri=${encodeForwardUri(forwardUri)}`; }; /** diff --git a/src/utils/Routes.jsx b/src/utils/Routes.jsx index 50efda65..79d2cf15 100644 --- a/src/utils/Routes.jsx +++ b/src/utils/Routes.jsx @@ -1,70 +1,51 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {Redirect, Route, Switch} from 'react-router-dom'; -import PasswordToken from '../components/login/PasswordToken'; -import PasswordReset from '../components/login/PasswordReset'; -import Login from '../components/login/Login'; -import Logout from '../components/login/Logout'; -import requireAuth from '../components/misc/hoc/RequireAuth'; -import UsersController from '../components/user/UsersController'; -import UserController from '../components/user/UserController'; -import PasswordChangeController from '../components/user/PasswordChangeController'; -import Statistics from '../components/statistics/Statistics'; -import InstitutionsController from '../components/institution/InstitutionsController'; -import InstitutionController from '../components/institution/InstitutionController'; -import RecordsController from '../components/record/RecordsController'; -import RecordController from '../components/record/RecordController'; -import HistoryActions from '../components/history/HistoryList'; -import HistoryAction from '../components/history/HistoryDetail'; -import DashboardController from '../components/dashboard/DashboardController'; -import Routes from '../constants/RoutesConstants'; +import React from "react"; +import { Redirect, Route, Switch } from "react-router-dom"; +import PasswordToken from "../components/login/PasswordToken"; +import PasswordReset from "../components/login/PasswordReset"; +import Login from "../components/login/Login"; +import Logout from "../components/login/Logout"; +import requireAuth from "../components/misc/hoc/RequireAuth"; +import UsersController from "../components/user/UsersController"; +import UserController from "../components/user/UserController"; +import PasswordChangeController from "../components/user/PasswordChangeController"; +import Statistics from "../components/statistics/Statistics"; +import InstitutionsController from "../components/institution/InstitutionsController"; +import InstitutionController from "../components/institution/InstitutionController"; +import RecordsController from "../components/record/RecordsController"; +import RecordController from "../components/record/RecordController"; +import HistoryActions from "../components/history/HistoryList"; +import HistoryAction from "../components/history/HistoryDetail"; +import DashboardController from "../components/dashboard/DashboardController"; +import Routes from "../constants/RoutesConstants"; export const unauthRoutes = ( - - - - - - ); + + + + + + +); export const authRoutes = ( - - - - - - - - - - - - ( - - )}> - - ( - - )}> - - - - - - -); \ No newline at end of file + + + + + + + + + + + + }> + }> + + + + + +); diff --git a/src/utils/Routing.js b/src/utils/Routing.js index d3d7f714..3aaf3c9c 100644 --- a/src/utils/Routing.js +++ b/src/utils/Routing.js @@ -1,14 +1,14 @@ -'use strict'; +"use strict"; -import {execute} from "./RoutingRules"; -import {setTransitionPayload} from "../actions/RouterActions"; -import {createBrowserHistory} from 'history'; -import {setViewHandlers} from "../actions/RouterActions"; +import { execute } from "./RoutingRules"; +import { setTransitionPayload } from "../actions/RouterActions"; +import { createBrowserHistory } from "history"; +import { setViewHandlers } from "../actions/RouterActions"; import * as Constants from "../constants/DefaultConstants"; -import {BASENAME} from "../../config"; +import { BASENAME } from "../../config"; export const history = createBrowserHistory({ - basename: BASENAME + basename: BASENAME, }); /** @@ -16,11 +16,11 @@ export const history = createBrowserHistory({ * @param route Route object */ export function transitionTo(route) { - let path = route.path; - execute(route.name); - history.push({ - pathname: path, - }); + let path = route.path; + execute(route.name); + history.push({ + pathname: path, + }); } /** @@ -29,44 +29,43 @@ export function transitionTo(route) { * @param options Transition options, can specify path parameters, query parameters, payload and view handlers. */ export function transitionToWithOpts(route, options) { - return function (dispatch) { - let path = route.path; - if (!options) { - options = {}; - } - if (options.params) { - path = setPathParams(path, options.params); - } - if (options.query) { - path = setQueryParams(path, options.query); - } - if (options.payload) { - dispatch(setTransitionPayload(route.name, options.payload)); - } - if (options.handlers) { - dispatch(setViewHandlers(route.name, options.handlers)); - } - execute(route.name); - history.push(path); + return function (dispatch) { + let path = route.path; + if (!options) { + options = {}; + } + if (options.params) { + path = setPathParams(path, options.params); + } + if (options.query) { + path = setQueryParams(path, options.query); } + if (options.payload) { + dispatch(setTransitionPayload(route.name, options.payload)); + } + if (options.handlers) { + dispatch(setViewHandlers(route.name, options.handlers)); + } + execute(route.name); + history.push(path); + }; } // TODO function setPathParams(path, params) { - for (let paramName in params) { - if (params.hasOwnProperty(paramName)) { - path = path.replace(':' + paramName, params[paramName]); - } + for (let paramName in params) { + if (params.hasOwnProperty(paramName)) { + path = path.replace(":" + paramName, params[paramName]); } - return path; + } + return path; } function setQueryParams(path, params) { - const paramValuePairs = Array.from(params.entries()).map((pair) => pair[0] + "=" + pair[1]); - return paramValuePairs.length > 0 ? path + "?" + paramValuePairs.join("&") : path; + const paramValuePairs = Array.from(params.entries()).map((pair) => pair[0] + "=" + pair[1]); + return paramValuePairs.length > 0 ? path + "?" + paramValuePairs.join("&") : path; } export function transitionToHome() { - transitionTo(Constants.HOME_ROUTE); + transitionTo(Constants.HOME_ROUTE); } - diff --git a/src/utils/RoutingRules.js b/src/utils/RoutingRules.js index 6f199677..35d7d069 100644 --- a/src/utils/RoutingRules.js +++ b/src/utils/RoutingRules.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; let rules = {}; @@ -19,9 +19,9 @@ let rules = {}; * @param routeName Route name */ export function execute(routeName) { - if (rules[routeName]) { - rules[routeName].forEach((item) => { - item.call(); - }); - } + if (rules[routeName]) { + rules[routeName].forEach((item) => { + item.call(); + }); + } } diff --git a/src/utils/SecurityUtils.js b/src/utils/SecurityUtils.js index 9bcdf071..119a2e43 100644 --- a/src/utils/SecurityUtils.js +++ b/src/utils/SecurityUtils.js @@ -1,26 +1,26 @@ -import {getOidcIdentityStorageKey, isUsingOidcAuth} from "./OidcUtils"; -import {sanitizeArray} from "./Utils"; -import {IMPERSONATOR_TYPE} from "../constants/Vocabulary"; -import {ROLE} from "../constants/DefaultConstants"; +import { getOidcIdentityStorageKey, isUsingOidcAuth } from "./OidcUtils"; +import { sanitizeArray } from "./Utils"; +import { IMPERSONATOR_TYPE } from "../constants/Vocabulary"; +import { ROLE } from "../constants/DefaultConstants"; export function getOidcToken() { - const identityData = sessionStorage.getItem(getOidcIdentityStorageKey()); - return identityData ? JSON.parse(identityData) : {}; + const identityData = sessionStorage.getItem(getOidcIdentityStorageKey()); + return identityData ? JSON.parse(identityData) : {}; } export function saveOidcToken(token) { - sessionStorage.setItem(getOidcIdentityStorageKey(), JSON.stringify(token)); + sessionStorage.setItem(getOidcIdentityStorageKey(), JSON.stringify(token)); } export function clearToken() { - sessionStorage.removeItem(getOidcIdentityStorageKey()); + sessionStorage.removeItem(getOidcIdentityStorageKey()); } export function isAdmin(currentUser) { - return currentUser.role === ROLE.ADMIN; + return currentUser.role === ROLE.ADMIN; } export function isImpersonator(currentUser) { - // When using OIDC, the access token does not contain any info that the current user is being impersonated - return !isUsingOidcAuth() && sanitizeArray(currentUser.types).indexOf(IMPERSONATOR_TYPE) !== -1; + // When using OIDC, the access token does not contain any info that the current user is being impersonated + return !isUsingOidcAuth() && sanitizeArray(currentUser.types).indexOf(IMPERSONATOR_TYPE) !== -1; } diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 39f45271..5da287ae 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -1,20 +1,61 @@ -'use strict'; -import Bowser from 'bowser'; +"use strict"; +import Bowser from "bowser"; import * as Constants from "../constants/DefaultConstants"; -import {HttpHeaders, ROLE} from "../constants/DefaultConstants"; +import { HttpHeaders, ROLE } from "../constants/DefaultConstants"; import * as Vocabulary from "../constants/Vocabulary"; import * as supportedDevices from "../constants/SupportedDevices"; -import {isAdmin} from "./SecurityUtils"; +import { isAdmin } from "./SecurityUtils"; import parseLinkHeader from "parse-link-header"; /** * Common propositions that should not be capitalized */ const PREPOSITIONS = [ - 'a', 'about', 'across', 'after', 'along', 'among', 'an', 'around', 'as', 'aside', 'at', 'before', 'behind', 'below', - 'beneath', 'beside', 'besides', 'between', 'beyond', 'but', 'by', 'for', 'given', 'in', 'inside', 'into', 'like', 'near', - 'of', 'off', 'on', 'onto', 'outside', 'over', 'since', 'than', 'through', 'to', 'until', 'up', 'via', 'with', 'within', - 'without', 'not' + "a", + "about", + "across", + "after", + "along", + "among", + "an", + "around", + "as", + "aside", + "at", + "before", + "behind", + "below", + "beneath", + "beside", + "besides", + "between", + "beyond", + "but", + "by", + "for", + "given", + "in", + "inside", + "into", + "like", + "near", + "of", + "off", + "on", + "onto", + "outside", + "over", + "since", + "than", + "through", + "to", + "until", + "up", + "via", + "with", + "within", + "without", + "not", ]; const URL_CONTAINS_QUERY = /^.+\?.+=.+$/; @@ -26,13 +67,13 @@ const CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567 * @param date The date to format */ export function formatDate(date) { - const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate().toString(); - const month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1).toString(); - const year = (date.getFullYear() % 100).toString(); - const h = date.getHours(); - const hour = h < 10 ? '0' + h : h.toString(); - const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes().toString(); - return (day + '-' + month + '-' + year + ' ' + hour + ':' + minute); + const day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate().toString(); + const month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1).toString(); + const year = (date.getFullYear() % 100).toString(); + const h = date.getHours(); + const hour = h < 10 ? "0" + h : h.toString(); + const minute = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes().toString(); + return day + "-" + month + "-" + year + " " + hour + ":" + minute; } /** @@ -41,19 +82,19 @@ export function formatDate(date) { * Replaces underscores with spaces. And if capitalize is selected, capitalizes the words. */ export function constantToString(constant, capitalize) { - if (!capitalize) { - return constant.replace(/_/g, ' '); + if (!capitalize) { + return constant.replace(/_/g, " "); + } + let words = constant.split("_"); + for (let i = 0, len = words.length; i < len; i++) { + let word = words[i]; + if (i > 0 && PREPOSITIONS.indexOf(word.toLowerCase()) !== -1) { + words[i] = word.toLowerCase(); + } else { + words[i] = word.charAt(0) + word.substring(1).toLowerCase(); } - let words = constant.split('_'); - for (let i = 0, len = words.length; i < len; i++) { - let word = words[i]; - if (i > 0 && PREPOSITIONS.indexOf(word.toLowerCase()) !== -1) { - words[i] = word.toLowerCase(); - } else { - words[i] = word.charAt(0) + word.substring(1).toLowerCase(); - } - } - return words.join(' '); + } + return words.join(" "); } /** @@ -68,31 +109,31 @@ export function constantToString(constant, capitalize) { * @return {*} Converted value */ export function convertTime(fromUnit, toUnit, value) { - if (fromUnit === toUnit) { - return value; - } - switch (fromUnit) { - case 'second': - if (toUnit === 'minute') { - return Math.round(value / 60); - } else { - return Math.round(value / 60 / 60); - } - case 'minute': - if (toUnit === 'second') { - return 60 * value; - } else { - return Math.round(value / 60); - } - case 'hour': - if (toUnit === 'second') { - return 60 * 60 * value; - } else { - return 60 * value; - } - default: - return value; - } + if (fromUnit === toUnit) { + return value; + } + switch (fromUnit) { + case "second": + if (toUnit === "minute") { + return Math.round(value / 60); + } else { + return Math.round(value / 60 / 60); + } + case "minute": + if (toUnit === "second") { + return 60 * value; + } else { + return Math.round(value / 60); + } + case "hour": + if (toUnit === "second") { + return 60 * 60 * value; + } else { + return 60 * value; + } + default: + return value; + } } /** @@ -101,11 +142,11 @@ export function convertTime(fromUnit, toUnit, value) { * @return {string} Report key as string */ export function extractKeyFromLocationHeader(response) { - const location = response.headers['location']; - if (!location) { - return ''; - } - return location.substring(location.lastIndexOf('/') + 1); + const location = response.headers["location"]; + if (!location) { + return ""; + } + return location.substring(location.lastIndexOf("/") + 1); } /** @@ -115,9 +156,9 @@ export function extractKeyFromLocationHeader(response) { * @return {String} */ export function getPathFromLocation() { - const hash = window.location.hash; - const result = /#[/]?([a-z/0-9]+)\?/.exec(hash); - return result ? result[1] : ''; + const hash = window.location.hash; + const result = /#[/]?([a-z/0-9]+)\?/.exec(hash); + return result ? result[1] : ""; } /** @@ -127,10 +168,10 @@ export function getPathFromLocation() { * @return extracted parameter value or undefined if the parameter is not present in the query */ export function extractQueryParam(queryString, paramName) { - queryString = decodeURI(queryString); // TODO This is a nasty hack, the problem with encoding seems to be - // somewhere in thunk - const reqexpMatch = queryString.match(new RegExp(paramName + "=([^&]*)")); - return reqexpMatch ? reqexpMatch[1] : undefined; + queryString = decodeURI(queryString); // TODO This is a nasty hack, the problem with encoding seems to be + // somewhere in thunk + const reqexpMatch = queryString.match(new RegExp(paramName + "=([^&]*)")); + return reqexpMatch ? reqexpMatch[1] : undefined; } /** @@ -140,9 +181,9 @@ export function extractQueryParam(queryString, paramName) { * @return {number} */ export function randomInt() { - const min = 0, - max = 1073741824; // Max Java Integer / 2 - return Math.floor(Math.random() * (max - min)) + min; + const min = 0, + max = 1073741824; // Max Java Integer / 2 + return Math.floor(Math.random() * (max - min)) + min; } /** @@ -155,15 +196,15 @@ export function randomInt() { * @return {*} */ export function idToName(items, id) { - if (!items) { - return id; - } - for (let i = 0, len = items.length; i < len; i++) { - if (items[i].id === id) { - return items[i].name; - } - } + if (!items) { return id; + } + for (let i = 0, len = items.length; i < len; i++) { + if (items[i].id === id) { + return items[i].name; + } + } + return id; } /** @@ -174,7 +215,7 @@ export function idToName(items, id) { * @return {string|*} */ export function getLastPathFragment(url) { - return url.substring(url.lastIndexOf('/') + 1); + return url.substring(url.lastIndexOf("/") + 1); } /** @@ -183,19 +224,19 @@ export function getLastPathFragment(url) { * @return {number} */ export function getStringHash(str) { - let hash = 0, - strlen = str ? str.length : 0, - i, - c; - if (strlen === 0) { - return hash; - } - for (i = 0; i < strlen; i++) { - c = str.charCodeAt(i); - hash = ((hash << 5) - hash) + c; - hash = hash & hash; // Convert to 32bit integer - } + let hash = 0, + strlen = str ? str.length : 0, + i, + c; + if (strlen === 0) { return hash; + } + for (i = 0; i < strlen; i++) { + c = str.charCodeAt(i); + hash = (hash << 5) - hash + c; + hash = hash & hash; // Convert to 32bit integer + } + return hash; } /** @@ -207,21 +248,21 @@ export function getStringHash(str) { * @return {*} Updated URL */ export function addParametersToUrl(url, parameters) { - if (parameters) { - url += URL_CONTAINS_QUERY.test(url) ? '&' : '?'; - Object.getOwnPropertyNames(parameters).forEach(function (param) { - url += param + '=' + parameters[param] + '&'; // '&' at the end of request URI should not be a problem - }); - } - return url; + if (parameters) { + url += URL_CONTAINS_QUERY.test(url) ? "&" : "?"; + Object.getOwnPropertyNames(parameters).forEach(function (param) { + url += param + "=" + parameters[param] + "&"; // '&' at the end of request URI should not be a problem + }); + } + return url; } export function generatePassword() { - let pass = ''; - for (let i = 0; i < Constants.PASSWORD_LENGTH; i++) { - pass += CHARACTERS.charAt(Math.floor(Math.random() * CHARACTERS.length)); - } - return pass; + let pass = ""; + for (let i = 0; i < Constants.PASSWORD_LENGTH; i++) { + pass += CHARACTERS.charAt(Math.floor(Math.random() * CHARACTERS.length)); + } + return pass; } /** @@ -232,61 +273,75 @@ export function generatePassword() { * @return {*|boolean} */ export function canLoadInstitutionsPatients(institutionKey, currentUser) { - return currentUser != null && (isAdmin(currentUser) || (currentUser.institution != null && currentUser.institution.key === institutionKey)); + return ( + currentUser != null && + (isAdmin(currentUser) || (currentUser.institution != null && currentUser.institution.key === institutionKey)) + ); } export function deviceIsMobile() { - const winWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth); - return (winWidth > 0 && winWidth < 321) - ? true - : (/Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini|Mobile|MeeGo/i.test( - navigator.userAgent || navigator.vendor || window.opera)); + const winWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; + return winWidth > 0 && winWidth < 321 + ? true + : /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini|Mobile|MeeGo/i.test( + navigator.userAgent || navigator.vendor || window.opera, + ); } export function getRole(user) { - const userToTest = user; - if (!userToTest) { - return undefined; - } - if (userToTest.types) { - if (userToTest.types.indexOf(Vocabulary.ADMIN_TYPE) !== -1) { - return ROLE.ADMIN; - } else { - return ROLE.DOCTOR; - } - } + const userToTest = user; + if (!userToTest) { return undefined; + } + if (userToTest.types) { + if (userToTest.types.indexOf(Vocabulary.ADMIN_TYPE) !== -1) { + return ROLE.ADMIN; + } else { + return ROLE.DOCTOR; + } + } + return undefined; } export function processInstitutions(institutions) { - return institutions.map((item) => { - return {label: item.name, value: item.uri} - }); + return institutions.map((item) => { + return { label: item.name, value: item.uri }; + }); } export function validateEmail(email) { - return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(email); + return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test( + email, + ); } export function deviceIsSupported() { - const browser = Bowser.getParser(window.navigator.userAgent); + const browser = Bowser.getParser(window.navigator.userAgent); - return browser.satisfies(supportedDevices.SUPPORTED_BROWSERS); + return browser.satisfies(supportedDevices.SUPPORTED_BROWSERS); } // format to DD-MM-YYYY HH:mm:ss:SSS export function formatDateWithMilliseconds(timestamp) { - const date = new Date(timestamp); - return ("00" + date.getDate()).slice(-2) + "-" + - ("00" + (date.getMonth() + 1)).slice(-2) + "-" + - date.getFullYear() + " " + - ("00" + date.getHours()).slice(-2) + ":" + - ("00" + date.getMinutes()).slice(-2) + ":" + - ("00" + date.getSeconds()).slice(-2) + ("00" + date.getMilliseconds()).slice(-2); + const date = new Date(timestamp); + return ( + ("00" + date.getDate()).slice(-2) + + "-" + + ("00" + (date.getMonth() + 1)).slice(-2) + + "-" + + date.getFullYear() + + " " + + ("00" + date.getHours()).slice(-2) + + ":" + + ("00" + date.getMinutes()).slice(-2) + + ":" + + ("00" + date.getSeconds()).slice(-2) + + ("00" + date.getMilliseconds()).slice(-2) + ); } export function sanitizeArray(arr) { - return arr ? (Array.isArray(arr) ? arr : [arr]) : []; + return arr ? (Array.isArray(arr) ? arr : [arr]) : []; } /** @@ -298,17 +353,17 @@ export function sanitizeArray(arr) { * @param mimeType Type of data */ export function fileDownload(data, filename, mimeType = "application/octet-stream") { - const blob = new Blob([data], {type: mimeType}); - const blobURL = window.URL.createObjectURL(blob); - const tempLink = document.createElement("a"); - tempLink.style.display = "none"; - tempLink.href = blobURL; - tempLink.setAttribute("download", filename); - - document.body.appendChild(tempLink); - tempLink.click(); - document.body.removeChild(tempLink); - window.URL.revokeObjectURL(blobURL); + const blob = new Blob([data], { type: mimeType }); + const blobURL = window.URL.createObjectURL(blob); + const tempLink = document.createElement("a"); + tempLink.style.display = "none"; + tempLink.href = blobURL; + tempLink.setAttribute("download", filename); + + document.body.appendChild(tempLink); + tempLink.click(); + document.body.removeChild(tempLink); + window.URL.revokeObjectURL(blobURL); } /** @@ -317,28 +372,28 @@ export function fileDownload(data, filename, mimeType = "application/octet-strea * @returns {string|string} */ export function paramsSerializer(paramData) { - const keys = Object.keys(paramData); - let options = ""; - - keys.forEach((key) => { - const isParamTypeObject = typeof paramData[key] === "object"; - const isParamTypeArray = isParamTypeObject && paramData[key].length >= 0; - if (paramData[key] === undefined || paramData[key] === null) { - return; - } - - if (!isParamTypeObject) { - options += `${key}=${encodeURIComponent(paramData[key])}&`; - } - - if (isParamTypeObject && isParamTypeArray) { - paramData[key].forEach((element) => { - options += `${key}=${encodeURIComponent(element)}&`; - }); - } - }); + const keys = Object.keys(paramData); + let options = ""; + + keys.forEach((key) => { + const isParamTypeObject = typeof paramData[key] === "object"; + const isParamTypeArray = isParamTypeObject && paramData[key].length >= 0; + if (paramData[key] === undefined || paramData[key] === null) { + return; + } - return options ? options.slice(0, -1) : options; + if (!isParamTypeObject) { + options += `${key}=${encodeURIComponent(paramData[key])}&`; + } + + if (isParamTypeObject && isParamTypeArray) { + paramData[key].forEach((element) => { + options += `${key}=${encodeURIComponent(element)}&`; + }); + } + }); + + return options ? options.slice(0, -1) : options; } /** @@ -347,14 +402,16 @@ export function paramsSerializer(paramData) { * @returns {number|undefined} Page number or undefined, if it could not have been extracted */ export function extractLastPageNumber(response) { - const linkHeader = response.headers[HttpHeaders.LINK]; - if (!linkHeader) { - return undefined; - } - const links = parseLinkHeader(linkHeader); - return links.last ? Number(links.last.page) : undefined; + const linkHeader = response.headers[HttpHeaders.LINK]; + if (!linkHeader) { + return undefined; + } + const links = parseLinkHeader(linkHeader); + return links.last ? Number(links.last.page) : undefined; } export function sortToParams(sort) { - return Object.keys(sort).filter(k => sort[k] !== undefined).map(k => `${sort[k]}${k}`); + return Object.keys(sort) + .filter((k) => sort[k] !== undefined) + .map((k) => `${sort[k]}${k}`); } diff --git a/src/utils/injectIntl.js b/src/utils/injectIntl.js index d522e784..c6b186d0 100644 --- a/src/utils/injectIntl.js +++ b/src/utils/injectIntl.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -import {injectIntl} from 'react-intl'; +import { injectIntl } from "react-intl"; /** * Our version of react-intl's injectIntl. @@ -9,16 +9,16 @@ import {injectIntl} from 'react-intl'; * tests). */ export default function (component, props) { - if (!props) { - props = {}; - } - // Store this only for development purposes - if (process.env.NODE_ENV !== 'production') { - props.withRef = true; - const comp = injectIntl(component, props); - comp.wrappedComponent = comp; - return comp; - } else { - return injectIntl(component, props); - } -}; + if (!props) { + props = {}; + } + // Store this only for development purposes + if (process.env.NODE_ENV !== "production") { + props.withRef = true; + const comp = injectIntl(component, props); + comp.wrappedComponent = comp; + return comp; + } else { + return injectIntl(component, props); + } +} diff --git a/src/validation/InstitutionValidator.jsx b/src/validation/InstitutionValidator.jsx index 8d73b667..69000370 100644 --- a/src/validation/InstitutionValidator.jsx +++ b/src/validation/InstitutionValidator.jsx @@ -1,7 +1,7 @@ -'use strict'; +"use strict"; export default class InstitutionValidator { - static isValid(institution) { - return !!institution.name; - } + static isValid(institution) { + return !!institution.name; + } } diff --git a/src/validation/RecordValidator.jsx b/src/validation/RecordValidator.jsx index e4a86bc8..40a3dd33 100644 --- a/src/validation/RecordValidator.jsx +++ b/src/validation/RecordValidator.jsx @@ -1,16 +1,16 @@ -'use strict'; +"use strict"; import * as Constants from "../constants/DefaultConstants"; export default class RecordValidator { - static isComplete(record) { - if (!record) { - return false; - } - for (let i = 0, len = Constants.RECORD_REQUIRED_FIELDS.length; i < len; i++) { - if (!record[Constants.RECORD_REQUIRED_FIELDS[i]]) { - return false; - } - } - return true; + static isComplete(record) { + if (!record) { + return false; } + for (let i = 0, len = Constants.RECORD_REQUIRED_FIELDS.length; i < len; i++) { + if (!record[Constants.RECORD_REQUIRED_FIELDS[i]]) { + return false; + } + } + return true; + } } diff --git a/src/validation/UserValidator.jsx b/src/validation/UserValidator.jsx index 1aa1e8ef..86148c9c 100644 --- a/src/validation/UserValidator.jsx +++ b/src/validation/UserValidator.jsx @@ -1,11 +1,11 @@ -'use strict'; +"use strict"; export default class UserValidator { - static isValid(user) { - return user.firstName && user.lastName && user.username && user.emailAddress && user.institution; - } + static isValid(user) { + return user.firstName && user.lastName && user.username && user.emailAddress && user.institution; + } - static isPasswordValid(password) { - return password.newPassword && password.confirmPassword; - } + static isPasswordValid(password) { + return password.newPassword && password.confirmPassword; + } } diff --git a/tests/__mocks__/styleMock.js b/tests/__mocks__/styleMock.js index a0995453..f053ebf7 100644 --- a/tests/__mocks__/styleMock.js +++ b/tests/__mocks__/styleMock.js @@ -1 +1 @@ -module.exports = {}; \ No newline at end of file +module.exports = {}; diff --git a/tests/__tests__/actions/AuthActions.spec.js b/tests/__tests__/actions/AuthActions.spec.js index d852f961..05ef92cd 100644 --- a/tests/__tests__/actions/AuthActions.spec.js +++ b/tests/__tests__/actions/AuthActions.spec.js @@ -1,266 +1,263 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; +import MockAdapter from "axios-mock-adapter"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; import * as actions from "../../../js/actions/AuthActions"; -import {API_URL} from '../../../config'; - -describe('Auth synchronize actions', function () { - const user = {username: 'test'}, - error = {message: 'error'}; - - it('creates an action that user is authenticating', () => { - const expectedAction = { - type: ActionConstants.AUTH_USER_PENDING - }; - expect(actions.userAuthPending()).toEqual(expectedAction) - }); - - it('creates an action that user was authenticated', () => { - const expectedAction = { - type: ActionConstants.AUTH_USER_SUCCESS, - username: user.username - }; - expect(actions.userAuthSuccess(user.username)).toEqual(expectedAction) - }); - - it('creates an action that there was error during authentication', () => { - const expectedAction = { - type: ActionConstants.AUTH_USER_ERROR, - error - }; - expect(actions.userAuthError(error)).toEqual(expectedAction) - }); - - it('creates an action that user was unauthenticated', () => { - const expectedAction = { - type: ActionConstants.UNAUTH_USER - }; - expect(actions.unauthUser()).toEqual(expectedAction) - }); - - it('creates an action to fetch current user', () => { - const expectedAction = { - type: ActionConstants.LOAD_USER_PROFILE_PENDING - }; - expect(actions.loadUserProfilePending()).toEqual(expectedAction) - }); - - it('creates an action to save fetched current user', () => { - const expectedAction = { - type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, - user - }; - expect(actions.loadUserProfileSuccess(user)).toEqual(expectedAction) - }); - - it('creates an action about error during fetching current user', () => { - const expectedAction = { - type: ActionConstants.LOAD_USER_PROFILE_ERROR, - error - }; - expect(actions.loadUserProfileError(error)).toEqual(expectedAction) - }); +import { API_URL } from "../../../config"; + +describe("Auth synchronize actions", function () { + const user = { username: "test" }, + error = { message: "error" }; + + it("creates an action that user is authenticating", () => { + const expectedAction = { + type: ActionConstants.AUTH_USER_PENDING, + }; + expect(actions.userAuthPending()).toEqual(expectedAction); + }); + + it("creates an action that user was authenticated", () => { + const expectedAction = { + type: ActionConstants.AUTH_USER_SUCCESS, + username: user.username, + }; + expect(actions.userAuthSuccess(user.username)).toEqual(expectedAction); + }); + + it("creates an action that there was error during authentication", () => { + const expectedAction = { + type: ActionConstants.AUTH_USER_ERROR, + error, + }; + expect(actions.userAuthError(error)).toEqual(expectedAction); + }); + + it("creates an action that user was unauthenticated", () => { + const expectedAction = { + type: ActionConstants.UNAUTH_USER, + }; + expect(actions.unauthUser()).toEqual(expectedAction); + }); + + it("creates an action to fetch current user", () => { + const expectedAction = { + type: ActionConstants.LOAD_USER_PROFILE_PENDING, + }; + expect(actions.loadUserProfilePending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched current user", () => { + const expectedAction = { + type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, + user, + }; + expect(actions.loadUserProfileSuccess(user)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching current user", () => { + const expectedAction = { + type: ActionConstants.LOAD_USER_PROFILE_ERROR, + error, + }; + expect(actions.loadUserProfileError(error)).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Auth asynchronize actions', function () { - let store, - mockApi; - const user = {username: 'test', password: 'testPassword', types: []}, - error = { - "message": "An error has occurred.", - "requestUri": "/rest/users/xxx" - }; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore(); - }); - - it('creates AUTH_USER_SUCCESS action when logging in successfully is done', function (done) { - const reply = { - errorMessage: null, - loggedIn: true, - success: true, - username: "test" - }; - const expectedActions = [ - {type: ActionConstants.AUTH_USER_PENDING}, - {type: ActionConstants.AUTH_USER_SUCCESS, username: user.username}, - {type: ActionConstants.LOAD_USER_PROFILE_PENDING}, - {type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, user} - ]; - - mockApi.onPost(`${API_URL}/j_spring_security_check`).reply(200, reply); - mockApi.onGet(`${API_URL}/rest/users/current`).reply(200, user); - - store.dispatch(actions.login(user.username, user.password, null)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates AUTH_USER_ERROR action when logging in fails', function (done) { - const reply = { - errorMessage: "User with username test not found.", - loggedIn: false, - success: false, - username: null - }; - const expectedActions = [ - {type: ActionConstants.AUTH_USER_PENDING}, - {type: ActionConstants.AUTH_USER_ERROR, error: reply} - ]; - - mockApi.onPost(`${API_URL}/j_spring_security_check`).reply(400, reply); - - store.dispatch(actions.login(user.username, user.password, null)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates UNAUTH_USER action when user successfully logs out', function (done) { - const expectedActions = [ - {type: ActionConstants.UNAUTH_USER} - ]; - store.getState().auth = {user}; - - mockApi.onPost(`${API_URL}/j_spring_security_logout`).reply(200); - - store.dispatch(actions.logout(user)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_USER_PROFILE_SUCCESS action when current user is successfully loaded', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_USER_PROFILE_PENDING}, - {type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, user} - ]; - - mockApi.onGet(`${API_URL}/rest/users/current`).reply(200, user); - - store.dispatch(actions.loadUserProfile()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_USER_PROFILE_ERROR action when current user is successfully loaded', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_USER_PROFILE_PENDING}, - {type: ActionConstants.LOAD_USER_PROFILE_ERROR, error} - ]; - - mockApi.onGet(`${API_URL}/rest/users/current`).reply(400, error); - - store.dispatch(actions.loadUserProfile()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates PASSWORD_RESET_SUCCESS action when password is successfully reset', function (done) { - const email = "admin@gmail.com"; - const expectedActions = [ - {type: ActionConstants.PASSWORD_RESET_PENDING}, - {type: ActionConstants.PASSWORD_RESET_SUCCESS, email} - ]; - - mockApi.onPost(`${API_URL}/rest/users/password-reset`).reply(200); - - store.dispatch(actions.passwordReset(email)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates VALIDATE_TOKEN_SUCCESS action when token exists', function (done) { - const token = "12345"; - const expectedActions = [ - {type: ActionConstants.VALIDATE_TOKEN_PENDING}, - {type: ActionConstants.VALIDATE_TOKEN_SUCCESS} - ]; - - mockApi.onPost(`${API_URL}/rest/users/validate-token`).reply(200); - - store.dispatch(actions.validateToken(token)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates VALIDATE_TOKEN_ERROR action when token does not exist', function (done) { - const token = "12345"; - const expectedActions = [ - {type: ActionConstants.VALIDATE_TOKEN_PENDING}, - {type: ActionConstants.VALIDATE_TOKEN_ERROR} - ]; - - mockApi.onPost(`${API_URL}/rest/users/validate-token`).reply(400); - - store.dispatch(actions.validateToken(token)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates PASSWORD_CHANGE_TOKEN_SUCCESS action when token exists', function (done) { - const token = "12345"; - const password = "12345"; - const expectedActions = [ - {type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING}, - {type: ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS} - ]; - - mockApi.onPut(`${API_URL}/rest/users/password-change-token`).reply(200); - - store.dispatch(actions.changePasswordToken(password, token)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates PASSWORD_CHANGE_TOKEN_ERROR action when token does not exist', function (done) { - const token = "12345"; - const password = "12345"; - const expectedActions = [ - {type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING}, - {type: ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR} - ]; - - mockApi.onPut(`${API_URL}/rest/users/password-change-token`).reply(400); - - store.dispatch(actions.changePasswordToken(password, token)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file +describe("Auth asynchronize actions", function () { + let store, mockApi; + const user = { username: "test", password: "testPassword", types: [] }, + error = { + message: "An error has occurred.", + requestUri: "/rest/users/xxx", + }; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore(); + }); + + it("creates AUTH_USER_SUCCESS action when logging in successfully is done", function (done) { + const reply = { + errorMessage: null, + loggedIn: true, + success: true, + username: "test", + }; + const expectedActions = [ + { type: ActionConstants.AUTH_USER_PENDING }, + { type: ActionConstants.AUTH_USER_SUCCESS, username: user.username }, + { type: ActionConstants.LOAD_USER_PROFILE_PENDING }, + { type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, user }, + ]; + + mockApi.onPost(`${API_URL}/j_spring_security_check`).reply(200, reply); + mockApi.onGet(`${API_URL}/rest/users/current`).reply(200, user); + + store.dispatch(actions.login(user.username, user.password, null)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates AUTH_USER_ERROR action when logging in fails", function (done) { + const reply = { + errorMessage: "User with username test not found.", + loggedIn: false, + success: false, + username: null, + }; + const expectedActions = [ + { type: ActionConstants.AUTH_USER_PENDING }, + { type: ActionConstants.AUTH_USER_ERROR, error: reply }, + ]; + + mockApi.onPost(`${API_URL}/j_spring_security_check`).reply(400, reply); + + store.dispatch(actions.login(user.username, user.password, null)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates UNAUTH_USER action when user successfully logs out", function (done) { + const expectedActions = [{ type: ActionConstants.UNAUTH_USER }]; + store.getState().auth = { user }; + + mockApi.onPost(`${API_URL}/j_spring_security_logout`).reply(200); + + store.dispatch(actions.logout(user)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_USER_PROFILE_SUCCESS action when current user is successfully loaded", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_USER_PROFILE_PENDING }, + { type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, user }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/current`).reply(200, user); + + store.dispatch(actions.loadUserProfile()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_USER_PROFILE_ERROR action when current user is successfully loaded", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_USER_PROFILE_PENDING }, + { type: ActionConstants.LOAD_USER_PROFILE_ERROR, error }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/current`).reply(400, error); + + store.dispatch(actions.loadUserProfile()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates PASSWORD_RESET_SUCCESS action when password is successfully reset", function (done) { + const email = "admin@gmail.com"; + const expectedActions = [ + { type: ActionConstants.PASSWORD_RESET_PENDING }, + { type: ActionConstants.PASSWORD_RESET_SUCCESS, email }, + ]; + + mockApi.onPost(`${API_URL}/rest/users/password-reset`).reply(200); + + store.dispatch(actions.passwordReset(email)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates VALIDATE_TOKEN_SUCCESS action when token exists", function (done) { + const token = "12345"; + const expectedActions = [ + { type: ActionConstants.VALIDATE_TOKEN_PENDING }, + { type: ActionConstants.VALIDATE_TOKEN_SUCCESS }, + ]; + + mockApi.onPost(`${API_URL}/rest/users/validate-token`).reply(200); + + store.dispatch(actions.validateToken(token)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates VALIDATE_TOKEN_ERROR action when token does not exist", function (done) { + const token = "12345"; + const expectedActions = [ + { type: ActionConstants.VALIDATE_TOKEN_PENDING }, + { type: ActionConstants.VALIDATE_TOKEN_ERROR }, + ]; + + mockApi.onPost(`${API_URL}/rest/users/validate-token`).reply(400); + + store.dispatch(actions.validateToken(token)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates PASSWORD_CHANGE_TOKEN_SUCCESS action when token exists", function (done) { + const token = "12345"; + const password = "12345"; + const expectedActions = [ + { type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING }, + { type: ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS }, + ]; + + mockApi.onPut(`${API_URL}/rest/users/password-change-token`).reply(200); + + store.dispatch(actions.changePasswordToken(password, token)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates PASSWORD_CHANGE_TOKEN_ERROR action when token does not exist", function (done) { + const token = "12345"; + const password = "12345"; + const expectedActions = [ + { type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING }, + { type: ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR }, + ]; + + mockApi.onPut(`${API_URL}/rest/users/password-change-token`).reply(400); + + store.dispatch(actions.changePasswordToken(password, token)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/HistoryActions.spec.js b/tests/__tests__/actions/HistoryActions.spec.js index b149e146..8a659c0c 100644 --- a/tests/__tests__/actions/HistoryActions.spec.js +++ b/tests/__tests__/actions/HistoryActions.spec.js @@ -1,99 +1,102 @@ import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; -import MockAdapter from 'axios-mock-adapter'; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; +import MockAdapter from "axios-mock-adapter"; import thunk from "redux-thunk"; import configureMockStore from "redux-mock-store"; -import {loadActionByKey, loadActions} from "../../../js/actions/HistoryActions"; -import {API_URL} from '../../../config'; -import {errorMessage} from "../../../js/model/Message"; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; -import {DEFAULT_PAGE_SIZE} from "../../../js/constants/DefaultConstants"; +import { loadActionByKey, loadActions } from "../../../js/actions/HistoryActions"; +import { API_URL } from "../../../config"; +import { errorMessage } from "../../../js/model/Message"; +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; +import { DEFAULT_PAGE_SIZE } from "../../../js/constants/DefaultConstants"; const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('History asynchronize actions', function () { - let store, - mockApi; - const error = { - "message": "An error has occurred.", - }, key = "12345", - action = {type: 'TEST_ACTION'}, - actions = [action, action]; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore(); - mockDateNow(); - }); - - afterEach(() => { - restoreDateNow(); - }); - - xit('creates LOAD_ACTION_HISTORY_SUCCESS action when loading of action is successfully done', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_ACTION_HISTORY_PENDING}, - {type: ActionConstants.LOAD_ACTION_HISTORY_SUCCESS, actionHistory: action} - ]; - - mockApi.onGet(`${API_URL}/rest/history/${key}`).reply(200, action); - - store.dispatch(loadActionByKey(key)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - xit('creates LOAD_ACTION_HISTORY_ERROR action if an error occurred during loading of action', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_ACTION_HISTORY_PENDING}, - {type: ActionConstants.LOAD_ACTION_HISTORY_ERROR, error} - ]; - - mockApi.onGet(`${API_URL}/rest/history/${key}`).reply(400, error); - - store.dispatch(loadActionByKey(key)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - xit('creates LOAD_ACTIONS_HISTORY_SUCCESS action when loading of actions is successfully done', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING}, - {type: ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS, actionsHistory: actions} - ]; - - mockApi.onGet(`${API_URL}/rest/history?page=1`).reply(200, actions); - - store.dispatch(loadActions(1, null)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_ACTIONS_HISTORY_ERROR action if an error occurred during loading of actions', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING}, - {type: ActionConstants.LOAD_ACTIONS_HISTORY_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('history.loading-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/history?page=1&size=${DEFAULT_PAGE_SIZE}`).reply(400, error); - - store.dispatch(loadActions(1, null)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file +describe("History asynchronize actions", function () { + let store, mockApi; + const error = { + message: "An error has occurred.", + }, + key = "12345", + action = { type: "TEST_ACTION" }, + actions = [action, action]; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore(); + mockDateNow(); + }); + + afterEach(() => { + restoreDateNow(); + }); + + xit("creates LOAD_ACTION_HISTORY_SUCCESS action when loading of action is successfully done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_ACTION_HISTORY_PENDING }, + { type: ActionConstants.LOAD_ACTION_HISTORY_SUCCESS, actionHistory: action }, + ]; + + mockApi.onGet(`${API_URL}/rest/history/${key}`).reply(200, action); + + store.dispatch(loadActionByKey(key)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + xit("creates LOAD_ACTION_HISTORY_ERROR action if an error occurred during loading of action", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_ACTION_HISTORY_PENDING }, + { type: ActionConstants.LOAD_ACTION_HISTORY_ERROR, error }, + ]; + + mockApi.onGet(`${API_URL}/rest/history/${key}`).reply(400, error); + + store.dispatch(loadActionByKey(key)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + xit("creates LOAD_ACTIONS_HISTORY_SUCCESS action when loading of actions is successfully done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING }, + { type: ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS, actionsHistory: actions }, + ]; + + mockApi.onGet(`${API_URL}/rest/history?page=1`).reply(200, actions); + + store.dispatch(loadActions(1, null)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_ACTIONS_HISTORY_ERROR action if an error occurred during loading of actions", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING }, + { type: ActionConstants.LOAD_ACTIONS_HISTORY_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("history.loading-error", { error: error.message }), + }, + ]; + + mockApi.onGet(`${API_URL}/rest/history?page=1&size=${DEFAULT_PAGE_SIZE}`).reply(400, error); + + store.dispatch(loadActions(1, null)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/InstitutionActions.spec.js b/tests/__tests__/actions/InstitutionActions.spec.js index 610a8b05..90452048 100644 --- a/tests/__tests__/actions/InstitutionActions.spec.js +++ b/tests/__tests__/actions/InstitutionActions.spec.js @@ -1,305 +1,313 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {ACTION_FLAG} from "../../../js/constants/DefaultConstants"; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; +import MockAdapter from "axios-mock-adapter"; +import { ACTION_FLAG } from "../../../js/constants/DefaultConstants"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; import { - createInstitution, - deleteInstitution, - deleteInstitutionError, - deleteInstitutionPending, - deleteInstitutionSuccess, - loadInstitution, - loadInstitutionError, - loadInstitutionPending, - loadInstitutionSuccess, - saveInstitutionError, - saveInstitutionPending, - saveInstitutionSuccess, - unloadInstitution, - unloadSavedInstitution, - updateInstitution + createInstitution, + deleteInstitution, + deleteInstitutionError, + deleteInstitutionPending, + deleteInstitutionSuccess, + loadInstitution, + loadInstitutionError, + loadInstitutionPending, + loadInstitutionSuccess, + saveInstitutionError, + saveInstitutionPending, + saveInstitutionSuccess, + unloadInstitution, + unloadSavedInstitution, + updateInstitution, } from "../../../js/actions/InstitutionActions"; -import {API_URL} from '../../../config'; +import { API_URL } from "../../../config"; import en from "../../../js/i18n/en"; -import {errorMessage, successMessage} from "../../../js/model/Message"; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; - -describe('Institution synchronous actions', function () { - const institution = {key: 7979868757}, - key = 7979868757, - error = {message: 'error'}; - - it('creates an action to save institution', () => { - const actionFlag = ACTION_FLAG.CREATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_INSTITUTION_PENDING, - actionFlag - }; - expect(saveInstitutionPending(actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to announce successful save of institution', () => { - const actionFlag = ACTION_FLAG.CREATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_INSTITUTION_SUCCESS, - institution, - key, - actionFlag - }; - expect(saveInstitutionSuccess(institution, key, actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to announce unsuccessful save of institution', () => { - const actionFlag = ACTION_FLAG.UPDATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_INSTITUTION_ERROR, - error, - institution, - actionFlag, - }; - expect(saveInstitutionError(error, institution, actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to unload saved institution', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_SAVED_INSTITUTION - }; - expect(unloadSavedInstitution()).toEqual(expectedAction) - }); - - it('creates an action to delete institution', () => { - const expectedAction = { - type: ActionConstants.DELETE_INSTITUTION_PENDING, - key - }; - expect(deleteInstitutionPending(key)).toEqual(expectedAction) - }); - - it('creates an action to announce successful delete of institution', () => { - const expectedAction = { - type: ActionConstants.DELETE_INSTITUTION_SUCCESS, - institution - }; - expect(deleteInstitutionSuccess(institution)).toEqual(expectedAction) - }); - - it('creates an action to announce unsuccessful delete of institution', () => { - const expectedAction = { - type: ActionConstants.DELETE_INSTITUTION_ERROR, - error, - institution - }; - expect(deleteInstitutionError(error, institution)).toEqual(expectedAction) - }); - - it('creates an action to fetch institution', () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTION_PENDING, - }; - expect(loadInstitutionPending()).toEqual(expectedAction) - }); - - it('creates an action to save fetched institution', () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTION_SUCCESS, - institution - }; - expect(loadInstitutionSuccess(institution)).toEqual(expectedAction) - }); - - it('creates an action about error during fetching institution', () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTION_ERROR, - error - }; - expect(loadInstitutionError(error)).toEqual(expectedAction) - }); - - it('creates an action to unload loaded institution', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_INSTITUTION, - }; - expect(unloadInstitution()).toEqual(expectedAction) - }); +import { errorMessage, successMessage } from "../../../js/model/Message"; +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; + +describe("Institution synchronous actions", function () { + const institution = { key: 7979868757 }, + key = 7979868757, + error = { message: "error" }; + + it("creates an action to save institution", () => { + const actionFlag = ACTION_FLAG.CREATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_INSTITUTION_PENDING, + actionFlag, + }; + expect(saveInstitutionPending(actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to announce successful save of institution", () => { + const actionFlag = ACTION_FLAG.CREATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_INSTITUTION_SUCCESS, + institution, + key, + actionFlag, + }; + expect(saveInstitutionSuccess(institution, key, actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to announce unsuccessful save of institution", () => { + const actionFlag = ACTION_FLAG.UPDATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_INSTITUTION_ERROR, + error, + institution, + actionFlag, + }; + expect(saveInstitutionError(error, institution, actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to unload saved institution", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_SAVED_INSTITUTION, + }; + expect(unloadSavedInstitution()).toEqual(expectedAction); + }); + + it("creates an action to delete institution", () => { + const expectedAction = { + type: ActionConstants.DELETE_INSTITUTION_PENDING, + key, + }; + expect(deleteInstitutionPending(key)).toEqual(expectedAction); + }); + + it("creates an action to announce successful delete of institution", () => { + const expectedAction = { + type: ActionConstants.DELETE_INSTITUTION_SUCCESS, + institution, + }; + expect(deleteInstitutionSuccess(institution)).toEqual(expectedAction); + }); + + it("creates an action to announce unsuccessful delete of institution", () => { + const expectedAction = { + type: ActionConstants.DELETE_INSTITUTION_ERROR, + error, + institution, + }; + expect(deleteInstitutionError(error, institution)).toEqual(expectedAction); + }); + + it("creates an action to fetch institution", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTION_PENDING, + }; + expect(loadInstitutionPending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched institution", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTION_SUCCESS, + institution, + }; + expect(loadInstitutionSuccess(institution)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching institution", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTION_ERROR, + error, + }; + expect(loadInstitutionError(error)).toEqual(expectedAction); + }); + + it("creates an action to unload loaded institution", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_INSTITUTION, + }; + expect(unloadInstitution()).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Institution asynchronous actions', function () { - let store, - mockApi; - const institution = {key: 696875909}, - institutions = [ - {key: 7986787608}, - {key: 8968756596} - ], - key = '696875909', - location = `rest/institutions/${key}`, - error = { - "message": "An error has occurred.", - "requestUri": "/rest/institutions/xxx" - }; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore({intl: en}); - mockDateNow(); - }); - - afterEach(() => { - restoreDateNow(); - }); - - it('creates SAVE_INSTITUTION_SUCCESS action when saving institution successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY}, - {type: ActionConstants.SAVE_INSTITUTION_SUCCESS, key, actionFlag: ACTION_FLAG.CREATE_ENTITY, institution}, - {type: ActionConstants.LOAD_INSTITUTIONS_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage('institution.save-success')}, - {type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions} - ]; - - mockApi.onPost(`${API_URL}/rest/institutions`).reply(200, null, {location}); - mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); - - store.dispatch(createInstitution(institution)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates SAVE_INSTITUTION_ERROR action if an error occurred during creating institution', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY}, - {type: ActionConstants.SAVE_INSTITUTION_ERROR, actionFlag: ACTION_FLAG.CREATE_ENTITY, error, institution}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('institution.save-error', {error: error.message})} - ]; - - mockApi.onPost(`${API_URL}/rest/institutions`).reply(400, error); - - store.dispatch(createInstitution(institution)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates UPDATE_INSTITUTION_SUCCESS action when saving institution successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY}, - { - type: ActionConstants.SAVE_INSTITUTION_SUCCESS, - key: null, - actionFlag: ACTION_FLAG.UPDATE_ENTITY, - institution - }, - {type: ActionConstants.LOAD_INSTITUTIONS_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage('institution.save-success')}, - {type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions} - ]; - - mockApi.onPut(`${API_URL}/rest/institutions/${institution.key}`).reply(200, null, {location}); - mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); - - store.dispatch(updateInstitution(institution)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates SAVE_INSTITUTION_ERROR action if an error occurred during updating institution', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY}, - {type: ActionConstants.SAVE_INSTITUTION_ERROR, actionFlag: ACTION_FLAG.UPDATE_ENTITY, error, institution}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('institution.save-error', {error: error.message})} - ]; - - mockApi.onPut(`${API_URL}/rest/institutions/${institution.key}`).reply(400, error); - - store.dispatch(updateInstitution(institution)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates DELETE_INSTITUTION_SUCCESS action when deleting institution successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.DELETE_INSTITUTION_PENDING, key: institution.key}, - {type: ActionConstants.LOAD_INSTITUTIONS_PENDING}, - {type: ActionConstants.DELETE_INSTITUTION_SUCCESS, institution}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage('institution.delete-success')}, - {type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions} - ]; - - mockApi.onDelete(`${API_URL}/rest/institutions/${institution.key}`).reply(200); - mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); - - store.dispatch(deleteInstitution(institution)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates DELETE_INSTITUTION_ERROR action if an error occurred during institution delete', function (done) { - const expectedActions = [ - {type: ActionConstants.DELETE_INSTITUTION_PENDING, key: institution.key}, - {type: ActionConstants.DELETE_INSTITUTION_ERROR, error, institution}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('institution.delete-error', {error: undefined})} - ]; - - mockApi.onDelete(`${API_URL}/rest/institutions/${institution.key}`).reply(400, error); - - store.dispatch(deleteInstitution(institution)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_INSTITUTION_SUCCESS action when loading institution successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_INSTITUTION_PENDING}, - {type: ActionConstants.LOAD_INSTITUTION_SUCCESS, institution} - ]; - - mockApi.onGet(`${API_URL}/rest/institutions/${institution.key}`).reply(200, {key: institution.key}); - - store.dispatch(loadInstitution(institution.key)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_INSTITUTION_ERROR action if an error occurred during loading institution', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_INSTITUTION_PENDING}, - {type: ActionConstants.LOAD_INSTITUTION_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('institution.load-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/institutions/${institution.key}`).reply(400, error); - - store.dispatch(loadInstitution(institution.key)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file +describe("Institution asynchronous actions", function () { + let store, mockApi; + const institution = { key: 696875909 }, + institutions = [{ key: 7986787608 }, { key: 8968756596 }], + key = "696875909", + location = `rest/institutions/${key}`, + error = { + message: "An error has occurred.", + requestUri: "/rest/institutions/xxx", + }; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore({ intl: en }); + mockDateNow(); + }); + + afterEach(() => { + restoreDateNow(); + }); + + it("creates SAVE_INSTITUTION_SUCCESS action when saving institution successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY }, + { type: ActionConstants.SAVE_INSTITUTION_SUCCESS, key, actionFlag: ACTION_FLAG.CREATE_ENTITY, institution }, + { type: ActionConstants.LOAD_INSTITUTIONS_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("institution.save-success") }, + { type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions }, + ]; + + mockApi.onPost(`${API_URL}/rest/institutions`).reply(200, null, { location }); + mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); + + store.dispatch(createInstitution(institution)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SAVE_INSTITUTION_ERROR action if an error occurred during creating institution", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY }, + { type: ActionConstants.SAVE_INSTITUTION_ERROR, actionFlag: ACTION_FLAG.CREATE_ENTITY, error, institution }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("institution.save-error", { error: error.message }), + }, + ]; + + mockApi.onPost(`${API_URL}/rest/institutions`).reply(400, error); + + store.dispatch(createInstitution(institution)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates UPDATE_INSTITUTION_SUCCESS action when saving institution successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, + { + type: ActionConstants.SAVE_INSTITUTION_SUCCESS, + key: null, + actionFlag: ACTION_FLAG.UPDATE_ENTITY, + institution, + }, + { type: ActionConstants.LOAD_INSTITUTIONS_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("institution.save-success") }, + { type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions }, + ]; + + mockApi.onPut(`${API_URL}/rest/institutions/${institution.key}`).reply(200, null, { location }); + mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); + + store.dispatch(updateInstitution(institution)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SAVE_INSTITUTION_ERROR action if an error occurred during updating institution", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_INSTITUTION_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, + { type: ActionConstants.SAVE_INSTITUTION_ERROR, actionFlag: ACTION_FLAG.UPDATE_ENTITY, error, institution }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("institution.save-error", { error: error.message }), + }, + ]; + + mockApi.onPut(`${API_URL}/rest/institutions/${institution.key}`).reply(400, error); + + store.dispatch(updateInstitution(institution)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates DELETE_INSTITUTION_SUCCESS action when deleting institution successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.DELETE_INSTITUTION_PENDING, key: institution.key }, + { type: ActionConstants.LOAD_INSTITUTIONS_PENDING }, + { type: ActionConstants.DELETE_INSTITUTION_SUCCESS, institution }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("institution.delete-success") }, + { type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions }, + ]; + + mockApi.onDelete(`${API_URL}/rest/institutions/${institution.key}`).reply(200); + mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); + + store.dispatch(deleteInstitution(institution)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates DELETE_INSTITUTION_ERROR action if an error occurred during institution delete", function (done) { + const expectedActions = [ + { type: ActionConstants.DELETE_INSTITUTION_PENDING, key: institution.key }, + { type: ActionConstants.DELETE_INSTITUTION_ERROR, error, institution }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("institution.delete-error", { error: undefined }), + }, + ]; + + mockApi.onDelete(`${API_URL}/rest/institutions/${institution.key}`).reply(400, error); + + store.dispatch(deleteInstitution(institution)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_INSTITUTION_SUCCESS action when loading institution successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_INSTITUTION_PENDING }, + { type: ActionConstants.LOAD_INSTITUTION_SUCCESS, institution }, + ]; + + mockApi.onGet(`${API_URL}/rest/institutions/${institution.key}`).reply(200, { key: institution.key }); + + store.dispatch(loadInstitution(institution.key)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_INSTITUTION_ERROR action if an error occurred during loading institution", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_INSTITUTION_PENDING }, + { type: ActionConstants.LOAD_INSTITUTION_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("institution.load-error", { error: error.message }), + }, + ]; + + mockApi.onGet(`${API_URL}/rest/institutions/${institution.key}`).reply(400, error); + + store.dispatch(loadInstitution(institution.key)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/InstitutionsActions.spec.js b/tests/__tests__/actions/InstitutionsActions.spec.js index 6b6574c5..eb5abaab 100644 --- a/tests/__tests__/actions/InstitutionsActions.spec.js +++ b/tests/__tests__/actions/InstitutionsActions.spec.js @@ -1,98 +1,100 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; +import MockAdapter from "axios-mock-adapter"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; import { - loadInstitutions, - loadInstitutionsError, - loadInstitutionsPending, - loadInstitutionsSuccess + loadInstitutions, + loadInstitutionsError, + loadInstitutionsPending, + loadInstitutionsSuccess, } from "../../../js/actions/InstitutionsActions"; -import {API_URL} from '../../../config'; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; -import {errorMessage} from "../../../js/model/Message"; - -const institutions = [{key: 786785600}, {key: 86875960}]; - -describe('Institutions synchronize actions', function () { - it('creates an action to fetch all institutions', () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTIONS_PENDING, - }; - expect(loadInstitutionsPending()).toEqual(expectedAction) - }); - - it('creates an action to save fetched institutions', () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, - institutions - }; - expect(loadInstitutionsSuccess(institutions)).toEqual(expectedAction) - }); - - it('creates an action about error during fetching institutions', () => { - const error = {message: 'error'}; - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTIONS_ERROR, - error - }; - expect(loadInstitutionsError(error)).toEqual(expectedAction) - }); +import { API_URL } from "../../../config"; +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; +import { errorMessage } from "../../../js/model/Message"; + +const institutions = [{ key: 786785600 }, { key: 86875960 }]; + +describe("Institutions synchronize actions", function () { + it("creates an action to fetch all institutions", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTIONS_PENDING, + }; + expect(loadInstitutionsPending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched institutions", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, + institutions, + }; + expect(loadInstitutionsSuccess(institutions)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching institutions", () => { + const error = { message: "error" }; + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTIONS_ERROR, + error, + }; + expect(loadInstitutionsError(error)).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Institutions asynchronize actions', function () { - let store, - mockApi; - const error = { - "message" : "An error has occurred.", - "requestUri": "/rest/institutions/xxx" - }; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore(); - mockDateNow(); - }); - - afterEach(() => { - restoreDateNow(); - }); - - it('creates LOAD_INSTITUTIONS_SUCCESS action when loading institutions successfully is done', function (done) { - const expectedActions = [ - { type: ActionConstants.LOAD_INSTITUTIONS_PENDING}, - { type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions} - ]; - - mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); - - store.dispatch(loadInstitutions()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_INSTITUTIONS_ERROR action if an error occurred during loading institutions', function (done) { - const expectedActions = [ - { type: ActionConstants.LOAD_INSTITUTIONS_PENDING}, - { type: ActionConstants.LOAD_INSTITUTIONS_ERROR, error}, - { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('institutions.loading-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/institutions`).reply(400, error); - - store.dispatch(loadInstitutions()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file +describe("Institutions asynchronize actions", function () { + let store, mockApi; + const error = { + message: "An error has occurred.", + requestUri: "/rest/institutions/xxx", + }; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore(); + mockDateNow(); + }); + + afterEach(() => { + restoreDateNow(); + }); + + it("creates LOAD_INSTITUTIONS_SUCCESS action when loading institutions successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_INSTITUTIONS_PENDING }, + { type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, institutions }, + ]; + + mockApi.onGet(`${API_URL}/rest/institutions`).reply(200, institutions); + + store.dispatch(loadInstitutions()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_INSTITUTIONS_ERROR action if an error occurred during loading institutions", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_INSTITUTIONS_PENDING }, + { type: ActionConstants.LOAD_INSTITUTIONS_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("institutions.loading-error", { error: error.message }), + }, + ]; + + mockApi.onGet(`${API_URL}/rest/institutions`).reply(400, error); + + store.dispatch(loadInstitutions()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/RecordActions.spec.js b/tests/__tests__/actions/RecordActions.spec.js index 5d3f1e06..fab90c53 100644 --- a/tests/__tests__/actions/RecordActions.spec.js +++ b/tests/__tests__/actions/RecordActions.spec.js @@ -1,288 +1,284 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; -import {ACTION_FLAG, ROLE} from "../../../js/constants/DefaultConstants"; +import MockAdapter from "axios-mock-adapter"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; +import { ACTION_FLAG, ROLE } from "../../../js/constants/DefaultConstants"; import { - createRecord, - deleteRecord, - deleteRecordError, - deleteRecordPending, - deleteRecordSuccess, - loadRecord, - loadRecordError, - loadRecordPending, - loadRecordSuccess, - saveRecordError, - saveRecordPending, - saveRecordSuccess, - unloadRecord, - unloadSavedRecord, - updateRecord + createRecord, + deleteRecord, + deleteRecordError, + deleteRecordPending, + deleteRecordSuccess, + loadRecord, + loadRecordError, + loadRecordPending, + loadRecordSuccess, + saveRecordError, + saveRecordPending, + saveRecordSuccess, + unloadRecord, + unloadSavedRecord, + updateRecord, } from "../../../js/actions/RecordActions"; -import {API_URL} from '../../../config'; +import { API_URL } from "../../../config"; import en from "../../../js/i18n/en"; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; -import {errorMessage, successMessage} from "../../../js/model/Message"; - -describe('Record synchronous actions', function () { - const record = {key: 7979868757}, - key = 7979868757, - error = {message: 'error'}; - - it('creates an action to save record', () => { - const actionFlag = ACTION_FLAG.CREATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_RECORD_PENDING, - actionFlag - }; - expect(saveRecordPending(actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to announce successful save of record', () => { - const actionFlag = ACTION_FLAG.CREATE_ENTITY ; - const expectedAction = { - type: ActionConstants.SAVE_RECORD_SUCCESS, - record, - key, - actionFlag - }; - expect(saveRecordSuccess(record, key, actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to announce unsuccessful save of record', () => { - const actionFlag = ACTION_FLAG.UPDATE_ENTITY ; - const expectedAction = { - type: ActionConstants.SAVE_RECORD_ERROR, - error, - record, - actionFlag, - }; - expect(saveRecordError(error, record, actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to unload saved record', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_SAVED_RECORD - }; - expect(unloadSavedRecord()).toEqual(expectedAction) - }); - - it('creates an action to delete record', () => { - const expectedAction = { - type: ActionConstants.DELETE_RECORD_PENDING, - key - }; - expect(deleteRecordPending(key)).toEqual(expectedAction) - }); - - it('creates an action to announce successful delete of record', () => { - const expectedAction = { - type: ActionConstants.DELETE_RECORD_SUCCESS, - record, - key - }; - expect(deleteRecordSuccess(record, key)).toEqual(expectedAction) - }); - - it('creates an action to announce unsuccessful delete of record', () => { - const expectedAction = { - type: ActionConstants.DELETE_RECORD_ERROR, - error, - record, - key - }; - expect(deleteRecordError(error, record, key)).toEqual(expectedAction) - }); - - it('creates an action to fetch record', () => { - const expectedAction = { - type: ActionConstants.LOAD_RECORD_PENDING, - }; - expect(loadRecordPending()).toEqual(expectedAction) - }); - - it('creates an action to save fetched record', () => { - const expectedAction = { - type: ActionConstants.LOAD_RECORD_SUCCESS, - record - }; - expect(loadRecordSuccess(record)).toEqual(expectedAction) - }); - - it('creates an action about error during fetching record', () => { - const expectedAction = { - type: ActionConstants.LOAD_RECORD_ERROR, - error - }; - expect(loadRecordError(error)).toEqual(expectedAction) - }); - - it('creates an action to unload loaded record', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_RECORD, - }; - expect(unloadRecord()).toEqual(expectedAction) - }); +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; +import { errorMessage, successMessage } from "../../../js/model/Message"; + +describe("Record synchronous actions", function () { + const record = { key: 7979868757 }, + key = 7979868757, + error = { message: "error" }; + + it("creates an action to save record", () => { + const actionFlag = ACTION_FLAG.CREATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_RECORD_PENDING, + actionFlag, + }; + expect(saveRecordPending(actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to announce successful save of record", () => { + const actionFlag = ACTION_FLAG.CREATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_RECORD_SUCCESS, + record, + key, + actionFlag, + }; + expect(saveRecordSuccess(record, key, actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to announce unsuccessful save of record", () => { + const actionFlag = ACTION_FLAG.UPDATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_RECORD_ERROR, + error, + record, + actionFlag, + }; + expect(saveRecordError(error, record, actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to unload saved record", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_SAVED_RECORD, + }; + expect(unloadSavedRecord()).toEqual(expectedAction); + }); + + it("creates an action to delete record", () => { + const expectedAction = { + type: ActionConstants.DELETE_RECORD_PENDING, + key, + }; + expect(deleteRecordPending(key)).toEqual(expectedAction); + }); + + it("creates an action to announce successful delete of record", () => { + const expectedAction = { + type: ActionConstants.DELETE_RECORD_SUCCESS, + record, + key, + }; + expect(deleteRecordSuccess(record, key)).toEqual(expectedAction); + }); + + it("creates an action to announce unsuccessful delete of record", () => { + const expectedAction = { + type: ActionConstants.DELETE_RECORD_ERROR, + error, + record, + key, + }; + expect(deleteRecordError(error, record, key)).toEqual(expectedAction); + }); + + it("creates an action to fetch record", () => { + const expectedAction = { + type: ActionConstants.LOAD_RECORD_PENDING, + }; + expect(loadRecordPending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched record", () => { + const expectedAction = { + type: ActionConstants.LOAD_RECORD_SUCCESS, + record, + }; + expect(loadRecordSuccess(record)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching record", () => { + const expectedAction = { + type: ActionConstants.LOAD_RECORD_ERROR, + error, + }; + expect(loadRecordError(error)).toEqual(expectedAction); + }); + + it("creates an action to unload loaded record", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_RECORD, + }; + expect(unloadRecord()).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Record asynchronous actions', function () { - let store, - mockApi; - const error = { - "message" : "An error has occurred.", - "requestUri": "/rest/institutions/xxx" - }, - record = {key: 696875909}, - records = [ - {key: 7986787608}, - {key: 8968756596} - ], - currentUser = { - role: ROLE.ADMIN - }, - key = '696875909', - location = `rest/records/${key}`; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore({intl: en, auth: {user: currentUser}}); - mockDateNow(); - }); - - afterEach(() => { - restoreDateNow(); - }); - - it('creates SAVE_RECORD_SUCCESS action when saving record successfully is done', function (done) { - const expectedActions = [ - { type: ActionConstants.SAVE_RECORD_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY }, - { type: ActionConstants.SAVE_RECORD_SUCCESS, key, actionFlag: ACTION_FLAG.CREATE_ENTITY, record}, - { type: ActionConstants.LOAD_RECORDS_PENDING}, - { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("record.save-success")}, - {type: ActionConstants.LOAD_RECORDS_SUCCESS, records} - ]; - - mockApi.onPost(`${API_URL}/rest/records`).reply(200, null, {location}); - mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); - - store.dispatch(createRecord(record)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates UPDATE_RECORD_SUCCESS action when saving record successfully is done', function (done) { - const expectedActions = [ - { type: ActionConstants.SAVE_RECORD_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, - { type: ActionConstants.SAVE_RECORD_SUCCESS, key: null, actionFlag: ACTION_FLAG.UPDATE_ENTITY, record}, - { type: ActionConstants.LOAD_RECORDS_PENDING}, - { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("record.save-success")}, - {type: ActionConstants.LOAD_RECORDS_SUCCESS, records} - ]; - - mockApi.onPut(`${API_URL}/rest/records/${record.key}`).reply(200, null, {location}); - mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); - - store.dispatch(updateRecord(record)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates SAVE_RECORD_ERROR action if an error occurred during updating record', function (done) { - const expectedActions = [ - { type: ActionConstants.SAVE_RECORD_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, - { type: ActionConstants.SAVE_RECORD_ERROR, actionFlag: ACTION_FLAG.UPDATE_ENTITY, error, record}, - { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('record.save-error', {error: undefined})} - ]; - - mockApi.onPut(`${API_URL}/rest/records/${record.key}`).reply(400, error); - - store.dispatch(updateRecord(record)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates DELETE_RECORD_SUCCESS action when deleting record successfully is done', function (done) { - const expectedActions = [ - { type: ActionConstants.DELETE_RECORD_PENDING, key: record.key}, - { type: ActionConstants.LOAD_RECORDS_PENDING}, - { type: ActionConstants.DELETE_RECORD_SUCCESS, record, key: record.key}, - { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("record.delete-success")}, - {type: ActionConstants.LOAD_RECORDS_SUCCESS, records} - ]; - - mockApi.onDelete(`${API_URL}/rest/records/${record.key}`).reply(200); - mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); - - store.dispatch(deleteRecord(record)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates DELETE_RECORD_ERROR action if an error occurred during deleting record', function (done) { - const expectedActions = [ - { type: ActionConstants.DELETE_RECORD_PENDING, key: record.key}, - { type: ActionConstants.DELETE_RECORD_ERROR, error, record, key: record.key}, - { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('record.delete-error', {error: error.message})} - ]; - - mockApi.onDelete(`${API_URL}/rest/records/${record.key}`).reply(400, error); - - store.dispatch(deleteRecord(record)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_RECORD_SUCCESS action when loading record successfully is done', function (done) { - const expectedActions = [ - { type: ActionConstants.LOAD_RECORD_PENDING}, - { type: ActionConstants.LOAD_RECORD_SUCCESS, record} - ]; - - mockApi.onGet(`${API_URL}/rest/records/${record.key}`).reply(200, {key: record.key}); - - store.dispatch(loadRecord(record.key)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_RECORD_ERROR action if an error occurred during loading record', function (done) { - const expectedActions = [ - { type: ActionConstants.LOAD_RECORD_PENDING}, - { type: ActionConstants.LOAD_RECORD_ERROR, error}, - { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('record.load-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/records/${record.key}`).reply(400, error); - - store.dispatch(loadRecord(record.key)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file +describe("Record asynchronous actions", function () { + let store, mockApi; + const error = { + message: "An error has occurred.", + requestUri: "/rest/institutions/xxx", + }, + record = { key: 696875909 }, + records = [{ key: 7986787608 }, { key: 8968756596 }], + currentUser = { + role: ROLE.ADMIN, + }, + key = "696875909", + location = `rest/records/${key}`; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore({ intl: en, auth: { user: currentUser } }); + mockDateNow(); + }); + + afterEach(() => { + restoreDateNow(); + }); + + it("creates SAVE_RECORD_SUCCESS action when saving record successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_RECORD_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY }, + { type: ActionConstants.SAVE_RECORD_SUCCESS, key, actionFlag: ACTION_FLAG.CREATE_ENTITY, record }, + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("record.save-success") }, + { type: ActionConstants.LOAD_RECORDS_SUCCESS, records }, + ]; + + mockApi.onPost(`${API_URL}/rest/records`).reply(200, null, { location }); + mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); + + store.dispatch(createRecord(record)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates UPDATE_RECORD_SUCCESS action when saving record successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_RECORD_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, + { type: ActionConstants.SAVE_RECORD_SUCCESS, key: null, actionFlag: ACTION_FLAG.UPDATE_ENTITY, record }, + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("record.save-success") }, + { type: ActionConstants.LOAD_RECORDS_SUCCESS, records }, + ]; + + mockApi.onPut(`${API_URL}/rest/records/${record.key}`).reply(200, null, { location }); + mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); + + store.dispatch(updateRecord(record)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SAVE_RECORD_ERROR action if an error occurred during updating record", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_RECORD_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, + { type: ActionConstants.SAVE_RECORD_ERROR, actionFlag: ACTION_FLAG.UPDATE_ENTITY, error, record }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("record.save-error", { error: undefined }) }, + ]; + + mockApi.onPut(`${API_URL}/rest/records/${record.key}`).reply(400, error); + + store.dispatch(updateRecord(record)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates DELETE_RECORD_SUCCESS action when deleting record successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.DELETE_RECORD_PENDING, key: record.key }, + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.DELETE_RECORD_SUCCESS, record, key: record.key }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("record.delete-success") }, + { type: ActionConstants.LOAD_RECORDS_SUCCESS, records }, + ]; + + mockApi.onDelete(`${API_URL}/rest/records/${record.key}`).reply(200); + mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); + + store.dispatch(deleteRecord(record)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates DELETE_RECORD_ERROR action if an error occurred during deleting record", function (done) { + const expectedActions = [ + { type: ActionConstants.DELETE_RECORD_PENDING, key: record.key }, + { type: ActionConstants.DELETE_RECORD_ERROR, error, record, key: record.key }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("record.delete-error", { error: error.message }) }, + ]; + + mockApi.onDelete(`${API_URL}/rest/records/${record.key}`).reply(400, error); + + store.dispatch(deleteRecord(record)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_RECORD_SUCCESS action when loading record successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_RECORD_PENDING }, + { type: ActionConstants.LOAD_RECORD_SUCCESS, record }, + ]; + + mockApi.onGet(`${API_URL}/rest/records/${record.key}`).reply(200, { key: record.key }); + + store.dispatch(loadRecord(record.key)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_RECORD_ERROR action if an error occurred during loading record", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_RECORD_PENDING }, + { type: ActionConstants.LOAD_RECORD_ERROR, error }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("record.load-error", { error: error.message }) }, + ]; + + mockApi.onGet(`${API_URL}/rest/records/${record.key}`).reply(400, error); + + store.dispatch(loadRecord(record.key)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/RecordsActions.spec.js b/tests/__tests__/actions/RecordsActions.spec.js index fa1bfd00..263e2539 100644 --- a/tests/__tests__/actions/RecordsActions.spec.js +++ b/tests/__tests__/actions/RecordsActions.spec.js @@ -1,144 +1,146 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; -import {ROLE} from "../../../js/constants/DefaultConstants"; +import MockAdapter from "axios-mock-adapter"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; +import { ROLE } from "../../../js/constants/DefaultConstants"; import { - loadRecords, - loadRecordsByInstitution, - loadRecordsError, - loadRecordsPending, - loadRecordsSuccess + loadRecords, + loadRecordsByInstitution, + loadRecordsError, + loadRecordsPending, + loadRecordsSuccess, } from "../../../js/actions/RecordsActions"; -import {API_URL} from '../../../config'; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; -import {errorMessage} from "../../../js/model/Message"; +import { API_URL } from "../../../config"; +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; +import { errorMessage } from "../../../js/model/Message"; import en from "../../../js/i18n/en"; -const records = [{key: 786785600}, {key: 86875960}]; - -describe('Records synchronous actions', function () { - it('creates an action to fetch all records', () => { - const expectedAction = { - type: ActionConstants.LOAD_RECORDS_PENDING, - }; - expect(loadRecordsPending()).toEqual(expectedAction) - }); - - it('creates an action to save fetched records', () => { - const expectedAction = { - type: ActionConstants.LOAD_RECORDS_SUCCESS, - records - }; - expect(loadRecordsSuccess(records)).toEqual(expectedAction) - }); - - it('creates an action about error during fetching records', () => { - const error = {message: 'error'}; - const expectedAction = { - type: ActionConstants.LOAD_RECORDS_ERROR, - error - }; - expect(loadRecordsError(error)).toEqual(expectedAction) - }); +const records = [{ key: 786785600 }, { key: 86875960 }]; + +describe("Records synchronous actions", function () { + it("creates an action to fetch all records", () => { + const expectedAction = { + type: ActionConstants.LOAD_RECORDS_PENDING, + }; + expect(loadRecordsPending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched records", () => { + const expectedAction = { + type: ActionConstants.LOAD_RECORDS_SUCCESS, + records, + }; + expect(loadRecordsSuccess(records)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching records", () => { + const error = { message: "error" }; + const expectedAction = { + type: ActionConstants.LOAD_RECORDS_ERROR, + error, + }; + expect(loadRecordsError(error)).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Records asynchronous actions', function () { - let store, - mockApi; - const error = { - "message": "An error has occurred.", - "requestUri": "/rest/records/xxx" - }, - doctor = { - role: ROLE.DOCTOR, - institution: { - key: 12345678 - } - }, - admin = { - role: ROLE.ADMIN - }, - institutionKey = 12345678; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore({intl: en, auth: {user: admin}}); - mockDateNow(); - }); - - afterEach(() => { - restoreDateNow(); - }); - - it('creates LOAD_RECORDS_SUCCESS action when loading all records successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_RECORDS_PENDING}, - {type: ActionConstants.LOAD_RECORDS_SUCCESS, records} - ]; - - mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); - - store.dispatch(loadRecords()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates LOAD_RECORDS_SUCCESS action when loading doctor's institution records is done successfully", function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_RECORDS_PENDING}, - {type: ActionConstants.LOAD_RECORDS_SUCCESS, records} - ]; - store.getState().auth.user = doctor; - - mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); - - store.dispatch(loadRecords()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_RECORDS_SUCCESS action when loading institution records by institution key is done successfully', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_RECORDS_PENDING}, - {type: ActionConstants.LOAD_RECORDS_SUCCESS, records} - ]; - - mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); - - store.dispatch(loadRecordsByInstitution(institutionKey)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_RECORDS_ERROR action if an error occurred during loading records', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_RECORDS_PENDING}, - {type: ActionConstants.LOAD_RECORDS_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('records.loading-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/records`).reply(400, error); - - store.dispatch(loadRecords()); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file +describe("Records asynchronous actions", function () { + let store, mockApi; + const error = { + message: "An error has occurred.", + requestUri: "/rest/records/xxx", + }, + doctor = { + role: ROLE.DOCTOR, + institution: { + key: 12345678, + }, + }, + admin = { + role: ROLE.ADMIN, + }, + institutionKey = 12345678; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore({ intl: en, auth: { user: admin } }); + mockDateNow(); + }); + + afterEach(() => { + restoreDateNow(); + }); + + it("creates LOAD_RECORDS_SUCCESS action when loading all records successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.LOAD_RECORDS_SUCCESS, records }, + ]; + + mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); + + store.dispatch(loadRecords()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_RECORDS_SUCCESS action when loading doctor's institution records is done successfully", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.LOAD_RECORDS_SUCCESS, records }, + ]; + store.getState().auth.user = doctor; + + mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); + + store.dispatch(loadRecords()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_RECORDS_SUCCESS action when loading institution records by institution key is done successfully", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.LOAD_RECORDS_SUCCESS, records }, + ]; + + mockApi.onGet(`${API_URL}/rest/records`).reply(200, records, {}); + + store.dispatch(loadRecordsByInstitution(institutionKey)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_RECORDS_ERROR action if an error occurred during loading records", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_RECORDS_PENDING }, + { type: ActionConstants.LOAD_RECORDS_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("records.loading-error", { error: error.message }), + }, + ]; + + mockApi.onGet(`${API_URL}/rest/records`).reply(400, error); + + store.dispatch(loadRecords()); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/RouterActions.spec.js b/tests/__tests__/actions/RouterActions.spec.js index 494f68f4..b4057b4c 100644 --- a/tests/__tests__/actions/RouterActions.spec.js +++ b/tests/__tests__/actions/RouterActions.spec.js @@ -1,26 +1,26 @@ import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {setTransitionPayload, setViewHandlers} from "../../../js/actions/RouterActions"; +import { setTransitionPayload, setViewHandlers } from "../../../js/actions/RouterActions"; -describe('Router synchronize actions', function () { - const routeName = "user", - payload = {data: 123456}, - handlers = {onEvent: jest.fn()}; +describe("Router synchronize actions", function () { + const routeName = "user", + payload = { data: 123456 }, + handlers = { onEvent: jest.fn() }; - it('creates an action to set view handlers', () => { - const expectedAction = { - type: ActionConstants.SET_VIEW_HANDLERS, - routeName, - handlers - }; - expect(setViewHandlers(routeName, handlers)).toEqual(expectedAction) - }); + it("creates an action to set view handlers", () => { + const expectedAction = { + type: ActionConstants.SET_VIEW_HANDLERS, + routeName, + handlers, + }; + expect(setViewHandlers(routeName, handlers)).toEqual(expectedAction); + }); - it('creates an action to set transition payload', () => { - const expectedAction = { - type: ActionConstants.SET_TRANSITION_PAYLOAD, - routeName, - payload - }; - expect(setTransitionPayload(routeName, payload)).toEqual(expectedAction) - }); -}); \ No newline at end of file + it("creates an action to set transition payload", () => { + const expectedAction = { + type: ActionConstants.SET_TRANSITION_PAYLOAD, + routeName, + payload, + }; + expect(setTransitionPayload(routeName, payload)).toEqual(expectedAction); + }); +}); diff --git a/tests/__tests__/actions/StatisticsActions.spec.js b/tests/__tests__/actions/StatisticsActions.spec.js index e5ea1628..5497bfa5 100644 --- a/tests/__tests__/actions/StatisticsActions.spec.js +++ b/tests/__tests__/actions/StatisticsActions.spec.js @@ -1,65 +1,67 @@ import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; -import MockAdapter from 'axios-mock-adapter'; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; +import MockAdapter from "axios-mock-adapter"; import thunk from "redux-thunk"; import configureMockStore from "redux-mock-store"; -import {loadStatistics} from "../../../js/actions/StatisticsActions"; -import {API_URL} from '../../../config'; -import {errorMessage} from "../../../js/model/Message"; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; +import { loadStatistics } from "../../../js/actions/StatisticsActions"; +import { API_URL } from "../../../config"; +import { errorMessage } from "../../../js/model/Message"; +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Statistics asynchronous actions', function () { - let store, - mockApi; - const payload = {numberOfPatients: 5, numberOfInstitutions: 10}, - error = { - "message": "An error has occurred.", - }; +describe("Statistics asynchronous actions", function () { + let store, mockApi; + const payload = { numberOfPatients: 5, numberOfInstitutions: 10 }, + error = { + message: "An error has occurred.", + }; - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore(); - mockDateNow(); - }); + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore(); + mockDateNow(); + }); - afterEach(() => { - restoreDateNow(); - }); + afterEach(() => { + restoreDateNow(); + }); - it('creates LOAD_STATISTICS_SUCCESS action when loading statistics is successfully done', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_STATISTICS_PENDING}, - {type: ActionConstants.LOAD_STATISTICS_SUCCESS, payload} - ]; + it("creates LOAD_STATISTICS_SUCCESS action when loading statistics is successfully done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_STATISTICS_PENDING }, + { type: ActionConstants.LOAD_STATISTICS_SUCCESS, payload }, + ]; - mockApi.onGet(`${API_URL}/rest/statistics`).reply(200, payload); + mockApi.onGet(`${API_URL}/rest/statistics`).reply(200, payload); - store.dispatch(loadStatistics()); + store.dispatch(loadStatistics()); - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); - it('creates LOAD_STATISTICS_ERROR action if an error occurred during loading statistics', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_STATISTICS_PENDING}, - {type: ActionConstants.LOAD_STATISTICS_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('history.loading-error', {error: error.message})} - ]; + it("creates LOAD_STATISTICS_ERROR action if an error occurred during loading statistics", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_STATISTICS_PENDING }, + { type: ActionConstants.LOAD_STATISTICS_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("history.loading-error", { error: error.message }), + }, + ]; - mockApi.onGet(`${API_URL}/rest/statistics`).reply(400, error); + mockApi.onGet(`${API_URL}/rest/statistics`).reply(400, error); - store.dispatch(loadStatistics()); + store.dispatch(loadStatistics()); - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/actions/UserActions.spec.js b/tests/__tests__/actions/UserActions.spec.js index b6f6a949..43d8141f 100644 --- a/tests/__tests__/actions/UserActions.spec.js +++ b/tests/__tests__/actions/UserActions.spec.js @@ -1,546 +1,558 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {ACTION_FLAG, ROLE} from "../../../js/constants/DefaultConstants"; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; +import MockAdapter from "axios-mock-adapter"; +import { ACTION_FLAG, ROLE } from "../../../js/constants/DefaultConstants"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; import { - changePassword, - createUser, deleteInvitationOption, - deleteUser, - deleteUserError, - deleteUserPending, - deleteUserSuccess, generateUsername, impersonate, - loadInstitutionMembers, - loadInstitutionMembersError, - loadInstitutionMembersPending, - loadInstitutionMembersSuccess, - loadUser, - loadUserError, - loadUserPending, - loadUserSuccess, - saveUserError, - saveUserPending, - saveUserSuccess, sendInvitation, unloadInstitutionMembers, - unloadSavedUser, - unloadUser, - updateUser + changePassword, + createUser, + deleteInvitationOption, + deleteUser, + deleteUserError, + deleteUserPending, + deleteUserSuccess, + generateUsername, + impersonate, + loadInstitutionMembers, + loadInstitutionMembersError, + loadInstitutionMembersPending, + loadInstitutionMembersSuccess, + loadUser, + loadUserError, + loadUserPending, + loadUserSuccess, + saveUserError, + saveUserPending, + saveUserSuccess, + sendInvitation, + unloadInstitutionMembers, + unloadSavedUser, + unloadUser, + updateUser, } from "../../../js/actions/UserActions"; -import {API_URL} from '../../../config'; +import { API_URL } from "../../../config"; import en from "../../../js/i18n/en"; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; -import {errorMessage, successMessage} from "../../../js/model/Message"; - -const members = [ - {username: 'record1'}, - {username: 'record2'} -]; - -describe('User synchronous actions', function () { - const user = {username: 'test'}, - error = {message: 'error'}; - - it('creates an action to save user', () => { - const actionFlag = ACTION_FLAG.CREATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_USER_PENDING, - actionFlag - }; - expect(saveUserPending(actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to announce successful save of user', () => { - const actionFlag = ACTION_FLAG.CREATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_USER_SUCCESS, - user, - actionFlag - }; - expect(saveUserSuccess(user, actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to announce unsuccessful save of user', () => { - const actionFlag = ACTION_FLAG.UPDATE_ENTITY; - const expectedAction = { - type: ActionConstants.SAVE_USER_ERROR, - error, - user, - actionFlag, - }; - expect(saveUserError(error, user, actionFlag)).toEqual(expectedAction) - }); - - it('creates an action to unload saved user', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_SAVED_USER - }; - expect(unloadSavedUser()).toEqual(expectedAction) - }); - - it('creates an action to delete user', () => { - const username = user.username; - const expectedAction = { - type: ActionConstants.DELETE_USER_PENDING, - username - }; - expect(deleteUserPending(username)).toEqual(expectedAction) - }); - - it('creates an action to announce successful delete of user', () => { - const expectedAction = { - type: ActionConstants.DELETE_USER_SUCCESS, - user - }; - expect(deleteUserSuccess(user)).toEqual(expectedAction) - }); - - it('creates an action to announce unsuccessful delete of user', () => { - const expectedAction = { - type: ActionConstants.DELETE_USER_ERROR, - error, - user - }; - expect(deleteUserError(error, user)).toEqual(expectedAction) - }); - - it('creates an action to fetch user', () => { - const expectedAction = { - type: ActionConstants.LOAD_USER_PENDING, - }; - expect(loadUserPending()).toEqual(expectedAction) - }); - - it('creates an action to save fetched user', () => { - const expectedAction = { - type: ActionConstants.LOAD_USER_SUCCESS, - user - }; - expect(loadUserSuccess(user)).toEqual(expectedAction) - }); - - it('creates an action about error during fetching user', () => { - const expectedAction = { - type: ActionConstants.LOAD_USER_ERROR, - error - }; - expect(loadUserError(error)).toEqual(expectedAction) - }); - - it('creates an action to unload loaded user', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_USER, - }; - expect(unloadUser()).toEqual(expectedAction) - }); - - it("creates an action to fetch all institution's members", () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING, - }; - expect(loadInstitutionMembersPending()).toEqual(expectedAction) - }); - - it("creates an action to save fetched institution's members", () => { - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, - members - }; - expect(loadInstitutionMembersSuccess(members)).toEqual(expectedAction) - }); - - it("creates an action about error during fetching institution's members", () => { - const error = {message: 'error'}; - const expectedAction = { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, - error - }; - expect(loadInstitutionMembersError(error)).toEqual(expectedAction) - }); - - it('creates an action to unload institution members', () => { - const expectedAction = { - type: ActionConstants.UNLOAD_INSTITUTION_MEMBERS - }; - expect(unloadInstitutionMembers()).toEqual(expectedAction) - }); +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; +import { errorMessage, successMessage } from "../../../js/model/Message"; + +const members = [{ username: "record1" }, { username: "record2" }]; + +describe("User synchronous actions", function () { + const user = { username: "test" }, + error = { message: "error" }; + + it("creates an action to save user", () => { + const actionFlag = ACTION_FLAG.CREATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_USER_PENDING, + actionFlag, + }; + expect(saveUserPending(actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to announce successful save of user", () => { + const actionFlag = ACTION_FLAG.CREATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_USER_SUCCESS, + user, + actionFlag, + }; + expect(saveUserSuccess(user, actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to announce unsuccessful save of user", () => { + const actionFlag = ACTION_FLAG.UPDATE_ENTITY; + const expectedAction = { + type: ActionConstants.SAVE_USER_ERROR, + error, + user, + actionFlag, + }; + expect(saveUserError(error, user, actionFlag)).toEqual(expectedAction); + }); + + it("creates an action to unload saved user", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_SAVED_USER, + }; + expect(unloadSavedUser()).toEqual(expectedAction); + }); + + it("creates an action to delete user", () => { + const username = user.username; + const expectedAction = { + type: ActionConstants.DELETE_USER_PENDING, + username, + }; + expect(deleteUserPending(username)).toEqual(expectedAction); + }); + + it("creates an action to announce successful delete of user", () => { + const expectedAction = { + type: ActionConstants.DELETE_USER_SUCCESS, + user, + }; + expect(deleteUserSuccess(user)).toEqual(expectedAction); + }); + + it("creates an action to announce unsuccessful delete of user", () => { + const expectedAction = { + type: ActionConstants.DELETE_USER_ERROR, + error, + user, + }; + expect(deleteUserError(error, user)).toEqual(expectedAction); + }); + + it("creates an action to fetch user", () => { + const expectedAction = { + type: ActionConstants.LOAD_USER_PENDING, + }; + expect(loadUserPending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched user", () => { + const expectedAction = { + type: ActionConstants.LOAD_USER_SUCCESS, + user, + }; + expect(loadUserSuccess(user)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching user", () => { + const expectedAction = { + type: ActionConstants.LOAD_USER_ERROR, + error, + }; + expect(loadUserError(error)).toEqual(expectedAction); + }); + + it("creates an action to unload loaded user", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_USER, + }; + expect(unloadUser()).toEqual(expectedAction); + }); + + it("creates an action to fetch all institution's members", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING, + }; + expect(loadInstitutionMembersPending()).toEqual(expectedAction); + }); + + it("creates an action to save fetched institution's members", () => { + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, + members, + }; + expect(loadInstitutionMembersSuccess(members)).toEqual(expectedAction); + }); + + it("creates an action about error during fetching institution's members", () => { + const error = { message: "error" }; + const expectedAction = { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, + error, + }; + expect(loadInstitutionMembersError(error)).toEqual(expectedAction); + }); + + it("creates an action to unload institution members", () => { + const expectedAction = { + type: ActionConstants.UNLOAD_INSTITUTION_MEMBERS, + }; + expect(unloadInstitutionMembers()).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('User asynchronous actions', function () { - let store, - mockApi; - const user = {username: 'test'}, - users = [ - {username: 'test1'}, - {username: 'test2'} - ], - institutionKey = 92979802112, - error = { - "message": "An error has occurred.", - "requestUri": "/rest/users/xxx" - }, - username = 'test', - password = { - newPassword: 'aaaa', - currentPassword: '1234' - }, - currentUserAdmin = { - role: ROLE.ADMIN - }, - usernamePrefix = 'doctor'; - - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore({intl: en}); - mockDateNow(); - }); - - afterEach(() => { - restoreDateNow(); - }); - - it('creates SAVE_USER_SUCCESS action when saving user successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY}, - {type: ActionConstants.SAVE_USER_SUCCESS, actionFlag: ACTION_FLAG.CREATE_ENTITY, user}, - {type: ActionConstants.LOAD_USERS_PENDING}, - {type: ActionConstants.LOAD_USERS_SUCCESS, users}, - ]; - - mockApi.onPost(`${API_URL}/rest/users`).reply(200); - mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); - - store.dispatch(createUser(user)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates SAVE_USER_ERROR action if an error occurred during creating user', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY}, - {type: ActionConstants.SAVE_USER_ERROR, actionFlag: ACTION_FLAG.CREATE_ENTITY, error, user} - ]; - - mockApi.onPost(`${API_URL}/rest/users`).reply(400, error); - - store.dispatch(createUser(user)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates UPDATE_USER_SUCCESS action when saving user successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY}, - {type: ActionConstants.SAVE_USER_SUCCESS, actionFlag: ACTION_FLAG.UPDATE_ENTITY, user}, - {type: ActionConstants.LOAD_USERS_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage('user.save-success-with-email')}, - {type: ActionConstants.LOAD_USERS_SUCCESS, users} - ]; - - mockApi.onPut(`${API_URL}/rest/users/${user.username}`).reply(200); - mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); - - store.dispatch(updateUser(user, currentUserAdmin)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates SAVE_USER_ERROR action if an error occurred during updating user', function (done) { - const expectedActions = [ - {type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY}, - {type: ActionConstants.SAVE_USER_ERROR, actionFlag: ACTION_FLAG.UPDATE_ENTITY, error, user}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.save-error', {error: error.message})} - ]; - - mockApi.onPut(`${API_URL}/rest/users/${user.username}`).reply(400, error); - - store.dispatch(updateUser(user, currentUserAdmin)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates DELETE_USER_SUCCESS action when deleting user successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.DELETE_USER_PENDING, username}, - {type: ActionConstants.LOAD_USERS_PENDING}, - {type: ActionConstants.DELETE_USER_SUCCESS, user}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.delete-success")}, - {type: ActionConstants.LOAD_USERS_SUCCESS, users} - ]; - - mockApi.onDelete(`${API_URL}/rest/users/${user.username}`).reply(200); - mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); - - store.dispatch(deleteUser(user)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates DELETE_USER_ERROR action if an error occurred during deleting user', function (done) { - const expectedActions = [ - {type: ActionConstants.DELETE_USER_PENDING, username}, - {type: ActionConstants.DELETE_USER_ERROR, error, user}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.delete-error', {error: error.message})} - ]; - - mockApi.onDelete(`${API_URL}/rest/users/${user.username}`).reply(400, error); - - store.dispatch(deleteUser(user)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_USER_SUCCESS action when loading user successfully is done', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_USER_PENDING}, - {type: ActionConstants.LOAD_USER_SUCCESS, user} - ]; - - mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, {username}); - - store.dispatch(loadUser(user.username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it('creates LOAD_USER_ERROR action if an error occurred during loading user', function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_USER_PENDING}, - {type: ActionConstants.LOAD_USER_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.load-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(400, error); - - store.dispatch(loadUser(user.username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates LOAD_INSTITUTION_MEMBERS_SUCCESS action when loading institution's memebrs successfully is done", function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING}, - {type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, members} - ]; - - mockApi.onGet(`${API_URL}/rest/users?institution=${institutionKey}`).reply(200, members); - - store.dispatch(loadInstitutionMembers(institutionKey)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates LOAD_INSTITUTION_MEMBERS_ERROR action if an error occurred during loading institution's memebrs", function (done) { - const expectedActions = [ - {type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING}, - {type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('institution.members.loading-error', {error: error.message})} - ]; - - mockApi.onGet(`${API_URL}/rest/users?institution=${institutionKey}`).reply(400, error); - - store.dispatch(loadInstitutionMembers(institutionKey)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates PASSWORD_CHANGE_SUCCESS action when changing password successfully is done", function (done) { - const expectedActions = [ - {type: ActionConstants.PASSWORD_CHANGE_PENDING}, - {type: ActionConstants.PASSWORD_CHANGE_SUCCESS}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage('user.password-change-success-with-email')}, - ]; - - mockApi.onPut(`${API_URL}/rest/users/${username}/password-change`).reply(200); - - store.dispatch(changePassword(username, password)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates PASSWORD_CHANGE_ERROR action if an error occurred during changing password", function (done) { - const expectedActions = [ - {type: ActionConstants.PASSWORD_CHANGE_PENDING}, - {type: ActionConstants.PASSWORD_CHANGE_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.password-change-error', {error: undefined})} - ]; - - mockApi.onPut(`${API_URL}/rest/users/${username}/password-change`).reply(400, error); - - store.dispatch(changePassword(username, password)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates GENERATE_USERNAME_SUCCESS action when changing password successfully is done", function (done) { - const expectedActions = [ - {type: ActionConstants.GENERATE_USERNAME_PENDING}, - {type: ActionConstants.GENERATE_USERNAME_SUCCESS, generatedUsername: `${usernamePrefix}1`} - ]; - - mockApi.onGet(`${API_URL}/rest/users/generate-username/${usernamePrefix}`).reply(200, `${usernamePrefix}1`); - - store.dispatch(generateUsername(usernamePrefix)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates SEND_INVITATION_SUCCESS action when user is invited successfully", function (done) { - const expectedActions = [ - {type: ActionConstants.SEND_INVITATION_PENDING, username}, - {type: ActionConstants.SEND_INVITATION_SUCCESS, username}, - {type: ActionConstants.LOAD_USER_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.send-invitation-success")}, - {type: ActionConstants.LOAD_USER_SUCCESS, user} - ]; - - mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, {username}); - mockApi.onPut(`${API_URL}/rest/users/send-invitation/${username}`).reply(200); - - store.dispatch(sendInvitation(username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates SEND_INVITATION_ERROR action if an error occurred during user invitation", function (done) { - const expectedActions = [ - {type: ActionConstants.SEND_INVITATION_PENDING, username}, - {type: ActionConstants.SEND_INVITATION_ERROR, error}, - {type: ActionConstants.LOAD_USER_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.send-invitation-error', {error: error.message})}, - {type: ActionConstants.LOAD_USER_SUCCESS, user} - ]; - - mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, {username}); - mockApi.onPut(`${API_URL}/rest/users/send-invitation/${username}`).reply(400, error); - - store.dispatch(sendInvitation(username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates INVITATION_OPTION_DELETE_SUCCESS action when option to invite user is deleted successfully", function (done) { - const expectedActions = [ - {type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, username}, - {type: ActionConstants.INVITATION_OPTION_DELETE_SUCCESS, username}, - {type: ActionConstants.LOAD_USER_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.delete-invitation-option-success")}, - {type: ActionConstants.LOAD_USER_SUCCESS, user} - ]; - - mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, {username}); - mockApi.onPost(`${API_URL}/rest/users/send-invitation/delete`).reply(200); - - store.dispatch(deleteInvitationOption(username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates INVITATION_OPTION_DELETE_ERROR action if an error occurred during deleting option to invite user", function (done) { - const expectedActions = [ - {type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, username}, - {type: ActionConstants.INVITATION_OPTION_DELETE_ERROR, error}, - {type: ActionConstants.LOAD_USER_PENDING}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.delete-invitation-option-error', {error: error.message})}, - {type: ActionConstants.LOAD_USER_SUCCESS, user} - ]; - - mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, {username}); - mockApi.onPost(`${API_URL}/rest/users/send-invitation/delete`).reply(400, error); - - store.dispatch(deleteInvitationOption(username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates IMPERSONATE_SUCCESS action when user is successfully impersonated", function (done) { - delete window.location; - window.location = {reload: jest.fn()}; - - const expectedActions = [ - {type: ActionConstants.IMPERSONATE_PENDING}, - {type: ActionConstants.IMPERSONATE_SUCCESS, username} - ]; - - mockApi.onPost(`${API_URL}/rest/users/impersonate`).reply(200); - - store.dispatch(impersonate(username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - - it("creates IMPERSONATE_ERROR action if an error occurred during impersonating user", function (done) { - const expectedActions = [ - {type: ActionConstants.IMPERSONATE_PENDING}, - {type: ActionConstants.IMPERSONATE_ERROR, error}, - {type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('user.impersonate-error', {error: error.message})} - ]; - - mockApi.onPost(`${API_URL}/rest/users/impersonate`).reply(400, error); - - store.dispatch(impersonate(username)); - - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); - +describe("User asynchronous actions", function () { + let store, mockApi; + const user = { username: "test" }, + users = [{ username: "test1" }, { username: "test2" }], + institutionKey = 92979802112, + error = { + message: "An error has occurred.", + requestUri: "/rest/users/xxx", + }, + username = "test", + password = { + newPassword: "aaaa", + currentPassword: "1234", + }, + currentUserAdmin = { + role: ROLE.ADMIN, + }, + usernamePrefix = "doctor"; + + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore({ intl: en }); + mockDateNow(); + }); + + afterEach(() => { + restoreDateNow(); + }); + + it("creates SAVE_USER_SUCCESS action when saving user successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY }, + { type: ActionConstants.SAVE_USER_SUCCESS, actionFlag: ACTION_FLAG.CREATE_ENTITY, user }, + { type: ActionConstants.LOAD_USERS_PENDING }, + { type: ActionConstants.LOAD_USERS_SUCCESS, users }, + ]; + + mockApi.onPost(`${API_URL}/rest/users`).reply(200); + mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); + + store.dispatch(createUser(user)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SAVE_USER_ERROR action if an error occurred during creating user", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.CREATE_ENTITY }, + { type: ActionConstants.SAVE_USER_ERROR, actionFlag: ACTION_FLAG.CREATE_ENTITY, error, user }, + ]; + + mockApi.onPost(`${API_URL}/rest/users`).reply(400, error); + + store.dispatch(createUser(user)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates UPDATE_USER_SUCCESS action when saving user successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, + { type: ActionConstants.SAVE_USER_SUCCESS, actionFlag: ACTION_FLAG.UPDATE_ENTITY, user }, + { type: ActionConstants.LOAD_USERS_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.save-success-with-email") }, + { type: ActionConstants.LOAD_USERS_SUCCESS, users }, + ]; + + mockApi.onPut(`${API_URL}/rest/users/${user.username}`).reply(200); + mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); + + store.dispatch(updateUser(user, currentUserAdmin)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SAVE_USER_ERROR action if an error occurred during updating user", function (done) { + const expectedActions = [ + { type: ActionConstants.SAVE_USER_PENDING, actionFlag: ACTION_FLAG.UPDATE_ENTITY }, + { type: ActionConstants.SAVE_USER_ERROR, actionFlag: ACTION_FLAG.UPDATE_ENTITY, error, user }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("user.save-error", { error: error.message }) }, + ]; + + mockApi.onPut(`${API_URL}/rest/users/${user.username}`).reply(400, error); + + store.dispatch(updateUser(user, currentUserAdmin)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates DELETE_USER_SUCCESS action when deleting user successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.DELETE_USER_PENDING, username }, + { type: ActionConstants.LOAD_USERS_PENDING }, + { type: ActionConstants.DELETE_USER_SUCCESS, user }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.delete-success") }, + { type: ActionConstants.LOAD_USERS_SUCCESS, users }, + ]; + + mockApi.onDelete(`${API_URL}/rest/users/${user.username}`).reply(200); + mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); + + store.dispatch(deleteUser(user)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates DELETE_USER_ERROR action if an error occurred during deleting user", function (done) { + const expectedActions = [ + { type: ActionConstants.DELETE_USER_PENDING, username }, + { type: ActionConstants.DELETE_USER_ERROR, error, user }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("user.delete-error", { error: error.message }) }, + ]; + + mockApi.onDelete(`${API_URL}/rest/users/${user.username}`).reply(400, error); + + store.dispatch(deleteUser(user)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_USER_SUCCESS action when loading user successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_USER_PENDING }, + { type: ActionConstants.LOAD_USER_SUCCESS, user }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, { username }); + + store.dispatch(loadUser(user.username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_USER_ERROR action if an error occurred during loading user", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_USER_PENDING }, + { type: ActionConstants.LOAD_USER_ERROR, error }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("user.load-error", { error: error.message }) }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(400, error); + + store.dispatch(loadUser(user.username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_INSTITUTION_MEMBERS_SUCCESS action when loading institution's memebrs successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING }, + { type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, members }, + ]; + + mockApi.onGet(`${API_URL}/rest/users?institution=${institutionKey}`).reply(200, members); + + store.dispatch(loadInstitutionMembers(institutionKey)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates LOAD_INSTITUTION_MEMBERS_ERROR action if an error occurred during loading institution's memebrs", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING }, + { type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("institution.members.loading-error", { error: error.message }), + }, + ]; + + mockApi.onGet(`${API_URL}/rest/users?institution=${institutionKey}`).reply(400, error); + + store.dispatch(loadInstitutionMembers(institutionKey)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates PASSWORD_CHANGE_SUCCESS action when changing password successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.PASSWORD_CHANGE_PENDING }, + { type: ActionConstants.PASSWORD_CHANGE_SUCCESS }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.password-change-success-with-email") }, + ]; + + mockApi.onPut(`${API_URL}/rest/users/${username}/password-change`).reply(200); + + store.dispatch(changePassword(username, password)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates PASSWORD_CHANGE_ERROR action if an error occurred during changing password", function (done) { + const expectedActions = [ + { type: ActionConstants.PASSWORD_CHANGE_PENDING }, + { type: ActionConstants.PASSWORD_CHANGE_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("user.password-change-error", { error: undefined }), + }, + ]; + + mockApi.onPut(`${API_URL}/rest/users/${username}/password-change`).reply(400, error); + + store.dispatch(changePassword(username, password)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates GENERATE_USERNAME_SUCCESS action when changing password successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.GENERATE_USERNAME_PENDING }, + { type: ActionConstants.GENERATE_USERNAME_SUCCESS, generatedUsername: `${usernamePrefix}1` }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/generate-username/${usernamePrefix}`).reply(200, `${usernamePrefix}1`); + + store.dispatch(generateUsername(usernamePrefix)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SEND_INVITATION_SUCCESS action when user is invited successfully", function (done) { + const expectedActions = [ + { type: ActionConstants.SEND_INVITATION_PENDING, username }, + { type: ActionConstants.SEND_INVITATION_SUCCESS, username }, + { type: ActionConstants.LOAD_USER_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.send-invitation-success") }, + { type: ActionConstants.LOAD_USER_SUCCESS, user }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, { username }); + mockApi.onPut(`${API_URL}/rest/users/send-invitation/${username}`).reply(200); + + store.dispatch(sendInvitation(username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates SEND_INVITATION_ERROR action if an error occurred during user invitation", function (done) { + const expectedActions = [ + { type: ActionConstants.SEND_INVITATION_PENDING, username }, + { type: ActionConstants.SEND_INVITATION_ERROR, error }, + { type: ActionConstants.LOAD_USER_PENDING }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("user.send-invitation-error", { error: error.message }), + }, + { type: ActionConstants.LOAD_USER_SUCCESS, user }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, { username }); + mockApi.onPut(`${API_URL}/rest/users/send-invitation/${username}`).reply(400, error); + + store.dispatch(sendInvitation(username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates INVITATION_OPTION_DELETE_SUCCESS action when option to invite user is deleted successfully", function (done) { + const expectedActions = [ + { type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, username }, + { type: ActionConstants.INVITATION_OPTION_DELETE_SUCCESS, username }, + { type: ActionConstants.LOAD_USER_PENDING }, + { type: ActionConstants.PUBLISH_MESSAGE, message: successMessage("user.delete-invitation-option-success") }, + { type: ActionConstants.LOAD_USER_SUCCESS, user }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, { username }); + mockApi.onPost(`${API_URL}/rest/users/send-invitation/delete`).reply(200); + + store.dispatch(deleteInvitationOption(username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates INVITATION_OPTION_DELETE_ERROR action if an error occurred during deleting option to invite user", function (done) { + const expectedActions = [ + { type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, username }, + { type: ActionConstants.INVITATION_OPTION_DELETE_ERROR, error }, + { type: ActionConstants.LOAD_USER_PENDING }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("user.delete-invitation-option-error", { error: error.message }), + }, + { type: ActionConstants.LOAD_USER_SUCCESS, user }, + ]; + + mockApi.onGet(`${API_URL}/rest/users/${user.username}`).reply(200, { username }); + mockApi.onPost(`${API_URL}/rest/users/send-invitation/delete`).reply(400, error); + + store.dispatch(deleteInvitationOption(username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates IMPERSONATE_SUCCESS action when user is successfully impersonated", function (done) { + delete window.location; + window.location = { reload: jest.fn() }; + + const expectedActions = [ + { type: ActionConstants.IMPERSONATE_PENDING }, + { type: ActionConstants.IMPERSONATE_SUCCESS, username }, + ]; + + mockApi.onPost(`${API_URL}/rest/users/impersonate`).reply(200); + + store.dispatch(impersonate(username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); + + it("creates IMPERSONATE_ERROR action if an error occurred during impersonating user", function (done) { + const expectedActions = [ + { type: ActionConstants.IMPERSONATE_PENDING }, + { type: ActionConstants.IMPERSONATE_ERROR, error }, + { + type: ActionConstants.PUBLISH_MESSAGE, + message: errorMessage("user.impersonate-error", { error: error.message }), + }, + ]; + + mockApi.onPost(`${API_URL}/rest/users/impersonate`).reply(400, error); + + store.dispatch(impersonate(username)); + + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); }); diff --git a/tests/__tests__/actions/UsersActions.spec.js b/tests/__tests__/actions/UsersActions.spec.js index 5f0bf6f4..394311a2 100644 --- a/tests/__tests__/actions/UsersActions.spec.js +++ b/tests/__tests__/actions/UsersActions.spec.js @@ -1,93 +1,92 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import configureMockStore from "redux-mock-store"; +import thunk from "redux-thunk"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import MockAdapter from 'axios-mock-adapter'; -import {TEST_TIMEOUT} from "../../constants/DefaultTestConstants"; -import {axiosBackend} from "../../../js/actions"; -import {loadUsers, loadUsersError, loadUsersPending, loadUsersSuccess} from "../../../js/actions/UsersActions"; -import {API_URL} from '../../../config'; -import {mockDateNow, restoreDateNow} from "../../environment/Environment"; -import {errorMessage} from "../../../js/model/Message"; +import MockAdapter from "axios-mock-adapter"; +import { TEST_TIMEOUT } from "../../constants/DefaultTestConstants"; +import { axiosBackend } from "../../../js/actions"; +import { loadUsers, loadUsersError, loadUsersPending, loadUsersSuccess } from "../../../js/actions/UsersActions"; +import { API_URL } from "../../../config"; +import { mockDateNow, restoreDateNow } from "../../environment/Environment"; +import { errorMessage } from "../../../js/model/Message"; -describe('Users synchronous actions', function () { - it('creates an action to fetch all users', () => { - const expectedAction = { - type: ActionConstants.LOAD_USERS_PENDING, - }; - expect(loadUsersPending()).toEqual(expectedAction) - }); +describe("Users synchronous actions", function () { + it("creates an action to fetch all users", () => { + const expectedAction = { + type: ActionConstants.LOAD_USERS_PENDING, + }; + expect(loadUsersPending()).toEqual(expectedAction); + }); - it('creates an action to save fetched users', () => { - const users = [{username: 'test1'},{username: 'test2'}]; - const expectedAction = { - type: ActionConstants.LOAD_USERS_SUCCESS, - users - }; - expect(loadUsersSuccess(users)).toEqual(expectedAction) - }); + it("creates an action to save fetched users", () => { + const users = [{ username: "test1" }, { username: "test2" }]; + const expectedAction = { + type: ActionConstants.LOAD_USERS_SUCCESS, + users, + }; + expect(loadUsersSuccess(users)).toEqual(expectedAction); + }); - it('creates an action about error during fetching users', () => { - const error = {message: 'error'}; - const expectedAction = { - type: ActionConstants.LOAD_USERS_ERROR, - error - }; - expect(loadUsersError(error)).toEqual(expectedAction) - }); + it("creates an action about error during fetching users", () => { + const error = { message: "error" }; + const expectedAction = { + type: ActionConstants.LOAD_USERS_ERROR, + error, + }; + expect(loadUsersError(error)).toEqual(expectedAction); + }); }); const middlewares = [thunk.withExtraArgument(axiosBackend)]; const mockStore = configureMockStore(middlewares); -describe('Users asynchronous actions', function () { - let store, - mockApi; - const users = [{username: 'test1'}, {username: 'test2'}], - error = { - "message" : "An error has occurred.", - "requestUri": "/rest/users/xxx" - }; +describe("Users asynchronous actions", function () { + let store, mockApi; + const users = [{ username: "test1" }, { username: "test2" }], + error = { + message: "An error has occurred.", + requestUri: "/rest/users/xxx", + }; - beforeEach(() => { - mockApi = new MockAdapter(axiosBackend); - store = mockStore(); - mockDateNow(); - }); + beforeEach(() => { + mockApi = new MockAdapter(axiosBackend); + store = mockStore(); + mockDateNow(); + }); - afterEach(() => { - restoreDateNow(); - }); + afterEach(() => { + restoreDateNow(); + }); - it('creates LOAD_USERS_SUCCESS action when loading users successfully is done', function (done) { - const expectedActions = [ - { type: ActionConstants.LOAD_USERS_PENDING}, - { type: ActionConstants.LOAD_USERS_SUCCESS, users} - ]; + it("creates LOAD_USERS_SUCCESS action when loading users successfully is done", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_USERS_PENDING }, + { type: ActionConstants.LOAD_USERS_SUCCESS, users }, + ]; - mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); + mockApi.onGet(`${API_URL}/rest/users`).reply(200, users); - store.dispatch(loadUsers()); + store.dispatch(loadUsers()); - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); - it('creates LOAD_USERS_ERROR action if an error occurred during loading users', function (done) { - const expectedActions = [ - { type: ActionConstants.LOAD_USERS_PENDING}, - { type: ActionConstants.LOAD_USERS_ERROR, error}, - { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage('users.loading-error', {error: error.message})} - ]; + it("creates LOAD_USERS_ERROR action if an error occurred during loading users", function (done) { + const expectedActions = [ + { type: ActionConstants.LOAD_USERS_PENDING }, + { type: ActionConstants.LOAD_USERS_ERROR, error }, + { type: ActionConstants.PUBLISH_MESSAGE, message: errorMessage("users.loading-error", { error: error.message }) }, + ]; - mockApi.onGet(`${API_URL}/rest/users`).reply(400, error); + mockApi.onGet(`${API_URL}/rest/users`).reply(400, error); - store.dispatch(loadUsers()); + store.dispatch(loadUsers()); - setTimeout(() => { - expect(store.getActions()).toEqual(expectedActions); - done(); - }, TEST_TIMEOUT); - }); -}); \ No newline at end of file + setTimeout(() => { + expect(store.getActions()).toEqual(expectedActions); + done(); + }, TEST_TIMEOUT); + }); +}); diff --git a/tests/__tests__/components/Dashboard.spec.js b/tests/__tests__/components/Dashboard.spec.js index bdcb35d2..bf41c5e4 100644 --- a/tests/__tests__/components/Dashboard.spec.js +++ b/tests/__tests__/components/Dashboard.spec.js @@ -1,117 +1,121 @@ -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; -import {ROLE} from "../../../js/constants/DefaultConstants"; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; +import { ROLE } from "../../../js/constants/DefaultConstants"; import Dashboard from "../../../js/components/dashboard/Dashboard"; -import enLang from '../../../js/i18n/en'; - -describe('Dashboard', function () { - const intlData = enLang; - let currentUserAdmin = { - username: 'test', - role: ROLE.ADMIN, - firstName: 'testName' - }, - doctorWithInstitution = { - username: 'test', - role: ROLE.DOCTOR, - institution: {key: 12345678} - }, - doctorWithoutInstitution = { - username: 'test', - role: ROLE.DOCTOR - }, - handlers = { - showUsers: jest.fn(), - showInstitutions: jest.fn(), - showRecords: jest.fn(), - createRecord: jest.fn(), - showMyInstitution: jest.fn(), - showMyProfile: jest.fn(), - showStatistics: jest.fn() - }; - - xit('renders dashboard with title and four buttons', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const title = TestUtils.findRenderedDOMComponentWithClass(tree, "formatted-message-size"); - expect(title).not.toBeNull(); - - const name = TestUtils.findRenderedDOMComponentWithClass(tree, "bold"); - expect(name.textContent).toEqual(currentUserAdmin.firstName); - - const container = TestUtils.findRenderedDOMComponentWithClass(tree, "container"); - expect(container).not.toBeNull(); - - const jumbotron = TestUtils.findRenderedDOMComponentWithClass(tree, "jumbotron"); - expect(jumbotron).not.toBeNull(); - - const cols = TestUtils.scryRenderedDOMComponentsWithClass(tree, "dashboard-sector"); - expect(cols.length).toEqual(5); - }); - - xit('renders four buttons to admin and click on them', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); - expect(buttons.length).toEqual(5); - - TestUtils.Simulate.click(buttons[0]); // Create record - expect(handlers.createRecord).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[1]); // View users - expect(handlers.showUsers).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[2]); // View institutions - expect(handlers.showInstitutions).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[3]); // View patients records - expect(handlers.showRecords).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[4]); // View statistics - expect(handlers.showStatistics).toHaveBeenCalled(); - }); - - xit('renders four buttons to doctor with institution and click on them', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); - expect(buttons.length).toEqual(4); - - TestUtils.Simulate.click(buttons[0]); // Create record - expect(handlers.createRecord).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[1]); // View my profile - expect(handlers.showMyProfile).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[2]); // View my institution - expect(handlers.showMyInstitution).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[3]); // View patients records - expect(handlers.showRecords).toHaveBeenCalled(); - }); - - xit('renders three buttons to doctor without institution and click on them', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); - expect(buttons.length).toEqual(3); - - TestUtils.Simulate.click(buttons[0]); // Create record - expect(handlers.createRecord).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[1]); // View my profile - expect(handlers.showMyProfile).toHaveBeenCalled(); - - TestUtils.Simulate.click(buttons[2]); // View patients records - expect(handlers.showRecords).toHaveBeenCalled(); - }); -}); \ No newline at end of file +import enLang from "../../../js/i18n/en"; + +describe("Dashboard", function () { + const intlData = enLang; + let currentUserAdmin = { + username: "test", + role: ROLE.ADMIN, + firstName: "testName", + }, + doctorWithInstitution = { + username: "test", + role: ROLE.DOCTOR, + institution: { key: 12345678 }, + }, + doctorWithoutInstitution = { + username: "test", + role: ROLE.DOCTOR, + }, + handlers = { + showUsers: jest.fn(), + showInstitutions: jest.fn(), + showRecords: jest.fn(), + createRecord: jest.fn(), + showMyInstitution: jest.fn(), + showMyProfile: jest.fn(), + showStatistics: jest.fn(), + }; + + xit("renders dashboard with title and four buttons", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const title = TestUtils.findRenderedDOMComponentWithClass(tree, "formatted-message-size"); + expect(title).not.toBeNull(); + + const name = TestUtils.findRenderedDOMComponentWithClass(tree, "bold"); + expect(name.textContent).toEqual(currentUserAdmin.firstName); + + const container = TestUtils.findRenderedDOMComponentWithClass(tree, "container"); + expect(container).not.toBeNull(); + + const jumbotron = TestUtils.findRenderedDOMComponentWithClass(tree, "jumbotron"); + expect(jumbotron).not.toBeNull(); + + const cols = TestUtils.scryRenderedDOMComponentsWithClass(tree, "dashboard-sector"); + expect(cols.length).toEqual(5); + }); + + xit("renders four buttons to admin and click on them", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); + expect(buttons.length).toEqual(5); + + TestUtils.Simulate.click(buttons[0]); // Create record + expect(handlers.createRecord).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[1]); // View users + expect(handlers.showUsers).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[2]); // View institutions + expect(handlers.showInstitutions).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[3]); // View patients records + expect(handlers.showRecords).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[4]); // View statistics + expect(handlers.showStatistics).toHaveBeenCalled(); + }); + + xit("renders four buttons to doctor with institution and click on them", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); + expect(buttons.length).toEqual(4); + + TestUtils.Simulate.click(buttons[0]); // Create record + expect(handlers.createRecord).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[1]); // View my profile + expect(handlers.showMyProfile).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[2]); // View my institution + expect(handlers.showMyInstitution).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[3]); // View patients records + expect(handlers.showRecords).toHaveBeenCalled(); + }); + + xit("renders three buttons to doctor without institution and click on them", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); + expect(buttons.length).toEqual(3); + + TestUtils.Simulate.click(buttons[0]); // Create record + expect(handlers.createRecord).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[1]); // View my profile + expect(handlers.showMyProfile).toHaveBeenCalled(); + + TestUtils.Simulate.click(buttons[2]); // View patients records + expect(handlers.showRecords).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/HistoryRow.spec.js b/tests/__tests__/components/HistoryRow.spec.js index ca80200c..fead75c2 100644 --- a/tests/__tests__/components/HistoryRow.spec.js +++ b/tests/__tests__/components/HistoryRow.spec.js @@ -1,44 +1,46 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import HistoryRow from "../../../js/components/history/HistoryRow"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('HistoryRow', function () { - const intlData = enLang; - let action = {key: "12345", type: "TEST", author: {username: "test"}, timestamp: 1526074842 }, - onOpen = jest.fn(); +describe("HistoryRow", function () { + const intlData = enLang; + let action = { key: "12345", type: "TEST", author: { username: "test" }, timestamp: 1526074842 }, + onOpen = jest.fn(); - it('renders one row of table with 4 columns and 1 button', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'td'); - expect(td.length).toEqual(4); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'Button'); - expect(buttons.length).toEqual(1); - }); + it("renders one row of table with 4 columns and 1 button", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td"); + expect(td.length).toEqual(4); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(1); + }); - it('renders "Open" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(1); + it('renders "Open" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(1); - TestUtils.Simulate.click(buttons[0]); // Open Action - expect(onOpen).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[0]); // Open Action + expect(onOpen).toHaveBeenCalled(); + }); }); diff --git a/tests/__tests__/components/HistorySearch.spec.js b/tests/__tests__/components/HistorySearch.spec.js index 4a1f2058..91a6b609 100644 --- a/tests/__tests__/components/HistorySearch.spec.js +++ b/tests/__tests__/components/HistorySearch.spec.js @@ -1,32 +1,33 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import HistorySearch from "../../../js/components/history/HistorySearch"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('HistorySearch', function () { - const intlData = enLang; - let searchData = {}, - handlers = { - handleChange: jest.fn(), - handleSearch: jest.fn(), - handleReset: jest.fn() +describe("HistorySearch", function () { + const intlData = enLang; + let searchData = {}, + handlers = { + handleChange: jest.fn(), + handleSearch: jest.fn(), + handleReset: jest.fn(), }; - it('renders search with 3 inputs and 2 buttons', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const inputs = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(inputs.length).toEqual(3); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'button'); - expect(buttons.length).toEqual(2); - }); + it("renders search with 3 inputs and 2 buttons", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const inputs = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(inputs.length).toEqual(3); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); + expect(buttons.length).toEqual(2); + }); }); diff --git a/tests/__tests__/components/HistoryTable.spec.js b/tests/__tests__/components/HistoryTable.spec.js index c0b08b05..432b4fca 100644 --- a/tests/__tests__/components/HistoryTable.spec.js +++ b/tests/__tests__/components/HistoryTable.spec.js @@ -1,32 +1,32 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import HistoryTable from "../../../js/components/history/HistoryTable"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('HistoryTable', function () { - const intlData = enLang; - let actions = [], - searchData = {}, - handlers = { - handleSearch: jest.fn(), - handleReset: jest.fn(), - handleChange: jest.fn(), - onKeyPress: jest.fn(), - onOpen: jest.fn() - }; +describe("HistoryTable", function () { + const intlData = enLang; + let actions = [], + searchData = {}, + handlers = { + handleSearch: jest.fn(), + handleReset: jest.fn(), + handleChange: jest.fn(), + onKeyPress: jest.fn(), + onOpen: jest.fn(), + }; - it('renders table with 4 headers columns', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree,'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree,'th'); - expect(th.length).toEqual(4); - }); + it("renders table with 4 headers columns", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(4); + }); }); diff --git a/tests/__tests__/components/Institution.spec.js b/tests/__tests__/components/Institution.spec.js index 7ff9cc30..2a193d75 100644 --- a/tests/__tests__/components/Institution.spec.js +++ b/tests/__tests__/components/Institution.spec.js @@ -1,168 +1,208 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; -import {ACTION_STATUS, ROLE, SortDirection} from "../../../js/constants/DefaultConstants"; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; +import { ACTION_STATUS, ROLE, SortDirection } from "../../../js/constants/DefaultConstants"; import Institution from "../../../js/components/institution/Institution"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('Institution', function () { - const intlData = enLang; - let institution, - newInstitution, - institutionSaved, - institutionLoaded, - admin, - user, - institutionMembers = {}, - recordsLoaded = { - records: [] - }, - filterAndSort, - formTemplatesLoaded = {}, - handlers = { - onSave: jest.fn(), - onCancel: jest.fn(), - onChange: jest.fn(), - onEditUser: jest.fn(), - onAddNewUser: jest.fn(), - onDelete: jest.fn(), - onEditPatient: jest.fn(), - onExportRecords: jest.fn() - }; +describe("Institution", function () { + const intlData = enLang; + let institution, + newInstitution, + institutionSaved, + institutionLoaded, + admin, + user, + institutionMembers = {}, + recordsLoaded = { + records: [], + }, + filterAndSort, + formTemplatesLoaded = {}, + handlers = { + onSave: jest.fn(), + onCancel: jest.fn(), + onChange: jest.fn(), + onEditUser: jest.fn(), + onAddNewUser: jest.fn(), + onDelete: jest.fn(), + onEditPatient: jest.fn(), + onExportRecords: jest.fn(), + }; + + user = { + username: "doctor", + role: ROLE.DOCTOR, + }; + admin = { + username: "admin", + role: ROLE.ADMIN, + }; + + institution = { + name: "test", + emailAddress: "test@test.cz", + }; - user = { - username: 'doctor', - role: ROLE.DOCTOR + institutionMembers = { + status: ACTION_STATUS.SUCCESS, + members: {}, + }; + + beforeEach(() => { + institutionLoaded = { + status: ACTION_STATUS.SUCCESS, + error: "", }; - admin = { - username: 'admin', - role: ROLE.ADMIN + institutionSaved = { + status: ACTION_STATUS.SUCCESS, + error: "", }; - - institution = { - "name": "test", - "emailAddress": "test@test.cz" + newInstitution = { + name: "", + emailAddress: "", + isNew: true, }; - - institutionMembers = { - status: ACTION_STATUS.SUCCESS, - members: {} + recordsLoaded = { + status: ACTION_STATUS.SUCCESS, + records: [], }; + filterAndSort = { + sort: { date: SortDirection.DESC }, + filters: {}, + onChange: jest.fn(), + }; + }); - beforeEach(() => { - institutionLoaded = { - status: ACTION_STATUS.SUCCESS, - error: '' - }; - institutionSaved = { - status: ACTION_STATUS.SUCCESS, - error: '' - }; - newInstitution = { - name: '', - emailAddress: '', - isNew: true - }; - recordsLoaded = { - status: ACTION_STATUS.SUCCESS, - records: [] - }; - filterAndSort = { - sort: {date: SortDirection.DESC}, - filters: {}, - onChange: jest.fn() - } - }); - - it("renders institution's form empty", function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree,'input'); - expect(result.length).toEqual(2); - for(let input of result) { - switch(input.name){ - case "localName": - expect(input.value).toEqual(""); - expect(input.type).toEqual("text"); - break; - case "email": - expect(input.value).toEqual(""); - expect(input.type).toEqual("email"); - break; - } - } - }); + it("renders institution's form empty", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(result.length).toEqual(2); + for (let input of result) { + switch (input.name) { + case "localName": + expect(input.value).toEqual(""); + expect(input.type).toEqual("text"); + break; + case "email": + expect(input.value).toEqual(""); + expect(input.type).toEqual("email"); + break; + } + } + }); - it('renders "Save" button for admin and click on it', function () { - newInstitution = { - ...newInstitution, - name: 'ahoj' - }; - const tree = TestUtils.renderIntoDocument( - - - ); - let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(2); + it('renders "Save" button for admin and click on it', function () { + newInstitution = { + ...newInstitution, + name: "ahoj", + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(2); - TestUtils.Simulate.click(buttons[0]); // save - expect(handlers.onSave).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[0]); // save + expect(handlers.onSave).toHaveBeenCalled(); + }); - it('does not render "Save" button for user', function () { - newInstitution = { - ...newInstitution, - name: 'ahoj' - }; - const tree = TestUtils.renderIntoDocument( - - - ); - let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(1); - }); + it('does not render "Save" button for user', function () { + newInstitution = { + ...newInstitution, + name: "ahoj", + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(1); + }); - it('renders "Cancel" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + it('renders "Cancel" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[1]); // cancel - expect(handlers.onCancel).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[1]); // cancel + expect(handlers.onCancel).toHaveBeenCalled(); + }); - it('renders loading spinner in "Save" button on saving', function () { - institutionSaved = { - ...institutionSaved, - status: ACTION_STATUS.PENDING - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const loader = TestUtils.findRenderedDOMComponentWithClass(tree, "loader"); - expect(loader).not.toBeNull(); - }); -}); \ No newline at end of file + it('renders loading spinner in "Save" button on saving', function () { + institutionSaved = { + ...institutionSaved, + status: ACTION_STATUS.PENDING, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const loader = TestUtils.findRenderedDOMComponentWithClass(tree, "loader"); + expect(loader).not.toBeNull(); + }); +}); diff --git a/tests/__tests__/components/InstitutionMembers.spec.js b/tests/__tests__/components/InstitutionMembers.spec.js index ae8c5cad..ba9e2246 100644 --- a/tests/__tests__/components/InstitutionMembers.spec.js +++ b/tests/__tests__/components/InstitutionMembers.spec.js @@ -1,164 +1,213 @@ import TestUtils from "react-dom/test-utils"; -import {ACTION_STATUS, ROLE} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS, ROLE } from "../../../js/constants/DefaultConstants"; import React from "react"; -import {IntlProvider} from "react-intl"; +import { IntlProvider } from "react-intl"; import InstitutionMembers from "../../../js/components/institution/InstitutionMembers"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('InstitutionMembers', function () { - const intlData = enLang; - let institutionMembers, - institutionMembersEmpty, - members, - institution, - onEditUser = jest.fn(), - onAddNewUser = jest.fn(), - onDelete = jest.fn(), - user, - admin, - userDeleted; +describe("InstitutionMembers", function () { + const intlData = enLang; + let institutionMembers, + institutionMembersEmpty, + members, + institution, + onEditUser = jest.fn(), + onAddNewUser = jest.fn(), + onDelete = jest.fn(), + user, + admin, + userDeleted; - members = [ - { - username: 'test1', - firstName: 'test', - lastName: 'test', - emailAddress: 'test@test.cz' - }, - { - username: 'test2', - firstName: 'test', - lastName: 'test', - emailAddress: 'test@test.cz' - } - ]; + members = [ + { + username: "test1", + firstName: "test", + lastName: "test", + emailAddress: "test@test.cz", + }, + { + username: "test2", + firstName: "test", + lastName: "test", + emailAddress: "test@test.cz", + }, + ]; - institutionMembersEmpty = { - status: ACTION_STATUS.SUCCESS, - members: [] - }; + institutionMembersEmpty = { + status: ACTION_STATUS.SUCCESS, + members: [], + }; - institution = { - key: 23123323312 - }; + institution = { + key: 23123323312, + }; - user = { - username: 'user', - role: ROLE.DOCTOR - }; + user = { + username: "user", + role: ROLE.DOCTOR, + }; - admin = { - username: 'admin', - role: ROLE.ADMIN - }; + admin = { + username: "admin", + role: ROLE.ADMIN, + }; - userDeleted = { - status: ACTION_STATUS.SUCCESS - }; + userDeleted = { + status: ACTION_STATUS.SUCCESS, + }; - beforeEach(() => { - institutionMembers = { - status: ACTION_STATUS.SUCCESS, - members - }; - }); + beforeEach(() => { + institutionMembers = { + status: ACTION_STATUS.SUCCESS, + members, + }; + }); - it('shows loader', function () { - institutionMembers = { - status: ACTION_STATUS.PENDING - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.findRenderedDOMComponentWithClass(tree, 'loader-spin'); - expect(result).not.toBeNull(); - }); + it("shows loader", function () { + institutionMembers = { + status: ACTION_STATUS.PENDING, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.findRenderedDOMComponentWithClass(tree, "loader-spin"); + expect(result).not.toBeNull(); + }); - it('renders card with table and table headers and columns', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree,'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree,'th'); - expect(th.length).toEqual(4); - const td = TestUtils.scryRenderedDOMComponentsWithTag(tree,'td'); - expect(td.length).toEqual(8); - }); + it("renders card with table and table headers and columns", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(4); + const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td"); + expect(td.length).toEqual(8); + }); - it('renders card with text, that no members were found', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const text = TestUtils.scryRenderedDOMComponentsWithTag(tree,'p'); - expect(text.length).toEqual(1); - }); + it("renders card with text, that no members were found", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const text = TestUtils.scryRenderedDOMComponentsWithTag(tree, "p"); + expect(text.length).toEqual(1); + }); - it('renders "Add new user" button for admin and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const button = TestUtils.findRenderedDOMComponentWithTag(tree, "Button"); - expect(button).not.toBeNull(); - TestUtils.Simulate.click(button); - expect(onAddNewUser).toHaveBeenCalled(); - }); + it('renders "Add new user" button for admin and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const button = TestUtils.findRenderedDOMComponentWithTag(tree, "Button"); + expect(button).not.toBeNull(); + TestUtils.Simulate.click(button); + expect(onAddNewUser).toHaveBeenCalled(); + }); - it('does not render "Add new user" button for user', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(0); - }); + it('does not render "Add new user" button for user', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(0); + }); - it('renders "Delete" button for admin for deleting user and opens modal when click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(5); - TestUtils.Simulate.click(buttons[1]); // Delete button - const modal = TestUtils.scryRenderedDOMComponentsWithClass(tree, "modal-dialog"); - expect(modal).not.toBeNull(); - }); + it('renders "Delete" button for admin for deleting user and opens modal when click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(5); + TestUtils.Simulate.click(buttons[1]); // Delete button + const modal = TestUtils.scryRenderedDOMComponentsWithClass(tree, "modal-dialog"); + expect(modal).not.toBeNull(); + }); - it('does not render "Delete" button for user, renders only open button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(2); - TestUtils.Simulate.click(buttons[0]); // Delete button - expect(onEditUser).toHaveBeenCalled(); - }); -}); \ No newline at end of file + it('does not render "Delete" button for user, renders only open button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(2); + TestUtils.Simulate.click(buttons[0]); // Delete button + expect(onEditUser).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/InstitutionPatients.spec.js b/tests/__tests__/components/InstitutionPatients.spec.js index fc2fd045..216ab69d 100644 --- a/tests/__tests__/components/InstitutionPatients.spec.js +++ b/tests/__tests__/components/InstitutionPatients.spec.js @@ -1,41 +1,47 @@ import TestUtils from "react-dom/test-utils"; import React from "react"; -import {IntlProvider} from "react-intl"; +import { IntlProvider } from "react-intl"; import InstitutionPatients from "../../../js/components/institution/InstitutionPatients"; -import enLang from '../../../js/i18n/en'; -import {ROLE, SortDirection} from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; +import { ROLE, SortDirection } from "../../../js/constants/DefaultConstants"; -describe('InstitutionPatients', function () { - const intlData = enLang; - let recordsLoaded, - formTemplatesLoaded = {}, - currentUser = { - username: 'testUser', - role: ROLE.DOCTOR - }, - filterAndSort = { - sort: { - date: SortDirection.DESC - }, - filters: {}, - onChange: jest.fn() - }, - onEdit = jest.fn(), - onExport = jest.fn(); +describe("InstitutionPatients", function () { + const intlData = enLang; + let recordsLoaded, + formTemplatesLoaded = {}, + currentUser = { + username: "testUser", + role: ROLE.DOCTOR, + }, + filterAndSort = { + sort: { + date: SortDirection.DESC, + }, + filters: {}, + onChange: jest.fn(), + }, + onEdit = jest.fn(), + onExport = jest.fn(); - it('renders card', function () { - recordsLoaded = { - records: [] - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - }); -}); \ No newline at end of file + it("renders card", function () { + recordsLoaded = { + records: [], + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + }); +}); diff --git a/tests/__tests__/components/InstitutionRow.spec.js b/tests/__tests__/components/InstitutionRow.spec.js index dca4337c..bf7cbf77 100644 --- a/tests/__tests__/components/InstitutionRow.spec.js +++ b/tests/__tests__/components/InstitutionRow.spec.js @@ -1,90 +1,110 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import InstitutionRow from "../../../js/components/institution/InstitutionRow"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('InstitutionRow', function () { - const intlData = enLang; - let institution, - deletionLoading = false, - onEdit = jest.fn(), - onDelete = jest.fn(); +describe("InstitutionRow", function () { + const intlData = enLang; + let institution, + deletionLoading = false, + onEdit = jest.fn(), + onDelete = jest.fn(); - institution = { - "uri": "http://test.io", - "key": "823372507340798303", - "name": "Test Institution", - "emailAddress": "test@institution.io" - }; + institution = { + uri: "http://test.io", + key: "823372507340798303", + name: "Test Institution", + emailAddress: "test@institution.io", + }; - it('renders one row of table with 3 columns and 3 buttons', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'td'); - expect(td.length).toEqual(3); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'Button'); - expect(buttons.length).toEqual(3); - }); + it("renders one row of table with 3 columns and 3 buttons", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td"); + expect(td.length).toEqual(3); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); + }); - it('renders "Open" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + it('renders "Open" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[0]); // Open Institution - expect(onEdit).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[0]); // Open Institution + expect(onEdit).toHaveBeenCalled(); + }); - it('renders name with link and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); + it("renders name with link and click on it", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); - const link = TestUtils.findRenderedDOMComponentWithClass(tree, "btn-link"); - expect(link).not.toBeNull(); + const link = TestUtils.findRenderedDOMComponentWithClass(tree, "btn-link"); + expect(link).not.toBeNull(); - TestUtils.Simulate.click(link); - expect(onEdit).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(link); + expect(onEdit).toHaveBeenCalled(); + }); - it('renders "Delete" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + it('renders "Delete" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[2]); // Delete Institution - expect(onDelete).toHaveBeenCalled(); - }); -}); \ No newline at end of file + TestUtils.Simulate.click(buttons[2]); // Delete Institution + expect(onDelete).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/InstitutionTable.spec.js b/tests/__tests__/components/InstitutionTable.spec.js index ea1e4f65..8de3eb98 100644 --- a/tests/__tests__/components/InstitutionTable.spec.js +++ b/tests/__tests__/components/InstitutionTable.spec.js @@ -1,50 +1,54 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import InstitutionTable from "../../../js/components/institution/InstitutionTable"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; -import enLang from '../../../js/i18n/en'; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; -describe('InstitutionTable', function () { - const intlData = enLang; - let institutions, - institutionDeleted = { - status: ACTION_STATUS.SUCCESS - }, - handlers = { - onEdit: jest.fn(), - onCreate: jest.fn(), - onDelete: jest.fn() - }; +describe("InstitutionTable", function () { + const intlData = enLang; + let institutions, + institutionDeleted = { + status: ACTION_STATUS.SUCCESS, + }, + handlers = { + onEdit: jest.fn(), + onCreate: jest.fn(), + onDelete: jest.fn(), + }; - institutions = [{ - "uri":"http://test.io", - "key":"823372507340798303", - "name":"Test Institution", - "emailAddress":"test@institution.io" - }]; + institutions = [ + { + uri: "http://test.io", + key: "823372507340798303", + name: "Test Institution", + emailAddress: "test@institution.io", + }, + ]; - it('renders table with 3 headers columns', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree,'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree,'th'); - expect(th.length).toEqual(3); - }); + it("renders table with 3 headers columns", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(3); + }); - it('renders modal window by "Delete" button click', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - TestUtils.Simulate.click(buttons[1]); // Delete Institution - const modal = TestUtils.scryRenderedDOMComponentsWithClass(tree, "modal-dialog"); - expect(modal).not.toBeNull(); - }); + it('renders modal window by "Delete" button click', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + TestUtils.Simulate.click(buttons[1]); // Delete Institution + const modal = TestUtils.scryRenderedDOMComponentsWithClass(tree, "modal-dialog"); + expect(modal).not.toBeNull(); + }); }); diff --git a/tests/__tests__/components/Institutions.spec.js b/tests/__tests__/components/Institutions.spec.js index db85a3f6..905db736 100644 --- a/tests/__tests__/components/Institutions.spec.js +++ b/tests/__tests__/components/Institutions.spec.js @@ -1,107 +1,122 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import Institutions from "../../../js/components/institution/Institutions"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; -import enLang from '../../../js/i18n/en'; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; -describe('Institutions', function () { - const intlData = enLang; - let institutionsLoaded, - institutionsLoadedEmpty, - institutionDeleted, - institutions, - handlers; +describe("Institutions", function () { + const intlData = enLang; + let institutionsLoaded, institutionsLoadedEmpty, institutionDeleted, institutions, handlers; - institutions = [{ - "uri": "http://test1.io", - "key": "823372507340798303", - "name": "Test1 Institution", - "emailAddress": "test1@institution.io" - }, { - "uri": "http://test2.io", - "key": "823372507340798301", - "name": "Test2 Institution", - "emailAddress": "test2@institution.io" - }]; + institutions = [ + { + uri: "http://test1.io", + key: "823372507340798303", + name: "Test1 Institution", + emailAddress: "test1@institution.io", + }, + { + uri: "http://test2.io", + key: "823372507340798301", + name: "Test2 Institution", + emailAddress: "test2@institution.io", + }, + ]; - beforeEach(() => { - institutionDeleted = { - status: ACTION_STATUS.SUCCESS - }; - handlers = { - onEdit: jest.fn(), - onCreate: jest.fn(), - onDelete: jest.fn() - }; - institutionsLoaded = { - status: ACTION_STATUS.SUCCESS, - institutions - }; - institutionsLoadedEmpty = { - status: ACTION_STATUS.SUCCESS, - institutions: [] - }; - }); + beforeEach(() => { + institutionDeleted = { + status: ACTION_STATUS.SUCCESS, + }; + handlers = { + onEdit: jest.fn(), + onCreate: jest.fn(), + onDelete: jest.fn(), + }; + institutionsLoaded = { + status: ACTION_STATUS.SUCCESS, + institutions, + }; + institutionsLoadedEmpty = { + status: ACTION_STATUS.SUCCESS, + institutions: [], + }; + }); - it('shows error about institutions were not loaded', function () { - institutionsLoaded = { - status: ACTION_STATUS.ERROR, - error: { - message: "Error" - } - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); - expect(alert).not.toBeNull(); - }); + it("shows error about institutions were not loaded", function () { + institutionsLoaded = { + status: ACTION_STATUS.ERROR, + error: { + message: "Error", + }, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); + expect(alert).not.toBeNull(); + }); - it('renders card with text, that no institutions were found', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const text = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'p'); - expect(text.length).toEqual(1); - }); + it("renders card with text, that no institutions were found", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const text = TestUtils.scryRenderedDOMComponentsWithTag(tree, "p"); + expect(text.length).toEqual(1); + }); - it('renders card with table and institutions', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'th'); - expect(th.length).toEqual(3); - }); + it("renders card with table and institutions", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(3); + }); - it('renders "Create institution" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(7); + it('renders "Create institution" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(7); - TestUtils.Simulate.click(buttons[6]); // Create Institution - expect(handlers.onCreate).toHaveBeenCalled(); - }); -}); \ No newline at end of file + TestUtils.Simulate.click(buttons[6]); // Create Institution + expect(handlers.onCreate).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/Loader.spec.js b/tests/__tests__/components/Loader.spec.js index 3df8bdeb..69c71447 100644 --- a/tests/__tests__/components/Loader.spec.js +++ b/tests/__tests__/components/Loader.spec.js @@ -1,44 +1,43 @@ -import React from 'react'; +import React from "react"; import TestUtils from "react-dom/test-utils"; -import Loader, {LoaderMask, LoaderCard} from "../../../js/components/Loader"; -import {IntlProvider} from "react-intl"; -import enLang from '../../../js/i18n/en'; +import Loader, { LoaderMask, LoaderCard } from "../../../js/components/Loader"; +import { IntlProvider } from "react-intl"; +import enLang from "../../../js/i18n/en"; -describe('Loader', function () { - const intlData = enLang; +describe("Loader", function () { + const intlData = enLang; - it('renders loader', function () { - const tree = TestUtils.renderIntoDocument( - - - - ); - const result = TestUtils.findRenderedDOMComponentWithClass(tree, 'loader-spin'); - expect(result).not.toBeNull(); - }); + it("renders loader", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.findRenderedDOMComponentWithClass(tree, "loader-spin"); + expect(result).not.toBeNull(); + }); - it('renders loader with card', function () { - const tree = TestUtils.renderIntoDocument( - - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const loaderSpin = TestUtils.findRenderedDOMComponentWithClass(tree, 'loader-spin'); - expect(loaderSpin).not.toBeNull(); - }); + it("renders loader with card", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const loaderSpin = TestUtils.findRenderedDOMComponentWithClass(tree, "loader-spin"); + expect(loaderSpin).not.toBeNull(); + }); - it('renders loader as mask', function () { - const tree = TestUtils.renderIntoDocument( - - - - ); - const mask = TestUtils.findRenderedDOMComponentWithClass(tree, 'mask'); - expect(mask).not.toBeNull(); - const loaderSpin = TestUtils.findRenderedDOMComponentWithClass(tree, 'loader-spin'); - expect(loaderSpin).not.toBeNull(); - }); - -}); \ No newline at end of file + it("renders loader as mask", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const mask = TestUtils.findRenderedDOMComponentWithClass(tree, "mask"); + expect(mask).not.toBeNull(); + const loaderSpin = TestUtils.findRenderedDOMComponentWithClass(tree, "loader-spin"); + expect(loaderSpin).not.toBeNull(); + }); +}); diff --git a/tests/__tests__/components/Pagination.spec.js b/tests/__tests__/components/Pagination.spec.js index 0bc9627f..768ed3eb 100644 --- a/tests/__tests__/components/Pagination.spec.js +++ b/tests/__tests__/components/Pagination.spec.js @@ -1,23 +1,22 @@ -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import Pagination from "../../../js/components/misc/Pagination"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('Pagination', function () { - const intlData = enLang; - let handlePagination = jest.fn(); +describe("Pagination", function () { + const intlData = enLang; + let handlePagination = jest.fn(); - it('renders pagination with first, previous and next button', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const pagination = TestUtils.findRenderedDOMComponentWithClass(tree, 'pagination'); - expect(pagination).not.toBeNull(); - const li = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'li'); - expect(li.length).toEqual(4); - }); + it("renders pagination with first, previous and next button", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const pagination = TestUtils.findRenderedDOMComponentWithClass(tree, "pagination"); + expect(pagination).not.toBeNull(); + const li = TestUtils.scryRenderedDOMComponentsWithTag(tree, "li"); + expect(li.length).toEqual(4); + }); }); diff --git a/tests/__tests__/components/PasswordChange.spec.js b/tests/__tests__/components/PasswordChange.spec.js index aac60a17..ae6440f7 100644 --- a/tests/__tests__/components/PasswordChange.spec.js +++ b/tests/__tests__/components/PasswordChange.spec.js @@ -1,130 +1,159 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; -import {ROLE} from "../../../js/constants/DefaultConstants"; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; +import { ROLE } from "../../../js/constants/DefaultConstants"; import PasswordChange from "../../../js/components/user/PasswordChange"; import * as UserFactory from "../../../js/utils/EntityFactory"; -import enLang from '../../../js/i18n/en'; - -describe('PasswordChange', function () { - const intlData = enLang; - let valid, - match, - passwordChange, - currentUser, - currentUserAdmin, - handlers, - passwordEmpty, - passwordFilled; - - beforeEach(() => { - handlers = { - onSave: jest.fn(), - onCancel: jest.fn(), - onChange: jest.fn(), - }; - valid = true; - }); - - currentUser = { - username: 'testUser', - role: ROLE.DOCTOR - }; - currentUserAdmin = { - username: 'testAdmin', - role: ROLE.ADMIN - }; +import enLang from "../../../js/i18n/en"; - match = { - params: { - username: currentUser.username - } - }; +describe("PasswordChange", function () { + const intlData = enLang; + let valid, match, passwordChange, currentUser, currentUserAdmin, handlers, passwordEmpty, passwordFilled; - passwordEmpty = UserFactory.initNewPassword(); - passwordFilled = { - currentPassword: 'aaaa', - newPassword: 'aaaa', - confirmPassword: 'aaaa' + beforeEach(() => { + handlers = { + onSave: jest.fn(), + onCancel: jest.fn(), + onChange: jest.fn(), }; - - passwordChange = {}; - - it('renders clickable "Save" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(2); - - expect(buttons[0].disabled).toBeFalsy(); - TestUtils.Simulate.click(buttons[0]); // save - expect(handlers.onSave).toHaveBeenCalled(); - }); - - it('renders disabled "Save" button', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(2); - - expect(buttons[0].disabled).toBeTruthy(); - }); - - it('shows alert that password is not valid', function () { - valid = false; - const tree = TestUtils.renderIntoDocument( - - - ); - const alert = TestUtils.findRenderedDOMComponentWithClass(tree, 'alert-danger'); - expect(alert).not.toBeNull(); - }); - - it('renders 2 inputs for admin who is changing password to someone else', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const inputs = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(inputs.length).toEqual(2); - }); - - it('renders 3 inputs when somebody is changing his password', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const inputs = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(inputs.length).toEqual(3); - }); - - it('renders "Cancel" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(2); - - TestUtils.Simulate.click(buttons[1]); // cancel - expect(handlers.onCancel).toHaveBeenCalled(); - }); -}); \ No newline at end of file + valid = true; + }); + + currentUser = { + username: "testUser", + role: ROLE.DOCTOR, + }; + currentUserAdmin = { + username: "testAdmin", + role: ROLE.ADMIN, + }; + + match = { + params: { + username: currentUser.username, + }, + }; + + passwordEmpty = UserFactory.initNewPassword(); + passwordFilled = { + currentPassword: "aaaa", + newPassword: "aaaa", + confirmPassword: "aaaa", + }; + + passwordChange = {}; + + it('renders clickable "Save" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(2); + + expect(buttons[0].disabled).toBeFalsy(); + TestUtils.Simulate.click(buttons[0]); // save + expect(handlers.onSave).toHaveBeenCalled(); + }); + + it('renders disabled "Save" button', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(2); + + expect(buttons[0].disabled).toBeTruthy(); + }); + + it("shows alert that password is not valid", function () { + valid = false; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.findRenderedDOMComponentWithClass(tree, "alert-danger"); + expect(alert).not.toBeNull(); + }); + + it("renders 2 inputs for admin who is changing password to someone else", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const inputs = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(inputs.length).toEqual(2); + }); + + it("renders 3 inputs when somebody is changing his password", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const inputs = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(inputs.length).toEqual(3); + }); + + it('renders "Cancel" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(2); + + TestUtils.Simulate.click(buttons[1]); // cancel + expect(handlers.onCancel).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/Record.spec.js b/tests/__tests__/components/Record.spec.js index 0a663a29..1f3c29d4 100644 --- a/tests/__tests__/components/Record.spec.js +++ b/tests/__tests__/components/Record.spec.js @@ -1,174 +1,240 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; -import {ACTION_STATUS, ROLE} from "../../../js/constants/DefaultConstants"; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; +import { ACTION_STATUS, ROLE } from "../../../js/constants/DefaultConstants"; import Record from "../../../js/components/record/Record"; import * as RecordState from "../../../js/model/RecordState"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -jest.mock("../../../js/components/record/TypeaheadAnswer", () =>() => ); +jest.mock("../../../js/components/record/TypeaheadAnswer", () => () => ); -describe.skip('Record', function () { - const intlData = enLang; - let record, - newRecord, - recordSaved, - showAlert, - recordLoaded, - formgen = {}, - currentUser, - handlers = { - onSave: jest.fn(), - onCancel: jest.fn(), - onChange: jest.fn(), - onEditUser: jest.fn(), - onAddNewUser: jest.fn(), - onDelete: jest.fn(), - }; - - beforeEach(() => { - showAlert = false; - recordLoaded = { - status: ACTION_STATUS.SUCCESS, - error: '' - }; - recordSaved = { - status: ACTION_STATUS.SUCCESS, - error: '' - }; - newRecord = { - localName: '', - complete: false, - isNew: true, - state: RecordState.createInitialState() - }; - currentUser = { - firstName: "Test", - lastName: "User", - role: ROLE.DOCTOR - }; - }); +describe.skip("Record", function () { + const intlData = enLang; + let record, + newRecord, + recordSaved, + showAlert, + recordLoaded, + formgen = {}, + currentUser, + handlers = { + onSave: jest.fn(), + onCancel: jest.fn(), + onChange: jest.fn(), + onEditUser: jest.fn(), + onAddNewUser: jest.fn(), + onDelete: jest.fn(), + }; - record = { - author: {firstName: 'test', lastName: 'test'}, - institution: {localName: 'testInstitution'}, - dateCreated: 1521225180115, - key: '640579951330382351', - localName: 'test', - lastModified: 1521277544192, - state: RecordState.createRecordState() + beforeEach(() => { + showAlert = false; + recordLoaded = { + status: ACTION_STATUS.SUCCESS, + error: "", + }; + recordSaved = { + status: ACTION_STATUS.SUCCESS, + error: "", }; + newRecord = { + localName: "", + complete: false, + isNew: true, + state: RecordState.createInitialState(), + }; + currentUser = { + firstName: "Test", + lastName: "User", + role: ROLE.DOCTOR, + }; + }); - it('shows loader', function () { - recordLoaded = { - status: ACTION_STATUS.PENDING - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.findRenderedDOMComponentWithClass(tree, 'loader-spin'); - expect(result).not.toBeNull(); - }); + record = { + author: { firstName: "test", lastName: "test" }, + institution: { localName: "testInstitution" }, + dateCreated: 1521225180115, + key: "640579951330382351", + localName: "test", + lastModified: 1521277544192, + state: RecordState.createRecordState(), + }; - it('shows error about record was not loaded', function () { - recordLoaded = { - ...recordLoaded, - status: ACTION_STATUS.ERROR, - error: { - message: "Error" - } - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); - expect(alert).not.toBeNull(); - }); + it("shows loader", function () { + recordLoaded = { + status: ACTION_STATUS.PENDING, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.findRenderedDOMComponentWithClass(tree, "loader-spin"); + expect(result).not.toBeNull(); + }); - it("renders record's form empty", function () { - const tree = mount( - - - - ); - const result = tree.find('input'); - expect(result.length).toEqual(1); - for (let input of result) { - switch (input.name) { - case "localName": - expect(input.value).toEqual(""); - expect(input.type).toEqual("text"); - break; - } - } - }); + it("shows error about record was not loaded", function () { + recordLoaded = { + ...recordLoaded, + status: ACTION_STATUS.ERROR, + error: { + message: "Error", + }, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); + expect(alert).not.toBeNull(); + }); - //TODO (after migrating to React 18): Create test cases for different extension (operator and supplier cases) - it('renders "Save" and "Cancel" buttons', function () { - const tree = mount( - - - - ); - let buttons = tree.find("Button"); - expect(buttons.length).toEqual(2); - }); + it("renders record's form empty", function () { + const tree = mount( + + + , + ); + const result = tree.find("input"); + expect(result.length).toEqual(1); + for (let input of result) { + switch (input.name) { + case "localName": + expect(input.value).toEqual(""); + expect(input.type).toEqual("text"); + break; + } + } + }); - it('shows successful alert that record was successfully saved', function () { - showAlert = true; - recordSaved = { - ...recordSaved, - status: ACTION_STATUS.SUCCESS - }; - const tree = TestUtils.renderIntoDocument( - - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-success"); - expect(alert).not.toBeNull(); - }); + //TODO (after migrating to React 18): Create test cases for different extension (operator and supplier cases) + it('renders "Save" and "Cancel" buttons', function () { + const tree = mount( + + + , + ); + let buttons = tree.find("Button"); + expect(buttons.length).toEqual(2); + }); - it('shows unsuccessful alert that record was not saved', function () { - showAlert = true; - recordSaved = { - ...recordSaved, - status: ACTION_STATUS.ERROR, - error: { - message: "error" - } - }; - const tree = TestUtils.renderIntoDocument( - - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); - expect(alert).not.toBeNull(); - }); + it("shows successful alert that record was successfully saved", function () { + showAlert = true; + recordSaved = { + ...recordSaved, + status: ACTION_STATUS.SUCCESS, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-success"); + expect(alert).not.toBeNull(); + }); - //TODO (after migrating to React 18): Create test cases for different extension (operator and supplier cases, adding complete & reject buttons) - it('renders loading spinner in "Save" button on saving', function () { - recordSaved = { - ...recordSaved, - status: ACTION_STATUS.PENDING - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const loader = TestUtils.findRenderedDOMComponentWithClass(tree, "loader"); - expect(loader).not.toBeNull(); - }); + it("shows unsuccessful alert that record was not saved", function () { + showAlert = true; + recordSaved = { + ...recordSaved, + status: ACTION_STATUS.ERROR, + error: { + message: "error", + }, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); + expect(alert).not.toBeNull(); + }); + + //TODO (after migrating to React 18): Create test cases for different extension (operator and supplier cases, adding complete & reject buttons) + it('renders loading spinner in "Save" button on saving', function () { + recordSaved = { + ...recordSaved, + status: ACTION_STATUS.PENDING, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const loader = TestUtils.findRenderedDOMComponentWithClass(tree, "loader"); + expect(loader).not.toBeNull(); + }); }); diff --git a/tests/__tests__/components/RecordProvenance.spec.js b/tests/__tests__/components/RecordProvenance.spec.js index 567ac137..734bcaf0 100644 --- a/tests/__tests__/components/RecordProvenance.spec.js +++ b/tests/__tests__/components/RecordProvenance.spec.js @@ -1,68 +1,69 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import RecordProvenance from "../../../js/components/record/RecordProvenance"; import * as RecordState from "../../../js/model/RecordState"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('RequiredProvenance', function () { - const intlData = enLang; - let createdRecord, - modifiedRecord, - newRecord; +describe("RequiredProvenance", function () { + const intlData = enLang; + let createdRecord, modifiedRecord, newRecord; - newRecord = { - localName: '', - complete: false, - isNew: true, - state: RecordState.createInitialState() - }; + newRecord = { + localName: "", + complete: false, + isNew: true, + state: RecordState.createInitialState(), + }; - createdRecord = { - author: {firstName: 'test', lastName: 'test'}, - institution: {localName: 'testInstitution'}, - dateCreated: 1521225180115, - key: '640579951330382351', - localName: 'test', - state: RecordState.createRecordState() - }; + createdRecord = { + author: { firstName: "test", lastName: "test" }, + institution: { localName: "testInstitution" }, + dateCreated: 1521225180115, + key: "640579951330382351", + localName: "test", + state: RecordState.createRecordState(), + }; - modifiedRecord = { - author: {firstName: 'test', lastName: 'test'}, - institution: {localName: 'testInstitution'}, - dateCreated: 1521225180115, - key: '640579951330382351', - localName: 'test', - lastModified: 1521277544192, - state: RecordState.createRecordState() - }; + modifiedRecord = { + author: { firstName: "test", lastName: "test" }, + institution: { localName: "testInstitution" }, + dateCreated: 1521225180115, + key: "640579951330382351", + localName: "test", + lastModified: 1521277544192, + state: RecordState.createRecordState(), + }; - it('does not render info about created date', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'b'); - expect(result.length).toEqual(0); - }); + it("does not render info about created date", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "b"); + expect(result.length).toEqual(0); + }); - it('renders info only about date created', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'b'); - expect(result.length).toEqual(1); - }); + it("renders info only about date created", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "b"); + expect(result.length).toEqual(1); + }); - it('renders info about date created and modified', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'b'); - expect(result.length).toEqual(2); - }); -}); \ No newline at end of file + it("renders info about date created and modified", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "b"); + expect(result.length).toEqual(2); + }); +}); diff --git a/tests/__tests__/components/RecordRow.spec.js b/tests/__tests__/components/RecordRow.spec.js index 79eda9b7..9cd6a1a0 100644 --- a/tests/__tests__/components/RecordRow.spec.js +++ b/tests/__tests__/components/RecordRow.spec.js @@ -1,93 +1,117 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import RecordRow from "../../../js/components/record/RecordRow"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('RecordRow', function () { - const intlData = enLang; - let record, - disableDelete = false, - deletionLoading = false, - onEdit = jest.fn(), - onDelete = jest.fn(); +describe("RecordRow", function () { + const intlData = enLang; + let record, + disableDelete = false, + deletionLoading = false, + onEdit = jest.fn(), + onDelete = jest.fn(); - record = { - "uri": "http://onto.fel.cvut.cz/ontologies/record-manager/patient-record#instance456619208", - "key": "159968282553298775", - "localName": "Test2", - "dateCreated": "1520956570035", - "author": {username: 'test'}, - "institution": {key: 12345678} - }; + record = { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/patient-record#instance456619208", + key: "159968282553298775", + localName: "Test2", + dateCreated: "1520956570035", + author: { username: "test" }, + institution: { key: 12345678 }, + }; - xit('renders one row of table with 5 columns and 2 buttons', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'td'); - expect(td.length).toEqual(5); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'Button'); - expect(buttons.length).toEqual(4); - }); + xit("renders one row of table with 5 columns and 2 buttons", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td"); + expect(td.length).toEqual(5); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(4); + }); - xit('renders "Open" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(4); + xit('renders "Open" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(4); - TestUtils.Simulate.click(buttons[0]); // Open Record - expect(onEdit).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[0]); // Open Record + expect(onEdit).toHaveBeenCalled(); + }); - xit('renders id and patients identifier buttons together with open and delete button and click on one but delete button', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); + xit("renders id and patients identifier buttons together with open and delete button and click on one but delete button", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); - const links = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); - expect(links.length).toEqual(4); + const links = TestUtils.scryRenderedDOMComponentsWithTag(tree, "button"); + expect(links.length).toEqual(4); - TestUtils.Simulate.click(links[0]); - expect(onEdit).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(links[0]); + expect(onEdit).toHaveBeenCalled(); + }); - xit('renders "Delete" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(4); + xit('renders "Delete" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(4); - TestUtils.Simulate.click(buttons[3]); // Delete Record - expect(onDelete).toHaveBeenCalled(); - }); -}); \ No newline at end of file + TestUtils.Simulate.click(buttons[3]); // Delete Record + expect(onDelete).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/RecordTable.spec.js b/tests/__tests__/components/RecordTable.spec.js index e5c40f1c..c63743f0 100644 --- a/tests/__tests__/components/RecordTable.spec.js +++ b/tests/__tests__/components/RecordTable.spec.js @@ -1,68 +1,77 @@ import TestUtils from "react-dom/test-utils"; import React from "react"; -import {IntlProvider} from "react-intl"; +import { IntlProvider } from "react-intl"; import RecordTable from "../../../js/components/record/RecordTable"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; -import enLang from '../../../js/i18n/en'; -import {ROLE} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; +import { ROLE } from "../../../js/constants/DefaultConstants"; +describe("RecordTable", function () { + const intlData = enLang; + let records, + recordsLoaded, + formTemplatesLoaded = {}, + recordDeleted = { status: ACTION_STATUS.SUCCESS }, + handlers = { onEdit: jest.fn() }, + currentUser = { + username: "testUser", + role: ROLE.DOCTOR, + }, + disableDelete = true; -describe('RecordTable', function () { - const intlData = enLang; - let records, - recordsLoaded, - formTemplatesLoaded = {}, - recordDeleted = {status: ACTION_STATUS.SUCCESS}, - handlers = {onEdit: jest.fn()}, - currentUser = { - username: 'testUser', - role: ROLE.DOCTOR - }, - disableDelete = true; + records = [ + { + key: 4324344, + }, + { + key: 4321434, + }, + ]; - records = [ - { - key: 4324344 - }, - { - key: 4321434 - } - ]; + beforeEach(() => { + recordsLoaded = { + status: ACTION_STATUS.SUCCESS, + records, + }; + }); - beforeEach(() => { - recordsLoaded = { - status: ACTION_STATUS.SUCCESS, - records - } - }); + xit("renders table with headers and columns", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(5); + const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td"); + expect(td.length).toEqual(10); + }); - xit('renders table with headers and columns', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'th'); - expect(th.length).toEqual(5); - const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'td'); - expect(td.length).toEqual(10); - }); - - xit('renders 2 "Open" buttons and 4 link buttons and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(6); - TestUtils.Simulate.click(buttons[0]); // open - expect(handlers.onEdit).toHaveBeenCalled(); - }); -}); \ No newline at end of file + xit('renders 2 "Open" buttons and 4 link buttons and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(6); + TestUtils.Simulate.click(buttons[0]); // open + expect(handlers.onEdit).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/Records.spec.js b/tests/__tests__/components/Records.spec.js index b4dd6561..b580479d 100644 --- a/tests/__tests__/components/Records.spec.js +++ b/tests/__tests__/components/Records.spec.js @@ -1,101 +1,111 @@ -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import Records from "../../../js/components/record/Records"; -import {ACTION_STATUS, ROLE, SortDirection} from "../../../js/constants/DefaultConstants"; -import enLang from '../../../js/i18n/en'; -import {INITIAL_PAGE} from "../../../js/components/misc/Pagination"; +import { ACTION_STATUS, ROLE, SortDirection } from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; +import { INITIAL_PAGE } from "../../../js/components/misc/Pagination"; -describe('Records', function () { - const intlData = enLang; - let admin, - records, - recordsLoaded, - recordDeleted, - recordsDeleting = [], - formTemplatesLoaded = {}, - pagination, - filterAndSort, - handlers; - admin = { - username: 'admin', - role: ROLE.ADMIN - }; - records = [{ - "uri": "http://onto.fel.cvut.cz/ontologies/record-manager/patient-record#instance456619209", - "key": "159968282553298774", - "localName": "Test1", - "dateCreated": "1520956570034", - "author": {username: 'test'}, - "institution": {key: 12345678} - }, { - "uri": "http://onto.fel.cvut.cz/ontologies/record-manager/patient-record#instance456619208", - "key": "159968282553298775", - "localName": "Test2", - "dateCreated": "1520956570035", - "author": {username: 'test'}, - "institution": {key: 12345678} - }]; - - beforeEach(() => { - recordsLoaded = { - status: ACTION_STATUS.SUCCESS, - records - }; - pagination = { - pageNumber: INITIAL_PAGE, - handlePagination: jest.fn(), - itemCount: records.length, - pageCount: 1 - }; - filterAndSort = { - sort: { - date: SortDirection.DESC - }, - filters: {}, - onChange: jest.fn() - }; - recordDeleted = { - status: ACTION_STATUS.SUCCESS - }; - handlers = { - onEdit: jest.fn(), - onCreate: jest.fn(), - onDelete: jest.fn(), - onExport: jest.fn() - }; +describe("Records", function () { + const intlData = enLang; + let admin, + records, + recordsLoaded, + recordDeleted, + recordsDeleting = [], + formTemplatesLoaded = {}, + pagination, + filterAndSort, + handlers; + admin = { + username: "admin", + role: ROLE.ADMIN, + }; + records = [ + { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/patient-record#instance456619209", + key: "159968282553298774", + localName: "Test1", + dateCreated: "1520956570034", + author: { username: "test" }, + institution: { key: 12345678 }, + }, + { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/patient-record#instance456619208", + key: "159968282553298775", + localName: "Test2", + dateCreated: "1520956570035", + author: { username: "test" }, + institution: { key: 12345678 }, + }, + ]; - }); + beforeEach(() => { + recordsLoaded = { + status: ACTION_STATUS.SUCCESS, + records, + }; + pagination = { + pageNumber: INITIAL_PAGE, + handlePagination: jest.fn(), + itemCount: records.length, + pageCount: 1, + }; + filterAndSort = { + sort: { + date: SortDirection.DESC, + }, + filters: {}, + onChange: jest.fn(), + }; + recordDeleted = { + status: ACTION_STATUS.SUCCESS, + }; + handlers = { + onEdit: jest.fn(), + onCreate: jest.fn(), + onDelete: jest.fn(), + onExport: jest.fn(), + }; + }); - function render() { - return TestUtils.renderIntoDocument( - - - ); - } + function render() { + return TestUtils.renderIntoDocument( + + + , + ); + } - it('renders card with table and records', function () { - const tree = render(); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'th'); - expect(th.length).toEqual(7); - }); + it("renders card with table and records", function () { + const tree = render(); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(7); + }); - it('renders "Create record" button and click on it', function () { - const tree = render(); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - const createButton = buttons.find(b => b.id === "records-create"); - expect(createButton).toBeDefined(); + it('renders "Create record" button and click on it', function () { + const tree = render(); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + const createButton = buttons.find((b) => b.id === "records-create"); + expect(createButton).toBeDefined(); - TestUtils.Simulate.click(createButton); // Create record - expect(handlers.onCreate).toHaveBeenCalled(); - }); -}); \ No newline at end of file + TestUtils.Simulate.click(createButton); // Create record + expect(handlers.onCreate).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/RequiredAttributes.spec.js b/tests/__tests__/components/RequiredAttributes.spec.js index 496636a0..79267879 100644 --- a/tests/__tests__/components/RequiredAttributes.spec.js +++ b/tests/__tests__/components/RequiredAttributes.spec.js @@ -1,45 +1,45 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import RequiredAttributes from "../../../js/components/record/RequiredAttributes"; import * as RecordState from "../../../js/model/RecordState"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('RequiredAttributes', function () { - const intlData = enLang; - let record, - completed = true, - onChange = jest.fn(); +describe("RequiredAttributes", function () { + const intlData = enLang; + let record, + completed = true, + onChange = jest.fn(); + record = { + author: { firstName: "test", lastName: "test" }, + institution: { localName: "testInstitution" }, + dateCreated: 1521225180115, + key: "640579951330382351", + localName: "test", + lastModified: 1521277544192, + state: RecordState.createRecordState(), + }; - record = { - author: {firstName: 'test', lastName: 'test'}, - institution: {localName: 'testInstitution'}, - dateCreated: 1521225180115, - key: '640579951330382351', - localName: 'test', - lastModified: 1521277544192, - state: RecordState.createRecordState() - }; - - xit('renders form with one input and help', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree,'input'); - expect(result.length).toEqual(1); - for(let input of result) { - switch(input.name){ - case "localName": - expect(input.value).toEqual("test"); - expect(input.type).toEqual("text"); - break; - } - } - const helpIcon = TestUtils.scryRenderedDOMComponentsWithClass(tree,'help-icon'); - expect(helpIcon.length).toEqual(1); - }); -}); \ No newline at end of file + xit("renders form with one input and help", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(result.length).toEqual(1); + for (let input of result) { + switch (input.name) { + case "localName": + expect(input.value).toEqual("test"); + expect(input.type).toEqual("text"); + break; + } + } + const helpIcon = TestUtils.scryRenderedDOMComponentsWithClass(tree, "help-icon"); + expect(helpIcon.length).toEqual(1); + }); +}); diff --git a/tests/__tests__/components/User.spec.js b/tests/__tests__/components/User.spec.js index 309ce978..03a490b7 100644 --- a/tests/__tests__/components/User.spec.js +++ b/tests/__tests__/components/User.spec.js @@ -1,415 +1,512 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import User from "../../../js/components/user/User"; -import {ACTION_STATUS, ROLE} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS, ROLE } from "../../../js/constants/DefaultConstants"; import * as EntityFactory from "../../../js/utils/EntityFactory"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('User', function () { - const intlData = enLang; - let user, - admin, - newUser = EntityFactory.initNewUser(), - institutions, - backToInstitution, - userSaved, - showAlert, - userLoaded, - currentUser, - currentUserAdmin, - handlers = { - onSave: jest.fn(), - onCancel: jest.fn(), - onChange: jest.fn(), - }; - - currentUser = { - username: 'test', - role: ROLE.DOCTOR - }; - currentUserAdmin = { - username: 'test', - role: ROLE.ADMIN - }; - newUser = { - ...newUser, - password: 'test' +describe("User", function () { + const intlData = enLang; + let user, + admin, + newUser = EntityFactory.initNewUser(), + institutions, + backToInstitution, + userSaved, + showAlert, + userLoaded, + currentUser, + currentUserAdmin, + handlers = { + onSave: jest.fn(), + onCancel: jest.fn(), + onChange: jest.fn(), }; - admin = { - "uri": "http://onto.fel.cvut.cz/ontologies/record-manager/Admin-Administratorowitch", - "firstName": "Test1", - "lastName": "Man", - "username": "testman1", - "password": "test", - "institution": { - "uri": "http://test.io", - "key": "823372507340798303", - "name": "Test Institution", - "emailAddress": "test@institution.io" - }, - "types": [ - "http://onto.fel.cvut.cz/ontologies/record-manager/administrator", - "http://onto.fel.cvut.cz/ontologies/record-manager/doctor" - ] - }; + currentUser = { + username: "test", + role: ROLE.DOCTOR, + }; + currentUserAdmin = { + username: "test", + role: ROLE.ADMIN, + }; + newUser = { + ...newUser, + password: "test", + }; - user = { - "uri": "http://onto.fel.cvut.cz/ontologies/record-manager/erter-tert", - "firstName": "Test2", - "lastName": "Man", - "username": "testman2", - "password": "test", - "emailAddress": "test@man.io", - "institution": { - "key": 18691 - }, - "types": [ - "http://onto.fel.cvut.cz/ontologies/record-manager/doctor" - ] - }; + admin = { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/Admin-Administratorowitch", + firstName: "Test1", + lastName: "Man", + username: "testman1", + password: "test", + institution: { + uri: "http://test.io", + key: "823372507340798303", + name: "Test Institution", + emailAddress: "test@institution.io", + }, + types: [ + "http://onto.fel.cvut.cz/ontologies/record-manager/administrator", + "http://onto.fel.cvut.cz/ontologies/record-manager/doctor", + ], + }; - institutions = [{ - "uri": "http://test1.io", - "key": "823372507340798303", - "name": "Test1 Institution", - "emailAddress": "test1@institution.io" - }, { - "uri": "http://test2.io", - "key": "823372507340798301", - "name": "Test2 Institution", - "emailAddress": "test2@institution.io" - }]; + user = { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/erter-tert", + firstName: "Test2", + lastName: "Man", + username: "testman2", + password: "test", + emailAddress: "test@man.io", + institution: { + key: 18691, + }, + types: ["http://onto.fel.cvut.cz/ontologies/record-manager/doctor"], + }; - beforeEach(() => { - showAlert = false; - userLoaded = { - status: ACTION_STATUS.SUCCESS, - error: '' - }; - userSaved = { - status: ACTION_STATUS.SUCCESS, - error: '' - }; - }); + institutions = [ + { + uri: "http://test1.io", + key: "823372507340798303", + name: "Test1 Institution", + emailAddress: "test1@institution.io", + }, + { + uri: "http://test2.io", + key: "823372507340798301", + name: "Test2 Institution", + emailAddress: "test2@institution.io", + }, + ]; - it('shows loader', function () { - userLoaded = { - status: ACTION_STATUS.PENDING - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.findRenderedDOMComponentWithClass(tree, 'loader-spin'); - expect(result).not.toBeNull(); - }); + beforeEach(() => { + showAlert = false; + userLoaded = { + status: ACTION_STATUS.SUCCESS, + error: "", + }; + userSaved = { + status: ACTION_STATUS.SUCCESS, + error: "", + }; + }); - it('shows error about user was not loaded', function () { - userLoaded = { - ...userLoaded, - status: ACTION_STATUS.ERROR, - error: { - message: "Error" - } - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); - expect(alert).not.toBeNull(); - }); + it("shows loader", function () { + userLoaded = { + status: ACTION_STATUS.PENDING, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.findRenderedDOMComponentWithClass(tree, "loader-spin"); + expect(result).not.toBeNull(); + }); - it("renders user's form empty with random button", function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(result.length).toEqual(5); - for (let input of result) { - switch (input.name) { - case "firstName": - expect(input.value).toEqual(""); - expect(input.type).toEqual("text"); - break; - case "lastName": - expect(input.value).toEqual(""); - expect(input.type).toEqual("text"); - break; - case "username": - expect(input.value).toEqual(""); - expect(input.type).toEqual("text"); - break; - case "emailAddress": - expect(input.value).toEqual(""); - expect(input.type).toEqual("email"); - break; - case "password": - expect(input.value).toEqual("test"); - expect(input.type).toEqual("text"); - expect(input.readOnly).toBeTruthy(); - break; - } - } - const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'select'); - expect(selects.length).toEqual(2); - expect(selects[1].value).toEqual(ROLE.DOCTOR); + it("shows error about user was not loaded", function () { + userLoaded = { + ...userLoaded, + status: ACTION_STATUS.ERROR, + error: { + message: "Error", + }, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); + expect(alert).not.toBeNull(); + }); - const randomButton = TestUtils.scryRenderedDOMComponentsWithClass(tree, 'button-random'); - expect(randomButton.length).toEqual(1); - }); + it("renders user's form empty with random button", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(result.length).toEqual(5); + for (let input of result) { + switch (input.name) { + case "firstName": + expect(input.value).toEqual(""); + expect(input.type).toEqual("text"); + break; + case "lastName": + expect(input.value).toEqual(""); + expect(input.type).toEqual("text"); + break; + case "username": + expect(input.value).toEqual(""); + expect(input.type).toEqual("text"); + break; + case "emailAddress": + expect(input.value).toEqual(""); + expect(input.type).toEqual("email"); + break; + case "password": + expect(input.value).toEqual("test"); + expect(input.type).toEqual("text"); + expect(input.readOnly).toBeTruthy(); + break; + } + } + const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, "select"); + expect(selects.length).toEqual(2); + expect(selects[1].value).toEqual(ROLE.DOCTOR); - it('renders clickable "Save" button and click on it', function () { - const newUserFilled = { - ...newUser, - username: 'test', - firstName: 'test1', - lastName: 'test2', - emailAddress: 'test@test.cz', - institution: {} - }; - const tree = TestUtils.renderIntoDocument( - - - ); - let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + const randomButton = TestUtils.scryRenderedDOMComponentsWithClass(tree, "button-random"); + expect(randomButton.length).toEqual(1); + }); - expect(buttons[1].disabled).toBeFalsy(); - TestUtils.Simulate.click(buttons[1]); // save - expect(handlers.onSave).toHaveBeenCalled(); - }); + it('renders clickable "Save" button and click on it', function () { + const newUserFilled = { + ...newUser, + username: "test", + firstName: "test1", + lastName: "test2", + emailAddress: "test@test.cz", + institution: {}, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + let buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); + expect(buttons[1].disabled).toBeFalsy(); + TestUtils.Simulate.click(buttons[1]); // save + expect(handlers.onSave).toHaveBeenCalled(); + }); - it('shows successful alert that user was successfully saved', function () { - showAlert = true; - userSaved = { - ...userSaved, - status: ACTION_STATUS.SUCCESS - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-success"); - expect(alert).not.toBeNull(); - }); + it("shows successful alert that user was successfully saved", function () { + showAlert = true; + userSaved = { + ...userSaved, + status: ACTION_STATUS.SUCCESS, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-success"); + expect(alert).not.toBeNull(); + }); - it('shows unsuccessful alert that user was not saved', function () { - showAlert = true; - userSaved = { - ...userSaved, - status: ACTION_STATUS.ERROR, - error: { - message: "Error" - } - }; - const tree = TestUtils.renderIntoDocument( - - - ); - const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); - expect(alert).not.toBeNull(); - }); + it("shows unsuccessful alert that user was not saved", function () { + showAlert = true; + userSaved = { + ...userSaved, + status: ACTION_STATUS.ERROR, + error: { + message: "Error", + }, + }; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const alert = TestUtils.scryRenderedDOMComponentsWithClass(tree, "alert-danger"); + expect(alert).not.toBeNull(); + }); - it('renders filled user\'s form without random button', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(result.length).toEqual(4); - for (let input of result) { - switch (input.name) { - case "firstName": - expect(input.value).toEqual("Test2"); - expect(input.type).toEqual("text"); - break; - case "lastName": - expect(input.value).toEqual("Man"); - expect(input.type).toEqual("text"); - break; - case "username": - expect(input.value).toEqual("testman2"); - expect(input.type).toEqual("text"); - expect(input.disabled).toBeTruthy(); - break; - case "emailAddress": - expect(input.value).toEqual("test@man.io"); - expect(input.type).toEqual("email"); - break; - } - } - const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'select'); - expect(selects.length).toEqual(2); - expect(selects[0].disabled).toBeFalsy(); - expect(selects[1].disabled).toBeFalsy(); + it("renders filled user's form without random button", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(result.length).toEqual(4); + for (let input of result) { + switch (input.name) { + case "firstName": + expect(input.value).toEqual("Test2"); + expect(input.type).toEqual("text"); + break; + case "lastName": + expect(input.value).toEqual("Man"); + expect(input.type).toEqual("text"); + break; + case "username": + expect(input.value).toEqual("testman2"); + expect(input.type).toEqual("text"); + expect(input.disabled).toBeTruthy(); + break; + case "emailAddress": + expect(input.value).toEqual("test@man.io"); + expect(input.type).toEqual("email"); + break; + } + } + const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, "select"); + expect(selects.length).toEqual(2); + expect(selects[0].disabled).toBeFalsy(); + expect(selects[1].disabled).toBeFalsy(); - const randomButton = TestUtils.scryRenderedDOMComponentsWithClass(tree, 'glyphicon'); - expect(randomButton.length).toEqual(0); - }); + const randomButton = TestUtils.scryRenderedDOMComponentsWithClass(tree, "glyphicon"); + expect(randomButton.length).toEqual(0); + }); - it('renders filled admin\'s form', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(result.length).toEqual(4); - for (let input of result) { - switch (input.name) { - case "firstName": - expect(input.value).toEqual("Test1"); - expect(input.type).toEqual("text"); - break; - case "lastName": - expect(input.value).toEqual("Man"); - expect(input.type).toEqual("text"); - break; - case "username": - expect(input.value).toEqual("testman1"); - expect(input.type).toEqual("text"); - expect(input.disabled).toBeTruthy(); - break; - case "emailAddress": - expect(input.value).toEqual(""); - expect(input.type).toEqual("email"); - break; - } - } - const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'select'); - expect(selects.length).toEqual(2); - expect(selects[1].value).toEqual(ROLE.ADMIN); - expect(selects[0].disabled).toBeFalsy(); - expect(selects[1].disabled).toBeFalsy(); - }); + it("renders filled admin's form", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(result.length).toEqual(4); + for (let input of result) { + switch (input.name) { + case "firstName": + expect(input.value).toEqual("Test1"); + expect(input.type).toEqual("text"); + break; + case "lastName": + expect(input.value).toEqual("Man"); + expect(input.type).toEqual("text"); + break; + case "username": + expect(input.value).toEqual("testman1"); + expect(input.type).toEqual("text"); + expect(input.disabled).toBeTruthy(); + break; + case "emailAddress": + expect(input.value).toEqual(""); + expect(input.type).toEqual("email"); + break; + } + } + const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, "select"); + expect(selects.length).toEqual(2); + expect(selects[1].value).toEqual(ROLE.ADMIN); + expect(selects[0].disabled).toBeFalsy(); + expect(selects[1].disabled).toBeFalsy(); + }); - it('renders filled user\'s form', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'input'); - expect(result.length).toEqual(4); - for (let input of result) { - switch (input.name) { - case "firstName": - expect(input.value).toEqual("Test1"); - expect(input.type).toEqual("text"); - break; - case "lastName": - expect(input.value).toEqual("Man"); - expect(input.type).toEqual("text"); - break; - case "username": - expect(input.value).toEqual("testman1"); - expect(input.type).toEqual("text"); - expect(input.disabled).toBeTruthy(); - break; - case "emailAddress": - expect(input.value).toEqual(""); - expect(input.type).toEqual("email"); - break; - } - } - const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'select'); - expect(selects.length).toEqual(1); - expect(selects[0].value).toEqual(ROLE.ADMIN); - expect(selects[0].disabled).toBeTruthy(); - }); + it("renders filled user's form", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const result = TestUtils.scryRenderedDOMComponentsWithTag(tree, "input"); + expect(result.length).toEqual(4); + for (let input of result) { + switch (input.name) { + case "firstName": + expect(input.value).toEqual("Test1"); + expect(input.type).toEqual("text"); + break; + case "lastName": + expect(input.value).toEqual("Man"); + expect(input.type).toEqual("text"); + break; + case "username": + expect(input.value).toEqual("testman1"); + expect(input.type).toEqual("text"); + expect(input.disabled).toBeTruthy(); + break; + case "emailAddress": + expect(input.value).toEqual(""); + expect(input.type).toEqual("email"); + break; + } + } + const selects = TestUtils.scryRenderedDOMComponentsWithTag(tree, "select"); + expect(selects.length).toEqual(1); + expect(selects[0].value).toEqual(ROLE.ADMIN); + expect(selects[0].disabled).toBeTruthy(); + }); - it('renders "Cancel" button and click on it', function () { - const user = { - ...newUser, - username: 'test', - firstName: 'test1', - lastName: 'test2', - emailAddress: 'test@test.cz', - institution: {} - }; + it('renders "Cancel" button and click on it', function () { + const user = { + ...newUser, + username: "test", + firstName: "test1", + lastName: "test2", + emailAddress: "test@test.cz", + institution: {}, + }; - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[2]); // cancel - expect(handlers.onCancel).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[2]); // cancel + expect(handlers.onCancel).toHaveBeenCalled(); + }); - it('renders "Back to institution" button and click on it', function () { - const user = { - ...newUser, - username: 'test', - firstName: 'test1', - lastName: 'test2', - emailAddress: 'test@test.cz', - institution: {} - }; + it('renders "Back to institution" button and click on it', function () { + const user = { + ...newUser, + username: "test", + firstName: "test1", + lastName: "test2", + emailAddress: "test@test.cz", + institution: {}, + }; - backToInstitution = true; - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + backToInstitution = true; + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[2]); // back to institution - expect(handlers.onCancel).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[2]); // back to institution + expect(handlers.onCancel).toHaveBeenCalled(); + }); - it('renders loading spinner in "Save" button on saving', function () { - userSaved = { - ...userSaved, - status: ACTION_STATUS.PENDING - }; - const user = { - ...newUser, - username: 'test', - firstName: 'test1', - lastName: 'test2', - emailAddress: 'test@test.cz', - institution: {} - }; + it('renders loading spinner in "Save" button on saving', function () { + userSaved = { + ...userSaved, + status: ACTION_STATUS.PENDING, + }; + const user = { + ...newUser, + username: "test", + firstName: "test1", + lastName: "test2", + emailAddress: "test@test.cz", + institution: {}, + }; - const tree = TestUtils.renderIntoDocument( - - - ); - const loader = TestUtils.findRenderedDOMComponentWithClass(tree, "loader"); - expect(loader).not.toBeNull(); - }); -}); \ No newline at end of file + const tree = TestUtils.renderIntoDocument( + + + , + ); + const loader = TestUtils.findRenderedDOMComponentWithClass(tree, "loader"); + expect(loader).not.toBeNull(); + }); +}); diff --git a/tests/__tests__/components/UserRow.spec.js b/tests/__tests__/components/UserRow.spec.js index cc913faa..8a4a09fa 100644 --- a/tests/__tests__/components/UserRow.spec.js +++ b/tests/__tests__/components/UserRow.spec.js @@ -1,101 +1,101 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import UserRow from "../../../js/components/user/UserRow"; -import enLang from '../../../js/i18n/en'; +import enLang from "../../../js/i18n/en"; -describe('UserRow', function () { - const intlData = enLang; - let user, - deletionLoading = false, - onEdit = jest.fn(), - onDelete = jest.fn(); +describe("UserRow", function () { + const intlData = enLang; + let user, + deletionLoading = false, + onEdit = jest.fn(), + onDelete = jest.fn(); - user = { - "uri": "http://onto.fel.cvut.cz/ontologies/record-manager/Admin-Administratorowitch", - "firstName": "Test1", - "lastName": "Man", - "username": "testman1", - "emailAddress": "test@man.io", - "institution": { - "uri": "http://test.io", - "key": "823372507340798303", - "name": "Test Institution", - "emailAddress": "test@institution.io" - }, - "types": [ - "http://onto.fel.cvut.cz/ontologies/record-manager/administrator", - "http://onto.fel.cvut.cz/ontologies/record-manager/doctor" - ] - }; + user = { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/Admin-Administratorowitch", + firstName: "Test1", + lastName: "Man", + username: "testman1", + emailAddress: "test@man.io", + institution: { + uri: "http://test.io", + key: "823372507340798303", + name: "Test Institution", + emailAddress: "test@institution.io", + }, + types: [ + "http://onto.fel.cvut.cz/ontologies/record-manager/administrator", + "http://onto.fel.cvut.cz/ontologies/record-manager/doctor", + ], + }; - it('renders one row of table with 5 columns and 2 buttons and 1 link button', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'td'); - expect(td.length).toEqual(5); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'Button'); - expect(buttons.length).toEqual(3); - }); + it("renders one row of table with 5 columns and 2 buttons and 1 link button", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td"); + expect(td.length).toEqual(5); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); + }); - it('renders "Open" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + it('renders "Open" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[0]); // Open User - expect(onEdit).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[0]); // Open User + expect(onEdit).toHaveBeenCalled(); + }); - it('renders name with link and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); + it("renders name with link and click on it", function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); - const buttons = TestUtils.scryRenderedDOMComponentsWithClass(tree, "btn-link"); - expect(buttons.length).toBe(1); + const buttons = TestUtils.scryRenderedDOMComponentsWithClass(tree, "btn-link"); + expect(buttons.length).toBe(1); - TestUtils.Simulate.click(buttons[0]); - expect(onEdit).toHaveBeenCalled(); - }); + TestUtils.Simulate.click(buttons[0]); + expect(onEdit).toHaveBeenCalled(); + }); - it('renders "Delete" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - - - -
    -
    ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(3); + it('renders "Delete" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + + + +
    +
    , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(3); - TestUtils.Simulate.click(buttons[2]); // Delete User - expect(onDelete).toHaveBeenCalled(); - }); -}); \ No newline at end of file + TestUtils.Simulate.click(buttons[2]); // Delete User + expect(onDelete).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/components/UserTable.spec.js b/tests/__tests__/components/UserTable.spec.js index e591deea..0456a928 100644 --- a/tests/__tests__/components/UserTable.spec.js +++ b/tests/__tests__/components/UserTable.spec.js @@ -1,54 +1,56 @@ -'use strict'; +"use strict"; -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import UserTable from "../../../js/components/user/UserTable"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; -import enLang from '../../../js/i18n/en'; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; -describe('UserTable', function () { - const intlData = enLang; - let users, - userDeleted = { - status: ACTION_STATUS.SUCCESS - }, - handlers = { - onEdit: jest.fn(), - onCreate: jest.fn(), - onDelete: jest.fn() - }; +describe("UserTable", function () { + const intlData = enLang; + let users, + userDeleted = { + status: ACTION_STATUS.SUCCESS, + }, + handlers = { + onEdit: jest.fn(), + onCreate: jest.fn(), + onDelete: jest.fn(), + }; - users = [{ - "uri":"http://onto.fel.cvut.cz/ontologies/record-manager/erter-tert", - "firstName":"Test2", - "lastName":"Man", - "username":"testman2", - "emailAddress":"test@man.io", - "types":[ - "http://onto.fel.cvut.cz/ontologies/record-manager/doctor" - ] - }]; + users = [ + { + uri: "http://onto.fel.cvut.cz/ontologies/record-manager/erter-tert", + firstName: "Test2", + lastName: "Man", + username: "testman2", + emailAddress: "test@man.io", + types: ["http://onto.fel.cvut.cz/ontologies/record-manager/doctor"], + }, + ]; - it('renders table with 5 headers columns', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree,'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree,'th'); - expect(th.length).toEqual(5); - }); + it("renders table with 5 headers columns", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(5); + }); - it('renders modal window by "Delete" button click', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - TestUtils.Simulate.click(buttons[1]); // Delete User - const modal = TestUtils.scryRenderedDOMComponentsWithClass(tree, "modal-dialog"); - expect(modal).not.toBeNull(); - }); + it('renders modal window by "Delete" button click', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + TestUtils.Simulate.click(buttons[1]); // Delete User + const modal = TestUtils.scryRenderedDOMComponentsWithClass(tree, "modal-dialog"); + expect(modal).not.toBeNull(); + }); }); diff --git a/tests/__tests__/components/Users.spec.js b/tests/__tests__/components/Users.spec.js index 279e695e..feb23012 100644 --- a/tests/__tests__/components/Users.spec.js +++ b/tests/__tests__/components/Users.spec.js @@ -1,76 +1,79 @@ -import React from 'react'; -import {IntlProvider} from 'react-intl'; -import TestUtils from 'react-dom/test-utils'; +import React from "react"; +import { IntlProvider } from "react-intl"; +import TestUtils from "react-dom/test-utils"; import Users from "../../../js/components/user/Users"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; -import enLang from '../../../js/i18n/en'; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; +import enLang from "../../../js/i18n/en"; -describe('Users', function () { - const intlData = enLang; - let users, - usersLoaded, - usersLoadedEmpty, - handlers; +describe("Users", function () { + const intlData = enLang; + let users, usersLoaded, usersLoadedEmpty, handlers; - users = [{ - "username": "testman1" - }, { - "username": "testman2" - }]; + users = [ + { + username: "testman1", + }, + { + username: "testman2", + }, + ]; - beforeEach(() => { - handlers = { - onEdit: jest.fn(), - onCreate: jest.fn(), - onDelete: jest.fn() - }; - usersLoaded = { - status: ACTION_STATUS.SUCCESS, - users - }; - usersLoadedEmpty = { - status: ACTION_STATUS.SUCCESS, - users: [] - }; - }); + beforeEach(() => { + handlers = { + onEdit: jest.fn(), + onCreate: jest.fn(), + onDelete: jest.fn(), + }; + usersLoaded = { + status: ACTION_STATUS.SUCCESS, + users, + }; + usersLoadedEmpty = { + status: ACTION_STATUS.SUCCESS, + users: [], + }; + }); - it('renders card with text, that no users were found', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const text = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'p'); - expect(text.length).toEqual(1); - }); + it("renders card with text, that no users were found", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const text = TestUtils.scryRenderedDOMComponentsWithTag(tree, "p"); + expect(text.length).toEqual(1); + }); - it('renders card with table and table headers', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, 'card'); - expect(cardHeading).not.toBeNull(); - const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, 'card-body'); - expect(cardBody).not.toBeNull(); - const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'table'); - expect(table).not.toBeNull(); - const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'th'); - expect(th.length).toEqual(5); - }); + it("renders card with table and table headers", function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const cardHeading = TestUtils.findRenderedDOMComponentWithClass(tree, "card"); + expect(cardHeading).not.toBeNull(); + const cardBody = TestUtils.findRenderedDOMComponentWithClass(tree, "card-body"); + expect(cardBody).not.toBeNull(); + const table = TestUtils.scryRenderedDOMComponentsWithTag(tree, "table"); + expect(table).not.toBeNull(); + const th = TestUtils.scryRenderedDOMComponentsWithTag(tree, "th"); + expect(th.length).toEqual(5); + }); - it('renders "Create user" button and click on it', function () { - const tree = TestUtils.renderIntoDocument( - - - ); - const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); - expect(buttons.length).toEqual(7); + it('renders "Create user" button and click on it', function () { + const tree = TestUtils.renderIntoDocument( + + + , + ); + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button"); + expect(buttons.length).toEqual(7); - TestUtils.Simulate.click(buttons[6]); // Create User - expect(handlers.onCreate).toHaveBeenCalled(); - }); -}); \ No newline at end of file + TestUtils.Simulate.click(buttons[6]); // Create User + expect(handlers.onCreate).toHaveBeenCalled(); + }); +}); diff --git a/tests/__tests__/reducers/AuthReducer.spec.js b/tests/__tests__/reducers/AuthReducer.spec.js index d38cbfb8..78eb3c39 100644 --- a/tests/__tests__/reducers/AuthReducer.spec.js +++ b/tests/__tests__/reducers/AuthReducer.spec.js @@ -1,300 +1,292 @@ - -import React from 'react'; +import React from "react"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; -import {getRole} from "../../../js/utils/Utils"; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; +import { getRole } from "../../../js/utils/Utils"; import AuthReducer from "../../../js/reducers/AuthReducer"; import UserReducer from "../../../js/reducers/UserReducer"; -describe('AuthReducer', function () { - const user = { - username: 'test', - types:[ - "http://onto.fel.cvut.cz/ontologies/record-manager/administrator", - "http://onto.fel.cvut.cz/ontologies/record-manager/doctor" - ]}, - error = { - message: 'An error has occurred.' - }; - - it('handles AUTH_USER_PENDING', () => { - const initialState = { - authenticated: false, - isLoaded: false, - isLogging: false, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.AUTH_USER_PENDING, - }; - - const newState = AuthReducer(initialState, action); - - const expectedState = { - authenticated: false, - isLoaded: false, - isLogging: true, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); - }); - - it('handles AUTH_USER_SUCCESS', () => { - const initialState = { - authenticated: false, - isLoaded: false, - isLogging: true, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.AUTH_USER_SUCCESS, - }; - - const newState = AuthReducer(initialState, action); - - const expectedState = { - error: '', - authenticated: true, - isLoaded: false, - isLogging: false, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); - }); - - it('handles AUTH_USER_ERROR', () => { - const initialState = { - authenticated: false, - isLoaded: false, - isLogging: true, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.AUTH_USER_ERROR, - error - }; - - const newState = AuthReducer(initialState, action); - - const expectedState = { - testEntry: "should not touch", - authenticated: false, - isLoaded: false, - isLogging: false, - error - }; - expect(newState).toEqual(expectedState); - }); - - it('handles LOAD_USER_PROFILE_PENDING', () => { - const initialState = { - authenticated: false, - isLoaded: false, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USER_PROFILE_PENDING, - }; - - const newState = AuthReducer(initialState, action); - - const expectedState = { - isLoaded: false, - authenticated: false, - status: ACTION_STATUS.PENDING, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); - }); - - it('handles LOAD_USER_PROFILE_SUCCESS', () => { - const initialState = { - authenticated: false, - isLoaded: false, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, - user, - }; - - const newState = AuthReducer(initialState, action); - - const expectedState = { - isLoaded: true, - authenticated: true, - status: ACTION_STATUS.SUCCESS, - user: { - ...user, - role: getRole(user) - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); - }); - - it('handles LOAD_USER_PROFILE_ERROR', () => { - const initialState = { - authenticated: false, - isLoaded: false, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USER_PROFILE_ERROR, - error - }; - - const newState = AuthReducer(initialState, action); - - const expectedState = { - isLoaded: false, - authenticated: false, - status: ACTION_STATUS.ERROR, - user: { - error: error - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); +describe("AuthReducer", function () { + const user = { + username: "test", + types: [ + "http://onto.fel.cvut.cz/ontologies/record-manager/administrator", + "http://onto.fel.cvut.cz/ontologies/record-manager/doctor", + ], + }, + error = { + message: "An error has occurred.", + }; + + it("handles AUTH_USER_PENDING", () => { + const initialState = { + authenticated: false, + isLoaded: false, + isLogging: false, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.AUTH_USER_PENDING, + }; + + const newState = AuthReducer(initialState, action); + + const expectedState = { + authenticated: false, + isLoaded: false, + isLogging: true, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles AUTH_USER_SUCCESS", () => { + const initialState = { + authenticated: false, + isLoaded: false, + isLogging: true, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.AUTH_USER_SUCCESS, + }; + + const newState = AuthReducer(initialState, action); + + const expectedState = { + error: "", + authenticated: true, + isLoaded: false, + isLogging: false, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles AUTH_USER_ERROR", () => { + const initialState = { + authenticated: false, + isLoaded: false, + isLogging: true, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.AUTH_USER_ERROR, + error, + }; + + const newState = AuthReducer(initialState, action); + + const expectedState = { + testEntry: "should not touch", + authenticated: false, + isLoaded: false, + isLogging: false, + error, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_USER_PROFILE_PENDING", () => { + const initialState = { + authenticated: false, + isLoaded: false, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USER_PROFILE_PENDING, + }; + + const newState = AuthReducer(initialState, action); + + const expectedState = { + isLoaded: false, + authenticated: false, + status: ACTION_STATUS.PENDING, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_USER_PROFILE_SUCCESS", () => { + const initialState = { + authenticated: false, + isLoaded: false, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USER_PROFILE_SUCCESS, + user, + }; + + const newState = AuthReducer(initialState, action); + + const expectedState = { + isLoaded: true, + authenticated: true, + status: ACTION_STATUS.SUCCESS, + user: { + ...user, + role: getRole(user), + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_USER_PROFILE_ERROR", () => { + const initialState = { + authenticated: false, + isLoaded: false, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USER_PROFILE_ERROR, + error, + }; + + const newState = AuthReducer(initialState, action); + + const expectedState = { + isLoaded: false, + authenticated: false, + status: ACTION_STATUS.ERROR, + user: { + error: error, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles PASSWORD_RESET_PENDING action", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.PASSWORD_RESET_PENDING, + }), + ).toEqual({ + passwordResetStatus: ACTION_STATUS.PENDING, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_RESET_PENDING action', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.PASSWORD_RESET_PENDING - }) - ).toEqual( - { - passwordResetStatus: ACTION_STATUS.PENDING, - testEntry: initialState.testEntry - }); + }); + + it("handles PASSWORD_RESET_SUCCESS action", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.PASSWORD_RESET_SUCCESS, + }), + ).toEqual({ + passwordResetStatus: ACTION_STATUS.SUCCESS, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_RESET_SUCCESS action', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.PASSWORD_RESET_SUCCESS - }) - ).toEqual( - { - passwordResetStatus: ACTION_STATUS.SUCCESS, - testEntry: initialState.testEntry - }); - }); - - it('handles VALIDATE_TOKEN_PENDING action', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.VALIDATE_TOKEN_PENDING - }) - ).toEqual( - { - validTokenStatus: ACTION_STATUS.PENDING, - testEntry: initialState.testEntry - }); + }); + + it("handles VALIDATE_TOKEN_PENDING action", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.VALIDATE_TOKEN_PENDING, + }), + ).toEqual({ + validTokenStatus: ACTION_STATUS.PENDING, + testEntry: initialState.testEntry, }); - - it('handles VALIDATE_TOKEN_SUCCESS action', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.VALIDATE_TOKEN_SUCCESS - }) - ).toEqual( - { - validTokenStatus: ACTION_STATUS.SUCCESS, - testEntry: initialState.testEntry - }); + }); + + it("handles VALIDATE_TOKEN_SUCCESS action", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.VALIDATE_TOKEN_SUCCESS, + }), + ).toEqual({ + validTokenStatus: ACTION_STATUS.SUCCESS, + testEntry: initialState.testEntry, }); - - it('handles VALIDATE_TOKEN_ERROR action', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.VALIDATE_TOKEN_ERROR, - error - }) - ).toEqual( - { - validTokenStatus: ACTION_STATUS.ERROR, - testEntry: initialState.testEntry - }); + }); + + it("handles VALIDATE_TOKEN_ERROR action", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.VALIDATE_TOKEN_ERROR, + error, + }), + ).toEqual({ + validTokenStatus: ACTION_STATUS.ERROR, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_CHANGE_TOKEN_PENDING action', () => { - const initialState = { - passwordChange: {}, - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING - }) - ).toEqual( - { - passwordChange: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); + }); + + it("handles PASSWORD_CHANGE_TOKEN_PENDING action", () => { + const initialState = { + passwordChange: {}, + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.PASSWORD_CHANGE_TOKEN_PENDING, + }), + ).toEqual({ + passwordChange: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_CHANGE_TOKEN_SUCCESS action', () => { - const initialState = { - passwordChange: {}, - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS - }) - ).toEqual( - { - passwordChange: { - status: ACTION_STATUS.SUCCESS - }, - testEntry: initialState.testEntry - }); + }); + + it("handles PASSWORD_CHANGE_TOKEN_SUCCESS action", () => { + const initialState = { + passwordChange: {}, + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.PASSWORD_CHANGE_TOKEN_SUCCESS, + }), + ).toEqual({ + passwordChange: { + status: ACTION_STATUS.SUCCESS, + }, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_CHANGE_TOKEN_ERROR action', () => { - const initialState = { - passwordChange: {}, - testEntry: "should not touch" - }; - - expect( - AuthReducer(initialState, { - type: ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR, - error - }) - ).toEqual( - { - passwordChange: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + }); + + it("handles PASSWORD_CHANGE_TOKEN_ERROR action", () => { + const initialState = { + passwordChange: {}, + testEntry: "should not touch", + }; + + expect( + AuthReducer(initialState, { + type: ActionConstants.PASSWORD_CHANGE_TOKEN_ERROR, + error, + }), + ).toEqual({ + passwordChange: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/HistoryReducer.spec.js b/tests/__tests__/reducers/HistoryReducer.spec.js index 56d2da4e..02265433 100644 --- a/tests/__tests__/reducers/HistoryReducer.spec.js +++ b/tests/__tests__/reducers/HistoryReducer.spec.js @@ -1,168 +1,161 @@ import HistoryReducer from "../../../js/reducers/HistoryReducer"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; - -describe('HistoryReducer', function () { - const error = { - message: 'An error has occurred.'}, - action = {type: 'TEST_ACTION'}, - actions = [action, action]; - - it('leaves state unchanged if action not recognized', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: 'NONEXISTENT_ACTION_TYPE', - payload: 'error' - }) - ).toEqual( - { - testEntry: initialState.testEntry - }); +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; + +describe("HistoryReducer", function () { + const error = { + message: "An error has occurred.", + }, + action = { type: "TEST_ACTION" }, + actions = [action, action]; + + it("leaves state unchanged if action not recognized", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: "NONEXISTENT_ACTION_TYPE", + payload: "error", + }), + ).toEqual({ + testEntry: initialState.testEntry, }); - - it('handles LOAD_ACTIONS_HISTORY_PENDING', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING - }) - ).toEqual( - { - actionsLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); + }); + + it("handles LOAD_ACTIONS_HISTORY_PENDING", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.LOAD_ACTIONS_HISTORY_PENDING, + }), + ).toEqual({ + actionsLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_ACTIONS_HISTORY_SUCCESS', () => { - const initialState = { - actionsLoaded: {}, - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS, - actionsHistory: actions - }) - ).toEqual( - { - actionsLoaded: { - status: ACTION_STATUS.SUCCESS, - actions, - error: '' - }, - testEntry: initialState.testEntry - }); + }); + + it("handles LOAD_ACTIONS_HISTORY_SUCCESS", () => { + const initialState = { + actionsLoaded: {}, + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.LOAD_ACTIONS_HISTORY_SUCCESS, + actionsHistory: actions, + }), + ).toEqual({ + actionsLoaded: { + status: ACTION_STATUS.SUCCESS, + actions, + error: "", + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_ACTIONS_HISTORY_ERROR', () => { - const initialState = { - actionsLoaded: {}, - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.LOAD_ACTIONS_HISTORY_ERROR, - error - }) - ).toEqual( - { - actionsLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + }); + + it("handles LOAD_ACTIONS_HISTORY_ERROR", () => { + const initialState = { + actionsLoaded: {}, + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.LOAD_ACTIONS_HISTORY_ERROR, + error, + }), + ).toEqual({ + actionsLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_ACTION_HISTORY_PENDING', () => { - const initialState = { - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.LOAD_ACTION_HISTORY_PENDING - }) - ).toEqual( - { - actionLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); + }); + + it("handles LOAD_ACTION_HISTORY_PENDING", () => { + const initialState = { + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.LOAD_ACTION_HISTORY_PENDING, + }), + ).toEqual({ + actionLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_ACTION_HISTORY_SUCCESS', () => { - const initialState = { - actionLoaded: {}, - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.LOAD_ACTION_HISTORY_SUCCESS, - actionHistory: action - }) - ).toEqual( - { - actionLoaded: { - status: ACTION_STATUS.SUCCESS, - action: action, - error: '' - }, - testEntry: initialState.testEntry - }); + }); + + it("handles LOAD_ACTION_HISTORY_SUCCESS", () => { + const initialState = { + actionLoaded: {}, + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.LOAD_ACTION_HISTORY_SUCCESS, + actionHistory: action, + }), + ).toEqual({ + actionLoaded: { + status: ACTION_STATUS.SUCCESS, + action: action, + error: "", + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_ACTION_HISTORY_ERROR', () => { - const initialState = { - actionLoaded: {}, - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.LOAD_ACTION_HISTORY_ERROR, - error - }) - ).toEqual( - { - actionLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + }); + + it("handles LOAD_ACTION_HISTORY_ERROR", () => { + const initialState = { + actionLoaded: {}, + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.LOAD_ACTION_HISTORY_ERROR, + error, + }), + ).toEqual({ + actionLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); - - it('handles UNLOAD_ACTION_HISTORY', () => { - const initialState = { - actionLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: "should not touch" - }; - - expect( - HistoryReducer(initialState, { - type: ActionConstants.UNLOAD_ACTION_HISTORY - }) - ).toEqual( - { - actionLoaded: {}, - testEntry: initialState.testEntry - }); + }); + + it("handles UNLOAD_ACTION_HISTORY", () => { + const initialState = { + actionLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: "should not touch", + }; + + expect( + HistoryReducer(initialState, { + type: ActionConstants.UNLOAD_ACTION_HISTORY, + }), + ).toEqual({ + actionLoaded: {}, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/InstitutionReducer.spec.js b/tests/__tests__/reducers/InstitutionReducer.spec.js index a2c6c039..5b2d21e4 100644 --- a/tests/__tests__/reducers/InstitutionReducer.spec.js +++ b/tests/__tests__/reducers/InstitutionReducer.spec.js @@ -1,290 +1,278 @@ -import {ACTION_FLAG, ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_FLAG, ACTION_STATUS } from "../../../js/constants/DefaultConstants"; import * as ActionConstants from "../../../js/constants/ActionConstants"; import InstitutionReducer from "../../../js/reducers/InstitutionReducer"; -describe('InstitutionReducer', function () { - const institution = { - name: 'test' - }, - key = 97972969812, - error = { - message: 'An error has occurred.' - }; +describe("InstitutionReducer", function () { + const institution = { + name: "test", + }, + key = 97972969812, + error = { + message: "An error has occurred.", + }; - it('leaves state unchanged if action not recognized', () => { - const initialState = { - institutionDeleted: {}, - testEntry: "should not touch" - }; + it("leaves state unchanged if action not recognized", () => { + const initialState = { + institutionDeleted: {}, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: 'NONEXISTENT_ACTION_TYPE', - payload: 'error' - }) - ).toEqual( - { - institutionDeleted: {}, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: "NONEXISTENT_ACTION_TYPE", + payload: "error", + }), + ).toEqual({ + institutionDeleted: {}, + testEntry: initialState.testEntry, }); + }); - it('handles SAVE_INSTITUTION_PENDING', () => { - const initialState = { - institutionSaved: {}, - testEntry: "should not touch" - }; + it("handles SAVE_INSTITUTION_PENDING", () => { + const initialState = { + institutionSaved: {}, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.SAVE_INSTITUTION_PENDING - }) - ).toEqual( - { - institutionSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.SAVE_INSTITUTION_PENDING, + }), + ).toEqual({ + institutionSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); + }); - it('handles SAVE_INSTITUTION_SUCCESS', () => { - const initialState = { - institutionSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles SAVE_INSTITUTION_SUCCESS", () => { + const initialState = { + institutionSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.SAVE_INSTITUTION_SUCCESS, - actionFlag: ACTION_FLAG.CREATE_ENTITY, - key, - institution - }) - ).toEqual( - { - institutionSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.SUCCESS, - institution: { - ...institution, - key - }, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.SAVE_INSTITUTION_SUCCESS, + actionFlag: ACTION_FLAG.CREATE_ENTITY, + key, + institution, + }), + ).toEqual({ + institutionSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.SUCCESS, + institution: { + ...institution, + key, + }, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles SAVE_INSTITUTION_ERROR', () => { - const initialState = { - institutionSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles SAVE_INSTITUTION_ERROR", () => { + const initialState = { + institutionSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.SAVE_INSTITUTION_ERROR, - actionFlag: ACTION_FLAG.CREATE_ENTITY, - institution, - error - }) - ).toEqual( - { - institutionSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.ERROR, - institution, - error - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.SAVE_INSTITUTION_ERROR, + actionFlag: ACTION_FLAG.CREATE_ENTITY, + institution, + error, + }), + ).toEqual({ + institutionSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.ERROR, + institution, + error, + }, + testEntry: initialState.testEntry, }); + }); - it('handles UNLOAD_SAVED_INSTITUTION', () => { - const initialState = { - institutionSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.SUCCESS, - institution, - error: '' - }, - testEntry: "should not touch" - }; + it("handles UNLOAD_SAVED_INSTITUTION", () => { + const initialState = { + institutionSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.SUCCESS, + institution, + error: "", + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.UNLOAD_SAVED_INSTITUTION - }) - ).toEqual( - { - institutionSaved: { - status: ACTION_STATUS.SUCCESS - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.UNLOAD_SAVED_INSTITUTION, + }), + ).toEqual({ + institutionSaved: { + status: ACTION_STATUS.SUCCESS, + }, + testEntry: initialState.testEntry, }); + }); - it('handles DELETE_INSTITUTION_PENDING', () => { - const initialState = { - institutionDeleted: {}, - testEntry: "should not touch" - }; + it("handles DELETE_INSTITUTION_PENDING", () => { + const initialState = { + institutionDeleted: {}, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.DELETE_INSTITUTION_PENDING, - key - }) - ).toEqual( - { - institutionDeleted: { - status: ACTION_STATUS.PENDING, - key - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.DELETE_INSTITUTION_PENDING, + key, + }), + ).toEqual({ + institutionDeleted: { + status: ACTION_STATUS.PENDING, + key, + }, + testEntry: initialState.testEntry, }); + }); - it('handles DELETE_INSTITUTION_SUCCESS', () => { - const initialState = { - institutionDeleted: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles DELETE_INSTITUTION_SUCCESS", () => { + const initialState = { + institutionDeleted: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.DELETE_INSTITUTION_SUCCESS, - institution - }) - ).toEqual( - { - institutionDeleted: { - status: ACTION_STATUS.SUCCESS, - institution, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.DELETE_INSTITUTION_SUCCESS, + institution, + }), + ).toEqual({ + institutionDeleted: { + status: ACTION_STATUS.SUCCESS, + institution, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles DELETE_INSTITUTION_ERROR', () => { - const initialState = { - institutionDeleted: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles DELETE_INSTITUTION_ERROR", () => { + const initialState = { + institutionDeleted: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.DELETE_INSTITUTION_ERROR, - institution, - error - }) - ).toEqual( - { - institutionDeleted: { - status: ACTION_STATUS.ERROR, - institution, - error - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.DELETE_INSTITUTION_ERROR, + institution, + error, + }), + ).toEqual({ + institutionDeleted: { + status: ACTION_STATUS.ERROR, + institution, + error, + }, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_INSTITUTION_PENDING', () => { - const initialState = { - institutionLoaded: { - testEntry: "should not touch" - }, - testEntry2: "should not touch" - }; + it("handles LOAD_INSTITUTION_PENDING", () => { + const initialState = { + institutionLoaded: { + testEntry: "should not touch", + }, + testEntry2: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTION_PENDING - }) - ).toEqual( - { - institutionLoaded: { - testEntry: initialState.institutionLoaded.testEntry, - status: ACTION_STATUS.PENDING, - }, - testEntry2: initialState.testEntry2 - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTION_PENDING, + }), + ).toEqual({ + institutionLoaded: { + testEntry: initialState.institutionLoaded.testEntry, + status: ACTION_STATUS.PENDING, + }, + testEntry2: initialState.testEntry2, }); + }); - it('handles LOAD_INSTITUTION_SUCCESS', () => { - const initialState = { - institutionLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_INSTITUTION_SUCCESS", () => { + const initialState = { + institutionLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTION_SUCCESS, - institution - }) - ).toEqual( - { - institutionLoaded: { - status: ACTION_STATUS.SUCCESS, - institution, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTION_SUCCESS, + institution, + }), + ).toEqual({ + institutionLoaded: { + status: ACTION_STATUS.SUCCESS, + institution, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_INSTITUTION_ERROR', () => { - const initialState = { - institutionLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_INSTITUTION_ERROR", () => { + const initialState = { + institutionLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTION_ERROR, - error - }) - ).toEqual( - { - institutionLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTION_ERROR, + error, + }), + ).toEqual({ + institutionLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); + }); - it('handles UNLOAD_INSTITUTION', () => { - const initialState = { - institutionLoaded: { - status: ACTION_STATUS.SUCCESS, - institution - }, - testEntry: "should not touch" - }; + it("handles UNLOAD_INSTITUTION", () => { + const initialState = { + institutionLoaded: { + status: ACTION_STATUS.SUCCESS, + institution, + }, + testEntry: "should not touch", + }; - expect( - InstitutionReducer(initialState, { - type: ActionConstants.UNLOAD_INSTITUTION - }) - ).toEqual( - { - institutionLoaded: {}, - testEntry: initialState.testEntry - }); + expect( + InstitutionReducer(initialState, { + type: ActionConstants.UNLOAD_INSTITUTION, + }), + ).toEqual({ + institutionLoaded: {}, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/InstitutionsReducer.spec.js b/tests/__tests__/reducers/InstitutionsReducer.spec.js index 64c7779b..d631e776 100644 --- a/tests/__tests__/reducers/InstitutionsReducer.spec.js +++ b/tests/__tests__/reducers/InstitutionsReducer.spec.js @@ -1,79 +1,76 @@ -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; import * as ActionConstants from "../../../js/constants/ActionConstants"; import InstitutionsReducer from "../../../js/reducers/InstitutionsReducer"; -describe('InstitutionsReducer', function () { - const institutions = [{key: 'test1'}, {key: 'test2'}], - error = { - message: 'An error has occurred.' - }; +describe("InstitutionsReducer", function () { + const institutions = [{ key: "test1" }, { key: "test2" }], + error = { + message: "An error has occurred.", + }; - it('handles LOAD_INSTITUTIONS_PENDING', () => { - const initialState = { - institutionsLoaded: { - testEntry1: "should not touch" - }, - testEntry2: "should not touch" - }; + it("handles LOAD_INSTITUTIONS_PENDING", () => { + const initialState = { + institutionsLoaded: { + testEntry1: "should not touch", + }, + testEntry2: "should not touch", + }; - expect( - InstitutionsReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTIONS_PENDING, - }) - ).toEqual( - { - institutionsLoaded: { - status: ACTION_STATUS.PENDING, - testEntry1: "should not touch" - }, - testEntry2: "should not touch" - }); + expect( + InstitutionsReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTIONS_PENDING, + }), + ).toEqual({ + institutionsLoaded: { + status: ACTION_STATUS.PENDING, + testEntry1: "should not touch", + }, + testEntry2: "should not touch", }); + }); - it('handles LOAD_INSTITUTIONS_SUCCESS', () => { - const initialState = { - institutionsLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_INSTITUTIONS_SUCCESS", () => { + const initialState = { + institutionsLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionsReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, - institutions - }) - ).toEqual( - { - institutionsLoaded: { - status: ACTION_STATUS.SUCCESS, - institutions, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionsReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTIONS_SUCCESS, + institutions, + }), + ).toEqual({ + institutionsLoaded: { + status: ACTION_STATUS.SUCCESS, + institutions, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_INSTITUTIONS_ERROR', () => { - const initialState = { - institutionsLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_INSTITUTIONS_ERROR", () => { + const initialState = { + institutionsLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - InstitutionsReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTIONS_ERROR, - error - }) - ).toEqual( - { - institutionsLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + expect( + InstitutionsReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTIONS_ERROR, + error, + }), + ).toEqual({ + institutionsLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/RecordReducer.spec.js b/tests/__tests__/reducers/RecordReducer.spec.js index 8dc2dc2f..4ccb6bf1 100644 --- a/tests/__tests__/reducers/RecordReducer.spec.js +++ b/tests/__tests__/reducers/RecordReducer.spec.js @@ -1,296 +1,284 @@ import RecordReducer from "../../../js/reducers/RecordReducer"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {ACTION_FLAG, ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_FLAG, ACTION_STATUS } from "../../../js/constants/DefaultConstants"; -describe('RecordReducer', function () { - const record = {key: 12345678}, - key = 12345678, - error = { - message: 'An error has occurred.' - }; +describe("RecordReducer", function () { + const record = { key: 12345678 }, + key = 12345678, + error = { + message: "An error has occurred.", + }; - it('leaves state unchanged if action not recognized', () => { - const initialState = { - recordDeleted: {}, - testEntry: "should not touch" - }; + it("leaves state unchanged if action not recognized", () => { + const initialState = { + recordDeleted: {}, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: 'NONEXISTENT_ACTION_TYPE', - payload: 'error' - }) - ).toEqual( - { - recordDeleted: {}, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: "NONEXISTENT_ACTION_TYPE", + payload: "error", + }), + ).toEqual({ + recordDeleted: {}, + testEntry: initialState.testEntry, }); + }); - it('handles SAVE_RECORD_PENDING', () => { - const initialState = { - recordSaved: {}, - testEntry: "should not touch" - }; + it("handles SAVE_RECORD_PENDING", () => { + const initialState = { + recordSaved: {}, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.SAVE_RECORD_PENDING - }) - ).toEqual( - { - recordSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.SAVE_RECORD_PENDING, + }), + ).toEqual({ + recordSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); + }); - it('handles SAVE_RECORD_SUCCESS', () => { - const initialState = { - recordSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles SAVE_RECORD_SUCCESS", () => { + const initialState = { + recordSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.SAVE_RECORD_SUCCESS, - actionFlag: ACTION_FLAG.CREATE_ENTITY, - key, - record - }) - ).toEqual( - { - recordSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.SUCCESS, - record: { - ...record, - key - }, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.SAVE_RECORD_SUCCESS, + actionFlag: ACTION_FLAG.CREATE_ENTITY, + key, + record, + }), + ).toEqual({ + recordSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.SUCCESS, + record: { + ...record, + key, + }, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles SAVE_RECORD_ERROR', () => { - const initialState = { - recordSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles SAVE_RECORD_ERROR", () => { + const initialState = { + recordSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.SAVE_RECORD_ERROR, - actionFlag: ACTION_FLAG.CREATE_ENTITY, - record, - error - }) - ).toEqual( - { - recordSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.ERROR, - record, - error - }, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.SAVE_RECORD_ERROR, + actionFlag: ACTION_FLAG.CREATE_ENTITY, + record, + error, + }), + ).toEqual({ + recordSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.ERROR, + record, + error, + }, + testEntry: initialState.testEntry, }); + }); - it('handles UNLOAD_SAVED_RECORD', () => { - const initialState = { - recordSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.SUCCESS, - record, - error: '' - }, - testEntry: "should not touch" - }; + it("handles UNLOAD_SAVED_RECORD", () => { + const initialState = { + recordSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.SUCCESS, + record, + error: "", + }, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.UNLOAD_SAVED_RECORD - }) - ).toEqual( - { - recordSaved: { - status: ACTION_STATUS.SUCCESS - }, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.UNLOAD_SAVED_RECORD, + }), + ).toEqual({ + recordSaved: { + status: ACTION_STATUS.SUCCESS, + }, + testEntry: initialState.testEntry, }); + }); - it('handles DELETE_RECORD_PENDING', () => { - const initialState = { - recordDeleted: {}, - recordsDeleting: [], - testEntry: "should not touch" - }; + it("handles DELETE_RECORD_PENDING", () => { + const initialState = { + recordDeleted: {}, + recordsDeleting: [], + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.DELETE_RECORD_PENDING, - key - }) - ).toEqual( - { - recordDeleted: { - status: ACTION_STATUS.PENDING, - key - }, - recordsDeleting: [key], - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.DELETE_RECORD_PENDING, + key, + }), + ).toEqual({ + recordDeleted: { + status: ACTION_STATUS.PENDING, + key, + }, + recordsDeleting: [key], + testEntry: initialState.testEntry, }); + }); - it('handles DELETE_RECORD_SUCCESS', () => { - const initialState = { - recordDeleted: { - status: ACTION_STATUS.PENDING - }, - recordsDeleting: [], - testEntry: "should not touch" - }; + it("handles DELETE_RECORD_SUCCESS", () => { + const initialState = { + recordDeleted: { + status: ACTION_STATUS.PENDING, + }, + recordsDeleting: [], + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.DELETE_RECORD_SUCCESS, - record, - key - }) - ).toEqual( - { - recordDeleted: { - status: ACTION_STATUS.SUCCESS, - record, - error: '' - }, - recordsDeleting: [], - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.DELETE_RECORD_SUCCESS, + record, + key, + }), + ).toEqual({ + recordDeleted: { + status: ACTION_STATUS.SUCCESS, + record, + error: "", + }, + recordsDeleting: [], + testEntry: initialState.testEntry, }); + }); - it('handles DELETE_RECORD_ERROR', () => { - const initialState = { - recordDeleted: { - status: ACTION_STATUS.PENDING - }, - recordsDeleting: [], - testEntry: "should not touch" - }; + it("handles DELETE_RECORD_ERROR", () => { + const initialState = { + recordDeleted: { + status: ACTION_STATUS.PENDING, + }, + recordsDeleting: [], + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.DELETE_RECORD_ERROR, - record, - error, - key - }) - ).toEqual( - { - recordDeleted: { - status: ACTION_STATUS.ERROR, - record, - error - }, - recordsDeleting: [], - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.DELETE_RECORD_ERROR, + record, + error, + key, + }), + ).toEqual({ + recordDeleted: { + status: ACTION_STATUS.ERROR, + record, + error, + }, + recordsDeleting: [], + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_RECORD_PENDING', () => { - const initialState = { - recordLoaded: { - testEntry: "should not touch" - }, - testEntry2: "should not touch" - }; + it("handles LOAD_RECORD_PENDING", () => { + const initialState = { + recordLoaded: { + testEntry: "should not touch", + }, + testEntry2: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.LOAD_RECORD_PENDING - }) - ).toEqual( - { - recordLoaded: { - testEntry: initialState.recordLoaded.testEntry, - status: ACTION_STATUS.PENDING, - }, - testEntry2: initialState.testEntry2 - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.LOAD_RECORD_PENDING, + }), + ).toEqual({ + recordLoaded: { + testEntry: initialState.recordLoaded.testEntry, + status: ACTION_STATUS.PENDING, + }, + testEntry2: initialState.testEntry2, }); + }); - it('handles LOAD_RECORD_SUCCESS', () => { - const initialState = { - recordLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_RECORD_SUCCESS", () => { + const initialState = { + recordLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.LOAD_RECORD_SUCCESS, - record - }) - ).toEqual( - { - recordLoaded: { - status: ACTION_STATUS.SUCCESS, - record, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.LOAD_RECORD_SUCCESS, + record, + }), + ).toEqual({ + recordLoaded: { + status: ACTION_STATUS.SUCCESS, + record, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_RECORD_ERROR', () => { - const initialState = { - recordLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_RECORD_ERROR", () => { + const initialState = { + recordLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.LOAD_RECORD_ERROR, - error - }) - ).toEqual( - { - recordLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.LOAD_RECORD_ERROR, + error, + }), + ).toEqual({ + recordLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); + }); - it('handles UNLOAD_RECORD', () => { - const initialState = { - recordLoaded: { - status: ACTION_STATUS.SUCCESS, - record - }, - testEntry: "should not touch" - }; + it("handles UNLOAD_RECORD", () => { + const initialState = { + recordLoaded: { + status: ACTION_STATUS.SUCCESS, + record, + }, + testEntry: "should not touch", + }; - expect( - RecordReducer(initialState, { - type: ActionConstants.UNLOAD_RECORD - }) - ).toEqual( - { - recordLoaded: {}, - testEntry: initialState.testEntry - }); + expect( + RecordReducer(initialState, { + type: ActionConstants.UNLOAD_RECORD, + }), + ).toEqual({ + recordLoaded: {}, + testEntry: initialState.testEntry, }); + }); }); diff --git a/tests/__tests__/reducers/RecordsReducer.spec.js b/tests/__tests__/reducers/RecordsReducer.spec.js index 8f8ef917..c9868ba7 100644 --- a/tests/__tests__/reducers/RecordsReducer.spec.js +++ b/tests/__tests__/reducers/RecordsReducer.spec.js @@ -1,79 +1,76 @@ -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; import * as ActionConstants from "../../../js/constants/ActionConstants"; import RecordsReducer from "../../../js/reducers/RecordsReducer"; -describe('RecordsReducer', function () { - const records = [{key: 12345678}, {key: 23456789}], - error = { - message: 'An error has occurred.' - }; +describe("RecordsReducer", function () { + const records = [{ key: 12345678 }, { key: 23456789 }], + error = { + message: "An error has occurred.", + }; - it('handles LOAD_RECORDS_PENDING', () => { - const initialState = { - recordsLoaded: { - testEntry1: "should not touch" - }, - testEntry2: "should not touch" - }; + it("handles LOAD_RECORDS_PENDING", () => { + const initialState = { + recordsLoaded: { + testEntry1: "should not touch", + }, + testEntry2: "should not touch", + }; - expect( - RecordsReducer(initialState, { - type: ActionConstants.LOAD_RECORDS_PENDING, - }) - ).toEqual( - { - recordsLoaded: { - status: ACTION_STATUS.PENDING, - testEntry1: "should not touch" - }, - testEntry2: "should not touch" - }); + expect( + RecordsReducer(initialState, { + type: ActionConstants.LOAD_RECORDS_PENDING, + }), + ).toEqual({ + recordsLoaded: { + status: ACTION_STATUS.PENDING, + testEntry1: "should not touch", + }, + testEntry2: "should not touch", }); + }); - it('handles LOAD_RECORDS_SUCCESS', () => { - const initialState = { - recordsLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_RECORDS_SUCCESS", () => { + const initialState = { + recordsLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - RecordsReducer(initialState, { - type: ActionConstants.LOAD_RECORDS_SUCCESS, - records - }) - ).toEqual( - { - recordsLoaded: { - status: ACTION_STATUS.SUCCESS, - records, - error: '' - }, - testEntry: initialState.testEntry - }); + expect( + RecordsReducer(initialState, { + type: ActionConstants.LOAD_RECORDS_SUCCESS, + records, + }), + ).toEqual({ + recordsLoaded: { + status: ACTION_STATUS.SUCCESS, + records, + error: "", + }, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_RECORDS_ERROR', () => { - const initialState = { - recordsLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; + it("handles LOAD_RECORDS_ERROR", () => { + const initialState = { + recordsLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; - expect( - RecordsReducer(initialState, { - type: ActionConstants.LOAD_RECORDS_ERROR, - error - }) - ).toEqual( - { - recordsLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + expect( + RecordsReducer(initialState, { + type: ActionConstants.LOAD_RECORDS_ERROR, + error, + }), + ).toEqual({ + recordsLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/RouterReducer.spec.js b/tests/__tests__/reducers/RouterReducer.spec.js index eb1f769f..3b833f1b 100644 --- a/tests/__tests__/reducers/RouterReducer.spec.js +++ b/tests/__tests__/reducers/RouterReducer.spec.js @@ -1,74 +1,71 @@ import * as ActionConstants from "../../../js/constants/ActionConstants"; import RouterReducer from "../../../js/reducers/RouterReducer"; -describe('RouterReducer', function () { - const routeName = "user", - payload = {data: 123456}, - handlers = {onEvent: jest.fn()}; +describe("RouterReducer", function () { + const routeName = "user", + payload = { data: 123456 }, + handlers = { onEvent: jest.fn() }; - it('leaves state unchanged if action not recognized', () => { - const initialState = { - transitionPayload: {}, - viewHandlers: {}, - testEntry: "should not touch" - }; + it("leaves state unchanged if action not recognized", () => { + const initialState = { + transitionPayload: {}, + viewHandlers: {}, + testEntry: "should not touch", + }; - expect( - RouterReducer(initialState, { - type: 'NONEXISTENT_ACTION_TYPE', - payload: 'error' - }) - ).toEqual( - { - transitionPayload: {}, - viewHandlers: {}, - testEntry: initialState.testEntry - }); + expect( + RouterReducer(initialState, { + type: "NONEXISTENT_ACTION_TYPE", + payload: "error", + }), + ).toEqual({ + transitionPayload: {}, + viewHandlers: {}, + testEntry: initialState.testEntry, }); + }); - it('handles action SET_TRANSITION_PAYLOAD', () => { - const initialState = { - transitionPayload: {}, - viewHandlers: {}, - testEntry: "should not touch" - }; + it("handles action SET_TRANSITION_PAYLOAD", () => { + const initialState = { + transitionPayload: {}, + viewHandlers: {}, + testEntry: "should not touch", + }; - expect( - RouterReducer(initialState, { - type: ActionConstants.SET_TRANSITION_PAYLOAD, - routeName, - payload - }) - ).toEqual( - { - transitionPayload: { - [routeName]: payload - }, - viewHandlers: {}, - testEntry: initialState.testEntry - }); + expect( + RouterReducer(initialState, { + type: ActionConstants.SET_TRANSITION_PAYLOAD, + routeName, + payload, + }), + ).toEqual({ + transitionPayload: { + [routeName]: payload, + }, + viewHandlers: {}, + testEntry: initialState.testEntry, }); + }); - it('handles action SET_VIEW_HANDLERS', () => { - const initialState = { - transitionPayload: {}, - viewHandlers: {}, - testEntry: "should not touch" - }; + it("handles action SET_VIEW_HANDLERS", () => { + const initialState = { + transitionPayload: {}, + viewHandlers: {}, + testEntry: "should not touch", + }; - expect( - RouterReducer(initialState, { - type: ActionConstants.SET_VIEW_HANDLERS, - routeName, - handlers - }) - ).toEqual( - { - transitionPayload: {}, - viewHandlers: { - [routeName]: handlers - }, - testEntry: initialState.testEntry - }); + expect( + RouterReducer(initialState, { + type: ActionConstants.SET_VIEW_HANDLERS, + routeName, + handlers, + }), + ).toEqual({ + transitionPayload: {}, + viewHandlers: { + [routeName]: handlers, + }, + testEntry: initialState.testEntry, }); + }); }); diff --git a/tests/__tests__/reducers/StatisticsReducer.spec.js b/tests/__tests__/reducers/StatisticsReducer.spec.js index 8c1997c0..64aceef9 100644 --- a/tests/__tests__/reducers/StatisticsReducer.spec.js +++ b/tests/__tests__/reducers/StatisticsReducer.spec.js @@ -1,81 +1,77 @@ import StatisticsReducer from "../../../js/reducers/StatisticsReducer"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; -describe('StatisticsReducer', function () { - const error = { - message: 'An error has occurred.' - }; +describe("StatisticsReducer", function () { + const error = { + message: "An error has occurred.", + }; - it('leaves state unchanged if action not recognized', () => { - const initialState = { - testEntry: "should not touch" - }; + it("leaves state unchanged if action not recognized", () => { + const initialState = { + testEntry: "should not touch", + }; - expect( - StatisticsReducer(initialState, { - type: 'NONEXISTENT_ACTION_TYPE', - payload: 'error' - }) - ).toEqual( - { - testEntry: initialState.testEntry - }); + expect( + StatisticsReducer(initialState, { + type: "NONEXISTENT_ACTION_TYPE", + payload: "error", + }), + ).toEqual({ + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_STATISTICS_PENDING', () => { - const initialState = { - testEntry: "should not touch" - }; + it("handles LOAD_STATISTICS_PENDING", () => { + const initialState = { + testEntry: "should not touch", + }; - expect( - StatisticsReducer(initialState, { - type: ActionConstants.LOAD_STATISTICS_PENDING - }) - ).toEqual( - { - status: ACTION_STATUS.PENDING, - error: undefined, - testEntry: initialState.testEntry - }); + expect( + StatisticsReducer(initialState, { + type: ActionConstants.LOAD_STATISTICS_PENDING, + }), + ).toEqual({ + status: ACTION_STATUS.PENDING, + error: undefined, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_STATISTICS_SUCCESS', () => { - const initialState = { - status: ACTION_STATUS.PENDING, - testEntry: "should not touch" - }; + it("handles LOAD_STATISTICS_SUCCESS", () => { + const initialState = { + status: ACTION_STATUS.PENDING, + testEntry: "should not touch", + }; - expect( - StatisticsReducer(initialState, { - type: ActionConstants.LOAD_STATISTICS_SUCCESS, - payload: {} - }) - ).toEqual( - { - status: ACTION_STATUS.SUCCESS, - error: undefined, - data: {}, - testEntry: initialState.testEntry - }); + expect( + StatisticsReducer(initialState, { + type: ActionConstants.LOAD_STATISTICS_SUCCESS, + payload: {}, + }), + ).toEqual({ + status: ACTION_STATUS.SUCCESS, + error: undefined, + data: {}, + testEntry: initialState.testEntry, }); + }); - it('handles LOAD_STATISTICS_ERROR', () => { - const initialState = { - status: ACTION_STATUS.PENDING, - testEntry: "should not touch" - }; + it("handles LOAD_STATISTICS_ERROR", () => { + const initialState = { + status: ACTION_STATUS.PENDING, + testEntry: "should not touch", + }; - expect( - StatisticsReducer(initialState, { - type: ActionConstants.LOAD_STATISTICS_ERROR, - error - }) - ).toEqual( - { - status: ACTION_STATUS.ERROR, - error, - testEntry: initialState.testEntry - }); + expect( + StatisticsReducer(initialState, { + type: ActionConstants.LOAD_STATISTICS_ERROR, + error, + }), + ).toEqual({ + status: ACTION_STATUS.ERROR, + error, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/UserReducer.spec.js b/tests/__tests__/reducers/UserReducer.spec.js index 67a4c7dc..ce9df9ae 100644 --- a/tests/__tests__/reducers/UserReducer.spec.js +++ b/tests/__tests__/reducers/UserReducer.spec.js @@ -1,678 +1,655 @@ -'use strict'; +"use strict"; -import React from 'react'; +import React from "react"; import UserReducer from "../../../js/reducers/UserReducer"; import * as ActionConstants from "../../../js/constants/ActionConstants"; -import {ACTION_FLAG, ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_FLAG, ACTION_STATUS } from "../../../js/constants/DefaultConstants"; import InstitutionReducer from "../../../js/reducers/InstitutionReducer"; -describe('UserReducer', function () { - const user = {username: 'test'}, - username = user.username, - members = [ - {username: 'record1'}, - {username: 'record2'} - ], - error = { - message: 'An error has occurred.' - }; - - it('leaves state unchanged if action not recognized', () => { - const initialState = { - testEntry: 'should not touch' - }; - const action = {type: 'NONEXISTENT_ACTION_TYPE', payload: 'error'}; - - const newState = UserReducer(initialState, action); - - const expectedState = { - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); +describe("UserReducer", function () { + const user = { username: "test" }, + username = user.username, + members = [{ username: "record1" }, { username: "record2" }], + error = { + message: "An error has occurred.", + }; + + it("leaves state unchanged if action not recognized", () => { + const initialState = { + testEntry: "should not touch", + }; + const action = { type: "NONEXISTENT_ACTION_TYPE", payload: "error" }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles SAVE_USER_PENDING", () => { + const initialState = { + userSaved: {}, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.SAVE_USER_PENDING, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles SAVE_USER_SUCCESS", () => { + const initialState = { + userSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.SAVE_USER_SUCCESS, + actionFlag: ACTION_FLAG.CREATE_ENTITY, + user, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.SUCCESS, + user, + error: "", + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles SAVE_USER_ERROR", () => { + const initialState = { + userSaved: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.SAVE_USER_ERROR, + actionFlag: ACTION_FLAG.CREATE_ENTITY, + user, + error, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.ERROR, + user, + error, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles UNLOAD_SAVED_USER", () => { + const initialState = { + userSaved: { + actionFlag: ACTION_FLAG.CREATE_ENTITY, + status: ACTION_STATUS.SUCCESS, + user, + error: "", + }, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.UNLOAD_SAVED_USER, + }), + ).toEqual({ + userSaved: { + status: ACTION_STATUS.SUCCESS, + }, + testEntry: initialState.testEntry, }); - - it('handles SAVE_USER_PENDING', () => { - const initialState = { - userSaved: {}, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.SAVE_USER_PENDING, - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles DELETE_USER_PENDING", () => { + const initialState = { + userDeleted: {}, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.DELETE_USER_PENDING, + username: user.username, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userDeleted: { + status: ACTION_STATUS.PENDING, + username: user.username, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles DELETE_USER_SUCCESS", () => { + const initialState = { + userDeleted: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.DELETE_USER_SUCCESS, + user, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userDeleted: { + status: ACTION_STATUS.SUCCESS, + user, + error: "", + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles DELETE_USER_ERROR", () => { + const initialState = { + userDeleted: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.DELETE_USER_ERROR, + user, + error, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userDeleted: { + status: ACTION_STATUS.ERROR, + user, + error, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_USER_PENDING", () => { + const initialState = { + userLoaded: { + testEntry: "should not touch", + }, + testEntry2: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USER_PENDING, + username: user.username, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userLoaded: { + testEntry: initialState.userLoaded.testEntry, + status: ACTION_STATUS.PENDING, + }, + testEntry2: initialState.testEntry2, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_USER_SUCCESS", () => { + const initialState = { + userLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USER_SUCCESS, + user, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userLoaded: { + status: ACTION_STATUS.SUCCESS, + user, + error: "", + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_USER_ERROR", () => { + const initialState = { + userLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USER_ERROR, + error, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles UNLOAD_USER", () => { + const initialState = { + userLoaded: { + status: ACTION_STATUS.SUCCESS, + user, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.UNLOAD_USER, + }; + + const newState = UserReducer(initialState, action); + + const expectedState = { + userLoaded: {}, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_INSTITUTION_MEMBERS_PENDING action", () => { + const initialState = { + institutionMembers: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING, + }), + ).toEqual({ + institutionMembers: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles SAVE_USER_SUCCESS', () => { - const initialState = { - userSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.SAVE_USER_SUCCESS, - actionFlag: ACTION_FLAG.CREATE_ENTITY, - user, - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.SUCCESS, - user, - error: '' - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_INSTITUTION_MEMBERS_SUCCESS action", () => { + const initialState = { + institutionMembers: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, + members, + }), + ).toEqual({ + institutionMembers: { + status: ACTION_STATUS.SUCCESS, + members, + error: "", + }, + testEntry: initialState.testEntry, }); - - it('handles SAVE_USER_ERROR', () => { - const initialState = { - userSaved: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.SAVE_USER_ERROR, - actionFlag: ACTION_FLAG.CREATE_ENTITY, - user, - error - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.ERROR, - user, - error - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles LOAD_INSTITUTION_MEMBERS_ERROR action", () => { + const initialState = { + institutionMembers: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, + error, + }), + ).toEqual({ + institutionMembers: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); - - it('handles UNLOAD_SAVED_USER', () => { - const initialState = { - userSaved: { - actionFlag: ACTION_FLAG.CREATE_ENTITY, - status: ACTION_STATUS.SUCCESS, - user, - error: '' - }, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.UNLOAD_SAVED_USER - }) - ).toEqual( - { - userSaved: { - status: ACTION_STATUS.SUCCESS - }, - testEntry: initialState.testEntry - }); + }); + + it("handles UNLOAD_INSTITUTION_MEMBERS action", () => { + const initialState = { + institutionMembers: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.UNLOAD_INSTITUTION_MEMBERS, + }), + ).toEqual({ + institutionMembers: {}, + testEntry: initialState.testEntry, }); - - it('handles DELETE_USER_PENDING', () => { - const initialState = { - userDeleted: {}, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.DELETE_USER_PENDING, - username: user.username - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userDeleted: { - status: ACTION_STATUS.PENDING, - username: user.username - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles PASSWORD_CHANGE_PENDING action", () => { + const initialState = { + passwordChange: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.PASSWORD_CHANGE_PENDING, + }), + ).toEqual({ + passwordChange: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles DELETE_USER_SUCCESS', () => { - const initialState = { - userDeleted: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.DELETE_USER_SUCCESS, - user - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userDeleted: { - status: ACTION_STATUS.SUCCESS, - user, - error: '' - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles PASSWORD_CHANGE_SUCCESS action", () => { + const initialState = { + passwordChange: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.PASSWORD_CHANGE_SUCCESS, + }), + ).toEqual({ + passwordChange: { + status: ACTION_STATUS.SUCCESS, + error: "", + }, + testEntry: initialState.testEntry, }); - - it('handles DELETE_USER_ERROR', () => { - const initialState = { - userDeleted: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.DELETE_USER_ERROR, - user, - error - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userDeleted: { - status: ACTION_STATUS.ERROR, - user, - error - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles PASSWORD_CHANGE_ERROR action", () => { + const initialState = { + passwordChange: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.PASSWORD_CHANGE_ERROR, + error, + }), + ).toEqual({ + passwordChange: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_USER_PENDING', () => { - const initialState = { - userLoaded: { - testEntry: "should not touch" - }, - testEntry2: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USER_PENDING, - username: user.username - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userLoaded: { - testEntry: initialState.userLoaded.testEntry, - status: ACTION_STATUS.PENDING, - }, - testEntry2: initialState.testEntry2 - }; - expect(newState).toEqual(expectedState); + }); + + it("handles GENERATE_USERNAME_PENDING action", () => { + const initialState = { + generatedUsername: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.GENERATE_USERNAME_PENDING, + }), + ).toEqual({ + generatedUsername: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_USER_SUCCESS', () => { - const initialState = { - userLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USER_SUCCESS, - user - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userLoaded: { - status: ACTION_STATUS.SUCCESS, - user, - error: '' - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles GENERATE_USERNAME_SUCCESS action", () => { + const initialState = { + generatedUsername: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.GENERATE_USERNAME_SUCCESS, + generatedUsername: username, + }), + ).toEqual({ + generatedUsername: { + status: ACTION_STATUS.SUCCESS, + username, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_USER_ERROR', () => { - const initialState = { - userLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USER_ERROR, - error - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles SEND_INVITATION_PENDING action", () => { + const initialState = { + invitationSent: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.SEND_INVITATION_PENDING, + username, + }), + ).toEqual({ + invitationSent: { + status: ACTION_STATUS.PENDING, + username, + }, + testEntry: initialState.testEntry, }); - - it('handles UNLOAD_USER', () => { - const initialState = { - userLoaded: { - status: ACTION_STATUS.SUCCESS, - user - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.UNLOAD_USER, - }; - - const newState = UserReducer(initialState, action); - - const expectedState = { - userLoaded: {}, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); + }); + + it("handles SEND_INVITATION_SUCCESS action", () => { + const initialState = { + invitationSent: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.SEND_INVITATION_SUCCESS, + username, + }), + ).toEqual({ + invitationSent: { + status: ACTION_STATUS.SUCCESS, + username, + error: "", + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_INSTITUTION_MEMBERS_PENDING action', () => { - const initialState = { - institutionMembers: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_PENDING - }) - ).toEqual( - { - institutionMembers: { - status: ACTION_STATUS.PENDING, - }, - testEntry: initialState.testEntry - }); + }); + + it("handles SEND_INVITATION_ERROR action", () => { + const initialState = { + invitationSent: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.SEND_INVITATION_ERROR, + error, + }), + ).toEqual({ + invitationSent: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_INSTITUTION_MEMBERS_SUCCESS action', () => { - const initialState = { - institutionMembers: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_SUCCESS, - members - }) - ).toEqual( - { - institutionMembers: { - status: ACTION_STATUS.SUCCESS, - members, - error: '' - }, - testEntry: initialState.testEntry - }); + }); + + it("handles INVITATION_OPTION_DELETE_PENDING action", () => { + const initialState = { + invitationDelete: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, + username, + }), + ).toEqual({ + invitationDelete: { + status: ACTION_STATUS.PENDING, + username, + }, + testEntry: initialState.testEntry, }); - - it('handles LOAD_INSTITUTION_MEMBERS_ERROR action', () => { - const initialState = { - institutionMembers: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.LOAD_INSTITUTION_MEMBERS_ERROR, - error - }) - ).toEqual( - { - institutionMembers: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); - }); - - it('handles UNLOAD_INSTITUTION_MEMBERS action', () => { - const initialState = { - institutionMembers: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.UNLOAD_INSTITUTION_MEMBERS - }) - ).toEqual( - { - institutionMembers: {}, - testEntry: initialState.testEntry - }); + }); + + it("handles INVITATION_OPTION_DELETE_SUCCESS action", () => { + const initialState = { + invitationDelete: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.INVITATION_OPTION_DELETE_SUCCESS, + username, + }), + ).toEqual({ + invitationDelete: { + status: ACTION_STATUS.SUCCESS, + username, + error: "", + }, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_CHANGE_PENDING action', () => { - const initialState = { - passwordChange: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.PASSWORD_CHANGE_PENDING - }) - ).toEqual( - { - passwordChange: { - status: ACTION_STATUS.PENDING, - }, - testEntry: initialState.testEntry - }); + }); + + it("handles INVITATION_OPTION_DELETE_ERROR action", () => { + const initialState = { + invitationDelete: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.INVITATION_OPTION_DELETE_ERROR, + error, + }), + ).toEqual({ + invitationDelete: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_CHANGE_SUCCESS action', () => { - const initialState = { - passwordChange: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.PASSWORD_CHANGE_SUCCESS - }) - ).toEqual( - { - passwordChange: { - status: ACTION_STATUS.SUCCESS, - error: '' - }, - testEntry: initialState.testEntry - }); + }); + + it("handles IMPERSONATE_PENDING action", () => { + const initialState = { + impersonation: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.IMPERSONATE_PENDING, + }), + ).toEqual({ + impersonation: { + status: ACTION_STATUS.PENDING, + }, + testEntry: initialState.testEntry, }); - - it('handles PASSWORD_CHANGE_ERROR action', () => { - const initialState = { - passwordChange: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.PASSWORD_CHANGE_ERROR, - error - }) - ).toEqual( - { - passwordChange: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + }); + + it("handles IMPERSONATE_SUCCESS action", () => { + const initialState = { + impersonation: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.IMPERSONATE_SUCCESS, + username, + }), + ).toEqual({ + impersonation: { + status: ACTION_STATUS.SUCCESS, + username, + }, + testEntry: initialState.testEntry, }); - - - it('handles GENERATE_USERNAME_PENDING action', () => { - const initialState = { - generatedUsername: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.GENERATE_USERNAME_PENDING - }) - ).toEqual( - { - generatedUsername: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); - }); - - it('handles GENERATE_USERNAME_SUCCESS action', () => { - const initialState = { - generatedUsername: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.GENERATE_USERNAME_SUCCESS, - generatedUsername: username - }) - ).toEqual( - { - generatedUsername: { - status: ACTION_STATUS.SUCCESS, - username - }, - testEntry: initialState.testEntry - }); - }); - - it('handles SEND_INVITATION_PENDING action', () => { - const initialState = { - invitationSent: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.SEND_INVITATION_PENDING, - username - }) - ).toEqual( - { - invitationSent: { - status: ACTION_STATUS.PENDING, - username - }, - testEntry: initialState.testEntry - }); - }); - - it('handles SEND_INVITATION_SUCCESS action', () => { - const initialState = { - invitationSent: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.SEND_INVITATION_SUCCESS, - username - }) - ).toEqual( - { - invitationSent: { - status: ACTION_STATUS.SUCCESS, - username, - error: '' - }, - testEntry: initialState.testEntry - }); - }); - - it('handles SEND_INVITATION_ERROR action', () => { - const initialState = { - invitationSent: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.SEND_INVITATION_ERROR, - error - }) - ).toEqual( - { - invitationSent: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); - }); - - it('handles INVITATION_OPTION_DELETE_PENDING action', () => { - const initialState = { - invitationDelete: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.INVITATION_OPTION_DELETE_PENDING, - username - }) - ).toEqual( - { - invitationDelete: { - status: ACTION_STATUS.PENDING, - username - }, - testEntry: initialState.testEntry - }); - }); - - it('handles INVITATION_OPTION_DELETE_SUCCESS action', () => { - const initialState = { - invitationDelete: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.INVITATION_OPTION_DELETE_SUCCESS, - username - }) - ).toEqual( - { - invitationDelete: { - status: ACTION_STATUS.SUCCESS, - username, - error: '' - }, - testEntry: initialState.testEntry - }); - }); - - it('handles INVITATION_OPTION_DELETE_ERROR action', () => { - const initialState = { - invitationDelete: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.INVITATION_OPTION_DELETE_ERROR, - error - }) - ).toEqual( - { - invitationDelete: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); - }); - - it('handles IMPERSONATE_PENDING action', () => { - const initialState = { - impersonation: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.IMPERSONATE_PENDING - }) - ).toEqual( - { - impersonation: { - status: ACTION_STATUS.PENDING - }, - testEntry: initialState.testEntry - }); - }); - - it('handles IMPERSONATE_SUCCESS action', () => { - const initialState = { - impersonation: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.IMPERSONATE_SUCCESS, - username - }) - ).toEqual( - { - impersonation: { - status: ACTION_STATUS.SUCCESS, - username, - }, - testEntry: initialState.testEntry - }); - }); - - it('handles IMPERSONATE_ERROR action', () => { - const initialState = { - impersonation: {}, - testEntry: "should not touch" - }; - - expect( - UserReducer(initialState, { - type: ActionConstants.IMPERSONATE_ERROR, - error - }) - ).toEqual( - { - impersonation: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }); + }); + + it("handles IMPERSONATE_ERROR action", () => { + const initialState = { + impersonation: {}, + testEntry: "should not touch", + }; + + expect( + UserReducer(initialState, { + type: ActionConstants.IMPERSONATE_ERROR, + error, + }), + ).toEqual({ + impersonation: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, }); -}); \ No newline at end of file + }); +}); diff --git a/tests/__tests__/reducers/UsersReducer.spec.js b/tests/__tests__/reducers/UsersReducer.spec.js index e45d17ce..50a0525a 100644 --- a/tests/__tests__/reducers/UsersReducer.spec.js +++ b/tests/__tests__/reducers/UsersReducer.spec.js @@ -1,85 +1,85 @@ -'use strict'; +"use strict"; -import React from 'react'; +import React from "react"; import * as ActionConstants from "../../../js/constants/ActionConstants"; import UsersReducer from "../../../js/reducers/UsersReducer"; -import {ACTION_STATUS} from "../../../js/constants/DefaultConstants"; +import { ACTION_STATUS } from "../../../js/constants/DefaultConstants"; -describe('UsersReducer', function () { - const users = [{username: 'test1'}, {username: 'test2'}], - error = { - message: 'An error has occurred.' - }; +describe("UsersReducer", function () { + const users = [{ username: "test1" }, { username: "test2" }], + error = { + message: "An error has occurred.", + }; - it('handles LOAD_USERS_PENDING', () => { - const initialState = { - usersLoaded: { - testEntry: "should not touch" - }, - testEntry2: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USERS_PENDING, - }; + it("handles LOAD_USERS_PENDING", () => { + const initialState = { + usersLoaded: { + testEntry: "should not touch", + }, + testEntry2: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USERS_PENDING, + }; - const newState = UsersReducer(initialState, action); + const newState = UsersReducer(initialState, action); - const expectedState = { - usersLoaded: { - testEntry: initialState.usersLoaded.testEntry, - status: ACTION_STATUS.PENDING - }, - testEntry2: initialState.testEntry2 - }; - expect(newState).toEqual(expectedState); - }); + const expectedState = { + usersLoaded: { + testEntry: initialState.usersLoaded.testEntry, + status: ACTION_STATUS.PENDING, + }, + testEntry2: initialState.testEntry2, + }; + expect(newState).toEqual(expectedState); + }); - it('handles LOAD_USERS_SUCCESS', () => { - const initialState = { - usersLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USERS_SUCCESS, - users - }; + it("handles LOAD_USERS_SUCCESS", () => { + const initialState = { + usersLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USERS_SUCCESS, + users, + }; - const newState = UsersReducer(initialState, action); + const newState = UsersReducer(initialState, action); - const expectedState = { - usersLoaded: { - status: ACTION_STATUS.SUCCESS, - users, - error: '' - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); - }); + const expectedState = { + usersLoaded: { + status: ACTION_STATUS.SUCCESS, + users, + error: "", + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); - it('handles LOAD_USERS_ERROR', () => { - const initialState = { - usersLoaded: { - status: ACTION_STATUS.PENDING - }, - testEntry: "should not touch" - }; - const action = { - type: ActionConstants.LOAD_USERS_ERROR, - error - }; + it("handles LOAD_USERS_ERROR", () => { + const initialState = { + usersLoaded: { + status: ACTION_STATUS.PENDING, + }, + testEntry: "should not touch", + }; + const action = { + type: ActionConstants.LOAD_USERS_ERROR, + error, + }; - const newState = UsersReducer(initialState, action); + const newState = UsersReducer(initialState, action); - const expectedState = { - usersLoaded: { - status: ACTION_STATUS.ERROR, - error - }, - testEntry: initialState.testEntry - }; - expect(newState).toEqual(expectedState); - }); -}); \ No newline at end of file + const expectedState = { + usersLoaded: { + status: ACTION_STATUS.ERROR, + error, + }, + testEntry: initialState.testEntry, + }; + expect(newState).toEqual(expectedState); + }); +}); diff --git a/tests/__tests__/utils/Utils.spec.js b/tests/__tests__/utils/Utils.spec.js index bdcdd3d9..17e41cfe 100644 --- a/tests/__tests__/utils/Utils.spec.js +++ b/tests/__tests__/utils/Utils.spec.js @@ -1,73 +1,69 @@ -import {extractLastPageNumber, paramsSerializer} from "../../../js/utils/Utils"; -import {HttpHeaders} from "../../../js/constants/DefaultConstants"; +import { extractLastPageNumber, paramsSerializer } from "../../../js/utils/Utils"; +import { HttpHeaders } from "../../../js/constants/DefaultConstants"; describe("Utils", () => { + describe("paramsSerializer", () => { + it("serializes singular query parameters into request query string", () => { + const parameters = { + page: 1, + size: 10, + includeImported: true, + searchString: "test", + }; + const result = paramsSerializer(parameters); + expect(result).toEqual("page=1&size=10&includeImported=true&searchString=test"); + }); - describe("paramsSerializer", () => { - it("serializes singular query parameters into request query string", () => { - const parameters = { - page: 1, - size: 10, - includeImported: true, - searchString: "test", - }; - const result = paramsSerializer(parameters); - expect(result).toEqual( - "page=1&size=10&includeImported=true&searchString=test" - ); - }); - - it("serializes parameter value 0", () => { - const parameters = { - page: 0, - size: 10, - }; - const result = paramsSerializer(parameters); - expect(result).toEqual( - "page=0&size=10" - ); - }); + it("serializes parameter value 0", () => { + const parameters = { + page: 0, + size: 10, + }; + const result = paramsSerializer(parameters); + expect(result).toEqual("page=0&size=10"); + }); - it("supports serializing plural query parameters", () => { - const parameters = { - includeTerms: ["a", "b", "c"], - }; - const result = paramsSerializer(parameters); - expect(result).toEqual("includeTerms=a&includeTerms=b&includeTerms=c"); - }); + it("supports serializing plural query parameters", () => { + const parameters = { + includeTerms: ["a", "b", "c"], + }; + const result = paramsSerializer(parameters); + expect(result).toEqual("includeTerms=a&includeTerms=b&includeTerms=c"); + }); - it("encodes query parameters before putting them into the query string", () => { - const parameters = { - includeTerms: ["http://example.org/one", "http://example.org/two"], - }; - const result = paramsSerializer(parameters); - expect(result).toEqual( - `includeTerms=${encodeURIComponent( - parameters.includeTerms[0] - )}&includeTerms=${encodeURIComponent(parameters.includeTerms[1])}` - ); - }); + it("encodes query parameters before putting them into the query string", () => { + const parameters = { + includeTerms: ["http://example.org/one", "http://example.org/two"], + }; + const result = paramsSerializer(parameters); + expect(result).toEqual( + `includeTerms=${encodeURIComponent( + parameters.includeTerms[0], + )}&includeTerms=${encodeURIComponent(parameters.includeTerms[1])}`, + ); }); + }); - describe("extractLastPageNumber", () => { - it("extracts last page number from last page rel link header URL", () => { - const resp = { - headers: {} - }; - resp.headers[HttpHeaders.LINK] = '; rel="next", ; rel="last"'; - expect(extractLastPageNumber(resp)).toEqual(8); - }); + describe("extractLastPageNumber", () => { + it("extracts last page number from last page rel link header URL", () => { + const resp = { + headers: {}, + }; + resp.headers[HttpHeaders.LINK] = + '; rel="next", ; rel="last"'; + expect(extractLastPageNumber(resp)).toEqual(8); + }); - it("returns undefined when response does not contain link header", () => { - expect(extractLastPageNumber({headers: {}})).not.toBeDefined(); - }); + it("returns undefined when response does not contain link header", () => { + expect(extractLastPageNumber({ headers: {} })).not.toBeDefined(); + }); - it("returns undefined when response link header does not contain last rel link", () => { - const resp = { - headers: {} - }; - resp.headers[HttpHeaders.LINK] = '; rel="next"'; - expect(extractLastPageNumber(resp)).not.toBeDefined(); - }); + it("returns undefined when response link header does not contain last rel link", () => { + const resp = { + headers: {}, + }; + resp.headers[HttpHeaders.LINK] = '; rel="next"'; + expect(extractLastPageNumber(resp)).not.toBeDefined(); }); -}); \ No newline at end of file + }); +}); diff --git a/tests/environment/Environment.js b/tests/environment/Environment.js index 073f0f58..e77ae0db 100644 --- a/tests/environment/Environment.js +++ b/tests/environment/Environment.js @@ -4,12 +4,12 @@ let dateNowSpy; * Mocks Date.now result to return a predefined value. */ export function mockDateNow(value = Date.now()) { - dateNowSpy = jest.spyOn(Date, "now").mockReturnValue(value); + dateNowSpy = jest.spyOn(Date, "now").mockReturnValue(value); } /** * Restores Date.now functionality to the default. */ export function restoreDateNow() { - dateNowSpy.mockRestore(); + dateNowSpy.mockRestore(); } diff --git a/tests/setup.js b/tests/setup.js index be659926..91125c36 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -1,12 +1,12 @@ -import enzyme, {shallow, mount} from 'enzyme'; -import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; +import enzyme, { shallow, mount } from "enzyme"; +import Adapter from "@wojtekmaj/enzyme-adapter-react-17"; -enzyme.configure({adapter: new Adapter()}); +enzyme.configure({ adapter: new Adapter() }); -require('dotenv-safe').config({ - allowEmptyValues: true, - path: './.env.test', - sample: './.env.example', -}) +require("dotenv-safe").config({ + allowEmptyValues: true, + path: "./.env.test", + sample: "./.env.example", +}); global.shallow = shallow; global.mount = mount; diff --git a/vite.config.js b/vite.config.js index c59989ec..a1416c0a 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,8 +1,8 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; -import dotenv from 'dotenv' +import dotenv from "dotenv"; -dotenv.config() +dotenv.config(); export default defineConfig({ base: "", @@ -15,5 +15,5 @@ export default defineConfig({ }, define: { "process.env": process.env, // workaround for parse-link-header library that depends on 2 vars defined in `process.env`, see https://github.com/thlorenz/parse-link-header/issues/31 - } + }, });