From 2dee250d2ba19272d4a1d3a598704e7a7f5e4dea Mon Sep 17 00:00:00 2001 From: August Andersen Date: Wed, 28 Aug 2024 13:39:31 +0200 Subject: [PATCH 1/3] formatted code. --- .prettierrc.js | 18 +- src/app/admin/admin-routing.module.ts | 154 ++-- src/app/admin/admin.component.html | 2 +- src/app/admin/admin.component.ts | 15 +- src/app/admin/admin.module.ts | 198 ++--- .../api-key-edit/api-key-edit.component.html | 107 ++- .../api-key-edit/api-key-edit.component.ts | 206 +++-- .../api-key-list/api-key-list.component.html | 22 +- .../api-key-list/api-key-list.component.ts | 55 +- .../api-key-table.component.html | 165 ++-- .../api-key-table/api-key-table.component.ts | 189 +++-- src/app/admin/api-key/api-key.component.ts | 10 +- src/app/admin/api-key/api-key.model.ts | 28 +- src/app/admin/api-key/api-key.service.ts | 135 ++-- .../organisation-detail.component.html | 28 +- .../organisation-detail.component.spec.ts | 37 +- .../organisation-detail.component.ts | 216 +++--- .../organisation-edit.component.html | 46 +- .../organisation-edit.component.spec.ts | 37 +- .../organisation-edit.component.ts | 186 +++-- .../organisation-list.component.html | 8 +- .../organisation-list.component.spec.ts | 36 +- .../organisation-list.component.ts | 40 +- .../organisation-tabel.component.html | 48 +- .../organisation-tabel.component.spec.ts | 37 +- .../organisation-tabel.component.ts | 64 +- .../organisation/organisation.component.html | 2 +- .../organisation/organisation.component.ts | 18 +- .../admin/organisation/organisation.model.ts | 42 +- .../organisation/organisation.service.ts | 115 ++- .../permission-detail.component.html | 35 +- .../permission-detail.component.spec.ts | 37 +- .../permission-detail.component.ts | 204 +++-- .../permission-edit.component.html | 126 +++- .../permission-edit.component.scss | 1 - .../permission-edit.component.spec.ts | 37 +- .../permission-edit.component.ts | 560 +++++++------- .../permission-list.component.html | 12 +- .../permission-list.component.spec.ts | 37 +- .../permission-list.component.ts | 103 ++- .../permission-tabel.component.html | 72 +- .../permission-tabel.component.spec.ts | 37 +- .../permission-tabel.component.ts | 75 +- .../permission/permission.component.html | 2 +- .../permission/permission.component.spec.ts | 37 +- .../admin/permission/permission.component.ts | 21 +- src/app/admin/permission/permission.model.ts | 68 +- .../admin/permission/permission.service.ts | 145 ++-- .../accept-user/accept-user.component.html | 101 +-- .../accept-user/accept-user.component.ts | 221 +++--- .../new-user.component.html | 130 ++-- .../new-user.component.ts | 266 +++---- .../user-detail/user-detail.component.html | 46 +- .../user-detail/user-detail.component.spec.ts | 37 +- .../user-detail/user-detail.component.ts | 166 ++-- .../users/user-edit/user-edit.component.html | 82 +- .../user-edit/user-edit.component.spec.ts | 37 +- .../users/user-edit/user-edit.component.ts | 244 +++--- .../awaiting-users-table-tab.component.html | 7 +- .../awaiting-users-table-tab.component.ts | 20 +- .../awaiting-users-table.component.html | 158 ++-- .../awaiting-users-table.component.ts | 249 +++--- .../users/user-list/user-list.component.html | 35 +- .../users/user-list/user-list.component.ts | 76 +- .../user-table-tab.component.html | 7 +- .../user-table-tab.component.ts | 20 +- .../user-table/user-table.component.html | 64 +- .../user-table/user-table.component.ts | 178 ++--- src/app/admin/users/user-minimal.model.ts | 2 +- src/app/admin/users/user-minimal.service.ts | 41 +- .../users/user-page/user-page.component.html | 119 +-- .../users/user-page/user-page.component.scss | 6 +- .../users/user-page/user-page.component.ts | 355 +++++---- src/app/admin/users/user.model.ts | 82 +- src/app/admin/users/user.service.ts | 265 +++---- src/app/admin/users/users.component.html | 2 +- src/app/admin/users/users.component.ts | 13 +- src/app/app-routing.module.ts | 80 +- src/app/app.component.html | 10 +- src/app/app.component.scss | 10 +- src/app/app.component.spec.ts | 18 +- src/app/app.component.ts | 20 +- src/app/app.module.ts | 181 +++-- .../application-detail.component.spec.ts | 38 +- .../application-edit.component.spec.ts | 38 +- .../application-edit.component.ts | 64 +- src/app/applications/application.model.ts | 108 +-- src/app/applications/application.service.ts | 138 ++-- .../applications-list.component.html | 57 +- .../applications-list.component.spec.ts | 39 +- .../applications-list.component.ts | 313 ++++---- .../applications-table.component.html | 344 +++++---- .../applications-table.component.scss | 2 +- .../applications-table.component.spec.ts | 37 +- .../applications-routing.module.ts | 170 ++--- .../applications.component.spec.ts | 37 +- .../applications/applications.component.ts | 13 +- src/app/applications/applications.module.ts | 94 ++- .../bulk-import/bulk-import.component.html | 79 +- .../bulk-import/bulk-import.component.scss | 1 - .../bulk-import/bulk-import.component.ts | 533 +++++++------ .../bulk-import/bulk-import.model.ts | 6 +- .../applications/bulk-import/bulk-mapping.ts | 224 +++--- ...get-detail-type-selector.directive.spec.ts | 16 +- ...tatarget-detail-type-selector.directive.ts | 7 +- .../datatarget-detail.component.html | 2 +- .../datatarget-detail.component.scss | 4 +- .../datatarget-detail.component.spec.ts | 37 +- .../datatarget-detail.component.ts | 85 +-- .../datatarget-detail/datatarget-detail.ts | 3 +- ...arget-edit-type-selector.directive.spec.ts | 16 +- ...datatarget-edit-type-selector.directive.ts | 10 +- .../datatarget-edit.component.html | 2 +- .../datatarget-edit.component.spec.ts | 37 +- .../datatarget-edit.component.ts | 127 ++-- .../datatarget-edit/datatarget-edit.ts | 3 +- .../datatarget-new.component.html | 63 +- .../datatarget-new.component.scss | 60 +- .../datatarget-new.component.spec.ts | 41 +- .../datatarget-new.component.ts | 106 ++- .../datatarget/datatarget-response.model.ts | 6 +- .../datatarget-tab.component.html | 32 +- .../datatarget-tab.component.ts | 18 +- .../datatarget-table.component.html | 112 +-- .../datatarget-table.component.spec.ts | 37 +- .../datatarget-table.component.ts | 81 +- .../datatarget-types.service.spec.ts | 20 +- .../datatarget/datatarget-types.service.ts | 152 ++-- .../datatarget/datatarget.model.ts | 8 +- .../datatarget/datatarget.module.ts | 142 ++-- .../datatarget/datatarget.service.spec.ts | 22 +- .../datatarget/datatarget.service.ts | 223 +++--- .../fiware-detail.component.html | 224 ++++-- .../fiware-detail.component.spec.ts | 41 +- .../fiware-detail/fiware-detail.component.ts | 173 ++--- .../fiware-edit/fiware-edit.component.html | 455 ++++++----- .../fiware-edit/fiware-edit.component.scss | 2 +- .../fiware-edit/fiware-edit.component.spec.ts | 41 +- .../fiware-edit/fiware-edit.component.ts | 594 +++++++-------- .../httppush-detail.component.html | 185 +++-- .../httppush-detail.component.scss | 2 +- .../httppush-detail.component.spec.ts | 41 +- .../httppush-detail.component.ts | 177 +++-- .../httppush-edit.component.html | 272 ++++--- .../httppush-edit.component.spec.ts | 41 +- .../httppush-edit/httppush-edit.component.ts | 610 ++++++++------- .../mqtt-detail/mqtt-detail.component.html | 167 ++-- .../mqtt-detail/mqtt-detail.component.ts | 161 ++-- .../mqtt-edit/mqtt-edit.component.html | 397 ++++++---- .../mqtt-edit/mqtt-edit.component.ts | 493 ++++++------ .../opendatadk/opendatadk-dataset.model.ts | 4 +- .../opendatadk-detail.component.html | 30 +- .../opendatadk-detail.component.spec.ts | 37 +- .../opendatadk-detail.component.ts | 19 +- .../opendatadk-edit.component.html | 699 +++++++++-------- .../opendatadk-edit.component.scss | 36 +- .../opendatadk-edit.component.spec.ts | 37 +- .../opendatadk-edit.component.ts | 712 +++++++++--------- .../opendatadk-mail-dialog.html | 32 +- .../opendatadk-mail-dialog.ts | 58 +- .../opendatadk-warning-dialog.html | 17 +- .../opendatadk-warning-dialog.ts | 20 +- .../opendatadk/opendatadk.component.spec.ts | 37 +- .../opendatadk/opendatadk.component.ts | 15 +- .../iot-devices/downlink.model.ts | 6 +- .../data-package/data-package.component.html | 10 +- .../data-package.component.spec.ts | 37 +- .../data-package/data-package.component.ts | 18 +- .../data-packages-timestamp.component.html | 42 +- .../data-packages-timestamp.component.scss | 3 +- .../data-packages-timestamp.component.ts | 41 +- .../device-model/device-model.component.html | 15 +- .../device-model/device-model.component.scss | 2 +- .../device-model.component.spec.ts | 37 +- .../device-model/device-model.component.ts | 52 +- .../downlink-dialog.component.html | 12 +- .../downlink-dialog.component.ts | 31 +- .../downlink/downlink.component.html | 49 +- .../downlink/downlink.component.ts | 196 ++--- ...iot-device-data-packets-tab.component.html | 23 +- .../iot-device-data-packets-tab.component.ts | 22 +- .../iot-device-detail-generic.component.html | 95 ++- .../iot-device-detail-generic.component.scss | 2 +- .../iot-device-detail-generic.component.ts | 133 ++-- .../iot-device-detail-lorawan.component.html | 41 +- .../iot-device-detail-lorawan.component.ts | 48 +- .../iot-device-detail-sigfox.component.html | 32 +- .../iot-device-detail-sigfox.component.ts | 19 +- .../iot-device-detail.component.html | 36 +- .../iot-device-detail.component.scss | 42 +- .../iot-device-detail.component.spec.ts | 37 +- .../iot-device-detail.component.ts | 400 +++++----- ...etails-mqtt-external-broker.component.html | 45 +- ...-details-mqtt-external-broker.component.ts | 20 +- ...etails-mqtt-internal-broker.component.html | 78 +- ...-details-mqtt-internal-broker.component.ts | 28 +- .../iot-device-details-tab.component.html | 14 +- .../iot-device-details-tab.component.ts | 30 +- .../iot-device-downlink-tab.component.html | 2 +- .../iot-device-downlink-tab.component.ts | 24 +- .../iot-device-history-tab.component.html | 61 +- .../iot-device-history-tab.component.ts | 260 +++---- .../iot-devices/iot-device-details-service.ts | 12 +- .../iot-device-edit.component.html | 619 +++++++++------ .../iot-device-edit.component.spec.ts | 37 +- .../mqtt-authentication-select.component.html | 122 +-- .../mqtt-authentication-select.component.scss | 4 +- .../mqtt-authentication-select.component.ts | 30 +- .../mqtt-device-edit.component.html | 352 +++++---- .../mqtt-device-edit.component.scss | 4 +- .../mqtt-device-edit.component.ts | 49 +- .../sigfox-device-edit.component.html | 268 ++++--- .../sigfox-device-edit.component.ts | 128 ++-- .../iot-devices/iot-device.service.ts | 173 ++--- .../export-csv-dialog.component.html | 16 +- .../iot-devices-tab.component.html | 54 +- .../iot-devices-tab.component.ts | 76 +- .../iot-devices-table.component.html | 273 +++---- .../iot-devices-table.component.scss | 1 - .../iot-devices-table.component.spec.ts | 37 +- .../iot-devices/iot-devices.module.ts | 148 ++-- .../models/application-device-type.model.ts | 8 +- .../multicast-detail.component.html | 247 +++--- .../multicast-detail.component.scss | 4 +- .../multicast-detail.component.ts | 291 ++++--- .../multicast-edit.component.html | 455 +++++------ .../multicast-edit.component.scss | 6 +- .../multicast-edit.component.ts | 367 +++++---- .../multicast/multicast-response.model.ts | 46 +- .../multicast-tab.component.html | 32 +- .../multicast-tab/multicast-tab.component.ts | 14 +- .../multicast-table.component.html | 113 +-- .../multicast-table.component.ts | 236 +++--- .../applications/multicast/multicast.model.ts | 46 +- .../multicast/multicast.module.ts | 65 +- .../multicast/multicast.service.ts | 168 ++--- src/app/auth/auth-guard.service.ts | 33 +- src/app/auth/auth.component.html | 43 +- src/app/auth/auth.component.scss | 1 - src/app/auth/auth.component.ts | 138 ++-- src/app/auth/auth.module.ts | 22 +- src/app/auth/auth.service.ts | 187 +++-- src/app/dashboard/dashboard.component.html | 75 +- src/app/dashboard/dashboard.component.ts | 179 +++-- .../Enums/controlled-propperty.enum.ts | 2 +- .../Enums/device-category.enum.ts | 20 +- .../Enums/device-function.enum.ts | 12 +- .../Enums/energy-limitation-class.model.ts | 8 +- .../Enums/supported-protocol.enum.ts | 34 +- .../device-model-detail.component.html | 61 +- .../device-model-detail.component.spec.ts | 37 +- .../device-model-detail.component.ts | 172 +++-- .../device-model-edit.component.html | 193 +++-- .../device-model-edit.component.ts | 200 +++-- .../device-model-list.component.html | 21 +- .../device-model-list.component.ts | 44 +- .../device-model-routing.module.ts | 30 +- .../device-model-table.component.html | 45 +- .../device-model-table.component.spec.ts | 37 +- .../device-model-table.component.ts | 225 +++--- src/app/device-model/device-model.module.ts | 61 +- src/app/device-model/device-model.service.ts | 234 +++--- src/app/device-model/device.model.ts | 15 +- src/app/device-model/supported-unit.model.ts | 146 ++-- src/app/error-page/error-page.component.html | 8 +- src/app/error-page/error-page.component.scss | 98 ++- src/app/error-page/error-page.component.ts | 38 +- .../gateway-detail.component.html | 266 ++++--- .../gateway-detail.component.scss | 2 +- .../gateway-overview.component.html | 48 +- .../gateway-overview.component.scss | 10 +- .../gateway-overview.component.ts | 158 ++-- .../gateway-list/gateway-list.component.html | 3 +- .../gateway-list/gateway-list.component.ts | 20 +- .../gateway-map/gateway-map.component.html | 3 +- .../gateway-status-overview.component.html | 6 +- .../gateway-status-overview.component.ts | 27 +- .../gateway-status.component.html | 147 ++-- .../gateway-status.component.scss | 146 ++-- .../gateway-status.component.ts | 471 ++++++------ .../gateway-table.component.html | 411 +++++----- .../gateway-table.component.scss | 4 +- src/app/gateway/gateway.module.ts | 136 ++-- src/app/gateway/gateway.service.ts | 12 +- .../gateway/gateways/gateways.component.html | 2 +- .../gateway/gateways/gateways.component.ts | 15 +- src/app/graph/graph.component.html | 22 +- src/app/graph/graph.component.scss | 36 +- src/app/graph/graph.component.ts | 157 ++-- src/app/graph/graph.module.ts | 18 +- .../global-admin/global-admin.component.html | 25 +- .../global-admin/global-admin.component.scss | 1 - .../global-admin/global-admin.component.ts | 45 +- src/app/navbar/navbar.component.html | 157 ++-- src/app/navbar/navbar.component.ts | 144 ++-- src/app/navbar/navbar.module.ts | 51 +- .../organisation-dropdown.component.html | 57 +- .../organisation-dropdown.component.scss | 1 - .../organisation-dropdown.component.spec.ts | 37 +- .../organisation-dropdown.component.ts | 155 ++-- .../sigfox-dropdown.component.html | 13 +- .../iot-device-minimal-table.component.html | 33 +- ...iot-device-minimal-table.component.spec.ts | 37 +- .../iot-device-minimal-table.component.ts | 139 ++-- .../payload-decoder-detail.component.html | 39 +- .../payload-decoder-detail.component.scss | 2 +- .../payload-decoder-detail.component.spec.ts | 37 +- .../payload-decoder-detail.component.ts | 183 +++-- .../payload-decoder-edit.component.html | 218 +++--- .../payload-decoder-edit.component.scss | 1 - .../payload-decoder-edit.component.spec.ts | 37 +- .../payload-decoder-edit.component.ts | 586 +++++++------- .../payload-decoder-list.component.html | 21 +- .../payload-decoder-list.component.spec.ts | 37 +- .../payload-decoder-list.component.ts | 34 +- .../payload-decoder-table.component.html | 65 +- .../payload-decoder-table.component.spec.ts | 37 +- .../payload-decoder-table.component.ts | 252 +++---- .../payload-decoder-routing.module.ts | 31 +- .../payload-decoder.component.html | 2 +- .../payload-decoder.component.spec.ts | 37 +- .../payload-decoder.component.ts | 21 +- .../payload-decoder/payload-decoder.model.ts | 35 +- .../payload-decoder/payload-decoder.module.ts | 100 +-- .../payload-decoder.service.ts | 128 ++-- .../payload-device-data.model.ts | 9 +- .../payload-device-datatarget.service.ts | 84 +-- .../test-payload-decoder.service.ts | 14 +- .../device-profiles/device-profile.model.ts | 4 +- .../device-profile.service.spec.ts | 22 +- .../device-profiles/device-profile.service.ts | 116 +-- .../device-profiles-edit.component.html | 338 ++++++--- .../device-profiles-edit.component.ts | 62 +- .../device-profiles-item.component.html | 8 +- .../device-profiles-item.component.ts | 40 +- .../device-profiles-list.component.html | 17 +- .../profiles-list.component.html | 2 +- .../profiles-list/profiles-list.component.ts | 42 +- src/app/profiles/profiles-routing.module.ts | 30 +- src/app/profiles/profiles.component.html | 2 +- src/app/profiles/profiles.component.ts | 13 +- src/app/profiles/profiles.module.ts | 83 +- src/app/search/search-results.model.ts | 32 +- .../search-table/search-table.component.html | 56 +- .../search-table.component.spec.ts | 37 +- .../search-table/search-table.component.ts | 268 +++---- src/app/search/search.component.html | 3 +- src/app/search/search.component.spec.ts | 37 +- src/app/search/search.component.ts | 43 +- src/app/search/search.module.ts | 48 +- src/app/search/search.service.ts | 32 +- src/app/shared/Modules/materiale.module.ts | 110 +-- .../components/alert/alert.component.html | 9 +- .../components/alert/alert.component.ts | 17 +- .../batteri-status.component.html | 6 +- .../batteri-status.component.scss | 10 +- .../batteri-status.component.spec.ts | 37 +- .../batteri-status.component.ts | 84 +-- .../column-selector.component.html | 58 +- .../column-selector.component.scss | 6 +- .../column-selector.component.ts | 128 ++-- .../delete-dialog.component.html | 22 +- .../delete-dialog/delete-dialog.component.ts | 39 +- .../delete-dialog/delete-dialog.service.ts | 127 ++-- .../dynamic-img/dynamic-img.component.html | 2 +- .../dynamic-img/dynamic-img.component.ts | 33 +- .../form-body-application.component.html | 444 +++++++---- .../form-body-application.component.spec.ts | 37 +- .../form-body-application.component.ts | 567 +++++++------- .../form-header/form-header.component.html | 10 +- .../form-header/form-header.component.scss | 92 ++- .../form-header/form-header.component.spec.ts | 37 +- .../form-header/form-header.component.ts | 57 +- .../form-key-value-list.component.html | 24 +- .../form-key-value-list.component.ts | 36 +- .../form-key-value-pair.component.html | 47 +- .../form-key-value-pair.component.scss | 4 +- .../form-key-value-pair.component.ts | 81 +- .../components/forms/form.component.html | 11 +- .../shared/components/forms/form.component.ts | 27 +- .../shared/components/forms/form.module.ts | 65 +- .../general-details.component.html | 10 +- .../general-details.component.spec.ts | 37 +- .../general-details.component.ts | 43 +- .../loading-spinner.component.html | 2 +- .../loading-spinner.component.ts | 10 +- .../components/map/map-coordinates.model.ts | 2 +- .../shared/components/map/map.component.html | 1 - .../components/map/map.component.spec.ts | 37 +- .../mat-select-search.module.ts | 18 +- .../mat-select-search.component.html | 32 +- .../mat-select-search.component.scss | 49 +- .../mat-select-search.component.ts | 552 +++++++------- .../metadata-details.component.html | 44 +- .../metadata-details.component.ts | 83 +- .../snack-bar/snack-bar.component.html | 8 +- .../snack-bar/snack-bar.component.ts | 15 +- .../top-bar-table.component.html | 73 +- .../top-bar-table.component.spec.ts | 37 +- .../top-bar-table/top-bar-table.component.ts | 72 +- .../components/top-bar/top-bar.component.html | 293 ++++--- .../components/top-bar/top-bar.component.scss | 44 +- .../top-bar/top-bar.component.spec.ts | 37 +- .../components/top-bar/top-bar.component.ts | 305 ++++---- .../welcome-dialog.component.html | 84 ++- .../welcome-dialog.component.scss | 88 +-- .../welcome-dialog.component.ts | 52 +- .../welcome-dialog/welcome-dialog.module.ts | 24 +- src/app/shared/constants/color-constants.ts | 2 +- src/app/shared/constants/date.constants.ts | 20 +- src/app/shared/constants/regex-constants.ts | 14 +- .../shared/directives/directives.module.ts | 30 +- .../shared/directives/drag-drop.directive.ts | 33 +- .../shared/directives/dropdown.directive.ts | 10 +- .../directives/placeholder.directive.ts | 6 +- src/app/shared/enums/access-scopes.ts | 6 +- src/app/shared/enums/activation-type.ts | 6 +- src/app/shared/enums/authentication-type.ts | 4 +- src/app/shared/enums/datatarget-type.ts | 8 +- src/app/shared/enums/device-type.ts | 28 +- src/app/shared/enums/multicast-type.ts | 4 +- src/app/shared/helpers/array.helper.ts | 77 +- .../shared/helpers/auth-jwt.interceptor.ts | 22 +- src/app/shared/helpers/download.helper.ts | 117 ++- .../shared/helpers/global-error-handler.ts | 16 +- src/app/shared/helpers/json.helper.ts | 29 +- .../shared/helpers/mat-paginator-intl-da.ts | 99 ++- src/app/shared/helpers/record.helper.ts | 17 +- .../helpers/server-error.interceptor.ts | 15 +- src/app/shared/helpers/string.helper.ts | 14 +- .../shared/helpers/table-sorting.helper.ts | 90 +-- src/app/shared/helpers/type.helper.ts | 9 +- src/app/shared/models/alert.model.ts | 2 +- .../shared/models/common-location.model.ts | 14 +- .../models/controlled-property.model.ts | 8 +- src/app/shared/models/dialog.model.ts | 18 +- .../shared/models/dropdown-button.model.ts | 4 +- src/app/shared/models/error-message.model.ts | 18 +- src/app/shared/models/error.model.ts | 2 +- .../shared/models/lorawan-settings.model.ts | 2 +- .../models/mqtt-broker-settings.model.ts | 2 +- .../models/mqtt-shared-settings.model.ts | 20 +- .../models/mqtt-subscriber-settings.model.ts | 4 +- .../models/quick-action-button.model.ts | 2 +- .../shared/models/sigfox-contract.model.ts | 1 - .../shared/models/sigfox-device-type.model.ts | 2 +- src/app/shared/models/sigfox-group.model.ts | 6 +- src/app/shared/models/sort.model.ts | 12 +- src/app/shared/pipes/activeDeactive.pipe.ts | 8 +- .../shared/pipes/created-updated-by.pipe.ts | 13 +- src/app/shared/pipes/custom-date.pipe.ts | 39 +- src/app/shared/pipes/filter-devices.pipe.ts | 36 +- .../gateway/gateway-status-class.pipe.ts | 54 +- .../gateway/gateway-status-tooltip.pipe.ts | 28 +- .../permission/can-edit-application.pipe.ts | 20 +- .../pipes/permission/is-global-admin.pipe.ts | 21 +- .../permission/translate-permissions.pipe.ts | 24 +- src/app/shared/pipes/pipes.module.ts | 105 ++- .../shared/pipes/sort-by-translation.pipe.ts | 51 +- src/app/shared/pipes/sort-by.pipe.ts | 28 +- src/app/shared/pipes/yesNo.pipe.ts | 8 +- src/app/shared/providers/saver.provider.ts | 6 +- src/app/shared/services/alert.service.spec.ts | 22 +- src/app/shared/services/alert.service.ts | 23 +- .../shared/services/bulk-import.service.ts | 12 +- .../chripstack-gateway.service.spec.ts | 26 +- src/app/shared/services/downlink.service.ts | 38 +- src/app/shared/services/download.service.ts | 42 +- src/app/shared/services/error.service.ts | 17 +- src/app/shared/services/loggedin.service.ts | 18 +- src/app/shared/services/logging.service.ts | 7 +- .../services/lorawan-gateway.service.ts | 43 +- src/app/shared/services/me.service.ts | 177 ++--- .../shared/services/notification.service.ts | 17 +- src/app/shared/services/opendatadk.service.ts | 16 +- src/app/shared/services/rest.service.spec.ts | 22 +- src/app/shared/services/rest.service.ts | 414 +++++----- .../services/scroll-to-top.service.spec.ts | 22 +- .../shared/services/scroll-to-top.service.ts | 25 +- src/app/shared/services/sigfox.service.ts | 112 ++- src/app/shared/services/snack.service.ts | 102 ++- .../shared-variable/shared-variable.module.ts | 16 +- .../shared-variable.service.ts | 150 ++-- src/app/shared/shared.module.ts | 114 +-- src/app/shared/styles/leaflet-styles.scss | 99 +-- src/app/shared/types/table.type.ts | 8 +- src/app/shared/types/tuple.type.ts | 4 +- src/app/shared/validators/name.validator.ts | 8 +- .../validators/phone-number.validator.ts | 10 +- .../sigfox-device-type-table.component.html | 11 +- .../sigfox-device-type-table.component.scss | 1 - ...sigfox-device-type-table.component.spec.ts | 37 +- .../sigfox-device-type-table.component.ts | 80 +- .../sigfox-device-types-edit.component.html | 95 ++- ...sigfox-device-types-edit.component.spec.ts | 37 +- .../sigfox-device-types-edit.component.ts | 228 +++--- .../sigfox-groups-detail.component.html | 14 +- .../sigfox-groups-detail.component.ts | 115 ++- .../sigfox-groups-edit.component.html | 44 +- .../sigfox-groups-edit.component.ts | 216 +++--- .../sigfox-groups-list-item.component.html | 8 +- .../sigfox-groups-list-item.component.ts | 45 +- .../sigfox-groups-list.component.html | 18 +- .../sigfox-groups-list.component.ts | 103 ++- src/app/sigfox/sigfox-routing.module.ts | 41 +- src/app/sigfox/sigfox-settings.model.ts | 2 +- src/app/sigfox/sigfox.module.ts | 73 +- src/assets/scss/animation/_jumping-dots.scss | 56 +- src/assets/scss/components/_boxes.scss | 81 +- src/assets/scss/components/_bulk-import.scss | 102 +-- src/assets/scss/components/_date-picker.scss | 38 +- src/assets/scss/components/_forms.scss | 284 ++++--- src/assets/scss/components/_list.scss | 64 +- .../scss/components/_loading-spinner.scss | 222 +++--- src/assets/scss/components/_map.scss | 2 +- .../scss/components/_monaco-editor.scss | 14 +- src/assets/scss/components/_navbar.scss | 101 ++- src/assets/scss/components/_tables.scss | 196 +++-- src/assets/scss/components/_topbar.scss | 109 ++- src/assets/scss/elements/_buttons.scss | 260 ++++--- src/assets/scss/elements/_icons.scss | 52 +- src/assets/scss/elements/_img.scss | 20 +- src/assets/scss/elements/_labels.scss | 12 +- src/assets/scss/elements/_links.scss | 85 +-- src/assets/scss/elements/_textfield.scss | 12 +- src/assets/scss/setup/_base.scss | 80 +- src/assets/scss/setup/_breakpoints.scss | 62 +- src/assets/scss/setup/_fonts.scss | 4 +- src/assets/scss/setup/_material-theme.scss | 115 ++- src/assets/scss/setup/_typography.scss | 370 +++++---- src/assets/scss/setup/_utilities.scss | 91 ++- src/assets/scss/setup/_variables.scss | 28 +- src/index.html | 42 +- src/main.ts | 10 +- src/polyfills.ts | 4 +- src/styles.scss | 143 ++-- src/test.ts | 20 +- 537 files changed, 21851 insertions(+), 21253 deletions(-) diff --git a/.prettierrc.js b/.prettierrc.js index 70761a2dd..0e4e8a747 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,11 +1,11 @@ module.exports = { - trailingComma: "es5", - tabWidth: 4, - printWidth: 120, - semi: true, - singleQuote: false, - useTabs: false, - bracketSpacing: true, - arrowParens: "avoid", - endOfLine: "auto", + trailingComma: "es5", + tabWidth: 4, + printWidth: 120, + semi: true, + singleQuote: false, + useTabs: false, + bracketSpacing: true, + arrowParens: "avoid", + endOfLine: "auto", }; diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index 1e03251c0..00568566a 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -1,86 +1,86 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { OrganisationDetailComponent } from './organisation/organisation-detail/organisation-detail.component'; -import { OrganisationEditComponent } from './organisation/organisation-edit/organisation-edit.component'; -import { OrganisationListComponent } from './organisation/organisation-list/organisation-list.component'; -import { OrganisationComponent } from './organisation/organisation.component'; -import { PermissionDetailComponent } from './permission/permission-detail/permission-detail.component'; -import { PermissionEditComponent } from './permission/permission-edit/permission-edit.component'; -import { PermissionListComponent } from './permission/permission-list/permission-list.component'; -import { PermissionComponent } from './permission/permission.component'; -import { UserDetailComponent } from './users/user-detail/user-detail.component'; -import { UserEditComponent } from './users/user-edit/user-edit.component'; -import { UserListComponent } from './users/user-list/user-list.component'; -import { UsersComponent } from './users/users.component'; -import { ApiKeyComponent } from './api-key/api-key.component'; -import { ApiKeyListComponent } from './api-key/api-key-list/api-key-list.component'; -import { ApiKeyEditComponent } from './api-key/api-key-edit/api-key-edit.component'; -import { AcceptUserComponent } from './users/accept-user/accept-user.component'; -import { UserTableTabComponent } from '@app/admin/users/user-list/user-table-tab/user-table-tab.component'; -import { AwaitingUsersTableTabComponent } from '@app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component'; +import { NgModule } from "@angular/core"; +import { Routes, RouterModule } from "@angular/router"; +import { OrganisationDetailComponent } from "./organisation/organisation-detail/organisation-detail.component"; +import { OrganisationEditComponent } from "./organisation/organisation-edit/organisation-edit.component"; +import { OrganisationListComponent } from "./organisation/organisation-list/organisation-list.component"; +import { OrganisationComponent } from "./organisation/organisation.component"; +import { PermissionDetailComponent } from "./permission/permission-detail/permission-detail.component"; +import { PermissionEditComponent } from "./permission/permission-edit/permission-edit.component"; +import { PermissionListComponent } from "./permission/permission-list/permission-list.component"; +import { PermissionComponent } from "./permission/permission.component"; +import { UserDetailComponent } from "./users/user-detail/user-detail.component"; +import { UserEditComponent } from "./users/user-edit/user-edit.component"; +import { UserListComponent } from "./users/user-list/user-list.component"; +import { UsersComponent } from "./users/users.component"; +import { ApiKeyComponent } from "./api-key/api-key.component"; +import { ApiKeyListComponent } from "./api-key/api-key-list/api-key-list.component"; +import { ApiKeyEditComponent } from "./api-key/api-key-edit/api-key-edit.component"; +import { AcceptUserComponent } from "./users/accept-user/accept-user.component"; +import { UserTableTabComponent } from "@app/admin/users/user-list/user-table-tab/user-table-tab.component"; +import { AwaitingUsersTableTabComponent } from "@app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component"; const adminRoutes: Routes = [ - { - path: 'organisations', - component: OrganisationComponent, - children: [ - { path: '', component: OrganisationListComponent }, - { path: 'new-organisation', component: OrganisationEditComponent }, - { path: ':org-id', component: OrganisationDetailComponent }, - { - path: ':org-id/edit-organisation', - component: OrganisationEditComponent, - }, - ], - }, - { - path: 'users', - component: UsersComponent, - children: [ - { - path: '', - component: UserListComponent, + { + path: "organisations", + component: OrganisationComponent, children: [ - { path: 'existing', component: UserTableTabComponent }, - { path: 'awaiting', component: AwaitingUsersTableTabComponent }, + { path: "", component: OrganisationListComponent }, + { path: "new-organisation", component: OrganisationEditComponent }, + { path: ":org-id", component: OrganisationDetailComponent }, + { + path: ":org-id/edit-organisation", + component: OrganisationEditComponent, + }, ], - }, - { path: 'organization/:organization-id', component: UserListComponent }, - { path: 'new-user', component: UserEditComponent }, - { path: ':user-id', component: UserDetailComponent }, - { path: ':user-id/edit-user', component: UserEditComponent }, - { path: 'accept-user/:user-id/:org-id', component: AcceptUserComponent }, - ], - }, - { - path: 'permissions', - component: PermissionComponent, - children: [ - { path: '', component: PermissionListComponent }, - { path: 'new-permission', component: PermissionEditComponent }, - { path: ':permission-id', component: PermissionDetailComponent }, - { - path: ':permission-id/edit-permission', - component: PermissionEditComponent, - }, - ], - }, - { - path: 'api-key', - component: ApiKeyComponent, - children: [ - { path: '', component: ApiKeyListComponent }, - { path: 'new-api-key', component: ApiKeyEditComponent }, - { - path: ':api-key-id/edit-api-key', - component: ApiKeyEditComponent, - }, - ], - }, + }, + { + path: "users", + component: UsersComponent, + children: [ + { + path: "", + component: UserListComponent, + children: [ + { path: "existing", component: UserTableTabComponent }, + { path: "awaiting", component: AwaitingUsersTableTabComponent }, + ], + }, + { path: "organization/:organization-id", component: UserListComponent }, + { path: "new-user", component: UserEditComponent }, + { path: ":user-id", component: UserDetailComponent }, + { path: ":user-id/edit-user", component: UserEditComponent }, + { path: "accept-user/:user-id/:org-id", component: AcceptUserComponent }, + ], + }, + { + path: "permissions", + component: PermissionComponent, + children: [ + { path: "", component: PermissionListComponent }, + { path: "new-permission", component: PermissionEditComponent }, + { path: ":permission-id", component: PermissionDetailComponent }, + { + path: ":permission-id/edit-permission", + component: PermissionEditComponent, + }, + ], + }, + { + path: "api-key", + component: ApiKeyComponent, + children: [ + { path: "", component: ApiKeyListComponent }, + { path: "new-api-key", component: ApiKeyEditComponent }, + { + path: ":api-key-id/edit-api-key", + component: ApiKeyEditComponent, + }, + ], + }, ]; @NgModule({ - imports: [RouterModule.forChild(adminRoutes)], - exports: [RouterModule], + imports: [RouterModule.forChild(adminRoutes)], + exports: [RouterModule], }) export class AdminRoutingModule {} diff --git a/src/app/admin/admin.component.html b/src/app/admin/admin.component.html index 90c6b6463..0680b43f9 100644 --- a/src/app/admin/admin.component.html +++ b/src/app/admin/admin.component.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/app/admin/admin.component.ts b/src/app/admin/admin.component.ts index d267ab24c..f5daf42e7 100644 --- a/src/app/admin/admin.component.ts +++ b/src/app/admin/admin.component.ts @@ -1,15 +1,12 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-admin', - templateUrl: './admin.component.html', - styleUrls: ['./admin.component.scss'] + selector: "app-admin", + templateUrl: "./admin.component.html", + styleUrls: ["./admin.component.scss"], }) export class AdminComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit(): void { - } - + ngOnInit(): void {} } diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index ace6a7bf1..f5b26f15f 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -1,104 +1,104 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; -import { AdminRoutingModule } from './admin-routing.module'; -import { ApplicationsModule } from '@applications/applications.module'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; -import { TranslateModule } from '@ngx-translate/core'; -import { FormModule } from '@shared/components/forms/form.module'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { SharedModule } from '@shared/shared.module'; -import { PermissionDetailComponent } from './permission/permission-detail/permission-detail.component'; -import { PermissionEditComponent } from './permission/permission-edit/permission-edit.component'; -import { PermissionListComponent } from './permission/permission-list/permission-list.component'; -import { PermissionTabelComponent } from './permission/permission-list/permission-tabel/permission-tabel.component'; -import { PermissionComponent } from './permission/permission.component'; -import { OrganisationDetailComponent } from './organisation/organisation-detail/organisation-detail.component'; -import { OrganisationEditComponent } from './organisation/organisation-edit/organisation-edit.component'; -import { OrganisationListComponent } from './organisation/organisation-list/organisation-list.component'; -import { OrganisationTabelComponent } from './organisation/organisation-list/organisation-tabel/organisation-tabel.component'; -import { OrganisationComponent } from './organisation/organisation.component'; -import { UserDetailComponent } from './users/user-detail/user-detail.component'; -import { UserEditComponent } from './users/user-edit/user-edit.component'; -import { UserListComponent } from './users/user-list/user-list.component'; -import { UserTableComponent } from './users/user-list/user-table/user-table.component'; -import { UsersComponent } from './users/users.component'; -import { MatSelectModule } from '@angular/material/select'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-select-search.module'; -import { ApiKeyComponent } from './api-key/api-key.component'; -import { ApiKeyListComponent } from './api-key/api-key-list/api-key-list.component'; -import { ApiKeyTableComponent } from './api-key/api-key-list/api-key-table/api-key-table.component'; -import { ApiKeyEditComponent } from './api-key/api-key-edit/api-key-edit.component'; -import { AwaitingUsersTableComponent } from './users/user-list/awaiting-users-table/awaiting-users-table.component'; -import { AcceptUserComponent } from './users/accept-user/accept-user.component'; -import { UserTableTabComponent } from './users/user-list/user-table-tab/user-table-tab.component'; -import { AwaitingUsersTableTabComponent } from './users/user-list/awaiting-user-tab/awaiting-users-table-tab.component'; +import { AdminRoutingModule } from "./admin-routing.module"; +import { ApplicationsModule } from "@applications/applications.module"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { RouterModule } from "@angular/router"; +import { TranslateModule } from "@ngx-translate/core"; +import { FormModule } from "@shared/components/forms/form.module"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { SharedModule } from "@shared/shared.module"; +import { PermissionDetailComponent } from "./permission/permission-detail/permission-detail.component"; +import { PermissionEditComponent } from "./permission/permission-edit/permission-edit.component"; +import { PermissionListComponent } from "./permission/permission-list/permission-list.component"; +import { PermissionTabelComponent } from "./permission/permission-list/permission-tabel/permission-tabel.component"; +import { PermissionComponent } from "./permission/permission.component"; +import { OrganisationDetailComponent } from "./organisation/organisation-detail/organisation-detail.component"; +import { OrganisationEditComponent } from "./organisation/organisation-edit/organisation-edit.component"; +import { OrganisationListComponent } from "./organisation/organisation-list/organisation-list.component"; +import { OrganisationTabelComponent } from "./organisation/organisation-list/organisation-tabel/organisation-tabel.component"; +import { OrganisationComponent } from "./organisation/organisation.component"; +import { UserDetailComponent } from "./users/user-detail/user-detail.component"; +import { UserEditComponent } from "./users/user-edit/user-edit.component"; +import { UserListComponent } from "./users/user-list/user-list.component"; +import { UserTableComponent } from "./users/user-list/user-table/user-table.component"; +import { UsersComponent } from "./users/users.component"; +import { MatSelectModule } from "@angular/material/select"; +import { MatFormFieldModule } from "@angular/material/form-field"; +import { MatSelectSearchModule } from "@shared/components/mat-select-search/mat-select-search.module"; +import { ApiKeyComponent } from "./api-key/api-key.component"; +import { ApiKeyListComponent } from "./api-key/api-key-list/api-key-list.component"; +import { ApiKeyTableComponent } from "./api-key/api-key-list/api-key-table/api-key-table.component"; +import { ApiKeyEditComponent } from "./api-key/api-key-edit/api-key-edit.component"; +import { AwaitingUsersTableComponent } from "./users/user-list/awaiting-users-table/awaiting-users-table.component"; +import { AcceptUserComponent } from "./users/accept-user/accept-user.component"; +import { UserTableTabComponent } from "./users/user-list/user-table-tab/user-table-tab.component"; +import { AwaitingUsersTableTabComponent } from "./users/user-list/awaiting-user-tab/awaiting-users-table-tab.component"; @NgModule({ - declarations: [ - UserDetailComponent, - UserEditComponent, - UserListComponent, - UsersComponent, - UserTableComponent, - PermissionComponent, - PermissionEditComponent, - PermissionDetailComponent, - PermissionListComponent, - PermissionTabelComponent, - OrganisationComponent, - OrganisationTabelComponent, - OrganisationDetailComponent, - OrganisationEditComponent, - OrganisationListComponent, - ApiKeyComponent, - ApiKeyListComponent, - ApiKeyTableComponent, - ApiKeyEditComponent, - AwaitingUsersTableComponent, - AcceptUserComponent, - UserTableTabComponent, - AwaitingUsersTableTabComponent, - ], - imports: [ - AdminRoutingModule, - NGMaterialModule, - PipesModule, - CommonModule, - TranslateModule, - FormsModule, - ReactiveFormsModule, - FormModule, - RouterModule, - ApplicationsModule, - SharedModule, - MatSelectModule, - MatFormFieldModule, - MatSelectSearchModule, - ], - exports: [ - UserDetailComponent, - UserEditComponent, - UserListComponent, - UsersComponent, - UserTableComponent, - PermissionComponent, - PermissionEditComponent, - PermissionDetailComponent, - PermissionListComponent, - PermissionTabelComponent, - OrganisationComponent, - OrganisationTabelComponent, - OrganisationDetailComponent, - OrganisationEditComponent, - OrganisationListComponent, - ApiKeyComponent, - ApiKeyListComponent, - ApiKeyTableComponent, - ApiKeyEditComponent, - ], + declarations: [ + UserDetailComponent, + UserEditComponent, + UserListComponent, + UsersComponent, + UserTableComponent, + PermissionComponent, + PermissionEditComponent, + PermissionDetailComponent, + PermissionListComponent, + PermissionTabelComponent, + OrganisationComponent, + OrganisationTabelComponent, + OrganisationDetailComponent, + OrganisationEditComponent, + OrganisationListComponent, + ApiKeyComponent, + ApiKeyListComponent, + ApiKeyTableComponent, + ApiKeyEditComponent, + AwaitingUsersTableComponent, + AcceptUserComponent, + UserTableTabComponent, + AwaitingUsersTableTabComponent, + ], + imports: [ + AdminRoutingModule, + NGMaterialModule, + PipesModule, + CommonModule, + TranslateModule, + FormsModule, + ReactiveFormsModule, + FormModule, + RouterModule, + ApplicationsModule, + SharedModule, + MatSelectModule, + MatFormFieldModule, + MatSelectSearchModule, + ], + exports: [ + UserDetailComponent, + UserEditComponent, + UserListComponent, + UsersComponent, + UserTableComponent, + PermissionComponent, + PermissionEditComponent, + PermissionDetailComponent, + PermissionListComponent, + PermissionTabelComponent, + OrganisationComponent, + OrganisationTabelComponent, + OrganisationDetailComponent, + OrganisationEditComponent, + OrganisationListComponent, + ApiKeyComponent, + ApiKeyListComponent, + ApiKeyTableComponent, + ApiKeyEditComponent, + ], }) export class AdminModule {} diff --git a/src/app/admin/api-key/api-key-edit/api-key-edit.component.html b/src/app/admin/api-key/api-key-edit/api-key-edit.component.html index 9a90bf142..97df63855 100644 --- a/src/app/admin/api-key/api-key-edit/api-key-edit.component.html +++ b/src/app/admin/api-key/api-key-edit/api-key-edit.component.html @@ -1,66 +1,59 @@
-
-
    -
  • - {{ error | translate }} -
  • -
-
+
+
    +
  • + {{ error | translate }} +
  • +
+
-
-
- * - +
+
+ * + +
-
-
-
- * - - - {{ permission.name }} - - +
+
+ * + + + {{ permission.name }} + + +
-
-
- - -
+
+ + +
diff --git a/src/app/admin/api-key/api-key-edit/api-key-edit.component.ts b/src/app/admin/api-key/api-key-edit/api-key-edit.component.ts index 9c441f75e..bb5c9bece 100644 --- a/src/app/admin/api-key/api-key-edit/api-key-edit.component.ts +++ b/src/app/admin/api-key/api-key-edit/api-key-edit.component.ts @@ -1,128 +1,114 @@ -import { Location } from '@angular/common'; -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { PermissionResponse } from '@app/admin/permission/permission.model'; -import { PermissionService } from '@app/admin/permission/permission.service'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { ApiKeyRequest } from '../api-key.model'; -import { ApiKeyService } from '../api-key.service'; +import { Location } from "@angular/common"; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { PermissionResponse } from "@app/admin/permission/permission.model"; +import { PermissionService } from "@app/admin/permission/permission.service"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { ApiKeyRequest } from "../api-key.model"; +import { ApiKeyService } from "../api-key.service"; @Component({ - selector: 'app-api-key-edit', - templateUrl: './api-key-edit.component.html', - styleUrls: ['./api-key-edit.component.scss'], + selector: "app-api-key-edit", + templateUrl: "./api-key-edit.component.html", + styleUrls: ["./api-key-edit.component.scss"], }) export class ApiKeyEditComponent implements OnInit { - apiKeyRequest = new ApiKeyRequest(); - public backButton: BackButton = { - label: '', - routerLink: ['admin', 'api-key'], - }; - public title = ''; - public submitButton = ''; - public errorMessage: string; - public errorMessages: string[]; - public errorFields: string[]; - public formFailedSubmit = false; - public permissions: PermissionResponse[] = []; - private organizationId: number; - private id: number; + apiKeyRequest = new ApiKeyRequest(); + public backButton: BackButton = { + label: "", + routerLink: ["admin", "api-key"], + }; + public title = ""; + public submitButton = ""; + public errorMessage: string; + public errorMessages: string[]; + public errorFields: string[]; + public formFailedSubmit = false; + public permissions: PermissionResponse[] = []; + private organizationId: number; + private id: number; - constructor( - private translate: TranslateService, - private route: ActivatedRoute, - private location: Location, - private apiKeyService: ApiKeyService, - private permissionService: PermissionService, - private errorMessageService: ErrorMessageService, - private sharedVariableService: SharedVariableService - ) {} + constructor( + private translate: TranslateService, + private route: ActivatedRoute, + private location: Location, + private apiKeyService: ApiKeyService, + private permissionService: PermissionService, + private errorMessageService: ErrorMessageService, + private sharedVariableService: SharedVariableService + ) {} - ngOnInit(): void { - this.getPermissions(); - this.translate.use('da'); - this.translate - .get(['NAV.API-KEY', 'FORM.EDIT-API-KEY', 'API-KEY.EDIT.SAVE']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.API-KEY']; - this.title = translations['FORM.EDIT-API-KEY']; - this.submitButton = translations['API-KEY.EDIT.SAVE']; - }); + ngOnInit(): void { + this.getPermissions(); + this.translate.use("da"); + this.translate.get(["NAV.API-KEY", "FORM.EDIT-API-KEY", "API-KEY.EDIT.SAVE"]).subscribe(translations => { + this.backButton.label = translations["NAV.API-KEY"]; + this.title = translations["FORM.EDIT-API-KEY"]; + this.submitButton = translations["API-KEY.EDIT.SAVE"]; + }); - this.id = +this.route.snapshot.paramMap.get('api-key-id'); + this.id = +this.route.snapshot.paramMap.get("api-key-id"); - if (this.id > 0) { - this.getApiKey(this.id); + if (this.id > 0) { + this.getApiKey(this.id); + } + this.organizationId = this.sharedVariableService.getSelectedOrganisationId(); } - this.organizationId = this.sharedVariableService.getSelectedOrganisationId(); - } - private getPermissions() { - this.permissionService - .getPermissions( - undefined, - undefined, - undefined, - undefined, - undefined, - this.organizationId - ) - .subscribe( - (permissionsResponse) => { - this.permissions = permissionsResponse.data.filter( - (x) => x.organization?.id === this.organizationId - ); - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + private getPermissions() { + this.permissionService + .getPermissions(undefined, undefined, undefined, undefined, undefined, this.organizationId) + .subscribe( + permissionsResponse => { + this.permissions = permissionsResponse.data.filter(x => x.organization?.id === this.organizationId); + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private getApiKey(id: number) { - this.apiKeyService.get(id).subscribe((key) => { - this.apiKeyRequest.id = key.id; - this.apiKeyRequest.name = key.name; - this.apiKeyRequest.permissionIds = key.permissions.map((pm) => pm.id); - }); - } + private getApiKey(id: number) { + this.apiKeyService.get(id).subscribe(key => { + this.apiKeyRequest.id = key.id; + this.apiKeyRequest.name = key.name; + this.apiKeyRequest.permissionIds = key.permissions.map(pm => pm.id); + }); + } - onSubmit(): void { - this.id ? this.update() : this.create(); - } + onSubmit(): void { + this.id ? this.update() : this.create(); + } - private create(): void { - this.apiKeyService.create(this.apiKeyRequest).subscribe( - () => this.routeBack(), - (err) => this.showError(err) - ); - } + private create(): void { + this.apiKeyService.create(this.apiKeyRequest).subscribe( + () => this.routeBack(), + err => this.showError(err) + ); + } - private update(): void { - this.apiKeyService.update(this.apiKeyRequest, this.id).subscribe( - () => this.routeBack(), - (err) => this.showError(err) - ); - } + private update(): void { + this.apiKeyService.update(this.apiKeyRequest, this.id).subscribe( + () => this.routeBack(), + err => this.showError(err) + ); + } - public compare( - matOptionValue: number, - ngModelObject: number - ): boolean { - return matOptionValue === ngModelObject; - } + public compare(matOptionValue: number, ngModelObject: number): boolean { + return matOptionValue === ngModelObject; + } - showError(err: HttpErrorResponse) { - const result = this.errorMessageService.handleErrorMessageWithFields(err); - this.errorFields = result.errorFields; - this.errorMessages = result.errorMessages; - } + showError(err: HttpErrorResponse) { + const result = this.errorMessageService.handleErrorMessageWithFields(err); + this.errorFields = result.errorFields; + this.errorMessages = result.errorMessages; + } - routeBack(): void { - this.location.back(); - } + routeBack(): void { + this.location.back(); + } } diff --git a/src/app/admin/api-key/api-key-list/api-key-list.component.html b/src/app/admin/api-key/api-key-list/api-key-list.component.html index 4960433b4..26b008ba3 100644 --- a/src/app/admin/api-key/api-key-list/api-key-list.component.html +++ b/src/app/admin/api-key/api-key-list/api-key-list.component.html @@ -1,18 +1,16 @@
-
-
-
- -
+
+
+
+ +
+
-
diff --git a/src/app/admin/api-key/api-key-list/api-key-list.component.ts b/src/app/admin/api-key/api-key-list/api-key-list.component.ts index 9fdf53d36..09ca4f49a 100644 --- a/src/app/admin/api-key/api-key-list/api-key-list.component.ts +++ b/src/app/admin/api-key/api-key-list/api-key-list.component.ts @@ -1,33 +1,36 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { TranslateService } from '@ngx-translate/core'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Component, Input, OnInit } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { TranslateService } from "@ngx-translate/core"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-api-key-list', - templateUrl: './api-key-list.component.html', - styleUrls: ['./api-key-list.component.scss'], + selector: "app-api-key-list", + templateUrl: "./api-key-list.component.html", + styleUrls: ["./api-key-list.component.scss"], }) export class ApiKeyListComponent implements OnInit { - @Input() organisationId: number; - canEdit: boolean; + @Input() organisationId: number; + canEdit: boolean; - constructor( - public translate: TranslateService, - private titleService: Title, - private globalService: SharedVariableService, - private meService: MeService - ) { - translate.use('da'); - } + constructor( + public translate: TranslateService, + private titleService: Title, + private globalService: SharedVariableService, + private meService: MeService + ) { + translate.use("da"); + } - ngOnInit(): void { - this.translate.get(['TITLE.API-KEY']).subscribe((translations) => { - this.titleService.setTitle(translations['TITLE.API-KEY']); - }); - this.organisationId = this.globalService.getSelectedOrganisationId(); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite, this.organisationId); - } + ngOnInit(): void { + this.translate.get(["TITLE.API-KEY"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.API-KEY"]); + }); + this.organisationId = this.globalService.getSelectedOrganisationId(); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.UserAdministrationWrite, + this.organisationId + ); + } } diff --git a/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.html b/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.html index 845210be2..94111bbc5 100644 --- a/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.html +++ b/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.html @@ -1,94 +1,85 @@
-
- -
- - - - - - +
+ +
+
- {{ 'API-KEY.NAME' | translate }} - - {{ element.name }} -
+ + + + + - - - - + - {{ 'NoUsersAdded' | translate }} - - - - - - - + + + + + - - - - - + + + + + - - -
+ {{ "API-KEY.NAME" | translate }} + + {{ element.name }} + - {{ 'API-KEY.PERMISSIONS' | translate }} - - - - {{ pm.name }} -
-
+ + +
+ {{ "API-KEY.PERMISSIONS" | translate }} + + + + {{ pm.name }} +
+
+
+ {{ "NoUsersAdded" | translate }} +
- {{ 'API-KEY.KEY' | translate }} - - {{ element.key }} - + {{ "API-KEY.KEY" | translate }} + + {{ element.key }} + - - + +
- - + + + + +
diff --git a/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.ts b/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.ts index 32bf4801b..fcafa1dfc 100644 --- a/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.ts +++ b/src/app/admin/api-key/api-key-list/api-key-table/api-key-table.component.ts @@ -1,115 +1,104 @@ -import { AfterViewInit, Component, Input, ViewChild } from '@angular/core'; -import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { Router } from '@angular/router'; -import { environment } from '@environments/environment'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { MeService } from '@shared/services/me.service'; -import { merge, Observable, of } from 'rxjs'; -import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { ApiKeyGetManyResponse, ApiKeyResponse } from '../../api-key.model'; -import { ApiKeyService } from '../../api-key.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { AfterViewInit, Component, Input, ViewChild } from "@angular/core"; +import { MatPaginator, PageEvent } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { Router } from "@angular/router"; +import { environment } from "@environments/environment"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { MeService } from "@shared/services/me.service"; +import { merge, Observable, of } from "rxjs"; +import { catchError, map, startWith, switchMap } from "rxjs/operators"; +import { ApiKeyGetManyResponse, ApiKeyResponse } from "../../api-key.model"; +import { ApiKeyService } from "../../api-key.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; @Component({ - selector: 'app-api-key-table', - templateUrl: './api-key-table.component.html', - styleUrls: ['./api-key-table.component.scss'], + selector: "app-api-key-table", + templateUrl: "./api-key-table.component.html", + styleUrls: ["./api-key-table.component.scss"], }) export class ApiKeyTableComponent implements AfterViewInit { - @Input() organisationId: number; - displayedColumns: string[] = [ - 'name', - 'permissions', - 'key', - 'menu', - ]; - data: ApiKeyResponse[] = []; - isLoadingResults = true; - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - resultsLength = 0; - public pageSize = environment.tablePageSize; - pageSizeOptions = DefaultPageSizeOptions; + @Input() organisationId: number; + displayedColumns: string[] = ["name", "permissions", "key", "menu"]; + data: ApiKeyResponse[] = []; + isLoadingResults = true; + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + resultsLength = 0; + public pageSize = environment.tablePageSize; + pageSizeOptions = DefaultPageSizeOptions; - constructor( - private meService: MeService, - private router: Router, - private apiKeyService: ApiKeyService, - private deleteDialogService: DeleteDialogService - ) {} + constructor( + private meService: MeService, + private router: Router, + private apiKeyService: ApiKeyService, + private deleteDialogService: DeleteDialogService + ) {} - ngAfterViewInit(): void { - // If the user changes the sort order, reset back to the first page. - this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + ngAfterViewInit(): void { + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); - merge(this.sort.sortChange, this.paginator.page) - .pipe( - startWith({}), - switchMap(() => { - this.isLoadingResults = true; - return this.getApiKeysByOrganisationId( - this.sort.active, - this.sort.direction - ); - }), - map((data) => { - // Flip flag to show that loading has finished. - this.isLoadingResults = false; - this.resultsLength = data.count; + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + return this.getApiKeysByOrganisationId(this.sort.active, this.sort.direction); + }), + map(data => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.resultsLength = data.count; - return data.data; - }), - catchError(() => { - this.isLoadingResults = false; - return of([]); - }) - ) - .subscribe((data) => (this.data = data)); - } + return data.data; + }), + catchError(() => { + this.isLoadingResults = false; + return of([]); + }) + ) + .subscribe(data => (this.data = data)); + } - getApiKeysByOrganisationId( - orderByColumn: string, - orderByDirection: string - ): Observable { - return this.apiKeyService.getApiKeys( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByColumn, - orderByDirection, - null, - this.organisationId - ); - } + getApiKeysByOrganisationId(orderByColumn: string, orderByDirection: string): Observable { + return this.apiKeyService.getApiKeys( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByColumn, + orderByDirection, + null, + this.organisationId + ); + } - canAccess(_element: ApiKeyResponse) { - return this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.UserAdministrationWrite, - this.organisationId - ); - } + canAccess(_element: ApiKeyResponse) { + return this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.UserAdministrationWrite, + this.organisationId + ); + } - routeToPermissions(element: any) { - this.router.navigate(['admin/api-key', element.id]); - } + routeToPermissions(element: any) { + this.router.navigate(["admin/api-key", element.id]); + } - deleteApiKey(id: number) { - this.deleteDialogService.showSimpleDialog().subscribe((response) => { - if (response) { - this.apiKeyService.delete(id).subscribe((response) => { - if (response.ok && response.body.affected > 0) { - this.refresh(); - } + deleteApiKey(id: number) { + this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.apiKeyService.delete(id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + this.refresh(); + } + }); + } }); - } - }); - } + } - private refresh() { - const pageEvent = new PageEvent(); - pageEvent.pageIndex = this.paginator.pageIndex; - pageEvent.pageSize = this.paginator.pageSize; - this.paginator.page.emit(pageEvent); - } + private refresh() { + const pageEvent = new PageEvent(); + pageEvent.pageIndex = this.paginator.pageIndex; + pageEvent.pageSize = this.paginator.pageSize; + this.paginator.page.emit(pageEvent); + } } diff --git a/src/app/admin/api-key/api-key.component.ts b/src/app/admin/api-key/api-key.component.ts index 97c6b2fef..3eb7d6e4d 100644 --- a/src/app/admin/api-key/api-key.component.ts +++ b/src/app/admin/api-key/api-key.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-api-key', - template: '', + selector: "app-api-key", + template: "", }) export class ApiKeyComponent implements OnInit { - constructor() {} + constructor() {} - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/admin/api-key/api-key.model.ts b/src/app/admin/api-key/api-key.model.ts index ed8380f94..6450b3d22 100644 --- a/src/app/admin/api-key/api-key.model.ts +++ b/src/app/admin/api-key/api-key.model.ts @@ -1,23 +1,23 @@ -import { PermissionResponse } from '../permission/permission.model'; +import { PermissionResponse } from "../permission/permission.model"; export class ApiKeyRequest { - id: number; - name: string; - permissionIds?: number[]; + id: number; + name: string; + permissionIds?: number[]; } export interface ApiKeyResponse { - id: number; - name: string; - key: string; - permissions?: PermissionResponse[]; - createdBy: number; - updatedBy: number; - createdByName: string; - updatedByName: string; + id: number; + name: string; + key: string; + permissions?: PermissionResponse[]; + createdBy: number; + updatedBy: number; + createdByName: string; + updatedByName: string; } export interface ApiKeyGetManyResponse { - data: ApiKeyResponse[]; - count: number; + data: ApiKeyResponse[]; + count: number; } diff --git a/src/app/admin/api-key/api-key.service.ts b/src/app/admin/api-key/api-key.service.ts index 87d1c3c8c..cdbb774d7 100644 --- a/src/app/admin/api-key/api-key.service.ts +++ b/src/app/admin/api-key/api-key.service.ts @@ -1,85 +1,74 @@ -import { Injectable } from '@angular/core'; -import { RestService } from '@shared/services/rest.service'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { UserMinimalService } from '../users/user-minimal.service'; -import { - ApiKeyGetManyResponse, - ApiKeyRequest, - ApiKeyResponse, -} from './api-key.model'; +import { Injectable } from "@angular/core"; +import { RestService } from "@shared/services/rest.service"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { UserMinimalService } from "../users/user-minimal.service"; +import { ApiKeyGetManyResponse, ApiKeyRequest, ApiKeyResponse } from "./api-key.model"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class ApiKeyService { - endpoint = 'api-key'; - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + endpoint = "api-key"; + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - create(body: ApiKeyRequest): Observable { - return this.restService.post(this.endpoint, body, { - observe: 'response', - }); - } + create(body: ApiKeyRequest): Observable { + return this.restService.post(this.endpoint, body, { + observe: "response", + }); + } - update(body: ApiKeyRequest, id: number): Observable { - return this.restService.put(this.endpoint, body, id, { - observe: 'response', - }); - } + update(body: ApiKeyRequest, id: number): Observable { + return this.restService.put(this.endpoint, body, id, { + observe: "response", + }); + } - get(id: number): Observable { - return this.restService.get(this.endpoint, {}, id).pipe( - map((response: ApiKeyResponse) => { - response.createdByName = this.userMinimalService.getUserNameFrom( - response.createdBy - ); - response.updatedByName = this.userMinimalService.getUserNameFrom( - response.updatedBy + get(id: number): Observable { + return this.restService.get(this.endpoint, {}, id).pipe( + map((response: ApiKeyResponse) => { + response.createdByName = this.userMinimalService.getUserNameFrom(response.createdBy); + response.updatedByName = this.userMinimalService.getUserNameFrom(response.updatedBy); + return response; + }) ); - return response; - }) - ); - } + } - getApiKeys( - limit: number = 1000, - offset: number = 0, - orderByColumn?: string, - orderByDirection?: string, - userId?: number, - organizationId?: number - ): Observable { - if (userId) { - return this.restService.get(this.endpoint, { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - userId, - }); - } else if (organizationId) { - return this.restService.get(this.endpoint, { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - organizationId, - }); - } else { - return this.restService.get(this.endpoint, { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - }); + getApiKeys( + limit: number = 1000, + offset: number = 0, + orderByColumn?: string, + orderByDirection?: string, + userId?: number, + organizationId?: number + ): Observable { + if (userId) { + return this.restService.get(this.endpoint, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + userId, + }); + } else if (organizationId) { + return this.restService.get(this.endpoint, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + organizationId, + }); + } else { + return this.restService.get(this.endpoint, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } } - } - delete(id: number) { - return this.restService.delete(this.endpoint, id); - } + delete(id: number) { + return this.restService.delete(this.endpoint, id); + } } diff --git a/src/app/admin/organisation/organisation-detail/organisation-detail.component.html b/src/app/admin/organisation/organisation-detail/organisation-detail.component.html index 0f7fac379..612612596 100644 --- a/src/app/admin/organisation/organisation-detail/organisation-detail.component.html +++ b/src/app/admin/organisation/organisation-detail/organisation-detail.component.html @@ -1,19 +1,19 @@
-
+
-

{{'ORGANISATION.HEADLINE' | translate}}

+

{{ "ORGANISATION.HEADLINE" | translate }}

@@ -22,10 +22,9 @@

{{'ORGANISATION.HEADLINE' | translate}}

- {{ 'ORGANISATION.DETAIL.APPLICATIONS' | translate }} + {{ "ORGANISATION.DETAIL.APPLICATIONS" | translate }}

- - +
@@ -33,10 +32,9 @@

- {{ 'ORGANISATION.DETAIL.PERMISSIONS' | translate }} + {{ "ORGANISATION.DETAIL.PERMISSIONS" | translate }}

- - +

diff --git a/src/app/admin/organisation/organisation-detail/organisation-detail.component.spec.ts b/src/app/admin/organisation/organisation-detail/organisation-detail.component.spec.ts index a6abf45c4..4be100065 100644 --- a/src/app/admin/organisation/organisation-detail/organisation-detail.component.spec.ts +++ b/src/app/admin/organisation/organisation-detail/organisation-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OrganisationDetailComponent } from './organisation-detail.component'; +import { OrganisationDetailComponent } from "./organisation-detail.component"; -describe('OrganisationDetailComponent', () => { - let component: OrganisationDetailComponent; - let fixture: ComponentFixture; +describe("OrganisationDetailComponent", () => { + let component: OrganisationDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OrganisationDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OrganisationDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OrganisationDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OrganisationDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/organisation/organisation-detail/organisation-detail.component.ts b/src/app/admin/organisation/organisation-detail/organisation-detail.component.ts index 737aa23e1..8add4d9d3 100644 --- a/src/app/admin/organisation/organisation-detail/organisation-detail.component.ts +++ b/src/app/admin/organisation/organisation-detail/organisation-detail.component.ts @@ -1,130 +1,124 @@ -import { Component, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; +import { Component, OnChanges, OnDestroy, OnInit, SimpleChanges } from "@angular/core"; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { Subscription } from 'rxjs'; -import { Application } from '@applications/application.model'; -import { OrganisationService } from '@app/admin/organisation/organisation.service'; -import { OrganisationResponse } from '../organisation.model'; -import { BackButton } from '@shared/models/back-button.model'; -import { PermissionResponse } from '@app/admin/permission/permission.model'; -import { PermissionService } from '@app/admin/permission/permission.service'; -import { Location } from '@angular/common'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { ApplicationService } from '@applications/application.service'; -import { environment } from '@environments/environment'; -import { Title } from '@angular/platform-browser'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { Subscription } from "rxjs"; +import { Application } from "@applications/application.model"; +import { OrganisationService } from "@app/admin/organisation/organisation.service"; +import { OrganisationResponse } from "../organisation.model"; +import { BackButton } from "@shared/models/back-button.model"; +import { PermissionResponse } from "@app/admin/permission/permission.model"; +import { PermissionService } from "@app/admin/permission/permission.service"; +import { Location } from "@angular/common"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { ApplicationService } from "@applications/application.service"; +import { environment } from "@environments/environment"; +import { Title } from "@angular/platform-browser"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-organisation-detail', - templateUrl: './organisation-detail.component.html', - styleUrls: ['./organisation-detail.component.scss'], + selector: "app-organisation-detail", + templateUrl: "./organisation-detail.component.html", + styleUrls: ["./organisation-detail.component.scss"], }) export class OrganisationDetailComponent implements OnInit, OnChanges, OnDestroy { - isLoadingResults = true; - resultsLength = 10; + isLoadingResults = true; + resultsLength = 10; - public pageLimit = environment.tablePageSize; - public pageTotal: number; - public pageOffset = 0; - public applications: Application[]; - private applicationsSubscription: Subscription; - private deleteDialogSubscription: Subscription; - public dropdownButton: DropdownButton; + public pageLimit = environment.tablePageSize; + public pageTotal: number; + public pageOffset = 0; + public applications: Application[]; + private applicationsSubscription: Subscription; + private deleteDialogSubscription: Subscription; + public dropdownButton: DropdownButton; - organisation: OrganisationResponse; - public backButton: BackButton = { - label: '', - routerLink: '/admin/organisations', - }; - id: number; - subscription: Subscription; - permissions: PermissionResponse[]; - canEdit: boolean; - - constructor( - public translate: TranslateService, - private route: ActivatedRoute, - private organisationService: OrganisationService, - private permissionsService: PermissionService, - private deleteDialogService: DeleteDialogService, - private location: Location, - private titleService: Title, - private meService: MeService - ) { } + organisation: OrganisationResponse; + public backButton: BackButton = { + label: "", + routerLink: "/admin/organisations", + }; + id: number; + subscription: Subscription; + permissions: PermissionResponse[]; + canEdit: boolean; - ngOnChanges(changes: SimpleChanges): void { - } + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + private organisationService: OrganisationService, + private permissionsService: PermissionService, + private deleteDialogService: DeleteDialogService, + private location: Location, + private titleService: Title, + private meService: MeService + ) {} - ngOnInit(): void { - this.translate.use('da'); - this.id = +this.route.snapshot.paramMap.get('org-id'); - if (this.id > 0) { - this.getOrganisation(this.id); - } - this.dropdownButton = { - label: '', - editRouterLink: 'edit-organisation', - isErasable: true, - }; + ngOnChanges(changes: SimpleChanges): void {} - this.translate.get(['NAV.ORGANISATIONS', 'ORGANISATION.DROPDOWN', 'TITLE.ORGANIZATION']) - .subscribe(translations => { - this.backButton.label = translations['NAV.ORGANISATIONS']; - this.dropdownButton.label = translations['ORGANISATION.DROPDOWN']; - this.titleService.setTitle(translations['TITLE.ORGANIZATION']); - }); + ngOnInit(): void { + this.translate.use("da"); + this.id = +this.route.snapshot.paramMap.get("org-id"); + if (this.id > 0) { + this.getOrganisation(this.id); + } + this.dropdownButton = { + label: "", + editRouterLink: "edit-organisation", + isErasable: true, + }; - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); - } + this.translate + .get(["NAV.ORGANISATIONS", "ORGANISATION.DROPDOWN", "TITLE.ORGANIZATION"]) + .subscribe(translations => { + this.backButton.label = translations["NAV.ORGANISATIONS"]; + this.dropdownButton.label = translations["ORGANISATION.DROPDOWN"]; + this.titleService.setTitle(translations["TITLE.ORGANIZATION"]); + }); - ngOnDestroy() { - // prevent memory leak by unsubscribing - if (this.applicationsSubscription) { - this.applicationsSubscription.unsubscribe(); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); } - if (this.deleteDialogSubscription) { - this.deleteDialogSubscription.unsubscribe(); + + ngOnDestroy() { + // prevent memory leak by unsubscribing + if (this.applicationsSubscription) { + this.applicationsSubscription.unsubscribe(); + } + if (this.deleteDialogSubscription) { + this.deleteDialogSubscription.unsubscribe(); + } } - } - private getOrganisation(id: number) { - this.subscription = this.organisationService - .getOne(id) - .subscribe((response) => { - this.organisation = response; - this.permissions = response.permissions; - }); - } + private getOrganisation(id: number) { + this.subscription = this.organisationService.getOne(id).subscribe(response => { + this.organisation = response; + this.permissions = response.permissions; + }); + } - clickDelete() { - this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe( - (response) => { - if (response) { - this.organisationService.delete(this.organisation.id) - .subscribe( - (response) => { - this.location.back(); - }); - } else { - console.log(response); - } - } - ); - } + clickDelete() { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.organisationService.delete(this.organisation.id).subscribe(response => { + this.location.back(); + }); + } else { + console.log(response); + } + }); + } - deletePermission(id: number) { - this.deleteDialogService.showSimpleDialog().subscribe((response) => { - if (response) { - this.permissionsService.deletePermission(id).subscribe((response) => { - if (response.ok && response.body.affected > 0) { - this.getOrganisation(this.id); - } + deletePermission(id: number) { + this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.permissionsService.deletePermission(id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + this.getOrganisation(this.id); + } + }); + } }); - } - }); - } + } } diff --git a/src/app/admin/organisation/organisation-edit/organisation-edit.component.html b/src/app/admin/organisation/organisation-edit/organisation-edit.component.html index b462a41fc..6c4dbb391 100644 --- a/src/app/admin/organisation/organisation-edit/organisation-edit.component.html +++ b/src/app/admin/organisation/organisation-edit/organisation-edit.component.html @@ -1,22 +1,34 @@
-
- {{errorMessage | translate}} -
+
+ {{ errorMessage | translate }} +
-
-
- * - +
+
+ * + +
-
-
- - -
- \ No newline at end of file +
+ + +
+ diff --git a/src/app/admin/organisation/organisation-edit/organisation-edit.component.spec.ts b/src/app/admin/organisation/organisation-edit/organisation-edit.component.spec.ts index bf9d76632..c3ec9f4eb 100644 --- a/src/app/admin/organisation/organisation-edit/organisation-edit.component.spec.ts +++ b/src/app/admin/organisation/organisation-edit/organisation-edit.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OrganisationEditComponent } from './organisation-edit.component'; +import { OrganisationEditComponent } from "./organisation-edit.component"; -describe('OrganisationEditComponent', () => { - let component: OrganisationEditComponent; - let fixture: ComponentFixture; +describe("OrganisationEditComponent", () => { + let component: OrganisationEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OrganisationEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OrganisationEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OrganisationEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OrganisationEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/organisation/organisation-edit/organisation-edit.component.ts b/src/app/admin/organisation/organisation-edit/organisation-edit.component.ts index c3ee99346..a8e3a35d7 100644 --- a/src/app/admin/organisation/organisation-edit/organisation-edit.component.ts +++ b/src/app/admin/organisation/organisation-edit/organisation-edit.component.ts @@ -1,111 +1,109 @@ -import { Component, OnInit } from '@angular/core'; -import { OrganisationService } from '@app/admin/organisation/organisation.service'; -import { HttpErrorResponse } from '@angular/common/http'; -import { UntypedFormGroup } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { Subscription } from 'rxjs'; -import { Location } from '@angular/common'; -import { Organisation } from '../organisation.model'; -import { BackButton } from '@shared/models/back-button.model'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; +import { Component, OnInit } from "@angular/core"; +import { OrganisationService } from "@app/admin/organisation/organisation.service"; +import { HttpErrorResponse } from "@angular/common/http"; +import { UntypedFormGroup } from "@angular/forms"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { Subscription } from "rxjs"; +import { Location } from "@angular/common"; +import { Organisation } from "../organisation.model"; +import { BackButton } from "@shared/models/back-button.model"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; @Component({ - selector: 'app-organisation-edit', - templateUrl: './organisation-edit.component.html', - styleUrls: ['./organisation-edit.component.scss'], + selector: "app-organisation-edit", + templateUrl: "./organisation-edit.component.html", + styleUrls: ["./organisation-edit.component.scss"], }) export class OrganisationEditComponent implements OnInit { - organisation = new Organisation(); - public errorMessage: string; - public errorFields: string[]; - public formFailedSubmit = false; - public form: UntypedFormGroup; - public backButton: BackButton = { label: '', routerLink: '/admin/organisations' }; - public title = ''; - public submitButton = ''; - id: number; - subscription: Subscription; + organisation = new Organisation(); + public errorMessage: string; + public errorFields: string[]; + public formFailedSubmit = false; + public form: UntypedFormGroup; + public backButton: BackButton = { label: "", routerLink: "/admin/organisations" }; + public title = ""; + public submitButton = ""; + id: number; + subscription: Subscription; - constructor( - private translate: TranslateService, - private route: ActivatedRoute, - private organisationService: OrganisationService, - private location: Location, - private sharedVariableService: SharedVariableService - ) { } + constructor( + private translate: TranslateService, + private route: ActivatedRoute, + private organisationService: OrganisationService, + private location: Location, + private sharedVariableService: SharedVariableService + ) {} - ngOnInit(): void { - this.translate.use('da'); - this.translate - .get(['NAV.ORGANISATIONS', 'FORM.EDIT-ORGANISATION', 'ORGANISATION.SAVE']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.ORGANISATIONS']; - this.title = translations['FORM.EDIT-ORGANISATION']; - this.submitButton = translations['ORGANISATION.SAVE']; - }); - this.id = +this.route.snapshot.paramMap.get('org-id'); - if (this.id > 0) { - this.getOrganisation(this.id); - this.setBackButton(this.id.toString()); + ngOnInit(): void { + this.translate.use("da"); + this.translate + .get(["NAV.ORGANISATIONS", "FORM.EDIT-ORGANISATION", "ORGANISATION.SAVE"]) + .subscribe(translations => { + this.backButton.label = translations["NAV.ORGANISATIONS"]; + this.title = translations["FORM.EDIT-ORGANISATION"]; + this.submitButton = translations["ORGANISATION.SAVE"]; + }); + this.id = +this.route.snapshot.paramMap.get("org-id"); + if (this.id > 0) { + this.getOrganisation(this.id); + this.setBackButton(this.id.toString()); + } } - } - setBackButton(organizationId: string) { - this.backButton.routerLink = ['admin','organisations', organizationId]; - } + setBackButton(organizationId: string) { + this.backButton.routerLink = ["admin", "organisations", organizationId]; + } - private getOrganisation(id: number) { - this.subscription = this.organisationService - .getOne(id) - .subscribe((response) => { - this.organisation = response; - }); - } + private getOrganisation(id: number) { + this.subscription = this.organisationService.getOne(id).subscribe(response => { + this.organisation = response; + }); + } - private create(): void { - this.organisationService.post(this.organisation).subscribe( - (response) => { - console.log(response); - this.sharedVariableService.setOrganizationInfo(); - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + private create(): void { + this.organisationService.post(this.organisation).subscribe( + response => { + console.log(response); + this.sharedVariableService.setOrganizationInfo(); + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private update(): void { - this.organisationService.put(this.organisation, this.id).subscribe( - (response) => { - this.sharedVariableService.setOrganizationInfo(); - this.routeBack(); - }, - (error) => { - this.showError(error); - } - ); - } + private update(): void { + this.organisationService.put(this.organisation, this.id).subscribe( + response => { + this.sharedVariableService.setOrganizationInfo(); + this.routeBack(); + }, + error => { + this.showError(error); + } + ); + } - onSubmit(): void { - if (this.organisation.id) { - this.update(); - } else { - this.create(); + onSubmit(): void { + if (this.organisation.id) { + this.update(); + } else { + this.create(); + } } - } - private showError(error: HttpErrorResponse) { - this.errorFields = []; - this.errorMessage = ''; + private showError(error: HttpErrorResponse) { + this.errorFields = []; + this.errorMessage = ""; - this.errorMessage = error.error.message; - this.errorFields.push('name'); - this.formFailedSubmit = true; - } + this.errorMessage = error.error.message; + this.errorFields.push("name"); + this.formFailedSubmit = true; + } - routeBack(): void { - this.location.back(); - } + routeBack(): void { + this.location.back(); + } } diff --git a/src/app/admin/organisation/organisation-list/organisation-list.component.html b/src/app/admin/organisation/organisation-list/organisation-list.component.html index d1b269ec0..c969a1eb6 100644 --- a/src/app/admin/organisation/organisation-list/organisation-list.component.html +++ b/src/app/admin/organisation/organisation-list/organisation-list.component.html @@ -1,5 +1,9 @@ - +
diff --git a/src/app/admin/organisation/organisation-list/organisation-list.component.spec.ts b/src/app/admin/organisation/organisation-list/organisation-list.component.spec.ts index baeacaeb0..e37d60700 100644 --- a/src/app/admin/organisation/organisation-list/organisation-list.component.spec.ts +++ b/src/app/admin/organisation/organisation-list/organisation-list.component.spec.ts @@ -1,24 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OrganisationListComponent } from './organisation-list.component'; +import { OrganisationListComponent } from "./organisation-list.component"; -describe('OrganisationListComponent', () => { - let component: OrganisationListComponent; - let fixture: ComponentFixture; +describe("OrganisationListComponent", () => { + let component: OrganisationListComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [OrganisationListComponent], - }).compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OrganisationListComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OrganisationListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OrganisationListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/organisation/organisation-list/organisation-list.component.ts b/src/app/admin/organisation/organisation-list/organisation-list.component.ts index 0fe174476..a5380d45e 100644 --- a/src/app/admin/organisation/organisation-list/organisation-list.component.ts +++ b/src/app/admin/organisation/organisation-list/organisation-list.component.ts @@ -1,29 +1,25 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { TranslateService } from '@ngx-translate/core'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Component, OnInit } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { TranslateService } from "@ngx-translate/core"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-organisation-list', - templateUrl: './organisation-list.component.html', - styleUrls: ['./organisation-list.component.scss'], + selector: "app-organisation-list", + templateUrl: "./organisation-list.component.html", + styleUrls: ["./organisation-list.component.scss"], }) export class OrganisationListComponent implements OnInit { - canEdit: boolean; + canEdit: boolean; - constructor( - public translate: TranslateService, - private titleService: Title, - private meService: MeService - ) { - translate.use('da'); - } + constructor(public translate: TranslateService, private titleService: Title, private meService: MeService) { + translate.use("da"); + } - ngOnInit(): void { - this.translate.get(['TITLE.ORGANIZATION']).subscribe((translations) => { - this.titleService.setTitle(translations['TITLE.ORGANIZATION']); - }); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); - } + ngOnInit(): void { + this.translate.get(["TITLE.ORGANIZATION"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.ORGANIZATION"]); + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); + } } diff --git a/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.html b/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.html index f25d447bd..0f93cce5d 100644 --- a/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.html +++ b/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.html @@ -3,25 +3,26 @@
- + {{ "ORGANISATION.APPLICATION-COUNT" | translate }} + - +
- {{ 'ORGANISATION.NAME' | translate }} + {{ "ORGANISATION.NAME" | translate }} - {{element.name}} + {{ element.name }} - {{ 'ORGANISATION.APPLICATION-COUNT' | translate }}
- {{element.applications.length}} + {{ element.applications.length }}
Ingen applikationer er tilknyttet endnu
@@ -33,20 +34,28 @@
-
- +
diff --git a/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.spec.ts b/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.spec.ts index d6ea50fca..33673a002 100644 --- a/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.spec.ts +++ b/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OrganisationTabelComponent } from './organisation-tabel.component'; +import { OrganisationTabelComponent } from "./organisation-tabel.component"; -describe('OrganisationTabelComponent', () => { - let component: OrganisationTabelComponent; - let fixture: ComponentFixture; +describe("OrganisationTabelComponent", () => { + let component: OrganisationTabelComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OrganisationTabelComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OrganisationTabelComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OrganisationTabelComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OrganisationTabelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.ts b/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.ts index 0d9143351..125d45468 100644 --- a/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.ts +++ b/src/app/admin/organisation/organisation-list/organisation-tabel/organisation-tabel.component.ts @@ -1,24 +1,21 @@ -import { AfterViewInit, Component, Input, ViewChild } from '@angular/core'; -import { OrganisationService } from '@app/admin/organisation/organisation.service'; -import { - OrganisationGetManyResponse, - OrganisationResponse, -} from '../../organisation.model'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { MatSort } from '@angular/material/sort'; -import { merge, Observable, of as observableOf } from 'rxjs'; -import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { environment } from '@environments/environment'; -import { startWith, switchMap, map, catchError } from 'rxjs/operators'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { AfterViewInit, Component, Input, ViewChild } from "@angular/core"; +import { OrganisationService } from "@app/admin/organisation/organisation.service"; +import { OrganisationGetManyResponse, OrganisationResponse } from "../../organisation.model"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { MatSort } from "@angular/material/sort"; +import { merge, Observable, of as observableOf } from "rxjs"; +import { MatPaginator, PageEvent } from "@angular/material/paginator"; +import { environment } from "@environments/environment"; +import { startWith, switchMap, map, catchError } from "rxjs/operators"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; @Component({ - selector: 'app-organisation-tabel', - templateUrl: './organisation-tabel.component.html', - styleUrls: ['./organisation-tabel.component.scss'], + selector: "app-organisation-tabel", + templateUrl: "./organisation-tabel.component.html", + styleUrls: ["./organisation-tabel.component.scss"], }) export class OrganisationTabelComponent implements AfterViewInit { - displayedColumns: string[] = ['name', 'applications', 'menu']; + displayedColumns: string[] = ["name", "applications", "menu"]; data: OrganisationResponse[]; @@ -34,10 +31,7 @@ export class OrganisationTabelComponent implements AfterViewInit { isLoadingResults = true; - constructor( - private organisationService: OrganisationService, - private deleteDialogService: DeleteDialogService - ) {} + constructor(private organisationService: OrganisationService, private deleteDialogService: DeleteDialogService) {} ngAfterViewInit() { // If the user changes the sort order, reset back to the first page. @@ -48,12 +42,9 @@ export class OrganisationTabelComponent implements AfterViewInit { startWith({}), switchMap(() => { this.isLoadingResults = true; - return this.getOrganisations( - this.sort.active, - this.sort.direction - ); + return this.getOrganisations(this.sort.active, this.sort.direction); }), - map((data) => { + map(data => { // Flip flag to show that loading has finished. this.isLoadingResults = false; this.resultsLength = data.count; @@ -65,13 +56,10 @@ export class OrganisationTabelComponent implements AfterViewInit { return observableOf([]); }) ) - .subscribe((data) => (this.data = data)); + .subscribe(data => (this.data = data)); } - getOrganisations( - orderByColumn: string, - orderByDirection: string - ): Observable { + getOrganisations(orderByColumn: string, orderByDirection: string): Observable { return this.organisationService.getMultiple( this.paginator.pageSize, this.paginator.pageIndex * this.paginator.pageSize, @@ -81,15 +69,13 @@ export class OrganisationTabelComponent implements AfterViewInit { } clickDelete(element: any) { - this.deleteDialogService.showSimpleDialog().subscribe((response) => { + this.deleteDialogService.showSimpleDialog().subscribe(response => { if (response) { - this.organisationService - .delete(element.id) - .subscribe((response) => { - if (response.ok) { - this.refresh(); - } - }); + this.organisationService.delete(element.id).subscribe(response => { + if (response.ok) { + this.refresh(); + } + }); } else { console.log(response); } diff --git a/src/app/admin/organisation/organisation.component.html b/src/app/admin/organisation/organisation.component.html index 90c6b6463..0680b43f9 100644 --- a/src/app/admin/organisation/organisation.component.html +++ b/src/app/admin/organisation/organisation.component.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/app/admin/organisation/organisation.component.ts b/src/app/admin/organisation/organisation.component.ts index b512d4d8d..00151f4af 100644 --- a/src/app/admin/organisation/organisation.component.ts +++ b/src/app/admin/organisation/organisation.component.ts @@ -1,15 +1,15 @@ -import { Component, OnInit } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, OnInit } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; @Component({ - selector: 'app-organisation', - templateUrl: './organisation.component.html', - styleUrls: ['./organisation.component.scss'], + selector: "app-organisation", + templateUrl: "./organisation.component.html", + styleUrls: ["./organisation.component.scss"], }) export class OrganisationComponent implements OnInit { - constructor(public translate: TranslateService) { - translate.use('da'); - } + constructor(public translate: TranslateService) { + translate.use("da"); + } - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/admin/organisation/organisation.model.ts b/src/app/admin/organisation/organisation.model.ts index fdf05791f..bf0a85639 100644 --- a/src/app/admin/organisation/organisation.model.ts +++ b/src/app/admin/organisation/organisation.model.ts @@ -1,34 +1,34 @@ -import { Application } from '@applications/application.model'; -import { PayloadDecoder } from '../../payload-decoder/payload-decoder.model'; -import { PermissionResponse } from '../permission/permission.model'; +import { Application } from "@applications/application.model"; +import { PayloadDecoder } from "../../payload-decoder/payload-decoder.model"; +import { PermissionResponse } from "../permission/permission.model"; export class Organisation { - id?: number; - name: string; + id?: number; + name: string; } export interface OrganisationResponse { - id: number; - createdAt: string; - updatedAt: string; - createdBy: number; - updatedBy: number; - createdByName: string; - updatedByName: string; - name: string; - openDataDkRegistered: boolean; + id: number; + createdAt: string; + updatedAt: string; + createdBy: number; + updatedBy: number; + createdByName: string; + updatedByName: string; + name: string; + openDataDkRegistered: boolean; - payloadDecoders: PayloadDecoder[]; - applications: Application[]; - permissions: PermissionResponse[]; + payloadDecoders: PayloadDecoder[]; + applications: Application[]; + permissions: PermissionResponse[]; } export interface OrganisationGetManyResponse { - data: OrganisationResponse[]; - count: number; + data: OrganisationResponse[]; + count: number; } export interface OrganisationGetMinimalResponse { - data: Organisation[]; - count: number; + data: Organisation[]; + count: number; } diff --git a/src/app/admin/organisation/organisation.service.ts b/src/app/admin/organisation/organisation.service.ts index c350f2f03..9709ac779 100644 --- a/src/app/admin/organisation/organisation.service.ts +++ b/src/app/admin/organisation/organisation.service.ts @@ -1,76 +1,69 @@ -import { Injectable } from '@angular/core'; -import { RestService } from '../../shared/services/rest.service'; -import { Observable } from 'rxjs'; +import { Injectable } from "@angular/core"; +import { RestService } from "../../shared/services/rest.service"; +import { Observable } from "rxjs"; import { - Organisation, - OrganisationResponse, - OrganisationGetManyResponse, - OrganisationGetMinimalResponse, -} from './organisation.model'; -import { map, shareReplay } from 'rxjs/operators'; -import { UserMinimalService } from '../users/user-minimal.service'; -import { UpdateUserOrgsDto } from '../users/user.model'; + Organisation, + OrganisationResponse, + OrganisationGetManyResponse, + OrganisationGetMinimalResponse, +} from "./organisation.model"; +import { map, shareReplay } from "rxjs/operators"; +import { UserMinimalService } from "../users/user-minimal.service"; +import { UpdateUserOrgsDto } from "../users/user.model"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class OrganisationService { - URL = 'organization'; - URLMINIMAL = 'organization/minimal'; - URLMINIMAL_NEWKOMBIT = 'kombitCreation/minimal'; + URL = "organization"; + URLMINIMAL = "organization/minimal"; + URLMINIMAL_NEWKOMBIT = "kombitCreation/minimal"; - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - post(body: Organisation): Observable { - return this.restService.post(this.URL, body); - } + post(body: Organisation): Observable { + return this.restService.post(this.URL, body); + } - put(body: Organisation, id: number): Observable { - return this.restService.put(this.URL, body, id, { - observe: 'response', - }); - } + put(body: Organisation, id: number): Observable { + return this.restService.put(this.URL, body, id, { + observe: "response", + }); + } - getOne(id: number): Observable { - return this.restService.get(this.URL, {}, id).pipe( - map((response: OrganisationResponse) => { - response.createdByName = this.userMinimalService.getUserNameFrom( - response.createdBy + getOne(id: number): Observable { + return this.restService.get(this.URL, {}, id).pipe( + map((response: OrganisationResponse) => { + response.createdByName = this.userMinimalService.getUserNameFrom(response.createdBy); + response.updatedByName = this.userMinimalService.getUserNameFrom(response.updatedBy); + return response; + }) ); - response.updatedByName = this.userMinimalService.getUserNameFrom( - response.updatedBy - ); - return response; - }) - ); - } + } - getMinimal(): Observable { - return this.restService.get(this.URLMINIMAL, {}).pipe(shareReplay(1)); - } + getMinimal(): Observable { + return this.restService.get(this.URLMINIMAL, {}).pipe(shareReplay(1)); + } - getMinimalNoPerm(): Observable { - return this.restService.get(this.URLMINIMAL_NEWKOMBIT, {}).pipe(shareReplay(1)); - } + getMinimalNoPerm(): Observable { + return this.restService.get(this.URLMINIMAL_NEWKOMBIT, {}).pipe(shareReplay(1)); + } - getMultiple( - limit: number = 1000, - offset: number = 0, - orderByColumn?: string, - orderByDirection?: string - ): Observable { - return this.restService.get(this.URL, { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - }); - } + getMultiple( + limit: number = 1000, + offset: number = 0, + orderByColumn?: string, + orderByDirection?: string + ): Observable { + return this.restService.get(this.URL, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } - delete(id: number) { - return this.restService.delete(this.URL, id); - } + delete(id: number) { + return this.restService.delete(this.URL, id); + } } diff --git a/src/app/admin/permission/permission-detail/permission-detail.component.html b/src/app/admin/permission/permission-detail/permission-detail.component.html index 5bd2decaa..16917edd6 100644 --- a/src/app/admin/permission/permission-detail/permission-detail.component.html +++ b/src/app/admin/permission/permission-detail/permission-detail.component.html @@ -1,18 +1,28 @@
- +
-
-

{{'PERMISSION.DETAIL.HEADLINE' | translate}}

+
+

{{ "PERMISSION.DETAIL.HEADLINE" | translate }}

-

{{'PERMISSION.DETAIL.TYPE' | translate}}{{permission.type | translatePermissions}}

-

{{'PERMISSION.DETAIL.ORG' | translate}} - {{permission.organization?.name}} +

+ {{ "PERMISSION.DETAIL.TYPE" | translate }}{{ permission.type | translatePermissions }} +

+

+ {{ "PERMISSION.DETAIL.ORG" | translate }} + {{ permission.organization?.name }}

-
@@ -20,7 +30,7 @@

{{'PERMISSION.DETAIL.HEADLINE' | translate}}

- {{ 'PERMISSION.DETAIL.USERS' | translate }} + {{ "PERMISSION.DETAIL.USERS" | translate }}

@@ -30,10 +40,13 @@

- {{ 'PERMISSION.DETAIL.APPLICATIONS' | translate }} + {{ "PERMISSION.DETAIL.APPLICATIONS" | translate }}

- +

diff --git a/src/app/admin/permission/permission-detail/permission-detail.component.spec.ts b/src/app/admin/permission/permission-detail/permission-detail.component.spec.ts index 52317fac0..f2d3e888d 100644 --- a/src/app/admin/permission/permission-detail/permission-detail.component.spec.ts +++ b/src/app/admin/permission/permission-detail/permission-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { PermissionDetailComponent } from './permission-detail.component'; +import { PermissionDetailComponent } from "./permission-detail.component"; -describe('PermissionDetailComponent', () => { - let component: PermissionDetailComponent; - let fixture: ComponentFixture; +describe("PermissionDetailComponent", () => { + let component: PermissionDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ PermissionDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PermissionDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(PermissionDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(PermissionDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/permission/permission-detail/permission-detail.component.ts b/src/app/admin/permission/permission-detail/permission-detail.component.ts index ef2bde9a3..6d77c36a6 100644 --- a/src/app/admin/permission/permission-detail/permission-detail.component.ts +++ b/src/app/admin/permission/permission-detail/permission-detail.component.ts @@ -1,116 +1,114 @@ -import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { PermissionService } from '@app/admin/permission/permission.service'; -import { Subscription } from 'rxjs'; -import { PermissionResponse, PermissionType } from '../permission.model'; -import { BackButton } from '@shared/models/back-button.model'; -import { QuickActionButton } from '@shared/models/quick-action-button.model'; -import { UserResponse } from '@app/admin/users/user.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { environment } from '@environments/environment'; -import { Title } from '@angular/platform-browser'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; - +import { Component, OnChanges, OnInit, SimpleChanges } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { PermissionService } from "@app/admin/permission/permission.service"; +import { Subscription } from "rxjs"; +import { PermissionResponse, PermissionType } from "../permission.model"; +import { BackButton } from "@shared/models/back-button.model"; +import { QuickActionButton } from "@shared/models/quick-action-button.model"; +import { UserResponse } from "@app/admin/users/user.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { environment } from "@environments/environment"; +import { Title } from "@angular/platform-browser"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-permission-detail', - templateUrl: './permission-detail.component.html', - styleUrls: ['./permission-detail.component.scss'] + selector: "app-permission-detail", + templateUrl: "./permission-detail.component.html", + styleUrls: ["./permission-detail.component.scss"], }) export class PermissionDetailComponent implements OnInit, OnChanges { - isLoadingResults = true; - public pageLimit: number = environment.tablePageSize; - public pageTotal: number; - public pageOffset = 0; - permission: PermissionResponse; - permissions: PermissionResponse[]; - public backButton: BackButton = { - label: '', - routerLink: '/admin/permissions', - }; - public buttons: QuickActionButton[] = [ - { - label: 'PERMISSIONS.DELETE', - type: 'delete', - }, - { - label: 'PERMISSIONS.EDIT', - type: 'edit', - }, - ]; - id: number; - subscription: Subscription; - users: UserResponse[]; - dropdownButton: DropdownButton; - canEdit: boolean; - showApplicationTable = false; + isLoadingResults = true; + public pageLimit: number = environment.tablePageSize; + public pageTotal: number; + public pageOffset = 0; + permission: PermissionResponse; + permissions: PermissionResponse[]; + public backButton: BackButton = { + label: "", + routerLink: "/admin/permissions", + }; + public buttons: QuickActionButton[] = [ + { + label: "PERMISSIONS.DELETE", + type: "delete", + }, + { + label: "PERMISSIONS.EDIT", + type: "edit", + }, + ]; + id: number; + subscription: Subscription; + users: UserResponse[]; + dropdownButton: DropdownButton; + canEdit: boolean; + showApplicationTable = false; - constructor( - public translate: TranslateService, - private route: ActivatedRoute, - private permissionService: PermissionService, - private router: Router, - private titleService: Title, - private deleteDialogService: DeleteDialogService, - private meService: MeService - ) { } + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + private permissionService: PermissionService, + private router: Router, + private titleService: Title, + private deleteDialogService: DeleteDialogService, + private meService: MeService + ) {} - ngOnInit(): void { - this.translate.use('da'); - this.id = +this.route.snapshot.paramMap.get('permission-id'); - if (this.id > 0) { - this.getPermission(this.id); - this.dropdownButton = { - label: '', - editRouterLink: 'edit-permission', - isErasable: true, - }; + ngOnInit(): void { + this.translate.use("da"); + this.id = +this.route.snapshot.paramMap.get("permission-id"); + if (this.id > 0) { + this.getPermission(this.id); + this.dropdownButton = { + label: "", + editRouterLink: "edit-permission", + isErasable: true, + }; + } + this.translate + .get(["NAV.PERMISSIONS", "PERMISSION.DETAIL.DROPDOWN", "TITLE.PERMISSION"]) + .subscribe(translations => { + this.backButton.label = translations["NAV.PERMISSIONS"]; + this.dropdownButton.label = translations["PERMISSION.DETAIL.DROPDOWN"]; + this.titleService.setTitle(translations["TITLE.PERMISSION"]); + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); } - this.translate.get(['NAV.PERMISSIONS', 'PERMISSION.DETAIL.DROPDOWN', 'TITLE.PERMISSION']) - .subscribe(translations => { - this.backButton.label = translations['NAV.PERMISSIONS']; - this.dropdownButton.label = translations['PERMISSION.DETAIL.DROPDOWN']; - this.titleService.setTitle(translations['TITLE.PERMISSION']); - }); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); - } - ngOnChanges(changes: SimpleChanges): void { - this.getPermission(this.id); - } + ngOnChanges(changes: SimpleChanges): void { + this.getPermission(this.id); + } - private getPermission(id: number) { - this.subscription = this.permissionService - .getPermission(id) - .subscribe((response) => { - this.permission = response; - this.users = response.users; - this.showApplicationTable = this.meService.hasPermissions( - response, - PermissionType.Read, - PermissionType.OrganizationApplicationAdmin, - PermissionType.GlobalAdmin - ); - this.isLoadingResults = false; - }); - } + private getPermission(id: number) { + this.subscription = this.permissionService.getPermission(id).subscribe(response => { + this.permission = response; + this.users = response.users; + this.showApplicationTable = this.meService.hasPermissions( + response, + PermissionType.Read, + PermissionType.OrganizationApplicationAdmin, + PermissionType.GlobalAdmin + ); + this.isLoadingResults = false; + }); + } - onDeletePermission() { - this.deleteDialogService.showSimpleDialog().subscribe((response) => { - if (response) { - this.permissionService.deletePermission(this.id).subscribe((response) => { - if (response.ok && response.body.affected > 0) { - this.router.navigate(['admin/permissions']); - } + onDeletePermission() { + this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.permissionService.deletePermission(this.id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + this.router.navigate(["admin/permissions"]); + } + }); + } }); - } - }); - } + } - onEditPermission() { - this.router.navigate(['edit-permission'], { relativeTo: this.route }); - } + onEditPermission() { + this.router.navigate(["edit-permission"], { relativeTo: this.route }); + } } diff --git a/src/app/admin/permission/permission-edit/permission-edit.component.html b/src/app/admin/permission/permission-edit/permission-edit.component.html index 7ab628f45..c446b2b7e 100644 --- a/src/app/admin/permission/permission-edit/permission-edit.component.html +++ b/src/app/admin/permission/permission-edit/permission-edit.component.html @@ -4,45 +4,74 @@
  • - {{error | translate}} + {{ error | translate }}
- * - {{ "PERMISSION.EDIT.NAME" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('name'), + 'is-valid': formFailedSubmit && !errorFields.includes('name') + }" + />
- * - {{ "PERMISSION.EDIT.TYPE" | translate }}* + - - {{'PERMISSION-TYPE.' + level.type | translate}} + [multiple]="true" + > + + {{ "PERMISSION-TYPE." + level.type | translate }}
- - + + - {{getTextForUser(user)}} + {{ getTextForUser(user) }} @@ -50,35 +79,50 @@
- * - - + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('organizationId'), + 'is-valid': formFailedSubmit && !errorFields.includes('organizationId') + }" + (ngModelChange)="organizationChanged()" + > +
- +
+ id="applicationIds" + [formControl]="applicationMultiCtrl" + [multiple]="true" + panelClass="overflow-x-hidden" + [(value)]="permission.applicationIds" + name="applicationIds" + #multiSelect + [compareWith]="compare" + > - {{app.name}} + {{ app.name }}
@@ -87,17 +131,21 @@
- +
- - {{'PERMISSION.EDIT.ADD-APPLICATION-ON-CREATE' | translate}} + + {{ "PERMISSION.EDIT.ADD-APPLICATION-ON-CREATE" | translate }}
- - + +
diff --git a/src/app/admin/permission/permission-edit/permission-edit.component.scss b/src/app/admin/permission/permission-edit/permission-edit.component.scss index d3f5a12fa..e69de29bb 100644 --- a/src/app/admin/permission/permission-edit/permission-edit.component.scss +++ b/src/app/admin/permission/permission-edit/permission-edit.component.scss @@ -1 +0,0 @@ - diff --git a/src/app/admin/permission/permission-edit/permission-edit.component.spec.ts b/src/app/admin/permission/permission-edit/permission-edit.component.spec.ts index 3955610df..803cb7111 100644 --- a/src/app/admin/permission/permission-edit/permission-edit.component.spec.ts +++ b/src/app/admin/permission/permission-edit/permission-edit.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { PermissionEditComponent } from './permission-edit.component'; +import { PermissionEditComponent } from "./permission-edit.component"; -describe('PermissionEditComponent', () => { - let component: PermissionEditComponent; - let fixture: ComponentFixture; +describe("PermissionEditComponent", () => { + let component: PermissionEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ PermissionEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PermissionEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(PermissionEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(PermissionEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/permission/permission-edit/permission-edit.component.ts b/src/app/admin/permission/permission-edit/permission-edit.component.ts index ed0d4a864..4df6d37e7 100644 --- a/src/app/admin/permission/permission-edit/permission-edit.component.ts +++ b/src/app/admin/permission/permission-edit/permission-edit.component.ts @@ -1,333 +1,305 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { HttpErrorResponse } from '@angular/common/http'; -import { UntypedFormControl, UntypedFormGroup } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { ReplaySubject, Subject, Subscription } from 'rxjs'; -import { Location } from '@angular/common'; -import { PermissionService } from '../permission.service'; -import { - PermissionRequest, - PermissionType, - PermissionTypes, -} from '../permission.model'; -import { OrganisationResponse } from '../../organisation/organisation.model'; -import { OrganisationService } from '../../organisation/organisation.service'; -import { UserService } from '../../users/user.service'; -import { UserResponse } from '../../users/user.model'; -import { ApplicationService } from '@applications/application.service'; -import { Application } from '@applications/application.model'; -import { BackButton } from '@shared/models/back-button.model'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { takeUntil } from 'rxjs/operators'; -import { MeService } from '@shared/services/me.service'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { HttpErrorResponse } from "@angular/common/http"; +import { UntypedFormControl, UntypedFormGroup } from "@angular/forms"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { ReplaySubject, Subject, Subscription } from "rxjs"; +import { Location } from "@angular/common"; +import { PermissionService } from "../permission.service"; +import { PermissionRequest, PermissionType, PermissionTypes } from "../permission.model"; +import { OrganisationResponse } from "../../organisation/organisation.model"; +import { OrganisationService } from "../../organisation/organisation.service"; +import { UserService } from "../../users/user.service"; +import { UserResponse } from "../../users/user.model"; +import { ApplicationService } from "@applications/application.service"; +import { Application } from "@applications/application.model"; +import { BackButton } from "@shared/models/back-button.model"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { takeUntil } from "rxjs/operators"; +import { MeService } from "@shared/services/me.service"; @Component({ - selector: 'app-permission-edit', - templateUrl: './permission-edit.component.html', - styleUrls: ['./permission-edit.component.scss'], + selector: "app-permission-edit", + templateUrl: "./permission-edit.component.html", + styleUrls: ["./permission-edit.component.scss"], }) export class PermissionEditComponent implements OnInit, OnDestroy { - permission = new PermissionRequest(); - isNotGlobalAdmin = true; - public organisations: OrganisationResponse[]; - public users: UserResponse[]; - public applications: Application[]; - public errorMessage: string; - public errorMessages: any; - public errorFields: string[]; - public formFailedSubmit = false; - public form: UntypedFormGroup; - public backButton: BackButton = { - label: '', - routerLink: ['admin', 'permissions'], - }; - public title = ''; - public submitButton = ''; - public isEditMode = false; - id: number; - subscription: Subscription; - organisationSubscription: Subscription; - userSubscription: Subscription; - applicationSubscription: Subscription; - allowedLevels: PermissionTypes[] = [ - { type: PermissionType.OrganizationUserAdmin }, - { type: PermissionType.OrganizationApplicationAdmin }, - { type: PermissionType.OrganizationGatewayAdmin }, - { type: PermissionType.Read }, - ]; + permission = new PermissionRequest(); + isNotGlobalAdmin = true; + public organisations: OrganisationResponse[]; + public users: UserResponse[]; + public applications: Application[]; + public errorMessage: string; + public errorMessages: any; + public errorFields: string[]; + public formFailedSubmit = false; + public form: UntypedFormGroup; + public backButton: BackButton = { + label: "", + routerLink: ["admin", "permissions"], + }; + public title = ""; + public submitButton = ""; + public isEditMode = false; + id: number; + subscription: Subscription; + organisationSubscription: Subscription; + userSubscription: Subscription; + applicationSubscription: Subscription; + allowedLevels: PermissionTypes[] = [ + { type: PermissionType.OrganizationUserAdmin }, + { type: PermissionType.OrganizationApplicationAdmin }, + { type: PermissionType.OrganizationGatewayAdmin }, + { type: PermissionType.Read }, + ]; - public userMultiCtrl: UntypedFormControl = new UntypedFormControl(); - public userMultiFilterCtrl: UntypedFormControl = new UntypedFormControl(); - public filteredUsersMulti: ReplaySubject = new ReplaySubject< - UserResponse[] - >(1); + public userMultiCtrl: UntypedFormControl = new UntypedFormControl(); + public userMultiFilterCtrl: UntypedFormControl = new UntypedFormControl(); + public filteredUsersMulti: ReplaySubject = new ReplaySubject(1); - public applicationMultiCtrl: UntypedFormControl = new UntypedFormControl(); - public applicationMultiFilterCtrl: UntypedFormControl = new UntypedFormControl(); - public filteredApplicationsMulti: ReplaySubject< - Application[] - > = new ReplaySubject(1); + public applicationMultiCtrl: UntypedFormControl = new UntypedFormControl(); + public applicationMultiFilterCtrl: UntypedFormControl = new UntypedFormControl(); + public filteredApplicationsMulti: ReplaySubject = new ReplaySubject(1); - public permissionLevelsCtrl: UntypedFormControl = new UntypedFormControl(); + public permissionLevelsCtrl: UntypedFormControl = new UntypedFormControl(); - /** Subject that emits when the component has been destroyed. */ - private _onDestroy = new Subject(); + /** Subject that emits when the component has been destroyed. */ + private _onDestroy = new Subject(); - constructor( - private translate: TranslateService, - private route: ActivatedRoute, - private permissionService: PermissionService, - private organisationService: OrganisationService, - private userService: UserService, - private applicationService: ApplicationService, - private location: Location, - private errormEssageService: ErrorMessageService, - private meService: MeService - ) {} + constructor( + private translate: TranslateService, + private route: ActivatedRoute, + private permissionService: PermissionService, + private organisationService: OrganisationService, + private userService: UserService, + private applicationService: ApplicationService, + private location: Location, + private errormEssageService: ErrorMessageService, + private meService: MeService + ) {} - ngOnInit(): void { - this.getOrganizations(); - this.getUsers(); - this.translate.use('da'); - this.translate - .get(['NAV.PERMISSIONS', 'FORM.EDIT-PERMISSION', 'PERMISSION.SAVE']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.PERMISSIONS']; - this.title = translations['FORM.EDIT-PERMISSION']; - this.submitButton = translations['PERMISSION.SAVE']; - }); - this.id = +this.route.snapshot.paramMap.get('permission-id'); - if (this.id > 0) { - this.getPermission(this.id); - this.isEditMode = true; - this.permissionLevelsCtrl.disable(); - this.setBackButton(); - } + ngOnInit(): void { + this.getOrganizations(); + this.getUsers(); + this.translate.use("da"); + this.translate.get(["NAV.PERMISSIONS", "FORM.EDIT-PERMISSION", "PERMISSION.SAVE"]).subscribe(translations => { + this.backButton.label = translations["NAV.PERMISSIONS"]; + this.title = translations["FORM.EDIT-PERMISSION"]; + this.submitButton = translations["PERMISSION.SAVE"]; + }); + this.id = +this.route.snapshot.paramMap.get("permission-id"); + if (this.id > 0) { + this.getPermission(this.id); + this.isEditMode = true; + this.permissionLevelsCtrl.disable(); + this.setBackButton(); + } - this.userMultiFilterCtrl.valueChanges - .pipe(takeUntil(this._onDestroy)) - .subscribe(() => { - this.filterUsersMulti(); - }); + this.userMultiFilterCtrl.valueChanges.pipe(takeUntil(this._onDestroy)).subscribe(() => { + this.filterUsersMulti(); + }); - this.applicationMultiFilterCtrl.valueChanges - .pipe(takeUntil(this._onDestroy)) - .subscribe(() => { - this.filterApplicationsMulti(); - }); - } + this.applicationMultiFilterCtrl.valueChanges.pipe(takeUntil(this._onDestroy)).subscribe(() => { + this.filterApplicationsMulti(); + }); + } - private filterApplicationsMulti() { - if (!this.applications) { - return; + private filterApplicationsMulti() { + if (!this.applications) { + return; + } + // get the search keyword + let search = this.applicationMultiFilterCtrl.value; + if (!search) { + this.filteredApplicationsMulti.next(this.applications.slice()); + return; + } else { + search = search.toLowerCase(); + } + // filter the banks + this.filteredApplicationsMulti.next( + this.applications.filter(app => app.name.toLowerCase().indexOf(search) > -1) + ); } - // get the search keyword - let search = this.applicationMultiFilterCtrl.value; - if (!search) { - this.filteredApplicationsMulti.next(this.applications.slice()); - return; - } else { - search = search.toLowerCase(); + + private filterUsersMulti() { + if (!this.users) { + return; + } + // get the search keyword + let search = this.userMultiFilterCtrl?.value?.trim(); + if (!search) { + this.filteredUsersMulti.next(this.users.slice()); + return; + } else { + search = search.toLowerCase(); + } + const filtered = this.users.filter(user => { + return ( + user.name.toLocaleLowerCase().indexOf(search) > -1 || + user?.email?.toLocaleLowerCase()?.indexOf(search) > -1 + ); + }); + // filter the banks + this.filteredUsersMulti.next(filtered); } - // filter the banks - this.filteredApplicationsMulti.next( - this.applications.filter( - (app) => app.name.toLowerCase().indexOf(search) > -1 - ) - ); - } - private filterUsersMulti() { - if (!this.users) { - return; + getTextForUser(user: UserResponse): string { + return `${user.name}` + (user.email ? ` (${user.email})` : ``); } - // get the search keyword - let search = this.userMultiFilterCtrl?.value?.trim(); - if (!search) { - this.filteredUsersMulti.next(this.users.slice()); - return; - } else { - search = search.toLowerCase(); + + private setBackButton() { + this.backButton.routerLink = ["admin", "permissions"]; } - const filtered = this.users.filter((user) => { - return ( - user.name.toLocaleLowerCase().indexOf(search) > -1 || - user?.email?.toLocaleLowerCase()?.indexOf(search) > -1 - ); - }); - // filter the banks - this.filteredUsersMulti.next(filtered); - } - getTextForUser(user: UserResponse): string { - return `${user.name}` + (user.email ? ` (${user.email})` : ``); - } + private getOrganizations() { + this.organisationSubscription = this.organisationService.getMultiple(1000, 0, "name", "asc").subscribe( + orgs => { + this.organisations = orgs.data; + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private setBackButton() { - this.backButton.routerLink = ['admin', 'permissions']; - } + private getUsers() { + this.userSubscription = this.userService.getMultiple(1000, 0, "name", "asc").subscribe( + users => { + this.users = users.data; + this.filteredUsersMulti.next(this.users.slice()); + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private getOrganizations() { - this.organisationSubscription = this.organisationService - .getMultiple(1000, 0, 'name', 'asc') - .subscribe( - (orgs) => { - this.organisations = orgs.data; - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + public compare(o1: any, o2: any): boolean { + return o1 === o2; + } - private getUsers() { - this.userSubscription = this.userService - .getMultiple(1000, 0, 'name', 'asc') - .subscribe( - (users) => { - this.users = users.data; - this.filteredUsersMulti.next(this.users.slice()); - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + public compareLevels(p1: PermissionTypes, p2: PermissionTypes): boolean { + return p1?.type === p2?.type; + } - public compare(o1: any, o2: any): boolean { - return o1 === o2; - } + organizationChanged() { + this.getApplications(this.permission.organizationId); + } - public compareLevels(p1: PermissionTypes, p2: PermissionTypes): boolean { - return p1?.type === p2?.type; - } + private getApplications(organizationId: number) { + this.applicationSubscription = this.applicationService + .getApplicationsByOrganizationId(organizationId) + .subscribe( + res => { + this.applications = res.data.sort((a, b) => a.name.localeCompare(b.name, "en", { numeric: true })); + this.filteredApplicationsMulti.next(this.applications.slice()); + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - organizationChanged() { - this.getApplications(this.permission.organizationId); - } + private getPermission(id: number) { + this.subscription = this.permissionService.getPermission(id).subscribe( + response => { + this.permission.name = response.name; + this.permission.levels = response.type; + this.permissionLevelsCtrl.setValue(this.permission.levels); + this.permission.userIds = response.users.map(x => x.id); + this.userMultiCtrl.setValue(this.permission.userIds); + this.permission.automaticallyAddNewApplications = response.automaticallyAddNewApplications; + this.isNotGlobalAdmin = this.meService.hasNotTargetPermissions(response, PermissionType.GlobalAdmin); - private getApplications(organizationId: number) { - this.applicationSubscription = this.applicationService - .getApplicationsByOrganizationId(organizationId) - .subscribe( - (res) => { - this.applications = res.data.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - this.filteredApplicationsMulti.next(this.applications.slice()); - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + if (this.isNotGlobalAdmin) { + this.permission.organizationId = response?.organization?.id; + this.buildAllowedLevels(); + } else { + this.allowedLevels = [{ type: PermissionType.GlobalAdmin }]; + } - private getPermission(id: number) { - this.subscription = this.permissionService.getPermission(id).subscribe( - (response) => { - this.permission.name = response.name; - this.permission.levels = response.type; - this.permissionLevelsCtrl.setValue(this.permission.levels); - this.permission.userIds = response.users.map((x) => x.id); - this.userMultiCtrl.setValue(this.permission.userIds); - this.permission.automaticallyAddNewApplications = - response.automaticallyAddNewApplications; - this.isNotGlobalAdmin = this.meService.hasNotTargetPermissions( - response, - PermissionType.GlobalAdmin + if ( + this.meService.hasPermissions( + response, + PermissionType.Read, + PermissionType.OrganizationApplicationAdmin + ) + ) { + this.getApplications(this.permission.organizationId); + this.permission.applicationIds = response.applications.map(x => x.id); + this.applicationMultiCtrl.setValue(this.permission.applicationIds); + } + }, + (error: HttpErrorResponse) => { + this.showError(error); + } ); + } - if (this.isNotGlobalAdmin) { - this.permission.organizationId = response?.organization?.id; - this.buildAllowedLevels(); - } else { - this.allowedLevels = [{ type: PermissionType.GlobalAdmin }]; - } - - if ( - this.meService.hasPermissions( - response, - PermissionType.Read, - PermissionType.OrganizationApplicationAdmin - ) - ) { - this.getApplications(this.permission.organizationId); - this.permission.applicationIds = response.applications.map( - (x) => x.id - ); - this.applicationMultiCtrl.setValue(this.permission.applicationIds); - } - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } - - private create(): void { - this.permissionService.createPermission(this.permission).subscribe( - (_response) => { - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + private create(): void { + this.permissionService.createPermission(this.permission).subscribe( + _response => { + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private update(): void { - this.permissionService.updatePermission(this.permission, this.id).subscribe( - () => { - this.routeBack(); - }, - (error) => { - this.showError(error); - } - ); - } + private update(): void { + this.permissionService.updatePermission(this.permission, this.id).subscribe( + () => { + this.routeBack(); + }, + error => { + this.showError(error); + } + ); + } - private buildAllowedLevels(): void { - this.allowedLevels = [ - { type: PermissionType.OrganizationUserAdmin }, - { type: PermissionType.OrganizationApplicationAdmin }, - { type: PermissionType.OrganizationGatewayAdmin }, - { type: PermissionType.Read }, - ]; - } + private buildAllowedLevels(): void { + this.allowedLevels = [ + { type: PermissionType.OrganizationUserAdmin }, + { type: PermissionType.OrganizationApplicationAdmin }, + { type: PermissionType.OrganizationGatewayAdmin }, + { type: PermissionType.Read }, + ]; + } - isOrganizationApplicationPermission() { - return this.isReadOrWrite(); - } + isOrganizationApplicationPermission() { + return this.isReadOrWrite(); + } - isReadOrWrite(): boolean { - return this.meService.hasPermissionTypes( - this.permission.levels, - PermissionType.Read, - PermissionType.OrganizationApplicationAdmin - ); - } + isReadOrWrite(): boolean { + return this.meService.hasPermissionTypes( + this.permission.levels, + PermissionType.Read, + PermissionType.OrganizationApplicationAdmin + ); + } - onSubmit(): void { - if (this.id) { - this.update(); - } else { - this.create(); + onSubmit(): void { + if (this.id) { + this.update(); + } else { + this.create(); + } } - } - private showError(err: HttpErrorResponse) { - const result = this.errormEssageService.handleErrorMessageWithFields(err); - this.errorFields = result.errorFields; - this.errorMessages = result.errorMessages; - } + private showError(err: HttpErrorResponse) { + const result = this.errormEssageService.handleErrorMessageWithFields(err); + this.errorFields = result.errorFields; + this.errorMessages = result.errorMessages; + } - routeBack(): void { - this.location.back(); - } + routeBack(): void { + this.location.back(); + } - ngOnDestroy() { - this._onDestroy.next(); - this._onDestroy.complete(); - } + ngOnDestroy() { + this._onDestroy.next(); + this._onDestroy.complete(); + } } diff --git a/src/app/admin/permission/permission-list/permission-list.component.html b/src/app/admin/permission/permission-list/permission-list.component.html index 684ba789d..5a5f2cb5c 100644 --- a/src/app/admin/permission/permission-list/permission-list.component.html +++ b/src/app/admin/permission/permission-list/permission-list.component.html @@ -1,11 +1,15 @@ - +
- - +
diff --git a/src/app/admin/permission/permission-list/permission-list.component.spec.ts b/src/app/admin/permission/permission-list/permission-list.component.spec.ts index 2656a4bf0..684473551 100644 --- a/src/app/admin/permission/permission-list/permission-list.component.spec.ts +++ b/src/app/admin/permission/permission-list/permission-list.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { PermissionListComponent } from './permission-list.component'; +import { PermissionListComponent } from "./permission-list.component"; -describe('PermissionListComponent', () => { - let component: PermissionListComponent; - let fixture: ComponentFixture; +describe("PermissionListComponent", () => { + let component: PermissionListComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ PermissionListComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PermissionListComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(PermissionListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(PermissionListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/permission/permission-list/permission-list.component.ts b/src/app/admin/permission/permission-list/permission-list.component.ts index 07ba2bb4a..fc7581629 100644 --- a/src/app/admin/permission/permission-list/permission-list.component.ts +++ b/src/app/admin/permission/permission-list/permission-list.component.ts @@ -1,63 +1,60 @@ -import { Component, OnInit, OnChanges, SimpleChanges } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { PermissionResponse } from '../permission.model'; -import { Subscription } from 'rxjs'; -import { PermissionService } from '../permission.service'; -import { Sort } from '@shared/models/sort.model'; -import { environment } from '@environments/environment'; -import { Title } from '@angular/platform-browser'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Component, OnInit, OnChanges, SimpleChanges } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; +import { PermissionResponse } from "../permission.model"; +import { Subscription } from "rxjs"; +import { PermissionService } from "../permission.service"; +import { Sort } from "@shared/models/sort.model"; +import { environment } from "@environments/environment"; +import { Title } from "@angular/platform-browser"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-permission-list', - templateUrl: './permission-list.component.html', - styleUrls: ['./permission-list.component.scss'], + selector: "app-permission-list", + templateUrl: "./permission-list.component.html", + styleUrls: ["./permission-list.component.scss"], }) export class PermissionListComponent implements OnInit, OnChanges { - isLoadingResults = true; - public pageLimit = environment.tablePageSize; - public selectedSortId = 1; + isLoadingResults = true; + public pageLimit = environment.tablePageSize; + public selectedSortId = 1; - public permissions: PermissionResponse[]; - permissionSubscription: Subscription; - canEdit: boolean; + public permissions: PermissionResponse[]; + permissionSubscription: Subscription; + canEdit: boolean; - constructor( - public translate: TranslateService, - private titleService: Title, - private permissionService: PermissionService, - private meService: MeService - ) { - translate.use('da'); - } - ngOnChanges(): void { - this.getPermissions(); - } + constructor( + public translate: TranslateService, + private titleService: Title, + private permissionService: PermissionService, + private meService: MeService + ) { + translate.use("da"); + } + ngOnChanges(): void { + this.getPermissions(); + } - ngOnInit(): void { - this.getPermissions(); - this.translate.get(['TITLE.PERMISSION']) - .subscribe(translations => { - this.titleService.setTitle(translations['TITLE.PERMISSION']); - }); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); - } + ngOnInit(): void { + this.getPermissions(); + this.translate.get(["TITLE.PERMISSION"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.PERMISSION"]); + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); + } - getPermissions() { - this.permissionSubscription = this.permissionService - .getPermissions() - .subscribe((response) => { - this.permissions = response.data; - this.isLoadingResults = false; - }); - } + getPermissions() { + this.permissionSubscription = this.permissionService.getPermissions().subscribe(response => { + this.permissions = response.data; + this.isLoadingResults = false; + }); + } - deletePermission(id: number) { - this.permissionService.deletePermission(id).subscribe((response) => { - if (response.ok && response.body.affected > 0) { - this.getPermissions(); - } - }); - } + deletePermission(id: number) { + this.permissionService.deletePermission(id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + this.getPermissions(); + } + }); + } } diff --git a/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.html b/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.html index 51892babf..375ee62d8 100644 --- a/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.html +++ b/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.html @@ -3,20 +3,22 @@
- @@ -24,21 +26,23 @@ + {{ "PERMISSION.ORGANISATION" | translate }} + + {{ "PERMISSION.NUMBER_OF_MEMBERS" | translate }} + @@ -47,7 +51,8 @@ + {{ "PERMISSION.TYPE" | translate }} + @@ -57,20 +62,30 @@ - +
- {{ 'PERMISSION.NAME' | translate }} + {{ "PERMISSION.NAME" | translate }} - - {{element.name}} + + {{ element.name }} - {{element.name}} + {{ element.name }} - {{ 'PERMISSION.ORGANISATION' | translate }} - {{element?.organization?.name ? element.organization.name : ("PERMISSION.NO_ORGANISATION" | translate)}} - + {{ + element?.organization?.name ? element.organization.name : ("PERMISSION.NO_ORGANISATION" | translate) + }} - {{ 'PERMISSION.NUMBER_OF_MEMBERS' | translate }}
- {{element.users.length}} - + {{ element.users.length }}
Ingen brugere er tilføjet
- {{ 'PERMISSION.TYPE' | translate }} {{ element.type | translatePermissions }} -
- +
diff --git a/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.spec.ts b/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.spec.ts index 6ab6fdee4..47d6b3e93 100644 --- a/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.spec.ts +++ b/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { PermissionTabelComponent } from './permission-tabel.component'; +import { PermissionTabelComponent } from "./permission-tabel.component"; -describe('PermissionTabelComponent', () => { - let component: PermissionTabelComponent; - let fixture: ComponentFixture; +describe("PermissionTabelComponent", () => { + let component: PermissionTabelComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ PermissionTabelComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PermissionTabelComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(PermissionTabelComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(PermissionTabelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.ts b/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.ts index 9a0cbd2c7..6e8e76ef7 100644 --- a/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.ts +++ b/src/app/admin/permission/permission-list/permission-tabel/permission-tabel.component.ts @@ -1,35 +1,25 @@ -import { Component, ViewChild, AfterViewInit, Input } from '@angular/core'; -import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { Router } from '@angular/router'; -import { environment } from '@environments/environment'; -import { TranslateService } from '@ngx-translate/core'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { MeService } from '@shared/services/me.service'; -import { merge, Observable, of as observableOf } from 'rxjs'; -import { startWith, switchMap, map, catchError } from 'rxjs/operators'; -import { - PermissionGetManyResponse, - PermissionResponse, - PermissionType, -} from '../../permission.model'; -import { PermissionService } from '../../permission.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { Component, ViewChild, AfterViewInit, Input } from "@angular/core"; +import { MatPaginator, PageEvent } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { Router } from "@angular/router"; +import { environment } from "@environments/environment"; +import { TranslateService } from "@ngx-translate/core"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { MeService } from "@shared/services/me.service"; +import { merge, Observable, of as observableOf } from "rxjs"; +import { startWith, switchMap, map, catchError } from "rxjs/operators"; +import { PermissionGetManyResponse, PermissionResponse, PermissionType } from "../../permission.model"; +import { PermissionService } from "../../permission.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; @Component({ - selector: 'app-permission-tabel', - templateUrl: './permission-tabel.component.html', - styleUrls: ['./permission-tabel.component.scss'], + selector: "app-permission-tabel", + templateUrl: "./permission-tabel.component.html", + styleUrls: ["./permission-tabel.component.scss"], }) export class PermissionTabelComponent implements AfterViewInit { - displayedColumns: string[] = [ - 'name', - 'organisations', - 'members', - 'type', - 'menu', - ]; + displayedColumns: string[] = ["name", "organisations", "members", "type", "menu"]; data: PermissionResponse[]; @ViewChild(MatPaginator) paginator: MatPaginator; @@ -49,9 +39,9 @@ export class PermissionTabelComponent implements AfterViewInit { private router: Router, private permissionService: PermissionService, private deleteDialogService: DeleteDialogService, - private meService: MeService, + private meService: MeService ) { - translate.use('da'); + translate.use("da"); } ngAfterViewInit() { @@ -63,12 +53,9 @@ export class PermissionTabelComponent implements AfterViewInit { startWith({}), switchMap(() => { this.isLoadingResults = true; - return this.getPermissions( - this.sort.active, - this.sort.direction - ); + return this.getPermissions(this.sort.active, this.sort.direction); }), - map((data) => { + map(data => { // Flip flag to show that loading has finished. this.isLoadingResults = false; this.resultsLength = data.count; @@ -80,13 +67,10 @@ export class PermissionTabelComponent implements AfterViewInit { return observableOf([]); }) ) - .subscribe((data) => (this.data = data)); + .subscribe(data => (this.data = data)); } - getPermissions( - orderByColumn: string, - orderByDirection: string - ): Observable { + getPermissions(orderByColumn: string, orderByDirection: string): Observable { return this.permissionService.getPermissions( this.paginator.pageSize, this.paginator.pageIndex * this.paginator.pageSize, @@ -98,13 +82,13 @@ export class PermissionTabelComponent implements AfterViewInit { } routeToPermissions(element: any) { - this.router.navigate(['admin/permissions', element.id]); + this.router.navigate(["admin/permissions", element.id]); } deletePermission(id: number) { - this.deleteDialogService.showSimpleDialog().subscribe((response) => { + this.deleteDialogService.showSimpleDialog().subscribe(response => { if (response) { - this.permissionService.deletePermission(id).subscribe((response) => { + this.permissionService.deletePermission(id).subscribe(response => { if (response.ok && response.body.affected > 0) { this.refresh(); } @@ -117,7 +101,10 @@ export class PermissionTabelComponent implements AfterViewInit { if (this.meService.hasPermissions(element, PermissionType.GlobalAdmin)) { return this.meService.hasGlobalAdmin(); } - return this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite, element.organization.id); + return this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.UserAdministrationWrite, + element.organization.id + ); } private refresh() { diff --git a/src/app/admin/permission/permission.component.html b/src/app/admin/permission/permission.component.html index 90c6b6463..0680b43f9 100644 --- a/src/app/admin/permission/permission.component.html +++ b/src/app/admin/permission/permission.component.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/app/admin/permission/permission.component.spec.ts b/src/app/admin/permission/permission.component.spec.ts index 46525adf9..ccd216f54 100644 --- a/src/app/admin/permission/permission.component.spec.ts +++ b/src/app/admin/permission/permission.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { PermissionComponent } from './permission.component'; +import { PermissionComponent } from "./permission.component"; -describe('PermissionComponent', () => { - let component: PermissionComponent; - let fixture: ComponentFixture; +describe("PermissionComponent", () => { + let component: PermissionComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ PermissionComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PermissionComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(PermissionComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(PermissionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/permission/permission.component.ts b/src/app/admin/permission/permission.component.ts index d8ddb28a8..6677b0b0b 100644 --- a/src/app/admin/permission/permission.component.ts +++ b/src/app/admin/permission/permission.component.ts @@ -1,17 +1,14 @@ -import { Component, OnInit } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, OnInit } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; @Component({ - selector: 'app-permission', - templateUrl: './permission.component.html', - styleUrls: ['./permission.component.scss'] + selector: "app-permission", + templateUrl: "./permission.component.html", + styleUrls: ["./permission.component.scss"], }) export class PermissionComponent implements OnInit { - - constructor(public translate: TranslateService) { - translate.use('da'); - } - ngOnInit(): void { - } - + constructor(public translate: TranslateService) { + translate.use("da"); + } + ngOnInit(): void {} } diff --git a/src/app/admin/permission/permission.model.ts b/src/app/admin/permission/permission.model.ts index f8777dfe5..0547ce733 100644 --- a/src/app/admin/permission/permission.model.ts +++ b/src/app/admin/permission/permission.model.ts @@ -1,52 +1,52 @@ -import { OrganisationResponse } from '../organisation/organisation.model'; -import { UserResponse } from '../users/user.model'; -import { Application } from '../../applications/application.model'; +import { OrganisationResponse } from "../organisation/organisation.model"; +import { UserResponse } from "../users/user.model"; +import { Application } from "../../applications/application.model"; export class PermissionRequest { - levels: PermissionTypes[]; - name: string; - organizationId: number; - userIds: number[]; - applicationIds: number[]; - automaticallyAddNewApplications = true; + levels: PermissionTypes[]; + name: string; + organizationId: number; + userIds: number[]; + applicationIds: number[]; + automaticallyAddNewApplications = true; } export class PermissionRequestAcceptUser { - organizationId: number; - userId: number; - permissionIds: number[]; + organizationId: number; + userId: number; + permissionIds: number[]; } export interface PermissionResponse { - type: PermissionTypes[]; - name: string; - users?: UserResponse[]; - organization?: OrganisationResponse; - applications?: Application[]; - applicationIds?: number[]; - id: number; - createdAt: Date; - updatedAt: Date; - createdBy: number; - updatedBy: number; - createdByName: string; - updatedByName: string; - automaticallyAddNewApplications: boolean; + type: PermissionTypes[]; + name: string; + users?: UserResponse[]; + organization?: OrganisationResponse; + applications?: Application[]; + applicationIds?: number[]; + id: number; + createdAt: Date; + updatedAt: Date; + createdBy: number; + updatedBy: number; + createdByName: string; + updatedByName: string; + automaticallyAddNewApplications: boolean; } export interface PermissionGetManyResponse { - data: PermissionResponse[]; - count: number; + data: PermissionResponse[]; + count: number; } export interface PermissionTypes { - type: PermissionType; + type: PermissionType; } export enum PermissionType { - GlobalAdmin = 'GlobalAdmin', - OrganizationUserAdmin = 'OrganizationUserAdmin', - OrganizationGatewayAdmin = 'OrganizationGatewayAdmin', - OrganizationApplicationAdmin = 'OrganizationApplicationAdmin', - Read = 'Read', + GlobalAdmin = "GlobalAdmin", + OrganizationUserAdmin = "OrganizationUserAdmin", + OrganizationGatewayAdmin = "OrganizationGatewayAdmin", + OrganizationApplicationAdmin = "OrganizationApplicationAdmin", + Read = "Read", } diff --git a/src/app/admin/permission/permission.service.ts b/src/app/admin/permission/permission.service.ts index d2ce1d8b1..2557a5c88 100644 --- a/src/app/admin/permission/permission.service.ts +++ b/src/app/admin/permission/permission.service.ts @@ -1,95 +1,78 @@ -import { Injectable } from '@angular/core'; -import { RestService } from '../../shared/services/rest.service'; -import { Observable } from 'rxjs'; +import { Injectable } from "@angular/core"; +import { RestService } from "../../shared/services/rest.service"; +import { Observable } from "rxjs"; import { - PermissionGetManyResponse, - PermissionResponse, - PermissionRequest, - PermissionRequestAcceptUser, -} from './permission.model'; -import { map } from 'rxjs/operators'; -import { UserMinimalService } from '../users/user-minimal.service'; + PermissionGetManyResponse, + PermissionResponse, + PermissionRequest, + PermissionRequestAcceptUser, +} from "./permission.model"; +import { map } from "rxjs/operators"; +import { UserMinimalService } from "../users/user-minimal.service"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class PermissionService { - endpoint = 'permission'; - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + endpoint = "permission"; + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - createPermission(body: PermissionRequest): Observable { - return this.restService.post(this.endpoint, body, { - observe: 'response', - }); - } + createPermission(body: PermissionRequest): Observable { + return this.restService.post(this.endpoint, body, { + observe: "response", + }); + } - createPermissionAcceptUser( - body: PermissionRequestAcceptUser - ): Observable { - return this.restService.put( - this.endpoint + '/acceptUser', - body, - undefined, - { - observe: 'response', - } - ); - } + createPermissionAcceptUser(body: PermissionRequestAcceptUser): Observable { + return this.restService.put(this.endpoint + "/acceptUser", body, undefined, { + observe: "response", + }); + } - updatePermission( - body: PermissionRequest, - id: number - ): Observable { - return this.restService.put(this.endpoint, body, id, { - observe: 'response', - }); - } + updatePermission(body: PermissionRequest, id: number): Observable { + return this.restService.put(this.endpoint, body, id, { + observe: "response", + }); + } - getPermission(id: number): Observable { - return this.restService.get(this.endpoint, {}, id).pipe( - map((response: PermissionResponse) => { - response.createdByName = this.userMinimalService.getUserNameFrom( - response.createdBy + getPermission(id: number): Observable { + return this.restService.get(this.endpoint, {}, id).pipe( + map((response: PermissionResponse) => { + response.createdByName = this.userMinimalService.getUserNameFrom(response.createdBy); + response.updatedByName = this.userMinimalService.getUserNameFrom(response.updatedBy); + return response; + }) ); - response.updatedByName = this.userMinimalService.getUserNameFrom( - response.updatedBy - ); - return response; - }) - ); - } + } - getPermissions( - limit: number = 1000, - offset: number = 0, - orderByColumn?: string, - orderByDirection?: string, - userId?: number, - organisationId?: number - ): Observable { - if (userId || organisationId) { - return this.restService.get(this.endpoint, { - limit: limit, - offset: offset, - orderOn: orderByColumn, - sort: orderByDirection, - userId: userId, - organisationId: organisationId, - }); - } else { - return this.restService.get(this.endpoint, { - limit: limit, - offset: offset, - orderOn: orderByColumn, - sort: orderByDirection, - }); + getPermissions( + limit: number = 1000, + offset: number = 0, + orderByColumn?: string, + orderByDirection?: string, + userId?: number, + organisationId?: number + ): Observable { + if (userId || organisationId) { + return this.restService.get(this.endpoint, { + limit: limit, + offset: offset, + orderOn: orderByColumn, + sort: orderByDirection, + userId: userId, + organisationId: organisationId, + }); + } else { + return this.restService.get(this.endpoint, { + limit: limit, + offset: offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } } - } - deletePermission(id: number) { - return this.restService.delete(this.endpoint, id); - } + deletePermission(id: number) { + return this.restService.delete(this.endpoint, id); + } } diff --git a/src/app/admin/users/accept-user/accept-user.component.html b/src/app/admin/users/accept-user/accept-user.component.html index 45aafb4a8..5c4771923 100644 --- a/src/app/admin/users/accept-user/accept-user.component.html +++ b/src/app/admin/users/accept-user/accept-user.component.html @@ -1,52 +1,61 @@
- + -
-
-
    -
  • - {{ error | translate }} -
  • -
-
-
-
-
-
-

- {{ 'USERS.ACCEPT-USER.QUESTION-ACCEPT' | translate }} - {{ user.name }} - - {{ 'USERS.ACCEPT-USER.IN-ORGANIZATION' | translate }} - {{ organizationName}} - -

- + +
+
    +
  • + {{ error | translate }} +
  • +
+
+
+
+
+
+

+ {{ "USERS.ACCEPT-USER.QUESTION-ACCEPT" | translate }} + {{ user.name }} + + {{ "USERS.ACCEPT-USER.IN-ORGANIZATION" | translate }} + {{ organizationName }} + +

+ -
- * - - - {{ permission.name }} - - -
-
- - +
+ * + + + {{ permission.name }} + + +
+
+ + +
+
+
-
-
-
- +
diff --git a/src/app/admin/users/accept-user/accept-user.component.ts b/src/app/admin/users/accept-user/accept-user.component.ts index 4d5f424fb..4171314e5 100644 --- a/src/app/admin/users/accept-user/accept-user.component.ts +++ b/src/app/admin/users/accept-user/accept-user.component.ts @@ -1,134 +1,119 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit, OnDestroy } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; import { - PermissionRequestAcceptUser, - PermissionType, - PermissionTypes, - PermissionResponse, -} from '@app/admin/permission/permission.model'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { Subscription } from 'rxjs'; -import { UserResponse } from '../user.model'; -import { UserService } from '../user.service'; -import { Location } from '@angular/common'; -import { PermissionService } from '@app/admin/permission/permission.service'; -import { UntypedFormControl } from '@angular/forms'; + PermissionRequestAcceptUser, + PermissionType, + PermissionTypes, + PermissionResponse, +} from "@app/admin/permission/permission.model"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { Subscription } from "rxjs"; +import { UserResponse } from "../user.model"; +import { UserService } from "../user.service"; +import { Location } from "@angular/common"; +import { PermissionService } from "@app/admin/permission/permission.service"; +import { UntypedFormControl } from "@angular/forms"; @Component({ - selector: 'app-accept-user', - templateUrl: './accept-user.component.html', - styleUrls: ['./accept-user.component.scss'], + selector: "app-accept-user", + templateUrl: "./accept-user.component.html", + styleUrls: ["./accept-user.component.scss"], }) export class AcceptUserComponent implements OnInit, OnDestroy { - public backButtonTitle: string; - permission = new PermissionRequestAcceptUser(); - public title: string; - userId: number; - subscription: Subscription; - permissionsForOrgSubscription: Subscription; - user: UserResponse; - errorFields: string[]; - organizationId: number; - organizationName: string; - public formFailedSubmit = false; - errorMessages: any; - allowedLevels: PermissionTypes[] = [ - { type: PermissionType.OrganizationUserAdmin }, - { type: PermissionType.OrganizationApplicationAdmin }, - { type: PermissionType.OrganizationGatewayAdmin }, - { type: PermissionType.Read }, - ]; - public permissionsCtrl: UntypedFormControl = new UntypedFormControl(); - permissions: PermissionResponse[] = []; + public backButtonTitle: string; + permission = new PermissionRequestAcceptUser(); + public title: string; + userId: number; + subscription: Subscription; + permissionsForOrgSubscription: Subscription; + user: UserResponse; + errorFields: string[]; + organizationId: number; + organizationName: string; + public formFailedSubmit = false; + errorMessages: any; + allowedLevels: PermissionTypes[] = [ + { type: PermissionType.OrganizationUserAdmin }, + { type: PermissionType.OrganizationApplicationAdmin }, + { type: PermissionType.OrganizationGatewayAdmin }, + { type: PermissionType.Read }, + ]; + public permissionsCtrl: UntypedFormControl = new UntypedFormControl(); + permissions: PermissionResponse[] = []; - constructor( - private userService: UserService, - private location: Location, - private translate: TranslateService, - private route: ActivatedRoute, - private errorMessageService: ErrorMessageService, - private permissionService: PermissionService - ) {} + constructor( + private userService: UserService, + private location: Location, + private translate: TranslateService, + private route: ActivatedRoute, + private errorMessageService: ErrorMessageService, + private permissionService: PermissionService + ) {} - ngOnInit(): void { - this.userId = +this.route.snapshot.paramMap.get('user-id'); - this.organizationId = +this.route.snapshot.paramMap.get('org-id'); + ngOnInit(): void { + this.userId = +this.route.snapshot.paramMap.get("user-id"); + this.organizationId = +this.route.snapshot.paramMap.get("org-id"); - if (this.userId) { - this.getUser(this.userId); - } + if (this.userId) { + this.getUser(this.userId); + } - this.translate - .get(['GEN.BACK', 'USERS.ACCEPT-USER.ACCEPT']) - .subscribe((translations) => { - this.backButtonTitle = translations['GEN.BACK']; - this.title = translations['USERS.ACCEPT-USER.ACCEPT']; - }); - this.permission.userId = this.userId; - this.permission.organizationId = this.organizationId; - this.getPermissionsForOrg(this.organizationId); - } + this.translate.get(["GEN.BACK", "USERS.ACCEPT-USER.ACCEPT"]).subscribe(translations => { + this.backButtonTitle = translations["GEN.BACK"]; + this.title = translations["USERS.ACCEPT-USER.ACCEPT"]; + }); + this.permission.userId = this.userId; + this.permission.organizationId = this.organizationId; + this.getPermissionsForOrg(this.organizationId); + } - private getUser(id: number) { - this.subscription = this.userService - .getOne(id, false) - .subscribe((response) => { - this.user = response; - }); - } + private getUser(id: number) { + this.subscription = this.userService.getOne(id, false).subscribe(response => { + this.user = response; + }); + } - private getPermissionsForOrg(orgId: number) { - this.permissionsForOrgSubscription = this.permissionService - .getPermissions( - undefined, - undefined, - undefined, - undefined, - undefined, - orgId - ) - .subscribe( - (permissionsResponse) => { - this.permissions = permissionsResponse.data.filter( - (x) => x.organization?.id === this.organizationId - ); - this.permissionsCtrl.setValue(this.permissions); - this.organizationName = permissionsResponse.data[0]?.organization?.name; - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + private getPermissionsForOrg(orgId: number) { + this.permissionsForOrgSubscription = this.permissionService + .getPermissions(undefined, undefined, undefined, undefined, undefined, orgId) + .subscribe( + permissionsResponse => { + this.permissions = permissionsResponse.data.filter(x => x.organization?.id === this.organizationId); + this.permissionsCtrl.setValue(this.permissions); + this.organizationName = permissionsResponse.data[0]?.organization?.name; + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private showError(err: HttpErrorResponse) { - const result = this.errorMessageService.handleErrorMessageWithFields(err); - this.errorFields = result.errorFields; - this.errorMessages = result.errorMessages; - } + private showError(err: HttpErrorResponse) { + const result = this.errorMessageService.handleErrorMessageWithFields(err); + this.errorFields = result.errorFields; + this.errorMessages = result.errorMessages; + } - routeBack(): void { - this.location.back(); - } + routeBack(): void { + this.location.back(); + } - onSubmit(): void { - this.permissionService - .createPermissionAcceptUser(this.permission) - .subscribe( - () => { - this.routeBack(); - }, - (error: HttpErrorResponse) => { - console.log(error); - this.showError(error); - } - ); - } + onSubmit(): void { + this.permissionService.createPermissionAcceptUser(this.permission).subscribe( + () => { + this.routeBack(); + }, + (error: HttpErrorResponse) => { + console.log(error); + this.showError(error); + } + ); + } - ngOnDestroy() { - this.subscription?.unsubscribe(); - this.permissionsForOrgSubscription?.unsubscribe(); - } + ngOnDestroy() { + this.subscription?.unsubscribe(); + this.permissionsForOrgSubscription?.unsubscribe(); + } } diff --git a/src/app/admin/users/new-kombit-user-page/new-user.component.html b/src/app/admin/users/new-kombit-user-page/new-user.component.html index 9ad02297b..751763c0a 100644 --- a/src/app/admin/users/new-kombit-user-page/new-user.component.html +++ b/src/app/admin/users/new-kombit-user-page/new-user.component.html @@ -1,75 +1,71 @@
-
-
-
-

- {{ 'NEW_USER.FIRST_LOGIN' | translate }} -

-
-
-
    -
  • - {{ error | translate }} -
  • -
  • - {{errorMessage | translate}} -
  • -
-
-
- * +
+
+
+

+ {{ "NEW_USER.FIRST_LOGIN" | translate }} +

+ +
+
    +
  • + {{ error | translate }} +
  • +
  • + {{ errorMessage | translate }} +
  • +
+
+
+ * - -
+ +
-
- * - - +
+ * + + - {{ org.name }} - -
-
- -
- -
+ {{ + org.name + }} + +
+
+ +
+ +
+
-
diff --git a/src/app/admin/users/new-kombit-user-page/new-user.component.ts b/src/app/admin/users/new-kombit-user-page/new-user.component.ts index 46aea1244..fef46c157 100644 --- a/src/app/admin/users/new-kombit-user-page/new-user.component.ts +++ b/src/app/admin/users/new-kombit-user-page/new-user.component.ts @@ -1,158 +1,136 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { UntypedFormControl } from '@angular/forms'; -import { Router } from '@angular/router'; -import { Organisation } from '@app/admin/organisation/organisation.model'; -import { OrganisationService } from '@app/admin/organisation/organisation.service'; -import { - CreateNewKombitUserDto, - CreateNewKombitUserFromFrontend, -} from '@app/admin/users/user.model'; -import { UserService } from '@app/admin/users/user.service'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { ReplaySubject, Subject, Subscription } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { UntypedFormControl } from "@angular/forms"; +import { Router } from "@angular/router"; +import { Organisation } from "@app/admin/organisation/organisation.model"; +import { OrganisationService } from "@app/admin/organisation/organisation.service"; +import { CreateNewKombitUserDto, CreateNewKombitUserFromFrontend } from "@app/admin/users/user.model"; +import { UserService } from "@app/admin/users/user.service"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { ReplaySubject, Subject, Subscription } from "rxjs"; +import { takeUntil } from "rxjs/operators"; @Component({ - selector: 'app-new-user', - templateUrl: './new-user.component.html', - styleUrls: ['./new-user.component.scss'], + selector: "app-new-user", + templateUrl: "./new-user.component.html", + styleUrls: ["./new-user.component.scss"], }) export class NewUserComponent implements OnInit { - public organisationSubscription: Subscription; - public userSubscription: Subscription; - public organisations: Organisation[]; - public formFailedSubmit = false; - public errorFields: string[]; - public errorMessages: unknown; - public createNewKombitUserFromFrontend: CreateNewKombitUserFromFrontend = new CreateNewKombitUserFromFrontend(); - public organisationsFilterCtrl: UntypedFormControl = new UntypedFormControl(); - public filteredOrganisations: ReplaySubject< - Organisation[] - > = new ReplaySubject(1); - public errorMessage: string; - private onDestroy = new Subject(); - - constructor( - private organisationService: OrganisationService, - private sharedService: SharedVariableService, - private userService: UserService, - private router: Router, - private translate: TranslateService, - private errorMessageService: ErrorMessageService - ) {} - - ngOnInit(): void { - if (history.state.fromKombit) { - this.translate.get([ - 'NEW_USER.FIRST_LOGIN', - 'USERS.EMAIL', - 'NAV.ORGANISATIONS', - 'NAV.BACK', - 'USERS.SAVE', - ]); - - this.getOrganisations(); - - this.organisationsFilterCtrl.valueChanges - .pipe(takeUntil(this.onDestroy)) - .subscribe(() => { - this.filterOrganisations(); - }); - } else { - this.router.navigate(['/not-found']); + public organisationSubscription: Subscription; + public userSubscription: Subscription; + public organisations: Organisation[]; + public formFailedSubmit = false; + public errorFields: string[]; + public errorMessages: unknown; + public createNewKombitUserFromFrontend: CreateNewKombitUserFromFrontend = new CreateNewKombitUserFromFrontend(); + public organisationsFilterCtrl: UntypedFormControl = new UntypedFormControl(); + public filteredOrganisations: ReplaySubject = new ReplaySubject(1); + public errorMessage: string; + private onDestroy = new Subject(); + + constructor( + private organisationService: OrganisationService, + private sharedService: SharedVariableService, + private userService: UserService, + private router: Router, + private translate: TranslateService, + private errorMessageService: ErrorMessageService + ) {} + + ngOnInit(): void { + if (history.state.fromKombit) { + this.translate.get(["NEW_USER.FIRST_LOGIN", "USERS.EMAIL", "NAV.ORGANISATIONS", "NAV.BACK", "USERS.SAVE"]); + + this.getOrganisations(); + + this.organisationsFilterCtrl.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe(() => { + this.filterOrganisations(); + }); + } else { + this.router.navigate(["/not-found"]); + } } - } - private filterOrganisations() { - if (!this.organisations) { - return; + private filterOrganisations() { + if (!this.organisations) { + return; + } + + // get the search keyword + let search = this.organisationsFilterCtrl?.value?.trim(); + if (!search) { + this.filteredOrganisations.next(this.organisations.slice()); + return; + } else { + search = search.toLowerCase(); + } + + const filtered = this.organisations.filter(org => { + return org.name.toLocaleLowerCase().indexOf(search) > -1; + }); + + this.filteredOrganisations.next(filtered); } - // get the search keyword - let search = this.organisationsFilterCtrl?.value?.trim(); - if (!search) { - this.filteredOrganisations.next(this.organisations.slice()); - return; - } else { - search = search.toLowerCase(); + onSubmit(): void { + this.resetErrors(); + + const createNewKombitUserDTO = this.mapToDto(this.createNewKombitUserFromFrontend); + + this.userService.updateNewKombit(createNewKombitUserDTO).subscribe( + () => { + this.router.navigate(["/applications"]); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } + ); } - const filtered = this.organisations.filter((org) => { - return org.name.toLocaleLowerCase().indexOf(search) > -1; - }); - - this.filteredOrganisations.next(filtered); - } - - onSubmit(): void { - this.resetErrors(); - - const createNewKombitUserDTO = this.mapToDto( - this.createNewKombitUserFromFrontend - ); - - this.userService.updateNewKombit(createNewKombitUserDTO).subscribe( - () => { - this.router.navigate(['/applications']); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } - - private mapToDto( - frontendModel: CreateNewKombitUserFromFrontend - ): CreateNewKombitUserDto { - const createNewKombitUserDTO = new CreateNewKombitUserDto(); - createNewKombitUserDTO.email = frontendModel.email; - createNewKombitUserDTO.requestedOrganizationIds = []; - - frontendModel.requestedOrganizations.forEach((organization) => { - createNewKombitUserDTO.requestedOrganizationIds.push(organization.id); - }); - - return createNewKombitUserDTO; - } - - public compare( - o1: Organisation | undefined, - o2: Organisation | undefined - ): boolean { - return o1?.id === o2?.id; - } - - public getOrganisations() { - this.organisations = this.sharedService.getOrganizationInfo(); - if (!this.organisations) { - this.filteredOrganisations.next(this.organisations.slice()); - } else { - this.organisationSubscription = this.organisationService - .getMinimalNoPerm() - .subscribe((orgs) => { - this.organisations = orgs.data; - this.filteredOrganisations.next(this.organisations.slice()); + private mapToDto(frontendModel: CreateNewKombitUserFromFrontend): CreateNewKombitUserDto { + const createNewKombitUserDTO = new CreateNewKombitUserDto(); + createNewKombitUserDTO.email = frontendModel.email; + createNewKombitUserDTO.requestedOrganizationIds = []; + + frontendModel.requestedOrganizations.forEach(organization => { + createNewKombitUserDTO.requestedOrganizationIds.push(organization.id); }); + + return createNewKombitUserDTO; } - } - - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } - - handleError(error: HttpErrorResponse) { - if (typeof error.error?.error === 'string' && typeof error.error?.message === 'string') { - this.errorMessage = error.error?.message; - } else { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; + + public compare(o1: Organisation | undefined, o2: Organisation | undefined): boolean { + return o1?.id === o2?.id; + } + + public getOrganisations() { + this.organisations = this.sharedService.getOrganizationInfo(); + if (!this.organisations) { + this.filteredOrganisations.next(this.organisations.slice()); + } else { + this.organisationSubscription = this.organisationService.getMinimalNoPerm().subscribe(orgs => { + this.organisations = orgs.data; + this.filteredOrganisations.next(this.organisations.slice()); + }); + } + } + + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + } + + handleError(error: HttpErrorResponse) { + if (typeof error.error?.error === "string" && typeof error.error?.message === "string") { + this.errorMessage = error.error?.message; + } else { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + } } - } } diff --git a/src/app/admin/users/user-detail/user-detail.component.html b/src/app/admin/users/user-detail/user-detail.component.html index 89edbc39e..5d9063222 100644 --- a/src/app/admin/users/user-detail/user-detail.component.html +++ b/src/app/admin/users/user-detail/user-detail.component.html @@ -1,23 +1,44 @@
- +
-
-

{{ 'USERS.DETAIL.HEADLINE' | translate }}

-

{{ 'USERS.DETAIL.EMAIL' | translate }}{{user.email}}

+
+

{{ "USERS.DETAIL.HEADLINE" | translate }}

+

+ {{ "USERS.DETAIL.EMAIL" | translate }}{{ user.email }} +

- {{ 'USERS.DETAIL.STATUS' | translate }}{{user.active | activeDeactive}}

+ {{ "USERS.DETAIL.STATUS" | translate }}{{ user.active | activeDeactive }} +

- {{ 'USERS.DETAIL.LAST-LOGIN' | translate }}{{user?.lastLogin | dkTime}}

+ {{ "USERS.DETAIL.LAST-LOGIN" | translate }}{{ user?.lastLogin | dkTime }}

-

{{ 'USERS.DETAIL.LAST-LOGIN' | translate }}{{ 'USERS.DETAIL.NO-LOGIN' | translate }} +

+ {{ "USERS.DETAIL.LAST-LOGIN" | translate }}{{ "USERS.DETAIL.NO-LOGIN" | translate }}

-

{{ 'USERS.DETAIL.GLOBALADMIN' | translate }} - {{((user.permissions | isGlobalAdmin) ? 'USERS.GLOBAL_ADMIN.TRUE' : 'USERS.GLOBAL_ADMIN.FALSE') | translate}} +

+ {{ "USERS.DETAIL.GLOBALADMIN" | translate }} + {{ + ((user.permissions | isGlobalAdmin) + ? "USERS.GLOBAL_ADMIN.TRUE" + : "USERS.GLOBAL_ADMIN.FALSE" + ) | translate + }}

@@ -26,10 +47,9 @@

{{ 'USERS.DETAIL.HEADLINE' | translate }}

- {{ 'USERS.DETAIL.PERMISSIONS' | translate }} + {{ "USERS.DETAIL.PERMISSIONS" | translate }}

- - +
diff --git a/src/app/admin/users/user-detail/user-detail.component.spec.ts b/src/app/admin/users/user-detail/user-detail.component.spec.ts index 700be6e28..d2ed2cb71 100644 --- a/src/app/admin/users/user-detail/user-detail.component.spec.ts +++ b/src/app/admin/users/user-detail/user-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { UserDetailComponent } from './user-detail.component'; +import { UserDetailComponent } from "./user-detail.component"; -describe('UserDetailComponent', () => { - let component: UserDetailComponent; - let fixture: ComponentFixture; +describe("UserDetailComponent", () => { + let component: UserDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ UserDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UserDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(UserDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UserDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/users/user-detail/user-detail.component.ts b/src/app/admin/users/user-detail/user-detail.component.ts index 46063d7c0..0cb6f3eb7 100644 --- a/src/app/admin/users/user-detail/user-detail.component.ts +++ b/src/app/admin/users/user-detail/user-detail.component.ts @@ -1,99 +1,93 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { Subscription } from 'rxjs'; -import { UserResponse } from '../user.model'; -import { UserService } from '../user.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { QuickActionButton } from '@shared/models/quick-action-button.model'; -import { Application } from '@applications/application.model'; -import { OrganisationResponse } from '@app/admin/organisation/organisation.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { environment } from '@environments/environment'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { Subscription } from "rxjs"; +import { UserResponse } from "../user.model"; +import { UserService } from "../user.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { QuickActionButton } from "@shared/models/quick-action-button.model"; +import { Application } from "@applications/application.model"; +import { OrganisationResponse } from "@app/admin/organisation/organisation.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { environment } from "@environments/environment"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-user-detail', - templateUrl: './user-detail.component.html', - styleUrls: ['./user-detail.component.scss'], + selector: "app-user-detail", + templateUrl: "./user-detail.component.html", + styleUrls: ["./user-detail.component.scss"], }) export class UserDetailComponent implements OnInit, OnDestroy { - isLoadingResults = true; - public pageLimit: number = environment.tablePageSize; - public pageTotal: number; - public pageOffset = 0; - public applications: Application[]; - private applicationsSubscription: Subscription; + isLoadingResults = true; + public pageLimit: number = environment.tablePageSize; + public pageTotal: number; + public pageOffset = 0; + public applications: Application[]; + private applicationsSubscription: Subscription; - organisation: OrganisationResponse; - user: UserResponse; - public backButton: BackButton = { - label: '', - routerLink: undefined, - }; - public buttons: QuickActionButton[] = [ - { - label: 'USERS.DELETE', - type: 'delete', - }, - { - label: 'USERS.EDIT', - type: 'edit', - }, - ]; - dropdownButton: DropdownButton; - id: number; - subscription: Subscription; - canEdit: boolean; + organisation: OrganisationResponse; + user: UserResponse; + public backButton: BackButton = { + label: "", + routerLink: undefined, + }; + public buttons: QuickActionButton[] = [ + { + label: "USERS.DELETE", + type: "delete", + }, + { + label: "USERS.EDIT", + type: "edit", + }, + ]; + dropdownButton: DropdownButton; + id: number; + subscription: Subscription; + canEdit: boolean; - constructor( - public translate: TranslateService, - private route: ActivatedRoute, - private userService: UserService, - private router: Router, - private meService: MeService - ) {} + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + private userService: UserService, + private router: Router, + private meService: MeService + ) {} - ngOnInit(): void { - this.translate.use('da'); - this.id = +this.route.snapshot.paramMap.get('user-id'); - if (this.id > 0) { - this.getUser(this.id); - this.dropdownButton = { - label: '', - editRouterLink: 'edit-user', - isErasable: false, - }; + ngOnInit(): void { + this.translate.use("da"); + this.id = +this.route.snapshot.paramMap.get("user-id"); + if (this.id > 0) { + this.getUser(this.id); + this.dropdownButton = { + label: "", + editRouterLink: "edit-user", + isErasable: false, + }; + } + this.translate.get(["NAV.USERS", "USERS.DETAIL.DROPDOWN"]).subscribe(translations => { + this.backButton.label = translations["NAV.USERS"]; + this.dropdownButton.label = translations["USERS.DETAIL.DROPDOWN"]; + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); } - this.translate - .get(['NAV.USERS', 'USERS.DETAIL.DROPDOWN']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.USERS']; - this.dropdownButton.label = translations['USERS.DETAIL.DROPDOWN']; - }); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.UserAdministrationWrite - ); - } - private getUser(id: number) { - this.subscription = this.userService - .getOne(id, true) - .subscribe((response) => { - this.user = response; - this.isLoadingResults = false; - }); - } + private getUser(id: number) { + this.subscription = this.userService.getOne(id, true).subscribe(response => { + this.user = response; + this.isLoadingResults = false; + }); + } - onEditUser() { - this.router.navigate(['edit-user'], { relativeTo: this.route }); - } + onEditUser() { + this.router.navigate(["edit-user"], { relativeTo: this.route }); + } - ngOnDestroy() { - // prevent memory leak by unsubscribing - if (this.applicationsSubscription) { - this.applicationsSubscription.unsubscribe(); + ngOnDestroy() { + // prevent memory leak by unsubscribing + if (this.applicationsSubscription) { + this.applicationsSubscription.unsubscribe(); + } } - } } diff --git a/src/app/admin/users/user-edit/user-edit.component.html b/src/app/admin/users/user-edit/user-edit.component.html index a7add0d85..d56c88b84 100644 --- a/src/app/admin/users/user-edit/user-edit.component.html +++ b/src/app/admin/users/user-edit/user-edit.component.html @@ -1,56 +1,98 @@ - +
  • - {{error | translate}} + {{ error | translate }}
  • - {{errorMessage | translate}} + {{ errorMessage | translate }}
- * - {{ "USERS.FORM.NAME" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('name'), + 'is-valid': formFailedSubmit && !errorFields.includes('name') + }" + />
- * - + * +
- * - {{ "USERS.FORM.PASSWORD" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('password'), + 'is-valid': formFailedSubmit && !errorFields.includes('password') + }" + />
- {{'USERS.FORM.ACTIVE' | translate}} + {{ "USERS.FORM.ACTIVE" | translate }}
- {{'USERS.FORM.GLOBAL-ADMIN' | translate}} + {{ "USERS.FORM.GLOBAL-ADMIN" | translate }}
- - + +
diff --git a/src/app/admin/users/user-edit/user-edit.component.spec.ts b/src/app/admin/users/user-edit/user-edit.component.spec.ts index 69e3971d8..de20938bb 100644 --- a/src/app/admin/users/user-edit/user-edit.component.spec.ts +++ b/src/app/admin/users/user-edit/user-edit.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { UserEditComponent } from './user-edit.component'; +import { UserEditComponent } from "./user-edit.component"; -describe('UserEditComponent', () => { - let component: UserEditComponent; - let fixture: ComponentFixture; +describe("UserEditComponent", () => { + let component: UserEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ UserEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UserEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(UserEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UserEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/admin/users/user-edit/user-edit.component.ts b/src/app/admin/users/user-edit/user-edit.component.ts index b8e5b61bd..1d272bd62 100644 --- a/src/app/admin/users/user-edit/user-edit.component.ts +++ b/src/app/admin/users/user-edit/user-edit.component.ts @@ -1,143 +1,137 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { UntypedFormGroup } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; -import { UserRequest } from '../user.model'; -import { TranslateService } from '@ngx-translate/core'; -import { UserService } from '../user.service'; -import { Subscription } from 'rxjs'; -import { Location } from '@angular/common'; -import { PermissionType } from '@app/admin/permission/permission.model'; -import { AuthService, CurrentUserInfoResponse } from '@auth/auth.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { UntypedFormGroup } from "@angular/forms"; +import { ActivatedRoute } from "@angular/router"; +import { UserRequest } from "../user.model"; +import { TranslateService } from "@ngx-translate/core"; +import { UserService } from "../user.service"; +import { Subscription } from "rxjs"; +import { Location } from "@angular/common"; +import { PermissionType } from "@app/admin/permission/permission.model"; +import { AuthService, CurrentUserInfoResponse } from "@auth/auth.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-user-edit', - templateUrl: './user-edit.component.html', - styleUrls: ['./user-edit.component.scss'], + selector: "app-user-edit", + templateUrl: "./user-edit.component.html", + styleUrls: ["./user-edit.component.scss"], }) export class UserEditComponent implements OnInit { - user = new UserRequest(); - public errorMessage: string; - public errorMessages: any; - public errorFields: string[]; - public formFailedSubmit = false; - public form: UntypedFormGroup; - public backButtonTitle = ''; - public title = ''; - public submitButton = ''; - id: number; - subscription: Subscription; - isGlobalAdmin = false; - isKombit: boolean; - canEdit: boolean; + user = new UserRequest(); + public errorMessage: string; + public errorMessages: any; + public errorFields: string[]; + public formFailedSubmit = false; + public form: UntypedFormGroup; + public backButtonTitle = ""; + public title = ""; + public submitButton = ""; + id: number; + subscription: Subscription; + isGlobalAdmin = false; + isKombit: boolean; + canEdit: boolean; - constructor( - private translate: TranslateService, - private route: ActivatedRoute, - private userService: UserService, - private location: Location, - private authService: AuthService, - private sharedVariableService: SharedVariableService, - private meService: MeService - ) {} + constructor( + private translate: TranslateService, + private route: ActivatedRoute, + private userService: UserService, + private location: Location, + private authService: AuthService, + private sharedVariableService: SharedVariableService, + private meService: MeService + ) {} - ngOnInit(): void { - this.translate.use('da'); - this.translate - .get(['NAV.USERS', 'FORM.EDIT-USERS', 'USERS.SAVE']) - .subscribe((translations) => { - this.backButtonTitle = translations['NAV.USERS']; - this.title = translations['FORM.EDIT-USERS']; - this.submitButton = translations['USERS.SAVE']; - }); - this.id = +this.route.snapshot.paramMap.get('user-id'); - if (this.id > 0) { - this.getUser(this.id); - } else { - // Default active to be true if we're creating a new user. - this.user.active = true; + ngOnInit(): void { + this.translate.use("da"); + this.translate.get(["NAV.USERS", "FORM.EDIT-USERS", "USERS.SAVE"]).subscribe(translations => { + this.backButtonTitle = translations["NAV.USERS"]; + this.title = translations["FORM.EDIT-USERS"]; + this.submitButton = translations["USERS.SAVE"]; + }); + this.id = +this.route.snapshot.paramMap.get("user-id"); + if (this.id > 0) { + this.getUser(this.id); + } else { + // Default active to be true if we're creating a new user. + this.user.active = true; + } + this.amIGlobalAdmin(); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); } - this.amIGlobalAdmin(); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); - } - private getUser(id: number) { - this.subscription = this.userService.getOne(id).subscribe((response) => { - this.user.name = response.name; - this.user.email = response.email; - this.user.id = response.id; - this.user.active = response.active; - this.user.globalAdmin = response.permissions.some((response) => - this.meService.hasPermissions(response, PermissionType.GlobalAdmin) - ); - this.isKombit = response.nameId != null; - // We cannot set the password. - }); - } + private getUser(id: number) { + this.subscription = this.userService.getOne(id).subscribe(response => { + this.user.name = response.name; + this.user.email = response.email; + this.user.id = response.id; + this.user.active = response.active; + this.user.globalAdmin = response.permissions.some(response => + this.meService.hasPermissions(response, PermissionType.GlobalAdmin) + ); + this.isKombit = response.nameId != null; + // We cannot set the password. + }); + } - amIGlobalAdmin() { - this.isGlobalAdmin = this.meService.hasGlobalAdmin(); - } + amIGlobalAdmin() { + this.isGlobalAdmin = this.meService.hasGlobalAdmin(); + } - private create(): void { - this.userService.post(this.user).subscribe( - (response) => { - console.log(response); - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.showError(error); - } - ); - } + private create(): void { + this.userService.post(this.user).subscribe( + response => { + console.log(response); + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.showError(error); + } + ); + } - private update(): void { - this.userService.put(this.user, this.id).subscribe( - (response) => { - this.routeBack(); - }, - (error) => { - this.showError(error); - } - ); - } + private update(): void { + this.userService.put(this.user, this.id).subscribe( + response => { + this.routeBack(); + }, + error => { + this.showError(error); + } + ); + } - onSubmit(): void { - if (this.user.id) { - this.update(); - } else { - this.create(); + onSubmit(): void { + if (this.user.id) { + this.update(); + } else { + this.create(); + } } - } - private showError(error: HttpErrorResponse) { - this.errorFields = []; - this.errorMessages = []; + private showError(error: HttpErrorResponse) { + this.errorFields = []; + this.errorMessages = []; - if (typeof error.error?.message === 'string') { - this.errorMessage = error.error.message; - if ( - error.error.message === 'MESSAGE.PASSWORD-DOES-NOT-MEET-REQUIREMENTS' - ) { - this.errorFields.push('password'); - } - } else if (error.error?.message?.length > 0) { - error.error.message.forEach((err) => { - this.errorFields.push(err.property); - this.errorMessages = this.errorMessages.concat( - Object.values(err.constraints) - ); - }); - } else { - this.errorMessage = error.message; + if (typeof error.error?.message === "string") { + this.errorMessage = error.error.message; + if (error.error.message === "MESSAGE.PASSWORD-DOES-NOT-MEET-REQUIREMENTS") { + this.errorFields.push("password"); + } + } else if (error.error?.message?.length > 0) { + error.error.message.forEach(err => { + this.errorFields.push(err.property); + this.errorMessages = this.errorMessages.concat(Object.values(err.constraints)); + }); + } else { + this.errorMessage = error.message; + } + this.formFailedSubmit = true; } - this.formFailedSubmit = true; - } - routeBack(): void { - this.location.back(); - } + routeBack(): void { + this.location.back(); + } } diff --git a/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.html b/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.html index 6201b134e..64f488cf2 100644 --- a/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.html +++ b/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.html @@ -1,7 +1,4 @@
- - + +
diff --git a/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.ts b/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.ts index 199f85dd3..f93a529cc 100644 --- a/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.ts +++ b/src/app/admin/users/user-list/awaiting-user-tab/awaiting-users-table-tab.component.ts @@ -1,16 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; +import { Component, OnInit } from "@angular/core"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; @Component({ - selector: 'app-awaiting-user-tab', - templateUrl: './awaiting-users-table-tab.component.html', - styleUrls: ['./awaiting-users-table-tab.component.scss'], + selector: "app-awaiting-user-tab", + templateUrl: "./awaiting-users-table-tab.component.html", + styleUrls: ["./awaiting-users-table-tab.component.scss"], }) export class AwaitingUsersTableTabComponent implements OnInit { - organizationId: number; - constructor(private globalService: SharedVariableService) { - this.organizationId = this.globalService.getSelectedOrganisationId(); - } + organizationId: number; + constructor(private globalService: SharedVariableService) { + this.organizationId = this.globalService.getSelectedOrganisationId(); + } - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html b/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html index 88817e562..8a418357d 100644 --- a/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html +++ b/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.html @@ -1,90 +1,78 @@
-
- -
-
- {{ errorMessage | translate }} -
- - - - - - +
+ +
+
+ {{ errorMessage | translate }} +
+
- {{ 'USERS.NAME' | translate }} - -

{{ element.name }}

-
+ + + + + - - - - - + + + + + - - - - - + + + + + - - -
+ {{ "USERS.NAME" | translate }} + +

{{ element.name }}

+
- {{ 'USERS.EMAIL' | translate }} - -

{{ element.email }}

-
+ {{ "USERS.EMAIL" | translate }} + +

{{ element.email }}

+
- - + +
- - + + + + +
diff --git a/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.ts b/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.ts index a7665b976..359157a61 100644 --- a/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.ts +++ b/src/app/admin/users/user-list/awaiting-users-table/awaiting-users-table.component.ts @@ -1,149 +1,142 @@ -import { AfterViewInit, Component, Input, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, Input, ViewChild } from "@angular/core"; import { - RejectUserDto, - UserGetManyResponse, - UserResponse, - UserResponsePerRequestedOrganization, -} from '../../user.model'; -import { UserService } from '../../user.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { environment } from '@environments/environment'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { TranslateService } from '@ngx-translate/core'; -import { merge, Observable, of as observableOf } from 'rxjs'; -import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; -import { MeService } from '@shared/services/me.service'; + RejectUserDto, + UserGetManyResponse, + UserResponse, + UserResponsePerRequestedOrganization, +} from "../../user.model"; +import { UserService } from "../../user.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { environment } from "@environments/environment"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { TranslateService } from "@ngx-translate/core"; +import { merge, Observable, of as observableOf } from "rxjs"; +import { catchError, map, startWith, switchMap } from "rxjs/operators"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; +import { MeService } from "@shared/services/me.service"; @Component({ - selector: 'app-awaiting-users-table', - templateUrl: './awaiting-users-table.component.html', - styleUrls: ['./awaiting-users-table.component.scss'], + selector: "app-awaiting-users-table", + templateUrl: "./awaiting-users-table.component.html", + styleUrls: ["./awaiting-users-table.component.scss"], }) export class AwaitingUsersTableComponent implements AfterViewInit { - displayedColumns: string[] = ['name', 'email', 'menu']; - users: UserResponsePerRequestedOrganization[]; + displayedColumns: string[] = ["name", "email", "menu"]; + users: UserResponsePerRequestedOrganization[]; - public pageSize = environment.tablePageSize; - pageSizeOptions = DefaultPageSizeOptions; + public pageSize = environment.tablePageSize; + pageSizeOptions = DefaultPageSizeOptions; - resultsLength = 0; - public errorMessage: string; - isLoadingResults = true; - message: string; - infoTitle: string; - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; + resultsLength = 0; + public errorMessage: string; + isLoadingResults = true; + message: string; + infoTitle: string; + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; - @Input() permissionId?: number; - @Input() canSort = true; - organizationId: number; + @Input() permissionId?: number; + @Input() canSort = true; + organizationId: number; - constructor( - public translate: TranslateService, - private userService: UserService, - private sharedService: SharedVariableService, - private deleteDialogService: DeleteDialogService, - private meService: MeService - ) { - this.organizationId = this.sharedService.getSelectedOrganisationId(); - } + constructor( + public translate: TranslateService, + private userService: UserService, + private sharedService: SharedVariableService, + private deleteDialogService: DeleteDialogService, + private meService: MeService + ) { + this.organizationId = this.sharedService.getSelectedOrganisationId(); + } - ngAfterViewInit() { - // If the user changes the sort order, reset back to the first page. - this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + ngAfterViewInit() { + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); - merge(this.sort.sortChange, this.paginator.page) - .pipe( - startWith({}), - switchMap(() => { - this.isLoadingResults = true; - return this.getUsers(this.sort.active, this.sort.direction); - }), - map((data) => { - // Flip flag to show that loading has finished. - this.isLoadingResults = false; - this.resultsLength = data.count; + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + return this.getUsers(this.sort.active, this.sort.direction); + }), + map(data => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.resultsLength = data.count; - return data.data; - }), - catchError(() => { - this.isLoadingResults = false; - return observableOf([] as UserResponse[]); - }) - ) - .subscribe((userResponses) => { - this.users = []; + return data.data; + }), + catchError(() => { + this.isLoadingResults = false; + return observableOf([] as UserResponse[]); + }) + ) + .subscribe(userResponses => { + this.users = []; - // Flatten users so each table row is exactly one request - for (const response of userResponses) { - const { requestedOrganizations, ...user} = response; + // Flatten users so each table row is exactly one request + for (const response of userResponses) { + const { requestedOrganizations, ...user } = response; - for (const organizationId of response.requestedOrganizations) { - this.users.push({ - ...user, - requestedOrganization: organizationId, + for (const organizationId of response.requestedOrganizations) { + this.users.push({ + ...user, + requestedOrganization: organizationId, + }); + } + } }); - } - } - }); - this.translate - .get(['USERS.DIALOG.QUESTION-REJECT', 'USERS.DIALOG.HEAD-REJECT']) - .subscribe((translations) => { - this.message = translations['USERS.DIALOG.QUESTION-REJECT']; - this.infoTitle = translations['USERS.DIALOG.HEAD-REJECT']; - }); - } + this.translate.get(["USERS.DIALOG.QUESTION-REJECT", "USERS.DIALOG.HEAD-REJECT"]).subscribe(translations => { + this.message = translations["USERS.DIALOG.QUESTION-REJECT"]; + this.infoTitle = translations["USERS.DIALOG.HEAD-REJECT"]; + }); + } - getUsers( - orderByColumn: string, - orderByDirection: string - ): Observable { - if(this.meService.hasGlobalAdmin()) { - return this.userService.getAwaitingUsers( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByColumn, - orderByDirection - ); - } else { - return this.userService.getAwaitingUsersForOrganization( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - this.organizationId, - orderByColumn, - orderByDirection - ); - } - } + getUsers(orderByColumn: string, orderByDirection: string): Observable { + if (this.meService.hasGlobalAdmin()) { + return this.userService.getAwaitingUsers( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByColumn, + orderByDirection + ); + } else { + return this.userService.getAwaitingUsersForOrganization( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + this.organizationId, + orderByColumn, + orderByDirection + ); + } + } - rejectUser(userId: number, organizationId: number) { - this.deleteDialogService - .showSimpleDialog(this.message, false, true, false, this.infoTitle, true) - .subscribe((response) => { - if (response) { - const rejectUserOrgDto: RejectUserDto = { - orgId: organizationId, - userIdToReject: userId, - }; + rejectUser(userId: number, organizationId: number) { + this.deleteDialogService + .showSimpleDialog(this.message, false, true, false, this.infoTitle, true) + .subscribe(response => { + if (response) { + const rejectUserOrgDto: RejectUserDto = { + orgId: organizationId, + userIdToReject: userId, + }; - this.userService - .rejectUser(rejectUserOrgDto) - .subscribe((response) => { - if (response) { - this.paginator.page.emit({ - pageIndex: this.paginator.pageIndex, - pageSize: this.paginator.pageSize, - length: this.resultsLength, - }); - } else { - this.errorMessage = response?.name; - } + this.userService.rejectUser(rejectUserOrgDto).subscribe(response => { + if (response) { + this.paginator.page.emit({ + pageIndex: this.paginator.pageIndex, + pageSize: this.paginator.pageSize, + length: this.resultsLength, + }); + } else { + this.errorMessage = response?.name; + } + }); + } }); - } - }); - } + } } diff --git a/src/app/admin/users/user-list/user-list.component.html b/src/app/admin/users/user-list/user-list.component.html index a2510123b..42393dc94 100644 --- a/src/app/admin/users/user-list/user-list.component.html +++ b/src/app/admin/users/user-list/user-list.component.html @@ -1,21 +1,24 @@
- diff --git a/src/app/admin/users/user-list/user-list.component.ts b/src/app/admin/users/user-list/user-list.component.ts index 3c3b89cd3..75d024348 100644 --- a/src/app/admin/users/user-list/user-list.component.ts +++ b/src/app/admin/users/user-list/user-list.component.ts @@ -1,46 +1,44 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { TranslateService } from '@ngx-translate/core'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { MeService } from '@shared/services/me.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { Router } from '@angular/router'; +import { Component, OnInit } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { TranslateService } from "@ngx-translate/core"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { MeService } from "@shared/services/me.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { Router } from "@angular/router"; @Component({ - selector: 'app-user-list', - templateUrl: './user-list.component.html', - styleUrls: ['./user-list.component.scss'], + selector: "app-user-list", + templateUrl: "./user-list.component.html", + styleUrls: ["./user-list.component.scss"], }) export class UserListComponent implements OnInit { - public navTabs: any[] = [ - { - label: 'USERS.EXISTING-USERS', - link: './existing', - index: 0, - }, - { - label: 'USERS.AWAITING-USERS', - link: './awaiting', - index: 1, - }, - ]; - canEdit: boolean; - constructor( - private titleService: Title, - private translate: TranslateService, - private meService: MeService, - public router: Router - ) {} + public navTabs: any[] = [ + { + label: "USERS.EXISTING-USERS", + link: "./existing", + index: 0, + }, + { + label: "USERS.AWAITING-USERS", + link: "./awaiting", + index: 1, + }, + ]; + canEdit: boolean; + constructor( + private titleService: Title, + private translate: TranslateService, + private meService: MeService, + public router: Router + ) {} - ngOnInit(): void { - this.translate.get(['TITLE.USER']).subscribe((translations) => { - this.titleService.setTitle(translations['TITLE.USER']); - }); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.UserAdministrationWrite - ); - if (this.router.url.split('/').length <= 3) { - this.router.navigateByUrl('admin/users/existing', { replaceUrl: true }); + ngOnInit(): void { + this.translate.get(["TITLE.USER"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.USER"]); + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.UserAdministrationWrite); + if (this.router.url.split("/").length <= 3) { + this.router.navigateByUrl("admin/users/existing", { replaceUrl: true }); + } } - } } diff --git a/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.html b/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.html index b1490a879..220655e66 100644 --- a/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.html +++ b/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.html @@ -1,7 +1,4 @@
- - + +
diff --git a/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.ts b/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.ts index 899041fe6..63356040d 100644 --- a/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.ts +++ b/src/app/admin/users/user-list/user-table-tab/user-table-tab.component.ts @@ -1,16 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; +import { Component, OnInit } from "@angular/core"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; @Component({ - selector: 'app-user-table-tab', - templateUrl: './user-table-tab.component.html', - styleUrls: ['./user-table-tab.component.scss'], + selector: "app-user-table-tab", + templateUrl: "./user-table-tab.component.html", + styleUrls: ["./user-table-tab.component.scss"], }) export class UserTableTabComponent implements OnInit { - organizationId: number; - constructor(private globalService: SharedVariableService) { - this.organizationId = this.globalService.getSelectedOrganisationId(); - } + organizationId: number; + constructor(private globalService: SharedVariableService) { + this.organizationId = this.globalService.getSelectedOrganisationId(); + } - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/admin/users/user-list/user-table/user-table.component.html b/src/app/admin/users/user-list/user-table/user-table.component.html index 56fe30c4f..3ea884029 100644 --- a/src/app/admin/users/user-list/user-table/user-table.component.html +++ b/src/app/admin/users/user-list/user-table/user-table.component.html @@ -3,33 +3,39 @@
- + {{ "USERS.EMAIL" | translate }} + + {{ "USERS.GLOBALADMIN" | translate }} + @@ -37,20 +43,21 @@ + {{ "USERS.STATUS" | translate }} + + {{ "USERS.LOGIN" | translate }} + - +
- {{ 'USERS.NAME' | translate }} + {{ "USERS.NAME" | translate }} - {{element.name}} + {{ element.name }} - {{ 'USERS.EMAIL' | translate }} -

{{element.email}}

+

{{ element.email }}

- {{ 'USERS.GLOBALADMIN' | translate }} -

{{((element.permissions | isGlobalAdmin) ? 'USERS.GLOBAL_ADMIN.TRUE' : 'USERS.GLOBAL_ADMIN.FALSE') | translate}} +

+ {{ + ((element.permissions | isGlobalAdmin) ? "USERS.GLOBAL_ADMIN.TRUE" : "USERS.GLOBAL_ADMIN.FALSE") + | translate + }}

- {{ 'USERS.STATUS' | translate }} - -

{{element.active | activeDeactive}}

+

{{ element.active | activeDeactive }}

- {{ 'USERS.LOGIN' | translate }}
-

{{element.lastLogin | tableDatePipe}}

+

{{ element.lastLogin | tableDatePipe }}

Ikke logget på endnu

@@ -62,15 +69,23 @@
-
- +
diff --git a/src/app/admin/users/user-list/user-table/user-table.component.ts b/src/app/admin/users/user-list/user-table/user-table.component.ts index 547f8c6cd..5e4cee3ce 100644 --- a/src/app/admin/users/user-list/user-table/user-table.component.ts +++ b/src/app/admin/users/user-list/user-table/user-table.component.ts @@ -1,111 +1,97 @@ -import { AfterViewInit, Component, Input, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { TranslateService } from '@ngx-translate/core'; -import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { UserGetManyResponse, UserResponse } from '../../user.model'; -import { UserService } from '../../user.service'; -import { merge, Observable, of as observableOf } from 'rxjs'; -import { environment } from '@environments/environment'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; -import { MeService } from '@shared/services/me.service'; +import { AfterViewInit, Component, Input, ViewChild } from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { TranslateService } from "@ngx-translate/core"; +import { catchError, map, startWith, switchMap } from "rxjs/operators"; +import { UserGetManyResponse, UserResponse } from "../../user.model"; +import { UserService } from "../../user.service"; +import { merge, Observable, of as observableOf } from "rxjs"; +import { environment } from "@environments/environment"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; +import { MeService } from "@shared/services/me.service"; @Component({ - selector: 'app-user-table', - templateUrl: './user-table.component.html', - styleUrls: ['./user-table.component.scss'], + selector: "app-user-table", + templateUrl: "./user-table.component.html", + styleUrls: ["./user-table.component.scss"], }) export class UserTableComponent implements AfterViewInit { - displayedColumns: string[] = [ - 'name', - 'email', - 'global', - 'status', - 'lastLogin', - 'menu', - ]; - data: UserResponse[]; + displayedColumns: string[] = ["name", "email", "global", "status", "lastLogin", "menu"]; + data: UserResponse[]; - public pageSize = environment.tablePageSize; - pageSizeOptions = DefaultPageSizeOptions; - resultsLength = 0; - isLoadingResults = true; - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; + public pageSize = environment.tablePageSize; + pageSizeOptions = DefaultPageSizeOptions; + resultsLength = 0; + isLoadingResults = true; + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; - // If supplied, users will only be retrieved for the specified organization - // If supplied, permissionId will ignored, even if supplied - @Input() organizationId?: number; + // If supplied, users will only be retrieved for the specified organization + // If supplied, permissionId will ignored, even if supplied + @Input() organizationId?: number; - // If supplied, users will be retrieved on the permissionId (userGroup/brugerGruppe) - @Input() permissionId?: number; + // If supplied, users will be retrieved on the permissionId (userGroup/brugerGruppe) + @Input() permissionId?: number; - @Input() canSort = true; - isGlobalAdmin: boolean; + @Input() canSort = true; + isGlobalAdmin: boolean; - constructor( - public translate: TranslateService, - private userService: UserService, - private meService: MeService - ) { - this.isGlobalAdmin = this.meService.hasGlobalAdmin(); - } + constructor(public translate: TranslateService, private userService: UserService, private meService: MeService) { + this.isGlobalAdmin = this.meService.hasGlobalAdmin(); + } - getUsers( - orderByColumn: string, - orderByDirection: string - ): Observable { - if (this.organizationId !== null && this.organizationId !== undefined) { - if (this.isGlobalAdmin) { - return this.userService.getMultiple( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByColumn, - orderByDirection - ); - } else { - return this.userService.getMultipleByOrganization( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByColumn, - orderByDirection, - this.organizationId - ); - } - } else { - return this.userService.getMultiple( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByColumn, - orderByDirection, - this.permissionId - ); + getUsers(orderByColumn: string, orderByDirection: string): Observable { + if (this.organizationId !== null && this.organizationId !== undefined) { + if (this.isGlobalAdmin) { + return this.userService.getMultiple( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByColumn, + orderByDirection + ); + } else { + return this.userService.getMultipleByOrganization( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByColumn, + orderByDirection, + this.organizationId + ); + } + } else { + return this.userService.getMultiple( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByColumn, + orderByDirection, + this.permissionId + ); + } } - } - ngAfterViewInit() { - // If the user changes the sort order, reset back to the first page. - this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + ngAfterViewInit() { + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); - merge(this.sort.sortChange, this.paginator.page) - .pipe( - startWith({}), - switchMap(() => { - this.isLoadingResults = true; - return this.getUsers(this.sort.active, this.sort.direction); - }), - map((data) => { - // Flip flag to show that loading has finished. - this.isLoadingResults = false; - this.resultsLength = data.count; + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + return this.getUsers(this.sort.active, this.sort.direction); + }), + map(data => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.resultsLength = data.count; - return data.data; - }), - catchError(() => { - this.isLoadingResults = false; - return observableOf([]); - }) - ) - .subscribe((data) => (this.data = data)); - } + return data.data; + }), + catchError(() => { + this.isLoadingResults = false; + return observableOf([]); + }) + ) + .subscribe(data => (this.data = data)); + } } diff --git a/src/app/admin/users/user-minimal.model.ts b/src/app/admin/users/user-minimal.model.ts index 2920de722..782c48de8 100644 --- a/src/app/admin/users/user-minimal.model.ts +++ b/src/app/admin/users/user-minimal.model.ts @@ -5,4 +5,4 @@ export interface UserMinimalResponse { export interface UserMinimal { id: number; name: string; -} \ No newline at end of file +} diff --git a/src/app/admin/users/user-minimal.service.ts b/src/app/admin/users/user-minimal.service.ts index 8aa36f43d..d613d05ef 100644 --- a/src/app/admin/users/user-minimal.service.ts +++ b/src/app/admin/users/user-minimal.service.ts @@ -1,19 +1,17 @@ -import { Injectable } from '@angular/core'; -import { RestService } from '@shared/services/rest.service'; -import { Observable } from 'rxjs'; -import { UserMinimal, UserMinimalResponse } from './user-minimal.model'; +import { Injectable } from "@angular/core"; +import { RestService } from "@shared/services/rest.service"; +import { Observable } from "rxjs"; +import { UserMinimal, UserMinimalResponse } from "./user-minimal.model"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class UserMinimalService { - - URL = 'user/minimal'; - URL_NEW_KOMBIT = "kombitCreation/minimalUsers" + URL = "user/minimal"; + URL_NEW_KOMBIT = "kombitCreation/minimalUsers"; private userMinimalList: UserMinimal[]; - constructor( - private restService: RestService) { } + constructor(private restService: RestService) {} getUserMinimalRest(): Observable { return this.restService.get(this.URL); @@ -24,36 +22,29 @@ export class UserMinimalService { } setUserMinimalList() { - return this.getUserMinimalRestNewKombit().subscribe( - (response: UserMinimalResponse) => { - localStorage.setItem( - 'userMinimalList', - JSON.stringify(response.users) - ); - this.userMinimalList = response.users; - } - ); + return this.getUserMinimalRestNewKombit().subscribe((response: UserMinimalResponse) => { + localStorage.setItem("userMinimalList", JSON.stringify(response.users)); + this.userMinimalList = response.users; + }); } private getUserMinimalList(): UserMinimal[] { if (this.userMinimalList) { return this.userMinimalList; } - return new Object(JSON.parse(localStorage.getItem('userMinimalList'))) as UserMinimal[]; + return new Object(JSON.parse(localStorage.getItem("userMinimalList"))) as UserMinimal[]; } getUserNameFrom(id: number): string { - const username = this.getUserMinimalList().find( - user => user.id === id - )?.name; + const username = this.getUserMinimalList().find(user => user.id === id)?.name; return username; } setHasSeenWelcomeScreen(): void { - localStorage.setItem('hasSeenWelcomeScreen', true.toString()); + localStorage.setItem("hasSeenWelcomeScreen", true.toString()); } getHasSeenWelcomeScreen(): boolean { - return !!localStorage.getItem('hasSeenWelcomeScreen'); + return !!localStorage.getItem("hasSeenWelcomeScreen"); } } diff --git a/src/app/admin/users/user-page/user-page.component.html b/src/app/admin/users/user-page/user-page.component.html index ff1785a06..1b89fc986 100644 --- a/src/app/admin/users/user-page/user-page.component.html +++ b/src/app/admin/users/user-page/user-page.component.html @@ -1,66 +1,67 @@
-
-
-
-

- {{ 'USER_PAGE.AWAITING_CONFIRMATION' | translate }} -

- -

- {{ 'USER_PAGE.APPLY_ORGANISATIONS' | translate }} -

-
-

{{ 'USER_PAGE.APPLIED_ORGANISATIONS' | translate }}

-

- {{ org.name }} -

-

- {{ 'USER_PAGE.NO_APPLIED_ORGS' | translate }} -

-
- {{ 'USER_PAGE.QUESTION_APPLY_ORGANISATIONS' | translate }} -
-
+
+
+
+

+ {{ "USER_PAGE.AWAITING_CONFIRMATION" | translate }} +

+ +

+ {{ "USER_PAGE.APPLY_ORGANISATIONS" | translate }} +

+
+

{{ "USER_PAGE.APPLIED_ORGANISATIONS" | translate }}

+

+ {{ org.name }} +

+

+ {{ "USER_PAGE.NO_APPLIED_ORGS" | translate }} +

+
+ {{ "USER_PAGE.QUESTION_APPLY_ORGANISATIONS" | translate }} +
+
-
-
-
    -
  • - {{ error | translate }} -
  • -
-
-
- - + +
+
    +
  • + {{ error | translate }} +
  • +
+
+
+ + - {{ org.name }} - -
-
- -
- -
+ {{ org.name }} + +
+
+ +
+ +
+
-
diff --git a/src/app/admin/users/user-page/user-page.component.scss b/src/app/admin/users/user-page/user-page.component.scss index fac1b736a..37bcf65cf 100644 --- a/src/app/admin/users/user-page/user-page.component.scss +++ b/src/app/admin/users/user-page/user-page.component.scss @@ -1,7 +1,7 @@ .newOrganisationsHeadLine { - margin-top: 15px; + margin-top: 15px; } .noOrgs { - font-style: italic; - font-size: 15px; + font-style: italic; + font-size: 15px; } diff --git a/src/app/admin/users/user-page/user-page.component.ts b/src/app/admin/users/user-page/user-page.component.ts index 5772e9029..697f14ab1 100644 --- a/src/app/admin/users/user-page/user-page.component.ts +++ b/src/app/admin/users/user-page/user-page.component.ts @@ -1,203 +1,186 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { UntypedFormControl } from '@angular/forms'; -import { Organisation } from '@app/admin/organisation/organisation.model'; -import { OrganisationService } from '@app/admin/organisation/organisation.service'; -import { - UpdateUserOrgFromFrontend, - UpdateUserOrgsDto, - UserResponse, -} from '@app/admin/users/user.model'; -import { UserService } from '@app/admin/users/user.service'; -import { CurrentUserInfoResponse } from '@auth/auth.service'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { ReplaySubject, Subject, Subscription } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { UntypedFormControl } from "@angular/forms"; +import { Organisation } from "@app/admin/organisation/organisation.model"; +import { OrganisationService } from "@app/admin/organisation/organisation.service"; +import { UpdateUserOrgFromFrontend, UpdateUserOrgsDto, UserResponse } from "@app/admin/users/user.model"; +import { UserService } from "@app/admin/users/user.service"; +import { CurrentUserInfoResponse } from "@auth/auth.service"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { ReplaySubject, Subject, Subscription } from "rxjs"; +import { takeUntil } from "rxjs/operators"; @Component({ - selector: 'app-user-page', - templateUrl: './user-page.component.html', - styleUrls: ['./user-page.component.scss'], + selector: "app-user-page", + templateUrl: "./user-page.component.html", + styleUrls: ["./user-page.component.scss"], }) export class UserPageComponent implements OnInit { - public updateUserOrgs: UpdateUserOrgsDto = new UpdateUserOrgsDto(); - public updateUserOrgsFromFrontend: UpdateUserOrgFromFrontend = new UpdateUserOrgFromFrontend(); - public organisationSubscription: Subscription; - public formFailedSubmit = false; - public backButtonTitle: string; - public errorFields: string[]; - public errorMessages: unknown; - public title: string; - public awaitingConfirmation: boolean; - public requestOrganizationsList: Organisation[]; - public requestedUserOrganizations: Organisation[]; - public checkForNoUserOrganizations = false; - public checkForRemainingOrganizations = false; - public userInfo: CurrentUserInfoResponse; - public pressed = false; - public organisationsFilterCtrl: UntypedFormControl = new UntypedFormControl(); - public filteredOrganisations: ReplaySubject< - Organisation[] - > = new ReplaySubject(1); - private onDestroy = new Subject(); - - constructor( - private userService: UserService, - private translate: TranslateService, - private organizationService: OrganisationService, - private sharedService: SharedVariableService, - private errorMessageService: ErrorMessageService, - private sharedVariableService: SharedVariableService, - ) {} - - ngOnInit(): void { - this.userInfo = this.sharedService.getUserInfo(); - const hasSomePermission = this.sharedVariableService.getHasAnyPermission(); - - this.userService - .getOneSimple(this.userInfo.user.id) - .subscribe((response: UserResponse) => { - // When used as user-page, check for users organizations so it's only possible to apply not already joined organizations - this.requestedUserOrganizations = response.requestedOrganizations; - if (this.userInfo.organizations.length > 0) { - this.compareRequestedAndAlreadyJoinedOrganizations( - this.requestedUserOrganizations, - this.userInfo.organizations - ); - } + public updateUserOrgs: UpdateUserOrgsDto = new UpdateUserOrgsDto(); + public updateUserOrgsFromFrontend: UpdateUserOrgFromFrontend = new UpdateUserOrgFromFrontend(); + public organisationSubscription: Subscription; + public formFailedSubmit = false; + public backButtonTitle: string; + public errorFields: string[]; + public errorMessages: unknown; + public title: string; + public awaitingConfirmation: boolean; + public requestOrganizationsList: Organisation[]; + public requestedUserOrganizations: Organisation[]; + public checkForNoUserOrganizations = false; + public checkForRemainingOrganizations = false; + public userInfo: CurrentUserInfoResponse; + public pressed = false; + public organisationsFilterCtrl: UntypedFormControl = new UntypedFormControl(); + public filteredOrganisations: ReplaySubject = new ReplaySubject(1); + private onDestroy = new Subject(); + + constructor( + private userService: UserService, + private translate: TranslateService, + private organizationService: OrganisationService, + private sharedService: SharedVariableService, + private errorMessageService: ErrorMessageService, + private sharedVariableService: SharedVariableService + ) {} + + ngOnInit(): void { + this.userInfo = this.sharedService.getUserInfo(); + const hasSomePermission = this.sharedVariableService.getHasAnyPermission(); + + this.userService.getOneSimple(this.userInfo.user.id).subscribe((response: UserResponse) => { + // When used as user-page, check for users organizations so it's only possible to apply not already joined organizations + this.requestedUserOrganizations = response.requestedOrganizations; + if (this.userInfo.organizations.length > 0) { + this.compareRequestedAndAlreadyJoinedOrganizations( + this.requestedUserOrganizations, + this.userInfo.organizations + ); + } + + if (this.requestedUserOrganizations.length === 0) { + this.checkForNoUserOrganizations = true; + } + + this.awaitingConfirmation = response.awaitingConfirmation; + if (!this.awaitingConfirmation && hasSomePermission) { + this.translate.get("GEN.BACK").subscribe(translation => (this.backButtonTitle = translation)); + } + this.translate.get("USER_PAGE.USER_PAGE").subscribe(translation => { + this.title = translation; + }); + + this.getOrganisations(); + }); - if (this.requestedUserOrganizations.length === 0) { - this.checkForNoUserOrganizations = true; + this.organisationsFilterCtrl.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe(() => { + this.filterOrganisations(); + }); + } + private filterOrganisations() { + if (!this.requestOrganizationsList) { + return; } - - this.awaitingConfirmation = response.awaitingConfirmation; - if (!this.awaitingConfirmation && hasSomePermission) { - this.translate - .get('GEN.BACK') - .subscribe((translation) => (this.backButtonTitle = translation)); + // get the search keyword + let search = this.organisationsFilterCtrl?.value?.trim(); + if (!search) { + this.filteredOrganisations.next(this.requestOrganizationsList.slice()); + return; + } else { + search = search.toLowerCase(); } - this.translate.get('USER_PAGE.USER_PAGE').subscribe((translation) => { - this.title = translation; + const filtered = this.requestOrganizationsList.filter(org => { + return org.name.toLocaleLowerCase().indexOf(search) > -1; }); + this.filteredOrganisations.next(filtered); + } - this.getOrganisations(); - }); - - this.organisationsFilterCtrl.valueChanges - .pipe(takeUntil(this.onDestroy)) - .subscribe(() => { - this.filterOrganisations(); - }); - } - private filterOrganisations() { - if (!this.requestOrganizationsList) { - return; + public compareRequestedAndAlreadyJoinedOrganizations( + requestedOrganizations: Organisation[], + alreadyJoinedOrganizations: Organisation[] + ) { + alreadyJoinedOrganizations.forEach(actOrg => { + if (!requestedOrganizations.find(org => org.id === actOrg.id)) { + this.requestedUserOrganizations.push(actOrg); + } + }); } - // get the search keyword - let search = this.organisationsFilterCtrl?.value?.trim(); - if (!search) { - this.filteredOrganisations.next(this.requestOrganizationsList.slice()); - return; - } else { - search = search.toLowerCase(); + + public compare(o1: Organisation | undefined, o2: Organisation | undefined): boolean { + return o1?.id === o2?.id; + } + + public getOrganisations() { + this.organisationSubscription = this.organizationService.getMinimalNoPerm().subscribe(orgs => { + this.requestOrganizationsList = orgs.data; + this.requestOrganizationsList = this.filterChosenOrganizations( + this.requestedUserOrganizations, + this.requestOrganizationsList + ); + this.filteredOrganisations.next(this.requestOrganizationsList.slice()); + }); } - const filtered = this.requestOrganizationsList.filter((org) => { - return org.name.toLocaleLowerCase().indexOf(search) > -1; - }); - this.filteredOrganisations.next(filtered); - } - - public compareRequestedAndAlreadyJoinedOrganizations( - requestedOrganizations: Organisation[], - alreadyJoinedOrganizations: Organisation[] - ) { - alreadyJoinedOrganizations.forEach((actOrg) => { - if (!requestedOrganizations.find((org) => org.id === actOrg.id)) { - this.requestedUserOrganizations.push(actOrg); - } - }); - } - - public compare( - o1: Organisation | undefined, - o2: Organisation | undefined - ): boolean { - return o1?.id === o2?.id; - } - - public getOrganisations() { - this.organisationSubscription = this.organizationService - .getMinimalNoPerm() - .subscribe((orgs) => { - this.requestOrganizationsList = orgs.data; - this.requestOrganizationsList = this.filterChosenOrganizations( - this.requestedUserOrganizations, - this.requestOrganizationsList - ); - this.filteredOrganisations.next(this.requestOrganizationsList.slice()); - }); - } - - public filterChosenOrganizations( - requestedUserOrganizations: Organisation[], - allOrganizations: Organisation[] - ): Organisation[] { - const filteredChosenOrganizations: Organisation[] = []; - - allOrganizations.forEach((allOrg) => { - if (!requestedUserOrganizations.find((org) => org.id === allOrg.id)) { - filteredChosenOrganizations.push(allOrg); - } - }); - if (filteredChosenOrganizations.length > 0) { - this.checkForRemainingOrganizations = true; - } else { - this.checkForRemainingOrganizations = false; + + public filterChosenOrganizations( + requestedUserOrganizations: Organisation[], + allOrganizations: Organisation[] + ): Organisation[] { + const filteredChosenOrganizations: Organisation[] = []; + + allOrganizations.forEach(allOrg => { + if (!requestedUserOrganizations.find(org => org.id === allOrg.id)) { + filteredChosenOrganizations.push(allOrg); + } + }); + if (filteredChosenOrganizations.length > 0) { + this.checkForRemainingOrganizations = true; + } else { + this.checkForRemainingOrganizations = false; + } + + return filteredChosenOrganizations; } - return filteredChosenOrganizations; - } - - public mapToDto(body: UpdateUserOrgFromFrontend) { - this.updateUserOrgs.requestedOrganizationIds = []; - if (body.requestedOrganizations) { - body.requestedOrganizations.forEach((organization) => { - this.updateUserOrgs.requestedOrganizationIds.push(organization.id); - }); - } else { - this.formFailedSubmit = true; + public mapToDto(body: UpdateUserOrgFromFrontend) { + this.updateUserOrgs.requestedOrganizationIds = []; + if (body.requestedOrganizations) { + body.requestedOrganizations.forEach(organization => { + this.updateUserOrgs.requestedOrganizationIds.push(organization.id); + }); + } else { + this.formFailedSubmit = true; + } } - } - - onSubmit(): void { - if (this.pressed === false) { - this.pressed = true; - - this.resetErrors(); - this.mapToDto(this.updateUserOrgsFromFrontend); - this.userService.updateUserOrgs(this.updateUserOrgs).subscribe( - () => { - window.location.reload(); - this.pressed = false; - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - this.pressed = false; + + onSubmit(): void { + if (this.pressed === false) { + this.pressed = true; + + this.resetErrors(); + this.mapToDto(this.updateUserOrgsFromFrontend); + this.userService.updateUserOrgs(this.updateUserOrgs).subscribe( + () => { + window.location.reload(); + this.pressed = false; + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + this.pressed = false; + } + ); } - ); } - } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } - handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - } + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + } + handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + } } diff --git a/src/app/admin/users/user.model.ts b/src/app/admin/users/user.model.ts index 01bbebdce..dd1b8395e 100644 --- a/src/app/admin/users/user.model.ts +++ b/src/app/admin/users/user.model.ts @@ -1,67 +1,63 @@ -import { - Organisation, - OrganisationResponse, -} from '../organisation/organisation.model'; -import { PermissionResponse } from '../permission/permission.model'; +import { Organisation, OrganisationResponse } from "../organisation/organisation.model"; +import { PermissionResponse } from "../permission/permission.model"; export class UserRequest { - id: number; - name: string; - email: string; - password: string; - active: boolean; - globalAdmin: boolean; - showWelcomeScreen: boolean; + id: number; + name: string; + email: string; + password: string; + active: boolean; + globalAdmin: boolean; + showWelcomeScreen: boolean; } export interface UserResponse { - id: number; - createdAt: string; - updatedAt: string; - createdBy: number; - updatedBy: number; - createdByName: string; - updatedByName: string; - name: string; - nameId: string; - email: string; - active: boolean; - lastLogin: Date; - permissions: PermissionResponse[]; - awaitingConfirmation: boolean; - showWelcomeScreen: boolean; - requestedOrganizations: OrganisationResponse[]; -} - -export interface UserResponsePerRequestedOrganization - extends Omit { - requestedOrganization: OrganisationResponse; + id: number; + createdAt: string; + updatedAt: string; + createdBy: number; + updatedBy: number; + createdByName: string; + updatedByName: string; + name: string; + nameId: string; + email: string; + active: boolean; + lastLogin: Date; + permissions: PermissionResponse[]; + awaitingConfirmation: boolean; + showWelcomeScreen: boolean; + requestedOrganizations: OrganisationResponse[]; +} + +export interface UserResponsePerRequestedOrganization extends Omit { + requestedOrganization: OrganisationResponse; } export interface UserGetManyResponse { - data: UserResponse[]; - count: number; + data: UserResponse[]; + count: number; } export class CreateNewKombitUserFromFrontend { - email: string; - requestedOrganizations: Organisation[]; + email: string; + requestedOrganizations: Organisation[]; } export class UpdateUserOrgFromFrontend { - requestedOrganizations: Organisation[]; + requestedOrganizations: Organisation[]; } export class UpdateUserOrgsDto { - requestedOrganizationIds: number[]; + requestedOrganizationIds: number[]; } export class RejectUserDto { - orgId: number; - userIdToReject: number; + orgId: number; + userIdToReject: number; } export class CreateNewKombitUserDto { - email: string; - requestedOrganizationIds: number[]; + email: string; + requestedOrganizationIds: number[]; } diff --git a/src/app/admin/users/user.service.ts b/src/app/admin/users/user.service.ts index 45c75b71c..8c70d6e0b 100644 --- a/src/app/admin/users/user.service.ts +++ b/src/app/admin/users/user.service.ts @@ -1,165 +1,140 @@ -import { Injectable } from '@angular/core'; -import { RestService } from '@shared/services/rest.service'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { Organisation } from '../organisation/organisation.model'; -import { UserMinimalService } from './user-minimal.service'; +import { Injectable } from "@angular/core"; +import { RestService } from "@shared/services/rest.service"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { Organisation } from "../organisation/organisation.model"; +import { UserMinimalService } from "./user-minimal.service"; import { - UserResponse, - UserRequest, - UserGetManyResponse, - CreateNewKombitUserDto, - UpdateUserOrgsDto, - RejectUserDto, -} from './user.model'; + UserResponse, + UserRequest, + UserGetManyResponse, + CreateNewKombitUserDto, + UpdateUserOrgsDto, + RejectUserDto, +} from "./user.model"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class UserService { - URL = 'user'; - URL_NEW_KOMBIT = 'kombitCreation'; + URL = "user"; + URL_NEW_KOMBIT = "kombitCreation"; - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - post(body: UserRequest): Observable { - return this.restService.post(this.URL, body); - } + post(body: UserRequest): Observable { + return this.restService.post(this.URL, body); + } - put(body: UserRequest, id: number): Observable { - return this.restService.put(this.URL, body, id, { - observe: 'response', - }); - } + put(body: UserRequest, id: number): Observable { + return this.restService.put(this.URL, body, id, { + observe: "response", + }); + } - getOne(id: number, extendedInfo = false): Observable { - return this.restService - .get(this.URL, { extendedInfo }, id) - .pipe( - map((response: UserResponse) => { - response.createdByName = this.userMinimalService.getUserNameFrom( - response.createdBy - ); - response.updatedByName = this.userMinimalService.getUserNameFrom( - response.updatedBy - ); - return response; - }) - ); - } + getOne(id: number, extendedInfo = false): Observable { + return this.restService.get(this.URL, { extendedInfo }, id).pipe( + map((response: UserResponse) => { + response.createdByName = this.userMinimalService.getUserNameFrom(response.createdBy); + response.updatedByName = this.userMinimalService.getUserNameFrom(response.updatedBy); + return response; + }) + ); + } - getMultiple( - limit: number = 1000, - offset: number = 0, - orderByColumn?: string, - orderByDirection?: string, - permissionId?: number - ): Observable { - if (permissionId != null) { - return this.restService.get(`permission/${permissionId}/users`, { - limit, - offset, - }); - } else { - return this.restService.get(this.URL, { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - }); + getMultiple( + limit: number = 1000, + offset: number = 0, + orderByColumn?: string, + orderByDirection?: string, + permissionId?: number + ): Observable { + if (permissionId != null) { + return this.restService.get(`permission/${permissionId}/users`, { + limit, + offset, + }); + } else { + return this.restService.get(this.URL, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } } - } - getMultipleByOrganization( - limit: number = 1000, - offset: number = 0, - orderByColumn?: string, - orderByDirection?: string, - organizationId?: number - ): Observable { - return this.restService.get(this.URL + `/organizationUsers/${organizationId}`, { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - }); - } + getMultipleByOrganization( + limit: number = 1000, + offset: number = 0, + orderByColumn?: string, + orderByDirection?: string, + organizationId?: number + ): Observable { + return this.restService.get(this.URL + `/organizationUsers/${organizationId}`, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } - hideWelcome(id: number): Observable { - return this.restService.put(`${this.URL}/${id}/hide-welcome`, null, null); - } + hideWelcome(id: number): Observable { + return this.restService.put(`${this.URL}/${id}/hide-welcome`, null, null); + } - getAwaitingUsers( - limit: number = 1000, - offset: number = 0, - orderByColumn?: string, - orderByDirection?: string - ): Observable { - return this.restService.get( - this.URL + '/awaitingUsers', - { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - }, - ); - } + getAwaitingUsers( + limit: number = 1000, + offset: number = 0, + orderByColumn?: string, + orderByDirection?: string + ): Observable { + return this.restService.get(this.URL + "/awaitingUsers", { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } - getAwaitingUsersForOrganization( - limit: number = 1000, - offset: number = 0, - organizationId: number, - orderByColumn?: string, - orderByDirection?: string - ): Observable { - return this.restService.get( - `${this.URL}/awaitingUsers/${organizationId}`, - { - limit, - offset, - orderOn: orderByColumn, - sort: orderByDirection, - }, - ); - } + getAwaitingUsersForOrganization( + limit: number = 1000, + offset: number = 0, + organizationId: number, + orderByColumn?: string, + orderByDirection?: string + ): Observable { + return this.restService.get(`${this.URL}/awaitingUsers/${organizationId}`, { + limit, + offset, + orderOn: orderByColumn, + sort: orderByDirection, + }); + } - getOneSimple(id: number): Observable { - return this.restService.get(this.URL_NEW_KOMBIT, {}, id).pipe( - map((response: UserResponse) => { - return response; - }) - ); - } + getOneSimple(id: number): Observable { + return this.restService.get(this.URL_NEW_KOMBIT, {}, id).pipe( + map((response: UserResponse) => { + return response; + }) + ); + } - updateNewKombit(body: CreateNewKombitUserDto): Observable { - return this.restService.put( - this.URL_NEW_KOMBIT + '/createNewKombitUser', - body, - undefined, - { - observe: 'response', - } - ); - } + updateNewKombit(body: CreateNewKombitUserDto): Observable { + return this.restService.put(this.URL_NEW_KOMBIT + "/createNewKombitUser", body, undefined, { + observe: "response", + }); + } - updateUserOrgs(body: UpdateUserOrgsDto): Observable { - return this.restService.put( - this.URL_NEW_KOMBIT + '/updateUserOrgs', - body, - undefined, - { - observe: 'response', - } - ); - } + updateUserOrgs(body: UpdateUserOrgsDto): Observable { + return this.restService.put(this.URL_NEW_KOMBIT + "/updateUserOrgs", body, undefined, { + observe: "response", + }); + } - rejectUser(body: RejectUserDto): Observable { - return this.restService.put(this.URL + '/rejectUser', body, undefined, { - observe: 'response', - }); - } + rejectUser(body: RejectUserDto): Observable { + return this.restService.put(this.URL + "/rejectUser", body, undefined, { + observe: "response", + }); + } } diff --git a/src/app/admin/users/users.component.html b/src/app/admin/users/users.component.html index 90c6b6463..0680b43f9 100644 --- a/src/app/admin/users/users.component.html +++ b/src/app/admin/users/users.component.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/app/admin/users/users.component.ts b/src/app/admin/users/users.component.ts index 8d6353400..3201a7ba6 100644 --- a/src/app/admin/users/users.component.ts +++ b/src/app/admin/users/users.component.ts @@ -1,14 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-users', - templateUrl: './users.component.html' + selector: "app-users", + templateUrl: "./users.component.html", }) export class UsersComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit(): void { - } - + ngOnInit(): void {} } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 711a17344..7bb9e02b9 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,32 +1,62 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule, PreloadAllModules } from '@angular/router'; -import { AuthComponent } from './auth/auth.component'; -import { ErrorPageComponent } from './error-page/error-page.component'; -import { SearchComponent } from './search/search.component'; -import { AuthGuardService as AuthGuard } from './auth/auth-guard.service'; -import { NewUserComponent } from './admin/users/new-kombit-user-page/new-user.component'; -import { UserPageComponent } from './admin/users/user-page/user-page.component'; +import { NgModule } from "@angular/core"; +import { Routes, RouterModule, PreloadAllModules } from "@angular/router"; +import { AuthComponent } from "./auth/auth.component"; +import { ErrorPageComponent } from "./error-page/error-page.component"; +import { SearchComponent } from "./search/search.component"; +import { AuthGuardService as AuthGuard } from "./auth/auth-guard.service"; +import { NewUserComponent } from "./admin/users/new-kombit-user-page/new-user.component"; +import { UserPageComponent } from "./admin/users/user-page/user-page.component"; const routes: Routes = [ - { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule), canActivate: [AuthGuard] }, - { path: 'auth', component: AuthComponent }, - { path: 'applications', loadChildren: () => import('./applications/applications.module').then(m => m.ApplicationsModule), canActivate: [AuthGuard] }, - { path: 'gateways', loadChildren: () => import('./gateway/gateway.module').then(m => m.GatewayModule), canActivate: [AuthGuard] }, - { path: 'profiles', loadChildren: () => import('./profiles/profiles.module').then(m => m.ProfilesModule), canActivate: [AuthGuard] }, - { path: 'payload-decoder', loadChildren: () => import('./payload-decoder/payload-decoder.module').then(m => m.PayloadDecoderModule), canActivate: [AuthGuard] }, - { path: 'sigfox', loadChildren: () => import('./sigfox/sigfox.module').then(m => m.SigfoxModule), canActivate: [AuthGuard] }, - { path: 'device-model', loadChildren: () => import('./device-model/device-model.module').then(m => m.DeviceModelModule), canActivate: [AuthGuard] }, - { path: 'search', component: SearchComponent, canActivate: [AuthGuard] }, - { path: 'not-found', component: ErrorPageComponent, data: { message: 'not-found', code: 404 } }, - { path: 'not-authorized', component: ErrorPageComponent }, - { path: 'new-user', component: NewUserComponent, canActivate: [AuthGuard]}, - { path: 'user-page', component: UserPageComponent, canActivate: [AuthGuard]}, - { path: '', redirectTo: '/applications', pathMatch: 'full' }, - { path: '**', redirectTo: '/not-found', pathMatch: 'full' } + { + path: "admin", + loadChildren: () => import("./admin/admin.module").then(m => m.AdminModule), + canActivate: [AuthGuard], + }, + { path: "auth", component: AuthComponent }, + { + path: "applications", + loadChildren: () => import("./applications/applications.module").then(m => m.ApplicationsModule), + canActivate: [AuthGuard], + }, + { + path: "gateways", + loadChildren: () => import("./gateway/gateway.module").then(m => m.GatewayModule), + canActivate: [AuthGuard], + }, + { + path: "profiles", + loadChildren: () => import("./profiles/profiles.module").then(m => m.ProfilesModule), + canActivate: [AuthGuard], + }, + { + path: "payload-decoder", + loadChildren: () => import("./payload-decoder/payload-decoder.module").then(m => m.PayloadDecoderModule), + canActivate: [AuthGuard], + }, + { + path: "sigfox", + loadChildren: () => import("./sigfox/sigfox.module").then(m => m.SigfoxModule), + canActivate: [AuthGuard], + }, + { + path: "device-model", + loadChildren: () => import("./device-model/device-model.module").then(m => m.DeviceModelModule), + canActivate: [AuthGuard], + }, + { path: "search", component: SearchComponent, canActivate: [AuthGuard] }, + { path: "not-found", component: ErrorPageComponent, data: { message: "not-found", code: 404 } }, + { path: "not-authorized", component: ErrorPageComponent }, + { path: "new-user", component: NewUserComponent, canActivate: [AuthGuard] }, + { path: "user-page", component: UserPageComponent, canActivate: [AuthGuard] }, + { path: "", redirectTo: "/applications", pathMatch: "full" }, + { path: "**", redirectTo: "/not-found", pathMatch: "full" }, ]; @NgModule({ - imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules, relativeLinkResolution: 'legacy' })], + imports: [ + RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules, relativeLinkResolution: "legacy" }), + ], exports: [RouterModule], }) -export class AppRoutingModule { } +export class AppRoutingModule {} diff --git a/src/app/app.component.html b/src/app/app.component.html index da2046f7b..ae6537124 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,8 +1,8 @@
- +
-
- -
-
\ No newline at end of file +
+ +
+
diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 8cd6829b6..a6598b008 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,8 +1,8 @@ -@import 'src/assets/scss/setup/breakpoints'; -@import 'src/assets/scss/setup/variables'; +@import "src/assets/scss/setup/breakpoints"; +@import "src/assets/scss/setup/variables"; #content { - @media(min-width: $screen-md-min) { - padding-left: $navWidth; - } + @media (min-width: $screen-md-min) { + padding-left: $navWidth; + } } diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 89507e7a1..e4b9264d2 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,8 +1,8 @@ -import { TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppComponent } from './app.component'; +import { TestBed, waitForAsync } from "@angular/core/testing"; +import { RouterTestingModule } from "@angular/router/testing"; +import { AppComponent } from "./app.component"; -describe('AppComponent', () => { +describe("AppComponent", () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [RouterTestingModule], @@ -10,7 +10,7 @@ describe('AppComponent', () => { }).compileComponents(); })); - it('should create the app', () => { + it("should create the app", () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; expect(app).toBeTruthy(); @@ -19,15 +19,13 @@ describe('AppComponent', () => { it(`should have as title 'OS2IoT-frontend'`, () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; - expect(app.title).toEqual('OS2IoT-frontend'); + expect(app.title).toEqual("OS2IoT-frontend"); }); - it('should render title', () => { + it("should render title", () => { const fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const compiled = fixture.nativeElement; - expect(compiled.querySelector('.content span').textContent).toContain( - 'OS2IoT-frontend app is running!' - ); + expect(compiled.querySelector(".content span").textContent).toContain("OS2IoT-frontend app is running!"); }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1d1f82702..af6f2f401 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,20 +1,18 @@ -import { Component } from '@angular/core'; -import { LoggedInService } from '@shared/services/loggedin.service'; +import { Component } from "@angular/core"; +import { LoggedInService } from "@shared/services/loggedin.service"; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], + selector: "app-root", + templateUrl: "./app.component.html", + styleUrls: ["./app.component.scss"], }) export class AppComponent { - title = 'OS2IoT-frontend'; + title = "OS2IoT-frontend"; isLoggedIn = true; constructor(private loggedInService: LoggedInService) { - loggedInService.changeEmitted?.subscribe( - (change) => { - this.isLoggedIn = change; - } - ); + loggedInService.changeEmitted?.subscribe(change => { + this.isLoggedIn = change; + }); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 85f83919b..1c44a6c6f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,105 +1,96 @@ -import { BrowserModule, Title } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; -import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; -import { TranslateHttpLoader } from '@ngx-translate/http-loader'; -import { - HttpClient, - HttpClientModule, - HTTP_INTERCEPTORS, -} from '@angular/common/http'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { NavbarModule } from './navbar/navbar.module'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ProfilesModule } from './profiles/profiles.module'; -import { AuthJwtInterceptor } from '@shared/helpers/auth-jwt.interceptor'; -import { AuthModule } from './auth/auth.module'; -import { GatewayModule } from './gateway/gateway.module'; -import { SharedVariableModule } from '@shared/shared-variable/shared-variable.module'; -import { SAVER, getSaver } from '@shared/providers/saver.provider'; -import { ErrorPageComponent } from './error-page/error-page.component'; -import { SearchModule } from './search/search.module'; -import { JwtModule } from '@auth0/angular-jwt'; -import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; -import { MatInputModule } from '@angular/material/input'; -import { MatPaginatorIntl } from '@angular/material/paginator'; -import { MatPaginatorIntlDa } from '@shared/helpers/mat-paginator-intl-da'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { NewUserComponent } from './admin/users/new-kombit-user-page/new-user.component'; -import { WelcomeDialogModule } from '@shared/components/welcome-dialog/welcome-dialog.module'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-select-search.module'; -import { UserPageComponent } from './admin/users/user-page/user-page.component'; -import { SharedModule } from '@shared/shared.module'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { CookieService } from 'ngx-cookie-service'; +import { BrowserModule, Title } from "@angular/platform-browser"; +import { NgModule } from "@angular/core"; +import { TranslateModule, TranslateLoader } from "@ngx-translate/core"; +import { TranslateHttpLoader } from "@ngx-translate/http-loader"; +import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http"; +import { AppRoutingModule } from "./app-routing.module"; +import { AppComponent } from "./app.component"; +import { NavbarModule } from "./navbar/navbar.module"; +import { NgbModule } from "@ng-bootstrap/ng-bootstrap"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { ProfilesModule } from "./profiles/profiles.module"; +import { AuthJwtInterceptor } from "@shared/helpers/auth-jwt.interceptor"; +import { AuthModule } from "./auth/auth.module"; +import { GatewayModule } from "./gateway/gateway.module"; +import { SharedVariableModule } from "@shared/shared-variable/shared-variable.module"; +import { SAVER, getSaver } from "@shared/providers/saver.provider"; +import { ErrorPageComponent } from "./error-page/error-page.component"; +import { SearchModule } from "./search/search.module"; +import { JwtModule } from "@auth0/angular-jwt"; +import { MonacoEditorModule } from "ngx-monaco-editor-v2"; +import { MatInputModule } from "@angular/material/input"; +import { MatPaginatorIntl } from "@angular/material/paginator"; +import { MatPaginatorIntlDa } from "@shared/helpers/mat-paginator-intl-da"; +import { MatTooltipModule } from "@angular/material/tooltip"; +import { NewUserComponent } from "./admin/users/new-kombit-user-page/new-user.component"; +import { WelcomeDialogModule } from "@shared/components/welcome-dialog/welcome-dialog.module"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { MatSelectSearchModule } from "@shared/components/mat-select-search/mat-select-search.module"; +import { UserPageComponent } from "./admin/users/user-page/user-page.component"; +import { SharedModule } from "@shared/shared.module"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { CookieService } from "ngx-cookie-service"; export function HttpLoaderFactory(http: HttpClient) { - return new TranslateHttpLoader(http, './assets/i18n/', '.json'); + return new TranslateHttpLoader(http, "./assets/i18n/", ".json"); } export function tokenGetter() { - return localStorage.getItem('id_token'); + return localStorage.getItem("id_token"); } @NgModule({ - declarations: [ - AppComponent, - ErrorPageComponent, - NewUserComponent, - UserPageComponent, - ], - imports: [ - SharedVariableModule.forRoot(), - AuthModule, - BrowserModule, - BrowserAnimationsModule, - HttpClientModule, - AppRoutingModule, - NavbarModule, - ProfilesModule, - TranslateModule.forRoot({ - defaultLanguage: 'da', - loader: { - provide: TranslateLoader, - useFactory: HttpLoaderFactory, - deps: [HttpClient], - }, - }), - NgbModule, - FormsModule, - ReactiveFormsModule, - BrowserAnimationsModule, - NGMaterialModule, - GatewayModule, - MatSelectSearchModule, - SearchModule, - SharedModule, - HttpClientModule, - MatInputModule, - MatTooltipModule, - JwtModule.forRoot({ - config: { - tokenGetter, - }, - }), - MonacoEditorModule.forRoot(), - WelcomeDialogModule, - PipesModule, - ], - bootstrap: [AppComponent], - exports: [TranslateModule], - providers: [ - // use these two providers only in dev environment - //{ provide: ErrorHandler, useClass: GlobalErrorHandler }, - //{ provide: HTTP_INTERCEPTORS, useClass: ServerErrorInterceptor, multi: true }, - Title, - { provide: HTTP_INTERCEPTORS, useClass: AuthJwtInterceptor, multi: true }, - { provide: SAVER, useFactory: getSaver }, - { provide: MatPaginatorIntl, useClass: MatPaginatorIntlDa }, - { provide: CookieService } - ], + declarations: [AppComponent, ErrorPageComponent, NewUserComponent, UserPageComponent], + imports: [ + SharedVariableModule.forRoot(), + AuthModule, + BrowserModule, + BrowserAnimationsModule, + HttpClientModule, + AppRoutingModule, + NavbarModule, + ProfilesModule, + TranslateModule.forRoot({ + defaultLanguage: "da", + loader: { + provide: TranslateLoader, + useFactory: HttpLoaderFactory, + deps: [HttpClient], + }, + }), + NgbModule, + FormsModule, + ReactiveFormsModule, + BrowserAnimationsModule, + NGMaterialModule, + GatewayModule, + MatSelectSearchModule, + SearchModule, + SharedModule, + HttpClientModule, + MatInputModule, + MatTooltipModule, + JwtModule.forRoot({ + config: { + tokenGetter, + }, + }), + MonacoEditorModule.forRoot(), + WelcomeDialogModule, + PipesModule, + ], + bootstrap: [AppComponent], + exports: [TranslateModule], + providers: [ + // use these two providers only in dev environment + //{ provide: ErrorHandler, useClass: GlobalErrorHandler }, + //{ provide: HTTP_INTERCEPTORS, useClass: ServerErrorInterceptor, multi: true }, + Title, + { provide: HTTP_INTERCEPTORS, useClass: AuthJwtInterceptor, multi: true }, + { provide: SAVER, useFactory: getSaver }, + { provide: MatPaginatorIntl, useClass: MatPaginatorIntlDa }, + { provide: CookieService }, + ], }) export class AppModule {} diff --git a/src/app/applications/application-detail/application-detail.component.spec.ts b/src/app/applications/application-detail/application-detail.component.spec.ts index df827095c..5bff09e0b 100644 --- a/src/app/applications/application-detail/application-detail.component.spec.ts +++ b/src/app/applications/application-detail/application-detail.component.spec.ts @@ -1,25 +1,23 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ApplicationDetailComponent } from './application-detail.component'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ApplicationDetailComponent } from "./application-detail.component"; +describe("ApplicationComponent", () => { + let component: ApplicationDetailComponent; + let fixture: ComponentFixture; -describe('ApplicationComponent', () => { - let component: ApplicationDetailComponent; - let fixture: ComponentFixture; + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ApplicationDetailComponent], + }).compileComponents(); + })); - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ApplicationDetailComponent] - }) - .compileComponents(); - })); + beforeEach(() => { + fixture = TestBed.createComponent(ApplicationDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - beforeEach(() => { - fixture = TestBed.createComponent(ApplicationDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/application-edit/application-edit.component.spec.ts b/src/app/applications/application-edit/application-edit.component.spec.ts index 4e690e3a4..8e7fa3271 100644 --- a/src/app/applications/application-edit/application-edit.component.spec.ts +++ b/src/app/applications/application-edit/application-edit.component.spec.ts @@ -1,25 +1,23 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ApplicationEditComponent } from './application-edit.component'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ApplicationEditComponent } from "./application-edit.component"; +describe("EditApplicationComponent", () => { + let component: ApplicationEditComponent; + let fixture: ComponentFixture; -describe('EditApplicationComponent', () => { - let component: ApplicationEditComponent; - let fixture: ComponentFixture; + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ApplicationEditComponent], + }).compileComponents(); + })); - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ApplicationEditComponent] - }) - .compileComponents(); - })); + beforeEach(() => { + fixture = TestBed.createComponent(ApplicationEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - beforeEach(() => { - fixture = TestBed.createComponent(ApplicationEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/application-edit/application-edit.component.ts b/src/app/applications/application-edit/application-edit.component.ts index b90e98a13..0a498e388 100644 --- a/src/app/applications/application-edit/application-edit.component.ts +++ b/src/app/applications/application-edit/application-edit.component.ts @@ -1,42 +1,40 @@ -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { BackButton } from '@shared/models/back-button.model'; +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { BackButton } from "@shared/models/back-button.model"; @Component({ - selector: 'app-application-edit', - templateUrl: './application-edit.component.html', - styleUrls: ['./application-edit.component.scss'] + selector: "app-application-edit", + templateUrl: "./application-edit.component.html", + styleUrls: ["./application-edit.component.scss"], }) export class ApplicationEditComponent implements OnInit { - public backButton: BackButton = { label: '', routerLink: 'applications' }; - public multiPage = false; - public title = ''; - public sectionTitle = ''; - public submitButton = ''; - private applicaitonId: string; + public backButton: BackButton = { label: "", routerLink: "applications" }; + public multiPage = false; + public title = ""; + public sectionTitle = ""; + public submitButton = ""; + private applicaitonId: string; - constructor( - public translate: TranslateService, - private route: ActivatedRoute - ) { - translate.use('da'); - } + constructor(public translate: TranslateService, private route: ActivatedRoute) { + translate.use("da"); + } - ngOnInit(): void { - this.translate.get(['NAV.APPLICATIONS', 'FORM.EDIT-NEW-APPLICATION', 'APPLICATION.SAVE']) - .subscribe(translations => { - this.backButton.label = translations['NAV.APPLICATIONS']; - this.title = translations['FORM.EDIT-NEW-APPLICATION']; - this.submitButton = translations['APPLICATION.SAVE']; - }); - this.applicaitonId = this.route.snapshot.paramMap.get('id'); - if (this.applicaitonId) { - this.setBackButton(this.applicaitonId); + ngOnInit(): void { + this.translate + .get(["NAV.APPLICATIONS", "FORM.EDIT-NEW-APPLICATION", "APPLICATION.SAVE"]) + .subscribe(translations => { + this.backButton.label = translations["NAV.APPLICATIONS"]; + this.title = translations["FORM.EDIT-NEW-APPLICATION"]; + this.submitButton = translations["APPLICATION.SAVE"]; + }); + this.applicaitonId = this.route.snapshot.paramMap.get("id"); + if (this.applicaitonId) { + this.setBackButton(this.applicaitonId); + } } - } - private setBackButton(applicationId: string) { - this.backButton.routerLink = ['applications', applicationId] - } + private setBackButton(applicationId: string) { + this.backButton.routerLink = ["applications", applicationId]; + } } diff --git a/src/app/applications/application.model.ts b/src/app/applications/application.model.ts index 6ebbf7d73..a88c3114f 100644 --- a/src/app/applications/application.model.ts +++ b/src/app/applications/application.model.ts @@ -1,63 +1,63 @@ -import { ControlledPropertyTypes } from '@app/device-model/Enums/controlled-propperty.enum'; -import { ApplicationDeviceTypeUnion } from '@shared/enums/device-type'; -import { ControlledProperty } from '@shared/models/controlled-property.model'; -import { Organisation } from '../admin/organisation/organisation.model'; -import { ApplicationStatus } from './enums/status.enum'; -import { IotDevice } from './iot-devices/iot-device.model'; -import { ApplicationDeviceType } from './models/application-device-type.model'; -import { PermissionResponse } from '@app/admin/permission/permission.model'; -import { Datatarget } from '@applications/datatarget/datatarget.model'; +import { ControlledPropertyTypes } from "@app/device-model/Enums/controlled-propperty.enum"; +import { ApplicationDeviceTypeUnion } from "@shared/enums/device-type"; +import { ControlledProperty } from "@shared/models/controlled-property.model"; +import { Organisation } from "../admin/organisation/organisation.model"; +import { ApplicationStatus } from "./enums/status.enum"; +import { IotDevice } from "./iot-devices/iot-device.model"; +import { ApplicationDeviceType } from "./models/application-device-type.model"; +import { PermissionResponse } from "@app/admin/permission/permission.model"; +import { Datatarget } from "@applications/datatarget/datatarget.model"; export class Application { - public id: number; - public createdAt: string; - public updatedAt: string; - public name: string; - public description: string; - public iotDevices?: IotDevice[]; - public belongsTo: Organisation; - public createdBy: number; - public updatedBy: number; - public createdByName: string; - public updatedByName: string; - public status?: ApplicationStatus; - public startDate?: Date; - public endDate?: Date; - public category?: string; - public owner?: string; - public contactPerson?: string; - public contactEmail?: string; - public contactPhone?: string; - public personalData?: boolean; - public hardware?: string; - public controlledProperties?: ControlledProperty[]; - public deviceTypes?: ApplicationDeviceType[]; - public permissions: PermissionResponse[]; - public permissionIds: number[]; - public dataTargets: Datatarget[]; + public id: number; + public createdAt: string; + public updatedAt: string; + public name: string; + public description: string; + public iotDevices?: IotDevice[]; + public belongsTo: Organisation; + public createdBy: number; + public updatedBy: number; + public createdByName: string; + public updatedByName: string; + public status?: ApplicationStatus; + public startDate?: Date; + public endDate?: Date; + public category?: string; + public owner?: string; + public contactPerson?: string; + public contactEmail?: string; + public contactPhone?: string; + public personalData?: boolean; + public hardware?: string; + public controlledProperties?: ControlledProperty[]; + public deviceTypes?: ApplicationDeviceType[]; + public permissions: PermissionResponse[]; + public permissionIds: number[]; + public dataTargets: Datatarget[]; } export class ApplicationRequest { - public name: string; - public description: string; - public organizationId: number; - public status?: ApplicationStatus; - public startDate?: Date; - public endDate?: Date; - public category?: string; - public owner?: string; - public contactPerson?: string; - public contactEmail?: string; - public contactPhone?: string; - public personalData?: boolean; - public hardware?: string; - public controlledProperties?: ControlledPropertyTypes[]; - public deviceTypes?: ApplicationDeviceTypeUnion[]; - public permissionIds: number[]; + public name: string; + public description: string; + public organizationId: number; + public status?: ApplicationStatus; + public startDate?: Date; + public endDate?: Date; + public category?: string; + public owner?: string; + public contactPerson?: string; + public contactEmail?: string; + public contactPhone?: string; + public personalData?: boolean; + public hardware?: string; + public controlledProperties?: ControlledPropertyTypes[]; + public deviceTypes?: ApplicationDeviceTypeUnion[]; + public permissionIds: number[]; } export interface ApplicationData { - data: Application[]; - ok?: boolean; - count?: number; + data: Application[]; + ok?: boolean; + count?: number; } diff --git a/src/app/applications/application.service.ts b/src/app/applications/application.service.ts index f44c172a7..2e42e5ff1 100644 --- a/src/app/applications/application.service.ts +++ b/src/app/applications/application.service.ts @@ -1,91 +1,79 @@ -import { Injectable } from '@angular/core'; -import { Application, ApplicationData } from '@applications/application.model'; -import { RestService } from '../shared/services/rest.service'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; +import { Injectable } from "@angular/core"; +import { Application, ApplicationData } from "@applications/application.model"; +import { RestService } from "../shared/services/rest.service"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; interface GetApplicationParameters { - limit: number; - offset: number; - sort: string; - orderOn: string; - organizationId?: number; - permissionId?: number; + limit: number; + offset: number; + sort: string; + orderOn: string; + organizationId?: number; + permissionId?: number; } @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class ApplicationService { - public id: number; - public canEdit = false; - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + public id: number; + public canEdit = false; + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - createApplication(body: any): Observable { - return this.restService.post('application', body, { observe: 'response' }); - } + createApplication(body: any): Observable { + return this.restService.post("application", body, { observe: "response" }); + } - updateApplication(body: any, id: number): Observable { - return this.restService.put('application', body, id, { - observe: 'response', - }); - } + updateApplication(body: any, id: number): Observable { + return this.restService.put("application", body, id, { + observe: "response", + }); + } - getApplication(id: number): Observable { - return this.restService.get('application', {}, id).pipe( - map((response: Application) => { - response.createdByName = this.userMinimalService.getUserNameFrom( - response.createdBy - ); - response.updatedByName = this.userMinimalService.getUserNameFrom( - response.updatedBy + getApplication(id: number): Observable { + return this.restService.get("application", {}, id).pipe( + map((response: Application) => { + response.createdByName = this.userMinimalService.getUserNameFrom(response.createdBy); + response.updatedByName = this.userMinimalService.getUserNameFrom(response.updatedBy); + return response; + }) ); - return response; - }) - ); - } + } - getApplications( - limit: number, - offset: number, - sort: string, - orderOn: string, - organizationId?: number, - permissionId?: number - ): Observable { - const body: GetApplicationParameters = { - limit, - offset, - sort, - orderOn, - }; - if (permissionId) { - body.permissionId = permissionId; - return this.restService.get( - `permission/${permissionId}/applications`, - body - ); - } else if (organizationId) { - body.organizationId = organizationId; - return this.restService.get('application', body); + getApplications( + limit: number, + offset: number, + sort: string, + orderOn: string, + organizationId?: number, + permissionId?: number + ): Observable { + const body: GetApplicationParameters = { + limit, + offset, + sort, + orderOn, + }; + if (permissionId) { + body.permissionId = permissionId; + return this.restService.get(`permission/${permissionId}/applications`, body); + } else if (organizationId) { + body.organizationId = organizationId; + return this.restService.get("application", body); + } + return this.restService.get("application", body); } - return this.restService.get('application', body); - } - getApplicationsByOrganizationId( - organizationId: number - ): Observable { - const body = { - organizationId, - }; - return this.restService.get('application', body); - } + getApplicationsByOrganizationId(organizationId: number): Observable { + const body = { + organizationId, + }; + return this.restService.get("application", body); + } - deleteApplication(id: number) { - return this.restService.delete('application', id); - } + deleteApplication(id: number) { + return this.restService.delete("application", id); + } } diff --git a/src/app/applications/applications-list/applications-list.component.html b/src/app/applications/applications-list/applications-list.component.html index 22e98f433..3983ef707 100644 --- a/src/app/applications/applications-list/applications-list.component.html +++ b/src/app/applications/applications-list/applications-list.component.html @@ -1,31 +1,38 @@ -
-
-
- -
-

{{'WELCOME-DIALOG.WELCOME' | translate}}

-

{{'WELCOME-DIALOG.NO-ACCESS' | translate}}

-
-
-
-
-
+
+
+
+ +
+

{{ "WELCOME-DIALOG.WELCOME" | translate }}

+

{{ "WELCOME-DIALOG.NO-ACCESS" | translate }}

+
+
+
+
+
- +
- - -
-
-
- -
-
-
+ + +
+
+
+ +
+
+
+
-
- +
diff --git a/src/app/applications/applications-list/applications-list.component.spec.ts b/src/app/applications/applications-list/applications-list.component.spec.ts index af4f40e6c..587cf9833 100644 --- a/src/app/applications/applications-list/applications-list.component.spec.ts +++ b/src/app/applications/applications-list/applications-list.component.spec.ts @@ -1,26 +1,23 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ApplicationsListComponent } from './applications-list.component'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ApplicationsListComponent } from "./applications-list.component"; +describe("ListApplicationsComponent", () => { + let component: ApplicationsListComponent; + let fixture: ComponentFixture; + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ApplicationsListComponent], + }).compileComponents(); + })); -describe('ListApplicationsComponent', () => { - let component: ApplicationsListComponent; - let fixture: ComponentFixture; + beforeEach(() => { + fixture = TestBed.createComponent(ApplicationsListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ApplicationsListComponent] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ApplicationsListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/applications-list/applications-list.component.ts b/src/app/applications/applications-list/applications-list.component.ts index 6ab622a82..7f832ce5e 100644 --- a/src/app/applications/applications-list/applications-list.component.ts +++ b/src/app/applications/applications-list/applications-list.component.ts @@ -1,168 +1,159 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { Title } from '@angular/platform-browser'; -import { ActivatedRoute, Router } from '@angular/router'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; -import { NavbarComponent } from '@app/navbar/navbar.component'; -import { Application } from '@applications/application.model'; -import { AuthService } from '@auth/auth.service'; -import { environment } from '@environments/environment'; -import { TranslateService } from '@ngx-translate/core'; -import { WelcomeDialogComponent } from '@shared/components/welcome-dialog/welcome-dialog.component'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { MeService } from '@shared/services/me.service'; -import { WelcomeDialogModel } from '@shared/models/dialog.model'; - -const welcomeDialogId = 'welcome-dialog'; +import { Component, Input, OnInit } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { Title } from "@angular/platform-browser"; +import { ActivatedRoute, Router } from "@angular/router"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; +import { NavbarComponent } from "@app/navbar/navbar.component"; +import { Application } from "@applications/application.model"; +import { AuthService } from "@auth/auth.service"; +import { environment } from "@environments/environment"; +import { TranslateService } from "@ngx-translate/core"; +import { WelcomeDialogComponent } from "@shared/components/welcome-dialog/welcome-dialog.component"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { MeService } from "@shared/services/me.service"; +import { WelcomeDialogModel } from "@shared/models/dialog.model"; + +const welcomeDialogId = "welcome-dialog"; @Component({ - providers: [NavbarComponent], - selector: 'app-applications-list', - templateUrl: './applications-list.component.html', - styleUrls: ['./applications-list.component.scss'], + providers: [NavbarComponent], + selector: "app-applications-list", + templateUrl: "./applications-list.component.html", + styleUrls: ["./applications-list.component.scss"], }) export class ApplicationsListComponent implements OnInit { - isLoadingResults = true; - - public pageLimit = environment.tablePageSize; - public resultsLength: number; - public pageOffset = 0; - public applications: Application[]; - @Input() organizationId: number; - canEdit: boolean; - private unauthorizedMessage: string; - private kombitError: string; - private noAccess: string; - hasSomePermission: boolean; - isGlobalAdmin = false; - - constructor( - public translate: TranslateService, - private titleService: Title, - private globalService: SharedVariableService, - private meService: MeService, - private sharedVariableService: SharedVariableService, - private authService: AuthService, - private route: ActivatedRoute, - private router: Router, - private dialog: MatDialog, - private userMinimalService: UserMinimalService - ) { - translate.use('da'); - } - - ngOnInit(): void { - this.translate.get(['TITLE.APPLICATION']).subscribe((translations) => { - this.titleService.setTitle(translations['TITLE.APPLICATION']); - }); - this.organizationId = this.globalService.getSelectedOrganisationId(); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite - ); - - // Authenticate user - this.verifyUserAndInit(); - } - - verifyUserAndInit() { - this.route.queryParams.subscribe(async (params) => { - await this.translate - .get([ - 'WELCOME-DIALOG.NO-JOB-ACCESS', - 'TITLE.FRONTPAGE', - 'WELCOME-DIALOG.KOMBIT-LOGIN-ERROR', - 'WELCOME-DIALOG.USER-INACTIVE', - ]) - .toPromise() - .then((translations) => { - this.unauthorizedMessage = - translations['WELCOME-DIALOG.NO-JOB-ACCESS']; - this.kombitError = translations['WELCOME-DIALOG.KOMBIT-LOGIN-ERROR']; - this.noAccess = translations['WELCOME-DIALOG.USER-INACTIVE']; - this.titleService.setTitle(translations['TITLE.FRONTPAGE']); + isLoadingResults = true; + + public pageLimit = environment.tablePageSize; + public resultsLength: number; + public pageOffset = 0; + public applications: Application[]; + @Input() organizationId: number; + canEdit: boolean; + private unauthorizedMessage: string; + private kombitError: string; + private noAccess: string; + hasSomePermission: boolean; + isGlobalAdmin = false; + + constructor( + public translate: TranslateService, + private titleService: Title, + private globalService: SharedVariableService, + private meService: MeService, + private sharedVariableService: SharedVariableService, + private authService: AuthService, + private route: ActivatedRoute, + private router: Router, + private dialog: MatDialog, + private userMinimalService: UserMinimalService + ) { + translate.use("da"); + } + + ngOnInit(): void { + this.translate.get(["TITLE.APPLICATION"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.APPLICATION"]); }); - // this is used when a user is returned from Kombit login - const jwt = params['jwt']; - - if (jwt) { - this.authService.setSession(jwt); - - const userInfo = await this.sharedVariableService.setUserInfo(); - if (!userInfo.user.email) { - this.router.navigate(['/new-user'], { - state: { fromKombit: true }, - }); - return; - } else { - // Clear the URL from the parameter - this.router.navigate(['/applications'], { replaceUrl: true }); - return; - } - } else { - const error = params['error']; - if (error) { - if ( - error === 'MESSAGE.KOMBIT-LOGIN-FAILED' || - error === 'MESSAGE.API-KEY-AUTH-FAILED' - ) { - this.router.navigate(['/not-authorized'], { - state: { message: this.kombitError, code: 401 }, - }); - } else if (error === 'MESSAGE.USER-INACTIVE') { - this.router.navigate(['/not-authorized'], { - state: { message: this.noAccess, code: 401 }, - }); - } else { - this.router.navigate(['/not-authorized'], { - state: { message: this.unauthorizedMessage, code: 401 }, - }); - } - - return; - } - } - - const userInfo = await this.sharedVariableService.setUserInfo(); - this.isGlobalAdmin = this.meService.hasGlobalAdmin(); - const hasSeenWelcomeScreen = this.userMinimalService.getHasSeenWelcomeScreen(); - this.hasSomePermission = this.sharedVariableService.getHasAnyPermission(); - const isOpen = !!this.dialog?.getDialogById(welcomeDialogId); - - if ( - !this.hasSomePermission || - (!this.isGlobalAdmin && - !hasSeenWelcomeScreen && - userInfo?.user?.showWelcomeScreen && - !isOpen) - ) { - this.userMinimalService.setHasSeenWelcomeScreen(); - - this.dialog.open(WelcomeDialogComponent, { - id: welcomeDialogId, - disableClose: true, - closeOnNavigation: true, - panelClass: 'welcome-screen', - maxWidth: '60vw', - data: { - hasSomePermission: this.hasSomePermission, - } as WelcomeDialogModel, + this.organizationId = this.globalService.getSelectedOrganisationId(); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite); + + // Authenticate user + this.verifyUserAndInit(); + } + + verifyUserAndInit() { + this.route.queryParams.subscribe(async params => { + await this.translate + .get([ + "WELCOME-DIALOG.NO-JOB-ACCESS", + "TITLE.FRONTPAGE", + "WELCOME-DIALOG.KOMBIT-LOGIN-ERROR", + "WELCOME-DIALOG.USER-INACTIVE", + ]) + .toPromise() + .then(translations => { + this.unauthorizedMessage = translations["WELCOME-DIALOG.NO-JOB-ACCESS"]; + this.kombitError = translations["WELCOME-DIALOG.KOMBIT-LOGIN-ERROR"]; + this.noAccess = translations["WELCOME-DIALOG.USER-INACTIVE"]; + this.titleService.setTitle(translations["TITLE.FRONTPAGE"]); + }); + // this is used when a user is returned from Kombit login + const jwt = params["jwt"]; + + if (jwt) { + this.authService.setSession(jwt); + + const userInfo = await this.sharedVariableService.setUserInfo(); + if (!userInfo.user.email) { + this.router.navigate(["/new-user"], { + state: { fromKombit: true }, + }); + return; + } else { + // Clear the URL from the parameter + this.router.navigate(["/applications"], { replaceUrl: true }); + return; + } + } else { + const error = params["error"]; + if (error) { + if (error === "MESSAGE.KOMBIT-LOGIN-FAILED" || error === "MESSAGE.API-KEY-AUTH-FAILED") { + this.router.navigate(["/not-authorized"], { + state: { message: this.kombitError, code: 401 }, + }); + } else if (error === "MESSAGE.USER-INACTIVE") { + this.router.navigate(["/not-authorized"], { + state: { message: this.noAccess, code: 401 }, + }); + } else { + this.router.navigate(["/not-authorized"], { + state: { message: this.unauthorizedMessage, code: 401 }, + }); + } + + return; + } + } + + const userInfo = await this.sharedVariableService.setUserInfo(); + this.isGlobalAdmin = this.meService.hasGlobalAdmin(); + const hasSeenWelcomeScreen = this.userMinimalService.getHasSeenWelcomeScreen(); + this.hasSomePermission = this.sharedVariableService.getHasAnyPermission(); + const isOpen = !!this.dialog?.getDialogById(welcomeDialogId); + + if ( + !this.hasSomePermission || + (!this.isGlobalAdmin && !hasSeenWelcomeScreen && userInfo?.user?.showWelcomeScreen && !isOpen) + ) { + this.userMinimalService.setHasSeenWelcomeScreen(); + + this.dialog.open(WelcomeDialogComponent, { + id: welcomeDialogId, + disableClose: true, + closeOnNavigation: true, + panelClass: "welcome-screen", + maxWidth: "60vw", + data: { + hasSomePermission: this.hasSomePermission, + } as WelcomeDialogModel, + }); + + if (!this.hasSomePermission) { + // In case a previous .navigate() was fired, ensure this is called after + setTimeout(() => { + this.router.navigate(["/user-page"], { replaceUrl: true }); + }); + } + } + + if (this.hasSomePermission) { + await this.sharedVariableService.setOrganizationInfo(); + this.userMinimalService.setUserMinimalList(); + } + + this.isLoadingResults = false; }); - - if (!this.hasSomePermission) { - // In case a previous .navigate() was fired, ensure this is called after - setTimeout(() => { - this.router.navigate(['/user-page'], { replaceUrl: true }); - }); - } - } - - if (this.hasSomePermission) { - await this.sharedVariableService.setOrganizationInfo(); - this.userMinimalService.setUserMinimalList(); - } - - this.isLoadingResults = false; - }); - } + } } diff --git a/src/app/applications/applications-list/applications-table/applications-table.component.html b/src/app/applications/applications-list/applications-table/applications-table.component.html index 72449d4c0..35aa21c69 100644 --- a/src/app/applications/applications-list/applications-table/applications-table.component.html +++ b/src/app/applications/applications-list/applications-table/applications-table.component.html @@ -1,166 +1,192 @@
-
- -
-
-
- {{errorMessage | translate}} +
+ +
+
+
+ {{ errorMessage | translate }} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ "APPLICATION-TABLE.NAME" | translate }} + + {{ element.name }} + + {{ "APPLICATION-TABLE.OWNER" | translate }} + + {{ application.owner ?? "-" }} + + {{ "APPLICATION-TABLE.CONTACT-PERSON" | translate }} + + {{ application.contactPerson ?? "-" }} + + {{ "APPLICATION-TABLE.IOT-DEVICES" | translate }} + + {{ element?.iotDevices?.length ?? 0 }} + + {{ "APPLICATION-TABLE.DATA-TARGETS" | translate }} + + {{ application?.dataTargets?.length ?? 0 }} + + {{ "APPLICATION-TABLE.OPEN-DATA-DK" | translate }} + + {{ isOpenDataDK(application.dataTargets) | yesNo }} + + {{ "APPLICATION-TABLE.STATUS" | translate }} + + {{ application.status ? ("APPLICATION.STATUS." + application.status | translate) : "-" }} + + {{ "APPLICATION-TABLE.PERSONAL-DATA" | translate }} + + + {{ !application.personalData ? "-" : "" }} + + {{ "APPLICATION-TABLE.START-DATE" | translate }} + + {{ (application.startDate | dateOnly) ?? "-" }} + + {{ "APPLICATION-TABLE.END-DATE" | translate }} + + {{ (application.endDate | dateOnly) ?? "-" }} + + {{ "APPLICATION-TABLE.CATEGORY" | translate }} + + {{ application.category ?? "-" }} + + {{ "APPLICATION-TABLE.CONTROLLED-PROPERTIES" | translate }} + + {{ mapControlledProperties(application.controlledProperties) ?? "-" }} + + {{ "APPLICATION-TABLE.DEVICE-TYPES" | translate }} + + {{ mapDeviceTypes(application.deviceTypes) ?? "-" }} + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- {{ 'APPLICATION-TABLE.NAME' | translate }} - - {{element.name}} - - {{'APPLICATION-TABLE.OWNER' | translate}} - - {{application.owner ?? '-'}} - - {{'APPLICATION-TABLE.CONTACT-PERSON' | translate}} - - {{application.contactPerson ?? '-'}} - - {{ 'APPLICATION-TABLE.IOT-DEVICES' | translate }} - {{element?.iotDevices?.length ?? 0}} - - {{ 'APPLICATION-TABLE.DATA-TARGETS' | translate}} - - {{application?.dataTargets?.length ?? 0}} - - {{ 'APPLICATION-TABLE.OPEN-DATA-DK' | translate }} - - {{isOpenDataDK(application.dataTargets) | yesNo}} - - {{'APPLICATION-TABLE.STATUS' | translate}} - - {{application.status ? ('APPLICATION.STATUS.' + application.status | translate) : '-'}} - - {{'APPLICATION-TABLE.PERSONAL-DATA' | translate}} - - - {{!application.personalData ? '-' : ''}} - - {{'APPLICATION-TABLE.START-DATE' | translate}} - - {{(application.startDate | dateOnly) ?? '-'}} - - {{'APPLICATION-TABLE.END-DATE' | translate}} - - {{(application.endDate | dateOnly) ?? '-'}} - - {{'APPLICATION-TABLE.CATEGORY' | translate}} - - {{application.category ?? '-'}} - - {{'APPLICATION-TABLE.CONTROLLED-PROPERTIES' | translate}} - - {{mapControlledProperties(application.controlledProperties) ?? '-'}} - - {{'APPLICATION-TABLE.DEVICE-TYPES' | translate}} - - {{mapDeviceTypes(application.deviceTypes) ?? '-'}} - - -
-
- - - + +
diff --git a/src/app/applications/applications-list/applications-table/applications-table.component.scss b/src/app/applications/applications-list/applications-table/applications-table.component.scss index 29eef3e50..d73f233bd 100644 --- a/src/app/applications/applications-list/applications-table/applications-table.component.scss +++ b/src/app/applications/applications-list/applications-table/applications-table.component.scss @@ -1,3 +1,3 @@ .flag-icon { - color: red; + color: red; } diff --git a/src/app/applications/applications-list/applications-table/applications-table.component.spec.ts b/src/app/applications/applications-list/applications-table/applications-table.component.spec.ts index f6e107433..794f92d86 100644 --- a/src/app/applications/applications-list/applications-table/applications-table.component.spec.ts +++ b/src/app/applications/applications-list/applications-table/applications-table.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { ApplicationsTableComponent } from './applications-table.component'; +import { ApplicationsTableComponent } from "./applications-table.component"; -describe('ApplicationTableOtherComponent', () => { - let component: ApplicationsTableComponent; - let fixture: ComponentFixture; +describe("ApplicationTableOtherComponent", () => { + let component: ApplicationsTableComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ ApplicationsTableComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ApplicationsTableComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(ApplicationsTableComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ApplicationsTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/applications-routing.module.ts b/src/app/applications/applications-routing.module.ts index 3500e7d2e..e19a57341 100644 --- a/src/app/applications/applications-routing.module.ts +++ b/src/app/applications/applications-routing.module.ts @@ -1,94 +1,94 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { ApplicationDetailComponent } from './application-detail/application-detail.component'; -import { ApplicationEditComponent } from './application-edit/application-edit.component'; -import { ApplicationsListComponent } from './applications-list/applications-list.component'; -import { ApplicationsComponent } from './applications.component'; -import { IoTDeviceDetailComponent } from './iot-devices/iot-device-detail/iot-device-detail.component'; -import { IotDeviceEditComponent } from './iot-devices/iot-device-edit/iot-device-edit.component'; -import { DatatargetEditComponent } from './datatarget/datatarget-edit/datatarget-edit.component'; -import { DatatargetDetailComponent } from './datatarget/datatarget-detail/datatarget-detail.component'; -import { BulkImportComponent } from './bulk-import/bulk-import.component'; -import { MulticastEditComponent } from './multicast/multicast-edit/multicast-edit.component'; -import { MulticastDetailComponent } from './multicast/multicast-detail/multicast-detail.component'; -import { DatatargetNewComponent } from './datatarget/datatarget-new/datatarget-new.component'; -import { IotDevicesTabComponent } from '@applications/iot-devices/iot-devices-tab/iot-devices-tab.component'; -import { MulticastTabComponent } from '@applications/multicast/multicast-tab/multicast-tab.component'; -import { DatatargetTabComponent } from '@applications/datatarget/datatarget-tab/datatarget-tab.component'; -import { IotDeviceDetailsTabComponent } from '@applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component'; -import { IotDeviceHistoryTabComponent } from '@applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component'; -import { IotDeviceDataPacketsTabComponent } from '@applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component'; -import { IotDeviceDownlinkTabComponent } from '@applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component'; +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { ApplicationDetailComponent } from "./application-detail/application-detail.component"; +import { ApplicationEditComponent } from "./application-edit/application-edit.component"; +import { ApplicationsListComponent } from "./applications-list/applications-list.component"; +import { ApplicationsComponent } from "./applications.component"; +import { IoTDeviceDetailComponent } from "./iot-devices/iot-device-detail/iot-device-detail.component"; +import { IotDeviceEditComponent } from "./iot-devices/iot-device-edit/iot-device-edit.component"; +import { DatatargetEditComponent } from "./datatarget/datatarget-edit/datatarget-edit.component"; +import { DatatargetDetailComponent } from "./datatarget/datatarget-detail/datatarget-detail.component"; +import { BulkImportComponent } from "./bulk-import/bulk-import.component"; +import { MulticastEditComponent } from "./multicast/multicast-edit/multicast-edit.component"; +import { MulticastDetailComponent } from "./multicast/multicast-detail/multicast-detail.component"; +import { DatatargetNewComponent } from "./datatarget/datatarget-new/datatarget-new.component"; +import { IotDevicesTabComponent } from "@applications/iot-devices/iot-devices-tab/iot-devices-tab.component"; +import { MulticastTabComponent } from "@applications/multicast/multicast-tab/multicast-tab.component"; +import { DatatargetTabComponent } from "@applications/datatarget/datatarget-tab/datatarget-tab.component"; +import { IotDeviceDetailsTabComponent } from "@applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component"; +import { IotDeviceHistoryTabComponent } from "@applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component"; +import { IotDeviceDataPacketsTabComponent } from "@applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component"; +import { IotDeviceDownlinkTabComponent } from "@applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component"; const applicationRoutes: Routes = [ - { - path: '', - component: ApplicationsComponent, - children: [ - { path: '', component: ApplicationsListComponent }, - { path: 'new-application', component: ApplicationEditComponent }, - { path: 'edit-application/:id', component: ApplicationEditComponent }, - { - path: ':id', + { + path: "", + component: ApplicationsComponent, children: [ - { - path: '', - component: ApplicationDetailComponent, - children: [ - { path: 'iot-devices', component: IotDevicesTabComponent }, - { path: 'multicast-groups', component: MulticastTabComponent }, - { path: 'data-targets', component: DatatargetTabComponent }, - ], - }, - { path: 'new-iot-device', component: IotDeviceEditComponent }, - { - path: 'iot-device-edit/:deviceId', - component: IotDeviceEditComponent, - }, - { - path: 'iot-device/:deviceId', - component: IoTDeviceDetailComponent, - children: [ - { path: 'details', component: IotDeviceDetailsTabComponent }, - { path: 'history', component: IotDeviceHistoryTabComponent }, - { - path: 'data-packets', - component: IotDeviceDataPacketsTabComponent, - }, - { - path: 'downlink', - component: IotDeviceDownlinkTabComponent, - }, - ], - }, - { path: 'datatarget-new', component: DatatargetNewComponent }, - { path: 'datatarget-edit', component: DatatargetEditComponent }, - { - path: 'datatarget-edit/:datatargetId', - component: DatatargetEditComponent, - }, - { - path: 'datatarget/:datatargetId', - component: DatatargetDetailComponent, - }, - { path: 'multicast-edit', component: MulticastEditComponent }, - { - path: 'multicast-edit/:multicastId', - component: MulticastEditComponent, - }, - { - path: 'multicast/:multicastId', - component: MulticastDetailComponent, - }, - { path: 'bulk-import', component: BulkImportComponent }, + { path: "", component: ApplicationsListComponent }, + { path: "new-application", component: ApplicationEditComponent }, + { path: "edit-application/:id", component: ApplicationEditComponent }, + { + path: ":id", + children: [ + { + path: "", + component: ApplicationDetailComponent, + children: [ + { path: "iot-devices", component: IotDevicesTabComponent }, + { path: "multicast-groups", component: MulticastTabComponent }, + { path: "data-targets", component: DatatargetTabComponent }, + ], + }, + { path: "new-iot-device", component: IotDeviceEditComponent }, + { + path: "iot-device-edit/:deviceId", + component: IotDeviceEditComponent, + }, + { + path: "iot-device/:deviceId", + component: IoTDeviceDetailComponent, + children: [ + { path: "details", component: IotDeviceDetailsTabComponent }, + { path: "history", component: IotDeviceHistoryTabComponent }, + { + path: "data-packets", + component: IotDeviceDataPacketsTabComponent, + }, + { + path: "downlink", + component: IotDeviceDownlinkTabComponent, + }, + ], + }, + { path: "datatarget-new", component: DatatargetNewComponent }, + { path: "datatarget-edit", component: DatatargetEditComponent }, + { + path: "datatarget-edit/:datatargetId", + component: DatatargetEditComponent, + }, + { + path: "datatarget/:datatargetId", + component: DatatargetDetailComponent, + }, + { path: "multicast-edit", component: MulticastEditComponent }, + { + path: "multicast-edit/:multicastId", + component: MulticastEditComponent, + }, + { + path: "multicast/:multicastId", + component: MulticastDetailComponent, + }, + { path: "bulk-import", component: BulkImportComponent }, + ], + }, ], - }, - ], - }, + }, ]; @NgModule({ - imports: [RouterModule.forChild(applicationRoutes)], - exports: [RouterModule], + imports: [RouterModule.forChild(applicationRoutes)], + exports: [RouterModule], }) export class ApplicaitonsRoutingModule {} diff --git a/src/app/applications/applications.component.spec.ts b/src/app/applications/applications.component.spec.ts index e8cbcb290..8afde1f52 100644 --- a/src/app/applications/applications.component.spec.ts +++ b/src/app/applications/applications.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { ApplicationsComponent } from './applications.component'; +import { ApplicationsComponent } from "./applications.component"; -describe('ApplicationsComponent', () => { - let component: ApplicationsComponent; - let fixture: ComponentFixture; +describe("ApplicationsComponent", () => { + let component: ApplicationsComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ApplicationsComponent] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ApplicationsComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(ApplicationsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ApplicationsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/applications.component.ts b/src/app/applications/applications.component.ts index 51cae9f3f..d2e52144d 100644 --- a/src/app/applications/applications.component.ts +++ b/src/app/applications/applications.component.ts @@ -1,14 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-applications', - templateUrl: './applications.component.html', + selector: "app-applications", + templateUrl: "./applications.component.html", }) export class ApplicationsComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit(): void { - } - + ngOnInit(): void {} } diff --git a/src/app/applications/applications.module.ts b/src/app/applications/applications.module.ts index f7c9c34c0..2783eac51 100644 --- a/src/app/applications/applications.module.ts +++ b/src/app/applications/applications.module.ts @@ -1,53 +1,49 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { RouterModule } from '@angular/router'; -import { TranslateModule } from '@ngx-translate/core'; -import { ApplicationsComponent } from './applications.component'; -import { FormModule } from '@shared/components/forms/form.module'; -import { ApplicationDetailComponent } from './application-detail/application-detail.component'; -import { ApplicationEditComponent } from './application-edit/application-edit.component'; -import { ApplicationsListComponent } from './applications-list/applications-list.component'; -import { ApplicaitonsRoutingModule } from './applications-routing.module'; -import { DatatargetModule } from './datatarget/datatarget.module'; -import { IotDevicesModule } from './iot-devices/iot-devices.module'; -import { SharedModule } from '@shared/shared.module'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { DirectivesModule } from '@shared/directives/directives.module'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { BulkImportComponent } from './bulk-import/bulk-import.component'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { ApplicationsTableComponent } from './applications-list/applications-table/applications-table.component'; -import { MulticastModule } from './multicast/multicast.module'; -import { ReactiveFormsModule } from '@angular/forms'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { RouterModule } from "@angular/router"; +import { TranslateModule } from "@ngx-translate/core"; +import { ApplicationsComponent } from "./applications.component"; +import { FormModule } from "@shared/components/forms/form.module"; +import { ApplicationDetailComponent } from "./application-detail/application-detail.component"; +import { ApplicationEditComponent } from "./application-edit/application-edit.component"; +import { ApplicationsListComponent } from "./applications-list/applications-list.component"; +import { ApplicaitonsRoutingModule } from "./applications-routing.module"; +import { DatatargetModule } from "./datatarget/datatarget.module"; +import { IotDevicesModule } from "./iot-devices/iot-devices.module"; +import { SharedModule } from "@shared/shared.module"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { DirectivesModule } from "@shared/directives/directives.module"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { BulkImportComponent } from "./bulk-import/bulk-import.component"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { ApplicationsTableComponent } from "./applications-list/applications-table/applications-table.component"; +import { MulticastModule } from "./multicast/multicast.module"; +import { ReactiveFormsModule } from "@angular/forms"; @NgModule({ - declarations: [ - ApplicationsComponent, - ApplicationDetailComponent, - ApplicationEditComponent, - ApplicationsListComponent, - ApplicationsTableComponent, - BulkImportComponent, - ], - exports: [ - ApplicaitonsRoutingModule, - ApplicationsComponent, - ApplicationsTableComponent, - ], - imports: [ - CommonModule, - RouterModule, - TranslateModule, - IotDevicesModule, - DatatargetModule, - DirectivesModule, - FormModule, - SharedModule, - FontAwesomeModule, - NGMaterialModule, - PipesModule, - MulticastModule, - ReactiveFormsModule, - ], + declarations: [ + ApplicationsComponent, + ApplicationDetailComponent, + ApplicationEditComponent, + ApplicationsListComponent, + ApplicationsTableComponent, + BulkImportComponent, + ], + exports: [ApplicaitonsRoutingModule, ApplicationsComponent, ApplicationsTableComponent], + imports: [ + CommonModule, + RouterModule, + TranslateModule, + IotDevicesModule, + DatatargetModule, + DirectivesModule, + FormModule, + SharedModule, + FontAwesomeModule, + NGMaterialModule, + PipesModule, + MulticastModule, + ReactiveFormsModule, + ], }) export class ApplicationsModule {} diff --git a/src/app/applications/bulk-import/bulk-import.component.html b/src/app/applications/bulk-import/bulk-import.component.html index 129225a5e..d298315e7 100644 --- a/src/app/applications/bulk-import/bulk-import.component.html +++ b/src/app/applications/bulk-import/bulk-import.component.html @@ -2,88 +2,107 @@
- +
    - {{'APPLICATION.BULK.FILEFORMATERRORMESSAGE' | translate}} + {{ + "APPLICATION.BULK.FILEFORMATERRORMESSAGE" | translate + }}
- -
- -
- +
+
-
-

{{ file }}

+
+

{{ file }}

-
- +
- - - + + - - + + - - + + - + - +
{{ 'APPLICATION.BULK.NAME' | translate }} {{element.device?.name}} {{ "APPLICATION.BULK.NAME" | translate }}{{ element.device?.name }} {{ 'APPLICATION.BULK.TYPE' | translate }} {{"IOT-DEVICE-TYPES." + element.device?.type | translate}} {{ "APPLICATION.BULK.TYPE" | translate }}{{ "IOT-DEVICE-TYPES." + element.device?.type | translate }} {{ 'APPLICATION.BULK.IMPORTSTATUS' | translate }} {{element.importStatus}} {{ "APPLICATION.BULK.IMPORTSTATUS" | translate }}{{ element.importStatus }} {{ 'APPLICATION.BULK.ERROR' | translate }} {{ "APPLICATION.BULK.ERROR" | translate }}
  • - {{error | translate}} + {{ error | translate }}
diff --git a/src/app/applications/bulk-import/bulk-import.component.scss b/src/app/applications/bulk-import/bulk-import.component.scss index d3f5a12fa..e69de29bb 100644 --- a/src/app/applications/bulk-import/bulk-import.component.scss +++ b/src/app/applications/bulk-import/bulk-import.component.scss @@ -1 +0,0 @@ - diff --git a/src/app/applications/bulk-import/bulk-import.component.ts b/src/app/applications/bulk-import/bulk-import.component.ts index 1fbebd7bb..e3ef383d7 100644 --- a/src/app/applications/bulk-import/bulk-import.component.ts +++ b/src/app/applications/bulk-import/bulk-import.component.ts @@ -1,308 +1,287 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { ActivatedRoute } from '@angular/router'; -import { - IotDeviceImportRequest, - IotDevicesImportResponse, -} from '@applications/iot-devices/iot-device.model'; -import { IoTDeviceService } from '@applications/iot-devices/iot-device.service'; -import { faDownload, faTrash } from '@fortawesome/free-solid-svg-icons'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { splitList } from '@shared/helpers/array.helper'; -import { Download } from '@shared/helpers/download.helper'; -import { BulkImportService } from '@shared/services/bulk-import.service'; -import { DownloadService } from '@shared/services/download.service'; -import { MeService } from '@shared/services/me.service'; -import { Papa } from 'ngx-papaparse'; -import { Observable, Subject } from 'rxjs'; -import { takeWhile } from 'rxjs/operators'; -import { BulkImport } from './bulk-import.model'; -import { BulkMapping } from './bulk-mapping'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { ActivatedRoute } from "@angular/router"; +import { IotDeviceImportRequest, IotDevicesImportResponse } from "@applications/iot-devices/iot-device.model"; +import { IoTDeviceService } from "@applications/iot-devices/iot-device.service"; +import { faDownload, faTrash } from "@fortawesome/free-solid-svg-icons"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { splitList } from "@shared/helpers/array.helper"; +import { Download } from "@shared/helpers/download.helper"; +import { BulkImportService } from "@shared/services/bulk-import.service"; +import { DownloadService } from "@shared/services/download.service"; +import { MeService } from "@shared/services/me.service"; +import { Papa } from "ngx-papaparse"; +import { Observable, Subject } from "rxjs"; +import { takeWhile } from "rxjs/operators"; +import { BulkImport } from "./bulk-import.model"; +import { BulkMapping } from "./bulk-mapping"; @Component({ - selector: 'app-bulk-import', - templateUrl: './bulk-import.component.html', - styleUrls: ['./bulk-import.component.scss'], + selector: "app-bulk-import", + templateUrl: "./bulk-import.component.html", + styleUrls: ["./bulk-import.component.scss"], }) export class BulkImportComponent implements OnInit { - displayedColumns: string[] = [ - 'name', - 'type', - 'importStatus', - 'errorMessages', - ]; - isLoading = false; - bulkImport: BulkImport[]; - bulkImportResult: BulkImport[]; - fileFormatErrorMessage = false; - files: any = []; - faTrash = faTrash; - faDownload = faDownload; - samples = [ - { - name: 'generic-http-sample.csv', - url: '../../../assets/docs/iotdevice_generichttp.csv', - }, - { - name: 'lorawan-otaa-sample.csv', - url: '../../../assets/docs/iotdevice_lorawan_otaa.csv', - }, - { - name: 'lorawan-abp-sample.csv', - url: '../../../assets/docs/iotdevice_lorawan_abp.csv', - }, - { - name: 'mqtt-internal-broker-sample.csv', - url: '../../../assets/docs/mqtt_internal_broker_sample.csv', - }, - { - name: 'mqtt-external-broker-sample.csv', - url: '../../../assets/docs/mqtt_external_broker_sample.csv', - }, - ]; - download$: Observable; - private bulkMapper = new BulkMapping(); - public backButtonTitle: string; - private applicationId; - - constructor( - private papa: Papa, - private iotDeviceService: IoTDeviceService, - private route: ActivatedRoute, - private titleService: Title, - private translate: TranslateService, - private downloads: DownloadService, - private errorMessageService: ErrorMessageService, - private meService: MeService, - private bulkImportService: BulkImportService - ) { - this.translate.use('da'); - } - - ngOnInit(): void { - this.translate.get(['TITLE.BULKIMPORT']).subscribe((translations) => { - this.titleService.setTitle(translations['TITLE.BULKIMPORT']); - }); - this.applicationId = +this.route.snapshot.paramMap.get('id'); - } + displayedColumns: string[] = ["name", "type", "importStatus", "errorMessages"]; + isLoading = false; + bulkImport: BulkImport[]; + bulkImportResult: BulkImport[]; + fileFormatErrorMessage = false; + files: any = []; + faTrash = faTrash; + faDownload = faDownload; + samples = [ + { + name: "generic-http-sample.csv", + url: "../../../assets/docs/iotdevice_generichttp.csv", + }, + { + name: "lorawan-otaa-sample.csv", + url: "../../../assets/docs/iotdevice_lorawan_otaa.csv", + }, + { + name: "lorawan-abp-sample.csv", + url: "../../../assets/docs/iotdevice_lorawan_abp.csv", + }, + { + name: "mqtt-internal-broker-sample.csv", + url: "../../../assets/docs/mqtt_internal_broker_sample.csv", + }, + { + name: "mqtt-external-broker-sample.csv", + url: "../../../assets/docs/mqtt_external_broker_sample.csv", + }, + ]; + download$: Observable; + private bulkMapper = new BulkMapping(); + public backButtonTitle: string; + private applicationId; - download({ name, url }: { name: string; url: string }) { - this.download$ = this.downloads.download(url, name); - } + constructor( + private papa: Papa, + private iotDeviceService: IoTDeviceService, + private route: ActivatedRoute, + private titleService: Title, + private translate: TranslateService, + private downloads: DownloadService, + private errorMessageService: ErrorMessageService, + private meService: MeService, + private bulkImportService: BulkImportService + ) { + this.translate.use("da"); + } - deleteAttachment(index) { - this.files.splice(index, 1); - } + ngOnInit(): void { + this.translate.get(["TITLE.BULKIMPORT"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.BULKIMPORT"]); + }); + this.applicationId = +this.route.snapshot.paramMap.get("id"); + } - handleDropedFile(evt: any) { - this.fileFormatErrorMessage = false; - if (!this.validateFile(evt[0].name)) { - console.log('Selected file format is not supported'); - this.fileFormatErrorMessage = true; - return false; + download({ name, url }: { name: string; url: string }) { + this.download$ = this.downloads.download(url, name); } - this.bulkImport = []; - this.bulkImportResult = []; - for (const element of evt) { - this.files.push(element.name); + deleteAttachment(index) { + this.files.splice(index, 1); } - // handle csv data - this.isLoading = true; - const files = evt; // File List object - const file = files[0]; - const reader = new FileReader(); - reader.readAsText(file); - reader.onload = (event: any) => { - const csv = event.target.result; // Content of CSV file - this.papa.parse(csv, { - skipEmptyLines: true, - header: true, - complete: (results) => { - this.mapData(results.data); - // this step ensures material can read from the array - should be fixed. - this.bulkImportResult = this.bulkImport; - if (this.bulkImport?.length === 0) { - alert('no data in csv'); - } else { - return this.bulkImport; - } - }, - }); - this.isLoading = false; - }; - } + handleDropedFile(evt: any) { + this.fileFormatErrorMessage = false; + if (!this.validateFile(evt[0].name)) { + console.log("Selected file format is not supported"); + this.fileFormatErrorMessage = true; + return false; + } + this.bulkImport = []; + this.bulkImportResult = []; + + for (const element of evt) { + this.files.push(element.name); + } + + // handle csv data + this.isLoading = true; + const files = evt; // File List object + const file = files[0]; + const reader = new FileReader(); + reader.readAsText(file); + reader.onload = (event: any) => { + const csv = event.target.result; // Content of CSV file + this.papa.parse(csv, { + skipEmptyLines: true, + header: true, + complete: results => { + this.mapData(results.data); + // this step ensures material can read from the array - should be fixed. + this.bulkImportResult = this.bulkImport; + if (this.bulkImport?.length === 0) { + alert("no data in csv"); + } else { + return this.bulkImport; + } + }, + }); + this.isLoading = false; + }; + } - private validateFile(name: string) { - const ext = name.substring(name.lastIndexOf('.') + 1); - if (ext.toLowerCase() === 'csv') { - return true; - } else { - return false; + private validateFile(name: string) { + const ext = name.substring(name.lastIndexOf(".") + 1); + if (ext.toLowerCase() === "csv") { + return true; + } else { + return false; + } } - } - private mapData(data: any[]) { - data.forEach((device) => { - const mappedDevice = this.bulkMapper.dataMapper( - device, - this.applicationId - ); - if (mappedDevice) { - this.bulkImport.push(new BulkImport(mappedDevice)); - } else { - this.translate.get(['ERROR.SEMANTIC']).subscribe((translations) => { - this.bulkImport.push( - new BulkImport(null, [translations['ERROR.SEMANTIC']]) - ); + private mapData(data: any[]) { + data.forEach(device => { + const mappedDevice = this.bulkMapper.dataMapper(device, this.applicationId); + if (mappedDevice) { + this.bulkImport.push(new BulkImport(mappedDevice)); + } else { + this.translate.get(["ERROR.SEMANTIC"]).subscribe(translations => { + this.bulkImport.push(new BulkImport(null, [translations["ERROR.SEMANTIC"]])); + }); + } }); - } - }); - } - - addIoTDevice() { - // Subscribe to subject in service, Emit the index of next item in the array to be previous - // The emit will activate the subscription which should call the updateIoTDevice - const { newDevices, updatedDevices } = this.splitDevices(); + } - this.postBulkImportPayload( - newDevices, - this.bulkImportService.nextCreateIotDeviceBatchIndex$, - this.iotDeviceService.createIoTDevices.bind(this.iotDeviceService) - ); - this.postBulkImportPayload( - updatedDevices, - this.bulkImportService.nextUpdateDeviceBatchIndex$, - this.iotDeviceService.updateIoTDevices.bind(this.iotDeviceService) - ); - } + addIoTDevice() { + // Subscribe to subject in service, Emit the index of next item in the array to be previous + // The emit will activate the subscription which should call the updateIoTDevice + const { newDevices, updatedDevices } = this.splitDevices(); - private postBulkImportPayload( - bulkDevices: BulkImport[][], - batchIndex$: Subject, - importDevices: ( - payload: IotDeviceImportRequest - ) => Observable - ): void { - if (!bulkDevices.length) { - return; + this.postBulkImportPayload( + newDevices, + this.bulkImportService.nextCreateIotDeviceBatchIndex$, + this.iotDeviceService.createIoTDevices.bind(this.iotDeviceService) + ); + this.postBulkImportPayload( + updatedDevices, + this.bulkImportService.nextUpdateDeviceBatchIndex$, + this.iotDeviceService.updateIoTDevices.bind(this.iotDeviceService) + ); } - let batchIndex = 0; + private postBulkImportPayload( + bulkDevices: BulkImport[][], + batchIndex$: Subject, + importDevices: (payload: IotDeviceImportRequest) => Observable + ): void { + if (!bulkDevices.length) { + return; + } - // takeWhile() will unsubscribe once the condition is false - batchIndex$.pipe(takeWhile(() => batchIndex in bulkDevices)).subscribe( - () => { - const requestItems = bulkDevices[batchIndex]; - const devices: IotDeviceImportRequest = { - data: requestItems.map((bulkResult) => bulkResult.device), - }; - importDevices(devices).subscribe( - (response) => { - this.onSuccessfulImport(response, requestItems); - ++batchIndex; - batchIndex$.next(); - }, - (error: HttpErrorResponse) => { - requestItems.forEach((item) => { - item.errorMessages = this.errorMessageService.handleErrorMessageWithFields( - error - ).errorMessages; - item.importStatus = 'Failed'; - }); - // Continue processing the next batches - ++batchIndex; - batchIndex$.next(); - } - ); - }, - (_error: HttpErrorResponse) => { - // Should not happen - }, - () => { - // Process any devices whose status hasn't been set and mark them as errors. - this.onCompleteImport(bulkDevices); - } - ); + let batchIndex = 0; - // Trigger our listener - batchIndex$.next(); - } + // takeWhile() will unsubscribe once the condition is false + batchIndex$.pipe(takeWhile(() => batchIndex in bulkDevices)).subscribe( + () => { + const requestItems = bulkDevices[batchIndex]; + const devices: IotDeviceImportRequest = { + data: requestItems.map(bulkResult => bulkResult.device), + }; + importDevices(devices).subscribe( + response => { + this.onSuccessfulImport(response, requestItems); + ++batchIndex; + batchIndex$.next(); + }, + (error: HttpErrorResponse) => { + requestItems.forEach(item => { + item.errorMessages = + this.errorMessageService.handleErrorMessageWithFields(error).errorMessages; + item.importStatus = "Failed"; + }); + // Continue processing the next batches + ++batchIndex; + batchIndex$.next(); + } + ); + }, + (_error: HttpErrorResponse) => { + // Should not happen + }, + () => { + // Process any devices whose status hasn't been set and mark them as errors. + this.onCompleteImport(bulkDevices); + } + ); - private onSuccessfulImport( - response: IotDevicesImportResponse[], - requestItems: BulkImport[] - ) { - response.forEach((responseItem) => { - const match = requestItems.find( - ({ device }) => - device.name === responseItem.idMetadata.name && - device.applicationId === responseItem.idMetadata.applicationId - ); - if (!match) { - return; - } + // Trigger our listener + batchIndex$.next(); + } - if (responseItem.error && match) { - match.errorMessages = this.errorMessageService.handleErrorMessageWithFields( - { error: responseItem.error } - ).errorMessages; - match.importStatus = 'Failed'; - } else { - match.errorMessages = []; - match.importStatus = 'Success'; - } - }); - } + private onSuccessfulImport(response: IotDevicesImportResponse[], requestItems: BulkImport[]) { + response.forEach(responseItem => { + const match = requestItems.find( + ({ device }) => + device.name === responseItem.idMetadata.name && + device.applicationId === responseItem.idMetadata.applicationId + ); + if (!match) { + return; + } - private onCompleteImport(devicesBulk: BulkImport[][]) { - for (const bulk of devicesBulk) { - for (const device of bulk) { - if (!device.importStatus) { - device.importStatus = 'Failed'; - device.errorMessages = this.errorMessageService.handleErrorMessageWithFields( - { - error: { - message: 'MESSAGE.FAILED-TO-CREATE-OR-UPDATE-IOT-DEVICE', - }, + if (responseItem.error && match) { + match.errorMessages = this.errorMessageService.handleErrorMessageWithFields({ + error: responseItem.error, + }).errorMessages; + match.importStatus = "Failed"; + } else { + match.errorMessages = []; + match.importStatus = "Success"; } - ).errorMessages; - } - } + }); } - } - private splitDevices(): { - newDevices: BulkImport[][]; - updatedDevices: BulkImport[][]; - } { - if (!this.bulkImportResult) { - return { newDevices: [], updatedDevices: [] }; + private onCompleteImport(devicesBulk: BulkImport[][]) { + for (const bulk of devicesBulk) { + for (const device of bulk) { + if (!device.importStatus) { + device.importStatus = "Failed"; + device.errorMessages = this.errorMessageService.handleErrorMessageWithFields({ + error: { + message: "MESSAGE.FAILED-TO-CREATE-OR-UPDATE-IOT-DEVICE", + }, + }).errorMessages; + } + } + } } - const { updatedDevices, newDevices } = this.bulkImportResult.reduce( - ( - res: { - newDevices: BulkImport[]; - updatedDevices: BulkImport[]; - }, - curr - ) => { - if (curr.device.id) { - res.updatedDevices.push(curr); - } else if (curr.device) { - res.newDevices.push(curr); + private splitDevices(): { + newDevices: BulkImport[][]; + updatedDevices: BulkImport[][]; + } { + if (!this.bulkImportResult) { + return { newDevices: [], updatedDevices: [] }; } - return res; - }, - { updatedDevices: [], newDevices: [] } - ); - return { - newDevices: splitList(newDevices), - updatedDevices: splitList(updatedDevices), - }; - } + + const { updatedDevices, newDevices } = this.bulkImportResult.reduce( + ( + res: { + newDevices: BulkImport[]; + updatedDevices: BulkImport[]; + }, + curr + ) => { + if (curr.device.id) { + res.updatedDevices.push(curr); + } else if (curr.device) { + res.newDevices.push(curr); + } + return res; + }, + { updatedDevices: [], newDevices: [] } + ); + return { + newDevices: splitList(newDevices), + updatedDevices: splitList(updatedDevices), + }; + } } diff --git a/src/app/applications/bulk-import/bulk-import.model.ts b/src/app/applications/bulk-import/bulk-import.model.ts index 904569f7e..82485996e 100644 --- a/src/app/applications/bulk-import/bulk-import.model.ts +++ b/src/app/applications/bulk-import/bulk-import.model.ts @@ -1,10 +1,10 @@ -import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; export class BulkImport { public device: IotDevice; public errorMessages: unknown[] = []; - public importStatus = ''; - constructor(device: IotDevice, errorMessages = [], importStatus = '') { + public importStatus = ""; + constructor(device: IotDevice, errorMessages = [], importStatus = "") { this.device = device; this.errorMessages = errorMessages; this.importStatus = importStatus; diff --git a/src/app/applications/bulk-import/bulk-mapping.ts b/src/app/applications/bulk-import/bulk-mapping.ts index efb2b8a14..f03694793 100644 --- a/src/app/applications/bulk-import/bulk-mapping.ts +++ b/src/app/applications/bulk-import/bulk-mapping.ts @@ -1,128 +1,120 @@ -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { DeviceType } from '@shared/enums/device-type'; -import { Buffer } from 'buffer'; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { DeviceType } from "@shared/enums/device-type"; +import { Buffer } from "buffer"; export class BulkMapping { - public dataMapper(data: IotDevice, applicationId: number): IotDevice { - switch (data.type.toUpperCase()) { - case DeviceType.LORAWAN: - return this.lorawanMapper(data, applicationId); - case DeviceType.MQTT_INTERNAL_BROKER: - return this.mqttInternalBrokerMapper(data, applicationId); - case DeviceType.MQTT_EXTERNAL_BROKER: - return this.mqttExternalBrokerMapper(data, applicationId); - case DeviceType.GENERIC_HTTP: - return this.baseMapper(data, applicationId); - default: - break; + public dataMapper(data: IotDevice, applicationId: number): IotDevice { + switch (data.type.toUpperCase()) { + case DeviceType.LORAWAN: + return this.lorawanMapper(data, applicationId); + case DeviceType.MQTT_INTERNAL_BROKER: + return this.mqttInternalBrokerMapper(data, applicationId); + case DeviceType.MQTT_EXTERNAL_BROKER: + return this.mqttExternalBrokerMapper(data, applicationId); + case DeviceType.GENERIC_HTTP: + return this.baseMapper(data, applicationId); + default: + break; + } } - } - private lorawanMapper(data: any, applicationId): IotDevice { - const newDevice = this.baseMapper(data, applicationId); - newDevice.lorawanSettings = { - devEUI: data.devEUI, - skipFCntCheck: data.skipFCntCheck - ? this.convertToBoolean(data.skipFCntCheck) - : undefined, - activationType: data.activationType ? data.activationType : undefined, - OTAAapplicationKey: data.OTAAapplicationKey - ? data.OTAAapplicationKey - : undefined, - devAddr: data.devAddr ? data.devAddr : undefined, - networkSessionKey: data.networkSessionKey - ? data.networkSessionKey - : undefined, - applicationSessionKey: data.applicationSessionKey - ? data.applicationSessionKey - : undefined, - deviceProfileID: data.deviceProfileID ? data.deviceProfileID : undefined, - fCntUp: data.fCntUp ? +data.fCntUp : undefined, - nFCntDown: data.nFCntDown ? +data.nFCntDown : undefined, - deviceStatusBattery: undefined, - deviceStatusMargin: undefined, - }; - newDevice.type = DeviceType.LORAWAN; - return newDevice; - } + private lorawanMapper(data: any, applicationId): IotDevice { + const newDevice = this.baseMapper(data, applicationId); + newDevice.lorawanSettings = { + devEUI: data.devEUI, + skipFCntCheck: data.skipFCntCheck ? this.convertToBoolean(data.skipFCntCheck) : undefined, + activationType: data.activationType ? data.activationType : undefined, + OTAAapplicationKey: data.OTAAapplicationKey ? data.OTAAapplicationKey : undefined, + devAddr: data.devAddr ? data.devAddr : undefined, + networkSessionKey: data.networkSessionKey ? data.networkSessionKey : undefined, + applicationSessionKey: data.applicationSessionKey ? data.applicationSessionKey : undefined, + deviceProfileID: data.deviceProfileID ? data.deviceProfileID : undefined, + fCntUp: data.fCntUp ? +data.fCntUp : undefined, + nFCntDown: data.nFCntDown ? +data.nFCntDown : undefined, + deviceStatusBattery: undefined, + deviceStatusMargin: undefined, + }; + newDevice.type = DeviceType.LORAWAN; + return newDevice; + } - private mqttInternalBrokerMapper(data: any, applicationId: number) { - const newDevice = this.baseMapper(data, applicationId); - newDevice.mqttInternalBrokerSettings = { - authenticationType: data.authenticationType, - caCertificate: undefined, - deviceCertificate: undefined, - deviceCertificateKey: undefined, - mqttPort: undefined, - mqttURL: undefined, - mqtttopicname: undefined, - mqttusername: data.mqttusername, - mqttpassword: data.mqttpassword, - }; - newDevice.type = DeviceType.MQTT_INTERNAL_BROKER; - return newDevice; - } + private mqttInternalBrokerMapper(data: any, applicationId: number) { + const newDevice = this.baseMapper(data, applicationId); + newDevice.mqttInternalBrokerSettings = { + authenticationType: data.authenticationType, + caCertificate: undefined, + deviceCertificate: undefined, + deviceCertificateKey: undefined, + mqttPort: undefined, + mqttURL: undefined, + mqtttopicname: undefined, + mqttusername: data.mqttusername, + mqttpassword: data.mqttpassword, + }; + newDevice.type = DeviceType.MQTT_INTERNAL_BROKER; + return newDevice; + } - private mqttExternalBrokerMapper(data: any, applicationId: number) { - const newDevice = this.baseMapper(data, applicationId); - newDevice.mqttExternalBrokerSettings = { - authenticationType: data.authenticationType, - caCertificate: this.base64Decode(data.caCertificate), - deviceCertificate: this.base64Decode(data.deviceCertificate), - deviceCertificateKey: this.base64Decode(data.deviceCertificateKey), - mqttPort: data.mqttPort ? Number(data.mqttPort) : undefined, - mqttURL: data.mqttURL, - mqtttopicname: data.mqtttopicname, - mqttpassword: data.mqttpassword, - mqttusername: data.mqttusername, - invalidMqttConfig: data.invalidMqttConfig, - }; - newDevice.type = DeviceType.MQTT_EXTERNAL_BROKER; - return newDevice; - } + private mqttExternalBrokerMapper(data: any, applicationId: number) { + const newDevice = this.baseMapper(data, applicationId); + newDevice.mqttExternalBrokerSettings = { + authenticationType: data.authenticationType, + caCertificate: this.base64Decode(data.caCertificate), + deviceCertificate: this.base64Decode(data.deviceCertificate), + deviceCertificateKey: this.base64Decode(data.deviceCertificateKey), + mqttPort: data.mqttPort ? Number(data.mqttPort) : undefined, + mqttURL: data.mqttURL, + mqtttopicname: data.mqtttopicname, + mqttpassword: data.mqttpassword, + mqttusername: data.mqttusername, + invalidMqttConfig: data.invalidMqttConfig, + }; + newDevice.type = DeviceType.MQTT_EXTERNAL_BROKER; + return newDevice; + } - private base64Decode(input: string) { - if (!input) { - return undefined; + private base64Decode(input: string) { + if (!input) { + return undefined; + } + return Buffer.from(input, "base64").toString("binary"); } - return Buffer.from(input, 'base64').toString('binary'); - } - private convertToBoolean(text: string): boolean { - if (text.toUpperCase() === 'TRUE') { - return true; - } else { - return false; + private convertToBoolean(text: string): boolean { + if (text.toUpperCase() === "TRUE") { + return true; + } else { + return false; + } } - } - private baseMapper(data: any, applicationId: number): IotDevice { - return { - name: data.name, - application: undefined, - location: undefined, - commentOnLocation: data.commentOnLocation, - comment: data.comment, - type: DeviceType.GENERIC_HTTP, - receivedMessagesMetadata: undefined, - metadata: undefined, - apiKey: undefined, - id: undefined, - createdAt: undefined, - updatedAt: undefined, - applicationId: applicationId, - longitude: data.longitude ? Number(data.longitude) : 0, - latitude: data.latitude ? Number(data.latitude) : 0, - latestReceivedMessage: undefined, - lorawanSettings: undefined, - sigfoxSettings: undefined, - mqttInternalBrokerSettings: undefined, - mqttExternalBrokerSettings: undefined, - createdBy: undefined, - updatedBy: undefined, - updatedByName: undefined, - createdByName: undefined, - deviceModelId: data.deviceModelId != '' ? +data.deviceModelId : undefined, - }; - } + private baseMapper(data: any, applicationId: number): IotDevice { + return { + name: data.name, + application: undefined, + location: undefined, + commentOnLocation: data.commentOnLocation, + comment: data.comment, + type: DeviceType.GENERIC_HTTP, + receivedMessagesMetadata: undefined, + metadata: undefined, + apiKey: undefined, + id: undefined, + createdAt: undefined, + updatedAt: undefined, + applicationId: applicationId, + longitude: data.longitude ? Number(data.longitude) : 0, + latitude: data.latitude ? Number(data.latitude) : 0, + latestReceivedMessage: undefined, + lorawanSettings: undefined, + sigfoxSettings: undefined, + mqttInternalBrokerSettings: undefined, + mqttExternalBrokerSettings: undefined, + createdBy: undefined, + updatedBy: undefined, + updatedByName: undefined, + createdByName: undefined, + deviceModelId: data.deviceModelId != "" ? +data.deviceModelId : undefined, + }; + } } diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.spec.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.spec.ts index 3a9402c7e..dd2130ba2 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.spec.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.spec.ts @@ -1,11 +1,11 @@ /* tslint:disable:no-unused-variable */ -import { ViewContainerRef } from '@angular/core'; -import { DatatargetDetailTypeSelectorDirective } from './datatarget-detail-type-selector.directive'; -let viewContainerRef: ViewContainerRef; -describe('Directive: DatatargetDetailTypeSelector', () => { - it('should create an instance', () => { - const directive = new DatatargetDetailTypeSelectorDirective(viewContainerRef); - expect(directive).toBeTruthy(); - }); +import { ViewContainerRef } from "@angular/core"; +import { DatatargetDetailTypeSelectorDirective } from "./datatarget-detail-type-selector.directive"; +let viewContainerRef: ViewContainerRef; +describe("Directive: DatatargetDetailTypeSelector", () => { + it("should create an instance", () => { + const directive = new DatatargetDetailTypeSelectorDirective(viewContainerRef); + expect(directive).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.ts index 84a3f73ad..4b07b3c07 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail-type-selector.directive.ts @@ -1,9 +1,8 @@ -import { Directive, ViewContainerRef } from '@angular/core'; +import { Directive, ViewContainerRef } from "@angular/core"; @Directive({ - selector: '[detail-component]' + selector: "[detail-component]", }) export class DatatargetDetailTypeSelectorDirective { - - constructor(public viewContainerRef: ViewContainerRef) { } + constructor(public viewContainerRef: ViewContainerRef) {} } diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.html b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.html index 68709486e..f5163d2b0 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.html +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.scss b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.scss index 6ea16b890..551c86e76 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.scss +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.scss @@ -1,3 +1,3 @@ pre { - word-wrap: break-word; -} \ No newline at end of file + word-wrap: break-word; +} diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.spec.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.spec.ts index 7da458394..d4f3c0d10 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.spec.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DatatargetDetailComponent } from './datatarget-detail.component'; +import { DatatargetDetailComponent } from "./datatarget-detail.component"; -describe('DatatargetComponent', () => { - let component: DatatargetDetailComponent; - let fixture: ComponentFixture; +describe("DatatargetComponent", () => { + let component: DatatargetDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [DatatargetDetailComponent] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DatatargetDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DatatargetDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DatatargetDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.ts index bcd5c5374..2e9f47c47 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.component.ts @@ -1,62 +1,51 @@ -import { - Component, - ComponentFactoryResolver, - OnDestroy, - OnInit, - Type, - ViewChild, -} from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { DatatargetTypesService } from '../datatarget-types.service'; -import { Datatarget } from '../datatarget.model'; -import { DatatargetService } from '../datatarget.service'; -import { DatatargetDetail } from './datatarget-detail'; -import { DatatargetDetailTypeSelectorDirective } from './datatarget-detail-type-selector.directive'; +import { Component, ComponentFactoryResolver, OnDestroy, OnInit, Type, ViewChild } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { DatatargetTypesService } from "../datatarget-types.service"; +import { Datatarget } from "../datatarget.model"; +import { DatatargetService } from "../datatarget.service"; +import { DatatargetDetail } from "./datatarget-detail"; +import { DatatargetDetailTypeSelectorDirective } from "./datatarget-detail-type-selector.directive"; @Component({ - selector: 'app-datatarget-detail', - templateUrl: './datatarget-detail.component.html', - styleUrls: ['./datatarget-detail.component.scss'], + selector: "app-datatarget-detail", + templateUrl: "./datatarget-detail.component.html", + styleUrls: ["./datatarget-detail.component.scss"], }) export class DatatargetDetailComponent implements OnInit, OnDestroy { - @ViewChild(DatatargetDetailTypeSelectorDirective, { static: true }) - adHost!: DatatargetDetailTypeSelectorDirective; + @ViewChild(DatatargetDetailTypeSelectorDirective, { static: true }) + adHost!: DatatargetDetailTypeSelectorDirective; - public datatarget: Datatarget; - private datatargetType: DataTargetType; + public datatarget: Datatarget; + private datatargetType: DataTargetType; - constructor( - private componentFactoryResolver: ComponentFactoryResolver, - private datatargetService: DatatargetService, - private route: ActivatedRoute, - private datatargetTypesService: DatatargetTypesService - ) {} + constructor( + private componentFactoryResolver: ComponentFactoryResolver, + private datatargetService: DatatargetService, + private route: ActivatedRoute, + private datatargetTypesService: DatatargetTypesService + ) {} - loadComponent(componentType: Type) { - const viewContainerRef = this.adHost.viewContainerRef; + loadComponent(componentType: Type) { + const viewContainerRef = this.adHost.viewContainerRef; - viewContainerRef.clear(); - const factory = this.componentFactoryResolver.resolveComponentFactory( - componentType - ); - viewContainerRef.createComponent(factory); - } + viewContainerRef.clear(); + const factory = this.componentFactoryResolver.resolveComponentFactory(componentType); + viewContainerRef.createComponent(factory); + } - ngOnInit(): void { - const id: number = +this.route.snapshot.paramMap.get('datatargetId'); + ngOnInit(): void { + const id: number = +this.route.snapshot.paramMap.get("datatargetId"); - this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { - this.datatarget = dataTarget; - this.datatargetType = dataTarget.type; + this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { + this.datatarget = dataTarget; + this.datatargetType = dataTarget.type; - const component = this.datatargetTypesService.getDetailComponent( - this.datatargetType - ); + const component = this.datatargetTypesService.getDetailComponent(this.datatargetType); - this.loadComponent(component); - }); - } + this.loadComponent(component); + }); + } - ngOnDestroy() {} + ngOnDestroy() {} } diff --git a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.ts b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.ts index 4d5f7bfbc..e0ab8dc6b 100644 --- a/src/app/applications/datatarget/datatarget-detail/datatarget-detail.ts +++ b/src/app/applications/datatarget/datatarget-detail/datatarget-detail.ts @@ -1,2 +1 @@ -export interface DatatargetDetail { -} +export interface DatatargetDetail {} diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.spec.ts b/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.spec.ts index 1c28242d4..70cbf5895 100644 --- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.spec.ts +++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.spec.ts @@ -1,11 +1,11 @@ /* tslint:disable:no-unused-variable */ -import { ViewContainerRef } from '@angular/core'; -import { DatatargetEditTypeSelectorDirective } from './datatarget-edit-type-selector.directive'; -let viewContainerRef: ViewContainerRef; -describe('Directive: DatatargetEditTypeSelector', () => { - it('should create an instance', () => { - const directive = new DatatargetEditTypeSelectorDirective(viewContainerRef); - expect(directive).toBeTruthy(); - }); +import { ViewContainerRef } from "@angular/core"; +import { DatatargetEditTypeSelectorDirective } from "./datatarget-edit-type-selector.directive"; +let viewContainerRef: ViewContainerRef; +describe("Directive: DatatargetEditTypeSelector", () => { + it("should create an instance", () => { + const directive = new DatatargetEditTypeSelectorDirective(viewContainerRef); + expect(directive).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.ts b/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.ts index 03b06ddb5..b99c5d660 100644 --- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.ts +++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit-type-selector.directive.ts @@ -1,10 +1,8 @@ -import { Directive, ViewContainerRef } from '@angular/core'; +import { Directive, ViewContainerRef } from "@angular/core"; @Directive({ - selector: '[edit-component]' + selector: "[edit-component]", }) -export class DatatargetEditTypeSelectorDirective { - - constructor(public viewContainerRef: ViewContainerRef) { } - +export class DatatargetEditTypeSelectorDirective { + constructor(public viewContainerRef: ViewContainerRef) {} } diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.html b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.html index c5cc8ced7..4264ec0b9 100644 --- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.html +++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.spec.ts b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.spec.ts index a3b3c4617..1c2f84387 100644 --- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.spec.ts +++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DatatargetEditComponent } from './datatarget-edit.component'; +import { DatatargetEditComponent } from "./datatarget-edit.component"; -describe('DatatargetEditComponent', () => { - let component: DatatargetEditComponent; - let fixture: ComponentFixture; +describe("DatatargetEditComponent", () => { + let component: DatatargetEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DatatargetEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DatatargetEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DatatargetEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DatatargetEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts index e73d1aab3..9e5177925 100644 --- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts +++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.component.ts @@ -1,84 +1,61 @@ -import { - Component, - ComponentFactoryResolver, - OnDestroy, - OnInit, - Type, - ViewChild, -} from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { DatatargetTypesService } from '../datatarget-types.service'; -import { Datatarget } from '../datatarget.model'; -import { DatatargetService } from '../datatarget.service'; -import { DatatargetEdit } from './datatarget-edit'; -import { DatatargetEditTypeSelectorDirective } from './datatarget-edit-type-selector.directive'; +import { Component, ComponentFactoryResolver, OnDestroy, OnInit, Type, ViewChild } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { DatatargetTypesService } from "../datatarget-types.service"; +import { Datatarget } from "../datatarget.model"; +import { DatatargetService } from "../datatarget.service"; +import { DatatargetEdit } from "./datatarget-edit"; +import { DatatargetEditTypeSelectorDirective } from "./datatarget-edit-type-selector.directive"; @Component({ - selector: 'app-datatarget-edit', - templateUrl: './datatarget-edit.component.html', - styleUrls: ['./datatarget-edit.component.scss'], + selector: "app-datatarget-edit", + templateUrl: "./datatarget-edit.component.html", + styleUrls: ["./datatarget-edit.component.scss"], }) export class DatatargetEditComponent implements OnInit, OnDestroy { - @ViewChild(DatatargetEditTypeSelectorDirective, { static: true }) - adHost!: DatatargetEditTypeSelectorDirective; - - public datatarget: Datatarget; - private datatargetType: DataTargetType; - - constructor( - private componentFactoryResolver: ComponentFactoryResolver, - private datatargetService: DatatargetService, - private route: ActivatedRoute, - private datatargetTypesService: DatatargetTypesService - ) {} - - loadComponent(componentType: Type) { - const viewContainerRef = this.adHost.viewContainerRef; - viewContainerRef.clear(); - const factory = this.componentFactoryResolver.resolveComponentFactory( - componentType - ); - viewContainerRef.createComponent(factory); - } - - ngOnInit(): void { - const id: number = +this.route.snapshot.paramMap.get('datatargetId'); + @ViewChild(DatatargetEditTypeSelectorDirective, { static: true }) + adHost!: DatatargetEditTypeSelectorDirective; + + public datatarget: Datatarget; + private datatargetType: DataTargetType; + + constructor( + private componentFactoryResolver: ComponentFactoryResolver, + private datatargetService: DatatargetService, + private route: ActivatedRoute, + private datatargetTypesService: DatatargetTypesService + ) {} + + loadComponent(componentType: Type) { + const viewContainerRef = this.adHost.viewContainerRef; + viewContainerRef.clear(); + const factory = this.componentFactoryResolver.resolveComponentFactory(componentType); + viewContainerRef.createComponent(factory); + } - if (id > 0) { - this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { - this.datatarget = dataTarget; - this.datatargetType = dataTarget.type; - const component = this.datatargetTypesService.getEditComponent( - this.datatargetType - ); - this.loadComponent(component); - }); - } else { - let datatargetTypeParam = this.route.snapshot.paramMap.get( - 'datatargetType' - ); - this.datatargetType = this.enumFromStringValue( - DataTargetType, - datatargetTypeParam - ); - if (this.datatargetType) { - const component = this.datatargetTypesService.getEditComponent( - this.datatargetType - ); - this.loadComponent(component); - } + ngOnInit(): void { + const id: number = +this.route.snapshot.paramMap.get("datatargetId"); + + if (id > 0) { + this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { + this.datatarget = dataTarget; + this.datatargetType = dataTarget.type; + const component = this.datatargetTypesService.getEditComponent(this.datatargetType); + this.loadComponent(component); + }); + } else { + let datatargetTypeParam = this.route.snapshot.paramMap.get("datatargetType"); + this.datatargetType = this.enumFromStringValue(DataTargetType, datatargetTypeParam); + if (this.datatargetType) { + const component = this.datatargetTypesService.getEditComponent(this.datatargetType); + this.loadComponent(component); + } + } } - } - enumFromStringValue( - enm: { [s: string]: T }, - value: string - ): T | undefined { - return ((Object.values(enm) as unknown) as string[]).includes(value) - ? ((value as unknown) as T) - : undefined; - } + enumFromStringValue(enm: { [s: string]: T }, value: string): T | undefined { + return (Object.values(enm) as unknown as string[]).includes(value) ? (value as unknown as T) : undefined; + } - ngOnDestroy() {} + ngOnDestroy() {} } diff --git a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.ts b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.ts index 16def3011..c08631a92 100644 --- a/src/app/applications/datatarget/datatarget-edit/datatarget-edit.ts +++ b/src/app/applications/datatarget/datatarget-edit/datatarget-edit.ts @@ -1,2 +1 @@ -export interface DatatargetEdit { -} +export interface DatatargetEdit {} diff --git a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.html b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.html index 7aab3e69b..78b95d117 100644 --- a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.html +++ b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.html @@ -1,34 +1,39 @@ - - +
-
- - -
-
+
+ + +
- - -
- {{dataTargetType.name | translate }} -
- - {{dataTargetType.provider}} - -
- - {{ dataTargetType.description | translate }} - + + +
+ {{ dataTargetType.name | translate }} +
+ + {{ dataTargetType.provider }} + +
+ + {{ dataTargetType.description | translate }} + - - - - - - -
-
+ + + + + +
+
diff --git a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.scss b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.scss index 71485bcb4..e2478d2e7 100644 --- a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.scss +++ b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.scss @@ -1,44 +1,42 @@ .data-component { - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin-left: 10px; + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin-left: 10px; } -.mat-card{ - display:flex; - flex-direction: column; - flex-wrap: wrap; - width: 300px; - min-width: 300px; - max-width: 400px; - height: 320px; - margin: 10px; +.mat-card { + display: flex; + flex-direction: column; + flex-wrap: wrap; + width: 300px; + min-width: 300px; + max-width: 400px; + height: 320px; + margin: 10px; } .mat-card-header { - flex-shrink: 1; - + flex-shrink: 1; } -.mat-card-content{ - flex-grow: 1; - overflow: auto; - margin-left: 10px; +.mat-card-content { + flex-grow: 1; + overflow: auto; + margin-left: 10px; } - -mat-card img{ - object-fit: contain; /*this makes the image in src fit to the size specified below*/ - object-position: left; - width: 50%; /* Here you can use wherever you want to specify the width and also the height of the */ - height: 20px; - margin-left: 3px; - margin-top: 3px; - margin-bottom: 3px; +mat-card img { + object-fit: contain; /*this makes the image in src fit to the size specified below*/ + object-position: left; + width: 50%; /* Here you can use wherever you want to specify the width and also the height of the */ + height: 20px; + margin-left: 3px; + margin-top: 3px; + margin-bottom: 3px; } -.img-placeholder{ - height: 26px; - clear: both; +.img-placeholder { + height: 26px; + clear: both; } diff --git a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.spec.ts b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.spec.ts index a7c9195d1..61a254b77 100644 --- a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.spec.ts +++ b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.spec.ts @@ -1,28 +1,27 @@ /* tslint:disable:no-unused-variable */ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { DebugElement } from "@angular/core"; -import { DatatargetNewComponent } from './datatarget-new.component'; +import { DatatargetNewComponent } from "./datatarget-new.component"; -describe('DatatargetNewComponent', () => { - let component: DatatargetNewComponent; - let fixture: ComponentFixture; +describe("DatatargetNewComponent", () => { + let component: DatatargetNewComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DatatargetNewComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DatatargetNewComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DatatargetNewComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DatatargetNewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.ts b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.ts index d3f90b129..192ba5bbb 100644 --- a/src/app/applications/datatarget/datatarget-new/datatarget-new.component.ts +++ b/src/app/applications/datatarget/datatarget-new/datatarget-new.component.ts @@ -1,63 +1,53 @@ -import { Component, OnInit } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { DatatargetTypeDescriptor } from '../datatarget.model'; -import { DatatargetTypesService } from '../datatarget-types.service'; - - +import { Component, OnInit } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { DatatargetTypeDescriptor } from "../datatarget.model"; +import { DatatargetTypesService } from "../datatarget-types.service"; @Component({ - selector: 'app-datatarget-new', - templateUrl: './datatarget-new.component.html', - styleUrls: ['./datatarget-new.component.scss'] + selector: "app-datatarget-new", + templateUrl: "./datatarget-new.component.html", + styleUrls: ["./datatarget-new.component.scss"], }) export class DatatargetNewComponent implements OnInit { - - public title = ''; - public sectionTitle = ''; - public backButtonTitle = ''; - public submitButton = ''; - public avaiableDataTargetTypes : DatatargetTypeDescriptor[]; - - constructor( - public translate: TranslateService, - private route: ActivatedRoute, - private router: Router, - private dataTargetTypesService: DatatargetTypesService - ) { - translate.use('da'); - } - - ngOnInit() { - - this.translate - .get([ - 'FORM.CREATE-NEW-DATATARGET', - 'FORM.EDIT-DATATARGET', - 'DATATARGET.SAVE', - 'NAV.DATATARGET', - ]) - .subscribe((translations) => { - const datatargetid = +this.route.snapshot.paramMap.get('datatargetId'); - if (datatargetid !== 0) { - this.title = translations['FORM.EDIT-DATATARGET']; - } else { - this.title = translations['FORM.CREATE-NEW-DATATARGET']; - } - this.submitButton = translations['DATATARGET.SAVE']; - this.backButtonTitle = translations['NAV.DATATARGET']; - }); - - this.avaiableDataTargetTypes = this.dataTargetTypesService.getAvailableDataTargetTypes(); - - } - - public createNewOf(typeDescriptor: DatatargetTypeDescriptor) - { - this.router.navigate(['../datatarget-edit', {datatargetType: typeDescriptor.type}], {relativeTo:this. route}); - } - public showReadMe(typeDescriptor: DatatargetTypeDescriptor) - { - window.open(typeDescriptor.readMoreUrl, "_blank"); - } + public title = ""; + public sectionTitle = ""; + public backButtonTitle = ""; + public submitButton = ""; + public avaiableDataTargetTypes: DatatargetTypeDescriptor[]; + + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + private router: Router, + private dataTargetTypesService: DatatargetTypesService + ) { + translate.use("da"); + } + + ngOnInit() { + this.translate + .get(["FORM.CREATE-NEW-DATATARGET", "FORM.EDIT-DATATARGET", "DATATARGET.SAVE", "NAV.DATATARGET"]) + .subscribe(translations => { + const datatargetid = +this.route.snapshot.paramMap.get("datatargetId"); + if (datatargetid !== 0) { + this.title = translations["FORM.EDIT-DATATARGET"]; + } else { + this.title = translations["FORM.CREATE-NEW-DATATARGET"]; + } + this.submitButton = translations["DATATARGET.SAVE"]; + this.backButtonTitle = translations["NAV.DATATARGET"]; + }); + + this.avaiableDataTargetTypes = this.dataTargetTypesService.getAvailableDataTargetTypes(); + } + + public createNewOf(typeDescriptor: DatatargetTypeDescriptor) { + this.router.navigate(["../datatarget-edit", { datatargetType: typeDescriptor.type }], { + relativeTo: this.route, + }); + } + public showReadMe(typeDescriptor: DatatargetTypeDescriptor) { + window.open(typeDescriptor.readMoreUrl, "_blank"); + } } diff --git a/src/app/applications/datatarget/datatarget-response.model.ts b/src/app/applications/datatarget/datatarget-response.model.ts index 173c4cc1d..5a9b605d2 100644 --- a/src/app/applications/datatarget/datatarget-response.model.ts +++ b/src/app/applications/datatarget/datatarget-response.model.ts @@ -1,6 +1,6 @@ -import { Application } from '@applications/application.model'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { OpenDataDkDataset } from './opendatadk/opendatadk-dataset.model'; +import { Application } from "@applications/application.model"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { OpenDataDkDataset } from "./opendatadk/opendatadk-dataset.model"; export class DatatargetResponse { application: Application; diff --git a/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.html b/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.html index 0aec64ac8..1fcc57460 100644 --- a/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.html +++ b/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.html @@ -1,18 +1,22 @@
-
-
-
-
- - +
+
+
+
+ + +
+ + + + + +
- - - - - -
-
diff --git a/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.ts b/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.ts index 97011be72..1f397671f 100644 --- a/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.ts +++ b/src/app/applications/datatarget/datatarget-tab/datatarget-tab.component.ts @@ -1,16 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { ApplicationService } from '@applications/application.service'; -import { environment } from '@environments/environment'; +import { Component, OnInit } from "@angular/core"; +import { ApplicationService } from "@applications/application.service"; +import { environment } from "@environments/environment"; @Component({ - selector: 'app-datatarget-tab', - templateUrl: './datatarget-tab.component.html', - styleUrls: ['./datatarget-tab.component.scss'], + selector: "app-datatarget-tab", + templateUrl: "./datatarget-tab.component.html", + styleUrls: ["./datatarget-tab.component.scss"], }) export class DatatargetTabComponent implements OnInit { - public pageLimit = environment.tablePageSize; + public pageLimit = environment.tablePageSize; - constructor(public applicationService: ApplicationService) {} + constructor(public applicationService: ApplicationService) {} - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/applications/datatarget/datatarget-table/datatarget-table.component.html b/src/app/applications/datatarget/datatarget-table/datatarget-table.component.html index 7e771696d..31fe0c12f 100644 --- a/src/app/applications/datatarget/datatarget-table/datatarget-table.component.html +++ b/src/app/applications/datatarget/datatarget-table/datatarget-table.component.html @@ -1,53 +1,69 @@
-
- -
- +
+ +
+
+ + + + + - - - - - + + + + + - - - - + + - {{'DATATARGET.' + element.type + '.TYPE' | translate}} - - - - - - - - - - -
+ {{ "DATATARGET-TABLE.NAME" | translate }} + + {{ + element.name + }} + - {{ 'DATATARGET-TABLE.NAME' | translate }} - - {{element.name}} - + {{ "DATATARGET-TABLE.TYPE" | translate }} + + {{ "DATATARGET." + element.type + ".TYPE" | translate }} + - {{ 'DATATARGET-TABLE.TYPE' | translate }} + + + + + - -
- - + + + + +
diff --git a/src/app/applications/datatarget/datatarget-table/datatarget-table.component.spec.ts b/src/app/applications/datatarget/datatarget-table/datatarget-table.component.spec.ts index fd15355d7..717603216 100644 --- a/src/app/applications/datatarget/datatarget-table/datatarget-table.component.spec.ts +++ b/src/app/applications/datatarget/datatarget-table/datatarget-table.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DatatargetTableComponent } from './datatarget-table.component'; +import { DatatargetTableComponent } from "./datatarget-table.component"; -describe('DatatargetTabelComponent', () => { - let component: DatatargetTableComponent; - let fixture: ComponentFixture; +describe("DatatargetTabelComponent", () => { + let component: DatatargetTableComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DatatargetTableComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DatatargetTableComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DatatargetTableComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DatatargetTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget-table/datatarget-table.component.ts b/src/app/applications/datatarget/datatarget-table/datatarget-table.component.ts index 91e083357..22bc822f2 100644 --- a/src/app/applications/datatarget/datatarget-table/datatarget-table.component.ts +++ b/src/app/applications/datatarget/datatarget-table/datatarget-table.component.ts @@ -1,28 +1,28 @@ -import { Component, OnInit, Input, OnDestroy, ViewChild, AfterViewInit } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { TranslateService } from '@ngx-translate/core'; -import { ActivatedRoute } from '@angular/router'; -import { Datatarget, DatatargetData } from '../datatarget.model'; -import { DatatargetService } from '../datatarget.service'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { environment } from '@environments/environment'; -import { tableSorter } from '@shared/helpers/table-sorting.helper'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { Component, OnInit, Input, OnDestroy, ViewChild, AfterViewInit } from "@angular/core"; +import { Subscription } from "rxjs"; +import { TranslateService } from "@ngx-translate/core"; +import { ActivatedRoute } from "@angular/router"; +import { Datatarget, DatatargetData } from "../datatarget.model"; +import { DatatargetService } from "../datatarget.service"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { MatTableDataSource } from "@angular/material/table"; +import { environment } from "@environments/environment"; +import { tableSorter } from "@shared/helpers/table-sorting.helper"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; @Component({ - selector: 'app-datatarget-table', - templateUrl: './datatarget-table.component.html', - styleUrls: ['./datatarget-table.component.scss'] + selector: "app-datatarget-table", + templateUrl: "./datatarget-table.component.html", + styleUrls: ["./datatarget-table.component.scss"], }) export class DatatargetTableComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; - displayedColumns: string[] = ['name', 'type', 'menu']; + displayedColumns: string[] = ["name", "type", "menu"]; dataSource = new MatTableDataSource(); datatargets: Datatarget[]; resultsLength = 0; @@ -44,14 +44,19 @@ export class DatatargetTableComponent implements OnInit, AfterViewInit, OnDestro private deleteDialogService: DeleteDialogService, private datatargetService: DatatargetService, private meService: MeService, - public translate: TranslateService) { - translate.use('da'); + public translate: TranslateService + ) { + translate.use("da"); } ngOnInit(): void { - this.applicationId = +Number(this.route.parent.snapshot.paramMap.get('id')); + this.applicationId = +Number(this.route.parent.snapshot.paramMap.get("id")); this.getDatatarget(); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite, undefined, this.applicationId); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + this.applicationId + ); } ngAfterViewInit() { @@ -63,11 +68,7 @@ export class DatatargetTableComponent implements OnInit, AfterViewInit, OnDestro const appId: number = this.applicationId; if (appId) { this.datatargetSubscription = this.datatargetService - .getByApplicationId( - this.pageLimit, - this.pageOffset * this.pageLimit, - appId - ) + .getByApplicationId(this.pageLimit, this.pageOffset * this.pageLimit, appId) .subscribe((datatargets: DatatargetData) => { this.datatargets = datatargets.data; this.dataSource = new MatTableDataSource(this.datatargets); @@ -80,23 +81,20 @@ export class DatatargetTableComponent implements OnInit, AfterViewInit, OnDestro } }); } - } deleteDatatarget(element: any) { - this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe( - (response) => { - if (response) { - this.datatargetService.delete(element.id).subscribe((response) => { - if (response.ok && response.body.affected > 0) { - this.getDatatarget(); - } - }); - } else { - console.log(response); - } + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.datatargetService.delete(element.id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + this.getDatatarget(); + } + }); + } else { + console.log(response); } - ); + }); } ngOnDestroy() { @@ -108,5 +106,4 @@ export class DatatargetTableComponent implements OnInit, AfterViewInit, OnDestro this.deleteDialogSubscription.unsubscribe(); } } - } diff --git a/src/app/applications/datatarget/datatarget-types.service.spec.ts b/src/app/applications/datatarget/datatarget-types.service.spec.ts index 1f4241271..78b60437f 100644 --- a/src/app/applications/datatarget/datatarget-types.service.spec.ts +++ b/src/app/applications/datatarget/datatarget-types.service.spec.ts @@ -1,16 +1,16 @@ /* tslint:disable:no-unused-variable */ -import { TestBed, inject, waitForAsync } from '@angular/core/testing'; -import { DatatargetTypesService } from './datatarget-types.service'; +import { TestBed, inject, waitForAsync } from "@angular/core/testing"; +import { DatatargetTypesService } from "./datatarget-types.service"; -describe('Service: DatatargetTypesService', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [DatatargetTypesService] +describe("Service: DatatargetTypesService", () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DatatargetTypesService], + }); }); - }); - it('should ...', inject([DatatargetTypesService], (service: DatatargetTypesService) => { - expect(service).toBeTruthy(); - })); + it("should ...", inject([DatatargetTypesService], (service: DatatargetTypesService) => { + expect(service).toBeTruthy(); + })); }); diff --git a/src/app/applications/datatarget/datatarget-types.service.ts b/src/app/applications/datatarget/datatarget-types.service.ts index a1ef01684..2383a0d54 100644 --- a/src/app/applications/datatarget/datatarget-types.service.ts +++ b/src/app/applications/datatarget/datatarget-types.service.ts @@ -1,92 +1,92 @@ -import { Injectable, Type } from '@angular/core'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { DatatargetDetail } from './datatarget-detail/datatarget-detail'; -import { DatatargetEdit } from './datatarget-edit/datatarget-edit'; -import { DatatargetTypeDescriptor } from './datatarget.model'; -import { FiwareDetailComponent } from './fiware/fiware-detail/fiware-detail.component'; -import { FiwareEditComponent } from './fiware/fiware-edit/fiware-edit.component'; -import { HttppushDetailComponent } from './httppush/httppush-detail/httppush-detail.component'; -import { HttppushEditComponent } from './httppush/httppush-edit/httppush-edit.component'; -import { MqttDetailComponent } from './mqtt-detail/mqtt-detail.component'; -import { MqttEditComponent } from './mqtt-edit/mqtt-edit.component'; -import { OpendatadkEditComponent } from './opendatadk/opendatadk-edit/opendatadk-edit.component'; +import { Injectable, Type } from "@angular/core"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { DatatargetDetail } from "./datatarget-detail/datatarget-detail"; +import { DatatargetEdit } from "./datatarget-edit/datatarget-edit"; +import { DatatargetTypeDescriptor } from "./datatarget.model"; +import { FiwareDetailComponent } from "./fiware/fiware-detail/fiware-detail.component"; +import { FiwareEditComponent } from "./fiware/fiware-edit/fiware-edit.component"; +import { HttppushDetailComponent } from "./httppush/httppush-detail/httppush-detail.component"; +import { HttppushEditComponent } from "./httppush/httppush-edit/httppush-edit.component"; +import { MqttDetailComponent } from "./mqtt-detail/mqtt-detail.component"; +import { MqttEditComponent } from "./mqtt-edit/mqtt-edit.component"; +import { OpendatadkEditComponent } from "./opendatadk/opendatadk-edit/opendatadk-edit.component"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class DatatargetTypesService { - constructor() {} + constructor() {} - getAvailableDataTargetTypes(): DatatargetTypeDescriptor[] { - return [ - { - name: 'DATATARGET.HTTP_PUSH.NAME', - type: DataTargetType.HTTPPUSH, - icon: null, - description: 'DATATARGET.HTTP_PUSH.DESCRIPTION', - readMoreUrl: '', - provider: 'OS2', - }, - { - name: 'DATATARGET.OPENDATA-DK.NAME', - type: DataTargetType.OPENDATADK, - icon: '/assets/images/logo_opendatadk.svg', - description: 'DATATARGET.OPENDATA-DK.DESCRIPTION', - readMoreUrl: 'https://www.opendata.dk/', - provider: 'OS2', - }, - { - name: 'DATATARGET.FIWARE.NAME', - type: DataTargetType.FIWARE, - icon: '/assets/images/logo_FIWARE.png', - description: 'DATATARGET.FIWARE.DESCRIPTION', - readMoreUrl: 'https://www.kmd.dk', - provider: 'KMD A/S', - }, - { - name: 'DATATARGET.MQTT.NAME', - type: DataTargetType.MQTT, - icon: '/assets/images/logo_mqtt.png', - description: 'DATATARGET.MQTT.DESCRIPTION', - readMoreUrl: 'https://mqtt.org/', - provider: 'OS2', - }, - ]; - } - - getDetailComponent(dataTargetType: DataTargetType): Type { - if (dataTargetType === DataTargetType.HTTPPUSH) { - return HttppushDetailComponent; + getAvailableDataTargetTypes(): DatatargetTypeDescriptor[] { + return [ + { + name: "DATATARGET.HTTP_PUSH.NAME", + type: DataTargetType.HTTPPUSH, + icon: null, + description: "DATATARGET.HTTP_PUSH.DESCRIPTION", + readMoreUrl: "", + provider: "OS2", + }, + { + name: "DATATARGET.OPENDATA-DK.NAME", + type: DataTargetType.OPENDATADK, + icon: "/assets/images/logo_opendatadk.svg", + description: "DATATARGET.OPENDATA-DK.DESCRIPTION", + readMoreUrl: "https://www.opendata.dk/", + provider: "OS2", + }, + { + name: "DATATARGET.FIWARE.NAME", + type: DataTargetType.FIWARE, + icon: "/assets/images/logo_FIWARE.png", + description: "DATATARGET.FIWARE.DESCRIPTION", + readMoreUrl: "https://www.kmd.dk", + provider: "KMD A/S", + }, + { + name: "DATATARGET.MQTT.NAME", + type: DataTargetType.MQTT, + icon: "/assets/images/logo_mqtt.png", + description: "DATATARGET.MQTT.DESCRIPTION", + readMoreUrl: "https://mqtt.org/", + provider: "OS2", + }, + ]; } - if (dataTargetType === DataTargetType.OPENDATADK) { - return HttppushDetailComponent; - } + getDetailComponent(dataTargetType: DataTargetType): Type { + if (dataTargetType === DataTargetType.HTTPPUSH) { + return HttppushDetailComponent; + } - if (dataTargetType === DataTargetType.FIWARE) { - return FiwareDetailComponent; - } + if (dataTargetType === DataTargetType.OPENDATADK) { + return HttppushDetailComponent; + } - if (dataTargetType === DataTargetType.MQTT) { - return MqttDetailComponent; - } - } + if (dataTargetType === DataTargetType.FIWARE) { + return FiwareDetailComponent; + } - getEditComponent(dataTargetType: DataTargetType): Type { - if (dataTargetType === DataTargetType.HTTPPUSH) { - return HttppushEditComponent; + if (dataTargetType === DataTargetType.MQTT) { + return MqttDetailComponent; + } } - if (dataTargetType === DataTargetType.OPENDATADK) { - return OpendatadkEditComponent; - } + getEditComponent(dataTargetType: DataTargetType): Type { + if (dataTargetType === DataTargetType.HTTPPUSH) { + return HttppushEditComponent; + } - if (dataTargetType === DataTargetType.FIWARE) { - return FiwareEditComponent; - } + if (dataTargetType === DataTargetType.OPENDATADK) { + return OpendatadkEditComponent; + } + + if (dataTargetType === DataTargetType.FIWARE) { + return FiwareEditComponent; + } - if (dataTargetType === DataTargetType.MQTT) { - return MqttEditComponent; + if (dataTargetType === DataTargetType.MQTT) { + return MqttEditComponent; + } } - } } diff --git a/src/app/applications/datatarget/datatarget.model.ts b/src/app/applications/datatarget/datatarget.model.ts index f66c885ad..c6999eb51 100644 --- a/src/app/applications/datatarget/datatarget.model.ts +++ b/src/app/applications/datatarget/datatarget.model.ts @@ -1,5 +1,5 @@ -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { OpenDataDkDataset as OpenDataDkDataset } from './opendatadk/opendatadk-dataset.model'; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { OpenDataDkDataset as OpenDataDkDataset } from "./opendatadk/opendatadk-dataset.model"; export class Datatarget { id: number; @@ -49,5 +49,5 @@ export class OddkMailInfo { organizationId?: number; organizationOddkAlias: string; comment?: string; - sharingUrl?: string -} \ No newline at end of file + sharingUrl?: string; +} diff --git a/src/app/applications/datatarget/datatarget.module.ts b/src/app/applications/datatarget/datatarget.module.ts index 2a8518acc..40adaa830 100644 --- a/src/app/applications/datatarget/datatarget.module.ts +++ b/src/app/applications/datatarget/datatarget.module.ts @@ -1,75 +1,75 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { DatatargetTableComponent } from './datatarget-table/datatarget-table.component'; -import { DatatargetEditComponent } from './datatarget-edit/datatarget-edit.component'; -import { DatatargetDetailComponent } from './datatarget-detail/datatarget-detail.component'; -import { TranslateModule } from '@ngx-translate/core'; -import { RouterModule } from '@angular/router'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { FormModule } from '@shared/components/forms/form.module'; -import { OpendatadkComponent } from './opendatadk/opendatadk.component'; -import { OpendatadkEditComponent } from './opendatadk/opendatadk-edit/opendatadk-edit.component'; -import { OpendatadkDetailComponent } from './opendatadk/opendatadk-detail/opendatadk-detail.component'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { SharedModule } from '@shared/shared.module'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { DatatargetNewComponent } from './datatarget-new/datatarget-new.component'; -import { FiwareEditComponent } from './fiware/fiware-edit/fiware-edit.component'; -import { FiwareDetailComponent } from './fiware/fiware-detail/fiware-detail.component'; -import { HttppushDetailComponent } from './httppush/httppush-detail/httppush-detail.component'; -import { HttppushEditComponent } from './httppush/httppush-edit/httppush-edit.component'; -import { DatatargetDetailTypeSelectorDirective } from './datatarget-detail/datatarget-detail-type-selector.directive'; -import { DatatargetEditTypeSelectorDirective } from './datatarget-edit/datatarget-edit-type-selector.directive'; -import { MqttEditComponent } from './mqtt-edit/mqtt-edit.component'; -import { MqttDetailComponent } from './mqtt-detail/mqtt-detail.component'; -import { DatatargetTabComponent } from './datatarget-tab/datatarget-tab.component'; -import { OpenDataDkMailDialogComponent } from './opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog'; -import { OpenDataDkWarningDialogComponent } from './opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { DatatargetTableComponent } from "./datatarget-table/datatarget-table.component"; +import { DatatargetEditComponent } from "./datatarget-edit/datatarget-edit.component"; +import { DatatargetDetailComponent } from "./datatarget-detail/datatarget-detail.component"; +import { TranslateModule } from "@ngx-translate/core"; +import { RouterModule } from "@angular/router"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { FormModule } from "@shared/components/forms/form.module"; +import { OpendatadkComponent } from "./opendatadk/opendatadk.component"; +import { OpendatadkEditComponent } from "./opendatadk/opendatadk-edit/opendatadk-edit.component"; +import { OpendatadkDetailComponent } from "./opendatadk/opendatadk-detail/opendatadk-detail.component"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { SharedModule } from "@shared/shared.module"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { DatatargetNewComponent } from "./datatarget-new/datatarget-new.component"; +import { FiwareEditComponent } from "./fiware/fiware-edit/fiware-edit.component"; +import { FiwareDetailComponent } from "./fiware/fiware-detail/fiware-detail.component"; +import { HttppushDetailComponent } from "./httppush/httppush-detail/httppush-detail.component"; +import { HttppushEditComponent } from "./httppush/httppush-edit/httppush-edit.component"; +import { DatatargetDetailTypeSelectorDirective } from "./datatarget-detail/datatarget-detail-type-selector.directive"; +import { DatatargetEditTypeSelectorDirective } from "./datatarget-edit/datatarget-edit-type-selector.directive"; +import { MqttEditComponent } from "./mqtt-edit/mqtt-edit.component"; +import { MqttDetailComponent } from "./mqtt-detail/mqtt-detail.component"; +import { DatatargetTabComponent } from "./datatarget-tab/datatarget-tab.component"; +import { OpenDataDkMailDialogComponent } from "./opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog"; +import { OpenDataDkWarningDialogComponent } from "./opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog"; @NgModule({ - declarations: [ - DatatargetTableComponent, - DatatargetEditComponent, - DatatargetNewComponent, - DatatargetDetailComponent, - FiwareDetailComponent, - FiwareEditComponent, - HttppushDetailComponent, - HttppushEditComponent, - OpendatadkComponent, - OpendatadkEditComponent, - OpendatadkDetailComponent, - OpenDataDkMailDialogComponent, - OpenDataDkWarningDialogComponent, - MqttDetailComponent, - MqttEditComponent, - DatatargetDetailTypeSelectorDirective, - DatatargetEditTypeSelectorDirective, - DatatargetTabComponent, - ], - imports: [ - CommonModule, - RouterModule, - TranslateModule, - FormModule, - NGMaterialModule, - FontAwesomeModule, - ReactiveFormsModule, - FormsModule, - SharedModule, - PipesModule, - ], - exports: [ - DatatargetTableComponent, - DatatargetEditComponent, - DatatargetNewComponent, - DatatargetDetailComponent, - FiwareDetailComponent, - FiwareEditComponent, - HttppushDetailComponent, - HttppushEditComponent, - NGMaterialModule, - ], + declarations: [ + DatatargetTableComponent, + DatatargetEditComponent, + DatatargetNewComponent, + DatatargetDetailComponent, + FiwareDetailComponent, + FiwareEditComponent, + HttppushDetailComponent, + HttppushEditComponent, + OpendatadkComponent, + OpendatadkEditComponent, + OpendatadkDetailComponent, + OpenDataDkMailDialogComponent, + OpenDataDkWarningDialogComponent, + MqttDetailComponent, + MqttEditComponent, + DatatargetDetailTypeSelectorDirective, + DatatargetEditTypeSelectorDirective, + DatatargetTabComponent, + ], + imports: [ + CommonModule, + RouterModule, + TranslateModule, + FormModule, + NGMaterialModule, + FontAwesomeModule, + ReactiveFormsModule, + FormsModule, + SharedModule, + PipesModule, + ], + exports: [ + DatatargetTableComponent, + DatatargetEditComponent, + DatatargetNewComponent, + DatatargetDetailComponent, + FiwareDetailComponent, + FiwareEditComponent, + HttppushDetailComponent, + HttppushEditComponent, + NGMaterialModule, + ], }) export class DatatargetModule {} diff --git a/src/app/applications/datatarget/datatarget.service.spec.ts b/src/app/applications/datatarget/datatarget.service.spec.ts index c2f0c3aa8..4be117c20 100644 --- a/src/app/applications/datatarget/datatarget.service.spec.ts +++ b/src/app/applications/datatarget/datatarget.service.spec.ts @@ -1,16 +1,16 @@ -import { TestBed } from '@angular/core/testing'; +import { TestBed } from "@angular/core/testing"; -import { DatatargetService } from './datatarget.service'; +import { DatatargetService } from "./datatarget.service"; -describe('DatatargetService', () => { - let service: DatatargetService; +describe("DatatargetService", () => { + let service: DatatargetService; - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(DatatargetService); - }); + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DatatargetService); + }); - it('should be created', () => { - expect(service).toBeTruthy(); - }); + it("should be created", () => { + expect(service).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/datatarget.service.ts b/src/app/applications/datatarget/datatarget.service.ts index 1efcb30eb..037241524 100644 --- a/src/app/applications/datatarget/datatarget.service.ts +++ b/src/app/applications/datatarget/datatarget.service.ts @@ -1,129 +1,126 @@ -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { DatatargetResponse } from '@applications/datatarget/datatarget-response.model'; -import { RestService } from '@shared/services/rest.service'; -import { DatatargetData, Datatarget, OddkMailInfo } from './datatarget.model'; -import { map } from 'rxjs/operators'; -import { OpenDataDkDataset } from './opendatadk/opendatadk-dataset.model'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { DatatargetResponse } from "@applications/datatarget/datatarget-response.model"; +import { RestService } from "@shared/services/rest.service"; +import { DatatargetData, Datatarget, OddkMailInfo } from "./datatarget.model"; +import { map } from "rxjs/operators"; +import { OpenDataDkDataset } from "./opendatadk/opendatadk-dataset.model"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class DatatargetService { + private dataTargetURL = "data-target"; - private dataTargetURL = 'data-target'; + constructor( + private restService: RestService, + private sharedVariableService: SharedVariableService, + private userMinimalService: UserMinimalService + ) {} - constructor( - private restService: RestService, - private sharedVariableService: SharedVariableService, - private userMinimalService: UserMinimalService) { } - - get(id: number): Observable { - return this.restService.get(this.dataTargetURL, null, id).pipe( - map( - (response: DatatargetResponse) => { - const datatarget = this.mapToDatatarget(response); - return datatarget; - } - ) - ); - } + get(id: number): Observable { + return this.restService.get(this.dataTargetURL, null, id).pipe( + map((response: DatatargetResponse) => { + const datatarget = this.mapToDatatarget(response); + return datatarget; + }) + ); + } - getByApplicationId( - limit: number, offset: number, applicationId: number - ): Observable { - const body = { - limit, - offset, - applicationId - // sort: sort, - // orderOn: orderOn, - // todo tilføj når iot-314 er tilføjet - }; - return this.restService.get(this.dataTargetURL, body); - } + getByApplicationId(limit: number, offset: number, applicationId: number): Observable { + const body = { + limit, + offset, + applicationId, + // sort: sort, + // orderOn: orderOn, + // todo tilføj når iot-314 er tilføjet + }; + return this.restService.get(this.dataTargetURL, body); + } - update(datatarget: Datatarget): Observable { - this.trimModel(datatarget); - return this.restService.put(this.dataTargetURL, datatarget, datatarget.id, { observe: 'response' }).pipe( - map( - (response: DatatargetResponse) => { - const datatarget = this.mapToDatatarget(response); - return datatarget; - } - ) - ); - } + update(datatarget: Datatarget): Observable { + this.trimModel(datatarget); + return this.restService.put(this.dataTargetURL, datatarget, datatarget.id, { observe: "response" }).pipe( + map((response: DatatargetResponse) => { + const datatarget = this.mapToDatatarget(response); + return datatarget; + }) + ); + } - create(datatarget: Datatarget): Observable { - this.trimModel(datatarget); - return this.restService.post(this.dataTargetURL, datatarget).pipe( - map( - (response: DatatargetResponse) => { - const datatarget = this.mapToDatatarget(response); - return datatarget; - } - ) - ); - } + create(datatarget: Datatarget): Observable { + this.trimModel(datatarget); + return this.restService.post(this.dataTargetURL, datatarget).pipe( + map((response: DatatargetResponse) => { + const datatarget = this.mapToDatatarget(response); + return datatarget; + }) + ); + } - delete(id: number) { - return this.restService.delete(this.dataTargetURL, id); - } + delete(id: number) { + return this.restService.delete(this.dataTargetURL, id); + } - private trimModel(datatarget: Datatarget) { - if (!datatarget.setToOpendataDk) { - datatarget.openDataDkDataset = null; + private trimModel(datatarget: Datatarget) { + if (!datatarget.setToOpendataDk) { + datatarget.openDataDkDataset = null; + } } - } - private mapToDatatarget(dataTargetResponse: DatatargetResponse): Datatarget { - const model: Datatarget = { - id: dataTargetResponse.id, - name: dataTargetResponse.name, - timeout: dataTargetResponse.timeout, - type: dataTargetResponse.type, - url: dataTargetResponse.url, - tenant: dataTargetResponse.tenant, - context: dataTargetResponse.context, - authorizationHeader: dataTargetResponse.authorizationHeader, - tokenEndpoint: dataTargetResponse.tokenEndpoint, - clientId: dataTargetResponse.clientId, - clientSecret: dataTargetResponse.clientSecret, - applicationId: dataTargetResponse.application.id, - setToOpendataDk: dataTargetResponse?.openDataDkDataset ? true : false, - openDataDkDataset: dataTargetResponse?.openDataDkDataset ? dataTargetResponse.openDataDkDataset : new OpenDataDkDataset(), - mqttPort: dataTargetResponse.mqttPort, - mqttTopic: dataTargetResponse.mqttTopic, - mqttQos: dataTargetResponse.mqttQos, - mqttUsername: dataTargetResponse.mqttUsername, - mqttPassword: dataTargetResponse.mqttPassword, - createdAt: dataTargetResponse.createdAt, - updatedAt: dataTargetResponse.updatedAt, - createdBy: dataTargetResponse.createdBy, - updatedBy: dataTargetResponse.updatedBy, - createdByName: this.userMinimalService.getUserNameFrom(dataTargetResponse.createdBy), - updatedByName: this.userMinimalService.getUserNameFrom(dataTargetResponse.updatedBy), - }; - model.openDataDkDataset.keywordsInput = dataTargetResponse.openDataDkDataset?.keywords?.join(', '); - model.openDataDkDataset.url = this.getOpendataSharingApiUrl(); - return model; - } + private mapToDatatarget(dataTargetResponse: DatatargetResponse): Datatarget { + const model: Datatarget = { + id: dataTargetResponse.id, + name: dataTargetResponse.name, + timeout: dataTargetResponse.timeout, + type: dataTargetResponse.type, + url: dataTargetResponse.url, + tenant: dataTargetResponse.tenant, + context: dataTargetResponse.context, + authorizationHeader: dataTargetResponse.authorizationHeader, + tokenEndpoint: dataTargetResponse.tokenEndpoint, + clientId: dataTargetResponse.clientId, + clientSecret: dataTargetResponse.clientSecret, + applicationId: dataTargetResponse.application.id, + setToOpendataDk: dataTargetResponse?.openDataDkDataset ? true : false, + openDataDkDataset: dataTargetResponse?.openDataDkDataset + ? dataTargetResponse.openDataDkDataset + : new OpenDataDkDataset(), + mqttPort: dataTargetResponse.mqttPort, + mqttTopic: dataTargetResponse.mqttTopic, + mqttQos: dataTargetResponse.mqttQos, + mqttUsername: dataTargetResponse.mqttUsername, + mqttPassword: dataTargetResponse.mqttPassword, + createdAt: dataTargetResponse.createdAt, + updatedAt: dataTargetResponse.updatedAt, + createdBy: dataTargetResponse.createdBy, + updatedBy: dataTargetResponse.updatedBy, + createdByName: this.userMinimalService.getUserNameFrom(dataTargetResponse.createdBy), + updatedByName: this.userMinimalService.getUserNameFrom(dataTargetResponse.updatedBy), + }; + model.openDataDkDataset.keywordsInput = dataTargetResponse.openDataDkDataset?.keywords?.join(", "); + model.openDataDkDataset.url = this.getOpendataSharingApiUrl(); + return model; + } - getOpendataSharingApiUrl(): string { - return this.restService.createResourceUrl('open-data-dk-sharing', this.sharedVariableService.getSelectedOrganisationId()); - } + getOpendataSharingApiUrl(): string { + return this.restService.createResourceUrl( + "open-data-dk-sharing", + this.sharedVariableService.getSelectedOrganisationId() + ); + } - getOpenDataDkRegistered(organizationId: number): Observable { - return this.restService.get(this.dataTargetURL + '/getOpenDataDkRegistered', undefined, organizationId); - } - updateOpenDataDkRegistered(organizationId: number): Observable { - return this.restService.put(this.dataTargetURL + '/updateOpenDataDkRegistered', undefined, organizationId); - } - sendOpenDataDkMail(mailDto: OddkMailInfo): Observable { - mailDto.sharingUrl = this.getOpendataSharingApiUrl(); - return this.restService.post(this.dataTargetURL + '/sendOpenDataDkMail', mailDto); - } + getOpenDataDkRegistered(organizationId: number): Observable { + return this.restService.get(this.dataTargetURL + "/getOpenDataDkRegistered", undefined, organizationId); + } + updateOpenDataDkRegistered(organizationId: number): Observable { + return this.restService.put(this.dataTargetURL + "/updateOpenDataDkRegistered", undefined, organizationId); + } + sendOpenDataDkMail(mailDto: OddkMailInfo): Observable { + mailDto.sharingUrl = this.getOpendataSharingApiUrl(); + return this.restService.post(this.dataTargetURL + "/sendOpenDataDkMail", mailDto); + } } diff --git a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.html b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.html index f878370cd..51206cf54 100644 --- a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.html +++ b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.html @@ -1,94 +1,158 @@
- +
-
-
-
-

{{ 'DATATARGET.DETAILS' | translate }}

- - -

Context Broker{{datatarget.url}}

-

{{ 'DATATARGET.TIMEOUT' | translate }}{{datatarget.timeout}}

-

{{ 'DATATARGET.TYPE' | translate }}{{'DATATARGET.' + datatarget.type + '.TYPE' | translate}}

- - -

{{ 'DATATARGET.TENANT' | translate }}

-
{{datatarget.tenant}}
- -

{{ 'DATATARGET.NO-TENANT' | translate }}

-
- -

{{ 'DATATARGET.CONTEXT' | translate }}

-
{{datatarget.context}}
- -

{{ 'DATATARGET.NO-CONTEXT' | translate }}

-
+
+
+
+

{{ "DATATARGET.DETAILS" | translate }}

+ + +

Context Broker{{ datatarget.url }}

+

+ {{ "DATATARGET.TIMEOUT" | translate }}{{ datatarget.timeout }} +

+

+ {{ "DATATARGET.TYPE" | translate }}{{ "DATATARGET." + datatarget.type + ".TYPE" | translate }} +

+ -

{{ 'DATATARGET.AUTHORIZATIONHEADER' | translate }}

-
{{datatarget.authorizationHeader}}
- -

{{ 'DATATARGET.NO-AUTHORIZATIONHEADER' | translate }}

-
+

+ {{ "DATATARGET.TENANT" | translate }} +

+ +
{{ datatarget.tenant }}
+
+ +

{{ "DATATARGET.NO-TENANT" | translate }}

+
-

{{ 'DATATARGET.TOKENENDPOINT' | translate }}

-
{{datatarget.tokenEndpoint}}
- -

{{ 'DATATARGET.NO-TOKENENDPOINT' | translate }}

-
+

+ {{ "DATATARGET.CONTEXT" | translate }} +

+ +
{{ datatarget.context }}
+
+ +

{{ "DATATARGET.NO-CONTEXT" | translate }}

+
-

{{ 'DATATARGET.CLIENTID' | translate }}

-
{{datatarget.clientId}}
- -

{{ 'DATATARGET.NO-CLIENTID' | translate }}

-
+

+ {{ "DATATARGET.AUTHORIZATIONHEADER" | translate }} +

+ +
{{
+                            datatarget.authorizationHeader
+                        }}
+
+ +

{{ "DATATARGET.NO-AUTHORIZATIONHEADER" | translate }}

+
-

{{ 'DATATARGET.CLIENTSECRET' | translate }}

-
{{''.padStart(20, '*')}}
- -

{{ 'DATATARGET.NO-CLIENTSECRET' | translate }}

-
+

+ {{ "DATATARGET.TOKENENDPOINT" | translate }} +

+ +
{{
+                            datatarget.tokenEndpoint
+                        }}
+
+ +

{{ "DATATARGET.NO-TOKENENDPOINT" | translate }}

+
-
-
+

+ {{ "DATATARGET.CLIENTID" | translate }} +

+ +
{{ datatarget.clientId }}
+
+ +

{{ "DATATARGET.NO-CLIENTID" | translate }}

+
+

+ {{ "DATATARGET.CLIENTSECRET" | translate }} +

+ +
{{
+                            "".padStart(20, "*")
+                        }}
+
+ +

{{ "DATATARGET.NO-CLIENTSECRET" | translate }}

+
+
+
-
-
-
-
-

{{ 'DATATARGET.RELATIONS' | translate }}

-
-

{{'DATATARGET.NO-RELATIONS' | translate}}

-
-
-
-
-
-

{{'DATATARGET.PAYLOADEDECODER' | translate}} - {{relation.payloadDecoder.name}} - - {{ 'DATATARGET.NO-PAYLOADDECODER' | translate}} -

-
-
- +
+
+
+
+

{{ "DATATARGET.RELATIONS" | translate }}

+
+

{{ "DATATARGET.NO-RELATIONS" | translate }}

+
+
+
+
+
+

+ {{ "DATATARGET.PAYLOADEDECODER" | translate }} + {{ relation.payloadDecoder.name }} + + {{ + "DATATARGET.NO-PAYLOADDECODER" | translate + }} +

+
+
+ +
+
+

+ {{ "DATATARGET.IOTDEVICE" | translate }} + + , + {{ device.name }} + +

+
+ +
+
+
+
-
-

{{'DATATARGET.IOTDEVICE' | translate}} - - , {{device.name}} - -

-
- -
-
-
-
-
+
diff --git a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.spec.ts b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.spec.ts index f048cadbf..2ffd14e87 100644 --- a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.spec.ts +++ b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.spec.ts @@ -1,28 +1,27 @@ /* tslint:disable:no-unused-variable */ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { DebugElement } from "@angular/core"; -import { FiwareDetailComponent } from './fiware-detail.component'; +import { FiwareDetailComponent } from "./fiware-detail.component"; -describe('FiwareDetailComponent', () => { - let component: FiwareDetailComponent; - let fixture: ComponentFixture; +describe("FiwareDetailComponent", () => { + let component: FiwareDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ FiwareDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [FiwareDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(FiwareDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(FiwareDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts index 97bc7c6a3..fea599e0a 100644 --- a/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts +++ b/src/app/applications/datatarget/fiware/fiware-detail/fiware-detail.component.ts @@ -1,103 +1,94 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { PayloadDeviceDatatargetGetByDataTarget } from '@app/payload-decoder/payload-device-data.model'; -import { PayloadDeviceDatatargetService } from '@app/payload-decoder/payload-device-datatarget.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { DatatargetService } from '../../datatarget.service'; -import { Location } from '@angular/common'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { Datatarget } from '../../datatarget.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { faArrowsAltH } from '@fortawesome/free-solid-svg-icons'; -import { DatatargetDetail } from '@applications/datatarget/datatarget-detail/datatarget-detail'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Subscription } from "rxjs"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { PayloadDeviceDatatargetGetByDataTarget } from "@app/payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetService } from "@app/payload-decoder/payload-device-datatarget.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { DatatargetService } from "../../datatarget.service"; +import { Location } from "@angular/common"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { Datatarget } from "../../datatarget.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { faArrowsAltH } from "@fortawesome/free-solid-svg-icons"; +import { DatatargetDetail } from "@applications/datatarget/datatarget-detail/datatarget-detail"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-fiware-detail', - templateUrl: './fiware-detail.component.html', - styleUrls: ['./fiware-detail.component.scss'], + selector: "app-fiware-detail", + templateUrl: "./fiware-detail.component.html", + styleUrls: ["./fiware-detail.component.scss"], }) -export class FiwareDetailComponent - implements DatatargetDetail, OnInit, OnDestroy { - public datatargetSubscription: Subscription; - public datatarget: Datatarget; - public backButton: BackButton = { label: '', routerLink: undefined }; - public dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; - private deleteDialogSubscription: Subscription; - public dropdownButton: DropdownButton; - arrowsAltH = faArrowsAltH; - canEdit: boolean; +export class FiwareDetailComponent implements DatatargetDetail, OnInit, OnDestroy { + public datatargetSubscription: Subscription; + public datatarget: Datatarget; + public backButton: BackButton = { label: "", routerLink: undefined }; + public dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; + private deleteDialogSubscription: Subscription; + public dropdownButton: DropdownButton; + arrowsAltH = faArrowsAltH; + canEdit: boolean; - constructor( - private route: ActivatedRoute, - private deleteDialogService: DeleteDialogService, - private location: Location, - private datatargetRelationServicer: PayloadDeviceDatatargetService, - private datatargetService: DatatargetService, - public translate: TranslateService, - private meService: MeService - ) {} + constructor( + private route: ActivatedRoute, + private deleteDialogService: DeleteDialogService, + private location: Location, + private datatargetRelationServicer: PayloadDeviceDatatargetService, + private datatargetService: DatatargetService, + public translate: TranslateService, + private meService: MeService + ) {} - ngOnInit(): void { - const id: number = +this.route.snapshot.paramMap.get('datatargetId'); - const appId: number = +this.route.snapshot.paramMap.get('id'); + ngOnInit(): void { + const id: number = +this.route.snapshot.paramMap.get("datatargetId"); + const appId: number = +this.route.snapshot.paramMap.get("id"); - if (id) { - this.getDatatarget(id); - this.getDatatargetRelations(id); - this.dropdownButton = { - label: '', - editRouterLink: '../../datatarget-edit/' + id, - isErasable: true, - }; + if (id) { + this.getDatatarget(id); + this.getDatatargetRelations(id); + this.dropdownButton = { + label: "", + editRouterLink: "../../datatarget-edit/" + id, + isErasable: true, + }; + } + this.translate.get(["NAV.MY-DATATARGET", "DATATARGET.SHOW-OPTIONS"]).subscribe(translations => { + this.backButton.label = translations["NAV.MY-DATATARGET"]; + this.dropdownButton.label = translations["DATATARGET.SHOW-OPTIONS"]; + }); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + appId + ); } - this.translate - .get(['NAV.MY-DATATARGET', 'DATATARGET.SHOW-OPTIONS']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.MY-DATATARGET']; - this.dropdownButton.label = translations['DATATARGET.SHOW-OPTIONS']; - }); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - appId - ); - } - getDatatarget(id: number) { - this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { - this.datatarget = dataTarget; - }); - } - onDeleteDatatarget() { - this.deleteDialogSubscription = this.deleteDialogService - .showSimpleDialog() - .subscribe((response) => { - if (response) { - this.datatargetService - .delete(this.datatarget.id) - .subscribe((response) => {}); - this.location.back(); - } else { - console.log(response); - } - }); - } + getDatatarget(id: number) { + this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { + this.datatarget = dataTarget; + }); + } + onDeleteDatatarget() { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.datatargetService.delete(this.datatarget.id).subscribe(response => {}); + this.location.back(); + } else { + console.log(response); + } + }); + } - getDatatargetRelations(id: number) { - this.datatargetRelationServicer - .getByDataTarget(id) - .subscribe((response) => { - this.dataTargetRelations = response.data; - }); - } + getDatatargetRelations(id: number) { + this.datatargetRelationServicer.getByDataTarget(id).subscribe(response => { + this.dataTargetRelations = response.data; + }); + } - ngOnDestroy(): void { - if (this.deleteDialogSubscription) { - this.deleteDialogSubscription.unsubscribe(); + ngOnDestroy(): void { + if (this.deleteDialogSubscription) { + this.deleteDialogSubscription.unsubscribe(); + } } - } } diff --git a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.html b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.html index ecc013dc9..79c7730fe 100644 --- a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.html +++ b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.html @@ -1,192 +1,295 @@ - - +
- -
-
    -
  • - {{error | translate}} -
  • -
-
- -
-
- * - +
+
    +
  • + {{ error | translate }} +
  • +
-
-
-
- * - +
+
+ * + +
-
-
-
- - - +
+
+ * + +
-
-
-
- - - +
+
+ + + +
-
-
-
- * - +
+
+ + + +
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
{{'QUESTION.DATATARGET.RELATIONS' | translate}}
-
-
- {{'QUESTION.ADD-RELATIONS' | translate}} - - - - - - - - - -
-
- - {{'QUESTION.DATATARGET.SELECT-DEVICES' | translate}} - - - - - - {{device.name}} - - -
-
-
- - {{'QUESTION.DATATARGET.SELECT-PAYLOADDECODER' | translate}} - - - {{'QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED' | translate}} - - - {{payloadDecoder.name}} - - - -
-
- -
- -

{{'DATATARGET.DELETE' | translate}}

-
-
-
-
+
+
+ * + +
-
- - +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
{{ "QUESTION.DATATARGET.RELATIONS" | translate }}
+
+
+ {{ + "QUESTION.ADD-RELATIONS" | translate + }} + + + + + + + + + +
+
+ + {{ "QUESTION.DATATARGET.SELECT-DEVICES" | translate }} + + + + + + {{ + device.name + }} + + +
+
+
+ + {{ + "QUESTION.DATATARGET.SELECT-PAYLOADDECODER" | translate + }} + + + {{ "QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED" | translate }} + + + {{ payloadDecoder.name }} + + + +
+
+ +
+ +

{{ "DATATARGET.DELETE" | translate }}

+
+
+
+
+
+ +
+ + +
-
diff --git a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.scss b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.scss index bb96f6577..aaae8f4e6 100644 --- a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.scss +++ b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.scss @@ -1,4 +1,4 @@ .form-info-icon { margin-left: 5px; cursor: pointer; -} \ No newline at end of file +} diff --git a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.spec.ts b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.spec.ts index f445a61e6..ac1101065 100644 --- a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.spec.ts +++ b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.spec.ts @@ -1,28 +1,27 @@ /* tslint:disable:no-unused-variable */ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { DebugElement } from "@angular/core"; -import { FiwareEditComponent } from './fiware-edit.component'; +import { FiwareEditComponent } from "./fiware-edit.component"; -describe('FiwareEditComponent', () => { - let component: FiwareEditComponent; - let fixture: ComponentFixture; +describe("FiwareEditComponent", () => { + let component: FiwareEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ FiwareEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [FiwareEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(FiwareEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(FiwareEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts index 32fb4fb4d..c89c350a0 100644 --- a/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts +++ b/src/app/applications/datatarget/fiware/fiware-edit/fiware-edit.component.ts @@ -1,352 +1,330 @@ -import { Component, OnInit, Input, OnDestroy } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Datatarget } from '../../datatarget.model'; -import { Subscription } from 'rxjs'; -import { Application } from '@applications/application.model'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { faTimesCircle } from '@fortawesome/free-solid-svg-icons'; +import { Component, OnInit, Input, OnDestroy } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { Datatarget } from "../../datatarget.model"; +import { Subscription } from "rxjs"; +import { Application } from "@applications/application.model"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { - PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, -} from '@payload-decoder/payload-device-data.model'; -import { DatatargetService } from '../../datatarget.service'; -import { ApplicationService } from '@applications/application.service'; -import { PayloadDecoderService } from '@payload-decoder/payload-decoder.service'; -import { PayloadDeviceDatatargetService } from '@payload-decoder/payload-device-datatarget.service'; -import { SnackService } from '@shared/services/snack.service'; -import { MatDialog } from '@angular/material/dialog'; -import { HttpErrorResponse } from '@angular/common/http'; -import { PayloadDecoderMappedResponse } from '@payload-decoder/payload-decoder.model'; -import { DeleteDialogComponent } from '@shared/components/delete-dialog/delete-dialog.component'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; -import { DatatargetEdit } from '@applications/datatarget/datatarget-edit/datatarget-edit'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; + PayloadDeviceDatatarget, + PayloadDeviceDatatargetGetByDataTargetResponse, +} from "@payload-decoder/payload-device-data.model"; +import { DatatargetService } from "../../datatarget.service"; +import { ApplicationService } from "@applications/application.service"; +import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; +import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; +import { SnackService } from "@shared/services/snack.service"; +import { MatDialog } from "@angular/material/dialog"; +import { HttpErrorResponse } from "@angular/common/http"; +import { PayloadDecoderMappedResponse } from "@payload-decoder/payload-decoder.model"; +import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons"; +import { DatatargetEdit } from "@applications/datatarget/datatarget-edit/datatarget-edit"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-fiware-edit', - templateUrl: './fiware-edit.component.html', - styleUrls: ['./fiware-edit.component.scss'], + selector: "app-fiware-edit", + templateUrl: "./fiware-edit.component.html", + styleUrls: ["./fiware-edit.component.scss"], }) export class FiwareEditComponent implements DatatargetEdit, OnInit, OnDestroy { - public multiPage = false; - public title = ''; - public sectionTitle = ''; - public backButtonTitle = ''; - @Input() submitButton: string; - public datatarget: Datatarget = new Datatarget(); - faTimesCircle = faTimesCircle; - public datatargetSubscription: Subscription; - public relationSubscription: Subscription; - public applicationSubscription: Subscription; - public payloadDecoderSubscription: Subscription; - public errorMessages: any; - public errorFields: string[]; - public formFailedSubmit = false; - public datatargetid: number; - private applicationId: number; - public application: Application; - public devices: IotDevice[]; - public payloadDecoders = []; - private counter: number; - payloadDeviceDatatarget: PayloadDeviceDatatarget[]; - newDynamic: any = {}; - faQuestionCircle = faQuestionCircle; - canEdit: boolean; + public multiPage = false; + public title = ""; + public sectionTitle = ""; + public backButtonTitle = ""; + @Input() submitButton: string; + public datatarget: Datatarget = new Datatarget(); + faTimesCircle = faTimesCircle; + public datatargetSubscription: Subscription; + public relationSubscription: Subscription; + public applicationSubscription: Subscription; + public payloadDecoderSubscription: Subscription; + public errorMessages: any; + public errorFields: string[]; + public formFailedSubmit = false; + public datatargetid: number; + private applicationId: number; + public application: Application; + public devices: IotDevice[]; + public payloadDecoders = []; + private counter: number; + payloadDeviceDatatarget: PayloadDeviceDatatarget[]; + newDynamic: any = {}; + faQuestionCircle = faQuestionCircle; + canEdit: boolean; - constructor( - public translate: TranslateService, - private route: ActivatedRoute, - private router: Router, - private datatargetService: DatatargetService, - private applicationService: ApplicationService, - private payloadDecoderService: PayloadDecoderService, - private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, - private snackService: SnackService, - private dialog: MatDialog, - private errorMessageService: ErrorMessageService, - private scrollToTopService: ScrollToTopService, - private meService: MeService - ) { - translate.use('da'); - } + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + private router: Router, + private datatargetService: DatatargetService, + private applicationService: ApplicationService, + private payloadDecoderService: PayloadDecoderService, + private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, + private snackService: SnackService, + private dialog: MatDialog, + private errorMessageService: ErrorMessageService, + private scrollToTopService: ScrollToTopService, + private meService: MeService + ) { + translate.use("da"); + } - ngOnInit() { - this.translate - .get([ - 'FORM.CREATE-NEW-DATATARGET', - 'FORM.EDIT-DATATARGET', - 'DATATARGET.SAVE', - 'NAV.DATATARGET', - ]) - .subscribe((translations) => { - const datatargetid = +this.route.snapshot.paramMap.get('datatargetId'); - if (datatargetid !== 0) { - this.title = translations['FORM.EDIT-DATATARGET']; - } else { - this.title = translations['FORM.CREATE-NEW-DATATARGET']; - } - this.submitButton = translations['DATATARGET.SAVE']; - this.backButtonTitle = translations['NAV.DATATARGET']; - }); + ngOnInit() { + this.translate + .get(["FORM.CREATE-NEW-DATATARGET", "FORM.EDIT-DATATARGET", "DATATARGET.SAVE", "NAV.DATATARGET"]) + .subscribe(translations => { + const datatargetid = +this.route.snapshot.paramMap.get("datatargetId"); + if (datatargetid !== 0) { + this.title = translations["FORM.EDIT-DATATARGET"]; + } else { + this.title = translations["FORM.CREATE-NEW-DATATARGET"]; + } + this.submitButton = translations["DATATARGET.SAVE"]; + this.backButtonTitle = translations["NAV.DATATARGET"]; + }); - this.datatargetid = +this.route.snapshot.paramMap.get('datatargetId'); - this.applicationId = +this.route.snapshot.paramMap.get('id'); + this.datatargetid = +this.route.snapshot.paramMap.get("datatargetId"); + this.applicationId = +this.route.snapshot.paramMap.get("id"); - this.datatarget.type = DataTargetType.FIWARE; + this.datatarget.type = DataTargetType.FIWARE; - if (this.datatargetid !== 0) { - this.getDatatarget(this.datatargetid); - this.getPayloadDeviceDatatarget(this.datatargetid); - } - if (this.applicationId !== 0) { - this.getDevices(); - } - this.getPayloadDecoders(); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite - ); - } - - addRow() { - if (!this.payloadDeviceDatatarget) { - this.payloadDeviceDatatarget = []; + if (this.datatargetid !== 0) { + this.getDatatarget(this.datatargetid); + this.getPayloadDeviceDatatarget(this.datatargetid); + } + if (this.applicationId !== 0) { + this.getDevices(); + } + this.getPayloadDecoders(); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite); } - this.payloadDeviceDatatarget.push({ - id: null, - iotDeviceIds: [], - payloadDecoderId: null, - dataTargetId: this.datatargetid, - }); - } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.payloadDeviceDataTargetService - .delete(this.payloadDeviceDatatarget[index].id) - .subscribe((response) => { - this.payloadDeviceDatatarget.splice(index, 1); + addRow() { + if (!this.payloadDeviceDatatarget) { + this.payloadDeviceDatatarget = []; + } + this.payloadDeviceDatatarget.push({ + id: null, + iotDeviceIds: [], + payloadDecoderId: null, + dataTargetId: this.datatargetid, }); } - } - openDeleteDialog(index) { - const dialog = this.dialog.open(DeleteDialogComponent, { - data: { - showAccept: true, - showCancel: true, - message: 'Er du sikker på at du vil slette?', - }, - }); + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { + this.payloadDeviceDatatarget.splice(index, 1); + } else { + this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(response => { + this.payloadDeviceDatatarget.splice(index, 1); + }); + } + } - dialog.afterClosed().subscribe((result) => { - if (result === true) { - this.deleteRow(index); - } - }); - } + openDeleteDialog(index) { + const dialog = this.dialog.open(DeleteDialogComponent, { + data: { + showAccept: true, + showCancel: true, + message: "Er du sikker på at du vil slette?", + }, + }); - onSubmit(): void { - this.counter = 0; - if (this.datatargetid) { - this.updateDatatarget(); - this.addPayloadDeviceDatatarget(); - } else { - this.createDatatarget(); + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.deleteRow(index); + } + }); } - } - public compare(o1: any, o2: any): boolean { - return o1 === o2; - } + onSubmit(): void { + this.counter = 0; + if (this.datatargetid) { + this.updateDatatarget(); + this.addPayloadDeviceDatatarget(); + } else { + this.createDatatarget(); + } + } - updateDatatarget() { - this.resetErrors(); - this.counter = - 1 + - (this.payloadDeviceDatatarget?.length - ? this.payloadDeviceDatatarget?.length - : 0); - this.datatargetService.update(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatarget = response; - this.countToRedirect(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } + public compare(o1: any, o2: any): boolean { + return o1 === o2; + } - addPayloadDeviceDatatarget() { - this.payloadDeviceDatatarget.map((pdd) => { - if (pdd.payloadDecoderId === 0) { - pdd.payloadDecoderId = null; - } - }); - this.payloadDeviceDatatarget.forEach((relation) => { - if (relation.id) { - this.payloadDeviceDataTargetService.put(relation).subscribe( - (response) => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } - ); - } else { - this.payloadDeviceDataTargetService.post(relation).subscribe( - (res: any) => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } + updateDatatarget() { + this.resetErrors(); + this.counter = 1 + (this.payloadDeviceDatatarget?.length ? this.payloadDeviceDatatarget?.length : 0); + this.datatargetService.update(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatarget = response; + this.countToRedirect(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } ); - } - }); - } - - countToRedirect() { - this.counter -= 1; - if (this.counter <= 0 && !this.formFailedSubmit) { - this.showSavedSnack(); - this.routeToDatatargets(); } - } - getPayloadDeviceDatatarget(id: number) { - this.relationSubscription = this.payloadDeviceDataTargetService - .getByDataTarget(id) - .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { - this.mapToDatatargetDevicePayload(response); - }); - } + addPayloadDeviceDatatarget() { + this.payloadDeviceDatatarget.map(pdd => { + if (pdd.payloadDecoderId === 0) { + pdd.payloadDecoderId = null; + } + }); + this.payloadDeviceDatatarget.forEach(relation => { + if (relation.id) { + this.payloadDeviceDataTargetService.put(relation).subscribe( + response => { + this.countToRedirect(); + }, + error => { + this.handleError(error); + } + ); + } else { + this.payloadDeviceDataTargetService.post(relation).subscribe( + (res: any) => { + this.countToRedirect(); + }, + error => { + this.handleError(error); + } + ); + } + }); + } - createDatatarget() { - this.resetErrors(); - this.datatarget.applicationId = this.applicationId; - this.datatargetService.create(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatargetid = response.id; - this.datatarget = response; - this.showSavedSnack(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } + countToRedirect() { + this.counter -= 1; + if (this.counter <= 0 && !this.formFailedSubmit) { + this.showSavedSnack(); + this.routeToDatatargets(); + } + } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } + getPayloadDeviceDatatarget(id: number) { + this.relationSubscription = this.payloadDeviceDataTargetService + .getByDataTarget(id) + .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { + this.mapToDatatargetDevicePayload(response); + }); + } - getDevices(): void { - this.applicationSubscription = this.applicationService - .getApplication(this.applicationId) - .subscribe((application: Application) => { - this.devices = application.iotDevices.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) + createDatatarget() { + this.resetErrors(); + this.datatarget.applicationId = this.applicationId; + this.datatargetService.create(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatargetid = response.id; + this.datatarget = response; + this.showSavedSnack(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } ); - }); - } - - public selectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map( - (device) => device.id - ); - } - - public deSelectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = []; - } + } - getPayloadDecoders() { - this.payloadDecoderSubscription = this.payloadDecoderService - .getMultiple(1000, 0, 'id', 'ASC') - .subscribe((response: PayloadDecoderMappedResponse) => { - this.payloadDecoders = response.data.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }); - } + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + } - handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - this.scrollToTopService.scrollToTop(); - } + getDevices(): void { + this.applicationSubscription = this.applicationService + .getApplication(this.applicationId) + .subscribe((application: Application) => { + this.devices = application.iotDevices.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }); + } - routeToDatatargets(): void { - this.router.navigate(['applications', this.applicationId.toString()]); - } + public selectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); + } - onCoordinateKey(event: any) { - if (event.target.value.length > event.target.maxLength) { - event.target.value = event.target.value.slice(0, event.target.maxLength); + public deSelectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = []; } - } - getDatatarget(id: number) { - this.datatargetSubscription = this.datatargetService - .get(id) - .subscribe((response: Datatarget) => { - this.datatarget = response; - }); - } + getPayloadDecoders() { + this.payloadDecoderSubscription = this.payloadDecoderService + .getMultiple(1000, 0, "id", "ASC") + .subscribe((response: PayloadDecoderMappedResponse) => { + this.payloadDecoders = response.data.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }); + } - showSavedSnack() { - this.snackService.showSavedSnack(); - } + handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); + } - disableSaveButton(): boolean { - const disable = false; + routeToDatatargets(): void { + this.router.navigate(["applications", this.applicationId.toString()]); + } - return disable; - } + onCoordinateKey(event: any) { + if (event.target.value.length > event.target.maxLength) { + event.target.value = event.target.value.slice(0, event.target.maxLength); + } + } - ngOnDestroy(): void { - if (this.relationSubscription) { - this.relationSubscription.unsubscribe(); + getDatatarget(id: number) { + this.datatargetSubscription = this.datatargetService.get(id).subscribe((response: Datatarget) => { + this.datatarget = response; + }); } - if (this.applicationSubscription) { - this.applicationSubscription.unsubscribe(); + + showSavedSnack() { + this.snackService.showSavedSnack(); } - if (this.datatargetSubscription) { - this.datatargetSubscription.unsubscribe(); + + disableSaveButton(): boolean { + const disable = false; + + return disable; } - if (this.payloadDecoderSubscription) { - this.payloadDecoderSubscription.unsubscribe(); + + ngOnDestroy(): void { + if (this.relationSubscription) { + this.relationSubscription.unsubscribe(); + } + if (this.applicationSubscription) { + this.applicationSubscription.unsubscribe(); + } + if (this.datatargetSubscription) { + this.datatargetSubscription.unsubscribe(); + } + if (this.payloadDecoderSubscription) { + this.payloadDecoderSubscription.unsubscribe(); + } } - } - private mapToDatatargetDevicePayload( - dto: PayloadDeviceDatatargetGetByDataTargetResponse - ) { - this.payloadDeviceDatatarget = []; - dto.data.forEach((element) => { - this.payloadDeviceDatatarget.push({ - id: element.id, - iotDeviceIds: element.iotDevices.map((x) => x.id), - payloadDecoderId: - element.payloadDecoder?.id === undefined - ? 0 - : element.payloadDecoder?.id, - dataTargetId: element.dataTarget.id, - }); - }); - } + private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse) { + this.payloadDeviceDatatarget = []; + dto.data.forEach(element => { + this.payloadDeviceDatatarget.push({ + id: element.id, + iotDeviceIds: element.iotDevices.map(x => x.id), + payloadDecoderId: element.payloadDecoder?.id === undefined ? 0 : element.payloadDecoder?.id, + dataTargetId: element.dataTarget.id, + }); + }); + } } diff --git a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html index 72d69c573..a33f9cc04 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html +++ b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.html @@ -1,78 +1,123 @@
- -
-
-
-
-

{{ 'DATATARGET.DETAILS' | translate }}

- - - -

{{ 'DATATARGET.URL' | translate }}{{datatarget.url}}

-

{{ 'DATATARGET.TIMEOUT' | translate }}{{datatarget.timeout}}

-
-

{{ 'DATATARGET.TYPE' | translate }}{{'DATATARGET.' + datatarget.type + '.TYPE' | translate}}

- - -

{{ 'DATATARGET.AUTHORIZATIONHEADER' | translate }}

-
{{datatarget.authorizationHeader}}
- -

{{ 'DATATARGET.NO-AUTHORIZATIONHEADER' | translate }}

-
-
- -
-
-
-
-

{{ 'DATATARGET.OPENDATA-DK.TYPE' | translate }}

-
- -
- -

{{ 'DATATARGET.NO-OPENDATA-DK' | translate }}

-
+ +
+
+
+
+

{{ "DATATARGET.DETAILS" | translate }}

+ + + +

+ {{ "DATATARGET.URL" | translate }}{{ datatarget.url }} +

+

+ {{ "DATATARGET.TIMEOUT" | translate }}{{ datatarget.timeout }} +

+
+

+ {{ "DATATARGET.TYPE" | translate }}{{ "DATATARGET." + datatarget.type + ".TYPE" | translate }} +

+ + +

+ {{ "DATATARGET.AUTHORIZATIONHEADER" | translate }} +

+ +
{{
+                                datatarget.authorizationHeader
+                            }}
+
+ +

{{ "DATATARGET.NO-AUTHORIZATIONHEADER" | translate }}

+
+
+
+
+
+
+

{{ "DATATARGET.OPENDATA-DK.TYPE" | translate }}

+
+ +
+ +

{{ "DATATARGET.NO-OPENDATA-DK" | translate }}

+
+
+
-
-
-
-
-
-
-

{{ 'DATATARGET.RELATIONS' | translate }}

-
-

{{'DATATARGET.NO-RELATIONS' | translate}}

-
-
-
-
-
-

{{'DATATARGET.PAYLOADEDECODER' | translate}} - {{relation.payloadDecoder.name}} - - {{ 'DATATARGET.NO-PAYLOADDECODER' | translate}} -

-
-
- -
-
-

{{'DATATARGET.IOTDEVICE' | translate}} - - , {{device.name}} - -

-
- +
+
+
+
+

{{ "DATATARGET.RELATIONS" | translate }}

+
+

{{ "DATATARGET.NO-RELATIONS" | translate }}

+
+
+
+
+
+

+ {{ "DATATARGET.PAYLOADEDECODER" | translate }} + {{ relation.payloadDecoder.name }} + + {{ + "DATATARGET.NO-PAYLOADDECODER" | translate + }} +

+
+
+ +
+
+

+ {{ "DATATARGET.IOTDEVICE" | translate }} + + , + {{ device.name }} + +

+
+ +
+
+
+
-
-
-
-
diff --git a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.scss b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.scss index e5e49dffe..3f8d6f3c4 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.scss +++ b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.scss @@ -1,3 +1,3 @@ pre { word-wrap: break-word; - } \ No newline at end of file +} diff --git a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.spec.ts b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.spec.ts index d7830e526..6f03b75cb 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.spec.ts +++ b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.spec.ts @@ -1,28 +1,27 @@ /* tslint:disable:no-unused-variable */ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { DebugElement } from "@angular/core"; -import { HttppushDetailComponent } from './httppush-detail.component'; +import { HttppushDetailComponent } from "./httppush-detail.component"; -describe('HttppushDetailComponent', () => { - let component: HttppushDetailComponent; - let fixture: ComponentFixture; +describe("HttppushDetailComponent", () => { + let component: HttppushDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ HttppushDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HttppushDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(HttppushDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HttppushDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts index 47878a841..5dfbc931d 100644 --- a/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts +++ b/src/app/applications/datatarget/httppush/httppush-detail/httppush-detail.component.ts @@ -1,106 +1,97 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { PayloadDeviceDatatargetGetByDataTarget } from '@app/payload-decoder/payload-device-data.model'; -import { PayloadDeviceDatatargetService } from '@app/payload-decoder/payload-device-datatarget.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { DatatargetService } from '../../datatarget.service'; -import { Location } from '@angular/common'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { Datatarget } from '../../datatarget.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { faArrowsAltH } from '@fortawesome/free-solid-svg-icons'; -import { DatatargetDetail } from '@applications/datatarget/datatarget-detail/datatarget-detail'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DataTargetType } from '@shared/enums/datatarget-type'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Subscription } from "rxjs"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { PayloadDeviceDatatargetGetByDataTarget } from "@app/payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetService } from "@app/payload-decoder/payload-device-datatarget.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { DatatargetService } from "../../datatarget.service"; +import { Location } from "@angular/common"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { Datatarget } from "../../datatarget.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { faArrowsAltH } from "@fortawesome/free-solid-svg-icons"; +import { DatatargetDetail } from "@applications/datatarget/datatarget-detail/datatarget-detail"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DataTargetType } from "@shared/enums/datatarget-type"; @Component({ - selector: 'app-httppush-detail', - templateUrl: './httppush-detail.component.html', - styleUrls: ['./httppush-detail.component.scss'], + selector: "app-httppush-detail", + templateUrl: "./httppush-detail.component.html", + styleUrls: ["./httppush-detail.component.scss"], }) -export class HttppushDetailComponent - implements DatatargetDetail, OnInit, OnDestroy { - dataTargetType = DataTargetType; +export class HttppushDetailComponent implements DatatargetDetail, OnInit, OnDestroy { + dataTargetType = DataTargetType; - public datatargetSubscription: Subscription; - public datatarget: Datatarget; - public backButton: BackButton = { label: '', routerLink: undefined }; - public dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; - private deleteDialogSubscription: Subscription; - public dropdownButton: DropdownButton; - arrowsAltH = faArrowsAltH; - canEdit: boolean; + public datatargetSubscription: Subscription; + public datatarget: Datatarget; + public backButton: BackButton = { label: "", routerLink: undefined }; + public dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; + private deleteDialogSubscription: Subscription; + public dropdownButton: DropdownButton; + arrowsAltH = faArrowsAltH; + canEdit: boolean; - constructor( - private route: ActivatedRoute, - private deleteDialogService: DeleteDialogService, - private location: Location, - private datatargetRelationServicer: PayloadDeviceDatatargetService, - private datatargetService: DatatargetService, - public translate: TranslateService, - private meService: MeService - ) {} + constructor( + private route: ActivatedRoute, + private deleteDialogService: DeleteDialogService, + private location: Location, + private datatargetRelationServicer: PayloadDeviceDatatargetService, + private datatargetService: DatatargetService, + public translate: TranslateService, + private meService: MeService + ) {} - ngOnInit(): void { - const id: number = +this.route.snapshot.paramMap.get('datatargetId'); - const appId: number = +this.route.snapshot.paramMap.get('id'); - if (id) { - this.getDatatarget(id); - this.getDatatargetRelations(id); - this.dropdownButton = { - label: '', - editRouterLink: '../../datatarget-edit/' + id, - isErasable: true, - }; + ngOnInit(): void { + const id: number = +this.route.snapshot.paramMap.get("datatargetId"); + const appId: number = +this.route.snapshot.paramMap.get("id"); + if (id) { + this.getDatatarget(id); + this.getDatatargetRelations(id); + this.dropdownButton = { + label: "", + editRouterLink: "../../datatarget-edit/" + id, + isErasable: true, + }; + } + this.translate.get(["NAV.MY-DATATARGET", "DATATARGET.SHOW-OPTIONS"]).subscribe(translations => { + this.backButton.label = translations["NAV.MY-DATATARGET"]; + this.dropdownButton.label = translations["DATATARGET.SHOW-OPTIONS"]; + }); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + appId + ); } - this.translate - .get(['NAV.MY-DATATARGET', 'DATATARGET.SHOW-OPTIONS']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.MY-DATATARGET']; - this.dropdownButton.label = translations['DATATARGET.SHOW-OPTIONS']; - }); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - appId - ); - } - getDatatarget(id: number) { - this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { - this.datatarget = dataTarget; - }); - } + getDatatarget(id: number) { + this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { + this.datatarget = dataTarget; + }); + } - onDeleteDatatarget() { - this.deleteDialogSubscription = this.deleteDialogService - .showSimpleDialog() - .subscribe((response) => { - if (response) { - this.datatargetService - .delete(this.datatarget.id) - .subscribe((response) => {}); - this.location.back(); - } else { - console.log(response); - } - }); - } + onDeleteDatatarget() { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.datatargetService.delete(this.datatarget.id).subscribe(response => {}); + this.location.back(); + } else { + console.log(response); + } + }); + } - getDatatargetRelations(id: number) { - this.datatargetRelationServicer - .getByDataTarget(id) - .subscribe((response) => { - this.dataTargetRelations = response.data; - }); - } + getDatatargetRelations(id: number) { + this.datatargetRelationServicer.getByDataTarget(id).subscribe(response => { + this.dataTargetRelations = response.data; + }); + } - ngOnDestroy(): void { - if (this.deleteDialogSubscription) { - this.deleteDialogSubscription.unsubscribe(); + ngOnDestroy(): void { + if (this.deleteDialogSubscription) { + this.deleteDialogSubscription.unsubscribe(); + } } - } } diff --git a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html index 96bbe9365..f4a750726 100644 --- a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html +++ b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.html @@ -1,132 +1,174 @@ - - +
-
    -
  • - {{error | translate}} -
  • -
+
    +
  • + {{ error | translate }} +
  • +
-
- * - -
+
+ * + +
-
- * - -
+
+ * + +
-
+
- * + * + type="number" + class="form-control" + id="timeout" + name="timeout" + required + [(ngModel)]="datatarget.timeout" + step="1" + min="0" + max="100000" + maxlength="7" + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('timeout'), + 'is-valid': formFailedSubmit && !errorFields.includes('timeout') + }" + />
-
-
+
+
- - + +
-
+
-
-
{{'QUESTION.DATATARGET.RELATIONS' | translate}}
-
-
- {{'QUESTION.ADD-RELATIONS' | translate}} - +
+
{{ "QUESTION.DATATARGET.RELATIONS" | translate }}
+
+
+ {{ "QUESTION.ADD-RELATIONS" | translate }} + - - - - - - - + + + + + + +
-
- - {{'QUESTION.DATATARGET.SELECT-DEVICES' | translate}} - - - - - - {{device.name}} - - -
-
-
- - {{'QUESTION.DATATARGET.SELECT-PAYLOADDECODER' | translate}} - - - {{'QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED' | translate}} - - - {{payloadDecoder.name}} - - - -
-
- -
- -

{{'DATATARGET.DELETE' | translate}}

-
-
-
+
+ + {{ "QUESTION.DATATARGET.SELECT-DEVICES" | translate }} + + + + + + {{ + device.name + }} + + +
+
+
+ + {{ "QUESTION.DATATARGET.SELECT-PAYLOADDECODER" | translate }} + + + {{ "QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED" | translate }} + + + {{ payloadDecoder.name }} + + + +
+
+ +
+ +

{{ "DATATARGET.DELETE" | translate }}

+
+
+
-
-
-
- - -
- +
+
+
+ + +
+ diff --git a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.spec.ts b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.spec.ts index 21980cfd2..16caecaa3 100644 --- a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.spec.ts +++ b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.spec.ts @@ -1,28 +1,27 @@ /* tslint:disable:no-unused-variable */ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { DebugElement } from "@angular/core"; -import { HttppushEditComponent } from './httppush-edit.component'; +import { HttppushEditComponent } from "./httppush-edit.component"; -describe('HttppushEditComponent', () => { - let component: HttppushEditComponent; - let fixture: ComponentFixture; +describe("HttppushEditComponent", () => { + let component: HttppushEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ HttppushEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HttppushEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(HttppushEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HttppushEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts index 1c27409b6..a3f144e9f 100644 --- a/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts +++ b/src/app/applications/datatarget/httppush/httppush-edit/httppush-edit.component.ts @@ -1,359 +1,337 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Datatarget } from '../../datatarget.model'; -import { Subscription } from 'rxjs'; -import { Application } from '@applications/application.model'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { faTimesCircle } from '@fortawesome/free-solid-svg-icons'; +import { Component, OnInit, OnDestroy } from "@angular/core"; +import { TranslateService } from "@ngx-translate/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { Datatarget } from "../../datatarget.model"; +import { Subscription } from "rxjs"; +import { Application } from "@applications/application.model"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { - PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, -} from '@payload-decoder/payload-device-data.model'; -import { DatatargetService } from '../../datatarget.service'; -import { ApplicationService } from '@applications/application.service'; -import { PayloadDecoderService } from '@payload-decoder/payload-decoder.service'; -import { PayloadDeviceDatatargetService } from '@payload-decoder/payload-device-datatarget.service'; -import { SnackService } from '@shared/services/snack.service'; -import { MatDialog } from '@angular/material/dialog'; -import { HttpErrorResponse } from '@angular/common/http'; -import { PayloadDecoderMappedResponse } from '@payload-decoder/payload-decoder.model'; -import { DeleteDialogComponent } from '@shared/components/delete-dialog/delete-dialog.component'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { DatatargetEdit } from '@applications/datatarget/datatarget-edit/datatarget-edit'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; + PayloadDeviceDatatarget, + PayloadDeviceDatatargetGetByDataTargetResponse, +} from "@payload-decoder/payload-device-data.model"; +import { DatatargetService } from "../../datatarget.service"; +import { ApplicationService } from "@applications/application.service"; +import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; +import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; +import { SnackService } from "@shared/services/snack.service"; +import { MatDialog } from "@angular/material/dialog"; +import { HttpErrorResponse } from "@angular/common/http"; +import { PayloadDecoderMappedResponse } from "@payload-decoder/payload-decoder.model"; +import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; +import { DatatargetEdit } from "@applications/datatarget/datatarget-edit/datatarget-edit"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-httppush-edit', - templateUrl: './httppush-edit.component.html', - styleUrls: ['./httppush-edit.component.scss'], + selector: "app-httppush-edit", + templateUrl: "./httppush-edit.component.html", + styleUrls: ["./httppush-edit.component.scss"], }) -export class HttppushEditComponent - implements DatatargetEdit, OnInit, OnDestroy { - public multiPage = false; - public title = ''; - public sectionTitle = ''; - public backButtonTitle = ''; - public submitButton: string; - public datatarget: Datatarget = new Datatarget(); - faTimesCircle = faTimesCircle; - public datatargetSubscription: Subscription; - public relationSubscription: Subscription; - public applicationSubscription: Subscription; - public payloadDecoderSubscription: Subscription; - public errorMessages: any; - public errorFields: string[]; - public formFailedSubmit = false; - public datatargetid: number; - private applicationId: number; - public application: Application; - public devices: IotDevice[]; - public payloadDecoders = []; - private counter: number; +export class HttppushEditComponent implements DatatargetEdit, OnInit, OnDestroy { + public multiPage = false; + public title = ""; + public sectionTitle = ""; + public backButtonTitle = ""; + public submitButton: string; + public datatarget: Datatarget = new Datatarget(); + faTimesCircle = faTimesCircle; + public datatargetSubscription: Subscription; + public relationSubscription: Subscription; + public applicationSubscription: Subscription; + public payloadDecoderSubscription: Subscription; + public errorMessages: any; + public errorFields: string[]; + public formFailedSubmit = false; + public datatargetid: number; + private applicationId: number; + public application: Application; + public devices: IotDevice[]; + public payloadDecoders = []; + private counter: number; - payloadDeviceDatatarget: PayloadDeviceDatatarget[]; - newDynamic: any = {}; - canEdit: boolean; + payloadDeviceDatatarget: PayloadDeviceDatatarget[]; + newDynamic: any = {}; + canEdit: boolean; - constructor( - public translate: TranslateService, - private route: ActivatedRoute, - private router: Router, - private datatargetService: DatatargetService, - private applicationService: ApplicationService, - private payloadDecoderService: PayloadDecoderService, - private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, - private saveSnackService: SnackService, - private dialog: MatDialog, - private errorMessageService: ErrorMessageService, - private scrollToTopService: ScrollToTopService, - private meService: MeService - ) { - translate.use('da'); - } - - ngOnInit() { - this.translate - .get([ - 'FORM.CREATE-NEW-DATATARGET', - 'FORM.EDIT-DATATARGET', - 'DATATARGET.SAVE', - 'NAV.DATATARGET', - ]) - .subscribe((translations) => { - const datatargetid = +this.route.snapshot.paramMap.get('datatargetId'); - if (datatargetid !== 0) { - this.title = translations['FORM.EDIT-DATATARGET']; - } else { - this.title = translations['FORM.CREATE-NEW-DATATARGET']; - } - this.submitButton = translations['DATATARGET.SAVE']; - this.backButtonTitle = translations['NAV.DATATARGET']; - }); - - this.datatargetid = +this.route.snapshot.paramMap.get('datatargetId'); - this.applicationId = +this.route.snapshot.paramMap.get('id'); - if (this.datatargetid !== 0) { - this.getDatatarget(this.datatargetid); - this.getPayloadDeviceDatatarget(this.datatargetid); - } - if (this.applicationId !== 0) { - this.getDevices(); + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + private router: Router, + private datatargetService: DatatargetService, + private applicationService: ApplicationService, + private payloadDecoderService: PayloadDecoderService, + private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, + private saveSnackService: SnackService, + private dialog: MatDialog, + private errorMessageService: ErrorMessageService, + private scrollToTopService: ScrollToTopService, + private meService: MeService + ) { + translate.use("da"); } - this.getPayloadDecoders(); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - this.applicationId - ); - } - addRow() { - if (!this.payloadDeviceDatatarget) { - this.payloadDeviceDatatarget = []; + ngOnInit() { + this.translate + .get(["FORM.CREATE-NEW-DATATARGET", "FORM.EDIT-DATATARGET", "DATATARGET.SAVE", "NAV.DATATARGET"]) + .subscribe(translations => { + const datatargetid = +this.route.snapshot.paramMap.get("datatargetId"); + if (datatargetid !== 0) { + this.title = translations["FORM.EDIT-DATATARGET"]; + } else { + this.title = translations["FORM.CREATE-NEW-DATATARGET"]; + } + this.submitButton = translations["DATATARGET.SAVE"]; + this.backButtonTitle = translations["NAV.DATATARGET"]; + }); + + this.datatargetid = +this.route.snapshot.paramMap.get("datatargetId"); + this.applicationId = +this.route.snapshot.paramMap.get("id"); + if (this.datatargetid !== 0) { + this.getDatatarget(this.datatargetid); + this.getPayloadDeviceDatatarget(this.datatargetid); + } + if (this.applicationId !== 0) { + this.getDevices(); + } + this.getPayloadDecoders(); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + this.applicationId + ); } - this.payloadDeviceDatatarget.push({ - id: null, - iotDeviceIds: [], - payloadDecoderId: null, - dataTargetId: this.datatargetid, - }); - } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.payloadDeviceDataTargetService - .delete(this.payloadDeviceDatatarget[index].id) - .subscribe((response) => { - this.payloadDeviceDatatarget.splice(index, 1); + addRow() { + if (!this.payloadDeviceDatatarget) { + this.payloadDeviceDatatarget = []; + } + this.payloadDeviceDatatarget.push({ + id: null, + iotDeviceIds: [], + payloadDecoderId: null, + dataTargetId: this.datatargetid, }); } - } - openDeleteDialog(index) { - const dialog = this.dialog.open(DeleteDialogComponent, { - data: { - showAccept: true, - showCancel: true, - message: 'Er du sikker på at du vil slette?', - }, - }); + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { + this.payloadDeviceDatatarget.splice(index, 1); + } else { + this.payloadDeviceDataTargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(response => { + this.payloadDeviceDatatarget.splice(index, 1); + }); + } + } - dialog.afterClosed().subscribe((result) => { - if (result === true) { - this.deleteRow(index); - } - }); - } + openDeleteDialog(index) { + const dialog = this.dialog.open(DeleteDialogComponent, { + data: { + showAccept: true, + showCancel: true, + message: "Er du sikker på at du vil slette?", + }, + }); - onSubmit(): void { - this.counter = 0; - if (this.datatargetid) { - if (!this.validatePayloadDeviceDatatarget()) return; - this.updateDatatarget(); - this.addPayloadDeviceDatatarget(); - } else { - this.createDatatarget(); + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.deleteRow(index); + } + }); } - } - public compare(o1: any, o2: any): boolean { - return o1 === o2; - } + onSubmit(): void { + this.counter = 0; + if (this.datatargetid) { + if (!this.validatePayloadDeviceDatatarget()) return; + this.updateDatatarget(); + this.addPayloadDeviceDatatarget(); + } else { + this.createDatatarget(); + } + } - updateDatatarget() { - this.resetErrors(); - this.counter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); - this.datatargetService.update(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatarget = response; - this.countToRedirect(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } + public compare(o1: any, o2: any): boolean { + return o1 === o2; + } - addPayloadDeviceDatatarget() { - this.payloadDeviceDatatarget.map((pdd) => { - if (pdd.payloadDecoderId === 0) { - pdd.payloadDecoderId = null; - } - }); - this.payloadDeviceDatatarget.forEach((relation) => { - if (relation.id) { - this.payloadDeviceDataTargetService.put(relation).subscribe( - (response) => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } - ); - } else { - this.payloadDeviceDataTargetService.post(relation).subscribe( - (res: any) => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } + updateDatatarget() { + this.resetErrors(); + this.counter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); + this.datatargetService.update(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatarget = response; + this.countToRedirect(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } ); - } - }); - } - - private validatePayloadDeviceDatatarget = () => { - const isError = this.payloadDeviceDatatarget?.some( - (relation) => (relation.iotDeviceIds?.length ?? 0) < 1 - ); - if (isError) { - this.errorFields = ['devices']; - this.errorMessages = [ - 'Must attach at least one IoT-device for each element in list of devices / decoders', - ]; - this.scrollToTopService.scrollToTop(); } - return !isError; - }; - countToRedirect() { - this.counter -= 1; - if (this.counter <= 0 && !this.formFailedSubmit) { - this.showSavedSnack(); - this.routeToDatatargets(); + addPayloadDeviceDatatarget() { + this.payloadDeviceDatatarget.map(pdd => { + if (pdd.payloadDecoderId === 0) { + pdd.payloadDecoderId = null; + } + }); + this.payloadDeviceDatatarget.forEach(relation => { + if (relation.id) { + this.payloadDeviceDataTargetService.put(relation).subscribe( + response => { + this.countToRedirect(); + }, + error => { + this.handleError(error); + } + ); + } else { + this.payloadDeviceDataTargetService.post(relation).subscribe( + (res: any) => { + this.countToRedirect(); + }, + error => { + this.handleError(error); + } + ); + } + }); } - } - getPayloadDeviceDatatarget(id: number) { - this.relationSubscription = this.payloadDeviceDataTargetService - .getByDataTarget(id) - .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { - this.mapToDatatargetDevicePayload(response); - }); - } + private validatePayloadDeviceDatatarget = () => { + const isError = this.payloadDeviceDatatarget?.some(relation => (relation.iotDeviceIds?.length ?? 0) < 1); + if (isError) { + this.errorFields = ["devices"]; + this.errorMessages = ["Must attach at least one IoT-device for each element in list of devices / decoders"]; + this.scrollToTopService.scrollToTop(); + } + return !isError; + }; - createDatatarget() { - this.resetErrors(); - this.datatarget.applicationId = this.applicationId; - this.datatargetService.create(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatargetid = response.id; - this.datatarget = response; - this.showSavedSnack(); - this.routeToCreatedDatatarget(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } + countToRedirect() { + this.counter -= 1; + if (this.counter <= 0 && !this.formFailedSubmit) { + this.showSavedSnack(); + this.routeToDatatargets(); + } + } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } + getPayloadDeviceDatatarget(id: number) { + this.relationSubscription = this.payloadDeviceDataTargetService + .getByDataTarget(id) + .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { + this.mapToDatatargetDevicePayload(response); + }); + } - getDevices(): void { - this.applicationSubscription = this.applicationService - .getApplication(this.applicationId) - .subscribe((application: Application) => { - this.devices = application.iotDevices.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) + createDatatarget() { + this.resetErrors(); + this.datatarget.applicationId = this.applicationId; + this.datatargetService.create(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatargetid = response.id; + this.datatarget = response; + this.showSavedSnack(); + this.routeToCreatedDatatarget(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } ); - }); - } - - public selectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map( - (device) => device.id - ); - } + } - public deSelectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = []; - } + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + } - getPayloadDecoders() { - this.payloadDecoderSubscription = this.payloadDecoderService - .getMultiple(1000, 0, 'id', 'ASC') - .subscribe((response: PayloadDecoderMappedResponse) => { - this.payloadDecoders = response.data.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }); - } + getDevices(): void { + this.applicationSubscription = this.applicationService + .getApplication(this.applicationId) + .subscribe((application: Application) => { + this.devices = application.iotDevices.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }); + } - handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - this.scrollToTopService.scrollToTop(); - } + public selectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); + } - routeToDatatargets = () => this.router.navigate(['applications', this.applicationId, 'data-targets']); - routeToCreatedDatatarget = () => - this.router.navigate( - ['applications', this.applicationId, 'datatarget', this.datatarget.id], - { replaceUrl: true } - ); + public deSelectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = []; + } - onCoordinateKey(event: any) { - if (event.target.value.length > event.target.maxLength) { - event.target.value = event.target.value.slice(0, event.target.maxLength); + getPayloadDecoders() { + this.payloadDecoderSubscription = this.payloadDecoderService + .getMultiple(1000, 0, "id", "ASC") + .subscribe((response: PayloadDecoderMappedResponse) => { + this.payloadDecoders = response.data.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }); } - } - getDatatarget(id: number) { - this.datatargetSubscription = this.datatargetService - .get(id) - .subscribe((response: Datatarget) => { - this.datatarget = response; - }); - } + handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); + } - showSavedSnack() { - this.saveSnackService.showSavedSnack(); - } + routeToDatatargets = () => this.router.navigate(["applications", this.applicationId, "data-targets"]); + routeToCreatedDatatarget = () => + this.router.navigate(["applications", this.applicationId, "datatarget", this.datatarget.id], { + replaceUrl: true, + }); - ngOnDestroy(): void { - if (this.relationSubscription) { - this.relationSubscription.unsubscribe(); + onCoordinateKey(event: any) { + if (event.target.value.length > event.target.maxLength) { + event.target.value = event.target.value.slice(0, event.target.maxLength); + } } - if (this.applicationSubscription) { - this.applicationSubscription.unsubscribe(); + + getDatatarget(id: number) { + this.datatargetSubscription = this.datatargetService.get(id).subscribe((response: Datatarget) => { + this.datatarget = response; + }); } - if (this.datatargetSubscription) { - this.datatargetSubscription.unsubscribe(); + + showSavedSnack() { + this.saveSnackService.showSavedSnack(); } - if (this.payloadDecoderSubscription) { - this.payloadDecoderSubscription.unsubscribe(); + + ngOnDestroy(): void { + if (this.relationSubscription) { + this.relationSubscription.unsubscribe(); + } + if (this.applicationSubscription) { + this.applicationSubscription.unsubscribe(); + } + if (this.datatargetSubscription) { + this.datatargetSubscription.unsubscribe(); + } + if (this.payloadDecoderSubscription) { + this.payloadDecoderSubscription.unsubscribe(); + } } - } - private mapToDatatargetDevicePayload( - dto: PayloadDeviceDatatargetGetByDataTargetResponse - ) { - this.payloadDeviceDatatarget = []; - dto.data.forEach((element) => { - this.payloadDeviceDatatarget.push({ - id: element.id, - iotDeviceIds: element.iotDevices.map((x) => x.id), - payloadDecoderId: - element.payloadDecoder?.id === undefined - ? 0 - : element.payloadDecoder?.id, - dataTargetId: element.dataTarget.id, - }); - }); - } + private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse) { + this.payloadDeviceDatatarget = []; + dto.data.forEach(element => { + this.payloadDeviceDatatarget.push({ + id: element.id, + iotDeviceIds: element.iotDevices.map(x => x.id), + payloadDecoderId: element.payloadDecoder?.id === undefined ? 0 : element.payloadDecoder?.id, + dataTargetId: element.dataTarget.id, + }); + }); + } } diff --git a/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.html b/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.html index e8b225e27..4def0a792 100644 --- a/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.html +++ b/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.html @@ -1,65 +1,116 @@
- - -
-
-
-
-

{{ 'DATATARGET.DETAILS' | translate }}

- - -

{{ 'DATATARGET.MQTT.BROKER-URL' | translate }}{{datatarget.url}}

-

{{ 'DATATARGET.TIMEOUT' | translate }}{{datatarget.timeout}}

-

{{ 'DATATARGET.TYPE' | translate }}{{'DATATARGET.' + datatarget.type + ".TYPE" | - translate}}

- -

{{ 'DATATARGET.MQTT.PORT' | translate }}{{datatarget.mqttPort}}

-

{{ 'DATATARGET.MQTT.TOPIC' | translate }}{{datatarget.mqttTopic}}

-

{{ 'DATATARGET.MQTT.QOS' | translate }}{{datatarget.mqttQos}}

-

{{ 'DATATARGET.MQTT.USERNAME' | translate }}{{datatarget.mqttUsername}}

-

{{ 'DATATARGET.MQTT.PASSWORD' | translate }}{{datatarget.mqttPassword}}

-
-
+ + +
+
+
+
+

{{ "DATATARGET.DETAILS" | translate }}

+ + +

+ {{ "DATATARGET.MQTT.BROKER-URL" | translate }}{{ datatarget.url }} +

+

+ {{ "DATATARGET.TIMEOUT" | translate }}{{ datatarget.timeout }} +

+

+ {{ "DATATARGET.TYPE" | translate }}{{ "DATATARGET." + datatarget.type + ".TYPE" | translate }} +

+ +

+ {{ "DATATARGET.MQTT.PORT" | translate }}{{ datatarget.mqttPort }} +

+

+ {{ "DATATARGET.MQTT.TOPIC" | translate }}{{ datatarget.mqttTopic }} +

+

+ {{ "DATATARGET.MQTT.QOS" | translate }}{{ datatarget.mqttQos }} +

+

+ {{ "DATATARGET.MQTT.USERNAME" | translate }}{{ datatarget.mqttUsername }} +

+

+ {{ "DATATARGET.MQTT.PASSWORD" | translate }}{{ datatarget.mqttPassword }} +

+
+
-
-
-
-
-

{{ 'DATATARGET.RELATIONS' | translate }}

-
-

{{'DATATARGET.NO-RELATIONS' | translate}}

-
-
-
-
-
-

{{'DATATARGET.PAYLOADEDECODER' | translate}} - {{relation.payloadDecoder.name}} - - {{ 'DATATARGET.NO-PAYLOADDECODER' | translate}} -

-
-
- +
+
+
+
+

{{ "DATATARGET.RELATIONS" | translate }}

+
+

{{ "DATATARGET.NO-RELATIONS" | translate }}

+
+
+
+
+
+

+ {{ "DATATARGET.PAYLOADEDECODER" | translate }} + {{ relation.payloadDecoder.name }} + + {{ + "DATATARGET.NO-PAYLOADDECODER" | translate + }} +

+
+
+ +
+
+

+ {{ "DATATARGET.IOTDEVICE" | translate }} + + , + {{ device.name }} + +

+
+ +
+
+
+
-
-

{{'DATATARGET.IOTDEVICE' | translate}} - - , {{device.name}} - -

-
- -
-
-
-
-
+
diff --git a/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.ts b/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.ts index 564d38dec..65390a17d 100644 --- a/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.ts +++ b/src/app/applications/datatarget/mqtt-detail/mqtt-detail.component.ts @@ -1,97 +1,92 @@ -import { Location } from '@angular/common'; -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { DatatargetDetail } from '@applications/datatarget/datatarget-detail/datatarget-detail'; -import { faArrowsAltH } from '@fortawesome/free-solid-svg-icons'; -import { TranslateService } from '@ngx-translate/core'; -import { PayloadDeviceDatatargetGetByDataTarget } from '@payload-decoder/payload-device-data.model'; -import { PayloadDeviceDatatargetService } from '@payload-decoder/payload-device-datatarget.service'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { Subscription } from 'rxjs'; -import { Datatarget } from '../datatarget.model'; -import { DatatargetService } from '../datatarget.service'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Location } from "@angular/common"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { DatatargetDetail } from "@applications/datatarget/datatarget-detail/datatarget-detail"; +import { faArrowsAltH } from "@fortawesome/free-solid-svg-icons"; +import { TranslateService } from "@ngx-translate/core"; +import { PayloadDeviceDatatargetGetByDataTarget } from "@payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { Subscription } from "rxjs"; +import { Datatarget } from "../datatarget.model"; +import { DatatargetService } from "../datatarget.service"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-mqtt-detail', - templateUrl: './mqtt-detail.component.html', - styleUrls: ['./mqtt-detail.component.scss'], + selector: "app-mqtt-detail", + templateUrl: "./mqtt-detail.component.html", + styleUrls: ["./mqtt-detail.component.scss"], }) // TODO: Most of the code is duplicated from other datatarget edit components. // Same applies to the html file. One solution is extending a base datatarget-edit component -export class MqttDetailComponent - implements DatatargetDetail, OnInit, OnDestroy { - public datatarget: Datatarget; - public backButton: BackButton = { label: '', routerLink: undefined }; - public dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; - private deleteDialogSubscription: Subscription; - public dropdownButton: DropdownButton; - arrowsAltH = faArrowsAltH; - canEdit: boolean; +export class MqttDetailComponent implements DatatargetDetail, OnInit, OnDestroy { + public datatarget: Datatarget; + public backButton: BackButton = { label: "", routerLink: undefined }; + public dataTargetRelations: PayloadDeviceDatatargetGetByDataTarget[]; + private deleteDialogSubscription: Subscription; + public dropdownButton: DropdownButton; + arrowsAltH = faArrowsAltH; + canEdit: boolean; - constructor( - private route: ActivatedRoute, - private deleteDialogService: DeleteDialogService, - private location: Location, - private datatargetRelationService: PayloadDeviceDatatargetService, - private datatargetService: DatatargetService, - public translate: TranslateService, - private meService: MeService - ) {} + constructor( + private route: ActivatedRoute, + private deleteDialogService: DeleteDialogService, + private location: Location, + private datatargetRelationService: PayloadDeviceDatatargetService, + private datatargetService: DatatargetService, + public translate: TranslateService, + private meService: MeService + ) {} - ngOnInit(): void { - const id: number = +this.route.snapshot.paramMap.get('datatargetId'); - const appId: number = +this.route.snapshot.paramMap.get('id'); + ngOnInit(): void { + const id: number = +this.route.snapshot.paramMap.get("datatargetId"); + const appId: number = +this.route.snapshot.paramMap.get("id"); - if (id) { - this.getDatatarget(id); - this.getDatatargetRelations(id); - this.dropdownButton = { - label: '', - editRouterLink: '../../datatarget-edit/' + id, - isErasable: true, - }; + if (id) { + this.getDatatarget(id); + this.getDatatargetRelations(id); + this.dropdownButton = { + label: "", + editRouterLink: "../../datatarget-edit/" + id, + isErasable: true, + }; + } + this.translate.get(["NAV.MY-DATATARGET", "DATATARGET.SHOW-OPTIONS"]).subscribe(translations => { + this.backButton.label = translations["NAV.MY-DATATARGET"]; + this.dropdownButton.label = translations["DATATARGET.SHOW-OPTIONS"]; + }); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + appId + ); } - this.translate - .get(['NAV.MY-DATATARGET', 'DATATARGET.SHOW-OPTIONS']) - .subscribe((translations) => { - this.backButton.label = translations['NAV.MY-DATATARGET']; - this.dropdownButton.label = translations['DATATARGET.SHOW-OPTIONS']; - }); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - appId - ); - } - getDatatarget(id: number) { - this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { - this.datatarget = dataTarget; - }); - } + getDatatarget(id: number) { + this.datatargetService.get(id).subscribe((dataTarget: Datatarget) => { + this.datatarget = dataTarget; + }); + } - onDeleteDatatarget() { - this.deleteDialogSubscription = this.deleteDialogService - .showSimpleDialog() - .subscribe((response) => { - if (response) { - this.datatargetService.delete(this.datatarget.id).subscribe(() => {}); - this.location.back(); - } - }); - } + onDeleteDatatarget() { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.datatargetService.delete(this.datatarget.id).subscribe(() => {}); + this.location.back(); + } + }); + } - getDatatargetRelations(id: number) { - this.datatargetRelationService.getByDataTarget(id).subscribe((response) => { - this.dataTargetRelations = response.data; - }); - } + getDatatargetRelations(id: number) { + this.datatargetRelationService.getByDataTarget(id).subscribe(response => { + this.dataTargetRelations = response.data; + }); + } - ngOnDestroy(): void { - this.deleteDialogSubscription?.unsubscribe(); - } + ngOnDestroy(): void { + this.deleteDialogSubscription?.unsubscribe(); + } } diff --git a/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.html b/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.html index acd45b98c..48090ae5f 100644 --- a/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.html +++ b/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.html @@ -1,164 +1,279 @@ - +
-
-
    -
  • - {{error | translate}} -
  • -
-
+
+
    +
  • + {{ error | translate }} +
  • +
+
-
-
- * - +
+
+ * + +
-
-
-
- * - +
+
+ * + +
-
-
-
- * - +
+
+ * + +
-
-
-
- * - - +
+
+ * + + +
-
-
-
- * - - +
+
+ * + + +
-
-
-
- * - +
+
+ * + +
-
-
-
- * - +
+
+ * + +
-
-
-
- * - +
+
+ * + +
-
-
-
{{'QUESTION.DATATARGET.RELATIONS' | translate}}
-
+
+
{{ "QUESTION.DATATARGET.RELATIONS" | translate }}
+
-
- {{'QUESTION.ADD-RELATIONS' | translate}} - - - - - - - - - -
-
- - {{'QUESTION.DATATARGET.SELECT-DEVICES' | translate}} - - - - - - {{device.name}} - - -
-
-
- - {{'QUESTION.DATATARGET.SELECT-PAYLOADDECODER' | translate}} - - - {{'QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED' | translate}} - - - {{payloadDecoder.name}} - - - -
-
- -
- -

{{'DATATARGET.DELETE' | translate}}

-
-
-
-
-
+
+ {{ "QUESTION.ADD-RELATIONS" | translate }} + + + + + + + + + +
+
+ + {{ "QUESTION.DATATARGET.SELECT-DEVICES" | translate }} + + + + + + {{ + device.name + }} + + +
+
+
+ + {{ "QUESTION.DATATARGET.SELECT-PAYLOADDECODER" | translate }} + + + {{ "QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED" | translate }} + + + {{ payloadDecoder.name }} + + + +
+
+ +
+ +

{{ "DATATARGET.DELETE" | translate }}

+
+
+
+
+
-
- - -
+
+ + +
diff --git a/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts b/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts index 512ab6e10..6574444ea 100644 --- a/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts +++ b/src/app/applications/datatarget/mqtt-edit/mqtt-edit.component.ts @@ -1,292 +1,275 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Application } from '@applications/application.model'; -import { ApplicationService } from '@applications/application.service'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { ActivatedRoute, Router } from "@angular/router"; +import { Application } from "@applications/application.model"; +import { ApplicationService } from "@applications/application.service"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { faQuestionCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons"; +import { PayloadDecoder, PayloadDecoderMappedResponse } from "@payload-decoder/payload-decoder.model"; +import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; import { - faQuestionCircle, - faTimesCircle, -} from '@fortawesome/free-solid-svg-icons'; -import { - PayloadDecoder, - PayloadDecoderMappedResponse, -} from '@payload-decoder/payload-decoder.model'; -import { PayloadDecoderService } from '@payload-decoder/payload-decoder.service'; -import { - PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, -} from '@payload-decoder/payload-device-data.model'; -import { PayloadDeviceDatatargetService } from '@payload-decoder/payload-device-datatarget.service'; -import { DeleteDialogComponent } from '@shared/components/delete-dialog/delete-dialog.component'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { SnackService } from '@shared/services/snack.service'; -import { Subscription } from 'rxjs'; -import { DatatargetEdit } from '../datatarget-edit/datatarget-edit'; -import { Datatarget } from '../datatarget.model'; -import { DatatargetService } from '../datatarget.service'; + PayloadDeviceDatatarget, + PayloadDeviceDatatargetGetByDataTargetResponse, +} from "@payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; +import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; +import { SnackService } from "@shared/services/snack.service"; +import { Subscription } from "rxjs"; +import { DatatargetEdit } from "../datatarget-edit/datatarget-edit"; +import { Datatarget } from "../datatarget.model"; +import { DatatargetService } from "../datatarget.service"; @Component({ - selector: 'app-mqtt-edit', - templateUrl: './mqtt-edit.component.html', - styleUrls: ['./mqtt-edit.component.scss'], + selector: "app-mqtt-edit", + templateUrl: "./mqtt-edit.component.html", + styleUrls: ["./mqtt-edit.component.scss"], }) // TODO: Most of the code is duplicated from other datatarget edit components. // Same applies to the html file. One solution is extending a base datatarget-edit component export class MqttEditComponent implements DatatargetEdit, OnInit, OnDestroy { - public errorMessages: string[]; - public errorFields: string[]; - public formFailedSubmit = false; - public datatarget: Datatarget = new Datatarget(); - public datatargetId: number; - private applicationId: number; - private datatargetSubscription: Subscription; - private applicationSubscription: Subscription; - private relationSubscription: Subscription; - private payloadDecoderSubscription: Subscription; - public payloadDecoders: PayloadDecoder[] = []; - public payloadDeviceDatatarget: PayloadDeviceDatatarget[]; - public devices: IotDevice[]; - private activeApiCalls: number; - faTimesCircle = faTimesCircle; - faQuestionCircle = faQuestionCircle; + public errorMessages: string[]; + public errorFields: string[]; + public formFailedSubmit = false; + public datatarget: Datatarget = new Datatarget(); + public datatargetId: number; + private applicationId: number; + private datatargetSubscription: Subscription; + private applicationSubscription: Subscription; + private relationSubscription: Subscription; + private payloadDecoderSubscription: Subscription; + public payloadDecoders: PayloadDecoder[] = []; + public payloadDeviceDatatarget: PayloadDeviceDatatarget[]; + public devices: IotDevice[]; + private activeApiCalls: number; + faTimesCircle = faTimesCircle; + faQuestionCircle = faQuestionCircle; - constructor( - private route: ActivatedRoute, - private router: Router, - private applicationService: ApplicationService, - private datatargetService: DatatargetService, - private payloadDecoderService: PayloadDecoderService, - private payloadDeviceDatatargetService: PayloadDeviceDatatargetService, - private dialog: MatDialog, - private snackService: SnackService, - private errorMessageService: ErrorMessageService, - private scrollToTopService: ScrollToTopService - ) {} + constructor( + private route: ActivatedRoute, + private router: Router, + private applicationService: ApplicationService, + private datatargetService: DatatargetService, + private payloadDecoderService: PayloadDecoderService, + private payloadDeviceDatatargetService: PayloadDeviceDatatargetService, + private dialog: MatDialog, + private snackService: SnackService, + private errorMessageService: ErrorMessageService, + private scrollToTopService: ScrollToTopService + ) {} - ngOnInit(): void { - this.datatargetId = +this.route.snapshot.paramMap.get('datatargetId'); - this.applicationId = +this.route.snapshot.paramMap.get('id'); - this.datatarget.type = DataTargetType.MQTT; + ngOnInit(): void { + this.datatargetId = +this.route.snapshot.paramMap.get("datatargetId"); + this.applicationId = +this.route.snapshot.paramMap.get("id"); + this.datatarget.type = DataTargetType.MQTT; - if (this.datatargetId !== 0) { - this.getDatatarget(this.datatargetId); - this.getPayloadDeviceDatatarget(this.datatargetId); + if (this.datatargetId !== 0) { + this.getDatatarget(this.datatargetId); + this.getPayloadDeviceDatatarget(this.datatargetId); + } + if (this.applicationId !== 0) { + this.getDevices(); + } + this.getPayloadDecoders(); } - if (this.applicationId !== 0) { - this.getDevices(); - } - this.getPayloadDecoders(); - } - - private getPayloadDecoders() { - this.payloadDecoderSubscription = this.payloadDecoderService - .getMultiple(1000, 0, 'id', 'ASC') - .subscribe((response: PayloadDecoderMappedResponse) => { - this.payloadDecoders = response.data.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }); - } - private handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - this.scrollToTopService.scrollToTop(); - } + private getPayloadDecoders() { + this.payloadDecoderSubscription = this.payloadDecoderService + .getMultiple(1000, 0, "id", "ASC") + .subscribe((response: PayloadDecoderMappedResponse) => { + this.payloadDecoders = response.data.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }); + } - routeToDatatargets(): void { - this.router.navigate(['applications', this.applicationId.toString()]); - } + private handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); + } - getDatatarget(id: number) { - this.datatargetSubscription = this.datatargetService - .get(id) - .subscribe((response: Datatarget) => { - this.datatarget = response; - }); - } + routeToDatatargets(): void { + this.router.navigate(["applications", this.applicationId.toString()]); + } - getDevices(): void { - this.applicationSubscription = this.applicationService - .getApplication(this.applicationId) - .subscribe((application: Application) => { - this.devices = application.iotDevices.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }); - } + getDatatarget(id: number) { + this.datatargetSubscription = this.datatargetService.get(id).subscribe((response: Datatarget) => { + this.datatarget = response; + }); + } - getPayloadDeviceDatatarget(id: number) { - this.relationSubscription = this.payloadDeviceDatatargetService - .getByDataTarget(id) - .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { - this.mapToDatatargetDevicePayload(response); - }); - } + getDevices(): void { + this.applicationSubscription = this.applicationService + .getApplication(this.applicationId) + .subscribe((application: Application) => { + this.devices = application.iotDevices.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }); + } - private mapToDatatargetDevicePayload( - dto: PayloadDeviceDatatargetGetByDataTargetResponse - ) { - this.payloadDeviceDatatarget = []; - dto.data.forEach((element) => { - this.payloadDeviceDatatarget.push({ - id: element.id, - iotDeviceIds: element.iotDevices.map((x) => x.id), - payloadDecoderId: - element.payloadDecoder?.id === undefined - ? 0 - : element.payloadDecoder?.id, - dataTargetId: element.dataTarget.id, - }); - }); - } + getPayloadDeviceDatatarget(id: number) { + this.relationSubscription = this.payloadDeviceDatatargetService + .getByDataTarget(id) + .subscribe((response: PayloadDeviceDatatargetGetByDataTargetResponse) => { + this.mapToDatatargetDevicePayload(response); + }); + } - public selectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map( - (device) => device.id - ); - } + private mapToDatatargetDevicePayload(dto: PayloadDeviceDatatargetGetByDataTargetResponse) { + this.payloadDeviceDatatarget = []; + dto.data.forEach(element => { + this.payloadDeviceDatatarget.push({ + id: element.id, + iotDeviceIds: element.iotDevices.map(x => x.id), + payloadDecoderId: element.payloadDecoder?.id === undefined ? 0 : element.payloadDecoder?.id, + dataTargetId: element.dataTarget.id, + }); + }); + } - public deselectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = []; - } + public selectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); + } - public addRow() { - if (!this.payloadDeviceDatatarget) { - this.payloadDeviceDatatarget = []; + public deselectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = []; } - this.payloadDeviceDatatarget.push({ - id: null, - iotDeviceIds: [], - payloadDecoderId: null, - dataTargetId: this.datatargetId, - }); - } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.payloadDeviceDatatargetService - .delete(this.payloadDeviceDatatarget[index].id) - .subscribe(() => { - this.payloadDeviceDatatarget.splice(index, 1); + public addRow() { + if (!this.payloadDeviceDatatarget) { + this.payloadDeviceDatatarget = []; + } + this.payloadDeviceDatatarget.push({ + id: null, + iotDeviceIds: [], + payloadDecoderId: null, + dataTargetId: this.datatargetId, }); } - } - openDeleteDialog(index) { - const dialog = this.dialog.open(DeleteDialogComponent, { - data: { - showAccept: true, - showCancel: true, - message: 'Er du sikker på at du vil slette?', - }, - }); - - dialog.afterClosed().subscribe((result) => { - if (result === true) { - this.deleteRow(index); - } - }); - } + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { + this.payloadDeviceDatatarget.splice(index, 1); + } else { + this.payloadDeviceDatatargetService.delete(this.payloadDeviceDatatarget[index].id).subscribe(() => { + this.payloadDeviceDatatarget.splice(index, 1); + }); + } + } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - this.activeApiCalls = 0; - } + openDeleteDialog(index) { + const dialog = this.dialog.open(DeleteDialogComponent, { + data: { + showAccept: true, + showCancel: true, + message: "Er du sikker på at du vil slette?", + }, + }); - onSubmit(): void { - this.resetErrors(); - if (this.datatargetId) { - this.updateDatatarget(); - this.addPayloadDeviceDatatarget(); - } else { - this.createDatatarget(); + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.deleteRow(index); + } + }); } - } - private updateDatatarget(): void { - this.activeApiCalls += 1; - this.datatargetService.update(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatarget = response; - this.countToRedirect(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } - - private createDatatarget(): void { - this.datatarget.applicationId = this.applicationId; - this.datatargetService.create(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatargetId = response.id; - this.datatarget = response; - this.snackService.showSavedSnack(); - this.routeToDatatargets(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; + this.activeApiCalls = 0; + } - private addPayloadDeviceDatatarget() { - this.payloadDeviceDatatarget.map((pdd) => { - if (pdd.payloadDecoderId === 0) { - pdd.payloadDecoderId = null; - } - }); - this.payloadDeviceDatatarget.forEach((relation) => { - this.activeApiCalls += 1; + onSubmit(): void { + this.resetErrors(); + if (this.datatargetId) { + this.updateDatatarget(); + this.addPayloadDeviceDatatarget(); + } else { + this.createDatatarget(); + } + } - if (relation.id) { - this.payloadDeviceDatatargetService.put(relation).subscribe( - () => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } + private updateDatatarget(): void { + this.activeApiCalls += 1; + this.datatargetService.update(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatarget = response; + this.countToRedirect(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } ); - } else { - this.payloadDeviceDatatargetService.post(relation).subscribe( - () => { - this.countToRedirect(); - }, - (error) => { - this.handleError(error); - } + } + + private createDatatarget(): void { + this.datatarget.applicationId = this.applicationId; + this.datatargetService.create(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatargetId = response.id; + this.datatarget = response; + this.snackService.showSavedSnack(); + this.routeToDatatargets(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + this.formFailedSubmit = true; + } ); - } - }); - } + } + + private addPayloadDeviceDatatarget() { + this.payloadDeviceDatatarget.map(pdd => { + if (pdd.payloadDecoderId === 0) { + pdd.payloadDecoderId = null; + } + }); + this.payloadDeviceDatatarget.forEach(relation => { + this.activeApiCalls += 1; - private countToRedirect() { - this.activeApiCalls -= 1; - if (this.activeApiCalls <= 0 && !this.formFailedSubmit) { - this.snackService.showSavedSnack(); - this.routeToDatatargets(); + if (relation.id) { + this.payloadDeviceDatatargetService.put(relation).subscribe( + () => { + this.countToRedirect(); + }, + error => { + this.handleError(error); + } + ); + } else { + this.payloadDeviceDatatargetService.post(relation).subscribe( + () => { + this.countToRedirect(); + }, + error => { + this.handleError(error); + } + ); + } + }); + } + + private countToRedirect() { + this.activeApiCalls -= 1; + if (this.activeApiCalls <= 0 && !this.formFailedSubmit) { + this.snackService.showSavedSnack(); + this.routeToDatatargets(); + } } - } - ngOnDestroy(): void { - this.relationSubscription?.unsubscribe(); - this.applicationSubscription?.unsubscribe(); - this.datatargetSubscription?.unsubscribe(); - this.payloadDecoderSubscription?.unsubscribe(); - } + ngOnDestroy(): void { + this.relationSubscription?.unsubscribe(); + this.applicationSubscription?.unsubscribe(); + this.datatargetSubscription?.unsubscribe(); + this.payloadDecoderSubscription?.unsubscribe(); + } } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts b/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts index 031f23095..e5cc11a06 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-dataset.model.ts @@ -1,11 +1,11 @@ export class OpenDataDkDataset { - id?: number; + id?: number; name: string; //reqired - max 120 resourceTitle: string; description: string; keywords: string[]; keywordsInput: string; - license = 'https://creativecommons.org/publicdomain/zero/1.0/'; + license = "https://creativecommons.org/publicdomain/zero/1.0/"; authorName: string; //required authorEmail: string; //reqired url: string; // autogenerated with orgid as input diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html index cfe1e7049..5c3df4464 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.html @@ -1,34 +1,34 @@

- {{ 'OPENDATADK.DETAILS.NAME' | translate }} - {{openDataDkDataset.name}} + {{ "OPENDATADK.DETAILS.NAME" | translate }} + {{ openDataDkDataset.name }}

- {{ 'OPENDATADK.DETAILS.RESOURCETITLE' | translate }} - {{openDataDkDataset.resourceTitle ? openDataDkDataset.resourceTitle : ('OPENDATADK.DETAILS.NA' | translate)}} + {{ "OPENDATADK.DETAILS.RESOURCETITLE" | translate }} + {{ openDataDkDataset.resourceTitle ? openDataDkDataset.resourceTitle : ("OPENDATADK.DETAILS.NA" | translate) }}

- {{ 'OPENDATADK.DETAILS.DESCRIPTION' | translate }} - {{openDataDkDataset.description ? openDataDkDataset.description : ('OPENDATADK.DETAILS.NA' | translate) }} + {{ "OPENDATADK.DETAILS.DESCRIPTION" | translate }} + {{ openDataDkDataset.description ? openDataDkDataset.description : ("OPENDATADK.DETAILS.NA" | translate) }}

- {{ 'OPENDATADK.DETAILS.KEYWORDS' | translate }} - {{openDataDkDataset.keywords ? openDataDkDataset.keywords : ('OPENDATADK.DETAILS.NA' | translate) }} + {{ "OPENDATADK.DETAILS.KEYWORDS" | translate }} + {{ openDataDkDataset.keywords ? openDataDkDataset.keywords : ("OPENDATADK.DETAILS.NA" | translate) }}

- {{ 'OPENDATADK.DETAILS.AUTHORNAME' | translate }} - {{openDataDkDataset.authorName}} + {{ "OPENDATADK.DETAILS.AUTHORNAME" | translate }} + {{ openDataDkDataset.authorName }}

- {{ 'OPENDATADK.DETAILS.AUTHOREMAIL' | translate }} - {{openDataDkDataset.authorEmail}} + {{ "OPENDATADK.DETAILS.AUTHOREMAIL" | translate }} + {{ openDataDkDataset.authorEmail }}

- {{ 'OPENDATADK.DETAILS.URL' | translate }} - {{openDataDkDataset.url}} -

\ No newline at end of file + {{ "OPENDATADK.DETAILS.URL" | translate }} + {{ openDataDkDataset.url }} +

diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.spec.ts b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.spec.ts index 5bec3c301..02ca10e7f 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.spec.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OpendatadkDetailComponent } from './opendatadk-detail.component'; +import { OpendatadkDetailComponent } from "./opendatadk-detail.component"; -describe('OpendatadkDetailComponent', () => { - let component: OpendatadkDetailComponent; - let fixture: ComponentFixture; +describe("OpendatadkDetailComponent", () => { + let component: OpendatadkDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OpendatadkDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OpendatadkDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OpendatadkDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OpendatadkDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.ts b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.ts index ca8bf7b5b..520b974b2 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-detail/opendatadk-detail.component.ts @@ -1,18 +1,15 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { OpenDataDkDataset } from '../opendatadk-dataset.model'; +import { Component, Input, OnInit } from "@angular/core"; +import { OpenDataDkDataset } from "../opendatadk-dataset.model"; @Component({ - selector: 'app-opendatadk-detail', - templateUrl: './opendatadk-detail.component.html', - styleUrls: ['./opendatadk-detail.component.scss'] + selector: "app-opendatadk-detail", + templateUrl: "./opendatadk-detail.component.html", + styleUrls: ["./opendatadk-detail.component.scss"], }) export class OpendatadkDetailComponent implements OnInit { + @Input() openDataDkDataset: OpenDataDkDataset; - @Input() openDataDkDataset: OpenDataDkDataset; - - constructor() { } - - ngOnInit(): void { - } + constructor() {} + ngOnInit(): void {} } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html index baaae5602..98351321b 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.html @@ -1,389 +1,368 @@ - +
-

{{'GUIDE' | translate}}

- - - +

{{ "GUIDE" | translate }}

+ + + +

+ {{ "OPENDATADK.INTRO.GUIDE_HEADER" | translate }} +

+
+

- {{ 'OPENDATADK.INTRO.GUIDE_HEADER' | translate }} + {{ "OPENDATADK.INTRO.GUIDE1" | translate }} +

+ {{ "OPENDATADK.INTRO.GUIDE2" | translate }} +

+ {{ "OPENDATADK.INTRO.GUIDE3" | translate }} +

+ {{ "OPENDATADK.INTRO.GUIDE4" | translate }} + {{ + "OPENDATADK.INTRO.GUIDE5" | translate + }} +

-
-
-

- {{ 'OPENDATADK.INTRO.GUIDE1' | translate }} -

- {{ 'OPENDATADK.INTRO.GUIDE2' | translate }} -

- {{ 'OPENDATADK.INTRO.GUIDE3' | translate }} -

- {{ 'OPENDATADK.INTRO.GUIDE4' | translate }} - {{ 'OPENDATADK.INTRO.GUIDE5' | translate }} -

-

-
- - - - -

- {{ 'OPENDATADK.INTRO.PROCEDURE_HEADER' | translate }} -

-
-
-
    -
  1. - {{ 'OPENDATADK.INTRO.PROCEDURE1' | translate }} - https://www.opendata.dk/ -

  2. -
  3. {{ 'OPENDATADK.INTRO.PROCEDURE2' | translate }}

  4. -
  5. {{ 'OPENDATADK.INTRO.PROCEDURE3' | translate }}

  6. -
  7. - {{ 'OPENDATADK.INTRO.PROCEDURE4' | translate }} - {{ 'OPENDATADK.INTRO.PROCEDURE4_LINK' | translate }} -

  8. -
-
+ + + + + +

+ {{ "OPENDATADK.INTRO.PROCEDURE_HEADER" | translate }} +

+
+
+
    +
  1. +

    + {{ "OPENDATADK.INTRO.PROCEDURE1" | translate }} + https://www.opendata.dk/ +

    +
  2. +
  3. +

    {{ "OPENDATADK.INTRO.PROCEDURE2" | translate }}

    +
  4. +
  5. +

    {{ "OPENDATADK.INTRO.PROCEDURE3" | translate }}

    +
  6. +
  7. +

    + {{ "OPENDATADK.INTRO.PROCEDURE4" | translate }} + {{ "OPENDATADK.INTRO.PROCEDURE4_LINK" | translate }} +

    +
  8. +
+
-
-

{{(datatargetId ? 'FORM.EDIT-DATATARGET' : 'FORM.CREATE-NEW-DATATARGET') | translate}}

+ +

{{ (datatargetId ? "FORM.EDIT-DATATARGET" : "FORM.CREATE-NEW-DATATARGET") | translate }}

-
-
    -
  • {{ error | translate }}
  • -
-
+
+
    +
  • {{ error | translate }}
  • +
+
- -
-
- - - - + +
+
+ + + + +
-
- -
-
- - - - + +
+
+ + + + +
-
- -
-
- - - - + +
+
+ + + + +
-
- -
-
- - + +
+
+ + +
-
- -
-
- - - - + +
+
+ + + + +
-
- -
-
- - + +
+
+ + +
-
- -
-
- - - {{kw}} - + +
+
+ + + {{ kw }} + +
-
- -
-
- -

- {{ 'OPENDATADK.QUESTION.ACCEPT-TERMS-PART-ONE' | translate }} - - {{ 'OPENDATADK.QUESTION.TERMS-AND-CONDITIONS' | translate }} - -

-
+ +
+
+ +

+ {{ "OPENDATADK.QUESTION.ACCEPT-TERMS-PART-ONE" | translate }} + + {{ "OPENDATADK.QUESTION.TERMS-AND-CONDITIONS" | translate }} + +

+
+
-
- -
{{ 'QUESTION.DATATARGET.RELATIONS' | translate }}
+ +
{{ "QUESTION.DATATARGET.RELATIONS" | translate }}
- - -
- - {{'QUESTION.ADD-RELATIONS' | translate}} - - - - - - - - - - -
-
- - {{'QUESTION.DATATARGET.SELECT-DEVICES' | translate}} - - - - - - {{ device.name }} - - -
-
-
- - {{ - 'QUESTION.DATATARGET.SELECT-PAYLOADDECODER' | translate - }} - - - {{ - 'QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED' - | translate - }} - - - {{ payloadDecoder.name }} - - - -
-
- -
- -

{{ 'DATATARGET.DELETE' | translate }}

-
-
-
-
-
+ + +
+ + {{ "QUESTION.ADD-RELATIONS" | translate }} + + + + + + + + + + +
+
+ + {{ "QUESTION.DATATARGET.SELECT-DEVICES" | translate }} + + + + + + {{ + device.name + }} + + +
+
+
+ + {{ "QUESTION.DATATARGET.SELECT-PAYLOADDECODER" | translate }} + + + {{ "QUESTION.DATATARGET.NO-PAYLOAD-DECODER-SELECTED" | translate }} + + + {{ payloadDecoder.name }} + + + +
+
+ +
+ +

{{ "DATATARGET.DELETE" | translate }}

+
+
+
+
+
- -
- - -
+ +
+ + +
diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss index 84d479e94..a35b9893b 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.scss @@ -1,22 +1,22 @@ -@import 'src/assets/scss/setup/fonts'; +@import "src/assets/scss/setup/fonts"; :host { - h3 { - border-bottom-width: 5px; - border-bottom-style: solid; - border-bottom-color: rgb(245, 122, 47); - width: fit-content; - padding-right: 12px; - } - .form-info-icon { - margin-left: 5px; - cursor: pointer; - } - mat-expansion-panel ol { - padding-left: 20px; - li { - font-family: $font-name, system; - display: list-item; + h3 { + border-bottom-width: 5px; + border-bottom-style: solid; + border-bottom-color: rgb(245, 122, 47); + width: fit-content; + padding-right: 12px; + } + .form-info-icon { + margin-left: 5px; + cursor: pointer; + } + mat-expansion-panel ol { + padding-left: 20px; + li { + font-family: $font-name, system; + display: list-item; + } } - } } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.spec.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.spec.ts index dbecd5a55..11ad7f687 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.spec.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OpendatadkEditComponent } from './opendatadk-edit.component'; +import { OpendatadkEditComponent } from "./opendatadk-edit.component"; -describe('OpendatadkEditComponent', () => { - let component: OpendatadkEditComponent; - let fixture: ComponentFixture; +describe("OpendatadkEditComponent", () => { + let component: OpendatadkEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OpendatadkEditComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OpendatadkEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OpendatadkEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OpendatadkEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts index a51ddf462..c5a78eba6 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-edit.component.ts @@ -1,406 +1,382 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnDestroy } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Application } from '@applications/application.model'; -import { ApplicationService } from '@applications/application.service'; -import { DatatargetEdit } from '@applications/datatarget/datatarget-edit/datatarget-edit'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnDestroy } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { ActivatedRoute, Router } from "@angular/router"; +import { Application } from "@applications/application.model"; +import { ApplicationService } from "@applications/application.service"; +import { DatatargetEdit } from "@applications/datatarget/datatarget-edit/datatarget-edit"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { faQuestionCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons"; +import { TranslateService } from "@ngx-translate/core"; +import { PayloadDecoderMappedResponse } from "@payload-decoder/payload-decoder.model"; +import { PayloadDecoderService } from "@payload-decoder/payload-decoder.service"; import { - faQuestionCircle, - faTimesCircle, -} from '@fortawesome/free-solid-svg-icons'; -import { TranslateService } from '@ngx-translate/core'; -import { PayloadDecoderMappedResponse } from '@payload-decoder/payload-decoder.model'; -import { PayloadDecoderService } from '@payload-decoder/payload-decoder.service'; -import { - PayloadDeviceDatatarget, - PayloadDeviceDatatargetGetByDataTargetResponse, -} from '@payload-decoder/payload-device-data.model'; -import { PayloadDeviceDatatargetService } from '@payload-decoder/payload-device-datatarget.service'; -import { DeleteDialogComponent } from '@shared/components/delete-dialog/delete-dialog.component'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DataTargetType } from '@shared/enums/datatarget-type'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { MeService } from '@shared/services/me.service'; -import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { SnackService } from '@shared/services/snack.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { first } from 'rxjs/operators'; -import { Datatarget, OddkMailInfo } from '../../datatarget.model'; -import { DatatargetService } from '../../datatarget.service'; -import { OpenDataDkDataset } from '../../opendatadk/opendatadk-dataset.model'; -import { OpenDataDkMailDialogComponent } from './opendatadk-mail-dialog/opendatadk-mail-dialog'; -import { OpenDataDkWarningDialogComponent } from './opendatadk-warning-dialog/opendatadk-warning-dialog'; + PayloadDeviceDatatarget, + PayloadDeviceDatatargetGetByDataTargetResponse, +} from "@payload-decoder/payload-device-data.model"; +import { PayloadDeviceDatatargetService } from "@payload-decoder/payload-device-datatarget.service"; +import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DataTargetType } from "@shared/enums/datatarget-type"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { MeService } from "@shared/services/me.service"; +import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; +import { SnackService } from "@shared/services/snack.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { first } from "rxjs/operators"; +import { Datatarget, OddkMailInfo } from "../../datatarget.model"; +import { DatatargetService } from "../../datatarget.service"; +import { OpenDataDkDataset } from "../../opendatadk/opendatadk-dataset.model"; +import { OpenDataDkMailDialogComponent } from "./opendatadk-mail-dialog/opendatadk-mail-dialog"; +import { OpenDataDkWarningDialogComponent } from "./opendatadk-warning-dialog/opendatadk-warning-dialog"; @Component({ - selector: 'app-opendatadk-edit', - templateUrl: './opendatadk-edit.component.html', - styleUrls: ['./opendatadk-edit.component.scss'], + selector: "app-opendatadk-edit", + templateUrl: "./opendatadk-edit.component.html", + styleUrls: ["./opendatadk-edit.component.scss"], }) export class OpendatadkEditComponent implements DatatargetEdit, OnDestroy { - faQuestionCircle = faQuestionCircle; - faTimesCircle = faTimesCircle; + faQuestionCircle = faQuestionCircle; + faTimesCircle = faTimesCircle; - title = 'FORM.CREATE-NEW-DATATARGET'; + title = "FORM.CREATE-NEW-DATATARGET"; - selectableKeyword = [ - 'Befolkning og samfund', - 'Energi', - 'Internationale spørgsmål', - 'Landbrug, fiskeri, skovbrug og fødevarer', - 'Midlertidige data', - 'Miljø', - 'Regeringen og den offentlige sektor', - 'Regioner og byer', - 'Retfærdighed, retssystem og offentlig sikkerhed', - 'Sundhed', - 'Transport', - 'Uddannelse, kultur og sport', - 'Videnskab og teknologi', - 'Økonomi og finanser', - ]; + selectableKeyword = [ + "Befolkning og samfund", + "Energi", + "Internationale spørgsmål", + "Landbrug, fiskeri, skovbrug og fødevarer", + "Midlertidige data", + "Miljø", + "Regeringen og den offentlige sektor", + "Regioner og byer", + "Retfærdighed, retssystem og offentlig sikkerhed", + "Sundhed", + "Transport", + "Uddannelse, kultur og sport", + "Videnskab og teknologi", + "Økonomi og finanser", + ]; - errorMessages: any[]; - errorFields: string[]; + errorMessages: any[]; + errorFields: string[]; - datatarget: Datatarget = new Datatarget(); - private subscriptions = []; + datatarget: Datatarget = new Datatarget(); + private subscriptions = []; - formFailedSubmit = false; - datatargetId: number; - private applicationId: number; - devices: IotDevice[]; - payloadDecoders = []; - private pendingRequestsCounter: number; + formFailedSubmit = false; + datatargetId: number; + private applicationId: number; + devices: IotDevice[]; + payloadDecoders = []; + private pendingRequestsCounter: number; - payloadDeviceDatatarget: PayloadDeviceDatatarget[]; - canEdit: boolean; + payloadDeviceDatatarget: PayloadDeviceDatatarget[]; + canEdit: boolean; - private alreadySentOddkMail: boolean = false; + private alreadySentOddkMail: boolean = false; - constructor( - translate: TranslateService, - private route: ActivatedRoute, - private router: Router, - private datatargetService: DatatargetService, - private applicationService: ApplicationService, - private payloadDecoderService: PayloadDecoderService, - private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, - private saveSnackService: SnackService, - private dialog: MatDialog, - private errorMessageService: ErrorMessageService, - private scrollToTopService: ScrollToTopService, - private meService: MeService, - private sharedVariableService: SharedVariableService - ) { - translate.use('da'); + constructor( + translate: TranslateService, + private route: ActivatedRoute, + private router: Router, + private datatargetService: DatatargetService, + private applicationService: ApplicationService, + private payloadDecoderService: PayloadDecoderService, + private payloadDeviceDataTargetService: PayloadDeviceDatatargetService, + private saveSnackService: SnackService, + private dialog: MatDialog, + private errorMessageService: ErrorMessageService, + private scrollToTopService: ScrollToTopService, + private meService: MeService, + private sharedVariableService: SharedVariableService + ) { + translate.use("da"); - this.datatarget.type = DataTargetType.OPENDATADK; - this.datatarget.setToOpendataDk = true; + this.datatarget.type = DataTargetType.OPENDATADK; + this.datatarget.setToOpendataDk = true; - this.datatargetId = +this.route.snapshot.paramMap.get('datatargetId'); - this.applicationId = +this.route.snapshot.paramMap.get('id'); - if (this.applicationId !== 0) { - this.getDevices(); - this.getPayloadDecoders(); - } - if (this.datatargetId !== 0) { - this.title = 'FORM.EDIT-DATATARGET'; - this.getDatatarget(this.datatargetId); - this.getPayloadDeviceDatatarget(this.datatargetId); + this.datatargetId = +this.route.snapshot.paramMap.get("datatargetId"); + this.applicationId = +this.route.snapshot.paramMap.get("id"); + if (this.applicationId !== 0) { + this.getDevices(); + this.getPayloadDecoders(); + } + if (this.datatargetId !== 0) { + this.title = "FORM.EDIT-DATATARGET"; + this.getDatatarget(this.datatargetId); + this.getPayloadDeviceDatatarget(this.datatargetId); + } + this.getAlreadySentOddkMail(); + + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + this.applicationId + ); } - this.getAlreadySentOddkMail(); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - this.applicationId - ); - } + ngOnDestroy(): void { + this.subscriptions.forEach(s => s?.unsubscribe()); + } - ngOnDestroy(): void { - this.subscriptions.forEach((s) => s?.unsubscribe()); - } + private getPayloadDeviceDatatarget(id: number) { + this.subscriptions.push( + this.payloadDeviceDataTargetService + .getByDataTarget(id) + .subscribe((dto: PayloadDeviceDatatargetGetByDataTargetResponse) => { + this.payloadDeviceDatatarget = []; + dto.data.forEach(element => { + this.payloadDeviceDatatarget.push({ + id: element.id, + iotDeviceIds: element.iotDevices.map(x => x.id), + payloadDecoderId: element.payloadDecoder?.id === undefined ? 0 : element.payloadDecoder?.id, + dataTargetId: element.dataTarget.id, + }); + }); + }) + ); + } - private getPayloadDeviceDatatarget(id: number) { - this.subscriptions.push( - this.payloadDeviceDataTargetService - .getByDataTarget(id) - .subscribe((dto: PayloadDeviceDatatargetGetByDataTargetResponse) => { - this.payloadDeviceDatatarget = []; - dto.data.forEach((element) => { - this.payloadDeviceDatatarget.push({ - id: element.id, - iotDeviceIds: element.iotDevices.map((x) => x.id), - payloadDecoderId: - element.payloadDecoder?.id === undefined - ? 0 - : element.payloadDecoder?.id, - dataTargetId: element.dataTarget.id, - }); - }); - }) - ); - } + private getDatatarget(id: number) { + this.subscriptions.push( + this.datatargetService.get(id).subscribe((response: Datatarget) => { + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + }) + ); + } - private getDatatarget(id: number) { - this.subscriptions.push( - this.datatargetService.get(id).subscribe((response: Datatarget) => { - this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; + onSubmit(): void { + this.resetErrors(); + if (this.datatargetId) { + if (!this.validatePayloadDeviceDatatarget()) return; + this.pendingRequestsCounter = 1 + (this.payloadDeviceDatatarget?.length ?? 0); + this.updateDatatarget(); + this.addPayloadDeviceDatatarget(); + } else { + this.createDatatarget(); } - }) - ); - } - - onSubmit(): void { - this.resetErrors(); - if (this.datatargetId) { - if (!this.validatePayloadDeviceDatatarget()) return; - this.pendingRequestsCounter = - 1 + (this.payloadDeviceDatatarget?.length ?? 0); - this.updateDatatarget(); - this.addPayloadDeviceDatatarget(); - } else { - this.createDatatarget(); } - } - private updateDatatarget() { - this.subscriptions.push( - this.datatargetService.update(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; - } - this.countToRedirect(); - }, - (error: HttpErrorResponse) => { - this.checkDataTargetModelOpendatadkdatasaet(); - this.handleError(error); - this.formFailedSubmit = true; - } - ) - ); - } - private addPayloadDeviceDatatarget() { - this.payloadDeviceDatatarget.forEach((relation) => { - if (relation.payloadDecoderId === 0) { - relation.payloadDecoderId = null; - } - if (relation.id) { + private updateDatatarget() { this.subscriptions.push( - this.payloadDeviceDataTargetService.put(relation).subscribe( - () => this.countToRedirect(), - (error) => this.handleError(error) - ) + this.datatargetService.update(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + this.countToRedirect(); + }, + (error: HttpErrorResponse) => { + this.checkDataTargetModelOpendatadkdatasaet(); + this.handleError(error); + this.formFailedSubmit = true; + } + ) ); - } else { + } + private addPayloadDeviceDatatarget() { + this.payloadDeviceDatatarget.forEach(relation => { + if (relation.payloadDecoderId === 0) { + relation.payloadDecoderId = null; + } + if (relation.id) { + this.subscriptions.push( + this.payloadDeviceDataTargetService.put(relation).subscribe( + () => this.countToRedirect(), + error => this.handleError(error) + ) + ); + } else { + this.subscriptions.push( + this.payloadDeviceDataTargetService.post(relation).subscribe( + () => this.countToRedirect(), + error => this.handleError(error) + ) + ); + } + }); + } + private validatePayloadDeviceDatatarget = () => { + const isError = this.payloadDeviceDatatarget?.some(relation => (relation.iotDeviceIds?.length ?? 0) < 1); + if (isError) { + this.errorFields = ["devices"]; + this.errorMessages = ["Must attach at least one IoT-device for each element in list of devices / decoders"]; + this.scrollToTopService.scrollToTop(); + } + return !isError; + }; + private createDatatarget() { + this.pendingRequestsCounter = 0; + this.datatarget.applicationId = this.applicationId; this.subscriptions.push( - this.payloadDeviceDataTargetService.post(relation).subscribe( - () => this.countToRedirect(), - (error) => this.handleError(error) - ) + this.datatargetService.create(this.datatarget).subscribe( + (response: Datatarget) => { + this.datatargetId = response.id; + this.datatarget = response; + if (this.datatarget.openDataDkDataset != null) { + this.datatarget.openDataDkDataset.acceptTerms = true; + } + this.saveSnackService.showSavedSnack(); + this.showMailOrRedirect(); + }, + (error: HttpErrorResponse) => { + this.checkDataTargetModelOpendatadkdatasaet(); + this.handleError(error); + this.formFailedSubmit = true; + } + ) ); - } - }); - } - private validatePayloadDeviceDatatarget = () => { - const isError = this.payloadDeviceDatatarget?.some( - (relation) => (relation.iotDeviceIds?.length ?? 0) < 1 - ); - if (isError) { - this.errorFields = ['devices']; - this.errorMessages = [ - 'Must attach at least one IoT-device for each element in list of devices / decoders', - ]; - this.scrollToTopService.scrollToTop(); } - return !isError; - }; - private createDatatarget() { - this.pendingRequestsCounter = 0; - this.datatarget.applicationId = this.applicationId; - this.subscriptions.push( - this.datatargetService.create(this.datatarget).subscribe( - (response: Datatarget) => { - this.datatargetId = response.id; - this.datatarget = response; - if (this.datatarget.openDataDkDataset != null) { - this.datatarget.openDataDkDataset.acceptTerms = true; - } - this.saveSnackService.showSavedSnack(); - this.showMailOrRedirect(); - }, - (error: HttpErrorResponse) => { - this.checkDataTargetModelOpendatadkdatasaet(); - this.handleError(error); - this.formFailedSubmit = true; + private showMailOrRedirect = () => { + if (!this.alreadySentOddkMail) { + this.openMailDialog(); + } else { + this.routeToCreatedDatatarget(); } - ) - ); - } - private showMailOrRedirect = () => { - if (!this.alreadySentOddkMail) { - this.openMailDialog(); - } else { - this.routeToCreatedDatatarget(); + }; + // Note: When updating, we send multiple async request, and use this counter to know when everything is done, so we can redirect + private countToRedirect() { + this.pendingRequestsCounter -= 1; + if (this.pendingRequestsCounter <= 0 && !this.formFailedSubmit) { + this.saveSnackService.showSavedSnack(); + this.showMailOrRedirect(); + } + } + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; } - }; - // Note: When updating, we send multiple async request, and use this counter to know when everything is done, so we can redirect - private countToRedirect() { - this.pendingRequestsCounter -= 1; - if (this.pendingRequestsCounter <= 0 && !this.formFailedSubmit) { - this.saveSnackService.showSavedSnack(); - this.showMailOrRedirect(); + private checkDataTargetModelOpendatadkdatasaet() { + this.datatarget.setToOpendataDk = true; + if (!this.datatarget.openDataDkDataset) { + this.datatarget.openDataDkDataset = new OpenDataDkDataset(); + } } - } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } - private checkDataTargetModelOpendatadkdatasaet() { - this.datatarget.setToOpendataDk = true; - if (!this.datatarget.openDataDkDataset) { - this.datatarget.openDataDkDataset = new OpenDataDkDataset(); + private handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); } - } - private handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - this.scrollToTopService.scrollToTop(); - } - routeToDatatargets = () => this.router.navigate(['applications', this.applicationId, 'data-targets']); - routeToCreatedDatatarget = () => - this.router.navigate( - ['applications', this.applicationId, 'datatarget', this.datatarget.id], - { replaceUrl: true } - ); + routeToDatatargets = () => this.router.navigate(["applications", this.applicationId, "data-targets"]); + routeToCreatedDatatarget = () => + this.router.navigate(["applications", this.applicationId, "datatarget", this.datatarget.id], { + replaceUrl: true, + }); - // For mail dialog - private getAlreadySentOddkMail = () => { - const orgId = this.sharedVariableService.getSelectedOrganisationId(); - this.subscriptions.push( - this.datatargetService - .getOpenDataDkRegistered(orgId) - .subscribe((response) => { - this.alreadySentOddkMail = !!response; - }) - ); - }; - private setAlreadySentOddkMail = async () => { - const orgId = this.sharedVariableService.getSelectedOrganisationId(); - await this.datatargetService - .updateOpenDataDkRegistered(orgId) - .pipe(first()) - .toPromise(); - }; - private openMailDialog = () => { - const dialog = this.dialog.open(OpenDataDkMailDialogComponent); - dialog.afterClosed().subscribe(async (result: OddkMailInfo) => { - if (result) { - // User accepted -> Send mail and continue - await this.datatargetService - .sendOpenDataDkMail(result) - .pipe(first()) - .toPromise(); - this.routeToCreatedDatatarget(); - } else { - // User cancelled -> Show the warning - this.openMailWarningDialog(); - } - }); - }; - private openMailWarningDialog = () => { - const dialog = this.dialog.open(OpenDataDkWarningDialogComponent); - dialog.afterClosed().subscribe(async (result) => { - if (result) { - // User accepted -> Save if 'never again' was checked, then continue - if (result.neverAgain) { - await this.setAlreadySentOddkMail(); - } - this.routeToCreatedDatatarget(); - } else { - // User cancelled -> Show the mail-dialog again - this.openMailDialog(); - } - }); - }; + // For mail dialog + private getAlreadySentOddkMail = () => { + const orgId = this.sharedVariableService.getSelectedOrganisationId(); + this.subscriptions.push( + this.datatargetService.getOpenDataDkRegistered(orgId).subscribe(response => { + this.alreadySentOddkMail = !!response; + }) + ); + }; + private setAlreadySentOddkMail = async () => { + const orgId = this.sharedVariableService.getSelectedOrganisationId(); + await this.datatargetService.updateOpenDataDkRegistered(orgId).pipe(first()).toPromise(); + }; + private openMailDialog = () => { + const dialog = this.dialog.open(OpenDataDkMailDialogComponent); + dialog.afterClosed().subscribe(async (result: OddkMailInfo) => { + if (result) { + // User accepted -> Send mail and continue + await this.datatargetService.sendOpenDataDkMail(result).pipe(first()).toPromise(); + this.routeToCreatedDatatarget(); + } else { + // User cancelled -> Show the warning + this.openMailWarningDialog(); + } + }); + }; + private openMailWarningDialog = () => { + const dialog = this.dialog.open(OpenDataDkWarningDialogComponent); + dialog.afterClosed().subscribe(async result => { + if (result) { + // User accepted -> Save if 'never again' was checked, then continue + if (result.neverAgain) { + await this.setAlreadySentOddkMail(); + } + this.routeToCreatedDatatarget(); + } else { + // User cancelled -> Show the mail-dialog again + this.openMailDialog(); + } + }); + }; - // For list of devices / payload-decoders - private getDevices(): void { - this.subscriptions.push( - this.applicationService - .getApplication(this.applicationId) - .subscribe((application: Application) => { - this.devices = application.iotDevices.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }) - ); - } - private getPayloadDecoders() { - this.subscriptions.push( - this.payloadDecoderService - .getMultiple(1000, 0, 'id', 'ASC') - .subscribe((response: PayloadDecoderMappedResponse) => { - this.payloadDecoders = response.data.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - }) - ); - } - addRow() { - if (!this.payloadDeviceDatatarget) { - this.payloadDeviceDatatarget = []; + // For list of devices / payload-decoders + private getDevices(): void { + this.subscriptions.push( + this.applicationService.getApplication(this.applicationId).subscribe((application: Application) => { + this.devices = application.iotDevices.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }) + ); } - this.payloadDeviceDatatarget.push({ - id: null, - iotDeviceIds: [], - payloadDecoderId: null, - dataTargetId: this.datatargetId, - }); - } - private deleteRow(index) { - if (this.payloadDeviceDatatarget.length === 0) { - } else if (this.payloadDeviceDatatarget[index]?.id === null) { - this.payloadDeviceDatatarget.splice(index, 1); - } else { - this.subscriptions.push( - this.payloadDeviceDataTargetService - .delete(this.payloadDeviceDatatarget[index].id) - .subscribe((response) => { + private getPayloadDecoders() { + this.subscriptions.push( + this.payloadDecoderService + .getMultiple(1000, 0, "id", "ASC") + .subscribe((response: PayloadDecoderMappedResponse) => { + this.payloadDecoders = response.data.sort((a, b) => + a.name.localeCompare(b.name, "en", { numeric: true }) + ); + }) + ); + } + addRow() { + if (!this.payloadDeviceDatatarget) { + this.payloadDeviceDatatarget = []; + } + this.payloadDeviceDatatarget.push({ + id: null, + iotDeviceIds: [], + payloadDecoderId: null, + dataTargetId: this.datatargetId, + }); + } + private deleteRow(index) { + if (this.payloadDeviceDatatarget.length === 0) { + } else if (this.payloadDeviceDatatarget[index]?.id === null) { this.payloadDeviceDatatarget.splice(index, 1); - }) - ); + } else { + this.subscriptions.push( + this.payloadDeviceDataTargetService + .delete(this.payloadDeviceDatatarget[index].id) + .subscribe(response => { + this.payloadDeviceDatatarget.splice(index, 1); + }) + ); + } + } + openDeleteDialog(index) { + const dialog = this.dialog.open(DeleteDialogComponent, { + data: { + showAccept: true, + showCancel: true, + message: "Er du sikker på at du vil slette?", + }, + }); + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.deleteRow(index); + } + }); + } + payloadDevicesDropdownCompare = (o1: any, o2: any): boolean => o1 === o2; + selectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map(device => device.id); + } + deSelectAllDevices(index: number) { + this.payloadDeviceDatatarget[index].iotDeviceIds = []; } - } - openDeleteDialog(index) { - const dialog = this.dialog.open(DeleteDialogComponent, { - data: { - showAccept: true, - showCancel: true, - message: 'Er du sikker på at du vil slette?', - }, - }); - dialog.afterClosed().subscribe((result) => { - if (result === true) { - this.deleteRow(index); - } - }); - } - payloadDevicesDropdownCompare = (o1: any, o2: any): boolean => o1 === o2; - selectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = this.devices.map( - (device) => device.id - ); - } - deSelectAllDevices(index: number) { - this.payloadDeviceDatatarget[index].iotDeviceIds = []; - } } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html index 3a60ee7ab..338a1535f 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.html @@ -1,9 +1,9 @@

{{'OPENDATADK.MAIL.DIALOG_TITLE' | translate}}

- {{'OPENDATADK.MAIL.DIALOG_TEXT1' | translate}} - {{selectedOrganizationName ?? ('OPENDATADK.MAIL.SELECTED_ORG_FALLBACK' | translate)}}{{'OPENDATADK.MAIL.DIALOG_TEXT2' | translate}} -

+ {{'OPENDATADK.MAIL.DIALOG_TEXT1' | translate}} {{selectedOrganizationName ?? + ('OPENDATADK.MAIL.SELECTED_ORG_FALLBACK' | translate)}}{{'OPENDATADK.MAIL.DIALOG_TEXT2' | translate}} +

@@ -11,9 +11,15 @@

{{'OPENDATADK.MAIL.DIALOG_TITLE' | translate}}

- +
@@ -21,9 +27,13 @@

{{'OPENDATADK.MAIL.DIALOG_TITLE' | translate}}

- + [(ngModel)]="commentInput" + />
@@ -31,7 +41,5 @@

{{'OPENDATADK.MAIL.DIALOG_TITLE' | translate}}

- -
\ No newline at end of file + +
diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts index 6eb667ffe..9691d149c 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-mail-dialog/opendatadk-mail-dialog.ts @@ -1,38 +1,38 @@ -import { Component } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; -import { OddkMailInfo } from '@applications/datatarget/datatarget.model'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; +import { Component } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; +import { OddkMailInfo } from "@applications/datatarget/datatarget.model"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; @Component({ - selector: 'app-opendatadk-mail-dialog', - templateUrl: './opendatadk-mail-dialog.html', - styleUrls: ['./opendatadk-mail-dialog.scss'], + selector: "app-opendatadk-mail-dialog", + templateUrl: "./opendatadk-mail-dialog.html", + styleUrls: ["./opendatadk-mail-dialog.scss"], }) export class OpenDataDkMailDialogComponent { - sendAttempted: boolean = false; - organizationInput: string = ''; - commentInput: string = ''; + sendAttempted: boolean = false; + organizationInput: string = ""; + commentInput: string = ""; - selectedOrganizationName: string; + selectedOrganizationName: string; - constructor( - public dialog: MatDialogRef, - private sharedVariableService: SharedVariableService - ) { - const selectedOrganisationId = sharedVariableService.getSelectedOrganisationId(); - this.selectedOrganizationName = sharedVariableService - .getOrganizationInfo() - ?.find((o) => o.id === selectedOrganisationId)?.name; - } + constructor( + public dialog: MatDialogRef, + private sharedVariableService: SharedVariableService + ) { + const selectedOrganisationId = sharedVariableService.getSelectedOrganisationId(); + this.selectedOrganizationName = sharedVariableService + .getOrganizationInfo() + ?.find(o => o.id === selectedOrganisationId)?.name; + } - send() { - this.sendAttempted = true; - if (this.organizationInput) { - this.dialog.close({ - organizationId: this.sharedVariableService.getSelectedOrganisationId(), - organizationOddkAlias: this.organizationInput, - comment: this.commentInput || undefined, - }); + send() { + this.sendAttempted = true; + if (this.organizationInput) { + this.dialog.close({ + organizationId: this.sharedVariableService.getSelectedOrganisationId(), + organizationOddkAlias: this.organizationInput, + comment: this.commentInput || undefined, + }); + } } - } } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html index 698444655..46f142e92 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.html @@ -2,23 +2,16 @@

{{'OPENDATADK.MAIL.WARNING' | translate}}

{{'OPENDATADK.MAIL.WARNING-TEXT' | translate}} -
+

- - {{ 'OPENDATADK.MAIL.NEVER-AGAIN' | translate }} - + {{ 'OPENDATADK.MAIL.NEVER-AGAIN' | translate }}
-
- - -
\ No newline at end of file + + +
diff --git a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts index a79b5fd1d..5e998ab6e 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk-edit/opendatadk-warning-dialog/opendatadk-warning-dialog.ts @@ -1,17 +1,17 @@ -import { Component } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; +import { Component } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; @Component({ - selector: 'app-opendatadk-warning-dialog', - templateUrl: './opendatadk-warning-dialog.html', - styleUrls: ['./opendatadk-warning-dialog.scss'], + selector: "app-opendatadk-warning-dialog", + templateUrl: "./opendatadk-warning-dialog.html", + styleUrls: ["./opendatadk-warning-dialog.scss"], }) export class OpenDataDkWarningDialogComponent { - neverAgain: boolean = false; + neverAgain: boolean = false; - constructor(public dialog: MatDialogRef) {} + constructor(public dialog: MatDialogRef) {} - ok() { - this.dialog.close({ neverAgain: this.neverAgain }); - } + ok() { + this.dialog.close({ neverAgain: this.neverAgain }); + } } diff --git a/src/app/applications/datatarget/opendatadk/opendatadk.component.spec.ts b/src/app/applications/datatarget/opendatadk/opendatadk.component.spec.ts index 5c4c4e9f4..4a723bc15 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk.component.spec.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { OpendatadkComponent } from './opendatadk.component'; +import { OpendatadkComponent } from "./opendatadk.component"; -describe('OpendatadkComponent', () => { - let component: OpendatadkComponent; - let fixture: ComponentFixture; +describe("OpendatadkComponent", () => { + let component: OpendatadkComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ OpendatadkComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [OpendatadkComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(OpendatadkComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(OpendatadkComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/datatarget/opendatadk/opendatadk.component.ts b/src/app/applications/datatarget/opendatadk/opendatadk.component.ts index 08eb8ea97..9016d569f 100644 --- a/src/app/applications/datatarget/opendatadk/opendatadk.component.ts +++ b/src/app/applications/datatarget/opendatadk/opendatadk.component.ts @@ -1,15 +1,12 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-opendatadk', - templateUrl: './opendatadk.component.html', - styleUrls: ['./opendatadk.component.scss'] + selector: "app-opendatadk", + templateUrl: "./opendatadk.component.html", + styleUrls: ["./opendatadk.component.scss"], }) export class OpendatadkComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit(): void { - } - + ngOnInit(): void {} } diff --git a/src/app/applications/iot-devices/downlink.model.ts b/src/app/applications/iot-devices/downlink.model.ts index b5ed50358..d3bb0a396 100644 --- a/src/app/applications/iot-devices/downlink.model.ts +++ b/src/app/applications/iot-devices/downlink.model.ts @@ -1,5 +1,5 @@ export class Downlink { - data: string; - port = 0; - confirmedDownlink? = false; + data: string; + port = 0; + confirmedDownlink? = false; } diff --git a/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.html b/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.html index 0e5de9d5b..69b325443 100644 --- a/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.html @@ -2,20 +2,20 @@

- {{'IOTDEVICE.LATEST-DATAPACKAGE' | translate}} + {{ "IOTDEVICE.LATEST-DATAPACKAGE" | translate }} - {{latestReceivedMessage.sentTime | tableDateWithSecondsPipe}} + {{ latestReceivedMessage.sentTime | tableDateWithSecondsPipe }}

-
{{latestReceivedMessage.rawData | json }}
-
+
{{ latestReceivedMessage.rawData | json }}
+

- {{'IOTDEVICE.NO-DATAPACKAGE' | translate}} + {{ "IOTDEVICE.NO-DATAPACKAGE" | translate }}

diff --git a/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.spec.ts b/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.spec.ts index b63cf2899..447e216d5 100644 --- a/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.spec.ts +++ b/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DataPackageComponent } from './data-package.component'; +import { DataPackageComponent } from "./data-package.component"; -describe('DataPackageComponent', () => { - let component: DataPackageComponent; - let fixture: ComponentFixture; +describe("DataPackageComponent", () => { + let component: DataPackageComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DataPackageComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DataPackageComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DataPackageComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DataPackageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.ts b/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.ts index 1f9a84540..7e83d373b 100644 --- a/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/data-package/data-package.component.ts @@ -1,17 +1,15 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { LatestReceivedMessage } from '@applications/iot-devices/latestReceivedMessage.model'; +import { Component, Input, OnInit } from "@angular/core"; +import { LatestReceivedMessage } from "@applications/iot-devices/latestReceivedMessage.model"; @Component({ - selector: 'app-data-package', - templateUrl: './data-package.component.html', - styleUrls: ['./data-package.component.scss'] + selector: "app-data-package", + templateUrl: "./data-package.component.html", + styleUrls: ["./data-package.component.scss"], }) export class DataPackageComponent implements OnInit { - @Input() latestReceivedMessage: LatestReceivedMessage; + @Input() latestReceivedMessage: LatestReceivedMessage; - constructor() { } - - ngOnInit(): void { - } + constructor() {} + ngOnInit(): void {} } diff --git a/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.html b/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.html index 17f2037ce..a432c9267 100644 --- a/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.html @@ -1,27 +1,21 @@ - - -

- {{ 'IOTDEVICE.LATEST-DATAPACKAGES' | translate }} -

-
-
-
-
-

- {{ i + 1 }} -

+ + +

+ {{ "IOTDEVICE.LATEST-DATAPACKAGES" | translate }} +

+
+
+
+
+

+ {{ i + 1 }} +

+
+
+

+ {{ metadata.sentTime | tableDateWithSecondsPipe }} +

+
-
-

- {{ metadata.sentTime | tableDateWithSecondsPipe }} -

-
-
diff --git a/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.scss b/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.scss index 618f3711a..ee885460e 100644 --- a/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.scss +++ b/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.scss @@ -1,4 +1,3 @@ .timestamps-container { - display: flex; + display: flex; } - diff --git a/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.ts b/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.ts index 708d1334d..da045b3ea 100644 --- a/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/data-packages-timestamp/data-packages-timestamp.component.ts @@ -1,35 +1,22 @@ -import { - Component, - Input, - OnChanges, - OnInit, - SimpleChanges, -} from '@angular/core'; -import { sortBy } from '@shared/helpers/array.helper'; -import { ReceivedMessageMetadata } from '@shared/models/received-message-metadata.model'; +import { Component, Input, OnChanges, OnInit, SimpleChanges } from "@angular/core"; +import { sortBy } from "@shared/helpers/array.helper"; +import { ReceivedMessageMetadata } from "@shared/models/received-message-metadata.model"; @Component({ - selector: 'app-data-packages-timestamp', - templateUrl: './data-packages-timestamp.component.html', - styleUrls: ['./data-packages-timestamp.component.scss'], + selector: "app-data-packages-timestamp", + templateUrl: "./data-packages-timestamp.component.html", + styleUrls: ["./data-packages-timestamp.component.scss"], }) export class DataPackagesTimestampComponent implements OnInit, OnChanges { - @Input() receivedMessagesMetadata: ReceivedMessageMetadata[] = []; - sortedMetadata: ReceivedMessageMetadata[] = []; + @Input() receivedMessagesMetadata: ReceivedMessageMetadata[] = []; + sortedMetadata: ReceivedMessageMetadata[] = []; - ngOnInit(): void {} + ngOnInit(): void {} - ngOnChanges(changes: SimpleChanges): void { - const { receivedMessagesMetadata } = changes; - if ( - receivedMessagesMetadata.currentValue !== - receivedMessagesMetadata.previousValue - ) { - this.sortedMetadata = sortBy( - receivedMessagesMetadata.currentValue, - 'sentTime', - 'desc' - ); + ngOnChanges(changes: SimpleChanges): void { + const { receivedMessagesMetadata } = changes; + if (receivedMessagesMetadata.currentValue !== receivedMessagesMetadata.previousValue) { + this.sortedMetadata = sortBy(receivedMessagesMetadata.currentValue, "sentTime", "desc"); + } } - } } diff --git a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.html b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.html index 9bbc3d610..167054794 100644 --- a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.html @@ -1,7 +1,12 @@ -

{{ 'IOTDEVICE.DEVICEMODEL' | translate }}

- +

{{ "IOTDEVICE.DEVICEMODEL" | translate }}

+ -

{{ 'IOTDEVICE.DEVICEMODEL-ERROR' | translate }}

-
\ No newline at end of file +

{{ "IOTDEVICE.DEVICEMODEL-ERROR" | translate }}

+ diff --git a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.scss b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.scss index 31e665bf5..433d8d5c5 100644 --- a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.scss +++ b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.scss @@ -1,4 +1,4 @@ div { resize: vertical; overflow: auto; - } \ No newline at end of file +} diff --git a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.spec.ts b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.spec.ts index 094e8cff3..f49d02840 100644 --- a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.spec.ts +++ b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DeviceModelComponent } from './device-model.component'; +import { DeviceModelComponent } from "./device-model.component"; -describe('DeviceModelComponent', () => { - let component: DeviceModelComponent; - let fixture: ComponentFixture; +describe("DeviceModelComponent", () => { + let component: DeviceModelComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DeviceModelComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DeviceModelComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DeviceModelComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DeviceModelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.ts b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.ts index d6182930c..20f014c52 100644 --- a/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/device-model/device-model.component.ts @@ -1,35 +1,37 @@ -import { Component, Input, OnChanges, OnInit } from '@angular/core'; -import { DeviceModelService } from '@app/device-model/device-model.service'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { Component, Input, OnChanges, OnInit } from "@angular/core"; +import { DeviceModelService } from "@app/device-model/device-model.service"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; @Component({ - selector: 'app-device-model', - templateUrl: './device-model.component.html', - styleUrls: ['./device-model.component.scss'] + selector: "app-device-model", + templateUrl: "./device-model.component.html", + styleUrls: ["./device-model.component.scss"], }) export class DeviceModelComponent implements OnInit, OnChanges { - @Input() device: IotDevice; - public deviceModel: string; - editorJsonOutpuOptions = { theme: 'vs', language: 'json', autoIndent: true, roundedSelection: true, minimap: { enabled: false }, readOnly: true }; + @Input() device: IotDevice; + public deviceModel: string; + editorJsonOutpuOptions = { + theme: "vs", + language: "json", + autoIndent: true, + roundedSelection: true, + minimap: { enabled: false }, + readOnly: true, + }; + constructor(private deviceModelService: DeviceModelService) {} - constructor(private deviceModelService: DeviceModelService) { } + ngOnInit(): void {} - ngOnInit(): void { - } - - ngOnChanges() { - if (this.device.deviceModelId) { - this.getDeviceModel(this.device.deviceModelId); + ngOnChanges() { + if (this.device.deviceModelId) { + this.getDeviceModel(this.device.deviceModelId); + } } - } - - getDeviceModel(id: number) { - this.deviceModelService.get(id).subscribe( - (response) => { - this.deviceModel = JSON.stringify(response.body, null, 4); - } - ); - } + getDeviceModel(id: number) { + this.deviceModelService.get(id).subscribe(response => { + this.deviceModel = JSON.stringify(response.body, null, 4); + }); + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.html b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.html index 115715847..35333fc53 100644 --- a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.html @@ -1,8 +1,12 @@ -

{{'IOTDEVICE.DOWNLINK.DIALOG-TITLE' | translate}}

+

{{ "IOTDEVICE.DOWNLINK.DIALOG-TITLE" | translate }}

- {{'IOTDEVICE.DOWNLINK.DIALOG-MESSAGE' | translate}} + {{ "IOTDEVICE.DOWNLINK.DIALOG-MESSAGE" | translate }}
- - + +
diff --git a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.ts b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.ts index 37c6355b6..b0e2cdea1 100644 --- a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component.ts @@ -1,24 +1,21 @@ -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; -import { DownlinkComponent } from '../downlink.component'; +import { Component, OnInit } from "@angular/core"; +import { MatDialogRef } from "@angular/material/dialog"; +import { TranslateService } from "@ngx-translate/core"; +import { DownlinkComponent } from "../downlink.component"; @Component({ - selector: 'app-downlink-dialog', - templateUrl: './downlink-dialog.component.html', - styleUrls: ['./downlink-dialog.component.scss'], + selector: "app-downlink-dialog", + templateUrl: "./downlink-dialog.component.html", + styleUrls: ["./downlink-dialog.component.scss"], }) export class DownlinkDialogComponent implements OnInit { - constructor( - private translate: TranslateService, - public dialog: MatDialogRef - ) {} + constructor(private translate: TranslateService, public dialog: MatDialogRef) {} - ngOnInit(): void { - this.translate.use('da'); - } + ngOnInit(): void { + this.translate.use("da"); + } - cancel() { - this.dialog.close(); - } + cancel() { + this.dialog.close(); + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.html b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.html index 84728130b..4cdd5d75b 100644 --- a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.html @@ -2,40 +2,59 @@
  • - {{error | translate}} + {{ error | translate }}
-

{{'IOTDEVICE.DOWNLINK.DESCRIPTION' | translate}}

+

{{ "IOTDEVICE.DOWNLINK.DESCRIPTION" | translate }}

- {{'IOTDEVICE.DOWNLINK.CONFIRMEDDOWNLINK' | translate}} + {{ "IOTDEVICE.DOWNLINK.CONFIRMEDDOWNLINK" | translate }}
- - + +
- - + +
-

{{'IOTDEVICE.DOWNLINK.SIGFOX-PAYLOAD-LENGTH' | translate}}

+

{{ "IOTDEVICE.DOWNLINK.SIGFOX-PAYLOAD-LENGTH" | translate }}

- +

- {{'IOTDEVICE.DOWNLINK.NOTIMPLEMENTED' | translate}} + {{ "IOTDEVICE.DOWNLINK.NOTIMPLEMENTED" | translate }}

-
\ No newline at end of file + diff --git a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.ts b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.ts index 2862319cd..23fe34cd2 100644 --- a/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/downlink/downlink.component.ts @@ -1,118 +1,118 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, Input, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { Downlink } from '@applications/iot-devices/downlink.model'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { TranslateService } from '@ngx-translate/core'; -import { DeviceType } from '@shared/enums/device-type'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { DownlinkService } from '@shared/services/downlink.service'; -import { DownlinkDialogComponent } from './downlink-dialog/downlink-dialog.component'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, Input, OnInit } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { Downlink } from "@applications/iot-devices/downlink.model"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { TranslateService } from "@ngx-translate/core"; +import { DeviceType } from "@shared/enums/device-type"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { DownlinkService } from "@shared/services/downlink.service"; +import { DownlinkDialogComponent } from "./downlink-dialog/downlink-dialog.component"; @Component({ - selector: 'app-downlink', - templateUrl: './downlink.component.html', - styleUrls: ['./downlink.component.scss'], + selector: "app-downlink", + templateUrl: "./downlink.component.html", + styleUrls: ["./downlink.component.scss"], }) export class DownlinkComponent implements OnInit { - @Input() device: IotDevice; - @Input() errorMessages: string[]; - public downlinkText: string; - public downlink = new Downlink(); + @Input() device: IotDevice; + @Input() errorMessages: string[]; + public downlinkText: string; + public downlink = new Downlink(); - constructor( - private snackBar: MatSnackBar, - private translate: TranslateService, - private downlinkService: DownlinkService, - public dialog: MatDialog, - private errorMessageService: ErrorMessageService - ) {} + constructor( + private snackBar: MatSnackBar, + private translate: TranslateService, + private downlinkService: DownlinkService, + public dialog: MatDialog, + private errorMessageService: ErrorMessageService + ) {} - ngOnInit(): void { - this.errorMessages = []; - } + ngOnInit(): void { + this.errorMessages = []; + } - clickDownlink() { - if (this.validateHex(this.downlink.data)) { - this.downlinkService.get(this.device.id).subscribe( - (response: any) => { - if (response.totalCount > 0) { - this.openDownlinkDialog(); - } else { - this.startDownlink(); - } - }, - (error) => { - this.handleError(error); - console.log(error); + clickDownlink() { + if (this.validateHex(this.downlink.data)) { + this.downlinkService.get(this.device.id).subscribe( + (response: any) => { + if (response.totalCount > 0) { + this.openDownlinkDialog(); + } else { + this.startDownlink(); + } + }, + error => { + this.handleError(error); + console.log(error); + } + ); } - ); } - } - private handleError(error: HttpErrorResponse) { - if (error?.error?.chirpstackError?.error == "f_port must be > 0") { - this.errorMessages = ["port must be > 0"] - return; + private handleError(error: HttpErrorResponse) { + if (error?.error?.chirpstackError?.error == "f_port must be > 0") { + this.errorMessages = ["port must be > 0"]; + return; + } + this.errorMessages = this.errorMessageService.handleErrorMessage(error); } - this.errorMessages = this.errorMessageService.handleErrorMessage(error); - } - private startDownlink() { - this.errorMessages = []; - this.downlinkService.post(this.downlink, this.device.id).subscribe( - (response) => { - this.snackBar.open('Element sat i kø', 'Downlink', { - duration: 10000, - }); - }, - (error) => { - this.handleError(error); - } - ); - } + private startDownlink() { + this.errorMessages = []; + this.downlinkService.post(this.downlink, this.device.id).subscribe( + response => { + this.snackBar.open("Element sat i kø", "Downlink", { + duration: 10000, + }); + }, + error => { + this.handleError(error); + } + ); + } - private validateHex(input: string): boolean { - const isHexinput = /^[a-fA-F\d]+$/.test(input); - let validator = false; - if (isHexinput) { - if (this.device.type === 'SIGFOX' && input.length != 16) { - this.addToErrorMessage('IOTDEVICE.DOWNLINK.SIGFOX-PAYLOAD-LENGTH'); - } - validator = true; - } else { - this.device.type === DeviceType.LORAWAN - ? this.addToErrorMessage('IOTDEVICE.DOWNLINK.NO-PORT-OR-PAYLOAD') - : this.addToErrorMessage('IOTDEVICE.DOWNLINK.NO-PAYLOAD'); - this.addToErrorMessage('IOTDEVICE.DOWNLINK.FORMAT-ERROR'); - validator = false; + private validateHex(input: string): boolean { + const isHexinput = /^[a-fA-F\d]+$/.test(input); + let validator = false; + if (isHexinput) { + if (this.device.type === "SIGFOX" && input.length != 16) { + this.addToErrorMessage("IOTDEVICE.DOWNLINK.SIGFOX-PAYLOAD-LENGTH"); + } + validator = true; + } else { + this.device.type === DeviceType.LORAWAN + ? this.addToErrorMessage("IOTDEVICE.DOWNLINK.NO-PORT-OR-PAYLOAD") + : this.addToErrorMessage("IOTDEVICE.DOWNLINK.NO-PAYLOAD"); + this.addToErrorMessage("IOTDEVICE.DOWNLINK.FORMAT-ERROR"); + validator = false; + } + return validator; } - return validator; - } - addToErrorMessage(text: string) { - this.translate.get([text]).subscribe((translations) => { - this.errorMessages.push(translations[text]); - }); - } + addToErrorMessage(text: string) { + this.translate.get([text]).subscribe(translations => { + this.errorMessages.push(translations[text]); + }); + } - getMaxDownloadLength(): number { - if (this.device.type === DeviceType.SIGFOX) { - return 16 - } else { - return 256 + getMaxDownloadLength(): number { + if (this.device.type === DeviceType.SIGFOX) { + return 16; + } else { + return 256; + } } - } - openDownlinkDialog() { - const dialog = this.dialog.open(DownlinkDialogComponent, {}); + openDownlinkDialog() { + const dialog = this.dialog.open(DownlinkDialogComponent, {}); - dialog.afterClosed().subscribe((result) => { - if (result === true) { - this.startDownlink(); - console.log(`Dialog result: ${result}`); - } - }); - } + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.startDownlink(); + console.log(`Dialog result: ${result}`); + } + }); + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.html index 59c24dece..2e5f81e3c 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.html @@ -1,14 +1,13 @@
- - - - - - - - -

- {{ 'IOTDEVICE.NO-DATAPACKAGE' | translate }} -

-
+ + + + + + + +

+ {{ "IOTDEVICE.NO-DATAPACKAGE" | translate }} +

+
diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.ts index 4d45cceb1..0f6959ea6 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component.ts @@ -1,17 +1,17 @@ -import { Component, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { IotDeviceDetailsService } from '@applications/iot-devices/iot-device-details-service'; +import { Component, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { IotDeviceDetailsService } from "@applications/iot-devices/iot-device-details-service"; @Component({ - selector: 'app-iot-device-data-packets-tab', - templateUrl: './iot-device-data-packets-tab.component.html', - styleUrls: ['./iot-device-data-packets-tab.component.scss'], + selector: "app-iot-device-data-packets-tab", + templateUrl: "./iot-device-data-packets-tab.component.html", + styleUrls: ["./iot-device-data-packets-tab.component.scss"], }) export class IotDeviceDataPacketsTabComponent implements OnInit { - device: IotDevice; - constructor(private iotDeviceDetailsService: IotDeviceDetailsService) {} + device: IotDevice; + constructor(private iotDeviceDetailsService: IotDeviceDetailsService) {} - ngOnInit(): void { - this.device = this.iotDeviceDetailsService.device; - } + ngOnInit(): void { + this.device = this.iotDeviceDetailsService.device; + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.html index ec7542301..8c7642cec 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.html @@ -1,22 +1,31 @@
-

{{ 'IOTDEVICE.DETAIL' | translate }}

-

{{ 'IOT-TABLE.APPLICATION' | translate }}{{device.application.name}}

+

{{ "IOTDEVICE.DETAIL" | translate }}

+

+ {{ "IOT-TABLE.APPLICATION" | translate }}{{ device.application.name }} +

- -
-

{{ 'IOT-TABLE.BATTERY' | translate }}

- -
+ +
+

+ {{ "IOT-TABLE.BATTERY" | translate }} +

+ +
-

{{ 'IOTDEVICE.TYPE' | translate }}{{ 'IOT-DEVICE-TYPES.' + device.type | translate}} +

+ {{ "IOTDEVICE.TYPE" | translate }}{{ "IOT-DEVICE-TYPES." + device.type | translate }}

@@ -29,66 +38,80 @@

{{ 'IOTDEVICE.DETAIL' | translate }}

- {{ 'IOTDEVICE.GENERIC_HTTP.APIKEY' | translate }} + {{ "IOTDEVICE.GENERIC_HTTP.APIKEY" | translate }} {{ httpDeviceUrl }}

- - - - -

{{ 'IOTDEVICE.MQTT.NOCONNECTION' | translate}}

- -
+ + + + +

+ {{ "IOTDEVICE.MQTT.NOCONNECTION" | translate }} +

+ +

- {{ 'IOTDEVICE.COMMENT' | translate }} + {{ "IOTDEVICE.COMMENT" | translate }} - {{device.comment}} + {{ device.comment }} - {{ 'IOTDEVICE.NOCOMMENT' | translate}} + {{ "IOTDEVICE.NOCOMMENT" | translate }}

- -

{{ 'QUESTION.METADATA' | translate }}

-

- {{i + 1}}: {{ tag.key }} - {{ tag.value }} -

+ +

+ {{ "QUESTION.METADATA" | translate }} +

+

+ {{ i + 1 }}: {{ tag.key }} + {{ tag.value }} +

-

{{ 'IOTDEVICE.LOCATION' | translate }}

+

{{ "IOTDEVICE.LOCATION" | translate }}

-
- -
+
+ +
-

{{ 'IOTDEVICE.LATITUDE' | translate }}{{latitude | number:'2.1-9'}}

+

+ {{ "IOTDEVICE.LATITUDE" | translate }}{{ latitude | number : "2.1-9" }} +

-

{{ 'IOTDEVICE.LONGITUDE' | translate }}{{longitude | number:'2.1-9'}}

+

+ {{ "IOTDEVICE.LONGITUDE" | translate }}{{ longitude | number : "2.1-9" }} +

-

{{ 'IOTDEVICE.NOLOCATION' | translate}}

+

{{ "IOTDEVICE.NOLOCATION" | translate }}

- {{ 'IOTDEVICE.COMMENTONLOCATION' | translate }} + {{ "IOTDEVICE.COMMENTONLOCATION" | translate }} - {{device.commentOnLocation}} + {{ device.commentOnLocation }} - {{ 'IOTDEVICE.NOCOMMENTONLOCATION' | translate}} + {{ "IOTDEVICE.NOCOMMENTONLOCATION" | translate }}

diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.scss b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.scss index 2f7d4fa0d..860322770 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.scss +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.scss @@ -1,4 +1,4 @@ -@import 'src/assets/scss/setup/variables'; +@import "src/assets/scss/setup/variables"; .pre { white-space: pre-wrap; diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.ts index a2e2110d1..d88c6dd07 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component.ts @@ -1,88 +1,75 @@ -import { Location } from '@angular/common'; -import { - Component, - EventEmitter, - Input, - OnChanges, - OnDestroy, - OnInit, - SimpleChanges, -} from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { IoTDeviceService } from '@applications/iot-devices/iot-device.service'; -import { environment } from '@environments/environment'; -import { TranslateService } from '@ngx-translate/core'; -import { jsonToList } from '@shared/helpers/json.helper'; -import { KeyValue } from '@shared/types/tuple.type'; -import { DeviceType } from '@shared/enums/device-type'; +import { Location } from "@angular/common"; +import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { IoTDeviceService } from "@applications/iot-devices/iot-device.service"; +import { environment } from "@environments/environment"; +import { TranslateService } from "@ngx-translate/core"; +import { jsonToList } from "@shared/helpers/json.helper"; +import { KeyValue } from "@shared/types/tuple.type"; +import { DeviceType } from "@shared/enums/device-type"; @Component({ - selector: 'app-iot-device-detail-generic', - templateUrl: './iot-device-detail-generic.component.html', - styleUrls: ['./iot-device-detail-generic.component.scss'], + selector: "app-iot-device-detail-generic", + templateUrl: "./iot-device-detail-generic.component.html", + styleUrls: ["./iot-device-detail-generic.component.scss"], }) -export class IotDeviceDetailGenericComponent - implements OnInit, OnChanges, OnDestroy { - batteryStatusColor = 'green'; - batteryStatusPercentage: number; - metadataTags: KeyValue[] = []; - @Input() device: IotDevice; - @Input() latitude = 0; - @Input() longitude = 0; - deleteDevice = new EventEmitter(); - baseUrl: string = environment.baseUrl; - httpDeviceUrl: string; +export class IotDeviceDetailGenericComponent implements OnInit, OnChanges, OnDestroy { + batteryStatusColor = "green"; + batteryStatusPercentage: number; + metadataTags: KeyValue[] = []; + @Input() device: IotDevice; + @Input() latitude = 0; + @Input() longitude = 0; + deleteDevice = new EventEmitter(); + baseUrl: string = environment.baseUrl; + httpDeviceUrl: string; - private readonly CHIRPSTACK_BATTERY_NOT_AVAILIBLE = 255; + private readonly CHIRPSTACK_BATTERY_NOT_AVAILIBLE = 255; - constructor( - private translate: TranslateService, - public iotDeviceService: IoTDeviceService, - private location: Location - ) {} + constructor( + private translate: TranslateService, + public iotDeviceService: IoTDeviceService, + private location: Location + ) {} - ngOnInit(): void {} + ngOnInit(): void {} - ngOnChanges(changes: SimpleChanges): void { - this.batteryStatusPercentage = this.getBatteryProcentage(); - this.httpDeviceUrl = this.getGenericHttpDeviceUrl(); - if ( - changes?.device?.previousValue?.metadata !== - changes?.device?.currentValue?.metadata && - this.device.metadata - ) { - this.metadataTags = jsonToList(this.device.metadata); + ngOnChanges(changes: SimpleChanges): void { + this.batteryStatusPercentage = this.getBatteryProcentage(); + this.httpDeviceUrl = this.getGenericHttpDeviceUrl(); + if ( + changes?.device?.previousValue?.metadata !== changes?.device?.currentValue?.metadata && + this.device.metadata + ) { + this.metadataTags = jsonToList(this.device.metadata); + } } - } - routeBack(): void { - this.location.back(); - } - getCoordinates() { - return { - longitude: this.longitude, - latitude: this.latitude, - draggable: false, - editEnabled: false, - useGeolocation: false, - }; - } + routeBack(): void { + this.location.back(); + } + getCoordinates() { + return { + longitude: this.longitude, + latitude: this.latitude, + draggable: false, + editEnabled: false, + useGeolocation: false, + }; + } - private getBatteryProcentage(): number { - if ( - this.device?.lorawanSettings?.deviceStatusBattery === - this.CHIRPSTACK_BATTERY_NOT_AVAILIBLE - ) { - return null; + private getBatteryProcentage(): number { + if (this.device?.lorawanSettings?.deviceStatusBattery === this.CHIRPSTACK_BATTERY_NOT_AVAILIBLE) { + return null; + } + return Math.round(this.device?.lorawanSettings?.deviceStatusBattery); } - return Math.round(this.device?.lorawanSettings?.deviceStatusBattery); - } - private getGenericHttpDeviceUrl(): string { - return `${this.baseUrl}receive-data?apiKey=${this.device.apiKey}`; - } + private getGenericHttpDeviceUrl(): string { + return `${this.baseUrl}receive-data?apiKey=${this.device.apiKey}`; + } - ngOnDestroy(): void {} + ngOnDestroy(): void {} - protected readonly DeviceType = DeviceType; + protected readonly DeviceType = DeviceType; } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.html index 9d75c49b9..886409833 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.html @@ -1,17 +1,40 @@ -

{{ 'IOTDEVICE.LORA.DEVEUI' | translate }}{{device.lorawanSettings.devEUI}}

-

{{ 'IOTDEVICE.LORA.DEVICEPROFILE' | translate }}{{deviceProfileName}}

+

+ {{ "IOTDEVICE.LORA.DEVEUI" | translate }}{{ device.lorawanSettings.devEUI }} +

+

+ {{ "IOTDEVICE.LORA.DEVICEPROFILE" | translate }}{{ deviceProfileName }} +

-

{{ 'IOTDEVICE.LORA.OTAAAPPLICATIONKEY' | translate }}{{device.lorawanSettings?.OTAAapplicationKey}} +

+ {{ "IOTDEVICE.LORA.OTAAAPPLICATIONKEY" | translate }}{{ device.lorawanSettings?.OTAAapplicationKey }}

-

{{ 'IOTDEVICE.LORA.DEVADDR' | translate }}{{device.lorawanSettings?.devAddr}}

-

{{ 'IOTDEVICE.LORA.NETWORKSESSIONKEY' | translate }}{{device.lorawanSettings?.activationType}} +

+ {{ "IOTDEVICE.LORA.DEVADDR" | translate }}{{ device.lorawanSettings?.devAddr }} +

+

+ {{ "IOTDEVICE.LORA.NETWORKSESSIONKEY" | translate }}{{ device.lorawanSettings?.activationType }} +

+

+ {{ "IOTDEVICE.LORA.APPLICATIONSESSIONKEY" | translate }}{{ device.lorawanSettings?.applicationSessionKey }} +

+

+ {{ "IOTDEVICE.LORA.FCNTUP" | translate }}{{ device.lorawanSettings?.fCntUp }}

-

{{ 'IOTDEVICE.LORA.APPLICATIONSESSIONKEY' | translate }}{{device.lorawanSettings?.applicationSessionKey}} +

+ {{ "IOTDEVICE.LORA.NFCNTDOWN" | translate }}{{ device.lorawanSettings?.nFCntDown }}

-

{{ 'IOTDEVICE.LORA.FCNTUP' | translate }}{{device.lorawanSettings?.fCntUp}}

-

{{ 'IOTDEVICE.LORA.NFCNTDOWN' | translate }}{{device.lorawanSettings?.nFCntDown }}

-

{{ 'IOTDEVICE.LORA.SKIPFCNTCHECK' | translate }}{{device.lorawanSettings?.skipFCntCheck | yesNo}} +

+ {{ "IOTDEVICE.LORA.SKIPFCNTCHECK" | translate }}{{ device.lorawanSettings?.skipFCntCheck | yesNo }}

diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.ts index c0307b004..27c58cf2a 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component.ts @@ -1,33 +1,31 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { DeviceProfileService } from '@profiles/device-profiles/device-profile.service'; -import { Subscription } from 'rxjs'; +import { Component, Input, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { DeviceProfileService } from "@profiles/device-profiles/device-profile.service"; +import { Subscription } from "rxjs"; @Component({ - selector: 'app-iot-device-detail-lorawan', - templateUrl: './iot-device-detail-lorawan.component.html', - styleUrls: ['./iot-device-detail-lorawan.component.scss'] + selector: "app-iot-device-detail-lorawan", + templateUrl: "./iot-device-detail-lorawan.component.html", + styleUrls: ["./iot-device-detail-lorawan.component.scss"], }) export class IotDeviceDetailLorawanComponent implements OnInit { + @Input() device: IotDevice; + deviceProfileSubscription: Subscription; + public OTAA: boolean; + public deviceProfileName: string; - @Input() device: IotDevice; - deviceProfileSubscription: Subscription; - public OTAA: boolean; - public deviceProfileName: string; + constructor(private deviceProfileService: DeviceProfileService) {} - constructor( - private deviceProfileService: DeviceProfileService, - ) { } + ngOnInit(): void { + this.getDeviceProfil(); + } - ngOnInit(): void { - this.getDeviceProfil(); - } - - getDeviceProfil() { - this.deviceProfileSubscription = this.deviceProfileService.getOne(this.device.lorawanSettings?.deviceProfileID) - .subscribe((response) => { - this.OTAA = response.deviceProfile.supportsJoin; - this.deviceProfileName = response.deviceProfile.name; - }); - } + getDeviceProfil() { + this.deviceProfileSubscription = this.deviceProfileService + .getOne(this.device.lorawanSettings?.deviceProfileID) + .subscribe(response => { + this.OTAA = response.deviceProfile.supportsJoin; + this.deviceProfileName = response.deviceProfile.name; + }); + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.html index 951b4b800..829d9893d 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.html @@ -1,8 +1,24 @@ -

{{ 'IOTDEVICE.SIGFOX.DEVICEID' | translate }}{{device.sigfoxSettings.deviceId}}

-

{{ 'IOTDEVICE.SIGFOX.GROUP-NAME' | translate }}{{device.sigfoxSettings.groupName}}

-

{{ 'IOTDEVICE.SIGFOX.DEVICETYPE' | translate }}{{device.sigfoxSettings.deviceTypeName}}

-

{{ 'IOTDEVICE.SIGFOX.PAC' | translate }}{{device.sigfoxSettings.pac}}

-

{{ 'IOTDEVICE.SIGFOX.ENDPRODUCTCERTIFICATE' | translate }}{{device.sigfoxSettings.endProductCertificate}} -

-

{{ 'IOTDEVICE.SIGFOX.PROTOTYPE' | translate }}{{device.sigfoxSettings.prototype ? 'true' : 'false' | translate}} -

\ No newline at end of file +

+ {{ "IOTDEVICE.SIGFOX.DEVICEID" | translate }}{{ device.sigfoxSettings.deviceId }} +

+

+ {{ "IOTDEVICE.SIGFOX.GROUP-NAME" | translate }}{{ device.sigfoxSettings.groupName }} +

+

+ {{ "IOTDEVICE.SIGFOX.DEVICETYPE" | translate }}{{ device.sigfoxSettings.deviceTypeName }} +

+

+ {{ "IOTDEVICE.SIGFOX.PAC" | translate }}{{ device.sigfoxSettings.pac }} +

+

+ {{ "IOTDEVICE.SIGFOX.ENDPRODUCTCERTIFICATE" | translate }}{{ device.sigfoxSettings.endProductCertificate }} +

+

+ {{ "IOTDEVICE.SIGFOX.PROTOTYPE" | translate }}{{ device.sigfoxSettings.prototype ? "true" : ("false" | translate) }} +

diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.ts index fda93f1c5..6156b5f3d 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component.ts @@ -1,18 +1,15 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { Component, Input, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; @Component({ - selector: 'app-iot-device-detail-sigfox', - templateUrl: './iot-device-detail-sigfox.component.html', - styleUrls: ['./iot-device-detail-sigfox.component.scss'] + selector: "app-iot-device-detail-sigfox", + templateUrl: "./iot-device-detail-sigfox.component.html", + styleUrls: ["./iot-device-detail-sigfox.component.scss"], }) export class IotDeviceDetailSigfoxComponent implements OnInit { + @Input() device: IotDevice; - @Input() device: IotDevice; - - constructor() { } - - ngOnInit(): void { - } + constructor() {} + ngOnInit(): void {} } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.html index 7034ffb91..92fa1bf35 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.html @@ -1,15 +1,25 @@ diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.scss b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.scss index fb64ad961..967fa2ad8 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.scss +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.scss @@ -1,33 +1,33 @@ -@import 'src/assets/scss/setup/breakpoints'; -@import 'src/assets/scss/setup/variables'; +@import "src/assets/scss/setup/breakpoints"; +@import "src/assets/scss/setup/variables"; .iot-device-component { - width: 100%; - margin-right: auto; - margin-left: auto; + width: 100%; + margin-right: auto; + margin-left: auto; - @include media-breakpoint-up(sm) { - max-width: 960px; - } + @include media-breakpoint-up(sm) { + max-width: 960px; + } - @include media-breakpoint-up(md) { - max-width: 1040px; - } + @include media-breakpoint-up(md) { + max-width: 1040px; + } - @include media-breakpoint-up(xl) { - max-width: 1200px; - } + @include media-breakpoint-up(xl) { + max-width: 1200px; + } - .bottom-separator { - min-height: 60px; - border-bottom: $grey-separator solid 1px; + .bottom-separator { + min-height: 60px; + border-bottom: $grey-separator solid 1px; - @include media-breakpoint-up(md) { - min-height: 150px; + @include media-breakpoint-up(md) { + min-height: 150px; + } } - } } .application-table-header { - // background-color: $white; + // background-color: $white; } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.spec.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.spec.ts index e41c22e08..3c729b3af 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.spec.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { IoTDeviceDetailComponent } from './iot-device-detail.component'; +import { IoTDeviceDetailComponent } from "./iot-device-detail.component"; -describe('IoTDeviceDetailComponent', () => { - let component: IoTDeviceDetailComponent; - let fixture: ComponentFixture; +describe("IoTDeviceDetailComponent", () => { + let component: IoTDeviceDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [IoTDeviceDetailComponent] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [IoTDeviceDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(IoTDeviceDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IoTDeviceDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.ts index 8034ac3e5..110d9957d 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-detail.component.ts @@ -1,222 +1,208 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Application } from '@applications/application.model'; -import { TranslateService } from '@ngx-translate/core'; -import { DeleteDialogComponent } from '@shared/components/delete-dialog/delete-dialog.component'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { DeviceType } from '@shared/enums/device-type'; -import { BackButton } from '@shared/models/back-button.model'; -import { Subscription } from 'rxjs'; -import { IotDevice } from '../iot-device.model'; -import { IoTDeviceService } from '../iot-device.service'; -import { - DropdownButton, - ExtraDropdownOption, -} from '@shared/models/dropdown-button.model'; -import { Title } from '@angular/platform-browser'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { IotDeviceDetailsService } from '@applications/iot-devices/iot-device-details-service'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { ActivatedRoute, Router } from "@angular/router"; +import { Application } from "@applications/application.model"; +import { TranslateService } from "@ngx-translate/core"; +import { DeleteDialogComponent } from "@shared/components/delete-dialog/delete-dialog.component"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { DeviceType } from "@shared/enums/device-type"; +import { BackButton } from "@shared/models/back-button.model"; +import { Subscription } from "rxjs"; +import { IotDevice } from "../iot-device.model"; +import { IoTDeviceService } from "../iot-device.service"; +import { DropdownButton, ExtraDropdownOption } from "@shared/models/dropdown-button.model"; +import { Title } from "@angular/platform-browser"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { IotDeviceDetailsService } from "@applications/iot-devices/iot-device-details-service"; @Component({ - selector: 'app-iot-device', - templateUrl: './iot-device-detail.component.html', - styleUrls: ['./iot-device-detail.component.scss'], + selector: "app-iot-device", + templateUrl: "./iot-device-detail.component.html", + styleUrls: ["./iot-device-detail.component.scss"], }) export class IoTDeviceDetailComponent implements OnInit, OnDestroy { - public navTabs: any[] = [ - { - label: 'APPLICATION.DETAILS', - link: './details', - index: 0, - }, - { - label: 'IOTDEVICE.HISTORY', - link: './history', - index: 1, - }, - { - label: 'IOTDEVICE.DATA-PACKETS', - link: './data-packets', - index: 2, - }, - { - label: 'IOTDEVICE.DOWNLINK-TAB', - link: './downlink', - index: 3, - }, - ]; - device: IotDevice; - public deviceId: number; - public backButton: BackButton = { label: '', routerLink: 'undefined' }; - public application: Application; - - public iotDeviceSubscription: Subscription; - public errorMessages: string[]; - private deleteDialogSubscription: Subscription; - public dropdownButton: DropdownButton; - public canEdit = false; - - private resetApiKeyId = 'RESET-API-KEY'; - private resetApiKeyOption: ExtraDropdownOption; - private resetApiKeyBody: string; - private resetApiKeyConfirm: string; - private resetApiKeyCancel: string; - - constructor( - private route: ActivatedRoute, - private iotDeviceService: IoTDeviceService, - private translate: TranslateService, - private router: Router, - private deleteDialogService: DeleteDialogService, - private dialog: MatDialog, - private titleService: Title, - private meService: MeService, - private iotDeviceDetailsService: IotDeviceDetailsService - ) {} - - ngOnInit(): void { - this.deviceId = +this.route.snapshot.paramMap.get('deviceId'); - const appId: number = +this.route.snapshot.paramMap.get('id'); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - appId - ); - this.backButton.routerLink = `applications/${appId}/iot-devices`; - - if (this.deviceId) { - this.bindIoTDeviceAndApplication(this.deviceId); - this.dropdownButton = { - label: '', - editRouterLink: '../../iot-device-edit/' + this.deviceId, - isErasable: true, - }; + public navTabs: any[] = [ + { + label: "APPLICATION.DETAILS", + link: "./details", + index: 0, + }, + { + label: "IOTDEVICE.HISTORY", + link: "./history", + index: 1, + }, + { + label: "IOTDEVICE.DATA-PACKETS", + link: "./data-packets", + index: 2, + }, + { + label: "IOTDEVICE.DOWNLINK-TAB", + link: "./downlink", + index: 3, + }, + ]; + device: IotDevice; + public deviceId: number; + public backButton: BackButton = { label: "", routerLink: "undefined" }; + public application: Application; + + public iotDeviceSubscription: Subscription; + public errorMessages: string[]; + private deleteDialogSubscription: Subscription; + public dropdownButton: DropdownButton; + public canEdit = false; + + private resetApiKeyId = "RESET-API-KEY"; + private resetApiKeyOption: ExtraDropdownOption; + private resetApiKeyBody: string; + private resetApiKeyConfirm: string; + private resetApiKeyCancel: string; + + constructor( + private route: ActivatedRoute, + private iotDeviceService: IoTDeviceService, + private translate: TranslateService, + private router: Router, + private deleteDialogService: DeleteDialogService, + private dialog: MatDialog, + private titleService: Title, + private meService: MeService, + private iotDeviceDetailsService: IotDeviceDetailsService + ) {} + + ngOnInit(): void { + this.deviceId = +this.route.snapshot.paramMap.get("deviceId"); + const appId: number = +this.route.snapshot.paramMap.get("id"); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + appId + ); + this.backButton.routerLink = `applications/${appId}/iot-devices`; + + if (this.deviceId) { + this.bindIoTDeviceAndApplication(this.deviceId); + this.dropdownButton = { + label: "", + editRouterLink: "../../iot-device-edit/" + this.deviceId, + isErasable: true, + }; + } + + this.translate + .get([ + "NAV.APPLICATIONS", + "IOTDEVICE-TABLE-ROW.SHOW-OPTIONS", + "TITLE.IOTDEVICE", + "IOTDEVICE-TABLE-ROW.RESET-API-KEY", + "IOTDEVICE.GENERIC_HTTP.RESET-API-KEY", + "GEN.CANCEL", + ]) + .subscribe(translations => { + this.backButton.label = translations["NAV.APPLICATIONS"]; + this.dropdownButton.label = translations["IOTDEVICE-TABLE-ROW.SHOW-OPTIONS"]; + this.titleService.setTitle(translations["TITLE.IOTDEVICE"]); + + this.resetApiKeyOption = { + id: this.resetApiKeyId, + label: translations["IOTDEVICE-TABLE-ROW.RESET-API-KEY"], + }; + this.resetApiKeyBody = translations["IOTDEVICE.GENERIC_HTTP.RESET-API-KEY"]["BODY"]; + this.resetApiKeyConfirm = translations["IOTDEVICE.GENERIC_HTTP.RESET-API-KEY"]["YESRESET"]; + this.resetApiKeyCancel = translations["GEN.CANCEL"]; + }); + + this.dropdownButton.extraOptions = []; + if (this.router.url.split("/").length <= 5) { + this.router.navigateByUrl(this.router.url + "/details", { + replaceUrl: true, + }); + } } - this.translate - .get([ - 'NAV.APPLICATIONS', - 'IOTDEVICE-TABLE-ROW.SHOW-OPTIONS', - 'TITLE.IOTDEVICE', - 'IOTDEVICE-TABLE-ROW.RESET-API-KEY', - 'IOTDEVICE.GENERIC_HTTP.RESET-API-KEY', - 'GEN.CANCEL', - ]) - .subscribe((translations) => { - this.backButton.label = translations['NAV.APPLICATIONS']; - this.dropdownButton.label = - translations['IOTDEVICE-TABLE-ROW.SHOW-OPTIONS']; - this.titleService.setTitle(translations['TITLE.IOTDEVICE']); - - this.resetApiKeyOption = { - id: this.resetApiKeyId, - label: translations['IOTDEVICE-TABLE-ROW.RESET-API-KEY'], - }; - this.resetApiKeyBody = - translations['IOTDEVICE.GENERIC_HTTP.RESET-API-KEY']['BODY']; - this.resetApiKeyConfirm = - translations['IOTDEVICE.GENERIC_HTTP.RESET-API-KEY']['YESRESET']; - this.resetApiKeyCancel = translations['GEN.CANCEL']; - }); - - this.dropdownButton.extraOptions = []; - if (this.router.url.split('/').length <= 5) { - this.router.navigateByUrl(this.router.url + '/details', { - replaceUrl: true, - }); + bindIoTDeviceAndApplication(deviceId: number) { + this.iotDeviceSubscription = this.iotDeviceService.getIoTDevice(deviceId).subscribe((device: IotDevice) => { + this.device = device; + this.iotDeviceDetailsService.device = device; + this.application = device.application; + if (this.device.location) { + this.iotDeviceDetailsService.longitude = this.device.location.coordinates[0]; + this.iotDeviceDetailsService.latitude = this.device.location.coordinates[1]; + } + + if (this.canEdit && this.device.type === DeviceType.GENERIC_HTTP) { + this.dropdownButton.extraOptions.push(this.resetApiKeyOption); + } + }); } - } - - bindIoTDeviceAndApplication(deviceId: number) { - this.iotDeviceSubscription = this.iotDeviceService - .getIoTDevice(deviceId) - .subscribe((device: IotDevice) => { - this.device = device; - this.iotDeviceDetailsService.device = device; - this.application = device.application; - if (this.device.location) { - this.iotDeviceDetailsService.longitude = this.device.location.coordinates[0]; - this.iotDeviceDetailsService.latitude = this.device.location.coordinates[1]; - } - if (this.canEdit && this.device.type === DeviceType.GENERIC_HTTP) { - this.dropdownButton.extraOptions.push(this.resetApiKeyOption); - } - }); - } - - showSigfoxDeleteDialog() { - const dialog = this.dialog.open(DeleteDialogComponent, { - data: { - message: - 'Sigfox enheder kan ikke slettes fra OS2IoT, de skal slettes fra backend.sigfox.com, hvorefter de automatisk bliver slettet fra OS2IoT inden for få minutter', - showAccept: false, - showCancel: true, - }, - }); - } - - routeToApplication(): void { - this.router.navigate(['applications', this.application.id, 'iot-devices']); - } - - clickDelete() { - if (this.device.type === DeviceType.SIGFOX) { - this.showSigfoxDeleteDialog(); - } else { - this.deleteDialogSubscription = this.deleteDialogService - .showSimpleDialog() - .subscribe((response) => { - if (response) { - this.iotDeviceService - .deleteIoTDevice(this.device.id) - .subscribe((response) => { - this.routeToApplication(); - }); - } else { - console.log(response); - } + showSigfoxDeleteDialog() { + const dialog = this.dialog.open(DeleteDialogComponent, { + data: { + message: + "Sigfox enheder kan ikke slettes fra OS2IoT, de skal slettes fra backend.sigfox.com, hvorefter de automatisk bliver slettet fra OS2IoT inden for få minutter", + showAccept: false, + showCancel: true, + }, }); } - } - ngOnDestroy() { - // prevent memory leak by unsubscribing - if (this.iotDeviceSubscription) { - this.iotDeviceSubscription.unsubscribe(); + routeToApplication(): void { + this.router.navigate(["applications", this.application.id, "iot-devices"]); } - if (this.deleteDialogSubscription) { - this.deleteDialogSubscription.unsubscribe(); + + clickDelete() { + if (this.device.type === DeviceType.SIGFOX) { + this.showSigfoxDeleteDialog(); + } else { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.iotDeviceService.deleteIoTDevice(this.device.id).subscribe(response => { + this.routeToApplication(); + }); + } else { + console.log(response); + } + }); + } } - } - - clickExtraDropdownOption(id: string) { - if (id === this.resetApiKeyId) { - this.deleteDialogService - .showSimpleDialog( - this.resetApiKeyBody, - true, - true, - false, - '', - false, - this.resetApiKeyConfirm, - this.resetApiKeyCancel - ) - .subscribe((isConfirmed) => { - if (isConfirmed) { - this.iotDeviceService - .resetHttpDeviceApiKey(this.device.id) - .subscribe((response) => { - this.device = { - ...this.device, - apiKey: response.apiKey, - }; - }); - } - }); + + ngOnDestroy() { + // prevent memory leak by unsubscribing + if (this.iotDeviceSubscription) { + this.iotDeviceSubscription.unsubscribe(); + } + if (this.deleteDialogSubscription) { + this.deleteDialogSubscription.unsubscribe(); + } + } + + clickExtraDropdownOption(id: string) { + if (id === this.resetApiKeyId) { + this.deleteDialogService + .showSimpleDialog( + this.resetApiKeyBody, + true, + true, + false, + "", + false, + this.resetApiKeyConfirm, + this.resetApiKeyCancel + ) + .subscribe(isConfirmed => { + if (isConfirmed) { + this.iotDeviceService.resetHttpDeviceApiKey(this.device.id).subscribe(response => { + this.device = { + ...this.device, + apiKey: response.apiKey, + }; + }); + } + }); + } } - } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.html index 6aa1198ec..541b09d7f 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.html @@ -1,11 +1,40 @@ -

{{ 'IOTDEVICE.MQTT.URL' | translate }}{{ device.mqttExternalBrokerSettings.mqttURL }}

-

{{ 'IOTDEVICE.MQTT.PORT' | translate }}{{ device.mqttExternalBrokerSettings.mqttPort }}

-

{{ 'IOTDEVICE.MQTT.TOPIC_NAME' | translate }}{{ device.mqttExternalBrokerSettings.mqtttopicname }}

- -

{{ 'QUESTION.MQTT.USERNAME-LABEL' | translate }}{{ device.mqttExternalBrokerSettings.mqttusername }}

+

+ {{ "IOTDEVICE.MQTT.URL" | translate }}{{ device.mqttExternalBrokerSettings.mqttURL }} +

+

+ {{ "IOTDEVICE.MQTT.PORT" | translate }}{{ device.mqttExternalBrokerSettings.mqttPort }} +

+

+ {{ "IOTDEVICE.MQTT.TOPIC_NAME" | translate }}{{ device.mqttExternalBrokerSettings.mqtttopicname }} +

+ +

+ {{ "QUESTION.MQTT.USERNAME-LABEL" | translate }}{{ device.mqttExternalBrokerSettings.mqttusername }} +

-

{{ 'QUESTION.MQTT.CA-CERTIFICATE' | translate }}

-

{{ 'QUESTION.MQTT.DEVICE-CERTIFICATE' | translate }}

-

{{ 'QUESTION.MQTT.DEVICE-CERTIFICATE-KEY' | translate }}

+

+ {{ "QUESTION.MQTT.CA-CERTIFICATE" | translate }} +

+

+ {{ "QUESTION.MQTT.DEVICE-CERTIFICATE" | translate }} +

+

+ {{ "QUESTION.MQTT.DEVICE-CERTIFICATE-KEY" | translate }} +

diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.ts index e74f503fb..3b066bb57 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component.ts @@ -1,18 +1,18 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { AuthenticationType } from '@shared/enums/authentication-type'; +import { Component, Input, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { AuthenticationType } from "@shared/enums/authentication-type"; @Component({ - selector: 'app-iot-device-details-mqtt-external-broker', - templateUrl: './iot-device-details-mqtt-external-broker.component.html', - styleUrls: ['./iot-device-details-mqtt-external-broker.component.scss'], + selector: "app-iot-device-details-mqtt-external-broker", + templateUrl: "./iot-device-details-mqtt-external-broker.component.html", + styleUrls: ["./iot-device-details-mqtt-external-broker.component.scss"], }) export class IotDeviceDetailsMqttExternalBrokerComponent implements OnInit { - @Input() device: IotDevice; + @Input() device: IotDevice; - constructor() {} + constructor() {} - ngOnInit(): void {} + ngOnInit(): void {} - protected readonly AuthenticationType = AuthenticationType; + protected readonly AuthenticationType = AuthenticationType; } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.html index cf321b63f..ee61a6a7f 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.html @@ -1,23 +1,65 @@ -

{{ 'IOTDEVICE.MQTT.URL' | translate }}{{ device.mqttInternalBrokerSettings.mqttURL }}

-

{{ 'IOTDEVICE.MQTT.PORT' | translate }}{{ device.mqttInternalBrokerSettings.mqttPort }}

-

{{ 'IOTDEVICE.MQTT.TOPIC_NAME' | translate }}{{device.mqttInternalBrokerSettings.mqtttopicname}}

+

+ {{ "IOTDEVICE.MQTT.URL" | translate }}{{ device.mqttInternalBrokerSettings.mqttURL }} +

+

+ {{ "IOTDEVICE.MQTT.PORT" | translate }}{{ device.mqttInternalBrokerSettings.mqttPort }} +

+

+ {{ "IOTDEVICE.MQTT.TOPIC_NAME" | translate }}{{ device.mqttInternalBrokerSettings.mqtttopicname }} +

-

{{ 'QUESTION.MQTT.USERNAME-LABEL' | translate }}{{ device.mqttInternalBrokerSettings.mqttusername }}

+

+ {{ "QUESTION.MQTT.USERNAME-LABEL" | translate }}{{ device.mqttInternalBrokerSettings.mqttusername }} +

-

{{ 'QUESTION.MQTT.CA-CERTIFICATE' | translate }} - - -

+

+ {{ "QUESTION.MQTT.CA-CERTIFICATE" | translate }} + + + +

-

{{ 'QUESTION.MQTT.DEVICE-CERTIFICATE' | translate }} - - - -

-

{{ 'QUESTION.MQTT.DEVICE-CERTIFICATE-KEY' | translate }} - - - -

+

+ {{ "QUESTION.MQTT.DEVICE-CERTIFICATE" | translate }} + + + +

+

+ {{ "QUESTION.MQTT.DEVICE-CERTIFICATE-KEY" | translate }} + + + +

diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.ts index 03a0c5312..3ab93cbb8 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component.ts @@ -1,23 +1,23 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { AuthenticationType } from '@shared/enums/authentication-type'; -import { simpleDownload } from '@shared/helpers/download.helper'; +import { Component, Input, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { AuthenticationType } from "@shared/enums/authentication-type"; +import { simpleDownload } from "@shared/helpers/download.helper"; @Component({ - selector: 'app-iot-device-details-mqtt-internal-broker', - templateUrl: './iot-device-details-mqtt-internal-broker.component.html', - styleUrls: ['./iot-device-details-mqtt-internal-broker.component.scss'], + selector: "app-iot-device-details-mqtt-internal-broker", + templateUrl: "./iot-device-details-mqtt-internal-broker.component.html", + styleUrls: ["./iot-device-details-mqtt-internal-broker.component.scss"], }) export class IotDeviceDetailsMqttInternalBrokerComponent implements OnInit { - @Input() device: IotDevice; + @Input() device: IotDevice; - constructor() {} + constructor() {} - ngOnInit(): void {} + ngOnInit(): void {} - protected readonly AuthenticationType = AuthenticationType; + protected readonly AuthenticationType = AuthenticationType; - downloadCaCertificate(caCertificate: string, filename: string) { - simpleDownload(caCertificate, filename); - } + downloadCaCertificate(caCertificate: string, filename: string) { + simpleDownload(caCertificate, filename); + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.html index 1f4c4401a..5957c1f11 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.html @@ -1,10 +1,10 @@
- - - -
-
- + + + +
+
+ +
-
diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.ts index 5af0a2a01..8522ad521 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-details-tab/iot-device-details-tab.component.ts @@ -1,22 +1,22 @@ -import { Component, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { IotDeviceDetailsService } from '@applications/iot-devices/iot-device-details-service'; +import { Component, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { IotDeviceDetailsService } from "@applications/iot-devices/iot-device-details-service"; @Component({ - selector: 'app-iot-device-details-tab', - templateUrl: './iot-device-details-tab.component.html', - styleUrls: ['./iot-device-details-tab.component.scss'], + selector: "app-iot-device-details-tab", + templateUrl: "./iot-device-details-tab.component.html", + styleUrls: ["./iot-device-details-tab.component.scss"], }) export class IotDeviceDetailsTabComponent implements OnInit { - device: IotDevice; - public latitude: number; - public longitude: number; + device: IotDevice; + public latitude: number; + public longitude: number; - constructor(private iotDeviceDetailsService: IotDeviceDetailsService) {} + constructor(private iotDeviceDetailsService: IotDeviceDetailsService) {} - ngOnInit(): void { - this.device = this.iotDeviceDetailsService.device; - this.latitude = this.iotDeviceDetailsService.latitude; - this.longitude = this.iotDeviceDetailsService.longitude; - } + ngOnInit(): void { + this.device = this.iotDeviceDetailsService.device; + this.latitude = this.iotDeviceDetailsService.latitude; + this.longitude = this.iotDeviceDetailsService.longitude; + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.html index 95ed6312a..2b550d040 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.ts index 830b9f9b4..fd91339df 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component.ts @@ -1,18 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { IotDeviceDetailsService } from '@applications/iot-devices/iot-device-details-service'; +import { Component, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { IotDeviceDetailsService } from "@applications/iot-devices/iot-device-details-service"; @Component({ - selector: 'app-iot-device-downlink-tab', - templateUrl: './iot-device-downlink-tab.component.html', - styleUrls: ['./iot-device-downlink-tab.component.scss'], + selector: "app-iot-device-downlink-tab", + templateUrl: "./iot-device-downlink-tab.component.html", + styleUrls: ["./iot-device-downlink-tab.component.scss"], }) export class IotDeviceDownlinkTabComponent implements OnInit { - device: IotDevice; - public errorMessages: string[]; - constructor(private iotDeviceDetailsService: IotDeviceDetailsService) {} + device: IotDevice; + public errorMessages: string[]; + constructor(private iotDeviceDetailsService: IotDeviceDetailsService) {} - ngOnInit(): void { - this.device = this.iotDeviceDetailsService.device; - } + ngOnInit(): void { + this.device = this.iotDeviceDetailsService.device; + } } diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.html b/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.html index 8829281b7..57809e0d3 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.html +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.html @@ -1,29 +1,42 @@ -
-
-
- - -
-
- - -
+
+
+
+ + +
+
+ + +
+
+
+
+ +
+
-
-
- -
-
-
-
-

- {{ 'IOTDEVICE.HISTORY-TAB.HISTORY-NOT-SUPPORTED' | translate }} -

-
+
+

+ {{ "IOTDEVICE.HISTORY-TAB.HISTORY-NOT-SUPPORTED" | translate }} +

+
diff --git a/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.ts b/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.ts index df44ef648..ad775213d 100644 --- a/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.ts +++ b/src/app/applications/iot-devices/iot-device-detail/iot-device-history-tab/iot-device-history-tab.component.ts @@ -1,167 +1,143 @@ -import { Component, OnInit } from '@angular/core'; -import { IotDeviceDetailsService } from '@applications/iot-devices/iot-device-details-service'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { DeviceType } from '@shared/enums/device-type'; -import { ChartConfiguration } from 'chart.js'; -import moment from 'moment/moment'; -import { ColorGraphBlue1 } from '@shared/constants/color-constants'; -import { recordToEntries } from '@shared/helpers/record.helper'; -import { IoTDeviceService } from '@applications/iot-devices/iot-device.service'; +import { Component, OnInit } from "@angular/core"; +import { IotDeviceDetailsService } from "@applications/iot-devices/iot-device-details-service"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { DeviceType } from "@shared/enums/device-type"; +import { ChartConfiguration } from "chart.js"; +import moment from "moment/moment"; +import { ColorGraphBlue1 } from "@shared/constants/color-constants"; +import { recordToEntries } from "@shared/helpers/record.helper"; +import { IoTDeviceService } from "@applications/iot-devices/iot-device.service"; /** * Ordered from "worst" to "best" (from DR0 and up) */ -const dataRateColors = [ - '#F57A2F', - '#FFA620', - '#F6CE06', - '#FFEB3B', - '#CDDC39', - '#93E528', - '#72D144', - '#56B257', -]; +const dataRateColors = ["#F57A2F", "#FFA620", "#F6CE06", "#FFEB3B", "#CDDC39", "#93E528", "#72D144", "#56B257"]; @Component({ - selector: 'app-iot-device-history-tab', - templateUrl: './iot-device-history-tab.component.html', - styleUrls: ['./iot-device-history-tab.component.scss'], + selector: "app-iot-device-history-tab", + templateUrl: "./iot-device-history-tab.component.html", + styleUrls: ["./iot-device-history-tab.component.scss"], }) export class IotDeviceHistoryTabComponent implements OnInit { - device: IotDevice; - dataRateChartData: ChartConfiguration['data'] = { datasets: [] }; - rssiChartData: ChartConfiguration['data'] = { datasets: [] }; - snrChartData: ChartConfiguration['data'] = { datasets: [] }; + device: IotDevice; + dataRateChartData: ChartConfiguration["data"] = { datasets: [] }; + rssiChartData: ChartConfiguration["data"] = { datasets: [] }; + snrChartData: ChartConfiguration["data"] = { datasets: [] }; - dataRateChartOptions: ChartConfiguration['options'] = { - scales: { - x: { stacked: true }, - y: { stacked: true }, - }, - plugins: { - tooltip: { - mode: 'index', - position: 'average', - }, - }, - }; - constructor( - private iotDeviceDetailsService: IotDeviceDetailsService, - private iotDeviceService: IoTDeviceService - ) {} - - ngOnInit(): void { - this.device = this.iotDeviceDetailsService.device; - this.getDeviceStats(); - } + dataRateChartOptions: ChartConfiguration["options"] = { + scales: { + x: { stacked: true }, + y: { stacked: true }, + }, + plugins: { + tooltip: { + mode: "index", + position: "average", + }, + }, + }; + constructor(private iotDeviceDetailsService: IotDeviceDetailsService, private iotDeviceService: IoTDeviceService) {} - private getDeviceStats(): void { - if ( - this.device?.type !== DeviceType.LORAWAN && - this.device?.type !== DeviceType.SIGFOX - ) { - return; + ngOnInit(): void { + this.device = this.iotDeviceDetailsService.device; + this.getDeviceStats(); } - this.iotDeviceService.getDeviceStats(this.device.id).subscribe( - (response) => { - if (!response) { - return; + private getDeviceStats(): void { + if (this.device?.type !== DeviceType.LORAWAN && this.device?.type !== DeviceType.SIGFOX) { + return; } - const { - rssiDatasets, - snrDatasets, - dataRateDatasets, - labels, - } = response.reduce( - ( - res: { - rssiDatasets: ChartConfiguration['data']['datasets']; - snrDatasets: ChartConfiguration['data']['datasets']; - dataRateDatasets: ChartConfiguration['data']['datasets']; - labels: ChartConfiguration['data']['labels']; - }, - data - ) => { - // Hide zero-values with null - res.rssiDatasets[0].data.push(data.rssi || null); - res.snrDatasets[0].data.push(data.snr || null); - this.addDataRate(res.dataRateDatasets, data.rxPacketsPerDr); + this.iotDeviceService.getDeviceStats(this.device.id).subscribe( + response => { + if (!response) { + return; + } - res.labels.push(moment(data.timestamp).format('MMM D')); - return res; - }, - { - rssiDatasets: [ - { - data: [], - borderColor: ColorGraphBlue1, - backgroundColor: ColorGraphBlue1, - }, - ], - snrDatasets: [ - { - data: [], - borderColor: ColorGraphBlue1, - backgroundColor: ColorGraphBlue1, - }, - ], - dataRateDatasets: this.initDataRates(), - labels: [], - } - ); + const { rssiDatasets, snrDatasets, dataRateDatasets, labels } = response.reduce( + ( + res: { + rssiDatasets: ChartConfiguration["data"]["datasets"]; + snrDatasets: ChartConfiguration["data"]["datasets"]; + dataRateDatasets: ChartConfiguration["data"]["datasets"]; + labels: ChartConfiguration["data"]["labels"]; + }, + data + ) => { + // Hide zero-values with null + res.rssiDatasets[0].data.push(data.rssi || null); + res.snrDatasets[0].data.push(data.snr || null); + this.addDataRate(res.dataRateDatasets, data.rxPacketsPerDr); - // Cleanup before saving - this.removeEmptyDatasets(dataRateDatasets); + res.labels.push(moment(data.timestamp).format("MMM D")); + return res; + }, + { + rssiDatasets: [ + { + data: [], + borderColor: ColorGraphBlue1, + backgroundColor: ColorGraphBlue1, + }, + ], + snrDatasets: [ + { + data: [], + borderColor: ColorGraphBlue1, + backgroundColor: ColorGraphBlue1, + }, + ], + dataRateDatasets: this.initDataRates(), + labels: [], + } + ); - this.rssiChartData = { datasets: rssiDatasets, labels }; - this.snrChartData = { datasets: snrDatasets, labels }; - this.dataRateChartData = { datasets: dataRateDatasets, labels }; - }, - (_error) => {} - ); - } + // Cleanup before saving + this.removeEmptyDatasets(dataRateDatasets); - private initDataRates(): ChartConfiguration['data']['datasets'] { - return dataRateColors.map((color, i) => ({ - data: [], - label: i.toString(), - borderColor: color, - backgroundColor: color, - })); - } + this.rssiChartData = { datasets: rssiDatasets, labels }; + this.snrChartData = { datasets: snrDatasets, labels }; + this.dataRateChartData = { datasets: dataRateDatasets, labels }; + }, + _error => {} + ); + } - private addDataRate( - datasets: ChartConfiguration['data']['datasets'], - dataRate: Record | undefined - ) { - if (!dataRate) { - return; + private initDataRates(): ChartConfiguration["data"]["datasets"] { + return dataRateColors.map((color, i) => ({ + data: [], + label: i.toString(), + borderColor: color, + backgroundColor: color, + })); } - const dataRateList = recordToEntries(dataRate, false); - datasets.forEach((dataset) => { - if (!dataRateList.length) { - dataset.data.push(0); - return; - } + private addDataRate( + datasets: ChartConfiguration["data"]["datasets"], + dataRate: Record | undefined + ) { + if (!dataRate) { + return; + } + + const dataRateList = recordToEntries(dataRate, false); + datasets.forEach(dataset => { + if (!dataRateList.length) { + dataset.data.push(0); + return; + } - const match = dataRateList.find( - (record) => record.key.toString() === dataset.label - ); - match ? dataset.data.push(match.value) : dataset.data.push(0); - }); - } + const match = dataRateList.find(record => record.key.toString() === dataset.label); + match ? dataset.data.push(match.value) : dataset.data.push(0); + }); + } - private removeEmptyDatasets( - datasets: ChartConfiguration['data']['datasets'] - ): void { - for (let i = datasets.length - 1; i >= 0; i--) { - const dataset = datasets[i]; - if (!dataset.data.some((point) => point !== 0)) { - datasets.splice(i, 1); - } + private removeEmptyDatasets(datasets: ChartConfiguration["data"]["datasets"]): void { + for (let i = datasets.length - 1; i >= 0; i--) { + const dataset = datasets[i]; + if (!dataset.data.some(point => point !== 0)) { + datasets.splice(i, 1); + } + } } - } } diff --git a/src/app/applications/iot-devices/iot-device-details-service.ts b/src/app/applications/iot-devices/iot-device-details-service.ts index a5c16e25c..d94b7f1a2 100644 --- a/src/app/applications/iot-devices/iot-device-details-service.ts +++ b/src/app/applications/iot-devices/iot-device-details-service.ts @@ -1,9 +1,9 @@ -import { Injectable } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; +import { Injectable } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; -@Injectable({ providedIn: 'root' }) +@Injectable({ providedIn: "root" }) export class IotDeviceDetailsService { - device: IotDevice; - latitude: number; - longitude: number; + device: IotDevice; + latitude: number; + longitude: number; } diff --git a/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.html b/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.html index 6094bf137..073811319 100644 --- a/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.html +++ b/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.html @@ -1,242 +1,437 @@ - +
-
-
    -
  • - {{error | translate}} -
  • -
-
- -
-
-
- -
-
- -
-
- -
-
- -
-
-
- -
-
- * - -
- -
- - {{application.name}} -
-
- - -
- -
- -
-

{{'DBLCLICKINFO' | translate}}

-
- - -
-
- - -
- -
- - +
+
    +
  • + {{ error | translate }} +
  • +
-
- - - - {{'QUESTION.DEVICE-MODEL-SELECT-NON' | translate }} - - - {{deviceModel.body.name}} - - +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
-
- -
-

{{'IOTDEVICE.LORAWANSETUP' | translate}}

-
+
+
+ * + +
-
- - -
+
+ + {{ application.name }} +
+
+ + +
- -
- * - -
-
+
+ +
+

{{ "DBLCLICKINFO" | translate }}

+
+ + +
+
+ + +
-
- -

{{'QUESTION.OTAA' | translate}}

-

{{'QUESTION.OTAA-ABP-CONFIG-HELP' | translate}}

- - + +
-
- -

{{'QUESTION.ABP' | translate}}

-

{{'QUESTION.OTAA-ABP-CONFIG-HELP' | translate}}

- - + + + + {{ "QUESTION.DEVICE-MODEL-SELECT-NON" | translate }} + + + {{ deviceModel.body.name }} + +
- +
+
- - +

{{ "IOTDEVICE.LORAWANSETUP" | translate }}

- - + +
+ +
+ * + +
+
+
- - + +

{{ "QUESTION.OTAA" | translate }}

+

{{ "QUESTION.OTAA-ABP-CONFIG-HELP" | translate }}

+
+ + +
+
+ + +

{{ "QUESTION.ABP" | translate }}

+

{{ "QUESTION.OTAA-ABP-CONFIG-HELP" | translate }}

+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
- - + +
+ + {{ "QUESTION.SKIPFCNTCHECK-YES" | translate }} + +
-
-
+
+ + + + + + + + + + +
+

{{ "QUESTION.METADATA" | translate }}

+ + +
- -
- - {{'QUESTION.SKIPFCNTCHECK-YES' | translate}} - -
+ +
- - - - - - - - - - - - -
-

{{ "QUESTION.METADATA" | translate}}

- - -
-
- - -
diff --git a/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.spec.ts b/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.spec.ts index 461449ee2..bfd89e166 100644 --- a/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.spec.ts +++ b/src/app/applications/iot-devices/iot-device-edit/iot-device-edit.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { IotDeviceEditComponent } from './iot-device-edit.component'; +import { IotDeviceEditComponent } from "./iot-device-edit.component"; -describe('IotDeviceEditComponent', () => { - let component: IotDeviceEditComponent; - let fixture: ComponentFixture; +describe("IotDeviceEditComponent", () => { + let component: IotDeviceEditComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [IotDeviceEditComponent] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [IotDeviceEditComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(IotDeviceEditComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IotDeviceEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.html b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.html index eb30c3d8c..28be65f38 100644 --- a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.html +++ b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.html @@ -1,64 +1,68 @@
- - + +
-
- - - - -
-
- - - - -
+
+ + + + +
+
+ + + + +
diff --git a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.scss b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.scss index 276abe9d1..aaae8f4e6 100644 --- a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.scss +++ b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.scss @@ -1,4 +1,4 @@ .form-info-icon { - margin-left: 5px; - cursor: pointer; + margin-left: 5px; + cursor: pointer; } diff --git a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.ts b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.ts index 557c2f2ca..8dc97cd7b 100644 --- a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.ts +++ b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component.ts @@ -1,23 +1,23 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { AuthenticationType } from '@shared/enums/authentication-type'; -import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; -import { MqttSharedSettings } from '@shared/models/mqtt-shared-settings.model'; +import { Component, Input, OnInit } from "@angular/core"; +import { AuthenticationType } from "@shared/enums/authentication-type"; +import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons"; +import { MqttSharedSettings } from "@shared/models/mqtt-shared-settings.model"; @Component({ - selector: 'app-mqtt-authentication-select', - templateUrl: './mqtt-authentication-select.component.html', - styleUrls: ['./mqtt-authentication-select.component.scss'], + selector: "app-mqtt-authentication-select", + templateUrl: "./mqtt-authentication-select.component.html", + styleUrls: ["./mqtt-authentication-select.component.scss"], }) export class MqttAuthenticationSelectComponent implements OnInit { - @Input() settings: MqttSharedSettings; - @Input() editMode: boolean = false; - @Input() formFailedSubmit: boolean = false; - @Input() errorFields: string[]; + @Input() settings: MqttSharedSettings; + @Input() editMode: boolean = false; + @Input() formFailedSubmit: boolean = false; + @Input() errorFields: string[]; - constructor() {} + constructor() {} - ngOnInit(): void {} + ngOnInit(): void {} - protected readonly AuthenticationType = AuthenticationType; - protected readonly faQuestionCircle = faQuestionCircle; + protected readonly AuthenticationType = AuthenticationType; + protected readonly faQuestionCircle = faQuestionCircle; } diff --git a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.html b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.html index 5318ee5db..07371fb46 100644 --- a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.html +++ b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.html @@ -1,171 +1,193 @@
-
-

{{'QUESTION.MQTT.TITLE' | translate}}

-
-
- - - - -
- - - - - -
- - -
-
- - +
+

{{ "QUESTION.MQTT.TITLE" | translate }}

- - -
- - -
- - - - -
-
- + + [icon]="faQuestionCircle" + class="form-info-icon" + [matTooltip]="'QUESTION.MQTT.SUBTYPE-HOVER' | translate" + matTooltipPosition="above" + matTooltipShowDelay="600" + matTooltipHideDelay="2000" + > - -
-
- - - - -
-
- -
- OBS!

{{ 'QUESTION.MQTT.CERTIFICATE-OBS' | translate }}

-
-

{{ 'QUESTION.MQTT.CONFIG-HELP' | translate }}

+ +
+ + + + + +
+ + +
+
+ + +
+
+ + +
+ + +
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+
+ OBS! +

{{ "QUESTION.MQTT.CERTIFICATE-OBS" | translate }}

+
+
+

{{ "QUESTION.MQTT.CONFIG-HELP" | translate }}

+
diff --git a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.scss b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.scss index 276abe9d1..aaae8f4e6 100644 --- a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.scss +++ b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.scss @@ -1,4 +1,4 @@ .form-info-icon { - margin-left: 5px; - cursor: pointer; + margin-left: 5px; + cursor: pointer; } diff --git a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.ts b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.ts index 282510dc0..9d740742b 100644 --- a/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.ts +++ b/src/app/applications/iot-devices/iot-device-edit/mqtt-device-edit/mqtt-device-edit.component.ts @@ -1,35 +1,32 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { TranslateService } from '@ngx-translate/core'; -import { DeviceType } from '@shared/enums/device-type'; -import { AuthenticationType } from '@shared/enums/authentication-type'; -import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; +import { Component, Input, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { TranslateService } from "@ngx-translate/core"; +import { DeviceType } from "@shared/enums/device-type"; +import { AuthenticationType } from "@shared/enums/authentication-type"; +import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons"; @Component({ - selector: 'app-mqtt-device-edit', - templateUrl: './mqtt-device-edit.component.html', - styleUrls: ['./mqtt-device-edit.component.scss'], + selector: "app-mqtt-device-edit", + templateUrl: "./mqtt-device-edit.component.html", + styleUrls: ["./mqtt-device-edit.component.scss"], }) export class MqttDeviceEditComponent implements OnInit { - @Input() iotDevice: IotDevice; - @Input() formFailedSubmit: boolean = false; - @Input() errorFields: string[]; - @Input() editMode: boolean = false; - public mqttDeviceTypes = [ - DeviceType.MQTT_INTERNAL_BROKER, - DeviceType.MQTT_EXTERNAL_BROKER, - ]; + @Input() iotDevice: IotDevice; + @Input() formFailedSubmit: boolean = false; + @Input() errorFields: string[]; + @Input() editMode: boolean = false; + public mqttDeviceTypes = [DeviceType.MQTT_INTERNAL_BROKER, DeviceType.MQTT_EXTERNAL_BROKER]; - constructor(public translate: TranslateService) {} + constructor(public translate: TranslateService) {} - ngOnInit(): void { - this.translate.use('da'); - if (this.iotDevice?.id) { - this.editMode = true; + ngOnInit(): void { + this.translate.use("da"); + if (this.iotDevice?.id) { + this.editMode = true; + } } - } - protected readonly DeviceType = DeviceType; - protected readonly AuthenticationType = AuthenticationType; - protected readonly faQuestionCircle = faQuestionCircle; + protected readonly DeviceType = DeviceType; + protected readonly AuthenticationType = AuthenticationType; + protected readonly faQuestionCircle = faQuestionCircle; } diff --git a/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.html b/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.html index 9b4913ce5..f2e7ec74c 100644 --- a/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.html +++ b/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.html @@ -1,105 +1,173 @@
-
-

{{'QUESTION.SIGFOX.TITLE' | translate}}

-
-
- - -
-
-
- - {{'QUESTION.SIGFOX.CONNECTTOEXISTINGDEVICEINBACKEND' | translate}} +
+

{{ "QUESTION.SIGFOX.TITLE" | translate }}

-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - - -

{{'QUESTION.SIGFOX.ENDPRODUCTCERTIFICATE-HELP-TITLE' | translate}} -

-
-
- -
- -
- - {{'QUESTION.SIGFOX.PROTOTYPE' | translate}} -
-
-
-
-
-
-
- - + - -
-
-
-

{{'QUESTION.SIGFOX.SELECTGROUPFIRST' | translate}}

+
-
- {{'QUESTION.SIGFOX.DISCLAIMER' | translate}} - - {{'QUESTION.SIGFOX.DISCLAIMER-CLICK' | translate}} - +
+
+ + {{ "QUESTION.SIGFOX.CONNECTTOEXISTINGDEVICEINBACKEND" | translate }} +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +

{{ "QUESTION.SIGFOX.ENDPRODUCTCERTIFICATE-HELP-TITLE" | translate }}

+
+
+ +
+ +
+ + {{ "QUESTION.SIGFOX.PROTOTYPE" | translate }} +
+
+
+
+
+
+
+ + +
+
+
+

{{ "QUESTION.SIGFOX.SELECTGROUPFIRST" | translate }}

+
+
+ {{ "QUESTION.SIGFOX.DISCLAIMER" | translate }} + + {{ "QUESTION.SIGFOX.DISCLAIMER-CLICK" | translate }} + +
-
- \ No newline at end of file + diff --git a/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.ts b/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.ts index faf3d8804..887d969df 100644 --- a/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.ts +++ b/src/app/applications/iot-devices/iot-device-edit/sigfox-device-edit/sigfox-device-edit.component.ts @@ -1,78 +1,72 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { TranslateService } from '@ngx-translate/core'; -import { SigfoxGroup } from '@shared/models/sigfox-group.model'; -import { SigfoxService } from '@shared/services/sigfox.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { SigfoxDeviceType, SigfoxDeviceTypeResponse } from '@shared/models/sigfox-device-type.model'; -import { SigfoxDevice, SigfoxDevicesResponse } from '@app/sigfox/sigfox-device.model'; +import { Component, Input, OnInit } from "@angular/core"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { TranslateService } from "@ngx-translate/core"; +import { SigfoxGroup } from "@shared/models/sigfox-group.model"; +import { SigfoxService } from "@shared/services/sigfox.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { SigfoxDeviceType, SigfoxDeviceTypeResponse } from "@shared/models/sigfox-device-type.model"; +import { SigfoxDevice, SigfoxDevicesResponse } from "@app/sigfox/sigfox-device.model"; @Component({ - selector: 'app-sigfox-device-edit', - templateUrl: './sigfox-device-edit.component.html', - styleUrls: ['./sigfox-device-edit.component.scss'] + selector: "app-sigfox-device-edit", + templateUrl: "./sigfox-device-edit.component.html", + styleUrls: ["./sigfox-device-edit.component.scss"], }) export class SigfoxDeviceEditComponent implements OnInit { + @Input() iotDevice: IotDevice; + @Input() errorFields: string[]; + @Input() formFailedSubmit = false; + public errorMessages: any; + private organizationId: number; + public sigfoxGroups: SigfoxGroup[] = []; + public sigfoxDevices: SigfoxDevice[]; + public sigfoxDeviceTypes: SigfoxDeviceType[] = []; + public editMode = false; - @Input() iotDevice: IotDevice; - @Input() errorFields: string[]; - @Input() formFailedSubmit = false; - public errorMessages: any; - private organizationId: number; - public sigfoxGroups: SigfoxGroup[] = []; - public sigfoxDevices: SigfoxDevice[]; - public sigfoxDeviceTypes: SigfoxDeviceType[] = []; - public editMode = false; + constructor( + public translate: TranslateService, + private sigfoxService: SigfoxService, + private sharedVariable: SharedVariableService + ) {} - constructor( - public translate: TranslateService, - private sigfoxService: SigfoxService, - private sharedVariable: SharedVariableService - ) { - } - - ngOnInit(): void { - this.translate.use('da'); - this.organizationId = this.sharedVariable.getSelectedOrganisationId(); - this.getGroups(); - if (this.iotDevice?.id) { - this.editMode = true; - this.getDeviceTypes(this.iotDevice.sigfoxSettings.groupId); + ngOnInit(): void { + this.translate.use("da"); + this.organizationId = this.sharedVariable.getSelectedOrganisationId(); + this.getGroups(); + if (this.iotDevice?.id) { + this.editMode = true; + this.getDeviceTypes(this.iotDevice.sigfoxSettings.groupId); + } + } + getGroups() { + this.sigfoxService.getGroups(this.organizationId).subscribe((response: any) => { + this.sigfoxGroups = response.data; + }); } - } - getGroups() { - this.sigfoxService.getGroups(this.organizationId) - .subscribe((response: any) => { - this.sigfoxGroups = response.data; - }); - } - - getDevicesInGroup(groupId: number) { - this.sigfoxService.getDevices(groupId) - .subscribe((response: SigfoxDevicesResponse) => { - this.sigfoxDevices = response.data; - }); - } - onGroupChange() { - this.adjustModelOnChangedGroup(); - if (this.iotDevice.sigfoxSettings.groupId) { - this.getDeviceTypes(this.iotDevice?.sigfoxSettings?.groupId); - this.getDevicesInGroup(this.iotDevice?.sigfoxSettings?.groupId); - } - } + getDevicesInGroup(groupId: number) { + this.sigfoxService.getDevices(groupId).subscribe((response: SigfoxDevicesResponse) => { + this.sigfoxDevices = response.data; + }); + } - adjustModelOnChangedGroup() { - this.iotDevice.sigfoxSettings.groupId = +this.iotDevice.sigfoxSettings.groupId; - this.iotDevice.sigfoxSettings.endProductCertificate = null; - this.iotDevice.sigfoxSettings.deviceTypeId = null; - this.iotDevice.sigfoxSettings.deviceId = null; - } + onGroupChange() { + this.adjustModelOnChangedGroup(); + if (this.iotDevice.sigfoxSettings.groupId) { + this.getDeviceTypes(this.iotDevice?.sigfoxSettings?.groupId); + this.getDevicesInGroup(this.iotDevice?.sigfoxSettings?.groupId); + } + } - getDeviceTypes(groupId: number) { - this.sigfoxService.getDeviceTypes(groupId) - .subscribe( (response: SigfoxDeviceTypeResponse) => { - this.sigfoxDeviceTypes = response.data; - }); - } + adjustModelOnChangedGroup() { + this.iotDevice.sigfoxSettings.groupId = +this.iotDevice.sigfoxSettings.groupId; + this.iotDevice.sigfoxSettings.endProductCertificate = null; + this.iotDevice.sigfoxSettings.deviceTypeId = null; + this.iotDevice.sigfoxSettings.deviceId = null; + } + getDeviceTypes(groupId: number) { + this.sigfoxService.getDeviceTypes(groupId).subscribe((response: SigfoxDeviceTypeResponse) => { + this.sigfoxDeviceTypes = response.data; + }); + } } diff --git a/src/app/applications/iot-devices/iot-device.service.ts b/src/app/applications/iot-devices/iot-device.service.ts index a6f4be1ad..766a3820b 100644 --- a/src/app/applications/iot-devices/iot-device.service.ts +++ b/src/app/applications/iot-devices/iot-device.service.ts @@ -1,112 +1,93 @@ -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; import { - IotDevice, - IoTDevicesMinimalResponse, - IotDevicesImportResponse, - IotDeviceImportRequest, - IoTDeviceStatsResponse, -} from './iot-device.model'; -import { RestService } from 'src/app/shared/services/rest.service'; -import { map } from 'rxjs/operators'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; + IotDevice, + IoTDevicesMinimalResponse, + IotDevicesImportResponse, + IotDeviceImportRequest, + IoTDeviceStatsResponse, +} from "./iot-device.model"; +import { RestService } from "src/app/shared/services/rest.service"; +import { map } from "rxjs/operators"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class IoTDeviceService { - private BASEURL = 'iot-device'; + private BASEURL = "iot-device"; - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - createIoTDevice(body: IotDevice): Observable { - return this.restService.post(this.BASEURL, body); - } + createIoTDevice(body: IotDevice): Observable { + return this.restService.post(this.BASEURL, body); + } - updateIoTDevice(body: IotDevice, id: number): Observable { - return this.restService.put(this.BASEURL, body, id, { - observe: 'response', - }); - } + updateIoTDevice(body: IotDevice, id: number): Observable { + return this.restService.put(this.BASEURL, body, id, { + observe: "response", + }); + } - createIoTDevices( - body: IotDeviceImportRequest - ): Observable { - return this.restService.post(`${this.BASEURL}/createMany`, body); - } + createIoTDevices(body: IotDeviceImportRequest): Observable { + return this.restService.post(`${this.BASEURL}/createMany`, body); + } - updateIoTDevices( - body: IotDeviceImportRequest - ): Observable { - return this.restService.post(`${this.BASEURL}/updateMany`, body); - } + updateIoTDevices(body: IotDeviceImportRequest): Observable { + return this.restService.post(`${this.BASEURL}/updateMany`, body); + } - getIoTDevice(id: number): Observable { - return this.restService.get(this.BASEURL, {}, id).pipe( - map((response: IotDevice) => { - return { - name: response.name, - application: response.application, - location: response.location, - commentOnLocation: response.commentOnLocation, - comment: response.comment, - type: response.type, - receivedMessagesMetadata: response.receivedMessagesMetadata, - metadata: response.metadata, - apiKey: response.apiKey, - id: response.id, - createdAt: response.createdAt, - updatedAt: response.updatedAt, - applicationId: response.applicationId, - longitude: response.longitude, - latitude: response.latitude, - deviceModelId: response.deviceModel?.id, - latestReceivedMessage: response.latestReceivedMessage, - lorawanSettings: response.lorawanSettings, - sigfoxSettings: response.sigfoxSettings, - mqttInternalBrokerSettings: response.mqttInternalBrokerSettings, - mqttExternalBrokerSettings: response.mqttExternalBrokerSettings, - createdBy: response.createdBy, - updatedBy: response.updatedBy, - createdByName: this.userMinimalService.getUserNameFrom( - response.createdBy - ), - updatedByName: this.userMinimalService.getUserNameFrom( - response.updatedBy - ), - }; - }) - ); - } + getIoTDevice(id: number): Observable { + return this.restService.get(this.BASEURL, {}, id).pipe( + map((response: IotDevice) => { + return { + name: response.name, + application: response.application, + location: response.location, + commentOnLocation: response.commentOnLocation, + comment: response.comment, + type: response.type, + receivedMessagesMetadata: response.receivedMessagesMetadata, + metadata: response.metadata, + apiKey: response.apiKey, + id: response.id, + createdAt: response.createdAt, + updatedAt: response.updatedAt, + applicationId: response.applicationId, + longitude: response.longitude, + latitude: response.latitude, + deviceModelId: response.deviceModel?.id, + latestReceivedMessage: response.latestReceivedMessage, + lorawanSettings: response.lorawanSettings, + sigfoxSettings: response.sigfoxSettings, + mqttInternalBrokerSettings: response.mqttInternalBrokerSettings, + mqttExternalBrokerSettings: response.mqttExternalBrokerSettings, + createdBy: response.createdBy, + updatedBy: response.updatedBy, + createdByName: this.userMinimalService.getUserNameFrom(response.createdBy), + updatedByName: this.userMinimalService.getUserNameFrom(response.updatedBy), + }; + }) + ); + } - getIoTDevicesUsingPayloadDecoderMinimal( - payloadDecoderId: number, - limit: number, - offset: number - ): Observable { - return this.restService.get( - `${this.BASEURL}/minimalByPayloadDecoder`, - { limit, offset }, - payloadDecoderId - ); - } + getIoTDevicesUsingPayloadDecoderMinimal( + payloadDecoderId: number, + limit: number, + offset: number + ): Observable { + return this.restService.get(`${this.BASEURL}/minimalByPayloadDecoder`, { limit, offset }, payloadDecoderId); + } - deleteIoTDevice(id: number) { - return this.restService.delete(this.BASEURL, id); - } + deleteIoTDevice(id: number) { + return this.restService.delete(this.BASEURL, id); + } - getDeviceStats(id: number): Observable { - return this.restService.get(`${this.BASEURL}/stats`, null, id); - } + getDeviceStats(id: number): Observable { + return this.restService.get(`${this.BASEURL}/stats`, null, id); + } - resetHttpDeviceApiKey(id: number): Observable> { - return this.restService.put( - `${this.BASEURL}/resetHttpDeviceApiKey`, - null, - id - ); - } + resetHttpDeviceApiKey(id: number): Observable> { + return this.restService.put(`${this.BASEURL}/resetHttpDeviceApiKey`, null, id); + } } diff --git a/src/app/applications/iot-devices/iot-devices-tab/export-csv-dialog/export-csv-dialog.component.html b/src/app/applications/iot-devices/iot-devices-tab/export-csv-dialog/export-csv-dialog.component.html index ade88d38d..c29089a9a 100644 --- a/src/app/applications/iot-devices/iot-devices-tab/export-csv-dialog/export-csv-dialog.component.html +++ b/src/app/applications/iot-devices/iot-devices-tab/export-csv-dialog/export-csv-dialog.component.html @@ -1,12 +1,12 @@ -

{{'DIALOG.EXPORT-CSV.TITLE' | translate}}

+

{{ "DIALOG.EXPORT-CSV.TITLE" | translate }}

- {{ 'DIALOG.EXPORT-CSV.BODY' | translate }} + {{ "DIALOG.EXPORT-CSV.BODY" | translate }}
- - + +
diff --git a/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.html b/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.html index 78a27c582..91a4c682b 100644 --- a/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.html +++ b/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.html @@ -1,27 +1,35 @@
-
-
-
-
- - +
+
+
+
+ + +
+
+ + +
+ + + + + +
-
- - -
- - - - - -
-
diff --git a/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.ts b/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.ts index ef79b7efa..d70c42bcb 100644 --- a/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.ts +++ b/src/app/applications/iot-devices/iot-devices-tab/iot-devices-tab.component.ts @@ -1,48 +1,46 @@ -import { Component, OnInit } from '@angular/core'; -import { ApplicationService } from '@applications/application.service'; -import { MatDialog } from '@angular/material/dialog'; -import { ExportCsvDialogComponent } from '@applications/iot-devices/iot-devices-tab/export-csv-dialog/export-csv-dialog.component'; -import { RestService } from '@shared/services/rest.service'; -import { Download } from '@shared/helpers/download.helper'; -import { DownloadService } from '@shared/services/download.service'; -import { environment } from '@environments/environment'; -import { Observable } from 'rxjs'; +import { Component, OnInit } from "@angular/core"; +import { ApplicationService } from "@applications/application.service"; +import { MatDialog } from "@angular/material/dialog"; +import { ExportCsvDialogComponent } from "@applications/iot-devices/iot-devices-tab/export-csv-dialog/export-csv-dialog.component"; +import { RestService } from "@shared/services/rest.service"; +import { Download } from "@shared/helpers/download.helper"; +import { DownloadService } from "@shared/services/download.service"; +import { environment } from "@environments/environment"; +import { Observable } from "rxjs"; @Component({ - selector: 'app-iot-devices-tab', - templateUrl: './iot-devices-tab.component.html', - styleUrls: ['./iot-devices-tab.component.scss'], + selector: "app-iot-devices-tab", + templateUrl: "./iot-devices-tab.component.html", + styleUrls: ["./iot-devices-tab.component.scss"], }) export class IotDevicesTabComponent implements OnInit { - download$: Observable; - private applicationId: number; + download$: Observable; + private applicationId: number; - constructor( - public applicationService: ApplicationService, - private dialog: MatDialog, - private downloader: DownloadService - ) {} - ngOnInit(): void { - this.applicationId = this.applicationService.id; - } + constructor( + public applicationService: ApplicationService, + private dialog: MatDialog, + private downloader: DownloadService + ) {} + ngOnInit(): void { + this.applicationId = this.applicationService.id; + } - get openDialogFunc() { - return this.openExportCsvDialog.bind(this); - } + get openDialogFunc() { + return this.openExportCsvDialog.bind(this); + } - public openExportCsvDialog() { - const dialog = this.dialog.open(ExportCsvDialogComponent); + public openExportCsvDialog() { + const dialog = this.dialog.open(ExportCsvDialogComponent); - dialog.afterClosed().subscribe(async (result) => { - if (result) { - // Start csv download - this.download$ = this.downloader.download( - environment.baseUrl + - 'iot-device/getDevicesMetadataCsv/' + - this.applicationId, - 'iotDeviceMetadata.csv' - ); - } - }); - } + dialog.afterClosed().subscribe(async result => { + if (result) { + // Start csv download + this.download$ = this.downloader.download( + environment.baseUrl + "iot-device/getDevicesMetadataCsv/" + this.applicationId, + "iotDeviceMetadata.csv" + ); + } + }); + } } diff --git a/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.html b/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.html index f61ebda98..ab3a6a851 100644 --- a/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.html +++ b/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.html @@ -1,147 +1,168 @@
-
- -
- - - {{'IOTDEVICE-TABLE-ROW.NOT-SUPPORTED-SHORT' | translate}} - - - {{'IOTDEVICE-TABLE-ROW.NOT-AVAILABLE' | translate}} - - - - - - - +
+ +
+
- {{ 'APPLICATION-TABLE.NAME' | translate }} - - {{iotDevice.name}} -
+ + {{ "IOTDEVICE-TABLE-ROW.NOT-SUPPORTED-SHORT" | translate }} + + + {{ "IOTDEVICE-TABLE-ROW.NOT-AVAILABLE" | translate }} + - - - - - + + + + + - - - - + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + + + + + - - - - + - - - - - - + - - - - - - + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + - - -
{{ 'IOT-TABLE.NETWORK-TECHNOLOGY' | translate }}{{"IOT-DEVICE-TYPES." + iotDevice.type | translate }} + {{ "APPLICATION-TABLE.NAME" | translate }} + + {{ + iotDevice.name + }} + {{ 'GATEWAY.PLACEMENT-LABEL' | translate }}{{ iotDevice.commentOnLocation ? truncateText(iotDevice.commentOnLocation) : '-' }}{{ "IOT-TABLE.NETWORK-TECHNOLOGY" | translate }}{{ "IOT-DEVICE-TYPES." + iotDevice.type | translate }}{{ 'IOTDEVICE.DEVICEMODEL' | translate }}{{ iotDevice.deviceModel?.body?.name ?? '-' }}{{ "GATEWAY.PLACEMENT-LABEL" | translate }} + {{ iotDevice.commentOnLocation ? truncateText(iotDevice.commentOnLocation) : "-" }} + {{ 'IOTDEVICE.LORA.DEVICEPROFILE' | translate }}{{ iotDevice.deviceProfileName ?? '-'}}{{ "IOTDEVICE.DEVICEMODEL" | translate }}{{ iotDevice.deviceModel?.body?.name ?? "-" }}{{ 'IOT-TABLE.DEV-EUI' | translate }}{{iotDevice.deviceEUI ?? '-'}}{{ "IOTDEVICE.LORA.DEVICEPROFILE" | translate }}{{ iotDevice.deviceProfileName ?? "-" }}{{ 'IOT-TABLE.APP-KEY' | translate }}{{iotDevice.OTAAapplicationKey ?? '-'}}{{ "IOT-TABLE.DEV-EUI" | translate }}{{ iotDevice.deviceEUI ?? "-" }}{{ "IOT-TABLE.APP-KEY" | translate }}{{ iotDevice.OTAAapplicationKey ?? "-" }} - {{ 'IOT-TABLE.RSSI' | translate }} - - -
- {{iotDevice.latestReceivedMessage.rssi}} -
+ + +
+ {{ "IOT-TABLE.RSSI" | translate }} + + +
+ {{ iotDevice.latestReceivedMessage.rssi }} +
+
+
- {{ 'IOT-TABLE.SNR' | translate }} - - -
- {{iotDevice.latestReceivedMessage?.snr}} -
+ + +
+ {{ "IOT-TABLE.SNR" | translate }} + + +
+ {{ iotDevice.latestReceivedMessage?.snr }} +
+
+
{{ 'APPLICATION-TABLE.DATA-TARGETS' | translate }}{{iotDevice.connections?.length ?? 0}} + {{ "APPLICATION-TABLE.DATA-TARGETS" | translate }} + {{ iotDevice.connections?.length ?? 0 }} - {{ 'IOT-TABLE.BATTERY' | translate }} - -
- - -
- -
- {{ 'IOTDEVICE-TABLE-ROW.NOT-SUPPORTED-SHORT' | translate }} -
-
-
+ {{ "IOT-TABLE.BATTERY" | translate }} + +
+ + +
+ +
+ {{ "IOTDEVICE-TABLE-ROW.NOT-SUPPORTED-SHORT" | translate }} +
+
+
- {{ 'IOT-TABLE.ACTIVE' | translate }} - {{lastActive(iotDevice)}} + {{ "IOT-TABLE.ACTIVE" | translate }} + {{ lastActive(iotDevice) }} - - + +
- - + + + + +
diff --git a/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.scss b/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.scss index d3f5a12fa..e69de29bb 100644 --- a/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.scss +++ b/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.scss @@ -1 +0,0 @@ - diff --git a/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.spec.ts b/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.spec.ts index fb8f6bc40..6f782c0ae 100644 --- a/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.spec.ts +++ b/src/app/applications/iot-devices/iot-devices-table/iot-devices-table.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { IotDevicesTableComponent } from './iot-devices-table.component'; +import { IotDevicesTableComponent } from "./iot-devices-table.component"; -describe('IotDevicesTableComponent', () => { - let component: IotDevicesTableComponent; - let fixture: ComponentFixture; +describe("IotDevicesTableComponent", () => { + let component: IotDevicesTableComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ IotDevicesTableComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [IotDevicesTableComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(IotDevicesTableComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IotDevicesTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/applications/iot-devices/iot-devices.module.ts b/src/app/applications/iot-devices/iot-devices.module.ts index 9c74297fb..3e40eae7e 100644 --- a/src/app/applications/iot-devices/iot-devices.module.ts +++ b/src/app/applications/iot-devices/iot-devices.module.ts @@ -1,78 +1,78 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; -import { TranslateModule } from '@ngx-translate/core'; -import { FormModule } from '@shared/components/forms/form.module'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { DownlinkComponent } from './iot-device-detail/downlink/downlink.component'; -import { IotDeviceDetailGenericComponent } from './iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component'; -import { IotDeviceDetailLorawanComponent } from './iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component'; -import { IotDeviceDetailSigfoxComponent } from './iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component'; -import { IoTDeviceDetailComponent } from './iot-device-detail/iot-device-detail.component'; -import { IotDeviceEditComponent } from './iot-device-edit/iot-device-edit.component'; -import { SigfoxDeviceEditComponent } from './iot-device-edit/sigfox-device-edit/sigfox-device-edit.component'; -import { IotDevicesTableComponent } from './iot-devices-table/iot-devices-table.component'; -import { DownlinkDialogComponent } from './iot-device-detail/downlink/downlink-dialog/downlink-dialog.component'; -import { SharedModule } from '@shared/shared.module'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { DeviceModelComponent } from './iot-device-detail/device-model/device-model.component'; -import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; -import { DataPackageComponent } from './iot-device-detail/data-package/data-package.component'; -import { DataPackagesTimestampComponent } from './iot-device-detail/data-packages-timestamp/data-packages-timestamp.component'; -import { GraphModule } from '@app/graph/graph.module'; -import { IotDevicesTabComponent } from './iot-devices-tab/iot-devices-tab.component'; -import { IotDeviceHistoryTabComponent } from './iot-device-detail/iot-device-history-tab/iot-device-history-tab.component'; -import { IotDeviceDetailsTabComponent } from './iot-device-detail/iot-device-details-tab/iot-device-details-tab.component'; -import { IotDeviceDataPacketsTabComponent } from './iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component'; -import { IotDeviceDownlinkTabComponent } from './iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component'; -import { MqttDeviceEditComponent } from './iot-device-edit/mqtt-device-edit/mqtt-device-edit.component'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { MqttAuthenticationSelectComponent } from './iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component'; -import { ClipboardModule } from '@angular/cdk/clipboard'; -import { ExportCsvDialogComponent } from './iot-devices-tab/export-csv-dialog/export-csv-dialog.component'; -import { IotDeviceDetailsMqttInternalBrokerComponent } from '@applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component'; -import { IotDeviceDetailsMqttExternalBrokerComponent } from '@applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component'; +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { FormsModule } from "@angular/forms"; +import { RouterModule } from "@angular/router"; +import { TranslateModule } from "@ngx-translate/core"; +import { FormModule } from "@shared/components/forms/form.module"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { DownlinkComponent } from "./iot-device-detail/downlink/downlink.component"; +import { IotDeviceDetailGenericComponent } from "./iot-device-detail/iot-device-detail-generic/iot-device-detail-generic.component"; +import { IotDeviceDetailLorawanComponent } from "./iot-device-detail/iot-device-detail-lorawan/iot-device-detail-lorawan.component"; +import { IotDeviceDetailSigfoxComponent } from "./iot-device-detail/iot-device-detail-sigfox/iot-device-detail-sigfox.component"; +import { IoTDeviceDetailComponent } from "./iot-device-detail/iot-device-detail.component"; +import { IotDeviceEditComponent } from "./iot-device-edit/iot-device-edit.component"; +import { SigfoxDeviceEditComponent } from "./iot-device-edit/sigfox-device-edit/sigfox-device-edit.component"; +import { IotDevicesTableComponent } from "./iot-devices-table/iot-devices-table.component"; +import { DownlinkDialogComponent } from "./iot-device-detail/downlink/downlink-dialog/downlink-dialog.component"; +import { SharedModule } from "@shared/shared.module"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { DeviceModelComponent } from "./iot-device-detail/device-model/device-model.component"; +import { MonacoEditorModule } from "ngx-monaco-editor-v2"; +import { DataPackageComponent } from "./iot-device-detail/data-package/data-package.component"; +import { DataPackagesTimestampComponent } from "./iot-device-detail/data-packages-timestamp/data-packages-timestamp.component"; +import { GraphModule } from "@app/graph/graph.module"; +import { IotDevicesTabComponent } from "./iot-devices-tab/iot-devices-tab.component"; +import { IotDeviceHistoryTabComponent } from "./iot-device-detail/iot-device-history-tab/iot-device-history-tab.component"; +import { IotDeviceDetailsTabComponent } from "./iot-device-detail/iot-device-details-tab/iot-device-details-tab.component"; +import { IotDeviceDataPacketsTabComponent } from "./iot-device-detail/iot-device-data-packets-tab/iot-device-data-packets-tab.component"; +import { IotDeviceDownlinkTabComponent } from "./iot-device-detail/iot-device-downlink-tab/iot-device-downlink-tab.component"; +import { MqttDeviceEditComponent } from "./iot-device-edit/mqtt-device-edit/mqtt-device-edit.component"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { MqttAuthenticationSelectComponent } from "./iot-device-edit/mqtt-device-edit/mqtt-authentication-select/mqtt-authentication-select.component"; +import { ClipboardModule } from "@angular/cdk/clipboard"; +import { ExportCsvDialogComponent } from "./iot-devices-tab/export-csv-dialog/export-csv-dialog.component"; +import { IotDeviceDetailsMqttInternalBrokerComponent } from "@applications/iot-devices/iot-device-detail/iot-device-details-mqtt-internal-broker/iot-device-details-mqtt-internal-broker.component"; +import { IotDeviceDetailsMqttExternalBrokerComponent } from "@applications/iot-devices/iot-device-detail/iot-device-details-mqtt-external-broker/iot-device-details-mqtt-external-broker.component"; @NgModule({ - declarations: [ - IotDevicesTableComponent, - IoTDeviceDetailComponent, - IotDeviceEditComponent, - SigfoxDeviceEditComponent, - IotDeviceDetailGenericComponent, - IotDeviceDetailLorawanComponent, - IotDeviceDetailSigfoxComponent, - DownlinkComponent, - DownlinkDialogComponent, - DeviceModelComponent, - DataPackageComponent, - DataPackagesTimestampComponent, - IotDevicesTabComponent, - IotDeviceHistoryTabComponent, - IotDeviceDetailsTabComponent, - IotDeviceDataPacketsTabComponent, - IotDeviceDownlinkTabComponent, - MqttDeviceEditComponent, - IotDeviceDetailsMqttInternalBrokerComponent, - MqttAuthenticationSelectComponent, - IotDeviceDetailsMqttExternalBrokerComponent, - ExportCsvDialogComponent, - ], - exports: [IotDevicesTableComponent, IoTDeviceDetailComponent], - imports: [ - SharedModule, - CommonModule, - RouterModule, - TranslateModule, - FormModule, - NGMaterialModule, - FormsModule, - PipesModule, - MonacoEditorModule, - GraphModule, - FontAwesomeModule, - ClipboardModule, - ], + declarations: [ + IotDevicesTableComponent, + IoTDeviceDetailComponent, + IotDeviceEditComponent, + SigfoxDeviceEditComponent, + IotDeviceDetailGenericComponent, + IotDeviceDetailLorawanComponent, + IotDeviceDetailSigfoxComponent, + DownlinkComponent, + DownlinkDialogComponent, + DeviceModelComponent, + DataPackageComponent, + DataPackagesTimestampComponent, + IotDevicesTabComponent, + IotDeviceHistoryTabComponent, + IotDeviceDetailsTabComponent, + IotDeviceDataPacketsTabComponent, + IotDeviceDownlinkTabComponent, + MqttDeviceEditComponent, + IotDeviceDetailsMqttInternalBrokerComponent, + MqttAuthenticationSelectComponent, + IotDeviceDetailsMqttExternalBrokerComponent, + ExportCsvDialogComponent, + ], + exports: [IotDevicesTableComponent, IoTDeviceDetailComponent], + imports: [ + SharedModule, + CommonModule, + RouterModule, + TranslateModule, + FormModule, + NGMaterialModule, + FormsModule, + PipesModule, + MonacoEditorModule, + GraphModule, + FontAwesomeModule, + ClipboardModule, + ], }) export class IotDevicesModule {} diff --git a/src/app/applications/models/application-device-type.model.ts b/src/app/applications/models/application-device-type.model.ts index 3efaf3a5d..fda01f048 100644 --- a/src/app/applications/models/application-device-type.model.ts +++ b/src/app/applications/models/application-device-type.model.ts @@ -1,7 +1,7 @@ -import { Application } from '@applications/application.model'; -import { ApplicationDeviceTypeUnion } from '@shared/enums/device-type'; +import { Application } from "@applications/application.model"; +import { ApplicationDeviceTypeUnion } from "@shared/enums/device-type"; export class ApplicationDeviceType { - public applications: Application[]; - public type: ApplicationDeviceTypeUnion; + public applications: Application[]; + public type: ApplicationDeviceTypeUnion; } diff --git a/src/app/applications/multicast/multicast-detail/multicast-detail.component.html b/src/app/applications/multicast/multicast-detail/multicast-detail.component.html index 3245567e2..b96a1930f 100644 --- a/src/app/applications/multicast/multicast-detail/multicast-detail.component.html +++ b/src/app/applications/multicast/multicast-detail/multicast-detail.component.html @@ -1,137 +1,122 @@
- -
-
-
-

{{ 'MULTICAST.BASIC-DETAILS' | translate }}

- -

- {{ 'MULTICAST.GROUPNAME' | translate }}{{ multicast.name | translate }} -

- -

{{ 'MULTICAST.LORAWAN-DETAILS' | translate }}

- -

- {{ 'MULTICAST.ADDRESS' | translate }}{{ multicast.mcAddr | translate }} -

-

- {{ 'MULTICAST.NETWORK-KEY' | translate }}{{ multicast.mcNwkSKey | translate }} -

-

- {{ 'MULTICAST.APPLICATION-KEY' | translate }}{{ multicast.mcAppSKey | translate }} -

-

- {{ 'MULTICAST.FRAMECOUNTER' | translate }}{{ multicast.fCnt }} -

-

- {{ 'MULTICAST.DATARATE' | translate }}{{ multicast.dr }} -

-

- {{ 'MULTICAST.FREQUENCY' | translate }}{{ multicast.frequency }} -

-

- {{ 'MULTICAST.GROUPTYPE' | translate }}{{ multicast.groupType }} -

- -
-
- -
-
-

{{ 'APPLICATION.ATTACHED-IOT' | translate }}

-
-

- {{ 'MULTICAST.IOTDEVICE' | translate }}: - - , - {{ device.name }} - -

-
-
-
-
-
-

Downlink

-
-
    -
  • - {{ error | translate }} -
  • -
-
-
- - + +
+
+
+

{{ "MULTICAST.BASIC-DETAILS" | translate }}

+ +

+ {{ "MULTICAST.GROUPNAME" | translate }}{{ multicast.name | translate }} +

+ +

{{ "MULTICAST.LORAWAN-DETAILS" | translate }}

+ +

+ {{ "MULTICAST.ADDRESS" | translate }}{{ multicast.mcAddr | translate }} +

+

+ {{ "MULTICAST.NETWORK-KEY" | translate }}{{ multicast.mcNwkSKey | translate }} +

+

+ {{ "MULTICAST.APPLICATION-KEY" | translate }}{{ multicast.mcAppSKey | translate }} +

+

+ {{ "MULTICAST.FRAMECOUNTER" | translate }}{{ multicast.fCnt }} +

+

+ {{ "MULTICAST.DATARATE" | translate }}{{ multicast.dr }} +

+

+ {{ "MULTICAST.FREQUENCY" | translate }}{{ multicast.frequency }} +

+

+ {{ "MULTICAST.GROUPTYPE" | translate }}{{ multicast.groupType }} +

+ +
-
- - + +
+
+

{{ "APPLICATION.ATTACHED-IOT" | translate }}

+
+

+ {{ "MULTICAST.IOTDEVICE" | translate }}: + + , + {{ + device.name + }} + +

+
+
-
- +
+
+

Downlink

+
+
    +
  • + {{ error | translate }} +
  • +
+
+
+ + +
+
+ + +
+
+ +
+
-
-
diff --git a/src/app/applications/multicast/multicast-detail/multicast-detail.component.scss b/src/app/applications/multicast/multicast-detail/multicast-detail.component.scss index ea3f31bc9..45a357501 100644 --- a/src/app/applications/multicast/multicast-detail/multicast-detail.component.scss +++ b/src/app/applications/multicast/multicast-detail/multicast-detail.component.scss @@ -1,3 +1,3 @@ -.loraDetails{ +.loraDetails { margin-top: 15px; -} \ No newline at end of file +} diff --git a/src/app/applications/multicast/multicast-detail/multicast-detail.component.ts b/src/app/applications/multicast/multicast-detail/multicast-detail.component.ts index c0dd9f4a2..2459e8659 100644 --- a/src/app/applications/multicast/multicast-detail/multicast-detail.component.ts +++ b/src/app/applications/multicast/multicast-detail/multicast-detail.component.ts @@ -1,174 +1,163 @@ -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { Subscription } from 'rxjs'; -import { Multicast } from '../multicast.model'; -import { Location } from '@angular/common'; -import { MulticastService } from '../multicast.service'; -import { SnackService } from '@shared/services/snack.service'; -import { Downlink } from '@applications/iot-devices/downlink.model'; -import { HttpErrorResponse } from '@angular/common/http'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { MatDialog } from '@angular/material/dialog'; -import { DownlinkDialogComponent } from '@applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component'; -import { keyPressedHex } from '@shared/constants/regex-constants'; -import { DownlinkService } from '@shared/services/downlink.service'; +import { Component, Input, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { Subscription } from "rxjs"; +import { Multicast } from "../multicast.model"; +import { Location } from "@angular/common"; +import { MulticastService } from "../multicast.service"; +import { SnackService } from "@shared/services/snack.service"; +import { Downlink } from "@applications/iot-devices/downlink.model"; +import { HttpErrorResponse } from "@angular/common/http"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { MatDialog } from "@angular/material/dialog"; +import { DownlinkDialogComponent } from "@applications/iot-devices/iot-device-detail/downlink/downlink-dialog/downlink-dialog.component"; +import { keyPressedHex } from "@shared/constants/regex-constants"; +import { DownlinkService } from "@shared/services/downlink.service"; @Component({ - selector: 'app-multicast-detail', - templateUrl: './multicast-detail.component.html', - styleUrls: ['./multicast-detail.component.scss'], + selector: "app-multicast-detail", + templateUrl: "./multicast-detail.component.html", + styleUrls: ["./multicast-detail.component.scss"], }) export class MulticastDetailComponent implements OnInit, OnDestroy { - public multicast: Multicast; - public backButton: BackButton = { label: '', routerLink: undefined }; - private deleteDialogSubscription: Subscription; - public dropdownButton: DropdownButton; - public formFailedSubmit = false; - private applicationId: number; - public downlink = new Downlink(); - @Input() errorMessages: string[]; + public multicast: Multicast; + public backButton: BackButton = { label: "", routerLink: undefined }; + private deleteDialogSubscription: Subscription; + public dropdownButton: DropdownButton; + public formFailedSubmit = false; + private applicationId: number; + public downlink = new Downlink(); + @Input() errorMessages: string[]; - constructor( - private route: ActivatedRoute, - private dialog: MatDialog, - private deleteDialogService: DeleteDialogService, - private location: Location, - private multicastService: MulticastService, - private translate: TranslateService, - private snackService: SnackService, - private errorMessageService: ErrorMessageService, - private downlinkService: DownlinkService - ) {} + constructor( + private route: ActivatedRoute, + private dialog: MatDialog, + private deleteDialogService: DeleteDialogService, + private location: Location, + private multicastService: MulticastService, + private translate: TranslateService, + private snackService: SnackService, + private errorMessageService: ErrorMessageService, + private downlinkService: DownlinkService + ) {} - ngOnInit(): void { - this.errorMessages = []; - const id: number = +this.route.snapshot.paramMap.get('multicastId'); - if (id) { - this.getMulticast(id); - this.dropdownButton = { - label: '', - editRouterLink: '../../multicast-edit/' + id, - isErasable: true, - }; - this.applicationId = +this.route.snapshot.paramMap.get('id'); + ngOnInit(): void { + this.errorMessages = []; + const id: number = +this.route.snapshot.paramMap.get("multicastId"); + if (id) { + this.getMulticast(id); + this.dropdownButton = { + label: "", + editRouterLink: "../../multicast-edit/" + id, + isErasable: true, + }; + this.applicationId = +this.route.snapshot.paramMap.get("id"); + } + this.translate.get(["GEN.BACK", "MULTICAST-TABLE-ROW.SHOW-OPTIONS"]).subscribe(translations => { + this.backButton.label = translations["GEN.BACK"]; + this.dropdownButton.label = translations["MULTICAST-TABLE-ROW.SHOW-OPTIONS"]; + }); } - this.translate - .get(['GEN.BACK', 'MULTICAST-TABLE-ROW.SHOW-OPTIONS']) - .subscribe((translations) => { - this.backButton.label = translations['GEN.BACK']; - this.dropdownButton.label = - translations['MULTICAST-TABLE-ROW.SHOW-OPTIONS']; - }); - } - getMulticast(id: number) { - this.multicastService.get(id).subscribe((multicast: Multicast) => { - this.multicast = multicast; - }); - } + getMulticast(id: number) { + this.multicastService.get(id).subscribe((multicast: Multicast) => { + this.multicast = multicast; + }); + } - // Class-B: - // only if classB can be used - // canShowPeriodicity(): boolean { - // if (this.multicast.groupType === MulticastType.ClassB) { - // return true; - // } else return false; - // } + // Class-B: + // only if classB can be used + // canShowPeriodicity(): boolean { + // if (this.multicast.groupType === MulticastType.ClassB) { + // return true; + // } else return false; + // } - onDeleteMulticast() { - this.deleteDialogSubscription = this.deleteDialogService - .showSimpleDialog() - .subscribe((response) => { - if (response) { - this.multicastService - .delete(this.multicast.id) - .subscribe((response) => { - if (response.status !== 0) { - this.snackService.showDeletedSnack(); - this.location.back(); - } else { - this.snackService.showFailSnack(); - } - }); - } else { - } - }); - } + onDeleteMulticast() { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + this.multicastService.delete(this.multicast.id).subscribe(response => { + if (response.status !== 0) { + this.snackService.showDeletedSnack(); + this.location.back(); + } else { + this.snackService.showFailSnack(); + } + }); + } else { + } + }); + } - keyPressHexadecimal(event) { - // make sure only hexadecimal can be typed in input with adresses. - keyPressedHex(event); - } + keyPressHexadecimal(event) { + // make sure only hexadecimal can be typed in input with adresses. + keyPressedHex(event); + } - private handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorMessages = errors.errorFields; - this.errorMessages = errors.errorMessages; - } + private handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorMessages = errors.errorFields; + this.errorMessages = errors.errorMessages; + } - clickDownlink() { - if (this.multicast.iotDevices.length > 0) { - if (this.validateHex(this.downlink.data)) { - this.multicastService - .multicastGet(this.multicast.id) - .subscribe((response: any) => { - if (response.deviceQueueItems.length > 0) { - this.openDownlinkDialog(); - } else { - this.startDownlink(); + clickDownlink() { + if (this.multicast.iotDevices.length > 0) { + if (this.validateHex(this.downlink.data)) { + this.multicastService.multicastGet(this.multicast.id).subscribe((response: any) => { + if (response.deviceQueueItems.length > 0) { + this.openDownlinkDialog(); + } else { + this.startDownlink(); + } + }); } - }); - } - } else { - this.downlinkService.showSendDownlinkFailNoDevices(); + } else { + this.downlinkService.showSendDownlinkFailNoDevices(); + } } - } - openDownlinkDialog() { - const dialog = this.dialog.open(DownlinkDialogComponent, {}); + openDownlinkDialog() { + const dialog = this.dialog.open(DownlinkDialogComponent, {}); - dialog.afterClosed().subscribe((result) => { - if (result === true) { - this.startDownlink(); - } - }); - } + dialog.afterClosed().subscribe(result => { + if (result === true) { + this.startDownlink(); + } + }); + } - private startDownlink() { - this.errorMessages = []; - this.multicastService - .multicastPost(this.downlink, this.multicast.id) - .subscribe( - () => { - this.snackService.showInQueueSnack(); - }, - (error) => { - this.handleError(error); - } - ); - } + private startDownlink() { + this.errorMessages = []; + this.multicastService.multicastPost(this.downlink, this.multicast.id).subscribe( + () => { + this.snackService.showInQueueSnack(); + }, + error => { + this.handleError(error); + } + ); + } - private validateHex(input: string): boolean { - const isHexinput = /^[a-fA-F\d]+$/.test(input); + private validateHex(input: string): boolean { + const isHexinput = /^[a-fA-F\d]+$/.test(input); - if (isHexinput) { - return true; - } else { - this.addToErrorMessage('MULTICAST.DOWNLINK.NO-PORT-OR-PAYLOAD'); - return false; + if (isHexinput) { + return true; + } else { + this.addToErrorMessage("MULTICAST.DOWNLINK.NO-PORT-OR-PAYLOAD"); + return false; + } } - } - addToErrorMessage(text: string) { - this.translate.get([text]).subscribe((translations) => { - this.errorMessages.push(translations[text]); - }); - } + addToErrorMessage(text: string) { + this.translate.get([text]).subscribe(translations => { + this.errorMessages.push(translations[text]); + }); + } - ngOnDestroy(): void { - this.deleteDialogSubscription?.unsubscribe(); - } + ngOnDestroy(): void { + this.deleteDialogSubscription?.unsubscribe(); + } } diff --git a/src/app/applications/multicast/multicast-edit/multicast-edit.component.html b/src/app/applications/multicast/multicast-edit/multicast-edit.component.html index 583a56dff..7d1ffbeef 100644 --- a/src/app/applications/multicast/multicast-edit/multicast-edit.component.html +++ b/src/app/applications/multicast/multicast-edit/multicast-edit.component.html @@ -1,206 +1,187 @@
-
-
    -
  • - {{ error | translate }} -
  • -
-
- -
-
- * - +
+
    +
  • + {{ error | translate }} +
  • +
-
- * - - -
+
+
+ * + +
-
- * - - -
+
+ * + + +
-
- * - - -
+
+ * + + +
-
- * - -
+
+ * + + +
-
- * - - -
+
+ * + +
-
- * - - -
+
+ * + + +
-
- * - - - {{ multicastType }} - - -
+
+ * + + +
- - + -
+
-
- +
+ -
- - {{ - 'QUESTION.MULTICAST.SELECT-DEVICES' | translate - }} - - +
+ + {{ "QUESTION.MULTICAST.SELECT-DEVICES" | translate }} + + - - - - - - {{ device.name }} - - + + + + + + {{ + device.name + }} + + +
+
+
+ +
-
-
- - -
diff --git a/src/app/applications/multicast/multicast-edit/multicast-edit.component.scss b/src/app/applications/multicast/multicast-edit/multicast-edit.component.scss index 74d588dab..335ea1f36 100644 --- a/src/app/applications/multicast/multicast-edit/multicast-edit.component.scss +++ b/src/app/applications/multicast/multicast-edit/multicast-edit.component.scss @@ -1,5 +1,5 @@ .onlyLorawan { - font-weight: bold; - font-size: 13px; - margin-left: 10px; + font-weight: bold; + font-size: 13px; + margin-left: 10px; } diff --git a/src/app/applications/multicast/multicast-edit/multicast-edit.component.ts b/src/app/applications/multicast/multicast-edit/multicast-edit.component.ts index c435b2b89..87c16d7c7 100644 --- a/src/app/applications/multicast/multicast-edit/multicast-edit.component.ts +++ b/src/app/applications/multicast/multicast-edit/multicast-edit.component.ts @@ -1,207 +1,192 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { MulticastType } from '@shared/enums/multicast-type'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { SnackService } from '@shared/services/snack.service'; -import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { ReplaySubject, Subject, Subscription } from 'rxjs'; -import { Multicast } from '../multicast.model'; -import { MulticastService } from '../multicast.service'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { ApplicationService } from '@applications/application.service'; -import { keyPressedHex } from '@shared/constants/regex-constants'; -import { UntypedFormControl } from '@angular/forms'; -import { takeUntil } from 'rxjs/operators'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, Input, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { MulticastType } from "@shared/enums/multicast-type"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { SnackService } from "@shared/services/snack.service"; +import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; +import { ReplaySubject, Subject, Subscription } from "rxjs"; +import { Multicast } from "../multicast.model"; +import { MulticastService } from "../multicast.service"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { ApplicationService } from "@applications/application.service"; +import { keyPressedHex } from "@shared/constants/regex-constants"; +import { UntypedFormControl } from "@angular/forms"; +import { takeUntil } from "rxjs/operators"; @Component({ - selector: 'app-multicast-edit', - templateUrl: './multicast-edit.component.html', - styleUrls: ['./multicast-edit.component.scss'], + selector: "app-multicast-edit", + templateUrl: "./multicast-edit.component.html", + styleUrls: ["./multicast-edit.component.scss"], }) export class MulticastEditComponent implements OnInit, OnDestroy { - public title: string; - public multicastId: number; - public errorMessages: unknown; - private multicastSubscription: Subscription; - public searchDevices: UntypedFormControl = new UntypedFormControl(); - public errorFields: string[]; - public iotDevices: IotDevice[] = []; - @Input() submitButton: string; - public backButtonTitle: string; - public multicast: Multicast = new Multicast(); - private applicationId: number; - private onDestroy = new Subject(); - public formFailedSubmit = false; - public multicastTypes: string[] = Object.values(MulticastType); - // Class-B: { public periodicities: number[] = [2, 4, 8, 16, 32, 64, 128]; // used for classB if it has to be used in the future } - public deviceFilterCtrl: UntypedFormControl = new UntypedFormControl(); - public filteredDevicesMulti: ReplaySubject = new ReplaySubject< - IotDevice[] - >(1); - - constructor( - private translate: TranslateService, - private route: ActivatedRoute, - private router: Router, - private multicastService: MulticastService, - private errorMessageService: ErrorMessageService, - private scrollToTopService: ScrollToTopService, - private snackService: SnackService, - private applicationService: ApplicationService - ) {} - - ngOnInit(): void { - this.multicastId = +this.route.snapshot.paramMap.get('multicastId'); - this.applicationId = +this.route.snapshot.paramMap.get('id'); - - this.translate - .get([ - 'FORM.CREATE-NEW-MULTICAST', - 'FORM.EDIT-MULTICAST', - 'MULTICAST.SAVE', - 'NAV.MULTICAST', - 'GEN.BACK', - ]) - .subscribe((translations) => { + public title: string; + public multicastId: number; + public errorMessages: unknown; + private multicastSubscription: Subscription; + public searchDevices: UntypedFormControl = new UntypedFormControl(); + public errorFields: string[]; + public iotDevices: IotDevice[] = []; + @Input() submitButton: string; + public backButtonTitle: string; + public multicast: Multicast = new Multicast(); + private applicationId: number; + private onDestroy = new Subject(); + public formFailedSubmit = false; + public multicastTypes: string[] = Object.values(MulticastType); + // Class-B: { public periodicities: number[] = [2, 4, 8, 16, 32, 64, 128]; // used for classB if it has to be used in the future } + public deviceFilterCtrl: UntypedFormControl = new UntypedFormControl(); + public filteredDevicesMulti: ReplaySubject = new ReplaySubject(1); + + constructor( + private translate: TranslateService, + private route: ActivatedRoute, + private router: Router, + private multicastService: MulticastService, + private errorMessageService: ErrorMessageService, + private scrollToTopService: ScrollToTopService, + private snackService: SnackService, + private applicationService: ApplicationService + ) {} + + ngOnInit(): void { + this.multicastId = +this.route.snapshot.paramMap.get("multicastId"); + this.applicationId = +this.route.snapshot.paramMap.get("id"); + + this.translate + .get(["FORM.CREATE-NEW-MULTICAST", "FORM.EDIT-MULTICAST", "MULTICAST.SAVE", "NAV.MULTICAST", "GEN.BACK"]) + .subscribe(translations => { + if (this.multicastId) { + this.title = translations["FORM.EDIT-MULTICAST"]; + } else { + this.title = translations["FORM.CREATE-NEW-MULTICAST"]; + } + this.submitButton = translations["MULTICAST.SAVE"]; + this.backButtonTitle = translations["GEN.BACK"]; + }); + + this.getApplication(this.applicationId); + if (this.multicastId) { - this.title = translations['FORM.EDIT-MULTICAST']; + // If edit is pressed, then get the specific multicast. + this.getMulticast(this.multicastId); + } + + this.deviceFilterCtrl.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe(() => { + this.filterDevicesMulti(); + }); + } + + private filterDevicesMulti() { + if (!this.iotDevices) { + return; + } + // get the search keyword + let search = this.deviceFilterCtrl?.value?.trim(); + if (!search) { + this.filteredDevicesMulti.next(this.iotDevices.slice()); + return; } else { - this.title = translations['FORM.CREATE-NEW-MULTICAST']; + search = search.toLowerCase(); } - this.submitButton = translations['MULTICAST.SAVE']; - this.backButtonTitle = translations['GEN.BACK']; - }); + const filtered = this.iotDevices.filter(device => { + return device.name.toLocaleLowerCase().indexOf(search) > -1; + }); + this.filteredDevicesMulti.next(filtered); + } - this.getApplication(this.applicationId); + onSubmit(): void { + if (this.multicastId) { + // if already created, only update + this.updateMulticast(); + } else { + // else create new + this.createMulticast(); + } + } - if (this.multicastId) { - // If edit is pressed, then get the specific multicast. - this.getMulticast(this.multicastId); + getMulticast(id: number) { + this.multicastSubscription = this.multicastService.get(id).subscribe((response: Multicast) => { + this.multicast = response; // gets the multicast and set's local multicast. Used when update. + }); } - this.deviceFilterCtrl.valueChanges - .pipe(takeUntil(this.onDestroy)) - .subscribe(() => { - this.filterDevicesMulti(); - }); - } + getApplication(id: number) { + this.applicationService.getApplication(id).subscribe(application => { + this.iotDevices = application.iotDevices ?? []; + this.filteredDevicesMulti.next(this.iotDevices.slice()); + }); + } + + // only if classB can be used + // showPeriodicity(): boolean { + // if (this.multicast.groupType === MulticastType.ClassB) { + // return true; + // } else return false; + // } + + updateMulticast(): void { + this.resetErrors(); + this.multicast.applicationID = this.applicationId; + + this.multicastService.update(this.multicast).subscribe( + () => { + this.snackService.showUpdatedSnack(); + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.snackService.showFailSnack(); + this.handleError(error); + this.formFailedSubmit = true; + } + ); + } + createMulticast(): void { + this.resetErrors(); + this.multicast.applicationID = this.applicationId; + + this.multicastService.create(this.multicast).subscribe( + () => { + this.snackService.showSavedSnack(); + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.snackService.showFailSnack(); + this.handleError(error); + this.formFailedSubmit = true; + } + ); + } + public compare(o1: IotDevice | undefined, o2: IotDevice | undefined): boolean { + return o1?.id === o2?.id; + } - private filterDevicesMulti() { - if (!this.iotDevices) { - return; + selectAll() { + this.multicast.iotDevices = this.iotDevices; + } + unSelectAll() { + this.multicast.iotDevices = []; + } + + routeBack(): void { + this.router.navigate(["applications", this.applicationId.toString()]); + } + keyPressHexadecimal(event) { + keyPressedHex(event); + } + private resetErrors() { + this.errorFields = []; + this.errorMessages = undefined; + this.formFailedSubmit = false; } - // get the search keyword - let search = this.deviceFilterCtrl?.value?.trim(); - if (!search) { - this.filteredDevicesMulti.next(this.iotDevices.slice()); - return; - } else { - search = search.toLowerCase(); + handleError(error: HttpErrorResponse) { + const errors = this.errorMessageService.handleErrorMessageWithFields(error); + this.errorFields = errors.errorFields; + this.errorMessages = errors.errorMessages; + this.scrollToTopService.scrollToTop(); } - const filtered = this.iotDevices.filter((device) => { - return device.name.toLocaleLowerCase().indexOf(search) > -1; - }); - this.filteredDevicesMulti.next(filtered); - } - - onSubmit(): void { - if (this.multicastId) { - // if already created, only update - this.updateMulticast(); - } else { - // else create new - this.createMulticast(); + ngOnDestroy(): void { + this.multicastSubscription?.unsubscribe(); } - } - - getMulticast(id: number) { - this.multicastSubscription = this.multicastService - .get(id) - .subscribe((response: Multicast) => { - this.multicast = response; // gets the multicast and set's local multicast. Used when update. - }); - } - - getApplication(id: number) { - this.applicationService.getApplication(id).subscribe((application) => { - this.iotDevices = application.iotDevices ?? []; - this.filteredDevicesMulti.next(this.iotDevices.slice()); - }); - } - - // only if classB can be used - // showPeriodicity(): boolean { - // if (this.multicast.groupType === MulticastType.ClassB) { - // return true; - // } else return false; - // } - - updateMulticast(): void { - this.resetErrors(); - this.multicast.applicationID = this.applicationId; - - this.multicastService.update(this.multicast).subscribe( - () => { - this.snackService.showUpdatedSnack(); - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.snackService.showFailSnack(); - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } - createMulticast(): void { - this.resetErrors(); - this.multicast.applicationID = this.applicationId; - - this.multicastService.create(this.multicast).subscribe( - () => { - this.snackService.showSavedSnack(); - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.snackService.showFailSnack(); - this.handleError(error); - this.formFailedSubmit = true; - } - ); - } - public compare( - o1: IotDevice | undefined, - o2: IotDevice | undefined - ): boolean { - return o1?.id === o2?.id; - } - - selectAll() { - this.multicast.iotDevices = this.iotDevices; - } - unSelectAll() { - this.multicast.iotDevices = []; - } - - routeBack(): void { - this.router.navigate(['applications', this.applicationId.toString()]); - } - keyPressHexadecimal(event) { - keyPressedHex(event); - } - private resetErrors() { - this.errorFields = []; - this.errorMessages = undefined; - this.formFailedSubmit = false; - } - handleError(error: HttpErrorResponse) { - const errors = this.errorMessageService.handleErrorMessageWithFields(error); - this.errorFields = errors.errorFields; - this.errorMessages = errors.errorMessages; - this.scrollToTopService.scrollToTop(); - } - ngOnDestroy(): void { - this.multicastSubscription?.unsubscribe(); - } } diff --git a/src/app/applications/multicast/multicast-response.model.ts b/src/app/applications/multicast/multicast-response.model.ts index 16d385f67..ee5e3d5fb 100644 --- a/src/app/applications/multicast/multicast-response.model.ts +++ b/src/app/applications/multicast/multicast-response.model.ts @@ -1,29 +1,29 @@ -import { Application } from '@applications/application.model'; -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { MulticastType } from '@shared/enums/multicast-type'; +import { Application } from "@applications/application.model"; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { MulticastType } from "@shared/enums/multicast-type"; export class MulticastResponse { - id: number; - application: Application; - iotDevices: IotDevice[]; - groupName: string; - lorawanMulticastDefinition: LorawanMulticastDefinition; - // periodicity: number; -> only if classB is gonna be used - createdAt: string; - updatedAt: string; - createdBy: number; - updatedBy: number; - createdByName: string; - updatedByName: string; + id: number; + application: Application; + iotDevices: IotDevice[]; + groupName: string; + lorawanMulticastDefinition: LorawanMulticastDefinition; + // periodicity: number; -> only if classB is gonna be used + createdAt: string; + updatedAt: string; + createdBy: number; + updatedBy: number; + createdByName: string; + updatedByName: string; } export class LorawanMulticastDefinition { - address: string; - networkSessionKey: string; - applicationSessionKey: string; - frameCounter = 0; - dataRate = 0; - frequency = 0; - groupType: MulticastType; - chirpstackGroupId?: string; + address: string; + networkSessionKey: string; + applicationSessionKey: string; + frameCounter = 0; + dataRate = 0; + frequency = 0; + groupType: MulticastType; + chirpstackGroupId?: string; } diff --git a/src/app/applications/multicast/multicast-tab/multicast-tab.component.html b/src/app/applications/multicast/multicast-tab/multicast-tab.component.html index a7931621d..3cb74fdb7 100644 --- a/src/app/applications/multicast/multicast-tab/multicast-tab.component.html +++ b/src/app/applications/multicast/multicast-tab/multicast-tab.component.html @@ -1,18 +1,22 @@
-
-
-
-
- - +
+
+
+
+ + +
+ + + + + +
- - - - - -
-
diff --git a/src/app/applications/multicast/multicast-tab/multicast-tab.component.ts b/src/app/applications/multicast/multicast-tab/multicast-tab.component.ts index 3d9914ea7..98a9654f4 100644 --- a/src/app/applications/multicast/multicast-tab/multicast-tab.component.ts +++ b/src/app/applications/multicast/multicast-tab/multicast-tab.component.ts @@ -1,13 +1,13 @@ -import { Component, OnInit } from '@angular/core'; -import { ApplicationService } from '@applications/application.service'; +import { Component, OnInit } from "@angular/core"; +import { ApplicationService } from "@applications/application.service"; @Component({ - selector: 'app-multicast-tab', - templateUrl: './multicast-tab.component.html', - styleUrls: ['./multicast-tab.component.scss'], + selector: "app-multicast-tab", + templateUrl: "./multicast-tab.component.html", + styleUrls: ["./multicast-tab.component.scss"], }) export class MulticastTabComponent implements OnInit { - constructor(public applicationService: ApplicationService) {} + constructor(public applicationService: ApplicationService) {} - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/applications/multicast/multicast-table/multicast-table.component.html b/src/app/applications/multicast/multicast-table/multicast-table.component.html index ba103ecfc..90b245ce1 100644 --- a/src/app/applications/multicast/multicast-table/multicast-table.component.html +++ b/src/app/applications/multicast/multicast-table/multicast-table.component.html @@ -1,53 +1,76 @@
- +
- +
+ + + + + - - - - - + + + + + - - - - + + - {{element.lorawanMulticastDefinition.groupType}} - - - - - - - - - - + +
+ {{ "MULTICAST-TABLE.NAME" | translate }} + + {{ + element.groupName + }} + - {{ 'MULTICAST-TABLE.NAME' | translate }} - - {{element.groupName}} - + {{ "MULTICAST-TABLE.TYPE" | translate }} + + {{ element.lorawanMulticastDefinition.groupType }} + - {{ 'MULTICAST-TABLE.TYPE' | translate }} + + + + + - -
- + -
+
diff --git a/src/app/applications/multicast/multicast-table/multicast-table.component.ts b/src/app/applications/multicast/multicast-table/multicast-table.component.ts index 2a8e91ea6..38bac8a92 100644 --- a/src/app/applications/multicast/multicast-table/multicast-table.component.ts +++ b/src/app/applications/multicast/multicast-table/multicast-table.component.ts @@ -1,140 +1,124 @@ -import { - AfterViewInit, - Component, - Input, - OnDestroy, - OnInit, - ViewChild, -} from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { ActivatedRoute } from '@angular/router'; -import { environment } from '@environments/environment'; -import { TranslateService } from '@ngx-translate/core'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { MeService } from '@shared/services/me.service'; -import { SnackService } from '@shared/services/snack.service'; -import { merge, Observable, Subscription, of as observableOf } from 'rxjs'; -import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { Multicast, MulticastData } from '../multicast.model'; -import { MulticastService } from '../multicast.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { AfterViewInit, Component, Input, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { ActivatedRoute } from "@angular/router"; +import { environment } from "@environments/environment"; +import { TranslateService } from "@ngx-translate/core"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { MeService } from "@shared/services/me.service"; +import { SnackService } from "@shared/services/snack.service"; +import { merge, Observable, Subscription, of as observableOf } from "rxjs"; +import { catchError, map, startWith, switchMap } from "rxjs/operators"; +import { Multicast, MulticastData } from "../multicast.model"; +import { MulticastService } from "../multicast.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; @Component({ - selector: 'app-multicast-table', - templateUrl: './multicast-table.component.html', - styleUrls: ['./multicast-table.component.scss'], + selector: "app-multicast-table", + templateUrl: "./multicast-table.component.html", + styleUrls: ["./multicast-table.component.scss"], }) -export class MulticastTableComponent - implements OnInit, AfterViewInit, OnDestroy { - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - displayedColumns: string[] = ['groupName', 'groupType', 'menu']; - multicasts: Multicast[] = []; - resultsLength = 0; - public canEdit = false; - @Input() isLoadingResults = true; - public pageSize = environment.tablePageSize; - public pageSizeOptions = DefaultPageSizeOptions; - public pageOffset = 0; - public applicationId: number; +export class MulticastTableComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + displayedColumns: string[] = ["groupName", "groupType", "menu"]; + multicasts: Multicast[] = []; + resultsLength = 0; + public canEdit = false; + @Input() isLoadingResults = true; + public pageSize = environment.tablePageSize; + public pageSizeOptions = DefaultPageSizeOptions; + public pageOffset = 0; + public applicationId: number; - private multicastSubscription: Subscription; - private deleteDialogSubscription: Subscription; + private multicastSubscription: Subscription; + private deleteDialogSubscription: Subscription; - constructor( - private route: ActivatedRoute, - private deleteDialogService: DeleteDialogService, - private multicastService: MulticastService, - private meService: MeService, - public translate: TranslateService, - public snackService: SnackService - ) { - translate.use('da'); - } + constructor( + private route: ActivatedRoute, + private deleteDialogService: DeleteDialogService, + private multicastService: MulticastService, + private meService: MeService, + public translate: TranslateService, + public snackService: SnackService + ) { + translate.use("da"); + } - ngOnInit(): void { - this.applicationId = +Number(this.route.parent.snapshot.paramMap.get('id')); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite, - undefined, - this.applicationId - ); - } + ngOnInit(): void { + this.applicationId = +Number(this.route.parent.snapshot.paramMap.get("id")); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + this.applicationId + ); + } - ngAfterViewInit() { - // If the user changes the sort order, reset back to the first page. - this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + ngAfterViewInit() { + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); - merge(this.sort.sortChange, this.paginator.page) - .pipe( - startWith({}), - switchMap(() => { - this.isLoadingResults = true; - const multicasts = this.getMulticasts( - this.sort.active, - this.sort.direction - ); - return multicasts; - }), - map((data) => { - // Flip flag to show that loading has finished. - if (data.ok === false) { - this.snackService.showLoadFailSnack(); - } - this.isLoadingResults = false; - this.resultsLength = data.count; + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + const multicasts = this.getMulticasts(this.sort.active, this.sort.direction); + return multicasts; + }), + map(data => { + // Flip flag to show that loading has finished. + if (data.ok === false) { + this.snackService.showLoadFailSnack(); + } + this.isLoadingResults = false; + this.resultsLength = data.count; - return data.data; - }), - catchError(() => { - this.isLoadingResults = false; - return observableOf([]); - }) - ) - .subscribe((data) => (this.multicasts = data)); - } + return data.data; + }), + catchError(() => { + this.isLoadingResults = false; + return observableOf([]); + }) + ) + .subscribe(data => (this.multicasts = data)); + } - getMulticasts( - orderByColumn: string, - orderByDirection: string - ): Observable { - if (this.applicationId) { - return this.multicastService.getMulticastsByApplicationId( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByDirection, - orderByColumn, - this.applicationId - ); + getMulticasts(orderByColumn: string, orderByDirection: string): Observable { + if (this.applicationId) { + return this.multicastService.getMulticastsByApplicationId( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByDirection, + orderByColumn, + this.applicationId + ); + } } - } - deleteMulticast(multicast: Multicast) { - this.deleteDialogSubscription = this.deleteDialogService - .showSimpleDialog() - .subscribe((response) => { - if (response) { - // if user presses "yes, delete", then delete the multicast. - this.multicastService.delete(multicast.id).subscribe((response) => { - if (response.ok && response.body.affected > 0) { - // if deleted succesfully, get the new array of multicasts and show a succesful snack. - this.paginator.page.emit({ - pageIndex: this.paginator.pageIndex, - pageSize: this.paginator.pageSize, - length: this.resultsLength, - }); - this.snackService.showDeletedSnack(); - } else { - this.snackService.showFailSnack(); + deleteMulticast(multicast: Multicast) { + this.deleteDialogSubscription = this.deleteDialogService.showSimpleDialog().subscribe(response => { + if (response) { + // if user presses "yes, delete", then delete the multicast. + this.multicastService.delete(multicast.id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + // if deleted succesfully, get the new array of multicasts and show a succesful snack. + this.paginator.page.emit({ + pageIndex: this.paginator.pageIndex, + pageSize: this.paginator.pageSize, + length: this.resultsLength, + }); + this.snackService.showDeletedSnack(); + } else { + this.snackService.showFailSnack(); + } + }); } - }); - } - }); - } - ngOnDestroy() { - this.multicastSubscription?.unsubscribe(); - this.deleteDialogSubscription?.unsubscribe(); - } + }); + } + ngOnDestroy() { + this.multicastSubscription?.unsubscribe(); + this.deleteDialogSubscription?.unsubscribe(); + } } diff --git a/src/app/applications/multicast/multicast.model.ts b/src/app/applications/multicast/multicast.model.ts index 1dec442cc..13f605498 100644 --- a/src/app/applications/multicast/multicast.model.ts +++ b/src/app/applications/multicast/multicast.model.ts @@ -1,29 +1,29 @@ -import { IotDevice } from '@applications/iot-devices/iot-device.model'; -import { MulticastType } from '@shared/enums/multicast-type'; +import { IotDevice } from "@applications/iot-devices/iot-device.model"; +import { MulticastType } from "@shared/enums/multicast-type"; export class Multicast { - id: number; - applicationID: number; - iotDevices?: IotDevice[]; - name: string; - mcAddr: string; - mcNwkSKey: string; - mcAppSKey: string; - fCnt: number = 0; - dr: number = 0; - frequency: number = 0; - groupType: MulticastType; - // periodicity: number; -> only if classB is gonna be used - createdAt: string; - updatedAt: string; - createdBy: number; - updatedBy: number; - createdByName: string; - updatedByName: string; + id: number; + applicationID: number; + iotDevices?: IotDevice[]; + name: string; + mcAddr: string; + mcNwkSKey: string; + mcAppSKey: string; + fCnt: number = 0; + dr: number = 0; + frequency: number = 0; + groupType: MulticastType; + // periodicity: number; -> only if classB is gonna be used + createdAt: string; + updatedAt: string; + createdBy: number; + updatedBy: number; + createdByName: string; + updatedByName: string; } export class MulticastData { - data: Multicast[]; - ok?: boolean; - count?: number; + data: Multicast[]; + ok?: boolean; + count?: number; } diff --git a/src/app/applications/multicast/multicast.module.ts b/src/app/applications/multicast/multicast.module.ts index 45ec89acd..d73b3f681 100644 --- a/src/app/applications/multicast/multicast.module.ts +++ b/src/app/applications/multicast/multicast.module.ts @@ -1,41 +1,32 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { SharedModule } from '@shared/shared.module'; -import { MulticastDetailComponent } from './multicast-detail/multicast-detail.component'; -import { MulticastEditComponent } from './multicast-edit/multicast-edit.component'; -import { MulticastTableComponent } from './multicast-table/multicast-table.component'; -import { RouterModule } from '@angular/router'; -import { TranslateModule } from '@ngx-translate/core'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { MatSelectSearchModule } from '@shared/components/mat-select-search/mat-select-search.module'; -import { MulticastTabComponent } from './multicast-tab/multicast-tab.component'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { SharedModule } from "@shared/shared.module"; +import { MulticastDetailComponent } from "./multicast-detail/multicast-detail.component"; +import { MulticastEditComponent } from "./multicast-edit/multicast-edit.component"; +import { MulticastTableComponent } from "./multicast-table/multicast-table.component"; +import { RouterModule } from "@angular/router"; +import { TranslateModule } from "@ngx-translate/core"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { MatSelectSearchModule } from "@shared/components/mat-select-search/mat-select-search.module"; +import { MulticastTabComponent } from "./multicast-tab/multicast-tab.component"; @NgModule({ - declarations: [ - MulticastDetailComponent, - MulticastEditComponent, - MulticastTableComponent, - MulticastTabComponent, - ], - imports: [ - CommonModule, - RouterModule, - TranslateModule, - NGMaterialModule, - FontAwesomeModule, - ReactiveFormsModule, - FormsModule, - SharedModule, - PipesModule, - MatSelectSearchModule, - ], - exports: [ - MulticastDetailComponent, - MulticastEditComponent, - MulticastTableComponent, - ], + declarations: [MulticastDetailComponent, MulticastEditComponent, MulticastTableComponent, MulticastTabComponent], + imports: [ + CommonModule, + RouterModule, + TranslateModule, + NGMaterialModule, + FontAwesomeModule, + ReactiveFormsModule, + FormsModule, + SharedModule, + PipesModule, + MatSelectSearchModule, + ], + exports: [MulticastDetailComponent, MulticastEditComponent, MulticastTableComponent], }) export class MulticastModule {} diff --git a/src/app/applications/multicast/multicast.service.ts b/src/app/applications/multicast/multicast.service.ts index 8dd061de3..901a263ac 100644 --- a/src/app/applications/multicast/multicast.service.ts +++ b/src/app/applications/multicast/multicast.service.ts @@ -1,102 +1,88 @@ -import { Injectable } from '@angular/core'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; -import { Downlink } from '@applications/iot-devices/downlink.model'; -import { RestService } from '@shared/services/rest.service'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { MulticastResponse } from './multicast-response.model'; -import { Multicast, MulticastData } from './multicast.model'; +import { Injectable } from "@angular/core"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; +import { Downlink } from "@applications/iot-devices/downlink.model"; +import { RestService } from "@shared/services/rest.service"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { MulticastResponse } from "./multicast-response.model"; +import { Multicast, MulticastData } from "./multicast.model"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class MulticastService { - constructor( - private restService: RestService, - private userMinimalService: UserMinimalService - ) {} + constructor(private restService: RestService, private userMinimalService: UserMinimalService) {} - private multicastURL = 'multicast'; - private multicastDownlinkURL = 'multicast/'; - private DOWNLINKMULTICASTURL = 'downlink-multicast'; + private multicastURL = "multicast"; + private multicastDownlinkURL = "multicast/"; + private DOWNLINKMULTICASTURL = "downlink-multicast"; - getMulticastsByApplicationId( - limit: number, - offset: number, - sort: string, - orderOn: string, - applicationId: number - ): Observable { - const body = { - limit, - offset, - sort, - orderOn, - applicationId, - }; - return this.restService.get(this.multicastURL, body); - } + getMulticastsByApplicationId( + limit: number, + offset: number, + sort: string, + orderOn: string, + applicationId: number + ): Observable { + const body = { + limit, + offset, + sort, + orderOn, + applicationId, + }; + return this.restService.get(this.multicastURL, body); + } - get(id: number): Observable { - return this.restService.get(this.multicastURL, {}, id).pipe( - // bind "this" correctly by creating a new lambda function - map((response: MulticastResponse) => { - const multicast = this.mapToMulticast(response); - return multicast; - }) - ); - } + get(id: number): Observable { + return this.restService.get(this.multicastURL, {}, id).pipe( + // bind "this" correctly by creating a new lambda function + map((response: MulticastResponse) => { + const multicast = this.mapToMulticast(response); + return multicast; + }) + ); + } - delete(id: number) { - return this.restService.delete(this.multicastURL, id); - } - update(multicast: Multicast): Observable { - return this.restService.put(this.multicastURL, multicast, multicast.id); - } - create(multicast: Multicast): Observable { - return this.restService.post(this.multicastURL, multicast); - } + delete(id: number) { + return this.restService.delete(this.multicastURL, id); + } + update(multicast: Multicast): Observable { + return this.restService.put(this.multicastURL, multicast, multicast.id); + } + create(multicast: Multicast): Observable { + return this.restService.post(this.multicastURL, multicast); + } - private mapToMulticast(multicastResponse: MulticastResponse): Multicast { - const model: Multicast = { - id: multicastResponse.id, - name: multicastResponse.groupName, - groupType: multicastResponse.lorawanMulticastDefinition.groupType, - mcAddr: multicastResponse.lorawanMulticastDefinition.address, - mcAppSKey: - multicastResponse.lorawanMulticastDefinition.applicationSessionKey, - dr: multicastResponse.lorawanMulticastDefinition.dataRate, - fCnt: multicastResponse.lorawanMulticastDefinition.frameCounter, - frequency: multicastResponse.lorawanMulticastDefinition.frequency, - mcNwkSKey: multicastResponse.lorawanMulticastDefinition.networkSessionKey, - applicationID: multicastResponse.application.id, - iotDevices: multicastResponse.iotDevices, - createdAt: multicastResponse.createdAt, - updatedAt: multicastResponse.updatedAt, - createdBy: multicastResponse.createdBy, - updatedBy: multicastResponse.updatedBy, - createdByName: this.userMinimalService.getUserNameFrom( - multicastResponse.createdBy - ), - updatedByName: this.userMinimalService.getUserNameFrom( - multicastResponse.updatedBy - ), - }; - return model; - } + private mapToMulticast(multicastResponse: MulticastResponse): Multicast { + const model: Multicast = { + id: multicastResponse.id, + name: multicastResponse.groupName, + groupType: multicastResponse.lorawanMulticastDefinition.groupType, + mcAddr: multicastResponse.lorawanMulticastDefinition.address, + mcAppSKey: multicastResponse.lorawanMulticastDefinition.applicationSessionKey, + dr: multicastResponse.lorawanMulticastDefinition.dataRate, + fCnt: multicastResponse.lorawanMulticastDefinition.frameCounter, + frequency: multicastResponse.lorawanMulticastDefinition.frequency, + mcNwkSKey: multicastResponse.lorawanMulticastDefinition.networkSessionKey, + applicationID: multicastResponse.application.id, + iotDevices: multicastResponse.iotDevices, + createdAt: multicastResponse.createdAt, + updatedAt: multicastResponse.updatedAt, + createdBy: multicastResponse.createdBy, + updatedBy: multicastResponse.updatedBy, + createdByName: this.userMinimalService.getUserNameFrom(multicastResponse.createdBy), + updatedByName: this.userMinimalService.getUserNameFrom(multicastResponse.updatedBy), + }; + return model; + } - public multicastGet(multicastId: number, params = {}): Observable { - const url = - this.multicastDownlinkURL + multicastId + '/' + this.DOWNLINKMULTICASTURL; - return this.restService.get(url, params); - } - public multicastPost( - downlink: Downlink, - multicastId: number, - params = {} - ): Observable { - const url = - this.multicastDownlinkURL + multicastId + '/' + this.DOWNLINKMULTICASTURL; - return this.restService.post(url, downlink, params); - } + public multicastGet(multicastId: number, params = {}): Observable { + const url = this.multicastDownlinkURL + multicastId + "/" + this.DOWNLINKMULTICASTURL; + return this.restService.get(url, params); + } + public multicastPost(downlink: Downlink, multicastId: number, params = {}): Observable { + const url = this.multicastDownlinkURL + multicastId + "/" + this.DOWNLINKMULTICASTURL; + return this.restService.post(url, downlink, params); + } } diff --git a/src/app/auth/auth-guard.service.ts b/src/app/auth/auth-guard.service.ts index 055f9685c..2de26c7fb 100644 --- a/src/app/auth/auth-guard.service.ts +++ b/src/app/auth/auth-guard.service.ts @@ -1,26 +1,23 @@ -import { Injectable } from '@angular/core'; -import { AuthService } from './auth.service'; -import { ActivatedRouteSnapshot, Router } from '@angular/router'; +import { Injectable } from "@angular/core"; +import { AuthService } from "./auth.service"; +import { ActivatedRouteSnapshot, Router } from "@angular/router"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class AuthGuardService { - constructor(public auth: AuthService, public router: Router) {} + constructor(public auth: AuthService, public router: Router) {} - canActivate(route: ActivatedRouteSnapshot): boolean { - // Allow KOMBIT adgangsstyring callback to work - if ( - route.queryParams['jwt'] !== undefined || - route.queryParams['error'] !== undefined - ) { - return true; - } + canActivate(route: ActivatedRouteSnapshot): boolean { + // Allow KOMBIT adgangsstyring callback to work + if (route.queryParams["jwt"] !== undefined || route.queryParams["error"] !== undefined) { + return true; + } - if (!this.auth.isAuthenticated()) { - this.router.navigate(['/auth']); - return false; + if (!this.auth.isAuthenticated()) { + this.router.navigate(["/auth"]); + return false; + } + return true; } - return true; - } } diff --git a/src/app/auth/auth.component.html b/src/app/auth/auth.component.html index 2640c689e..e0b7a1754 100644 --- a/src/app/auth/auth.component.html +++ b/src/app/auth/auth.component.html @@ -3,7 +3,7 @@
  • - {{error | translate}} + {{ error | translate }}
@@ -12,21 +12,46 @@
- - + +
- - + +
diff --git a/src/app/auth/auth.component.scss b/src/app/auth/auth.component.scss index d3f5a12fa..e69de29bb 100644 --- a/src/app/auth/auth.component.scss +++ b/src/app/auth/auth.component.scss @@ -1 +0,0 @@ - diff --git a/src/app/auth/auth.component.ts b/src/app/auth/auth.component.ts index 94372f724..58ff42532 100644 --- a/src/app/auth/auth.component.ts +++ b/src/app/auth/auth.component.ts @@ -1,83 +1,83 @@ -import { Component, OnInit } from '@angular/core'; -import { NgForm } from '@angular/forms'; -import { AuthService } from './auth.service'; -import { Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { environment } from '@environments/environment'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { LoggedInService } from '@shared/services/loggedin.service'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; +import { Component, OnInit } from "@angular/core"; +import { NgForm } from "@angular/forms"; +import { AuthService } from "./auth.service"; +import { Router } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { environment } from "@environments/environment"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { LoggedInService } from "@shared/services/loggedin.service"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; @Component({ - selector: 'app-auth', - templateUrl: './auth.component.html', - styleUrls: ['./auth.component.scss'], + selector: "app-auth", + templateUrl: "./auth.component.html", + styleUrls: ["./auth.component.scss"], }) export class AuthComponent implements OnInit { - public errorMessage: string; - public errorMessages: any; - public errorFields: string[]; - public formFailedSubmit = false; - isLoginMode = true; - isLoading = false; - isKombit = false; - error: string = null; + public errorMessage: string; + public errorMessages: any; + public errorFields: string[]; + public formFailedSubmit = false; + isLoginMode = true; + isLoading = false; + isKombit = false; + error: string = null; - constructor( - private authService: AuthService, - private router: Router, - public translate: TranslateService, - private loggedinService: LoggedInService, - private sharedVariableService: SharedVariableService, - private userMinimalService: UserMinimalService - ) {} + constructor( + private authService: AuthService, + private router: Router, + public translate: TranslateService, + private loggedinService: LoggedInService, + private sharedVariableService: SharedVariableService, + private userMinimalService: UserMinimalService + ) {} - ngOnInit(): void {} + ngOnInit(): void {} - getKombitLoginUrl() { - const frontpage = encodeURI(window.location.origin + '/applications'); - return `${environment.baseUrl}auth/kombit/login?redirect=${frontpage}`; - } - - onSwitchMode() { - this.isLoginMode = !this.isLoginMode; - } + getKombitLoginUrl() { + const frontpage = encodeURI(window.location.origin + "/applications"); + return `${environment.baseUrl}auth/kombit/login?redirect=${frontpage}`; + } - async success() { - await this.sharedVariableService.setUserInfo(); - await this.sharedVariableService.setOrganizationInfo(); - this.userMinimalService.setUserMinimalList(); - this.isLoading = false; - this.loggedinService.emitChange(true); - this.router.navigateByUrl('/applications'); - } + onSwitchMode() { + this.isLoginMode = !this.isLoginMode; + } - fail() { - this.isLoading = false; - this.errorFields = ['username', 'password']; - this.errorMessages = ['Login failed. Wrong username or password.']; - this.formFailedSubmit = true; - } + async success() { + await this.sharedVariableService.setUserInfo(); + await this.sharedVariableService.setOrganizationInfo(); + this.userMinimalService.setUserMinimalList(); + this.isLoading = false; + this.loggedinService.emitChange(true); + this.router.navigateByUrl("/applications"); + } - onSubmit(form: NgForm) { - if (!form.valid) { - return; + fail() { + this.isLoading = false; + this.errorFields = ["username", "password"]; + this.errorMessages = ["Login failed. Wrong username or password."]; + this.formFailedSubmit = true; } - const username = form.value.username; - const password = form.value.password; - this.isLoading = true; - this.authService.login(username, password).subscribe( - (x: any) => { - if (x.accessToken) { - this.success(); - } else { - this.fail(); + onSubmit(form: NgForm) { + if (!form.valid) { + return; } - }, - (err) => { - console.log(err); - } - ); - } + const username = form.value.username; + const password = form.value.password; + + this.isLoading = true; + this.authService.login(username, password).subscribe( + (x: any) => { + if (x.accessToken) { + this.success(); + } else { + this.fail(); + } + }, + err => { + console.log(err); + } + ); + } } diff --git a/src/app/auth/auth.module.ts b/src/app/auth/auth.module.ts index 450c06802..c455f125f 100644 --- a/src/app/auth/auth.module.ts +++ b/src/app/auth/auth.module.ts @@ -1,17 +1,11 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { AuthComponent } from './auth.component'; -import { FormsModule } from '@angular/forms'; -import { SharedModule } from '@shared/shared.module'; - - +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { AuthComponent } from "./auth.component"; +import { FormsModule } from "@angular/forms"; +import { SharedModule } from "@shared/shared.module"; @NgModule({ - declarations: [AuthComponent], - imports: [ - CommonModule, - FormsModule, - SharedModule, - ] + declarations: [AuthComponent], + imports: [CommonModule, FormsModule, SharedModule], }) -export class AuthModule { } +export class AuthModule {} diff --git a/src/app/auth/auth.service.ts b/src/app/auth/auth.service.ts index 6bcd1d736..0cf07538b 100644 --- a/src/app/auth/auth.service.ts +++ b/src/app/auth/auth.service.ts @@ -1,113 +1,108 @@ -import { Injectable } from '@angular/core'; -import { catchError, shareReplay, tap } from 'rxjs/operators'; -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { environment } from '@environments/environment'; -import jwtDecode from 'jwt-decode'; -import moment from 'moment'; -import { RestService } from '@shared/services/rest.service'; -import { Observable, of } from 'rxjs'; -import { Organisation } from '@app/admin/organisation/organisation.model'; -import { UserResponse } from '../admin/users/user.model'; -import { JwtHelperService } from '@auth0/angular-jwt'; +import { Injectable } from "@angular/core"; +import { catchError, shareReplay, tap } from "rxjs/operators"; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { environment } from "@environments/environment"; +import jwtDecode from "jwt-decode"; +import moment from "moment"; +import { RestService } from "@shared/services/rest.service"; +import { Observable, of } from "rxjs"; +import { Organisation } from "@app/admin/organisation/organisation.model"; +import { UserResponse } from "../admin/users/user.model"; +import { JwtHelperService } from "@auth0/angular-jwt"; export interface AuthResponseData { - accessToken: string; + accessToken: string; } export interface CurrentUserInfoResponse { - user: UserResponse; - organizations: Organisation[]; + user: UserResponse; + organizations: Organisation[]; } @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class AuthService { - private baseUrl = environment.baseUrl; - private URL = 'auth/login'; - - private readonly LOCAL_STORAGE_JWT_LOCATION = 'id_token'; - - constructor( - private http: HttpClient, - private restService: RestService, - private jwtHelper: JwtHelperService) {} - - isAuthenticated(): boolean { - const token = localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); - return !this.jwtHelper.isTokenExpired(token); - } - - // global-admin@os2iot.dk - // hunter2 - - login(username: string, password: string) { - return this.http - .post(this.baseUrl + this.URL, { - username: username, - password: password, - }) - .pipe( - tap((res) => this.setSession(res.accessToken)), - catchError((error: HttpErrorResponse) => { - return of(error.status); - }) - ); - } - - me(): Observable { - return this.restService.get('auth/me').pipe( - shareReplay(1) - ); - } - - setSession(jwt: string) { - localStorage.setItem(this.LOCAL_STORAGE_JWT_LOCATION, jwt); - } - - getJwt() { - return localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); - } - - isLoggedInWithKombit() { - const jwt = localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); - - const token = this.getDecodedAccessToken(jwt); - return token?.isKombit == true; - } - - logout() { - localStorage.clear(); - } - - public isLoggedIn() { - const exp = this.getExpiration(); - const now = moment(); - return now.isBefore(exp); - } - - getExpiration() { - const jwt = localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); - - if (!jwt) { - return moment(0); + private baseUrl = environment.baseUrl; + private URL = "auth/login"; + + private readonly LOCAL_STORAGE_JWT_LOCATION = "id_token"; + + constructor(private http: HttpClient, private restService: RestService, private jwtHelper: JwtHelperService) {} + + isAuthenticated(): boolean { + const token = localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); + return !this.jwtHelper.isTokenExpired(token); + } + + // global-admin@os2iot.dk + // hunter2 + + login(username: string, password: string) { + return this.http + .post(this.baseUrl + this.URL, { + username: username, + password: password, + }) + .pipe( + tap(res => this.setSession(res.accessToken)), + catchError((error: HttpErrorResponse) => { + return of(error.status); + }) + ); + } + + me(): Observable { + return this.restService.get("auth/me").pipe(shareReplay(1)); + } + + setSession(jwt: string) { + localStorage.setItem(this.LOCAL_STORAGE_JWT_LOCATION, jwt); + } + + getJwt() { + return localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); + } + + isLoggedInWithKombit() { + const jwt = localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); + + const token = this.getDecodedAccessToken(jwt); + return token?.isKombit == true; + } + + logout() { + localStorage.clear(); } - const decoded_jwt = this.getDecodedAccessToken(jwt); - if (decoded_jwt.exp) { - return moment.unix(decoded_jwt.exp); + public isLoggedIn() { + const exp = this.getExpiration(); + const now = moment(); + return now.isBefore(exp); } - return moment.unix(0); - } + getExpiration() { + const jwt = localStorage.getItem(this.LOCAL_STORAGE_JWT_LOCATION); + + if (!jwt) { + return moment(0); + } + + const decoded_jwt = this.getDecodedAccessToken(jwt); + if (decoded_jwt.exp) { + return moment.unix(decoded_jwt.exp); + } + + return moment.unix(0); + } - getDecodedAccessToken(token: string): any { - try { - const decoded = jwtDecode(token); - return decoded; - } catch (Error) { - console.log('Tried to decode jwt but failed? ', Error); - return null; + getDecodedAccessToken(token: string): any { + try { + const decoded = jwtDecode(token); + return decoded; + } catch (Error) { + console.log("Tried to decode jwt but failed? ", Error); + return null; + } } - } } diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 172e0559a..cca73d39d 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -3,44 +3,55 @@
- - +
-
-

+
+

-

{{'DASHBOARD.WELCOME' | translate}}

-

{{'DASHBOARD.WELCOME-SUB' | translate}}

+

{{ "DASHBOARD.WELCOME" | translate }}

+

{{ "DASHBOARD.WELCOME-SUB" | translate }}

-

{{'DASHBOARD.LIST.HEADLINE' | translate}} +

+ {{ "DASHBOARD.LIST.HEADLINE" | translate }}

    -
  • {{'DASHBOARD.LIST.P1' | translate}}
  • -
  • {{'DASHBOARD.LIST.P2' | translate}}
  • -
  • {{'DASHBOARD.LIST.P3' | translate}}
  • -
  • {{'DASHBOARD.LIST.P4' | translate}}
  • -
  • {{'DASHBOARD.LIST.P5' | translate}}
  • -
  • {{'DASHBOARD.LIST.P6' | translate}}
  • -
  • {{'DASHBOARD.LIST.P7' | translate}}
  • +
  • {{ "DASHBOARD.LIST.P1" | translate }}
  • +
  • {{ "DASHBOARD.LIST.P2" | translate }}
  • +
  • {{ "DASHBOARD.LIST.P3" | translate }}
  • +
  • {{ "DASHBOARD.LIST.P4" | translate }}
  • +
  • {{ "DASHBOARD.LIST.P5" | translate }}
  • +
  • {{ "DASHBOARD.LIST.P6" | translate }}
  • +
  • {{ "DASHBOARD.LIST.P7" | translate }}
-

{{'DASHBOARD.SUB-HEADER-1' | translate}}

-

{{'DASHBOARD.WELCOME-MESSAGE' | translate}}{{'DASHBOARD.LINK-1' | - translate}}{{'DASHBOARD.WELCOME-MESSAGE-3' | translate}} +

+ {{ "DASHBOARD.SUB-HEADER-1" | translate }}

-

{{'DASHBOARD.SUB-HEADER-2' | translate}}

-

{{'DASHBOARD.WELCOME-MESSAGE-2' | translate}}{{'DASHBOARD.LINK-2' | - translate}} +

+ {{ "DASHBOARD.WELCOME-MESSAGE" | translate + }}{{ + "DASHBOARD.LINK-1" | translate + }}{{ "DASHBOARD.WELCOME-MESSAGE-3" | translate }} +

+

+ {{ "DASHBOARD.SUB-HEADER-2" | translate }} +

+

+ {{ "DASHBOARD.WELCOME-MESSAGE-2" | translate + }}{{ + "DASHBOARD.LINK-2" | translate + }}

@@ -48,8 +59,12 @@

{{'DASHBOARD.WELCOME-SUB' | translate}}

@@ -57,12 +72,12 @@

{{'DASHBOARD.WELCOME-SUB' | translate}}

-
-
+
+
-

{{'DASHBOARD.WELCOME' | translate}}

-

{{'DASHBOARD.NO-ACCESS' | translate}}

+

{{ "DASHBOARD.WELCOME" | translate }}

+

{{ "DASHBOARD.NO-ACCESS" | translate }}

@@ -70,4 +85,4 @@

{{'DASHBOARD.NO-ACCESS' | translate}}

-
\ No newline at end of file +
diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index 4d07981a2..68986fb9e 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,103 +1,98 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { ActivatedRoute, Router } from '@angular/router'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; -import { AuthService } from '@auth/auth.service'; -import { TranslateService } from '@ngx-translate/core'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { MeService } from '@shared/services/me.service'; +import { Component, OnInit } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { ActivatedRoute, Router } from "@angular/router"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; +import { AuthService } from "@auth/auth.service"; +import { TranslateService } from "@ngx-translate/core"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { MeService } from "@shared/services/me.service"; @Component({ - selector: 'app-dashboard', - templateUrl: './dashboard.component.html', - styleUrls: ['./dashboard.component.scss'], + selector: "app-dashboard", + templateUrl: "./dashboard.component.html", + styleUrls: ["./dashboard.component.scss"], }) export class DashboardComponent implements OnInit { - unauthorizedMessage: string; - kombitError: string; - noAccess: string; - isLoadingResults = true; - hasSomePermission: boolean; - isGlobalAdmin = false; + unauthorizedMessage: string; + kombitError: string; + noAccess: string; + isLoadingResults = true; + hasSomePermission: boolean; + isGlobalAdmin = false; - constructor( - private route: ActivatedRoute, - private authService: AuthService, - private router: Router, - private sharedVariableService: SharedVariableService, - private translate: TranslateService, - private titleService: Title, - private userMinimalService: UserMinimalService, - private meService: MeService - ) { + constructor( + private route: ActivatedRoute, + private authService: AuthService, + private router: Router, + private sharedVariableService: SharedVariableService, + private translate: TranslateService, + private titleService: Title, + private userMinimalService: UserMinimalService, + private meService: MeService + ) { + this.route.queryParams.subscribe(async params => { + this.translate.use("da"); + await this.translate + .get([ + "DASHBOARD.NO-JOB-ACCESS", + "TITLE.FRONTPAGE", + "DASHBOARD.KOMBIT-LOGIN-ERROR", + "DASHBOARD.USER-INACTIVE", + ]) + .toPromise() + .then(translations => { + this.unauthorizedMessage = translations["DASHBOARD.NO-JOB-ACCESS"]; + this.kombitError = translations["DASHBOARD.KOMBIT-LOGIN-ERROR"]; + this.noAccess = translations["DASHBOARD.USER-INACTIVE"]; + this.titleService.setTitle(translations["TITLE.FRONTPAGE"]); + }); - this.route.queryParams.subscribe(async (params) => { - this.translate.use('da'); - await this.translate - .get([ - 'DASHBOARD.NO-JOB-ACCESS', - 'TITLE.FRONTPAGE', - 'DASHBOARD.KOMBIT-LOGIN-ERROR', - 'DASHBOARD.USER-INACTIVE', - ]) - .toPromise() - .then((translations) => { - this.unauthorizedMessage = translations['DASHBOARD.NO-JOB-ACCESS']; - this.kombitError = translations['DASHBOARD.KOMBIT-LOGIN-ERROR']; - this.noAccess = translations['DASHBOARD.USER-INACTIVE']; - this.titleService.setTitle(translations['TITLE.FRONTPAGE']); - }); - - // this is used when a user is returned from Kombit login - const jwt = params['jwt']; - if (jwt) { - this.authService.setSession(jwt); - const userInfo = await this.sharedVariableService.setUserInfo(); - if (!userInfo.user.email) { - this.router.navigate(['/new-user'], { - state: { code: 200 }, - }); - } else { - // Clear the URL from the parameter - this.router.navigate(['/dashboard']); - } + // this is used when a user is returned from Kombit login + const jwt = params["jwt"]; + if (jwt) { + this.authService.setSession(jwt); + const userInfo = await this.sharedVariableService.setUserInfo(); + if (!userInfo.user.email) { + this.router.navigate(["/new-user"], { + state: { code: 200 }, + }); + } else { + // Clear the URL from the parameter + this.router.navigate(["/dashboard"]); + } + } else { + const error = params["error"]; + if (error) { + if (error == "MESSAGE.KOMBIT-LOGIN-FAILED" || error == "MESSAGE.API-KEY-AUTH-FAILED") { + this.router.navigate(["/not-authorized"], { + state: { message: this.kombitError, code: 401 }, + }); + } + if (error == "MESSAGE.USER-INACTIVE") { + this.router.navigate(["/not-authorized"], { + state: { message: this.noAccess, code: 401 }, + }); + } else { + this.router.navigate(["/not-authorized"], { + state: { message: this.unauthorizedMessage, code: 401 }, + }); + } + } + } - } else { - const error = params['error']; - if (error) { - if ( - error == 'MESSAGE.KOMBIT-LOGIN-FAILED' || - error == 'MESSAGE.API-KEY-AUTH-FAILED' - ) { - this.router.navigate(['/not-authorized'], { - state: { message: this.kombitError, code: 401 }, - }); - } - if (error == 'MESSAGE.USER-INACTIVE') { - this.router.navigate(['/not-authorized'], { - state: { message: this.noAccess, code: 401 }, - }); - } else { - this.router.navigate(['/not-authorized'], { - state: { message: this.unauthorizedMessage, code: 401 }, - }); - } - } - } + const userInfo = await this.sharedVariableService.setUserInfo(); + await this.sharedVariableService.setOrganizationInfo(); - const userInfo = await this.sharedVariableService.setUserInfo(); - await this.sharedVariableService.setOrganizationInfo(); + this.userMinimalService.setUserMinimalList(); + this.hasSomePermission = this.sharedVariableService.getHasAnyPermission(); + this.isGlobalAdmin = this.meService.hasGlobalAdmin(); + this.isLoadingResults = false; - this.userMinimalService.setUserMinimalList(); - this.hasSomePermission = this.sharedVariableService.getHasAnyPermission(); - this.isGlobalAdmin = this. meService.hasGlobalAdmin(); - this.isLoadingResults = false; - - if (userInfo.user.awaitingConfirmation && userInfo.user.email) { - this.router.navigate(['/user-page']); - } - }); - } + if (userInfo.user.awaitingConfirmation && userInfo.user.email) { + this.router.navigate(["/user-page"]); + } + }); + } - ngOnInit(): void {} + ngOnInit(): void {} } diff --git a/src/app/device-model/Enums/controlled-propperty.enum.ts b/src/app/device-model/Enums/controlled-propperty.enum.ts index 1918ddcbf..d74074c01 100644 --- a/src/app/device-model/Enums/controlled-propperty.enum.ts +++ b/src/app/device-model/Enums/controlled-propperty.enum.ts @@ -39,5 +39,5 @@ export enum ControlledPropertyTypes { WEATHERCONDITIONS = "weatherConditions", WEIGHT = "weight", WINDDIRECTION = "windDirection", - WINDSPEED = "windSpeed" + WINDSPEED = "windSpeed", } diff --git a/src/app/device-model/Enums/device-category.enum.ts b/src/app/device-model/Enums/device-category.enum.ts index 8b6cf9628..b10ffce60 100644 --- a/src/app/device-model/Enums/device-category.enum.ts +++ b/src/app/device-model/Enums/device-category.enum.ts @@ -1,12 +1,12 @@ export enum DeviceCategory { - ACTUATOR = 'actuator', - ENDGUN = 'endgun', - HVAC = 'HVAC', - IMPLEMENT = 'implement', - IRRSECTION = 'irrSection', - IRRSYSTEM = 'irrSystem', - METER = 'meter', - MULTIMEDIA = 'multimedia', - NETWORK = 'network', - SENSOR = 'sensor', + ACTUATOR = "actuator", + ENDGUN = "endgun", + HVAC = "HVAC", + IMPLEMENT = "implement", + IRRSECTION = "irrSection", + IRRSYSTEM = "irrSystem", + METER = "meter", + MULTIMEDIA = "multimedia", + NETWORK = "network", + SENSOR = "sensor", } diff --git a/src/app/device-model/Enums/device-function.enum.ts b/src/app/device-model/Enums/device-function.enum.ts index ed84087e3..3c54000fa 100644 --- a/src/app/device-model/Enums/device-function.enum.ts +++ b/src/app/device-model/Enums/device-function.enum.ts @@ -1,8 +1,8 @@ export enum DeviceFunction { - LEVELCONTROL = 'levelControl', - SENSING = 'sensing', - ONOFF = 'onOff', - OPENCLOSE = 'openClose', - METERING = 'metering', - EVENTNOTIFICATION = 'eventNotification' + LEVELCONTROL = "levelControl", + SENSING = "sensing", + ONOFF = "onOff", + OPENCLOSE = "openClose", + METERING = "metering", + EVENTNOTIFICATION = "eventNotification", } diff --git a/src/app/device-model/Enums/energy-limitation-class.model.ts b/src/app/device-model/Enums/energy-limitation-class.model.ts index 6b1d17f29..bd975b149 100644 --- a/src/app/device-model/Enums/energy-limitation-class.model.ts +++ b/src/app/device-model/Enums/energy-limitation-class.model.ts @@ -3,10 +3,10 @@ export class EnergyLimitationClass { constructor() { this.energyLimits = [ - { code: 'E0', name: 'Event energy-limited'}, - { code: 'E1', name: 'Period energy-limited'}, - { code: 'E2', name: 'Lifetime energy-limited'}, - { code: 'E9', name: 'No direct quantitative limitations to available energy'} + { code: "E0", name: "Event energy-limited" }, + { code: "E1", name: "Period energy-limited" }, + { code: "E2", name: "Lifetime energy-limited" }, + { code: "E9", name: "No direct quantitative limitations to available energy" }, ]; } } diff --git a/src/app/device-model/Enums/supported-protocol.enum.ts b/src/app/device-model/Enums/supported-protocol.enum.ts index 87f18424e..f74149b96 100644 --- a/src/app/device-model/Enums/supported-protocol.enum.ts +++ b/src/app/device-model/Enums/supported-protocol.enum.ts @@ -1,19 +1,19 @@ export enum SupportedProtocol { - THREEG = '3g', - BLUETOOTH = 'bluetooth', - BLUETOOTHLE = 'bluetooth LE', - CATM = 'cat-m', - COAP = 'coap', - ECGSMIOT = 'ec-gsm-iot', - GRPS = 'grps', - HTTP = 'http', - LORA = 'lora', - LTEM = 'lte-m', - LWM2M = 'lwm2m', - MQTT = 'mqtt', - NBIOT = 'nb-iot', - ONEM2M = 'onem2m', - SIGFOX = 'sigfox', - UL20 = 'ul20', - WEBSOCKET = 'websocket' + THREEG = "3g", + BLUETOOTH = "bluetooth", + BLUETOOTHLE = "bluetooth LE", + CATM = "cat-m", + COAP = "coap", + ECGSMIOT = "ec-gsm-iot", + GRPS = "grps", + HTTP = "http", + LORA = "lora", + LTEM = "lte-m", + LWM2M = "lwm2m", + MQTT = "mqtt", + NBIOT = "nb-iot", + ONEM2M = "onem2m", + SIGFOX = "sigfox", + UL20 = "ul20", + WEBSOCKET = "websocket", } diff --git a/src/app/device-model/device-model-detail/device-model-detail.component.html b/src/app/device-model/device-model-detail/device-model-detail.component.html index f43d3ab07..ea8b73b93 100644 --- a/src/app/device-model/device-model-detail/device-model-detail.component.html +++ b/src/app/device-model/device-model-detail/device-model-detail.component.html @@ -1,31 +1,62 @@
- +
-

{{ 'DEVICE-MODEL.HEADLINE' | translate }}

+

{{ "DEVICE-MODEL.HEADLINE" | translate }}

-

{{ 'DEVICE-MODEL.ID' | translate }}{{deviceModel.body.id}}

-

{{ 'DEVICE-MODEL.BRANDNAME' | translate }}{{deviceModel.body.brandName}}

-

{{ 'DEVICE-MODEL.MODELNAME' | translate }}{{deviceModel.body.modelName}}

-

{{ 'DEVICE-MODEL.MANUFACTURERNAME' | translate }}{{deviceModel.body.manufacturerName}} +

+ {{ "DEVICE-MODEL.ID" | translate }}{{ deviceModel.body.id }}

-

{{ 'DEVICE-MODEL.CONTROLLEDPROPERTY' | translate }}{{deviceModel.body.controlledProperty.join(', ')}} +

+ {{ "DEVICE-MODEL.BRANDNAME" | translate }}{{ deviceModel.body.brandName }}

-

{{ 'DEVICE-MODEL.CATEGORY' | translate }}{{deviceModel.body.category}}

-

{{ 'DEVICE-MODEL.SUPPORTEDUNITS' | translate }}{{deviceModel.body.supportedUnits}} +

+ {{ "DEVICE-MODEL.MODELNAME" | translate }}{{ deviceModel.body.modelName }}

-

{{ 'DEVICE-MODEL.FUNCTION' | translate }}{{deviceModel.body.function}}

-

{{ 'DEVICE-MODEL.ENERGYLIMITATIONCLASS' | translate }}{{deviceModel.body.energyLimitationClass}} +

+ {{ "DEVICE-MODEL.MANUFACTURERNAME" | translate }}{{ deviceModel.body.manufacturerName }}

-

{{ 'DEVICE-MODEL.SUPPORTEDPROTOCOL' | translate }}{{deviceModel.body.supportedProtocol}} +

+ {{ "DEVICE-MODEL.CONTROLLEDPROPERTY" | translate }}{{ deviceModel.body.controlledProperty.join(", ") }} +

+

+ {{ "DEVICE-MODEL.CATEGORY" | translate }}{{ deviceModel.body.category }} +

+

+ {{ "DEVICE-MODEL.SUPPORTEDUNITS" | translate }}{{ deviceModel.body.supportedUnits }} +

+

+ {{ "DEVICE-MODEL.FUNCTION" | translate }}{{ deviceModel.body.function }} +

+

+ {{ "DEVICE-MODEL.ENERGYLIMITATIONCLASS" | translate }}{{ deviceModel.body.energyLimitationClass }} +

+

+ {{ "DEVICE-MODEL.SUPPORTEDPROTOCOL" | translate }}{{ deviceModel.body.supportedProtocol }}

-
diff --git a/src/app/device-model/device-model-detail/device-model-detail.component.spec.ts b/src/app/device-model/device-model-detail/device-model-detail.component.spec.ts index 33ed13275..4c203b444 100644 --- a/src/app/device-model/device-model-detail/device-model-detail.component.spec.ts +++ b/src/app/device-model/device-model-detail/device-model-detail.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DeviceModelDetailComponent } from './device-model-detail.component'; +import { DeviceModelDetailComponent } from "./device-model-detail.component"; -describe('DeviceModelDetailComponent', () => { - let component: DeviceModelDetailComponent; - let fixture: ComponentFixture; +describe("DeviceModelDetailComponent", () => { + let component: DeviceModelDetailComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DeviceModelDetailComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DeviceModelDetailComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DeviceModelDetailComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DeviceModelDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/device-model/device-model-detail/device-model-detail.component.ts b/src/app/device-model/device-model-detail/device-model-detail.component.ts index a98105967..a0de055d4 100644 --- a/src/app/device-model/device-model-detail/device-model-detail.component.ts +++ b/src/app/device-model/device-model-detail/device-model-detail.component.ts @@ -1,101 +1,99 @@ -import { Location } from '@angular/common'; -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { DropdownButton } from '@shared/models/dropdown-button.model'; -import { Subscription } from 'rxjs'; -import { DeviceModelService } from '../device-model.service'; -import { DeviceModel } from '../device.model'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Location } from "@angular/common"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { DropdownButton } from "@shared/models/dropdown-button.model"; +import { Subscription } from "rxjs"; +import { DeviceModelService } from "../device-model.service"; +import { DeviceModel } from "../device.model"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-device-model-detail', - templateUrl: './device-model-detail.component.html', - styleUrls: ['./device-model-detail.component.scss'] + selector: "app-device-model-detail", + templateUrl: "./device-model-detail.component.html", + styleUrls: ["./device-model-detail.component.scss"], }) export class DeviceModelDetailComponent implements OnInit, OnDestroy { + deviceModel: DeviceModel; + public backButton: BackButton = { label: "", routerLink: "device-model" }; + public title: string; + deleteDialogSubscription: Subscription; + dropdownButton: DropdownButton; + errorTitle: string; + canEdit: boolean; - deviceModel: DeviceModel; - public backButton: BackButton = { label: '', routerLink: 'device-model' }; - public title: string; - deleteDialogSubscription: Subscription; - dropdownButton: DropdownButton; - errorTitle: string; - canEdit: boolean; + constructor( + private translate: TranslateService, + private route: ActivatedRoute, + private deviceModelService: DeviceModelService, + private deleteDialogservice: DeleteDialogService, + private router: Router, + private meService: MeService + ) {} - constructor( - private translate: TranslateService, - private route: ActivatedRoute, - private deviceModelService: DeviceModelService, - private deleteDialogservice: DeleteDialogService, - private router: Router, - private meService: MeService - ) { } + ngOnInit(): void { + const deviceModelId = +this.route.snapshot.paramMap.get("deviceId"); + const appId: number = +this.route.snapshot.paramMap.get("id"); - ngOnInit(): void { - const deviceModelId = +this.route.snapshot.paramMap.get('deviceId'); - const appId: number = +this.route.snapshot.paramMap.get('id'); + if (deviceModelId) { + this.getDeviceModel(deviceModelId); + this.dropdownButton = { + label: "", + editRouterLink: "/device-model/device-model-edit/" + deviceModelId, + isErasable: true, + }; + } + this.translate.use("da"); + this.translate + .get([ + "DEVICE-MODEL.DETAIL-TITLE", + "DEVICE-MODEL.DEVICE-MODEL", + "DEVICE-MODEL.SHOW-OPTIONS", + "DEVICE-MODEL.DELETE-FAILED", + ]) + .subscribe(translations => { + this.backButton.label = translations["DEVICE-MODEL.DEVICE-MODEL"]; + this.dropdownButton.label = translations["DEVICE-MODEL.SHOW-OPTIONS"]; + this.title = translations["DEVICE-MODEL.DETAIL-TITLE"]; + this.errorTitle = translations["DEVICE-MODEL.DELETE-FAILED"]; + }); + this.canEdit = this.meService.hasAccessToTargetOrganization( + OrganizationAccessScope.ApplicationWrite, + undefined, + appId + ); + } - if (deviceModelId) { - this.getDeviceModel(deviceModelId); - this.dropdownButton = { - label: '', - editRouterLink: '/device-model/device-model-edit/' + deviceModelId, - isErasable: true, - }; + private getDeviceModel(id: number) { + this.deviceModelService.get(id).subscribe(response => { + this.deviceModel = response; + }); } - this.translate.use('da'); - this.translate.get(['DEVICE-MODEL.DETAIL-TITLE', 'DEVICE-MODEL.DEVICE-MODEL', 'DEVICE-MODEL.SHOW-OPTIONS', 'DEVICE-MODEL.DELETE-FAILED']) - .subscribe(translations => { - this.backButton.label = translations['DEVICE-MODEL.DEVICE-MODEL']; - this.dropdownButton.label = translations['DEVICE-MODEL.SHOW-OPTIONS']; - this.title = translations['DEVICE-MODEL.DETAIL-TITLE']; - this.errorTitle = translations['DEVICE-MODEL.DELETE-FAILED']; - }); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite, undefined, appId); - } - private getDeviceModel(id: number) { - this.deviceModelService.get(id) - .subscribe((response) => { - this.deviceModel = response; - }); - } + public clickDelete() { + this.deleteDialogSubscription = this.deleteDialogservice.showSimpleDialog().subscribe(response => { + if (response) { + this.deviceModelService.delete(this.deviceModel.id).subscribe(response => { + if (response.ok && response.body.affected > 0) { + this.router.navigate(["device-model"]); + } else { + this.deleteDialogSubscription = this.deleteDialogservice + .showSimpleDialog(response.error.message, false, false, true, this.errorTitle) + .subscribe(); + } + }); + } else { + console.log(response); + } + }); + } - public clickDelete() { - this.deleteDialogSubscription = this.deleteDialogservice.showSimpleDialog() - .subscribe( - (response) => { - if (response) { - this.deviceModelService.delete(this.deviceModel.id) - .subscribe( - (response) => { - if (response.ok && response.body.affected > 0) { - this.router.navigate(['device-model']); - } else { - this.deleteDialogSubscription = this.deleteDialogservice.showSimpleDialog( - response.error.message, - false, - false, - true, - this.errorTitle).subscribe(); - } - } - ); - } else { - console.log(response); - } + ngOnDestroy(): void { + if (this.deleteDialogSubscription) { + this.deleteDialogSubscription.unsubscribe(); } - ); - } - - ngOnDestroy(): void { - if (this.deleteDialogSubscription) { - this.deleteDialogSubscription.unsubscribe(); } - } - } diff --git a/src/app/device-model/device-model-edit/device-model-edit.component.html b/src/app/device-model/device-model-edit/device-model-edit.component.html index 3b349ba1f..de32776c7 100644 --- a/src/app/device-model/device-model-edit/device-model-edit.component.html +++ b/src/app/device-model/device-model-edit/device-model-edit.component.html @@ -3,76 +3,135 @@
  • - {{error | translate}} + {{ error | translate }}
- * - {{ "QUESTION.DEVICE-MODEL.GIVE-NAME" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('name'), + 'is-valid': formFailedSubmit && !errorFields.includes('name') + }" + />
- * - {{ "QUESTION.DEVICE-MODEL.GIVE-ID" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('id'), + 'is-valid': formFailedSubmit && !errorFields.includes('id') + }" + />
- * - {{ "QUESTION.DEVICE-MODEL.GIVE-BRANDNAME" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('brandName'), + 'is-valid': formFailedSubmit && !errorFields.includes('brandName') + }" + />
- * - {{ "QUESTION.DEVICE-MODEL.GIVE-MODELNAME" | translate }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('modelName'), + 'is-valid': formFailedSubmit && !errorFields.includes('modelName') + }" + />
- * - {{ + "QUESTION.DEVICE-MODEL.GIVE-MANUFACTURERNAME" | translate + }}* + + [ngClass]="{ + 'is-invalid': formFailedSubmit && errorFields.includes('manufacturerName'), + 'is-valid': formFailedSubmit && !errorFields.includes('manufacturerName') + }" + />
- * + * - - {{control}} + [(ngModel)]="deviceModel.body.controlledProperty" + > + + {{ control }}
@@ -80,16 +139,16 @@
- * + * - - {{category}} + [(ngModel)]="deviceModel.body.category" + > + + {{ category }}
@@ -97,17 +156,18 @@
- + - - {{unit.name}} + [(ngModel)]="deviceModel.body.supportedUnits" + > + + {{ unit.name }}
@@ -115,16 +175,18 @@
- + - - {{function}} + multiple + [compareWith]="compare" + [(ngModel)]="deviceModel.body.function" + > + + {{ function }}
@@ -132,16 +194,17 @@
- + - - {{elclass.name}} + [(ngModel)]="deviceModel.body.energyLimitationClass" + > + + {{ elclass.name }}
@@ -149,16 +212,18 @@
- + - - {{protocol}} + multiple + [compareWith]="compare" + [(ngModel)]="deviceModel.body.supportedProtocol" + > + + {{ protocol }}
@@ -167,12 +232,12 @@ -
- - -
+
+ + +
diff --git a/src/app/device-model/device-model-edit/device-model-edit.component.ts b/src/app/device-model/device-model-edit/device-model-edit.component.ts index d9a13e786..ca178fcee 100644 --- a/src/app/device-model/device-model-edit/device-model-edit.component.ts +++ b/src/app/device-model/device-model-edit/device-model-edit.component.ts @@ -1,119 +1,113 @@ -import { Location } from '@angular/common'; -import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorMessageService } from '@shared/error-message.service'; -import { BackButton } from '@shared/models/back-button.model'; -import { ScrollToTopService } from '@shared/services/scroll-to-top.service'; -import { DeviceModelService } from '../device-model.service'; -import { DeviceModel } from '../device.model'; -import { ControlledPropertyTypes } from '../Enums/controlled-propperty.enum'; -import { DeviceCategory } from '../Enums/device-category.enum'; -import { DeviceFunction } from '../Enums/device-function.enum'; -import { EnergyLimitationClass } from '../Enums/energy-limitation-class.model'; -import { SupportedProtocol } from '../Enums/supported-protocol.enum'; -import { SupportedUnit } from '../supported-unit.model'; +import { Location } from "@angular/common"; +import { HttpErrorResponse } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorMessageService } from "@shared/error-message.service"; +import { BackButton } from "@shared/models/back-button.model"; +import { ScrollToTopService } from "@shared/services/scroll-to-top.service"; +import { DeviceModelService } from "../device-model.service"; +import { DeviceModel } from "../device.model"; +import { ControlledPropertyTypes } from "../Enums/controlled-propperty.enum"; +import { DeviceCategory } from "../Enums/device-category.enum"; +import { DeviceFunction } from "../Enums/device-function.enum"; +import { EnergyLimitationClass } from "../Enums/energy-limitation-class.model"; +import { SupportedProtocol } from "../Enums/supported-protocol.enum"; +import { SupportedUnit } from "../supported-unit.model"; @Component({ - selector: 'app-device-model-edit', - templateUrl: './device-model-edit.component.html', - styleUrls: ['./device-model-edit.component.scss'] + selector: "app-device-model-edit", + templateUrl: "./device-model-edit.component.html", + styleUrls: ["./device-model-edit.component.scss"], }) export class DeviceModelEditComponent implements OnInit { + public errorMessages: string[]; + public errorFields: string[]; + public deviceModel: DeviceModel = new DeviceModel(); + public backButton: BackButton = { label: "", routerLink: "/device-model" }; + public title = ""; + public formFailedSubmit = false; + controlledPropperties: ControlledPropertyTypes[] = []; + categories: DeviceCategory[] = []; + supportedUnits = new SupportedUnit(); + deviceFunctions: DeviceFunction[] = []; + energyLimitationClass = new EnergyLimitationClass(); + supportedProtocol: SupportedProtocol[] = []; - public errorMessages: string[]; - public errorFields: string[]; - public deviceModel: DeviceModel = new DeviceModel(); - public backButton: BackButton = { label: '', routerLink: '/device-model' }; - public title = ''; - public formFailedSubmit = false; - controlledPropperties: ControlledPropertyTypes[] = []; - categories: DeviceCategory[] = []; - supportedUnits = new SupportedUnit(); - deviceFunctions: DeviceFunction[] = []; - energyLimitationClass = new EnergyLimitationClass(); - supportedProtocol: SupportedProtocol[] = []; + constructor( + private translate: TranslateService, + private location: Location, + private deviceModelService: DeviceModelService, + private errorMessageService: ErrorMessageService, + private route: ActivatedRoute, + private scrollToTopService: ScrollToTopService + ) {} - constructor( - private translate: TranslateService, - private location: Location, - private deviceModelService: DeviceModelService, - private errorMessageService: ErrorMessageService, - private route: ActivatedRoute, - private scrollToTopService: ScrollToTopService, - ) { } - - ngOnInit(): void { - this.translate.get(['NAV.DEVICE-MODEL']) - .subscribe(translations => { - this.backButton.label = translations['NAV.DEVICE-MODEL']; - this.title = translations['NAV.DEVICE-MODEL']; - }); - this.mapEnumsToArray(); - const deviceModelId = +this.route.snapshot.paramMap.get('deviceId'); - if (deviceModelId) { - this.getDeviceModel(deviceModelId); + ngOnInit(): void { + this.translate.get(["NAV.DEVICE-MODEL"]).subscribe(translations => { + this.backButton.label = translations["NAV.DEVICE-MODEL"]; + this.title = translations["NAV.DEVICE-MODEL"]; + }); + this.mapEnumsToArray(); + const deviceModelId = +this.route.snapshot.paramMap.get("deviceId"); + if (deviceModelId) { + this.getDeviceModel(deviceModelId); + } + this.supportedUnits.units.sort((a, b) => a.name.localeCompare(b.name)); + this.deviceFunctions.sort((a, b) => a.localeCompare(b)); } - this.supportedUnits.units.sort((a, b) => a.name.localeCompare(b.name)); - this.deviceFunctions.sort((a, b) => a.localeCompare(b)); - } - mapEnumsToArray() { - this.controlledPropperties = Object.values(ControlledPropertyTypes); - this.categories = Object.values(DeviceCategory); - this.deviceFunctions = Object.values(DeviceFunction); - this.supportedProtocol = Object.values(SupportedProtocol); - } - - public compare(o1: any, o2: any): boolean { - return o1 === o2; - } + mapEnumsToArray() { + this.controlledPropperties = Object.values(ControlledPropertyTypes); + this.categories = Object.values(DeviceCategory); + this.deviceFunctions = Object.values(DeviceFunction); + this.supportedProtocol = Object.values(SupportedProtocol); + } - private getDeviceModel(id: number) { - this.deviceModelService.get(id) - .subscribe((response) => { - this.deviceModel = response; - }); - } + public compare(o1: any, o2: any): boolean { + return o1 === o2; + } - createDeviceModel() { - this.deviceModelService.create(this.deviceModel) - .subscribe( - (response) => { - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - } - ); - } + private getDeviceModel(id: number) { + this.deviceModelService.get(id).subscribe(response => { + this.deviceModel = response; + }); + } - handleError(err: HttpErrorResponse) { - const errorResponse = this.errorMessageService.handleErrorMessageWithFields(err); - this.errorMessages = errorResponse.errorMessages; - this.errorFields = errorResponse.errorFields; - this.scrollToTopService.scrollToTop(); - } + createDeviceModel() { + this.deviceModelService.create(this.deviceModel).subscribe( + response => { + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + } + ); + } - updateDeviceModel() { - this.deviceModelService.update(this.deviceModel, +this.deviceModel.id) - .subscribe( - (response) => { - this.routeBack(); - }, - (error: HttpErrorResponse) => { - this.handleError(error); - } - ); - } + handleError(err: HttpErrorResponse) { + const errorResponse = this.errorMessageService.handleErrorMessageWithFields(err); + this.errorMessages = errorResponse.errorMessages; + this.errorFields = errorResponse.errorFields; + this.scrollToTopService.scrollToTop(); + } - onSubmit() { - this.deviceModel.id ? this.updateDeviceModel() : this.createDeviceModel(); - } + updateDeviceModel() { + this.deviceModelService.update(this.deviceModel, +this.deviceModel.id).subscribe( + response => { + this.routeBack(); + }, + (error: HttpErrorResponse) => { + this.handleError(error); + } + ); + } - routeBack(): void { - this.location.back(); - } + onSubmit() { + this.deviceModel.id ? this.updateDeviceModel() : this.createDeviceModel(); + } + routeBack(): void { + this.location.back(); + } } diff --git a/src/app/device-model/device-model-list/device-model-list.component.html b/src/app/device-model/device-model-list/device-model-list.component.html index 4c06fc42d..d2f1fecfe 100644 --- a/src/app/device-model/device-model-list/device-model-list.component.html +++ b/src/app/device-model/device-model-list/device-model-list.component.html @@ -1,13 +1,16 @@ - +
-
-
-
- -
+
+
+
+ +
+
-
diff --git a/src/app/device-model/device-model-list/device-model-list.component.ts b/src/app/device-model/device-model-list/device-model-list.component.ts index 287897d00..878a1ddfa 100644 --- a/src/app/device-model/device-model-list/device-model-list.component.ts +++ b/src/app/device-model/device-model-list/device-model-list.component.ts @@ -1,32 +1,26 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; -import { TranslateService } from '@ngx-translate/core'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { MeService } from '@shared/services/me.service'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; +import { Component, OnInit } from "@angular/core"; +import { Title } from "@angular/platform-browser"; +import { TranslateService } from "@ngx-translate/core"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { MeService } from "@shared/services/me.service"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; @Component({ - selector: 'app-device-model-list', - templateUrl: './device-model-list.component.html', - styleUrls: ['./device-model-list.component.scss'] + selector: "app-device-model-list", + templateUrl: "./device-model-list.component.html", + styleUrls: ["./device-model-list.component.scss"], }) export class DeviceModelListComponent implements OnInit { - canEdit: boolean; + canEdit: boolean; - constructor( - private translate: TranslateService, - private titleService: Title, - private meService: MeService - ) { - translate.use('da'); - } - - ngOnInit(): void { - this.translate.get(['TITLE.DEVICEMODEL']) - .subscribe(translations => { - this.titleService.setTitle(translations['TITLE.DEVICEMODEL']); - }); - this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite); - } + constructor(private translate: TranslateService, private titleService: Title, private meService: MeService) { + translate.use("da"); + } + ngOnInit(): void { + this.translate.get(["TITLE.DEVICEMODEL"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.DEVICEMODEL"]); + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite); + } } diff --git a/src/app/device-model/device-model-routing.module.ts b/src/app/device-model/device-model-routing.module.ts index c56b6bd1c..67609d119 100644 --- a/src/app/device-model/device-model-routing.module.ts +++ b/src/app/device-model/device-model-routing.module.ts @@ -1,24 +1,24 @@ -import { Routes, RouterModule } from '@angular/router'; -import { NgModule } from '@angular/core'; -import { DeviceModelListComponent } from './device-model-list/device-model-list.component'; -import { DeviceModelEditComponent } from './device-model-edit/device-model-edit.component'; -import { DeviceModelDetailComponent } from './device-model-detail/device-model-detail.component'; -import { DeviceModelTableComponent } from './device-model-table/device-model-table.component'; +import { Routes, RouterModule } from "@angular/router"; +import { NgModule } from "@angular/core"; +import { DeviceModelListComponent } from "./device-model-list/device-model-list.component"; +import { DeviceModelEditComponent } from "./device-model-edit/device-model-edit.component"; +import { DeviceModelDetailComponent } from "./device-model-detail/device-model-detail.component"; +import { DeviceModelTableComponent } from "./device-model-table/device-model-table.component"; const routes: Routes = [ { - path: '', + path: "", children: [ - { path: '', component: DeviceModelListComponent }, - { path: 'device-model-edit', component: DeviceModelEditComponent }, - { path: 'device-model-edit/:deviceId', component: DeviceModelEditComponent }, - { path: 'device-model-detail/:deviceId', component: DeviceModelDetailComponent } - ] - } + { path: "", component: DeviceModelListComponent }, + { path: "device-model-edit", component: DeviceModelEditComponent }, + { path: "device-model-edit/:deviceId", component: DeviceModelEditComponent }, + { path: "device-model-detail/:deviceId", component: DeviceModelDetailComponent }, + ], + }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + exports: [RouterModule], }) -export class DeviceModelRoutingModule { } +export class DeviceModelRoutingModule {} diff --git a/src/app/device-model/device-model-table/device-model-table.component.html b/src/app/device-model/device-model-table/device-model-table.component.html index b4b761447..5b2eb58c3 100644 --- a/src/app/device-model/device-model-table/device-model-table.component.html +++ b/src/app/device-model/device-model-table/device-model-table.component.html @@ -6,11 +6,14 @@ - {{ 'DEVICE-MODEL.NAME' | translate }} + {{ "DEVICE-MODEL.NAME" | translate }} - + {{ element.body.name }} @@ -18,7 +21,7 @@ - {{ 'DEVICE-MODEL.TABLE.ID' | translate }} + {{ "DEVICE-MODEL.TABLE.ID" | translate }} {{ element.id }} @@ -29,17 +32,26 @@ @@ -47,8 +59,13 @@ - + - +
diff --git a/src/app/device-model/device-model-table/device-model-table.component.spec.ts b/src/app/device-model/device-model-table/device-model-table.component.spec.ts index 285c7a643..b0b1bedcf 100644 --- a/src/app/device-model/device-model-table/device-model-table.component.spec.ts +++ b/src/app/device-model/device-model-table/device-model-table.component.spec.ts @@ -1,25 +1,24 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { DeviceModelTableComponent } from './device-model-table.component'; +import { DeviceModelTableComponent } from "./device-model-table.component"; -describe('DeviceModelTableComponent', () => { - let component: DeviceModelTableComponent; - let fixture: ComponentFixture; +describe("DeviceModelTableComponent", () => { + let component: DeviceModelTableComponent; + let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ DeviceModelTableComponent ] - }) - .compileComponents(); - })); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DeviceModelTableComponent], + }).compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(DeviceModelTableComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DeviceModelTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it("should create", () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/device-model/device-model-table/device-model-table.component.ts b/src/app/device-model/device-model-table/device-model-table.component.ts index e4f44bc22..0a1654a1f 100644 --- a/src/app/device-model/device-model-table/device-model-table.component.ts +++ b/src/app/device-model/device-model-table/device-model-table.component.ts @@ -1,135 +1,118 @@ -import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { environment } from '@environments/environment'; -import { TranslateService } from '@ngx-translate/core'; -import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dialog.service'; -import { MeService } from '@shared/services/me.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { merge, Observable, of as observableOf, Subscription } from 'rxjs'; -import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { DeviceModelService } from '../device-model.service'; -import { DeviceModel, DeviceModelResponse } from '../device.model'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { AfterViewInit, Component, OnInit, ViewChild } from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; +import { environment } from "@environments/environment"; +import { TranslateService } from "@ngx-translate/core"; +import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service"; +import { MeService } from "@shared/services/me.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { merge, Observable, of as observableOf, Subscription } from "rxjs"; +import { catchError, map, startWith, switchMap } from "rxjs/operators"; +import { DeviceModelService } from "../device-model.service"; +import { DeviceModel, DeviceModelResponse } from "../device.model"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; @Component({ - selector: 'app-device-model-table', - templateUrl: './device-model-table.component.html', - styleUrls: ['./device-model-table.component.scss'], + selector: "app-device-model-table", + templateUrl: "./device-model-table.component.html", + styleUrls: ["./device-model-table.component.scss"], }) export class DeviceModelTableComponent implements OnInit, AfterViewInit { - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - public data: DeviceModel[]; - public displayedColumns: string[] = ['name', 'id', 'menu']; - public pageSize = environment.tablePageSize; - public pageSizeOptions = DefaultPageSizeOptions; - public isLoadingResults = false; - public resultsLength = 0; - deleteDialogSubscription: Subscription; - errorTitle: string; - public canEdit = false; + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + public data: DeviceModel[]; + public displayedColumns: string[] = ["name", "id", "menu"]; + public pageSize = environment.tablePageSize; + public pageSizeOptions = DefaultPageSizeOptions; + public isLoadingResults = false; + public resultsLength = 0; + deleteDialogSubscription: Subscription; + errorTitle: string; + public canEdit = false; - constructor( - private sharedVariableService: SharedVariableService, - private deviceModelService: DeviceModelService, - private deleteDialogservice: DeleteDialogService, - private translateService: TranslateService, - private meService: MeService - ) {} + constructor( + private sharedVariableService: SharedVariableService, + private deviceModelService: DeviceModelService, + private deleteDialogservice: DeleteDialogService, + private translateService: TranslateService, + private meService: MeService + ) {} - ngOnInit(): void { - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.ApplicationWrite - ); - this.translateService - .get(['DEVICE-MODEL.DELETE-FAILED']) - .subscribe((translations) => { - this.errorTitle = translations['DEVICE-MODEL.DELETE-FAILED']; - }); - } + ngOnInit(): void { + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.ApplicationWrite); + this.translateService.get(["DEVICE-MODEL.DELETE-FAILED"]).subscribe(translations => { + this.errorTitle = translations["DEVICE-MODEL.DELETE-FAILED"]; + }); + } - ngAfterViewInit() { - // If the user changes the sort order, reset back to the first page. - this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + ngAfterViewInit() { + // If the user changes the sort order, reset back to the first page. + this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); - merge(this.sort.sortChange, this.paginator.page) - .pipe( - startWith({}), - switchMap(() => { - this.isLoadingResults = true; - return this.getDeviceModels(this.sort.active, this.sort.direction); - }), - map((data) => { - // Flip flag to show that loading has finished. - this.isLoadingResults = false; - this.resultsLength = data.count; - return data.data.sort((a, b) => { - if (a.body.name === undefined || b.body.name === undefined) { - return -1; - } - return a.body.name.localeCompare(b.body.name, 'en', { - numeric: true, - }); - }); - }), - catchError(() => { - this.isLoadingResults = false; - return observableOf([]); - }) - ) - .subscribe((data) => (this.data = data)); - } + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + return this.getDeviceModels(this.sort.active, this.sort.direction); + }), + map(data => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.resultsLength = data.count; + return data.data.sort((a, b) => { + if (a.body.name === undefined || b.body.name === undefined) { + return -1; + } + return a.body.name.localeCompare(b.body.name, "en", { + numeric: true, + }); + }); + }), + catchError(() => { + this.isLoadingResults = false; + return observableOf([]); + }) + ) + .subscribe(data => (this.data = data)); + } - getDeviceModels( - orderByColumn: string, - orderByDirection: string - ): Observable { - return this.deviceModelService.getMultiple( - this.paginator.pageSize, - this.paginator.pageIndex * this.paginator.pageSize, - orderByDirection, - orderByColumn, - this.sharedVariableService.getSelectedOrganisationId() - ); - } + getDeviceModels(orderByColumn: string, orderByDirection: string): Observable { + return this.deviceModelService.getMultiple( + this.paginator.pageSize, + this.paginator.pageIndex * this.paginator.pageSize, + orderByDirection, + orderByColumn, + this.sharedVariableService.getSelectedOrganisationId() + ); + } - public clickDelete(deviceModel) { - this.deleteDialogSubscription = this.deleteDialogservice - .showSimpleDialog() - .subscribe((response) => { - if (response) { - this.deviceModelService - .delete(deviceModel.id) - .subscribe((response) => { - if (response.ok) { - this.paginator.page.emit({ - pageIndex: this.paginator.pageIndex, - pageSize: this.paginator.pageSize, - length: this.resultsLength, + public clickDelete(deviceModel) { + this.deleteDialogSubscription = this.deleteDialogservice.showSimpleDialog().subscribe(response => { + if (response) { + this.deviceModelService.delete(deviceModel.id).subscribe(response => { + if (response.ok) { + this.paginator.page.emit({ + pageIndex: this.paginator.pageIndex, + pageSize: this.paginator.pageSize, + length: this.resultsLength, + }); + } else { + this.deleteDialogSubscription = this.deleteDialogservice + .showSimpleDialog(response.error.message, false, false, true, this.errorTitle) + .subscribe(); + } }); - } else { - this.deleteDialogSubscription = this.deleteDialogservice - .showSimpleDialog( - response.error.message, - false, - false, - true, - this.errorTitle - ) - .subscribe(); - } - }); - } else { - console.log(response); - } - }); - } + } else { + console.log(response); + } + }); + } - ngOnDestroy(): void { - if (this.deleteDialogSubscription) { - this.deleteDialogSubscription.unsubscribe(); + ngOnDestroy(): void { + if (this.deleteDialogSubscription) { + this.deleteDialogSubscription.unsubscribe(); + } } - } } diff --git a/src/app/device-model/device-model.module.ts b/src/app/device-model/device-model.module.ts index bc7c8f11d..89549153c 100644 --- a/src/app/device-model/device-model.module.ts +++ b/src/app/device-model/device-model.module.ts @@ -1,33 +1,34 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { DeviceModelListComponent } from './device-model-list/device-model-list.component'; -import { DeviceModelRoutingModule } from './device-model-routing.module'; -import { DeviceModelTableComponent } from './device-model-table/device-model-table.component'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { TranslateModule } from '@ngx-translate/core'; -import { DeviceModelDetailComponent } from './device-model-detail/device-model-detail.component'; -import { DeviceModelEditComponent } from './device-model-edit/device-model-edit.component'; -import { SharedModule } from '@shared/shared.module'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { FormModule } from '@shared/components/forms/form.module'; -import { PipesModule } from '@shared/pipes/pipes.module'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { DeviceModelListComponent } from "./device-model-list/device-model-list.component"; +import { DeviceModelRoutingModule } from "./device-model-routing.module"; +import { DeviceModelTableComponent } from "./device-model-table/device-model-table.component"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { TranslateModule } from "@ngx-translate/core"; +import { DeviceModelDetailComponent } from "./device-model-detail/device-model-detail.component"; +import { DeviceModelEditComponent } from "./device-model-edit/device-model-edit.component"; +import { SharedModule } from "@shared/shared.module"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { FormModule } from "@shared/components/forms/form.module"; +import { PipesModule } from "@shared/pipes/pipes.module"; @NgModule({ - declarations: [ - DeviceModelListComponent, - DeviceModelTableComponent, - DeviceModelDetailComponent, - DeviceModelEditComponent], - imports: [ - CommonModule, - DeviceModelRoutingModule, - NGMaterialModule, - TranslateModule, - SharedModule, - FormsModule, - FormModule, - ReactiveFormsModule, - PipesModule - ] + declarations: [ + DeviceModelListComponent, + DeviceModelTableComponent, + DeviceModelDetailComponent, + DeviceModelEditComponent, + ], + imports: [ + CommonModule, + DeviceModelRoutingModule, + NGMaterialModule, + TranslateModule, + SharedModule, + FormsModule, + FormModule, + ReactiveFormsModule, + PipesModule, + ], }) -export class DeviceModelModule { } +export class DeviceModelModule {} diff --git a/src/app/device-model/device-model.service.ts b/src/app/device-model/device-model.service.ts index 72aedb3a0..5bb7aa21d 100644 --- a/src/app/device-model/device-model.service.ts +++ b/src/app/device-model/device-model.service.ts @@ -1,132 +1,130 @@ -import { Injectable } from '@angular/core'; -import { UserMinimalService } from '@app/admin/users/user-minimal.service'; -import { GetPayloadDecoderParameters } from '@payload-decoder/payload-decoder.model'; -import { RestService } from '@shared/services/rest.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { buildDriverProvider } from 'protractor/built/driverProviders'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { DeviceModel, DeviceModelBody, DeviceModelRequest, DeviceModelResponse } from './device.model'; +import { Injectable } from "@angular/core"; +import { UserMinimalService } from "@app/admin/users/user-minimal.service"; +import { GetPayloadDecoderParameters } from "@payload-decoder/payload-decoder.model"; +import { RestService } from "@shared/services/rest.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { buildDriverProvider } from "protractor/built/driverProviders"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { DeviceModel, DeviceModelBody, DeviceModelRequest, DeviceModelResponse } from "./device.model"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class DeviceModelService { + private DEVICEMODELURL = "device-model"; - private DEVICEMODELURL = 'device-model'; + constructor( + private restService: RestService, + private sharedVariable: SharedVariableService, + private userMinimalService: UserMinimalService + ) {} - constructor( - private restService: RestService, - private sharedVariable: SharedVariableService, - private userMinimalService: UserMinimalService) { } - - create(deviceModel: DeviceModel): Observable { - this.trimModel(deviceModel.body); - const body = new DeviceModelRequest(deviceModel.body, +this.sharedVariable.getSelectedOrganisationId()); - return this.restService.post(this.DEVICEMODELURL, body, { observe: 'response' }); - } - - update(deviceModel: DeviceModel, id: number): Observable { - this.trimModel(deviceModel.body); - const body = new DeviceModelRequest(deviceModel.body, +this.sharedVariable.getSelectedOrganisationId()); - return this.restService.put(this.DEVICEMODELURL, body, id, { - observe: 'response', - }); - } - - get(id: number): Observable { - return this.restService.get(this.DEVICEMODELURL, {}, id).pipe( - map( - response => - new DeviceModel( - response.id, - new DeviceModelBody( - response.body.id, - response.body.name, - response.body.brandName, - response.body.modelName, - response.body.manufacturerName, - response.body.category, - response.body.energyLimitationClass, - response.body.controlledProperty, - response.body.supportedUnits, - response.body.function, - response.body.supportedProtocol, - - ), - response.createdAt, - response.updatedAt, - response.createdBy, - response.updatedBy, - this.userMinimalService.getUserNameFrom(response.createdBy), - this.userMinimalService.getUserNameFrom(response.updatedBy), - ) - ) - ); - } + create(deviceModel: DeviceModel): Observable { + this.trimModel(deviceModel.body); + const body = new DeviceModelRequest(deviceModel.body, +this.sharedVariable.getSelectedOrganisationId()); + return this.restService.post(this.DEVICEMODELURL, body, { observe: "response" }); + } - getMultiple( - limit: number, - offset: number, - sort: string, - orderOn: string, - organizationId?: number - ): Observable { - const body: GetPayloadDecoderParameters = { - limit: limit, - offset: offset, - sort: sort, - orderOn: orderOn, - organizationId: undefined, - }; - if (organizationId) { - body.organizationId = organizationId; + update(deviceModel: DeviceModel, id: number): Observable { + this.trimModel(deviceModel.body); + const body = new DeviceModelRequest(deviceModel.body, +this.sharedVariable.getSelectedOrganisationId()); + return this.restService.put(this.DEVICEMODELURL, body, id, { + observe: "response", + }); } - return this.restService - .get(this.DEVICEMODELURL, body) - .pipe( - map((response) => { - return { - data: response.data.map( - (item: any) => - new DeviceModel( - item.id, - new DeviceModelBody( - item.body.id, - item.body.name, - item.body.brandName, - item.body.modelName, - item.body.manufacturerName, - item.body.category, - item.body.energyLimitationClass, - item.body.controlledProperty, - item.body.supportedUnits, - item.body.function, - item.body.supportedProtocol - ) + + get(id: number): Observable { + return this.restService + .get(this.DEVICEMODELURL, {}, id) + .pipe( + map( + response => + new DeviceModel( + response.id, + new DeviceModelBody( + response.body.id, + response.body.name, + response.body.brandName, + response.body.modelName, + response.body.manufacturerName, + response.body.category, + response.body.energyLimitationClass, + response.body.controlledProperty, + response.body.supportedUnits, + response.body.function, + response.body.supportedProtocol + ), + response.createdAt, + response.updatedAt, + response.createdBy, + response.updatedBy, + this.userMinimalService.getUserNameFrom(response.createdBy), + this.userMinimalService.getUserNameFrom(response.updatedBy) + ) ) - ), - count: response.count, - }; - }) - ); - }; - + ); + } - delete(id: number) { - return this.restService.delete(this.DEVICEMODELURL, id); - } + getMultiple( + limit: number, + offset: number, + sort: string, + orderOn: string, + organizationId?: number + ): Observable { + const body: GetPayloadDecoderParameters = { + limit: limit, + offset: offset, + sort: sort, + orderOn: orderOn, + organizationId: undefined, + }; + if (organizationId) { + body.organizationId = organizationId; + } + return this.restService.get(this.DEVICEMODELURL, body).pipe( + map(response => { + return { + data: response.data.map( + (item: any) => + new DeviceModel( + item.id, + new DeviceModelBody( + item.body.id, + item.body.name, + item.body.brandName, + item.body.modelName, + item.body.manufacturerName, + item.body.category, + item.body.energyLimitationClass, + item.body.controlledProperty, + item.body.supportedUnits, + item.body.function, + item.body.supportedProtocol + ) + ) + ), + count: response.count, + }; + }) + ); + } - private trimModel(deviceModel: DeviceModelBody) { - deviceModel.id = deviceModel.id ? deviceModel.id : undefined; - deviceModel.brandName = deviceModel.brandName ? deviceModel.brandName : undefined; - deviceModel.modelName = deviceModel.modelName ? deviceModel.modelName : undefined; - deviceModel.manufacturerName = deviceModel.manufacturerName ? deviceModel.manufacturerName : undefined; - if (!deviceModel.controlledProperty || deviceModel.controlledProperty.length === 0) { - deviceModel.controlledProperty = undefined; + delete(id: number) { + return this.restService.delete(this.DEVICEMODELURL, id); } - if (!deviceModel.category || deviceModel.category.length === 0) { - deviceModel.category = undefined; + + private trimModel(deviceModel: DeviceModelBody) { + deviceModel.id = deviceModel.id ? deviceModel.id : undefined; + deviceModel.brandName = deviceModel.brandName ? deviceModel.brandName : undefined; + deviceModel.modelName = deviceModel.modelName ? deviceModel.modelName : undefined; + deviceModel.manufacturerName = deviceModel.manufacturerName ? deviceModel.manufacturerName : undefined; + if (!deviceModel.controlledProperty || deviceModel.controlledProperty.length === 0) { + deviceModel.controlledProperty = undefined; + } + if (!deviceModel.category || deviceModel.category.length === 0) { + deviceModel.category = undefined; + } } - } } diff --git a/src/app/device-model/device.model.ts b/src/app/device-model/device.model.ts index 8e009364c..4a48f1ab8 100644 --- a/src/app/device-model/device.model.ts +++ b/src/app/device-model/device.model.ts @@ -1,8 +1,7 @@ - export class DeviceModelBody { id?: string; name?: string; - private type = 'DeviceModel'; + private type = "DeviceModel"; brandName?: string; modelName?: string; manufacturerName?: string; @@ -13,7 +12,6 @@ export class DeviceModelBody { function?: string[]; supportedProtocol?: string[]; - constructor( id?: string, name?: string, @@ -25,11 +23,11 @@ export class DeviceModelBody { controlledProperty?: string[], supportedUnits?: string[], sensorFunction?: string[], - supportedProtocol?: string[], + supportedProtocol?: string[] ) { this.id = id; this.name = name; - this.type = 'DeviceModel'; + this.type = "DeviceModel"; this.brandName = brandName; this.modelName = modelName; this.manufacturerName = manufacturerName; @@ -39,7 +37,6 @@ export class DeviceModelBody { this.supportedUnits = supportedUnits; this.function = sensorFunction; this.supportedProtocol = supportedProtocol; - } } @@ -58,14 +55,16 @@ export class DeviceModel { createdByName: string; updatedByName: string; - constructor(id?: number, + constructor( + id?: number, body: DeviceModelBody = new DeviceModelBody(), createdAt?: string, updatedAt?: string, createdBy?: number, updatedBy?: number, createdByName?: string, - updatedByName?: string) { + updatedByName?: string + ) { this.id = id; this.body = body; this.createdAt = createdAt; diff --git a/src/app/device-model/supported-unit.model.ts b/src/app/device-model/supported-unit.model.ts index d1464e97b..292424a2e 100644 --- a/src/app/device-model/supported-unit.model.ts +++ b/src/app/device-model/supported-unit.model.ts @@ -2,79 +2,79 @@ export class SupportedUnit { units: Unit[]; constructor() { - this. units = [ - { code: '28', name: 'kg/m²'}, - { code: '2N', name: 'dB'}, - { code: '4H', name: 'µm'}, - { code: '4K', name: 'mA'}, - { code: '4P', name: 'N/m'}, - { code: 'A24', name: 'cd/m²'}, - { code: 'A86', name: 'GHz'}, - { code: 'A94', name: 'g/mol'}, - { code: 'B22', name: 'kA'}, - { code: 'B32', name: 'kg • m2'}, - { code: 'B43', name: 'kJ/(kg.K)'}, - { code: 'B49', name: 'kΩ'}, - { code: 'B61', name: 'lm/W'}, - { code: 'BAR', name: 'bar'}, - { code: 'C16', name: 'mm/s'}, - { code: 'C24', name: 'mPa.s'}, - { code: 'C26', name: 'ms'}, - { code: 'C45', name: 'nm'}, - { code: 'C62', name: '1'}, - { code: 'C65', name: 'Pa.s'}, - { code: 'C91', name: '1/K'}, - { code: 'C94', name: 'min-1'}, - { code: 'CDL', name: 'cd'}, - { code: 'CEL', name: '°C'}, - { code: 'CMQ', name: 'cm³'}, - { code: 'CMT', name: 'cm'}, - { code: 'D33', name: 'T'}, - { code: 'D52', name: 'W/K'}, - { code: 'D74', name: 'kg/mol'}, - { code: 'DAY', name: 'd'}, - { code: 'DD', name: '°'}, - { code: 'E01', name: 'N/cm²'}, - { code: 'E32', name: 'l/h'}, - { code: 'FAR', name: 'F'}, - { code: 'GM', name: 'g/m²'}, - { code: 'GRM', name: 'g'}, - { code: 'HTZ', name: 'Hz'}, - { code: 'HUR', name: 'h'}, - { code: 'KEL', name: 'K'}, - { code: 'KGM', name: 'kg'}, - { code: 'KGS', name: 'kg/s'}, - { code: 'KHZ', name: 'kHz'}, - { code: 'KL', name: 'kg/m'}, - { code: 'KMQ', name: 'kg/m³'}, - { code: 'KVT', name: 'kV'}, - { code: 'KWT', name: 'kW'}, - { code: 'L2', name: 'l/min'}, - { code: 'LTR', name: 'l'}, - { code: 'LUM', name: 'lm'}, - { code: 'LUX', name: 'lx'}, - { code: 'MBR', name: 'mbar'}, - { code: 'MHZ', name: 'MHz'}, - { code: 'MIN', name: 'min'}, - { code: 'MMK', name: 'mm²'}, - { code: 'MMQ', name: 'mm³'}, - { code: 'MMT', name: 'mm'}, - { code: 'MPA', name: 'MPa'}, - { code: 'MQH', name: 'm3/h'}, - { code: 'MQS', name: 'm³/s'}, - { code: 'MTK', name: 'm²'}, - { code: 'MTQ', name: 'm³'}, - { code: 'MTR', name: 'm'}, - { code: 'MTS', name: 'm/s'}, - { code: 'NEW', name: 'N'}, - { code: 'NU', name: 'N • m'}, - { code: 'NUDOT', name: 'N.m'}, - { code: 'OHM', name: 'Ω'}, - { code: 'P1', name: '%'}, - { code: 'PAL', name: 'Pa'}, - { code: 'SEC', name: 's'}, - { code: 'VLT', name: 'V'}, - { code: 'WTT', name: 'W '} + this.units = [ + { code: "28", name: "kg/m²" }, + { code: "2N", name: "dB" }, + { code: "4H", name: "µm" }, + { code: "4K", name: "mA" }, + { code: "4P", name: "N/m" }, + { code: "A24", name: "cd/m²" }, + { code: "A86", name: "GHz" }, + { code: "A94", name: "g/mol" }, + { code: "B22", name: "kA" }, + { code: "B32", name: "kg • m2" }, + { code: "B43", name: "kJ/(kg.K)" }, + { code: "B49", name: "kΩ" }, + { code: "B61", name: "lm/W" }, + { code: "BAR", name: "bar" }, + { code: "C16", name: "mm/s" }, + { code: "C24", name: "mPa.s" }, + { code: "C26", name: "ms" }, + { code: "C45", name: "nm" }, + { code: "C62", name: "1" }, + { code: "C65", name: "Pa.s" }, + { code: "C91", name: "1/K" }, + { code: "C94", name: "min-1" }, + { code: "CDL", name: "cd" }, + { code: "CEL", name: "°C" }, + { code: "CMQ", name: "cm³" }, + { code: "CMT", name: "cm" }, + { code: "D33", name: "T" }, + { code: "D52", name: "W/K" }, + { code: "D74", name: "kg/mol" }, + { code: "DAY", name: "d" }, + { code: "DD", name: "°" }, + { code: "E01", name: "N/cm²" }, + { code: "E32", name: "l/h" }, + { code: "FAR", name: "F" }, + { code: "GM", name: "g/m²" }, + { code: "GRM", name: "g" }, + { code: "HTZ", name: "Hz" }, + { code: "HUR", name: "h" }, + { code: "KEL", name: "K" }, + { code: "KGM", name: "kg" }, + { code: "KGS", name: "kg/s" }, + { code: "KHZ", name: "kHz" }, + { code: "KL", name: "kg/m" }, + { code: "KMQ", name: "kg/m³" }, + { code: "KVT", name: "kV" }, + { code: "KWT", name: "kW" }, + { code: "L2", name: "l/min" }, + { code: "LTR", name: "l" }, + { code: "LUM", name: "lm" }, + { code: "LUX", name: "lx" }, + { code: "MBR", name: "mbar" }, + { code: "MHZ", name: "MHz" }, + { code: "MIN", name: "min" }, + { code: "MMK", name: "mm²" }, + { code: "MMQ", name: "mm³" }, + { code: "MMT", name: "mm" }, + { code: "MPA", name: "MPa" }, + { code: "MQH", name: "m3/h" }, + { code: "MQS", name: "m³/s" }, + { code: "MTK", name: "m²" }, + { code: "MTQ", name: "m³" }, + { code: "MTR", name: "m" }, + { code: "MTS", name: "m/s" }, + { code: "NEW", name: "N" }, + { code: "NU", name: "N • m" }, + { code: "NUDOT", name: "N.m" }, + { code: "OHM", name: "Ω" }, + { code: "P1", name: "%" }, + { code: "PAL", name: "Pa" }, + { code: "SEC", name: "s" }, + { code: "VLT", name: "V" }, + { code: "WTT", name: "W " }, ]; } } diff --git a/src/app/error-page/error-page.component.html b/src/app/error-page/error-page.component.html index 7dd51905e..dbbf74c7a 100644 --- a/src/app/error-page/error-page.component.html +++ b/src/app/error-page/error-page.component.html @@ -6,18 +6,18 @@

- {{errorMessage.code | translate}} + {{ errorMessage.code | translate }} - {{errorMessage.message | translate}} + {{ errorMessage.message | translate }}

- +
-
\ No newline at end of file +
diff --git a/src/app/error-page/error-page.component.scss b/src/app/error-page/error-page.component.scss index 85c344dc9..2d8a54c53 100644 --- a/src/app/error-page/error-page.component.scss +++ b/src/app/error-page/error-page.component.scss @@ -1,57 +1,55 @@ -@import 'src/assets/scss/setup/breakpoints'; -@import 'src/assets/scss/setup/variables'; +@import "src/assets/scss/setup/breakpoints"; +@import "src/assets/scss/setup/variables"; .error-page { - height: 85vh; - background-color: $color-primary; - background-size: cover; - background-position: top; - position: relative; - - &__text-box { - position: absolute; - top: 40%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - width: 100%; - .error-page-primary { - color: $color-white-001; - text-transform: uppercase; - - backface-visibility: hidden; - margin-bottom: 6rem; - - &--main { - display: block; - font-size: 6rem; - font-weight: 400; - line-height: 6rem; - margin-bottom: 3rem; - } - - &--sub { - display: block; - font-size: 2rem; - font-weight: 700; + height: 85vh; + background-color: $color-primary; + background-size: cover; + background-position: top; + position: relative; + + &__text-box { + position: absolute; + top: 40%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + width: 100%; + .error-page-primary { + color: $color-white-001; + text-transform: uppercase; + + backface-visibility: hidden; + margin-bottom: 6rem; + + &--main { + display: block; + font-size: 6rem; + font-weight: 400; + line-height: 6rem; + margin-bottom: 3rem; + } + + &--sub { + display: block; + font-size: 2rem; + font-weight: 700; + } } } - } - &__logo-box { - position: absolute; - bottom: 5vh; - right: 5rem; - } - - &__logo { - height: 3.5rem; - } - - @supports (clip-path: polygon(0 0)) or (-webkit-clip-path: polygon(0 0)) { - -webkit-clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%); - clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%); - height: 90vh; - } + &__logo-box { + position: absolute; + bottom: 5vh; + right: 5rem; + } + &__logo { + height: 3.5rem; + } + @supports (clip-path: polygon(0 0)) or (-webkit-clip-path: polygon(0 0)) { + -webkit-clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%); + clip-path: polygon(0 0, 100% 0, 100% 75vh, 0 100%); + height: 90vh; + } } diff --git a/src/app/error-page/error-page.component.ts b/src/app/error-page/error-page.component.ts index d00cdf4f3..eb7038ffe 100644 --- a/src/app/error-page/error-page.component.ts +++ b/src/app/error-page/error-page.component.ts @@ -1,28 +1,26 @@ -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Data, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { ErrorPageMessage } from '@shared/models/error-message.model'; +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute, Data, Router } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { ErrorPageMessage } from "@shared/models/error-message.model"; @Component({ - selector: 'app-error-page', - templateUrl: './error-page.component.html', - styleUrls: ['./error-page.component.scss'] + selector: "app-error-page", + templateUrl: "./error-page.component.html", + styleUrls: ["./error-page.component.scss"], }) export class ErrorPageComponent implements OnInit { - errorMessage: any; + errorMessage: any; - constructor() { - } + constructor() {} - ngOnInit() { - if (history.state.code === 401) { - this.errorMessage = history.state; - } else { - this.errorMessage = { - message: 'Page not found', - code: 404 - } + ngOnInit() { + if (history.state.code === 401) { + this.errorMessage = history.state; + } else { + this.errorMessage = { + message: "Page not found", + code: 404, + }; + } } - } } - diff --git a/src/app/gateway/gateway-detail/gateway-detail.component.html b/src/app/gateway/gateway-detail/gateway-detail.component.html index f0a57a574..5f6b08813 100644 --- a/src/app/gateway/gateway-detail/gateway-detail.component.html +++ b/src/app/gateway/gateway-detail/gateway-detail.component.html @@ -1,115 +1,181 @@
- -
-
-
-
-

{{ 'GATEWAY.DETAILS' | translate }}

-

{{ 'GATEWAY.ID' | translate }}{{gateway.gatewayId}}

-

{{ 'GATEWAY.ORGANIZATION' | translate }}{{gateway.organizationName}}

- -

{{ 'GATEWAY.TAGS' | translate }}{{gateway.tagsString}}

-

{{ 'LORA-GATEWAY-TABLE.PLACEMENT' | translate }}{{'GATEWAY.PLACEMENT.' + gateway.placement | translate}}

-

{{ 'LORA-GATEWAY-TABLE.MODEL-NAME' | translate }}{{gateway.modelName}}

-

{{ 'LORA-GATEWAY-TABLE.ANTENNA-TYPE' | translate }}{{gateway.antennaType}}

-

{{ 'LORA-GATEWAY-TABLE.STATUS' | translate }}{{'GATEWAY.STATUS.' + gateway.status | translate}}

-

{{ 'LORA-GATEWAY-TABLE.RESPONSIBLE-NAME' | translate }}{{gateway.gatewayResponsibleName}}

-

{{ 'LORA-GATEWAY-TABLE.RESPONSIBLE-EMAIL' | translate }}{{gateway.gatewayResponsibleEmail}}

-

{{ 'LORA-GATEWAY-TABLE.RESPONSIBLE-PHONE-NUMBER' | translate }}{{gateway.gatewayResponsiblePhoneNumber}}

-

{{ 'LORA-GATEWAY-TABLE.OPERATIONAL-NAME' | translate }}{{gateway.operationalResponsibleName}}

-

{{ 'LORA-GATEWAY-TABLE.OPERATIONAL-EMAIL' | translate }}{{gateway.operationalResponsibleEmail}}

-

- {{ 'GATEWAY.DESCRIPTION' | translate }} -

-

{{gateway.description}}

-
-
-
-
-
-

{{ 'GATEWAY.LOCATION' | translate }}

-
- + +
+
+
+
+

{{ "GATEWAY.DETAILS" | translate }}

+

+ {{ "GATEWAY.ID" | translate }}{{ gateway.gatewayId }} +

+

+ {{ "GATEWAY.ORGANIZATION" | translate }}{{ gateway.organizationName }} +

+ +

+ {{ "GATEWAY.TAGS" | translate }}{{ gateway.tagsString }} +

+

+ {{ "LORA-GATEWAY-TABLE.PLACEMENT" | translate }}{{ "GATEWAY.PLACEMENT." + gateway.placement | translate }} +

+

+ {{ "LORA-GATEWAY-TABLE.MODEL-NAME" | translate }}{{ gateway.modelName }} +

+

+ {{ "LORA-GATEWAY-TABLE.ANTENNA-TYPE" | translate }}{{ gateway.antennaType }} +

+

+ {{ "LORA-GATEWAY-TABLE.STATUS" | translate }}{{ "GATEWAY.STATUS." + gateway.status | translate }} +

+

+ {{ "LORA-GATEWAY-TABLE.RESPONSIBLE-NAME" | translate }}{{ gateway.gatewayResponsibleName }} +

+

+ {{ "LORA-GATEWAY-TABLE.RESPONSIBLE-EMAIL" | translate }}{{ gateway.gatewayResponsibleEmail }} +

+

+ {{ "LORA-GATEWAY-TABLE.RESPONSIBLE-PHONE-NUMBER" | translate }}{{ gateway.gatewayResponsiblePhoneNumber }} +

+

+ {{ "LORA-GATEWAY-TABLE.OPERATIONAL-NAME" | translate }}{{ gateway.operationalResponsibleName }} +

+

+ {{ "LORA-GATEWAY-TABLE.OPERATIONAL-EMAIL" | translate }}{{ gateway.operationalResponsibleEmail }} +

+

+ {{ "GATEWAY.DESCRIPTION" | translate }} +

+

{{gateway.description}}

+
-
-
-

{{ 'GATEWAY.LATITUDE' | translate }} - {{gateway.location.latitude | number:'2.1-9'}}

-
-
-

{{ 'GATEWAY.LONGITUDE' | translate }} - {{gateway.location?.longitude | number:'2.1-9'}}

-
-
-

{{ 'GATEWAY.ALTITUDE' | translate }} - {{gateway.location.altitude | number:'2.1-9'}}

-
+
+
+
+

{{ "GATEWAY.LOCATION" | translate }}

+
+ +
+
+
+

+ {{ "GATEWAY.LATITUDE" | translate }} + {{ gateway.location.latitude | number : "2.1-9" }} +

+
+
+

+ {{ "GATEWAY.LONGITUDE" | translate }} + {{ gateway.location?.longitude | number : "2.1-9" }} +

+
+
+

+ {{ "GATEWAY.ALTITUDE" | translate }} + {{ gateway.location.altitude | number : "2.1-9" }} +

+
+
+
+ +

{{ "GATEWAY.NOLOCATION" | translate }}

+
+
-
- -

{{ 'GATEWAY.NOLOCATION' | translate}}

-
-
-
-
-
-
- - -
+
+
+
+ + +
-
-

{{ 'GATEWAY.DATA-PACKETS' | translate }}

-
- -
+
+

{{ "GATEWAY.DATA-PACKETS" | translate }}

+
+ +
-
-
- - -
-
- - -
-
+
+
+ + +
+
+ + +
+
- - - - - +
- {{ 'GATEWAY.STATS-RXPACKETSRECEIVED' | translate }} - {{element.rxPacketsReceived}}
+ + + + - - - - + + + + - - - - + + + + - - -
+ {{ "GATEWAY.STATS-RXPACKETSRECEIVED" | translate }} + {{ element.rxPacketsReceived }}{{ 'GATEWAY.STATS-TXPACKETSEMITTED' | translate }} - {{element.txPacketsEmitted}}{{ "GATEWAY.STATS-TXPACKETSEMITTED" | translate }}{{ element.txPacketsEmitted }}{{ 'GATEWAY.STATS-TIMESTAMP' | translate }}{{element.timestamp | date}}{{ "GATEWAY.STATS-TIMESTAMP" | translate }}{{ element.timestamp | date }}
- - -
+ + + + + +
+
-
diff --git a/src/app/gateway/gateway-detail/gateway-detail.component.scss b/src/app/gateway/gateway-detail/gateway-detail.component.scss index 1922e7ffa..bdadd8bb1 100644 --- a/src/app/gateway/gateway-detail/gateway-detail.component.scss +++ b/src/app/gateway/gateway-detail/gateway-detail.component.scss @@ -1,3 +1,3 @@ table { - width: 100%; + width: 100%; } diff --git a/src/app/gateway/gateway-overview/gateway-overview.component.html b/src/app/gateway/gateway-overview/gateway-overview.component.html index a9dd6ed59..4fc0ee8a8 100644 --- a/src/app/gateway/gateway-overview/gateway-overview.component.html +++ b/src/app/gateway/gateway-overview/gateway-overview.component.html @@ -1,21 +1,33 @@ - + diff --git a/src/app/gateway/gateway-overview/gateway-overview.component.scss b/src/app/gateway/gateway-overview/gateway-overview.component.scss index efcb18989..e8eb0dc15 100644 --- a/src/app/gateway/gateway-overview/gateway-overview.component.scss +++ b/src/app/gateway/gateway-overview/gateway-overview.component.scss @@ -1,6 +1,6 @@ -.select-all{ - margin-left: 17px; - font-size: inherit; - line-height: 3em; - height: 3em; +.select-all { + margin-left: 17px; + font-size: inherit; + line-height: 3em; + height: 3em; } diff --git a/src/app/gateway/gateway-overview/gateway-overview.component.ts b/src/app/gateway/gateway-overview/gateway-overview.component.ts index c91c1468e..5969cef9e 100644 --- a/src/app/gateway/gateway-overview/gateway-overview.component.ts +++ b/src/app/gateway/gateway-overview/gateway-overview.component.ts @@ -1,94 +1,90 @@ -import { Component, OnChanges, OnDestroy, OnInit } from '@angular/core'; -import { Organisation } from '@app/admin/organisation/organisation.model'; -import { TranslateService } from '@ngx-translate/core'; -import moment from 'moment'; -import { Subscription } from 'rxjs'; -import { MeService } from '@shared/services/me.service'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { environment } from '@environments/environment'; -import { Title } from '@angular/platform-browser'; -import { OrganizationAccessScope } from '@shared/enums/access-scopes'; -import { GatewayService } from '@app/gateway/gateway.service'; -import { NavigationEnd, Router } from '@angular/router'; +import { Component, OnChanges, OnDestroy, OnInit } from "@angular/core"; +import { Organisation } from "@app/admin/organisation/organisation.model"; +import { TranslateService } from "@ngx-translate/core"; +import moment from "moment"; +import { Subscription } from "rxjs"; +import { MeService } from "@shared/services/me.service"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { environment } from "@environments/environment"; +import { Title } from "@angular/platform-browser"; +import { OrganizationAccessScope } from "@shared/enums/access-scopes"; +import { GatewayService } from "@app/gateway/gateway.service"; +import { NavigationEnd, Router } from "@angular/router"; @Component({ - selector: 'app-gateway-list', - templateUrl: './gateway-overview.component.html', - styleUrls: ['./gateway-overview.component.scss'], + selector: "app-gateway-list", + templateUrl: "./gateway-overview.component.html", + styleUrls: ["./gateway-overview.component.scss"], }) export class GatewayOverviewComponent implements OnInit, OnChanges, OnDestroy { - public navTabs: any[] = [ - { - label: 'GATEWAY.TABEL-TAB', - link: './list', - index: 0, - }, - { - label: 'GATEWAY.MAP-TAB', - link: './map', - index: 1, - }, - { - label: 'LORA-GATEWAY-TABLE.STATUS', - link: './status', - index: 2, - }, - ]; - public pageLimit = environment.tablePageSize; - private gatewaySubscription: Subscription; + public navTabs: any[] = [ + { + label: "GATEWAY.TABEL-TAB", + link: "./list", + index: 0, + }, + { + label: "GATEWAY.MAP-TAB", + link: "./map", + index: 1, + }, + { + label: "LORA-GATEWAY-TABLE.STATUS", + link: "./status", + index: 2, + }, + ]; + public pageLimit = environment.tablePageSize; + private gatewaySubscription: Subscription; - organisations: Organisation[]; + organisations: Organisation[]; - private deleteDialogSubscription: Subscription; - private routerSubscription: Subscription; - canEdit: boolean; + private deleteDialogSubscription: Subscription; + private routerSubscription: Subscription; + canEdit: boolean; - constructor( - public translate: TranslateService, - private meService: MeService, - private titleService: Title, - private sharedVariableService: SharedVariableService, - public gatewayService: GatewayService, - private router: Router - ) { - translate.use('da'); - moment.locale('da'); - } + constructor( + public translate: TranslateService, + private meService: MeService, + private titleService: Title, + private sharedVariableService: SharedVariableService, + public gatewayService: GatewayService, + private router: Router + ) { + translate.use("da"); + moment.locale("da"); + } - ngOnInit(): void { - this.organisations = this.sharedVariableService.getOrganizationInfo(); - this.organisations.sort((a, b) => - a.name.localeCompare(b.name, 'en', { numeric: true }) - ); - this.translate.get(['TITLE.LORAWAN-GATEWAY']).subscribe((translations) => { - this.titleService.setTitle(translations['TITLE.LORAWAN-GATEWAY']); - }); - this.canEdit = this.meService.hasAccessToTargetOrganization( - OrganizationAccessScope.GatewayWrite - ); - if (this.router.url === '/gateways') { - this.router.navigateByUrl('/gateways/list', { replaceUrl: true }); + ngOnInit(): void { + this.organisations = this.sharedVariableService.getOrganizationInfo(); + this.organisations.sort((a, b) => a.name.localeCompare(b.name, "en", { numeric: true })); + this.translate.get(["TITLE.LORAWAN-GATEWAY"]).subscribe(translations => { + this.titleService.setTitle(translations["TITLE.LORAWAN-GATEWAY"]); + }); + this.canEdit = this.meService.hasAccessToTargetOrganization(OrganizationAccessScope.GatewayWrite); + if (this.router.url === "/gateways") { + this.router.navigateByUrl("/gateways/list", { replaceUrl: true }); + } + // Subscribe to route change to root and route to list view + this.routerSubscription = this.router.events.subscribe(e => { + if (e instanceof NavigationEnd && e.url === "/gateways") { + this.router.navigateByUrl("/gateways/list", { replaceUrl: true }); + } + }); } - // Subscribe to route change to root and route to list view - this.routerSubscription = this.router.events.subscribe((e) => { - if (e instanceof NavigationEnd && e.url === '/gateways') { - this.router.navigateByUrl('/gateways/list', { replaceUrl: true }); - } - }); - } - ngOnChanges() {} + ngOnChanges() {} - setOrgIdFilter(orgId: number) { - this.gatewayService.selectedOrg = orgId; - this.gatewayService.organisationChangeSubject.next(orgId); - this.gatewayService.isGatewayStatusVisibleSubject.next(); - } + setOrgIdFilter(orgId: number) { + this.gatewayService.selectedOrg = orgId; + this.gatewayService.organisationChangeSubject.next(orgId); + this.gatewayService.isGatewayStatusVisibleSubject.next(); + } - ngOnDestroy() { - // prevent memory leak by unsubscribing - this.gatewaySubscription?.unsubscribe(); - this.deleteDialogSubscription?.unsubscribe(); - this.routerSubscription?.unsubscribe(); - } + ngOnDestroy() { + // prevent memory leak by unsubscribing + this.gatewaySubscription?.unsubscribe(); + this.deleteDialogSubscription?.unsubscribe(); + this.routerSubscription?.unsubscribe(); + } } diff --git a/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.html b/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.html index 879f78ff1..185a0a4c0 100644 --- a/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.html +++ b/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.html @@ -1,4 +1,3 @@
- - +
diff --git a/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.ts b/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.ts index 7867e6cd7..8522b9f4e 100644 --- a/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.ts +++ b/src/app/gateway/gateway-overview/gateway-tabs/gateway-list/gateway-list.component.ts @@ -1,17 +1,15 @@ -import { AfterViewInit, Component } from '@angular/core'; -import { GatewayService } from '@app/gateway/gateway.service'; +import { AfterViewInit, Component } from "@angular/core"; +import { GatewayService } from "@app/gateway/gateway.service"; @Component({ - selector: 'app-gateway-list', - templateUrl: './gateway-list.component.html', - styleUrls: ['./gateway-list.component.scss'], + selector: "app-gateway-list", + templateUrl: "./gateway-list.component.html", + styleUrls: ["./gateway-list.component.scss"], }) export class GatewayListComponent implements AfterViewInit { - constructor(public gatewayService: GatewayService) {} + constructor(public gatewayService: GatewayService) {} - ngAfterViewInit(): void { - this.gatewayService.organisationChangeSubject.next( - this.gatewayService.selectedOrg - ); - } + ngAfterViewInit(): void { + this.gatewayService.organisationChangeSubject.next(this.gatewayService.selectedOrg); + } } diff --git a/src/app/gateway/gateway-overview/gateway-tabs/gateway-map/gateway-map.component.html b/src/app/gateway/gateway-overview/gateway-tabs/gateway-map/gateway-map.component.html index a9ad787c7..3e31f8253 100644 --- a/src/app/gateway/gateway-overview/gateway-tabs/gateway-map/gateway-map.component.html +++ b/src/app/gateway/gateway-overview/gateway-tabs/gateway-map/gateway-map.component.html @@ -1,4 +1,3 @@
- - +
diff --git a/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.html b/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.html index b4e786a10..3447a7a33 100644 --- a/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.html +++ b/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.html @@ -1,4 +1,6 @@
- +
diff --git a/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.ts b/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.ts index 7c61bedd4..5b9f8a397 100644 --- a/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.ts +++ b/src/app/gateway/gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component.ts @@ -1,23 +1,16 @@ -import { - AfterContentInit, - AfterViewChecked, - AfterViewInit, - Component, -} from '@angular/core'; -import { GatewayService } from '@app/gateway/gateway.service'; +import { AfterContentInit, AfterViewChecked, AfterViewInit, Component } from "@angular/core"; +import { GatewayService } from "@app/gateway/gateway.service"; @Component({ - selector: 'app-gateway-status-overview', - templateUrl: './gateway-status-overview.component.html', - styleUrls: ['./gateway-status-overview.component.scss'], + selector: "app-gateway-status-overview", + templateUrl: "./gateway-status-overview.component.html", + styleUrls: ["./gateway-status-overview.component.scss"], }) export class GatewayStatusOverviewComponent implements AfterViewInit { - constructor(public gatewayService: GatewayService) {} + constructor(public gatewayService: GatewayService) {} - ngAfterViewInit(): void { - this.gatewayService.organisationChangeSubject.next( - this.gatewayService.selectedOrg - ); - this.gatewayService.isGatewayStatusVisibleSubject.next(); - } + ngAfterViewInit(): void { + this.gatewayService.organisationChangeSubject.next(this.gatewayService.selectedOrg); + this.gatewayService.isGatewayStatusVisibleSubject.next(); + } } diff --git a/src/app/gateway/gateway-status/gateway-status.component.html b/src/app/gateway/gateway-status/gateway-status.component.html index b050143a4..b0d8e6bbb 100644 --- a/src/app/gateway/gateway-status/gateway-status.component.html +++ b/src/app/gateway/gateway-status/gateway-status.component.html @@ -1,70 +1,101 @@ - -

{{ 'GEN.NO-DATA' | translate }}

-
+ +

{{ "GEN.NO-DATA" | translate }}

+
-

{{title}}

- - - {{ 'LORA-GATEWAY-STATUS.INTERVAL.' + interval | translate }} - - +

{{ title }}

+ + + {{ "LORA-GATEWAY-STATUS.INTERVAL." + interval | translate }} + +
-
- -
- - - - - - +
+ +
+
- {{element.name}} - {{element.name}} - - {{'GEN.DATE' | translate}} -
- {{'LORA-GATEWAY-STATUS.TIMESTAMP' | translate}} -
+ + + + + - - - - - + + + + + - - - -
+ {{ element.name }} + {{ element.name }} + + {{ "GEN.DATE" | translate }} +
+ {{ "LORA-GATEWAY-STATUS.TIMESTAMP" | translate }} +
- {{time.datePart}} -
- {{time.timePart}} -
+ {{ time.datePart }} +
+ {{ time.timePart }} +
+ + + +
- +
-
-
- {{ "GEN.ONLINE" | translate}} -
-
-
- {{ "GEN.OFFLINE" | translate}} -
-
-
- {{ "GEN.NEVER-SEEN" | translate}} -
+
+
+ {{ "GEN.ONLINE" | translate }} +
+
+
+ {{ "GEN.OFFLINE" | translate }} +
+
+
+ {{ "GEN.NEVER-SEEN" | translate }} +
diff --git a/src/app/gateway/gateway-status/gateway-status.component.scss b/src/app/gateway/gateway-status/gateway-status.component.scss index a0594995e..d1c7d0a54 100644 --- a/src/app/gateway/gateway-status/gateway-status.component.scss +++ b/src/app/gateway/gateway-status/gateway-status.component.scss @@ -1,4 +1,4 @@ -@import 'src/assets/scss/setup/variables'; +@import "src/assets/scss/setup/variables"; $online: #56b257; $offline: #e74c3c; @@ -6,100 +6,100 @@ $neverSeen: #acacac; $cellFontSize: 0.9rem; .status-table { - border-collapse: separate; - border-spacing: 10px 4px; - - .online { - background-color: $online; - } - .offline { - background-color: $offline; - } - .never-seen { - background-color: $neverSeen; - } - - tr { - &:hover { - background-color: unset; - } - - > td { - font-size: $cellFontSize; - &:hover { - transition: $transition-short; - filter: brightness(0.65); - } - - &.mat-cell { - min-width: 1.2rem; - - &:not(:first-child) { - max-width: 1.2rem; - border-radius: 3px; - } + border-collapse: separate; + border-spacing: 10px 4px; - &:first-child { - padding-left: 0; - min-width: 5rem; - } - - &:last-child { - max-width: 1.2rem; - padding-right: 0; - } - } + .online { + background-color: $online; + } + .offline { + background-color: $offline; + } + .never-seen { + background-color: $neverSeen; + } - &.mat-footer-cell { - &:first-child { - padding-left: 0; + tr { + &:hover { + background-color: unset; } - &:last-child { - padding-right: 0; + > td { + font-size: $cellFontSize; + &:hover { + transition: $transition-short; + filter: brightness(0.65); + } + + &.mat-cell { + min-width: 1.2rem; + + &:not(:first-child) { + max-width: 1.2rem; + border-radius: 3px; + } + + &:first-child { + padding-left: 0; + min-width: 5rem; + } + + &:last-child { + max-width: 1.2rem; + padding-right: 0; + } + } + + &.mat-footer-cell { + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } } - } } - } } .status-legend { - .legend { - width: 5rem; - height: 8px; + .legend { + width: 5rem; + height: 8px; - &.online { - background-color: $online; - } - &.offline { - background-color: $offline; - } - &.never-seen { - background-color: $neverSeen; + &.online { + background-color: $online; + } + &.offline { + background-color: $offline; + } + &.never-seen { + background-color: $neverSeen; + } } - } - span { - color: rgba($color: #000, $alpha: 0.6); - font-size: $cellFontSize; - } + span { + color: rgba($color: #000, $alpha: 0.6); + font-size: $cellFontSize; + } } .overflow-auto { - overflow: auto; + overflow: auto; } .no-shadow { - box-shadow: unset; - -webkit-box-shadow: unset; - -moz-box-shadow: unset; + box-shadow: unset; + -webkit-box-shadow: unset; + -moz-box-shadow: unset; } .status-interval { - width: 180px; - font-size: $cellFontSize; + width: 180px; + font-size: $cellFontSize; } .title { - margin-bottom: 0 !important; + margin-bottom: 0 !important; } diff --git a/src/app/gateway/gateway-status/gateway-status.component.ts b/src/app/gateway/gateway-status/gateway-status.component.ts index f9bb6b7a2..41faad29c 100644 --- a/src/app/gateway/gateway-status/gateway-status.component.ts +++ b/src/app/gateway/gateway-status/gateway-status.component.ts @@ -1,283 +1,238 @@ -import { - AfterContentInit, - Component, - Input, - OnDestroy, - ViewChild, -} from '@angular/core'; -import { MatOptionSelectionChange } from '@angular/material/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatTableDataSource } from '@angular/material/table'; -import { environment } from '@environments/environment'; -import { TranslateService } from '@ngx-translate/core'; -import { recordToEntries } from '@shared/helpers/record.helper'; -import { LoRaWANGatewayService } from '@shared/services/lorawan-gateway.service'; -import moment from 'moment'; -import { Observable, Subject, Subscription } from 'rxjs'; -import { - GatewayStatusInterval, - gatewayStatusIntervalToDate, -} from '../enums/gateway-status-interval.enum'; -import { GatewayStatus, AllGatewayStatusResponse } from '../gateway.model'; -import { map } from 'rxjs/operators'; -import { DefaultPageSizeOptions } from '@shared/constants/page.constants'; +import { AfterContentInit, Component, Input, OnDestroy, ViewChild } from "@angular/core"; +import { MatOptionSelectionChange } from "@angular/material/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatTableDataSource } from "@angular/material/table"; +import { environment } from "@environments/environment"; +import { TranslateService } from "@ngx-translate/core"; +import { recordToEntries } from "@shared/helpers/record.helper"; +import { LoRaWANGatewayService } from "@shared/services/lorawan-gateway.service"; +import moment from "moment"; +import { Observable, Subject, Subscription } from "rxjs"; +import { GatewayStatusInterval, gatewayStatusIntervalToDate } from "../enums/gateway-status-interval.enum"; +import { GatewayStatus, AllGatewayStatusResponse } from "../gateway.model"; +import { map } from "rxjs/operators"; +import { DefaultPageSizeOptions } from "@shared/constants/page.constants"; interface TimeColumn { - exactTimestamp: string; - tooltip: string; - datePart: string; - timePart: string; + exactTimestamp: string; + tooltip: string; + datePart: string; + timePart: string; } @Component({ - selector: 'app-gateway-status', - templateUrl: './gateway-status.component.html', - styleUrls: ['./gateway-status.component.scss'], + selector: "app-gateway-status", + templateUrl: "./gateway-status.component.html", + styleUrls: ["./gateway-status.component.scss"], }) export class GatewayStatusComponent implements AfterContentInit, OnDestroy { - @Input() organisationChangeSubject: Subject; - @Input() isVisibleSubject: Subject; - @Input() paginatorClass: string; - @Input() title: string; - @Input() gatewayId: string; - @Input() shouldLinkToDetails = true; - - private gatewayStatusSubscription: Subscription; - private readonly columnGatewayName = 'gatewayName'; - dataSource: MatTableDataSource; - /** - * List of pre-processed timestamps for performance - */ - timeColumns: TimeColumn[] = []; - /** - * Columns to display. Must not contain objects in order for the table to render. - */ - displayedColumns: string[] = []; - nameText = ''; - neverSeenText = ''; - timestampText = ''; - visibleFooterTimeInterval = 1; - pageSize = environment.tablePageSize; - public pageSizeOptions = DefaultPageSizeOptions; - resultsLength = 0; - organizationId: number | undefined; - isLoadingResults = false; - isDirty = true; - statusIntervals: GatewayStatusInterval[]; - selectedStatusInterval = GatewayStatusInterval.DAY; - - @ViewChild(MatPaginator) paginator: MatPaginator; - - constructor( - private translate: TranslateService, - private lorawanGatewayService: LoRaWANGatewayService - ) {} - - ngAfterContentInit(): void { - this.translate - .get(['GEN.NAME', 'GEN.NEVER-SEEN', 'LORA-GATEWAY-STATUS.TIMESTAMP']) - .subscribe((translations) => { - this.nameText = translations['GEN.NAME']; - this.neverSeenText = translations['GEN.NEVER-SEEN']; - this.timestampText = translations['LORA-GATEWAY-STATUS.TIMESTAMP']; - }); - - this.organisationChangeSubject?.subscribe((orgId) => { - if (this.organizationId !== orgId) { - this.organizationId = orgId; - this.isDirty = true; - } - }); - - this.isVisibleSubject?.pipe().subscribe(() => { - if (!this.isDirty) { - return; - } + @Input() organisationChangeSubject: Subject; + @Input() isVisibleSubject: Subject; + @Input() paginatorClass: string; + @Input() title: string; + @Input() gatewayId: string; + @Input() shouldLinkToDetails = true; + + private gatewayStatusSubscription: Subscription; + private readonly columnGatewayName = "gatewayName"; + dataSource: MatTableDataSource; + /** + * List of pre-processed timestamps for performance + */ + timeColumns: TimeColumn[] = []; + /** + * Columns to display. Must not contain objects in order for the table to render. + */ + displayedColumns: string[] = []; + nameText = ""; + neverSeenText = ""; + timestampText = ""; + visibleFooterTimeInterval = 1; + pageSize = environment.tablePageSize; + public pageSizeOptions = DefaultPageSizeOptions; + resultsLength = 0; + organizationId: number | undefined; + isLoadingResults = false; + isDirty = true; + statusIntervals: GatewayStatusInterval[]; + selectedStatusInterval = GatewayStatusInterval.DAY; + + @ViewChild(MatPaginator) paginator: MatPaginator; + + constructor(private translate: TranslateService, private lorawanGatewayService: LoRaWANGatewayService) {} + + ngAfterContentInit(): void { + this.translate.get(["GEN.NAME", "GEN.NEVER-SEEN", "LORA-GATEWAY-STATUS.TIMESTAMP"]).subscribe(translations => { + this.nameText = translations["GEN.NAME"]; + this.neverSeenText = translations["GEN.NEVER-SEEN"]; + this.timestampText = translations["LORA-GATEWAY-STATUS.TIMESTAMP"]; + }); - this.isDirty = false; - this.subscribeToGetAllGatewayStatus(); - }); + this.organisationChangeSubject?.subscribe(orgId => { + if (this.organizationId !== orgId) { + this.organizationId = orgId; + this.isDirty = true; + } + }); - this.statusIntervals = recordToEntries(GatewayStatusInterval).map( - (interval) => interval.value - ); - } + this.isVisibleSubject?.pipe().subscribe(() => { + if (!this.isDirty) { + return; + } - private getGatewayStatus( - organizationId = this.organizationId, - timeInterval = this.selectedStatusInterval - ): Observable { - const params: Record = { - timeInterval, - // Paginator is only avaiable in ngAfterViewInit - limit: this.paginator?.pageSize, - offset: this.paginator?.pageIndex * this.paginator.pageSize, - }; + this.isDirty = false; + this.subscribeToGetAllGatewayStatus(); + }); - if (organizationId) { - params.organizationId = organizationId; + this.statusIntervals = recordToEntries(GatewayStatusInterval).map(interval => interval.value); } - return !this.gatewayId - ? this.lorawanGatewayService.getAllStatus(params) - : this.lorawanGatewayService - .getStatus(this.gatewayId, { timeInterval }) - .pipe( - map( - (response) => - ({ data: [response], count: 1 } as AllGatewayStatusResponse) - ) - ); - } - - private subscribeToGetAllGatewayStatus( - organizationId = this.organizationId, - timeInterval = this.selectedStatusInterval - ): void { - this.isLoadingResults = true; - this.paginator.pageIndex = 0; - this.gatewayStatusSubscription = this.getGatewayStatus( - organizationId, - timeInterval - ).subscribe((response) => { - this.isLoadingResults = false; - // Get the earliest date from the selected interval - const fromDate = gatewayStatusIntervalToDate(timeInterval); - - if (Array.isArray(response?.data)) { - this.handleStatusResponse(response, fromDate); - } - }); - } - - private handleStatusResponse( - response: AllGatewayStatusResponse, - fromDate: Date - ) { - this.resultsLength = response.count; - const gatewaysWithLatestTimestampsPerHour = this.takeLatestTimestampInHour( - response.data - ); - const gatewaysWithWholeHourTimestamps = this.toWholeHour( - gatewaysWithLatestTimestampsPerHour - ); - - // Sort the gateways and their status timestamps - const sortedData = gatewaysWithWholeHourTimestamps - .slice() - .sort((a, b) => a.name.localeCompare(b.name)) - .map((gateway) => ({ - ...gateway, - statusTimestamps: gateway.statusTimestamps.sort( - (a, b) => a.timestamp.getTime() - b.timestamp.getTime() - ), - })); - - this.buildColumns(fromDate, new Date()); - this.visibleFooterTimeInterval = Math.round( - this.clamp(this.timeColumns.length / 4, 1, 6) - ); - - this.dataSource = new MatTableDataSource(sortedData); - this.dataSource.paginator = this.paginator; - } - - private buildColumns(fromDate: Date, toDate: Date) { - // Ensure the first column is the (earliest) selected date - this.timeColumns = []; - - // If there's a date range, build the columns from them - if (fromDate && toDate) { - const currDate = moment(fromDate).startOf('hour'); - const lastDate = moment(toDate).startOf('hour'); + private getGatewayStatus( + organizationId = this.organizationId, + timeInterval = this.selectedStatusInterval + ): Observable { + const params: Record = { + timeInterval, + // Paginator is only avaiable in ngAfterViewInit + limit: this.paginator?.pageSize, + offset: this.paginator?.pageIndex * this.paginator.pageSize, + }; + + if (organizationId) { + params.organizationId = organizationId; + } + + return !this.gatewayId + ? this.lorawanGatewayService.getAllStatus(params) + : this.lorawanGatewayService + .getStatus(this.gatewayId, { timeInterval }) + .pipe(map(response => ({ data: [response], count: 1 } as AllGatewayStatusResponse))); + } - do { - this.timeColumns.push({ - exactTimestamp: currDate.toISOString(), - tooltip: currDate.format('DD-MM-YYYY HH:00'), - datePart: currDate.format('DD-MM'), - timePart: currDate.format('HH:00'), + private subscribeToGetAllGatewayStatus( + organizationId = this.organizationId, + timeInterval = this.selectedStatusInterval + ): void { + this.isLoadingResults = true; + this.paginator.pageIndex = 0; + this.gatewayStatusSubscription = this.getGatewayStatus(organizationId, timeInterval).subscribe(response => { + this.isLoadingResults = false; + // Get the earliest date from the selected interval + const fromDate = gatewayStatusIntervalToDate(timeInterval); + + if (Array.isArray(response?.data)) { + this.handleStatusResponse(response, fromDate); + } }); - } while (currDate.add(1, 'hour').startOf('hour').diff(lastDate) <= 0); } - this.displayedColumns = [ - this.columnGatewayName, - ...this.timeColumns.map((column) => column.exactTimestamp), - ]; - } - - private toWholeHour(data: GatewayStatus[]): typeof data { - return data.map((gateway) => ({ - ...gateway, - statusTimestamps: gateway.statusTimestamps.map((status) => ({ - ...status, - timestamp: moment(status.timestamp).startOf('hour').toDate(), - })), - })); - } - - /** - * The most recent status per time period takes priority. The data can contain multiple data points - * per time period. This method processeses the data and keeps the latest data point per time period. - * - * @param data A list of gateway status' - */ - private takeLatestTimestampInHour(data: GatewayStatus[]): typeof data { - return data.map((gateway) => { - const timestamps = gateway.statusTimestamps.reduce( - (res: typeof gateway.statusTimestamps, currentStatus) => { - // Check if we already passed a timestamp in the same hour slot as the current one and if it's older - const currentTimestamp = moment(currentStatus.timestamp); - const sameHourTimestampIndex = res.findIndex((storedStatus) => { - const storedTimestamp = moment(storedStatus.timestamp); - return storedTimestamp.isSame(currentTimestamp, 'hour'); - }); + private handleStatusResponse(response: AllGatewayStatusResponse, fromDate: Date) { + this.resultsLength = response.count; + const gatewaysWithLatestTimestampsPerHour = this.takeLatestTimestampInHour(response.data); + const gatewaysWithWholeHourTimestamps = this.toWholeHour(gatewaysWithLatestTimestampsPerHour); + + // Sort the gateways and their status timestamps + const sortedData = gatewaysWithWholeHourTimestamps + .slice() + .sort((a, b) => a.name.localeCompare(b.name)) + .map(gateway => ({ + ...gateway, + statusTimestamps: gateway.statusTimestamps.sort( + (a, b) => a.timestamp.getTime() - b.timestamp.getTime() + ), + })); + + this.buildColumns(fromDate, new Date()); + this.visibleFooterTimeInterval = Math.round(this.clamp(this.timeColumns.length / 4, 1, 6)); + + this.dataSource = new MatTableDataSource(sortedData); + this.dataSource.paginator = this.paginator; + } - if (sameHourTimestampIndex >= 0) { - // Only keep the latest timestamp in the same slot - if ( - res[sameHourTimestampIndex].timestamp < currentStatus.timestamp - ) { - res.splice(sameHourTimestampIndex, 1); - } else { - // Don't store the current timestamp as it's older than the stored one - return res; - } - } + private buildColumns(fromDate: Date, toDate: Date) { + // Ensure the first column is the (earliest) selected date + this.timeColumns = []; + + // If there's a date range, build the columns from them + if (fromDate && toDate) { + const currDate = moment(fromDate).startOf("hour"); + const lastDate = moment(toDate).startOf("hour"); + + do { + this.timeColumns.push({ + exactTimestamp: currDate.toISOString(), + tooltip: currDate.format("DD-MM-YYYY HH:00"), + datePart: currDate.format("DD-MM"), + timePart: currDate.format("HH:00"), + }); + } while (currDate.add(1, "hour").startOf("hour").diff(lastDate) <= 0); + } + + this.displayedColumns = [this.columnGatewayName, ...this.timeColumns.map(column => column.exactTimestamp)]; + } - res.push(currentStatus); - return res; - }, - [] - ); + private toWholeHour(data: GatewayStatus[]): typeof data { + return data.map(gateway => ({ + ...gateway, + statusTimestamps: gateway.statusTimestamps.map(status => ({ + ...status, + timestamp: moment(status.timestamp).startOf("hour").toDate(), + })), + })); + } - return { - ...gateway, - statusTimestamps: timestamps, - }; - }); - } + /** + * The most recent status per time period takes priority. The data can contain multiple data points + * per time period. This method processeses the data and keeps the latest data point per time period. + * + * @param data A list of gateway status' + */ + private takeLatestTimestampInHour(data: GatewayStatus[]): typeof data { + return data.map(gateway => { + const timestamps = gateway.statusTimestamps.reduce( + (res: typeof gateway.statusTimestamps, currentStatus) => { + // Check if we already passed a timestamp in the same hour slot as the current one and if it's older + const currentTimestamp = moment(currentStatus.timestamp); + const sameHourTimestampIndex = res.findIndex(storedStatus => { + const storedTimestamp = moment(storedStatus.timestamp); + return storedTimestamp.isSame(currentTimestamp, "hour"); + }); + + if (sameHourTimestampIndex >= 0) { + // Only keep the latest timestamp in the same slot + if (res[sameHourTimestampIndex].timestamp < currentStatus.timestamp) { + res.splice(sameHourTimestampIndex, 1); + } else { + // Don't store the current timestamp as it's older than the stored one + return res; + } + } + + res.push(currentStatus); + return res; + }, + [] + ); + + return { + ...gateway, + statusTimestamps: timestamps, + }; + }); + } - private clamp(value: number, min: number, max: number) { - return Math.max(min, Math.min(max, value)); - } + private clamp(value: number, min: number, max: number) { + return Math.max(min, Math.min(max, value)); + } - onSelectInterval({ - isUserInput, - source: { value: newInterval }, - }: MatOptionSelectionChange) { - if ( - isUserInput && - newInterval !== this.selectedStatusInterval && - !this.isLoadingResults - ) { - this.subscribeToGetAllGatewayStatus(this.organizationId, newInterval); + onSelectInterval({ isUserInput, source: { value: newInterval } }: MatOptionSelectionChange) { + if (isUserInput && newInterval !== this.selectedStatusInterval && !this.isLoadingResults) { + this.subscribeToGetAllGatewayStatus(this.organizationId, newInterval); + } } - } - ngOnDestroy() { - // prevent memory leak by unsubscribing - this.gatewayStatusSubscription?.unsubscribe(); - } + ngOnDestroy() { + // prevent memory leak by unsubscribing + this.gatewayStatusSubscription?.unsubscribe(); + } } diff --git a/src/app/gateway/gateway-table/gateway-table.component.html b/src/app/gateway/gateway-table/gateway-table.component.html index 40be24cc5..e1ab9031e 100644 --- a/src/app/gateway/gateway-table/gateway-table.component.html +++ b/src/app/gateway/gateway-table/gateway-table.component.html @@ -1,191 +1,230 @@
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- {{ 'LORA-GATEWAY-TABLE.NAME' | translate }} - - - {{ gateway.name }} - - - {{ 'LORA-GATEWAY-TABLE.GATEWAYID' | translate }} - - {{ gateway.gatewayId }} - {{ 'LORA-GATEWAY-TABLE.ORGANIZATION' | translate }} - - {{ gateway.organizationName }} - {{ 'LORA-GATEWAY-TABLE.PACKETS-RECEIVED' | translate }} - {{ gateway.rxPacketsReceived }} - {{ 'LORA-GATEWAY-TABLE.PACKETS-SENT' | translate }} - {{ gateway.txPacketsEmitted }} - {{ 'LORA-GATEWAY-TABLE.PLACEMENT' | translate }} - {{ gateway.placement ? ('GATEWAY.PLACEMENT.' + gateway.placement | translate) : '' }} - {{ 'LORA-GATEWAY-TABLE.MODEL-NAME' | translate }} - {{ gateway.modelName }} - {{ 'LORA-GATEWAY-TABLE.ANTENNA-TYPE' | translate }} - {{ gateway.antennaType }} - {{ 'LORA-GATEWAY-TABLE.STATUS' | translate }} - {{ gateway.status ? ("GATEWAY.STATUS." + gateway.status | translate) : '' }} - {{ 'LORA-GATEWAY-TABLE.RESPONSIBLE-NAME' | translate }} - {{ gateway.gatewayResponsibleName }} - {{ 'LORA-GATEWAY-TABLE.RESPONSIBLE-EMAIL' | translate }} - {{ gateway.gatewayResponsibleEmail }} - {{ 'LORA-GATEWAY-TABLE.RESPONSIBLE-PHONE-NUMBER' | translate }} - {{ gateway.gatewayResponsiblePhoneNumber }} - {{ 'LORA-GATEWAY-TABLE.OPERATIONAL-NAME' | translate }} - {{ gateway.operationalResponsibleName }} - {{ 'LORA-GATEWAY-TABLE.OPERATIONAL-EMAIL' | translate }} - {{ gateway.operationalResponsibleEmail }} - {{ 'LORA-GATEWAY-TABLE.TAGS' | translate }} - {{gateway.tagsString}} - {{ 'LORA-GATEWAY-TABLE.LOCATION' | translate }} - {{ gateway.location.latitude | number:'2.1-6' }}, - {{ gateway.location.longitude | number:'2.1-6' }} - {{ 'LORA-GATEWAY-TABLE.CREATED-AT' | translate }} - {{ gateway.createdAt | dateOnly }} - - {{ 'LORA-GATEWAY-TABLE.LAST-SEEN-AT' | translate }} - - {{lastActive(gateway)}} - - {{ 'LORA-GATEWAY-TABLE.STATUS' | translate }} - - - - - - - - - - -
- - +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ "LORA-GATEWAY-TABLE.NAME" | translate }} + + + {{ gateway.name }} + + + {{ "LORA-GATEWAY-TABLE.GATEWAYID" | translate }} + + {{ gateway.gatewayId }} + + {{ "LORA-GATEWAY-TABLE.ORGANIZATION" | translate }} + + {{ gateway.organizationName }} + + {{ "LORA-GATEWAY-TABLE.PACKETS-RECEIVED" | translate }} + + {{ gateway.rxPacketsReceived }} + + {{ "LORA-GATEWAY-TABLE.PACKETS-SENT" | translate }} + + {{ gateway.txPacketsEmitted }} + {{ "LORA-GATEWAY-TABLE.PLACEMENT" | translate }} + {{ gateway.placement ? ("GATEWAY.PLACEMENT." + gateway.placement | translate) : "" }} + + {{ "LORA-GATEWAY-TABLE.MODEL-NAME" | translate }} + + {{ gateway.modelName }} + + {{ "LORA-GATEWAY-TABLE.ANTENNA-TYPE" | translate }} + + {{ gateway.antennaType }} + {{ "LORA-GATEWAY-TABLE.STATUS" | translate }} + {{ gateway.status ? ("GATEWAY.STATUS." + gateway.status | translate) : "" }} + + {{ "LORA-GATEWAY-TABLE.RESPONSIBLE-NAME" | translate }} + + {{ gateway.gatewayResponsibleName }} + + {{ "LORA-GATEWAY-TABLE.RESPONSIBLE-EMAIL" | translate }} + + {{ gateway.gatewayResponsibleEmail }} + + {{ "LORA-GATEWAY-TABLE.RESPONSIBLE-PHONE-NUMBER" | translate }} + + {{ gateway.gatewayResponsiblePhoneNumber }} + + {{ "LORA-GATEWAY-TABLE.OPERATIONAL-NAME" | translate }} + + {{ gateway.operationalResponsibleName }} + + {{ "LORA-GATEWAY-TABLE.OPERATIONAL-EMAIL" | translate }} + + {{ gateway.operationalResponsibleEmail }} + + {{ "LORA-GATEWAY-TABLE.TAGS" | translate }} + + {{ gateway.tagsString }} + + {{ "LORA-GATEWAY-TABLE.LOCATION" | translate }} + + {{ gateway.location.latitude | number : "2.1-6" }}, + {{ gateway.location.longitude | number : "2.1-6" }} + {{ "LORA-GATEWAY-TABLE.CREATED-AT" | translate }} + {{ gateway.createdAt | dateOnly }} + + {{ "LORA-GATEWAY-TABLE.LAST-SEEN-AT" | translate }} + + {{ lastActive(gateway) }} + + {{ "LORA-GATEWAY-TABLE.STATUS" | translate }} + + + + + + + + + + +
+ +
diff --git a/src/app/gateway/gateway-table/gateway-table.component.scss b/src/app/gateway/gateway-table/gateway-table.component.scss index 2ac450395..c65fba7c4 100644 --- a/src/app/gateway/gateway-table/gateway-table.component.scss +++ b/src/app/gateway/gateway-table/gateway-table.component.scss @@ -7,9 +7,9 @@ } .min-width-150 { - min-width: 150px; + min-width: 150px; } .min-width-250 { - min-width: 250px; + min-width: 250px; } diff --git a/src/app/gateway/gateway.module.ts b/src/app/gateway/gateway.module.ts index c73455411..b5b20d7eb 100644 --- a/src/app/gateway/gateway.module.ts +++ b/src/app/gateway/gateway.module.ts @@ -1,77 +1,77 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { RouterModule, Routes } from '@angular/router'; -import { TranslateModule } from '@ngx-translate/core'; -import { GatewayTableComponent } from './gateway-table/gateway-table.component'; -import { GatewaysComponent } from './gateways/gateways.component'; -import { GatewayOverviewComponent } from './gateway-overview/gateway-overview.component'; -import { GatewayEditComponent } from './gateway-edit/gateway-edit.component'; -import { FormsModule } from '@angular/forms'; -import { GatewayDetailComponent } from './gateway-detail/gateway-detail.component'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { FormModule } from '@shared/components/forms/form.module'; -import { SharedModule } from '@shared/shared.module'; -import { PipesModule } from '@shared/pipes/pipes.module'; -import { GatewayStatusComponent } from './gateway-status/gateway-status.component'; -import { GraphModule } from '@app/graph/graph.module'; -import { GatewayListComponent } from './gateway-overview/gateway-tabs/gateway-list/gateway-list.component'; -import { GatewayMapComponent } from './gateway-overview/gateway-tabs/gateway-map/gateway-map.component'; -import { GatewayStatusOverviewComponent } from './gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component'; +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { RouterModule, Routes } from "@angular/router"; +import { TranslateModule } from "@ngx-translate/core"; +import { GatewayTableComponent } from "./gateway-table/gateway-table.component"; +import { GatewaysComponent } from "./gateways/gateways.component"; +import { GatewayOverviewComponent } from "./gateway-overview/gateway-overview.component"; +import { GatewayEditComponent } from "./gateway-edit/gateway-edit.component"; +import { FormsModule } from "@angular/forms"; +import { GatewayDetailComponent } from "./gateway-detail/gateway-detail.component"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { FormModule } from "@shared/components/forms/form.module"; +import { SharedModule } from "@shared/shared.module"; +import { PipesModule } from "@shared/pipes/pipes.module"; +import { GatewayStatusComponent } from "./gateway-status/gateway-status.component"; +import { GraphModule } from "@app/graph/graph.module"; +import { GatewayListComponent } from "./gateway-overview/gateway-tabs/gateway-list/gateway-list.component"; +import { GatewayMapComponent } from "./gateway-overview/gateway-tabs/gateway-map/gateway-map.component"; +import { GatewayStatusOverviewComponent } from "./gateway-overview/gateway-tabs/gateway-status-overview/gateway-status-overview.component"; const gatewayRoutes: Routes = [ - { - path: '', - component: GatewaysComponent, - children: [ - { - path: '', - component: GatewayOverviewComponent, + { + path: "", + component: GatewaysComponent, children: [ - { path: 'list', component: GatewayListComponent }, - { path: 'map', component: GatewayMapComponent }, - { path: 'status', component: GatewayStatusOverviewComponent }, + { + path: "", + component: GatewayOverviewComponent, + children: [ + { path: "list", component: GatewayListComponent }, + { path: "map", component: GatewayMapComponent }, + { path: "status", component: GatewayStatusOverviewComponent }, + ], + }, + { path: "gateway-edit/:id", component: GatewayEditComponent }, + { path: "gateway-edit", component: GatewayEditComponent }, + { path: "gateway-detail/:id", component: GatewayDetailComponent }, ], - }, - { path: 'gateway-edit/:id', component: GatewayEditComponent }, - { path: 'gateway-edit', component: GatewayEditComponent }, - { path: 'gateway-detail/:id', component: GatewayDetailComponent }, - ], - }, + }, ]; @NgModule({ - declarations: [ - GatewayTableComponent, - GatewaysComponent, - GatewayOverviewComponent, - GatewayDetailComponent, - GatewayEditComponent, - GatewayStatusComponent, - GatewayListComponent, - GatewayMapComponent, - GatewayStatusOverviewComponent, - ], - imports: [ - CommonModule, - RouterModule, - TranslateModule, - FormModule, - FormsModule, - FontAwesomeModule, - NGMaterialModule, - RouterModule.forChild(gatewayRoutes), - SharedModule, - PipesModule, - GraphModule, - ], - exports: [ - GatewayTableComponent, - GatewaysComponent, - GatewayOverviewComponent, - GatewayEditComponent, - GatewayStatusComponent, - RouterModule, - ], + declarations: [ + GatewayTableComponent, + GatewaysComponent, + GatewayOverviewComponent, + GatewayDetailComponent, + GatewayEditComponent, + GatewayStatusComponent, + GatewayListComponent, + GatewayMapComponent, + GatewayStatusOverviewComponent, + ], + imports: [ + CommonModule, + RouterModule, + TranslateModule, + FormModule, + FormsModule, + FontAwesomeModule, + NGMaterialModule, + RouterModule.forChild(gatewayRoutes), + SharedModule, + PipesModule, + GraphModule, + ], + exports: [ + GatewayTableComponent, + GatewaysComponent, + GatewayOverviewComponent, + GatewayEditComponent, + GatewayStatusComponent, + RouterModule, + ], }) export class GatewayModule {} diff --git a/src/app/gateway/gateway.service.ts b/src/app/gateway/gateway.service.ts index 24debf78b..09b02b76d 100644 --- a/src/app/gateway/gateway.service.ts +++ b/src/app/gateway/gateway.service.ts @@ -1,9 +1,9 @@ -import { Injectable } from '@angular/core'; -import { Subject } from 'rxjs'; +import { Injectable } from "@angular/core"; +import { Subject } from "rxjs"; -@Injectable({ providedIn: 'root' }) +@Injectable({ providedIn: "root" }) export class GatewayService { - organisationChangeSubject: Subject = new Subject(); - isGatewayStatusVisibleSubject: Subject = new Subject(); - selectedOrg: number; + organisationChangeSubject: Subject = new Subject(); + isGatewayStatusVisibleSubject: Subject = new Subject(); + selectedOrg: number; } diff --git a/src/app/gateway/gateways/gateways.component.html b/src/app/gateway/gateways/gateways.component.html index 90c6b6463..0680b43f9 100644 --- a/src/app/gateway/gateways/gateways.component.html +++ b/src/app/gateway/gateways/gateways.component.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/app/gateway/gateways/gateways.component.ts b/src/app/gateway/gateways/gateways.component.ts index 986622b55..ca73a17b4 100644 --- a/src/app/gateway/gateways/gateways.component.ts +++ b/src/app/gateway/gateways/gateways.component.ts @@ -1,15 +1,12 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-gateways', - templateUrl: './gateways.component.html', - styleUrls: ['./gateways.component.scss'] + selector: "app-gateways", + templateUrl: "./gateways.component.html", + styleUrls: ["./gateways.component.scss"], }) export class GatewaysComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit(): void { - } - + ngOnInit(): void {} } diff --git a/src/app/graph/graph.component.html b/src/app/graph/graph.component.html index 1c8030cf3..2ed007300 100644 --- a/src/app/graph/graph.component.html +++ b/src/app/graph/graph.component.html @@ -1,13 +1,13 @@ - - - {{title}} - - - -
- {{ 'GEN.NO-DATA' | translate }} -
- -
+ + + {{ title }} + + + +
+ {{ "GEN.NO-DATA" | translate }} +
+ +
diff --git a/src/app/graph/graph.component.scss b/src/app/graph/graph.component.scss index aacf82cda..9b71b3545 100644 --- a/src/app/graph/graph.component.scss +++ b/src/app/graph/graph.component.scss @@ -1,29 +1,29 @@ :host { - height: 100%; - width: 100%; + height: 100%; + width: 100%; } .chart-container { - height: 100%; + height: 100%; - canvas { - background-color: white; - } + canvas { + background-color: white; + } - mat-card-content { - position: relative; - } + mat-card-content { + position: relative; + } - .no-data-container { - position: absolute; - display: flex; - width: 100%; - height: 90%; - justify-content: center; - align-items: center; - } + .no-data-container { + position: absolute; + display: flex; + width: 100%; + height: 90%; + justify-content: center; + align-items: center; + } } .width-100-percent { - width: 100%; + width: 100%; } diff --git a/src/app/graph/graph.component.ts b/src/app/graph/graph.component.ts index 89dac1a80..00ee01fa3 100644 --- a/src/app/graph/graph.component.ts +++ b/src/app/graph/graph.component.ts @@ -1,100 +1,89 @@ -import { - Component, - ElementRef, - Input, - OnChanges, - SimpleChanges, - ViewChild, -} from '@angular/core'; -import { Chart, ChartConfiguration } from 'chart.js'; +import { Component, ElementRef, Input, OnChanges, SimpleChanges, ViewChild } from "@angular/core"; +import { Chart, ChartConfiguration } from "chart.js"; -const canvasId = 'someGraph'; +const canvasId = "someGraph"; @Component({ - selector: 'app-graph', - templateUrl: './graph.component.html', - styleUrls: ['./graph.component.scss'], + selector: "app-graph", + templateUrl: "./graph.component.html", + styleUrls: ["./graph.component.scss"], }) export class GraphComponent implements OnChanges { - @Input() data: ChartConfiguration['data']; - @Input() type: ChartConfiguration['type']; - @Input() options: ChartConfiguration['options'] = { - plugins: { legend: { display: false } }, - responsive: true, - layout: { - padding: { - top: 15, - left: 10, - right: 10, - }, - }, - }; - @Input() title: string; - @Input() graphCardClass: string; - @Input() graphHeaderClass: string; - chartInstance: Chart = null; - isGraphEmpty: boolean; - - @ViewChild(canvasId) chart: ElementRef; - - constructor() { - this.isGraphEmpty = this.checkIfGraphIsEmpty(); - } + @Input() data: ChartConfiguration["data"]; + @Input() type: ChartConfiguration["type"]; + @Input() options: ChartConfiguration["options"] = { + plugins: { legend: { display: false } }, + responsive: true, + layout: { + padding: { + top: 15, + left: 10, + right: 10, + }, + }, + }; + @Input() title: string; + @Input() graphCardClass: string; + @Input() graphHeaderClass: string; + chartInstance: Chart = null; + isGraphEmpty: boolean; - ngOnChanges(_changes: SimpleChanges): void { - this.buildChart(); - } + @ViewChild(canvasId) chart: ElementRef; - buildChart(): void { - // Update the chart with (new) data. Destroying the chart and re-creating it seems the most stable. - if (this.chartInstance) { - this.chartInstance.destroy(); + constructor() { + this.isGraphEmpty = this.checkIfGraphIsEmpty(); } - if (!this.chart?.nativeElement) { - return; + ngOnChanges(_changes: SimpleChanges): void { + this.buildChart(); } - const options = this.buildOptionsForNoData(this.options); + buildChart(): void { + // Update the chart with (new) data. Destroying the chart and re-creating it seems the most stable. + if (this.chartInstance) { + this.chartInstance.destroy(); + } - this.chartInstance = new Chart(this.chart.nativeElement.getContext('2d'), { - data: this.data, - type: this.type, - options, - }); - } + if (!this.chart?.nativeElement) { + return; + } - private checkIfGraphIsEmpty(): boolean { - // Currently, only the first dataset is checked for zeroes. - return ( - !this.data?.datasets?.length || - (this.data.datasets.length === 1 && - !this.data.datasets[0].data.some( - (point) => point !== null && point !== undefined - )) - ); - } + const options = this.buildOptionsForNoData(this.options); - private buildOptionsForNoData( - options: ChartConfiguration['options'] - ): typeof options { - this.isGraphEmpty = this.checkIfGraphIsEmpty(); + this.chartInstance = new Chart(this.chart.nativeElement.getContext("2d"), { + data: this.data, + type: this.type, + options, + }); + } - return this.isGraphEmpty - ? { - ...options, - scales: { - ...options?.scales, - x: { - ...options?.scales?.x, - display: false, - }, - y: { - ...options?.scales?.y, - display: false, - }, - }, - } - : options; - } + private checkIfGraphIsEmpty(): boolean { + // Currently, only the first dataset is checked for zeroes. + return ( + !this.data?.datasets?.length || + (this.data.datasets.length === 1 && + !this.data.datasets[0].data.some(point => point !== null && point !== undefined)) + ); + } + + private buildOptionsForNoData(options: ChartConfiguration["options"]): typeof options { + this.isGraphEmpty = this.checkIfGraphIsEmpty(); + + return this.isGraphEmpty + ? { + ...options, + scales: { + ...options?.scales, + x: { + ...options?.scales?.x, + display: false, + }, + y: { + ...options?.scales?.y, + display: false, + }, + }, + } + : options; + } } diff --git a/src/app/graph/graph.module.ts b/src/app/graph/graph.module.ts index c675024f1..c3811dd31 100644 --- a/src/app/graph/graph.module.ts +++ b/src/app/graph/graph.module.ts @@ -1,16 +1,16 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { NGMaterialModule } from '@shared/Modules/materiale.module'; -import { Chart, registerables } from 'chart.js'; -import { GraphComponent } from './graph.component'; +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { TranslateModule } from "@ngx-translate/core"; +import { NGMaterialModule } from "@shared/Modules/materiale.module"; +import { Chart, registerables } from "chart.js"; +import { GraphComponent } from "./graph.component"; // Register everything necessary to cover all configurations Chart.register(...registerables); @NgModule({ - declarations: [GraphComponent], - imports: [CommonModule, NGMaterialModule, TranslateModule], - exports: [GraphComponent], + declarations: [GraphComponent], + imports: [CommonModule, NGMaterialModule, TranslateModule], + exports: [GraphComponent], }) export class GraphModule {} diff --git a/src/app/navbar/global-admin/global-admin.component.html b/src/app/navbar/global-admin/global-admin.component.html index 11bc45cc5..be0e29bca 100644 --- a/src/app/navbar/global-admin/global-admin.component.html +++ b/src/app/navbar/global-admin/global-admin.component.html @@ -1,7 +1,7 @@ - + @@ -9,24 +9,29 @@ - - \ No newline at end of file + diff --git a/src/app/navbar/global-admin/global-admin.component.scss b/src/app/navbar/global-admin/global-admin.component.scss index d3f5a12fa..e69de29bb 100644 --- a/src/app/navbar/global-admin/global-admin.component.scss +++ b/src/app/navbar/global-admin/global-admin.component.scss @@ -1 +0,0 @@ - diff --git a/src/app/navbar/global-admin/global-admin.component.ts b/src/app/navbar/global-admin/global-admin.component.ts index 4db06ad28..be0b3a523 100644 --- a/src/app/navbar/global-admin/global-admin.component.ts +++ b/src/app/navbar/global-admin/global-admin.component.ts @@ -1,32 +1,29 @@ -import { Component, OnInit } from '@angular/core'; -import { PermissionType } from '@app/admin/permission/permission.model'; -import { UserResponse } from '@app/admin/users/user.model'; -import { faGlobe, faUsers, faIdBadge, faSitemap, faUser } from '@fortawesome/free-solid-svg-icons'; -import { SharedVariableService } from '@shared/shared-variable/shared-variable.service'; -import { MeService } from '@shared/services/me.service'; +import { Component, OnInit } from "@angular/core"; +import { PermissionType } from "@app/admin/permission/permission.model"; +import { UserResponse } from "@app/admin/users/user.model"; +import { faGlobe, faUsers, faIdBadge, faSitemap, faUser } from "@fortawesome/free-solid-svg-icons"; +import { SharedVariableService } from "@shared/shared-variable/shared-variable.service"; +import { MeService } from "@shared/services/me.service"; @Component({ - selector: 'app-global-admin', - templateUrl: './global-admin.component.html', - styleUrls: ['./global-admin.component.scss'], + selector: "app-global-admin", + templateUrl: "./global-admin.component.html", + styleUrls: ["./global-admin.component.scss"], }) export class GlobalAdminComponent implements OnInit { - faGlobe = faGlobe; - faUsers = faUsers; - faIdBadge = faIdBadge; - faSitemap = faSitemap; - faUser = faUser; + faGlobe = faGlobe; + faUsers = faUsers; + faIdBadge = faIdBadge; + faSitemap = faSitemap; + faUser = faUser; - public user: UserResponse; - public isGlobalAdmin = false; + public user: UserResponse; + public isGlobalAdmin = false; - constructor( - private sharedVariableService: SharedVariableService, - private meService: MeService - ) {} + constructor(private sharedVariableService: SharedVariableService, private meService: MeService) {} - ngOnInit(): void { - this.user = this.sharedVariableService.getUserInfo().user; - this.isGlobalAdmin = this.meService.hasGlobalAdmin(); - } + ngOnInit(): void { + this.user = this.sharedVariableService.getUserInfo().user; + this.isGlobalAdmin = this.meService.hasGlobalAdmin(); + } } diff --git a/src/app/navbar/navbar.component.html b/src/app/navbar/navbar.component.html index 412185bb9..e4ef8b6a9 100644 --- a/src/app/navbar/navbar.component.html +++ b/src/app/navbar/navbar.component.html @@ -1,70 +1,97 @@ -