@sumaris-net/ngx-components 1.23.44 → 2.0.0-rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/doc/build.md +2 -2
- package/doc/changelog.md +8 -0
- package/esm2020/public_api.mjs +278 -0
- package/esm2020/public_test_api.mjs +46 -0
- package/esm2020/src/app/admin/admin-routing.module.mjs +41 -0
- package/esm2020/src/app/admin/admin.module.mjs +34 -0
- package/esm2020/src/app/admin/services/filter/person.filter.mjs +59 -0
- package/esm2020/src/app/admin/services/person.service.mjs +161 -0
- package/esm2020/src/app/admin/services/validator/person.validator.mjs +34 -0
- package/esm2020/src/app/admin/users/list/users.mjs +233 -0
- package/esm2020/src/app/admin/users/list/users.module.mjs +58 -0
- package/esm2020/src/app/core/about/modal-about.mjs +71 -0
- package/esm2020/src/app/core/account/account.mjs +230 -0
- package/esm2020/src/app/core/auth/form/form-auth.mjs +131 -0
- package/esm2020/src/app/core/auth/modal/modal-auth.mjs +72 -0
- package/esm2020/src/app/core/core.module.mjs +223 -0
- package/esm2020/src/app/core/core.testing.module.mjs +86 -0
- package/esm2020/src/app/core/form/editor.class.mjs +672 -0
- package/esm2020/src/app/core/form/entity-editor-modal.class.mjs +407 -0
- package/esm2020/src/app/core/form/entity-editor.class.mjs +646 -0
- package/esm2020/src/app/core/form/entity-metadata.component.mjs +25 -0
- package/esm2020/src/app/core/form/form-buttons-bar.component.mjs +71 -0
- package/esm2020/src/app/core/form/form.class.mjs +337 -0
- package/esm2020/src/app/core/form/form.utils.mjs +299 -0
- package/esm2020/src/app/core/form/list.form.mjs +222 -0
- package/esm2020/src/app/core/form/properties/properties.form.mjs +129 -0
- package/esm2020/src/app/core/form/properties/property.validator.mjs +23 -0
- package/esm2020/src/app/core/form/properties/testing/properties-form.test.mjs +90 -0
- package/esm2020/src/app/core/form/properties/testing/properties-form.testing.module.mjs +39 -0
- package/esm2020/src/app/core/graphql/graphql.module.mjs +22 -0
- package/esm2020/src/app/core/graphql/graphql.service.mjs +730 -0
- package/esm2020/src/app/core/graphql/graphql.utils.mjs +117 -0
- package/esm2020/src/app/core/home/home.mjs +257 -0
- package/esm2020/src/app/core/icon/icon.component.mjs +41 -0
- package/esm2020/src/app/core/icon/icon.module.mjs +29 -0
- package/esm2020/src/app/core/install/install-upgrade-card.component.mjs +337 -0
- package/esm2020/src/app/core/install/install-upgrade-card.module.mjs +33 -0
- package/esm2020/src/app/core/menu/menu.component.mjs +317 -0
- package/{esm2015/src/app/core/menu/menu.model.js → esm2020/src/app/core/menu/menu.model.mjs} +0 -0
- package/esm2020/src/app/core/menu/menu.module.mjs +45 -0
- package/{esm2015/src/app/core/menu/menu.service.js → esm2020/src/app/core/menu/menu.service.mjs} +9 -7
- package/esm2020/src/app/core/offline/update-offline-mode-card.component.mjs +27 -0
- package/esm2020/src/app/core/peer/select-peer.modal.mjs +130 -0
- package/esm2020/src/app/core/peer/select-peer.module.mjs +35 -0
- package/esm2020/src/app/core/register/confirm/confirm.mjs +81 -0
- package/esm2020/src/app/core/register/form/form-register.mjs +181 -0
- package/esm2020/src/app/core/register/modal/modal-register.mjs +52 -0
- package/esm2020/src/app/core/register/register.module.mjs +42 -0
- package/esm2020/src/app/core/services/account.service.mjs +1112 -0
- package/esm2020/src/app/core/services/auth-guard.service.mjs +71 -0
- package/esm2020/src/app/core/services/base-entity-service.class.mjs +432 -0
- package/esm2020/src/app/core/services/base-graphql-service.class.mjs +219 -0
- package/{esm2015/src/app/core/services/base58.js → esm2020/src/app/core/services/base58.mjs} +0 -0
- package/{esm2015/src/app/core/services/config/core.config.js → esm2020/src/app/core/services/config/core.config.mjs} +0 -0
- package/esm2020/src/app/core/services/config.service.mjs +354 -0
- package/{esm2015/src/app/core/services/crypto.service.js → esm2020/src/app/core/services/crypto.service.mjs} +7 -5
- package/{esm2015/src/app/core/services/errors.js → esm2020/src/app/core/services/errors.mjs} +0 -0
- package/esm2020/src/app/core/services/local-settings.service.mjs +442 -0
- package/esm2020/src/app/core/services/model/account.model.mjs +50 -0
- package/esm2020/src/app/core/services/model/config.model.mjs +89 -0
- package/esm2020/src/app/core/services/model/department.model.mjs +30 -0
- package/esm2020/src/app/core/services/model/entity.decorators.mjs +107 -0
- package/esm2020/src/app/core/services/model/entity.model.mjs +242 -0
- package/{esm2015/src/app/core/services/model/filter.model.js → esm2020/src/app/core/services/model/filter.model.mjs} +0 -0
- package/{esm2015/src/app/core/services/model/history.model.js → esm2020/src/app/core/services/model/history.model.mjs} +0 -0
- package/{esm2015/src/app/core/services/model/model.enum.js → esm2020/src/app/core/services/model/model.enum.mjs} +0 -0
- package/esm2020/src/app/core/services/model/peer.model.mjs +68 -0
- package/esm2020/src/app/core/services/model/person.model.mjs +83 -0
- package/esm2020/src/app/core/services/model/referential.model.mjs +145 -0
- package/esm2020/src/app/core/services/model/settings.model.mjs +75 -0
- package/esm2020/src/app/core/services/network.service.mjs +595 -0
- package/esm2020/src/app/core/services/network.utils.mjs +16 -0
- package/esm2020/src/app/core/services/pipes/account.pipes.mjs +38 -0
- package/esm2020/src/app/core/services/pipes/department-to-string.pipe.mjs +23 -0
- package/esm2020/src/app/core/services/pipes/person-to-string.pipe.mjs +23 -0
- package/esm2020/src/app/core/services/pipes/usage-mode.pipes.mjs +37 -0
- package/esm2020/src/app/core/services/platform.service.mjs +476 -0
- package/esm2020/src/app/core/services/storage/entities-storage.service.mjs +422 -0
- package/esm2020/src/app/core/services/storage/entity-store.class.mjs +449 -0
- package/esm2020/src/app/core/services/testing/referential-filter.model.mjs +23 -0
- package/esm2020/src/app/core/services/testing/referential.validator.mjs +45 -0
- package/esm2020/src/app/core/services/validator/account.validator.mjs +52 -0
- package/esm2020/src/app/core/services/validator/base.validator.class.mjs +47 -0
- package/esm2020/src/app/core/services/validator/local-settings.validator.mjs +66 -0
- package/esm2020/src/app/core/services/validator/user-settings.validator.mjs +29 -0
- package/esm2020/src/app/core/settings/settings.page.mjs +290 -0
- package/esm2020/src/app/core/table/actions-column.component.mjs +96 -0
- package/esm2020/src/app/core/table/entities-table-datasource.class.mjs +394 -0
- package/esm2020/src/app/core/table/memory-table.class.mjs +53 -0
- package/esm2020/src/app/core/table/table-select-columns.component.mjs +43 -0
- package/esm2020/src/app/core/table/table.class.mjs +1666 -0
- package/esm2020/src/app/core/table/table.utils.mjs +13 -0
- package/esm2020/src/app/core/table/testing/table.testing.mjs +264 -0
- package/esm2020/src/app/core/table/testing/table.testing.module.mjs +38 -0
- package/esm2020/src/app/core/text-popover/testing/text-popover.testing.mjs +37 -0
- package/esm2020/src/app/core/text-popover/testing/text-popover.testing.module.mjs +45 -0
- package/esm2020/src/app/core/text-popover/text-form.component.mjs +84 -0
- package/esm2020/src/app/core/text-popover/text-popover.component.mjs +92 -0
- package/esm2020/src/app/shared/alerts.mjs +238 -0
- package/esm2020/src/app/shared/audio/audio.mjs +201 -0
- package/esm2020/src/app/shared/audio/audio.testing.mjs +31 -0
- package/esm2020/src/app/shared/audio/audio.testing.module.mjs +45 -0
- package/esm2020/src/app/shared/capacitor/keyboard.mjs +40 -0
- package/esm2020/src/app/shared/capacitor/plugins.mjs +9 -0
- package/{esm2015/src/app/shared/constants.js → esm2020/src/app/shared/constants.mjs} +2 -1
- package/esm2020/src/app/shared/dates.mjs +134 -0
- package/esm2020/src/app/shared/debug/debug.component.mjs +39 -0
- package/esm2020/src/app/shared/debug/debug.module.mjs +44 -0
- package/esm2020/src/app/shared/directives/autofocus.directive.mjs +92 -0
- package/esm2020/src/app/shared/directives/autotitle.directive.mjs +30 -0
- package/esm2020/src/app/shared/directives/directives.module.mjs +43 -0
- package/esm2020/src/app/shared/directives/drag-and-drop.directive.mjs +53 -0
- package/esm2020/src/app/shared/directives/ng-var.directive.mjs +31 -0
- package/esm2020/src/app/shared/directives/resizable/resizable.component.mjs +59 -0
- package/esm2020/src/app/shared/directives/resizable/resizable.directive.mjs +40 -0
- package/esm2020/src/app/shared/directives/resizable/resizable.module.mjs +17 -0
- package/esm2020/src/app/shared/events.mjs +64 -0
- package/esm2020/src/app/shared/file/csv.utils.mjs +74 -0
- package/esm2020/src/app/shared/file/file.service.mjs +117 -0
- package/esm2020/src/app/shared/file/file.utils.mjs +113 -0
- package/esm2020/src/app/shared/file/images.utils.mjs +161 -0
- package/{esm2015/src/app/shared/file/uri.utils.js → esm2020/src/app/shared/file/uri.utils.mjs} +0 -0
- package/{esm2015/src/app/shared/focusable.js → esm2020/src/app/shared/focusable.mjs} +0 -0
- package/esm2020/src/app/shared/form/field.component.mjs +244 -0
- package/{esm2015/src/app/shared/form/field.model.js → esm2020/src/app/shared/form/field.model.mjs} +1 -1
- package/esm2020/src/app/shared/form/loading-spinner.mjs +36 -0
- package/esm2020/src/app/shared/forms.mjs +374 -0
- package/esm2020/src/app/shared/functions.mjs +430 -0
- package/{esm2015/src/app/shared/gesture/gesture-config.js → esm2020/src/app/shared/gesture/gesture-config.mjs} +7 -5
- package/esm2020/src/app/shared/gesture/hammer.utils.mjs +2 -0
- package/{esm2015/src/app/shared/graph/colors.utils.js → esm2020/src/app/shared/graph/colors.utils.mjs} +0 -0
- package/esm2020/src/app/shared/graph/graph-colors.mjs +254 -0
- package/esm2020/src/app/shared/guard/component-dirty.guard.mjs +57 -0
- package/esm2020/src/app/shared/help/help.modal.mjs +53 -0
- package/esm2020/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +23 -0
- package/esm2020/src/app/shared/hotkeys/hotkeys.service.mjs +84 -0
- package/esm2020/src/app/shared/hotkeys/shared-hotkeys.module.mjs +42 -0
- package/esm2020/src/app/shared/http/http.utils.mjs +52 -0
- package/esm2020/src/app/shared/image/gallery/image-gallery.component.mjs +279 -0
- package/esm2020/src/app/shared/image/gallery/image-gallery.module.mjs +46 -0
- package/esm2020/src/app/shared/image/gallery/testing/gallegry.model.testing.mjs +27 -0
- package/esm2020/src/app/shared/image/gallery/testing/gallery.service.testing.mjs +89 -0
- package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.mjs +33 -0
- package/esm2020/src/app/shared/image/gallery/testing/gallery.testing.module.mjs +56 -0
- package/esm2020/src/app/shared/image/image.model.mjs +2 -0
- package/esm2020/src/app/shared/image/image.module.mjs +29 -0
- package/esm2020/src/app/shared/image/image.service.mjs +99 -0
- package/{esm2015/src/app/shared/inputs.js → esm2020/src/app/shared/inputs.mjs} +4 -4
- package/{esm2015/src/app/shared/interceptors/progess.interceptor.js → esm2020/src/app/shared/interceptors/progess.interceptor.mjs} +0 -0
- package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +47 -0
- package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.mjs +836 -0
- package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +78 -0
- package/esm2020/src/app/shared/material/autocomplete/material.autocomplete.utils.mjs +19 -0
- package/esm2020/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +205 -0
- package/esm2020/src/app/shared/material/badge/badge.directive.mjs +157 -0
- package/esm2020/src/app/shared/material/badge/badge.module.mjs +32 -0
- package/esm2020/src/app/shared/material/badge/badge.test.mjs +26 -0
- package/esm2020/src/app/shared/material/boolean/boolean.module.mjs +68 -0
- package/esm2020/src/app/shared/material/boolean/material.boolean.mjs +253 -0
- package/esm2020/src/app/shared/material/chips/chips.module.mjs +76 -0
- package/esm2020/src/app/shared/material/chips/material.chips.mjs +691 -0
- package/esm2020/src/app/shared/material/chips/testing/chips.test.mjs +136 -0
- package/esm2020/src/app/shared/material/datetime/datetime.module.mjs +91 -0
- package/esm2020/src/app/shared/material/datetime/material.date.mjs +388 -0
- package/esm2020/src/app/shared/material/datetime/material.dateshort.mjs +327 -0
- package/esm2020/src/app/shared/material/datetime/material.datetime.mjs +434 -0
- package/esm2020/src/app/shared/material/datetime/testing/mat-date-time.test.mjs +110 -0
- package/esm2020/src/app/shared/material/datetime/testing/mat-date.test.mjs +111 -0
- package/esm2020/src/app/shared/material/duration/duration.module.mjs +67 -0
- package/{esm2015/src/app/shared/material/duration/duration.utils.js → esm2020/src/app/shared/material/duration/duration.utils.mjs} +0 -0
- package/esm2020/src/app/shared/material/duration/material.duration.mjs +257 -0
- package/esm2020/src/app/shared/material/latlong/latlong.utils.mjs +266 -0
- package/esm2020/src/app/shared/material/latlong/material.latlong.mjs +381 -0
- package/esm2020/src/app/shared/material/latlong/material.latlong.module.mjs +67 -0
- package/esm2020/src/app/shared/material/latlong/testing/latlong.test.mjs +74 -0
- package/{esm2015/src/app/shared/material/material.animations.js → esm2020/src/app/shared/material/material.animations.mjs} +0 -0
- package/esm2020/src/app/shared/material/material.module.mjs +224 -0
- package/esm2020/src/app/shared/material/material.testing.module.mjs +145 -0
- package/esm2020/src/app/shared/material/numpad/numpad.append-to-input.directive.mjs +98 -0
- package/esm2020/src/app/shared/material/numpad/numpad.component.mjs +80 -0
- package/esm2020/src/app/shared/material/numpad/numpad.container.mjs +190 -0
- package/esm2020/src/app/shared/material/numpad/numpad.content.mjs +17 -0
- package/esm2020/src/app/shared/material/numpad/numpad.directive.mjs +162 -0
- package/esm2020/src/app/shared/material/numpad/numpad.dom-service.mjs +37 -0
- package/{esm2015/src/app/shared/material/numpad/numpad.model.js → esm2020/src/app/shared/material/numpad/numpad.model.mjs} +1 -1
- package/esm2020/src/app/shared/material/numpad/numpad.module.mjs +60 -0
- package/esm2020/src/app/shared/material/numpad/testing/numpad.test.mjs +46 -0
- package/esm2020/src/app/shared/material/paginator/material.paginator-i18n.mjs +42 -0
- package/esm2020/src/app/shared/material/stepper/material.stepper-i18n.mjs +22 -0
- package/esm2020/src/app/shared/material/swipe/material.swipe.mjs +334 -0
- package/esm2020/src/app/shared/material/swipe/swipe.module.mjs +51 -0
- package/esm2020/src/app/shared/material/swipe/testing/swipe.test.mjs +65 -0
- package/esm2020/src/app/shared/observables.mjs +96 -0
- package/esm2020/src/app/shared/pipes/arrays.pipe.mjs +135 -0
- package/esm2020/src/app/shared/pipes/colors.pipe.mjs +23 -0
- package/esm2020/src/app/shared/pipes/date-diff-duration.pipe.mjs +49 -0
- package/esm2020/src/app/shared/pipes/date-format.pipe.mjs +42 -0
- package/{esm2015/src/app/shared/pipes/date-from-now.pipe.js → esm2020/src/app/shared/pipes/date-from-now.pipe.mjs} +13 -12
- package/{esm2015/src/app/shared/pipes/duration.pipe.js → esm2020/src/app/shared/pipes/duration.pipe.mjs} +13 -12
- package/esm2020/src/app/shared/pipes/file-size.pipe.mjs +62 -0
- package/esm2020/src/app/shared/pipes/form.pipes.mjs +187 -0
- package/esm2020/src/app/shared/pipes/highlight.pipe.mjs +48 -0
- package/esm2020/src/app/shared/pipes/latlong-format.pipe.mjs +46 -0
- package/esm2020/src/app/shared/pipes/maps.pipe.mjs +63 -0
- package/esm2020/src/app/shared/pipes/math.pipes.mjs +59 -0
- package/esm2020/src/app/shared/pipes/ng-init.pipe.mjs +21 -0
- package/{esm2015/src/app/shared/pipes/number-format.pipe.js → esm2020/src/app/shared/pipes/number-format.pipe.mjs} +14 -9
- package/esm2020/src/app/shared/pipes/pipes.module.mjs +210 -0
- package/esm2020/src/app/shared/pipes/property.pipes.mjs +96 -0
- package/esm2020/src/app/shared/pipes/string.pipes.mjs +69 -0
- package/esm2020/src/app/shared/pipes/translate-context.pipe.mjs +43 -0
- package/esm2020/src/app/shared/platforms.mjs +49 -0
- package/esm2020/src/app/shared/services/entity-service.class.mjs +7 -0
- package/esm2020/src/app/shared/services/job.utils.mjs +92 -0
- package/esm2020/src/app/shared/services/memory-entity-service.class.mjs +331 -0
- package/esm2020/src/app/shared/services/progress-bar.service.mjs +32 -0
- package/esm2020/src/app/shared/services/startable-observable-service.class.mjs +119 -0
- package/esm2020/src/app/shared/services/startable-service.class.mjs +105 -0
- package/esm2020/src/app/shared/services/storage/storage.service.mjs +132 -0
- package/esm2020/src/app/shared/services/storage/storage.utils.mjs +13 -0
- package/esm2020/src/app/shared/services/translate-context.service.mjs +81 -0
- package/esm2020/src/app/shared/services/validator-service.class.mjs +2 -0
- package/esm2020/src/app/shared/services.mjs +62 -0
- package/esm2020/src/app/shared/shared-routing.module.mjs +63 -0
- package/esm2020/src/app/shared/shared.module.mjs +208 -0
- package/esm2020/src/app/shared/shared.testing.module.mjs +76 -0
- package/esm2020/src/app/shared/testing/tests.page.mjs +33 -0
- package/esm2020/src/app/shared/toast/toast.testing.mjs +51 -0
- package/esm2020/src/app/shared/toast/toast.testing.module.mjs +45 -0
- package/esm2020/src/app/shared/toast/toasts.mjs +144 -0
- package/esm2020/src/app/shared/toolbar/modal-toolbar.mjs +58 -0
- package/esm2020/src/app/shared/toolbar/toolbar.mjs +226 -0
- package/esm2020/src/app/shared/toolbar/toolbar.module.mjs +53 -0
- package/{esm2015/src/app/shared/types.js → esm2020/src/app/shared/types.mjs} +0 -0
- package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.mjs +57 -0
- package/esm2020/src/app/shared/upload-file/testing/upload-file.testing.module.mjs +45 -0
- package/esm2020/src/app/shared/upload-file/upload-file-popover.component.mjs +97 -0
- package/esm2020/src/app/shared/upload-file/upload-file.component.mjs +204 -0
- package/esm2020/src/app/shared/upload-file/upload-file.model.mjs +20 -0
- package/esm2020/src/app/shared/validator/form-error-adapter.class.mjs +104 -0
- package/esm2020/src/app/shared/validator/validators.mjs +544 -0
- package/{esm2015/src/app/shared/version/versions.js → esm2020/src/app/shared/version/versions.mjs} +0 -0
- package/esm2020/src/app/social/job/job.model.mjs +26 -0
- package/esm2020/src/app/social/job/job.module.mjs +35 -0
- package/esm2020/src/app/social/job/job.service.mjs +71 -0
- package/esm2020/src/app/social/job/progression/job-progression.icon.mjs +210 -0
- package/esm2020/src/app/social/job/progression/job-progression.list.mjs +22 -0
- package/esm2020/src/app/social/job/testing/job-progression.testing.mjs +53 -0
- package/esm2020/src/app/social/job/testing/job-progression.testing.service.mjs +55 -0
- package/esm2020/src/app/social/job/testing/job.testing.module.mjs +35 -0
- package/esm2020/src/app/social/message/message.form.mjs +81 -0
- package/esm2020/src/app/social/message/message.modal.mjs +93 -0
- package/esm2020/src/app/social/message/message.model.mjs +65 -0
- package/esm2020/src/app/social/message/message.module.mjs +35 -0
- package/esm2020/src/app/social/message/message.service.mjs +84 -0
- package/{esm2015/src/app/social/social.errors.js → esm2020/src/app/social/social.errors.mjs} +0 -0
- package/esm2020/src/app/social/social.module.mjs +47 -0
- package/esm2020/src/app/social/social.testing.module.mjs +51 -0
- package/esm2020/src/app/social/user-event/notification/user-event-notification.icon.mjs +108 -0
- package/esm2020/src/app/social/user-event/notification/user-event-notification.list.mjs +212 -0
- package/esm2020/src/app/social/user-event/testing/user-event.testing.mjs +228 -0
- package/esm2020/src/app/social/user-event/testing/user-event.testing.model.mjs +107 -0
- package/esm2020/src/app/social/user-event/testing/user-event.testing.module.mjs +35 -0
- package/esm2020/src/app/social/user-event/testing/user-event.testing.service.mjs +111 -0
- package/esm2020/src/app/social/user-event/user-event.model.mjs +2 -0
- package/esm2020/src/app/social/user-event/user-event.module.mjs +39 -0
- package/esm2020/src/app/social/user-event/user-event.service.mjs +486 -0
- package/{esm2015/src/app/vendor.js → esm2020/src/app/vendor.mjs} +3 -3
- package/esm2020/src/environments/environment.class.mjs +5 -0
- package/esm2020/src/environments/environment.mjs +86 -0
- package/esm2020/sumaris-net.ngx-components.mjs +5 -0
- package/fesm2015/sumaris-net.ngx-components.mjs +33173 -0
- package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -0
- package/fesm2020/sumaris-net.ngx-components.mjs +32440 -0
- package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +27 -32
- package/public_api.d.ts +29 -31
- package/public_test_api.d.ts +37 -0
- package/resources/README.md +8 -0
- package/src/app/admin/admin-routing.module.d.ts +7 -0
- package/src/app/admin/admin.module.d.ts +7 -0
- package/src/app/admin/services/person.service.d.ts +3 -0
- package/src/app/admin/services/validator/person.validator.d.ts +8 -5
- package/src/app/admin/users/list/users.d.ts +11 -7
- package/src/app/admin/users/list/users.module.d.ts +14 -0
- package/src/app/core/about/modal-about.d.ts +3 -0
- package/src/app/core/account/account.d.ts +11 -8
- package/src/app/core/auth/form/form-auth.d.ts +6 -3
- package/src/app/core/auth/modal/modal-auth.d.ts +3 -0
- package/src/app/core/core.module.d.ts +36 -0
- package/src/app/core/core.testing.module.d.ts +10 -0
- package/src/app/core/form/editor.class.d.ts +6 -1
- package/src/app/core/form/entity-editor-modal.class.d.ts +7 -4
- package/src/app/core/form/entity-editor.class.d.ts +4 -1
- package/src/app/core/form/entity-metadata.component.d.ts +3 -0
- package/src/app/core/form/form-buttons-bar.component.d.ts +3 -0
- package/src/app/core/form/form.class.d.ts +12 -9
- package/src/app/core/form/form.utils.d.ts +5 -5
- package/src/app/core/form/list.form.d.ts +10 -7
- package/src/app/core/form/properties/properties.form.d.ts +43 -0
- package/src/app/core/form/properties/property.validator.d.ts +13 -0
- package/src/app/core/form/properties/testing/properties-form.test.d.ts +19 -0
- package/src/app/core/form/properties/testing/properties-form.testing.module.d.ts +12 -0
- package/src/app/core/graphql/graphql.module.d.ts +5 -0
- package/src/app/core/graphql/graphql.service.d.ts +9 -2
- package/src/app/core/graphql/graphql.utils.d.ts +8 -0
- package/src/app/core/home/home.d.ts +4 -1
- package/src/app/core/icon/icon.component.d.ts +5 -2
- package/src/app/core/icon/icon.module.d.ts +7 -0
- package/src/app/core/install/install-upgrade-card.component.d.ts +5 -2
- package/src/app/core/install/install-upgrade-card.module.d.ts +10 -0
- package/src/app/core/menu/menu.component.d.ts +7 -5
- package/src/app/core/menu/menu.module.d.ts +8 -0
- package/src/app/core/menu/menu.service.d.ts +3 -0
- package/src/app/core/offline/update-offline-mode-card.component.d.ts +3 -0
- package/src/app/core/peer/select-peer.modal.d.ts +7 -4
- package/src/app/core/peer/select-peer.module.d.ts +9 -0
- package/src/app/core/register/confirm/confirm.d.ts +3 -0
- package/src/app/core/register/form/form-register.d.ts +10 -7
- package/src/app/core/register/modal/modal-register.d.ts +3 -0
- package/src/app/core/register/register.module.d.ts +12 -0
- package/src/app/core/services/account.service.d.ts +5 -2
- package/src/app/core/services/auth-guard.service.d.ts +3 -0
- package/src/app/core/services/base-entity-service.class.d.ts +3 -0
- package/src/app/core/services/base-graphql-service.class.d.ts +3 -0
- package/src/app/core/services/config.service.d.ts +4 -1
- package/src/app/core/services/crypto.service.d.ts +3 -0
- package/src/app/core/services/local-settings.service.d.ts +5 -1
- package/src/app/core/services/model/referential.model.d.ts +1 -1
- package/src/app/core/services/network.service.d.ts +6 -5
- package/src/app/core/services/pipes/account.pipes.d.ts +7 -0
- package/src/app/core/services/pipes/department-to-string.pipe.d.ts +4 -0
- package/src/app/core/services/pipes/person-to-string.pipe.d.ts +4 -0
- package/src/app/core/services/pipes/usage-mode.pipes.d.ts +7 -0
- package/src/app/core/services/platform.service.d.ts +22 -21
- package/src/app/core/services/storage/entities-storage.service.d.ts +5 -2
- package/src/app/core/services/storage/entity-store.class.d.ts +3 -3
- package/src/app/core/services/testing/referential.validator.d.ts +8 -5
- package/src/app/core/services/validator/account.validator.d.ts +6 -3
- package/src/app/core/services/validator/base.validator.class.d.ts +8 -5
- package/src/app/core/services/validator/local-settings.validator.d.ts +8 -5
- package/src/app/core/services/validator/user-settings.validator.d.ts +6 -3
- package/src/app/core/settings/settings.page.d.ts +8 -5
- package/src/app/core/table/actions-column.component.d.ts +3 -0
- package/src/app/core/table/entities-table-datasource.class.d.ts +16 -15
- package/src/app/core/table/memory-table.class.d.ts +3 -0
- package/src/app/core/table/table-select-columns.component.d.ts +4 -5
- package/src/app/core/table/table.class.d.ts +52 -34
- package/src/app/core/table/table.utils.d.ts +2 -1
- package/src/app/core/table/testing/table.testing.d.ts +13 -15
- package/src/app/core/table/testing/table.testing.module.d.ts +9 -0
- package/src/app/core/text-popover/testing/text-popover.testing.d.ts +4 -1
- package/src/app/core/text-popover/testing/text-popover.testing.module.d.ts +9 -0
- package/src/app/core/text-popover/text-form.component.d.ts +7 -4
- package/src/app/core/text-popover/text-popover.component.d.ts +3 -0
- package/src/app/shared/alerts.d.ts +4 -4
- package/src/app/shared/audio/audio.d.ts +20 -11
- package/src/app/shared/audio/audio.testing.d.ts +13 -0
- package/src/app/shared/audio/audio.testing.module.d.ts +11 -0
- package/src/app/shared/capacitor/keyboard.d.ts +16 -0
- package/src/app/shared/capacitor/plugins.d.ts +7 -0
- package/src/app/shared/constants.d.ts +1 -0
- package/src/app/shared/debug/debug.component.d.ts +13 -0
- package/src/app/shared/debug/debug.module.d.ts +12 -0
- package/src/app/shared/directives/autofocus.directive.d.ts +9 -7
- package/src/app/shared/directives/autotitle.directive.d.ts +3 -0
- package/src/app/shared/directives/directives.module.d.ts +10 -0
- package/src/app/shared/directives/drag-and-drop.directive.d.ts +3 -0
- package/src/app/shared/directives/ng-var.directive.d.ts +3 -0
- package/src/app/shared/directives/resizable/resizable.component.d.ts +3 -0
- package/src/app/shared/directives/resizable/resizable.directive.d.ts +3 -0
- package/src/app/shared/directives/resizable/resizable.module.d.ts +6 -0
- package/src/app/shared/file/file.service.d.ts +3 -0
- package/src/app/shared/file/file.utils.d.ts +1 -1
- package/src/app/shared/form/field.component.d.ts +12 -3
- package/src/app/shared/form/field.model.d.ts +2 -2
- package/src/app/shared/form/loading-spinner.d.ts +3 -0
- package/src/app/shared/forms.d.ts +13 -13
- package/src/app/shared/gesture/gesture-config.d.ts +3 -0
- package/src/app/shared/gesture/hammer.utils.d.ts +11 -11
- package/src/app/shared/graph/graph-colors.d.ts +8 -7
- package/src/app/shared/guard/component-dirty.guard.d.ts +3 -0
- package/src/app/shared/help/help.modal.d.ts +4 -1
- package/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.d.ts +3 -0
- package/src/app/shared/hotkeys/hotkeys.service.d.ts +4 -1
- package/src/app/shared/hotkeys/shared-hotkeys.module.d.ts +9 -0
- package/src/app/shared/image/gallery/image-gallery.component.d.ts +77 -0
- package/src/app/shared/image/gallery/image-gallery.module.d.ts +12 -0
- package/src/app/shared/image/gallery/testing/gallegry.model.testing.d.ts +12 -0
- package/src/app/shared/image/gallery/testing/gallery.service.testing.d.ts +33 -0
- package/src/app/shared/image/gallery/testing/gallery.testing.d.ts +15 -0
- package/src/app/shared/image/gallery/testing/gallery.testing.module.d.ts +12 -0
- package/src/app/shared/image/image.model.d.ts +5 -0
- package/src/app/shared/image/image.module.d.ts +8 -0
- package/src/app/shared/image/image.service.d.ts +32 -0
- package/src/app/shared/inputs.d.ts +3 -3
- package/src/app/shared/material/autocomplete/material.autocomplete.config.d.ts +36 -0
- package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +11 -40
- package/src/app/shared/material/autocomplete/material.autocomplete.module.d.ts +19 -0
- package/src/app/shared/material/autocomplete/material.autocomplete.utils.d.ts +4 -0
- package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +12 -9
- package/src/app/shared/material/badge/badge.directive.d.ts +28 -0
- package/src/app/shared/material/badge/badge.module.d.ts +10 -0
- package/src/app/shared/material/badge/badge.test.d.ts +12 -0
- package/src/app/shared/material/boolean/boolean.module.d.ts +17 -0
- package/src/app/shared/material/boolean/material.boolean.d.ts +7 -4
- package/src/app/shared/material/chips/chips.module.d.ts +19 -0
- package/src/app/shared/material/chips/material.chips.d.ts +11 -8
- package/src/app/shared/material/chips/testing/chips.test.d.ts +8 -5
- package/src/app/shared/material/datetime/datetime.module.d.ts +22 -0
- package/src/app/shared/material/datetime/material.date.d.ts +19 -18
- package/src/app/shared/material/datetime/material.dateshort.d.ts +10 -9
- package/src/app/shared/material/datetime/material.datetime.d.ts +21 -20
- package/src/app/shared/material/datetime/testing/mat-date-time.test.d.ts +11 -9
- package/src/app/shared/material/datetime/testing/mat-date.test.d.ts +11 -9
- package/src/app/shared/material/duration/duration.module.d.ts +16 -0
- package/src/app/shared/material/duration/material.duration.d.ts +8 -5
- package/src/app/shared/material/latlong/material.latlong.d.ts +8 -5
- package/src/app/shared/material/latlong/material.latlong.module.d.ts +17 -0
- package/src/app/shared/material/latlong/testing/latlong.test.d.ts +10 -7
- package/src/app/shared/material/material.module.d.ts +43 -0
- package/src/app/shared/material/material.testing.module.d.ts +19 -0
- package/src/app/shared/material/numpad/numpad.append-to-input.directive.d.ts +3 -0
- package/src/app/shared/material/numpad/numpad.component.d.ts +4 -1
- package/src/app/shared/material/numpad/numpad.container.d.ts +5 -2
- package/src/app/shared/material/numpad/numpad.content.d.ts +3 -0
- package/src/app/shared/material/numpad/numpad.directive.d.ts +4 -1
- package/src/app/shared/material/numpad/numpad.dom-service.d.ts +3 -0
- package/src/app/shared/material/numpad/numpad.model.d.ts +1 -1
- package/src/app/shared/material/numpad/numpad.module.d.ts +14 -0
- package/src/app/shared/material/numpad/testing/numpad.test.d.ts +7 -4
- package/src/app/shared/material/paginator/material.paginator-i18n.d.ts +3 -0
- package/src/app/shared/material/stepper/material.stepper-i18n.d.ts +3 -0
- package/src/app/shared/material/swipe/material.swipe.d.ts +6 -3
- package/src/app/shared/material/swipe/swipe.module.d.ts +13 -0
- package/src/app/shared/material/swipe/testing/swipe.test.d.ts +7 -4
- package/src/app/shared/pipes/arrays.pipe.d.ts +17 -0
- package/src/app/shared/pipes/colors.pipe.d.ts +9 -0
- package/src/app/shared/pipes/date-diff-duration.pipe.d.ts +4 -0
- package/src/app/shared/pipes/date-format.pipe.d.ts +4 -0
- package/src/app/shared/pipes/date-from-now.pipe.d.ts +4 -0
- package/src/app/shared/pipes/duration.pipe.d.ts +4 -0
- package/src/app/shared/pipes/file-size.pipe.d.ts +3 -0
- package/src/app/shared/pipes/form.pipes.d.ts +18 -5
- package/src/app/shared/pipes/highlight.pipe.d.ts +4 -0
- package/src/app/shared/pipes/latlong-format.pipe.d.ts +7 -0
- package/src/app/shared/pipes/maps.pipe.d.ts +10 -0
- package/src/app/shared/pipes/math.pipes.d.ts +10 -0
- package/src/app/shared/pipes/ng-init.pipe.d.ts +3 -0
- package/src/app/shared/pipes/number-format.pipe.d.ts +4 -0
- package/src/app/shared/pipes/pipes.module.d.ts +24 -0
- package/src/app/shared/pipes/property.pipes.d.ts +6 -0
- package/src/app/shared/pipes/string.pipes.d.ts +11 -0
- package/src/app/shared/pipes/translate-context.pipe.d.ts +7 -0
- package/src/app/shared/platforms.d.ts +1 -0
- package/src/app/shared/services/memory-entity-service.class.d.ts +3 -0
- package/src/app/shared/services/progress-bar.service.d.ts +4 -1
- package/src/app/shared/services/startable-observable-service.class.d.ts +1 -1
- package/src/app/shared/services/startable-service.class.d.ts +1 -1
- package/src/app/shared/services/storage/storage.service.d.ts +23 -0
- package/src/app/shared/services/storage/storage.utils.d.ts +19 -0
- package/src/app/shared/services/translate-context.service.d.ts +3 -0
- package/src/app/shared/services/validator-service.class.d.ts +2 -2
- package/src/app/shared/shared-routing.module.d.ts +7 -0
- package/src/app/shared/shared.module.d.ts +23 -0
- package/src/app/shared/shared.testing.module.d.ts +12 -0
- package/src/app/shared/testing/tests.page.d.ts +3 -0
- package/src/app/shared/toast/toast.testing.d.ts +6 -5
- package/src/app/shared/toast/toast.testing.module.d.ts +9 -0
- package/src/app/shared/toast/toasts.d.ts +5 -2
- package/src/app/shared/toolbar/modal-toolbar.d.ts +5 -2
- package/src/app/shared/toolbar/toolbar.d.ts +9 -5
- package/src/app/shared/toolbar/toolbar.module.d.ts +15 -0
- package/src/app/shared/upload-file/testing/upload-file.testing.d.ts +4 -1
- package/src/app/shared/upload-file/testing/upload-file.testing.module.d.ts +9 -0
- package/src/app/shared/upload-file/upload-file-popover.component.d.ts +3 -0
- package/src/app/shared/upload-file/upload-file.component.d.ts +3 -0
- package/src/app/shared/validator/form-error-adapter.class.d.ts +3 -0
- package/src/app/shared/validator/validators.d.ts +9 -9
- package/src/app/social/job/job.module.d.ts +9 -0
- package/src/app/social/job/job.service.d.ts +3 -0
- package/src/app/social/job/progression/job-progression.icon.d.ts +4 -1
- package/src/app/social/job/progression/job-progression.list.d.ts +3 -0
- package/src/app/social/job/testing/job-progression.testing.d.ts +3 -0
- package/src/app/social/job/testing/job-progression.testing.service.d.ts +3 -0
- package/src/app/social/job/testing/job.testing.module.d.ts +9 -0
- package/src/app/social/message/message.form.d.ts +5 -2
- package/src/app/social/message/message.modal.d.ts +5 -2
- package/src/app/social/message/message.module.d.ts +9 -0
- package/src/app/social/message/message.service.d.ts +3 -0
- package/src/app/social/social.module.d.ts +10 -0
- package/src/app/social/social.testing.module.d.ts +9 -0
- package/src/app/social/user-event/notification/user-event-notification.icon.d.ts +4 -1
- package/src/app/social/user-event/notification/user-event-notification.list.d.ts +7 -4
- package/src/app/social/user-event/testing/user-event.testing.d.ts +3 -0
- package/src/app/social/user-event/testing/user-event.testing.model.d.ts +1 -0
- package/src/app/social/user-event/testing/user-event.testing.module.d.ts +9 -0
- package/src/app/social/user-event/testing/user-event.testing.service.d.ts +5 -1
- package/src/app/social/user-event/user-event.model.d.ts +3 -2
- package/src/app/social/user-event/user-event.module.d.ts +10 -0
- package/src/app/social/user-event/user-event.service.d.ts +16 -11
- package/src/assets/audio/beep-notification.mp3 +0 -0
- package/src/assets/i18n/fr.json +9 -2
- package/src/environments/environment.class.d.ts +2 -0
- package/src/environments/environment.d.ts +1 -1
- package/src/theme/_icons.scss +1 -1
- package/src/theme/_material.globals.scss +29 -31
- package/src/theme/_material.scss +32 -6
- package/src/theme/_mixins.scss +4 -4
- package/src/theme/_ngx-components.scss +27 -0
- package/src/theme/_print.scss +24 -0
- package/bundles/sumaris-net.ngx-components.umd.js +0 -35755
- package/bundles/sumaris-net.ngx-components.umd.js.map +0 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +0 -25
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +0 -1
- package/esm2015/public_api.js +0 -245
- package/esm2015/src/app/admin/admin-routing.module.js +0 -34
- package/esm2015/src/app/admin/admin.module.js +0 -34
- package/esm2015/src/app/admin/services/filter/person.filter.js +0 -59
- package/esm2015/src/app/admin/services/person.service.js +0 -175
- package/esm2015/src/app/admin/services/validator/person.validator.js +0 -37
- package/esm2015/src/app/admin/users/list/users.js +0 -216
- package/esm2015/src/app/core/about/modal-about.js +0 -63
- package/esm2015/src/app/core/account/account.js +0 -240
- package/esm2015/src/app/core/auth/form/form-auth.js +0 -134
- package/esm2015/src/app/core/auth/modal/modal-auth.js +0 -78
- package/esm2015/src/app/core/core.module.js +0 -127
- package/esm2015/src/app/core/core.testing.module.js +0 -51
- package/esm2015/src/app/core/form/editor.class.js +0 -698
- package/esm2015/src/app/core/form/entity-editor-modal.class.js +0 -422
- package/esm2015/src/app/core/form/entity-editor.class.js +0 -676
- package/esm2015/src/app/core/form/entity-metadata.component.js +0 -22
- package/esm2015/src/app/core/form/form-buttons-bar.component.js +0 -63
- package/esm2015/src/app/core/form/form.class.js +0 -342
- package/esm2015/src/app/core/form/form.utils.js +0 -299
- package/esm2015/src/app/core/form/list.form.js +0 -219
- package/esm2015/src/app/core/form/properties.form.js +0 -119
- package/esm2015/src/app/core/graphql/graphql.module.js +0 -18
- package/esm2015/src/app/core/graphql/graphql.service.js +0 -734
- package/esm2015/src/app/core/graphql/graphql.utils.js +0 -106
- package/esm2015/src/app/core/home/home.js +0 -265
- package/esm2015/src/app/core/icon/icon.component.js +0 -32
- package/esm2015/src/app/core/icon/icon.module.js +0 -26
- package/esm2015/src/app/core/install/install-upgrade-card.component.js +0 -358
- package/esm2015/src/app/core/menu/menu.component.js +0 -329
- package/esm2015/src/app/core/menu/menu.module.js +0 -28
- package/esm2015/src/app/core/offline/update-offline-mode-card.component.js +0 -26
- package/esm2015/src/app/core/peer/select-peer.modal.js +0 -134
- package/esm2015/src/app/core/register/confirm/confirm.js +0 -86
- package/esm2015/src/app/core/register/form/form-register.js +0 -172
- package/esm2015/src/app/core/register/modal/modal-register.js +0 -55
- package/esm2015/src/app/core/services/account.service.js +0 -1165
- package/esm2015/src/app/core/services/auth-guard.service.js +0 -77
- package/esm2015/src/app/core/services/base-entity-service.class.js +0 -454
- package/esm2015/src/app/core/services/base-graphql-service.class.js +0 -221
- package/esm2015/src/app/core/services/config.service.js +0 -385
- package/esm2015/src/app/core/services/local-settings.service.js +0 -460
- package/esm2015/src/app/core/services/model/account.model.js +0 -50
- package/esm2015/src/app/core/services/model/config.model.js +0 -89
- package/esm2015/src/app/core/services/model/department.model.js +0 -30
- package/esm2015/src/app/core/services/model/entity.decorators.js +0 -104
- package/esm2015/src/app/core/services/model/entity.model.js +0 -245
- package/esm2015/src/app/core/services/model/peer.model.js +0 -68
- package/esm2015/src/app/core/services/model/person.model.js +0 -83
- package/esm2015/src/app/core/services/model/referential.model.js +0 -147
- package/esm2015/src/app/core/services/model/settings.model.js +0 -75
- package/esm2015/src/app/core/services/network.service.js +0 -631
- package/esm2015/src/app/core/services/network.utils.js +0 -19
- package/esm2015/src/app/core/services/pipes/account.pipes.js +0 -28
- package/esm2015/src/app/core/services/pipes/department-to-string.pipe.js +0 -18
- package/esm2015/src/app/core/services/pipes/person-to-string.pipe.js +0 -18
- package/esm2015/src/app/core/services/pipes/usage-mode.pipes.js +0 -27
- package/esm2015/src/app/core/services/platform.service.js +0 -549
- package/esm2015/src/app/core/services/storage/entities-storage.service.js +0 -452
- package/esm2015/src/app/core/services/storage/entity-store.class.js +0 -461
- package/esm2015/src/app/core/services/testing/referential-filter.model.js +0 -23
- package/esm2015/src/app/core/services/testing/referential.validator.js +0 -44
- package/esm2015/src/app/core/services/validator/account.validator.js +0 -55
- package/esm2015/src/app/core/services/validator/base.validator.class.js +0 -48
- package/esm2015/src/app/core/services/validator/local-settings.validator.js +0 -72
- package/esm2015/src/app/core/services/validator/user-settings.validator.js +0 -30
- package/esm2015/src/app/core/settings/settings.page.js +0 -305
- package/esm2015/src/app/core/table/actions-column.component.js +0 -74
- package/esm2015/src/app/core/table/entities-table-datasource.class.js +0 -405
- package/esm2015/src/app/core/table/memory-table.class.js +0 -59
- package/esm2015/src/app/core/table/table-select-columns.component.js +0 -44
- package/esm2015/src/app/core/table/table.class.js +0 -1677
- package/esm2015/src/app/core/table/table.utils.js +0 -13
- package/esm2015/src/app/core/table/testing/table.testing.js +0 -242
- package/esm2015/src/app/core/table/testing/table.testing.module.js +0 -26
- package/esm2015/src/app/core/text-popover/testing/text-popover.testing.js +0 -37
- package/esm2015/src/app/core/text-popover/testing/text-popover.testing.module.js +0 -33
- package/esm2015/src/app/core/text-popover/text-form.component.js +0 -72
- package/esm2015/src/app/core/text-popover/text-popover.component.js +0 -90
- package/esm2015/src/app/shared/alerts.js +0 -251
- package/esm2015/src/app/shared/audio/audio.js +0 -178
- package/esm2015/src/app/shared/dates.js +0 -134
- package/esm2015/src/app/shared/directives/autofocus.directive.js +0 -90
- package/esm2015/src/app/shared/directives/autotitle.directive.js +0 -27
- package/esm2015/src/app/shared/directives/directives.module.js +0 -30
- package/esm2015/src/app/shared/directives/drag-and-drop.directive.js +0 -43
- package/esm2015/src/app/shared/directives/ng-var.directive.js +0 -32
- package/esm2015/src/app/shared/directives/resizable/resizable.component.js +0 -54
- package/esm2015/src/app/shared/directives/resizable/resizable.directive.js +0 -34
- package/esm2015/src/app/shared/directives/resizable/resizable.module.js +0 -12
- package/esm2015/src/app/shared/events.js +0 -61
- package/esm2015/src/app/shared/file/csv.utils.js +0 -70
- package/esm2015/src/app/shared/file/file.service.js +0 -120
- package/esm2015/src/app/shared/file/file.utils.js +0 -116
- package/esm2015/src/app/shared/file/images.utils.js +0 -166
- package/esm2015/src/app/shared/form/field.component.js +0 -206
- package/esm2015/src/app/shared/form/loading-spinner.js +0 -24
- package/esm2015/src/app/shared/forms.js +0 -358
- package/esm2015/src/app/shared/functions.js +0 -431
- package/esm2015/src/app/shared/gesture/hammer.utils.js +0 -2
- package/esm2015/src/app/shared/graph/graph-colors.js +0 -205
- package/esm2015/src/app/shared/guard/component-dirty.guard.js +0 -61
- package/esm2015/src/app/shared/help/help.modal.js +0 -56
- package/esm2015/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.js +0 -20
- package/esm2015/src/app/shared/hotkeys/hotkeys.service.js +0 -91
- package/esm2015/src/app/shared/hotkeys/shared-hotkeys.module.js +0 -29
- package/esm2015/src/app/shared/http/http.utils.js +0 -57
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +0 -825
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.module.js +0 -46
- package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +0 -200
- package/esm2015/src/app/shared/material/badge/badge-icon.directive.js +0 -135
- package/esm2015/src/app/shared/material/badge/badge-icon.module.js +0 -23
- package/esm2015/src/app/shared/material/badge/badge-icon.test.js +0 -17
- package/esm2015/src/app/shared/material/boolean/boolean.module.js +0 -41
- package/esm2015/src/app/shared/material/boolean/material.boolean.js +0 -223
- package/esm2015/src/app/shared/material/chips/chips.module.js +0 -45
- package/esm2015/src/app/shared/material/chips/material.chips.js +0 -636
- package/esm2015/src/app/shared/material/chips/testing/chips.test.js +0 -138
- package/esm2015/src/app/shared/material/datetime/datetime.module.js +0 -54
- package/esm2015/src/app/shared/material/datetime/material.date.js +0 -375
- package/esm2015/src/app/shared/material/datetime/material.dateshort.js +0 -316
- package/esm2015/src/app/shared/material/datetime/material.datetime.js +0 -398
- package/esm2015/src/app/shared/material/datetime/testing/mat-date-time.test.js +0 -110
- package/esm2015/src/app/shared/material/datetime/testing/mat-date.test.js +0 -108
- package/esm2015/src/app/shared/material/duration/duration.module.js +0 -40
- package/esm2015/src/app/shared/material/duration/material.duration.js +0 -246
- package/esm2015/src/app/shared/material/latlong/latlong.utils.js +0 -249
- package/esm2015/src/app/shared/material/latlong/material.latlong.js +0 -350
- package/esm2015/src/app/shared/material/latlong/material.latlong.module.js +0 -41
- package/esm2015/src/app/shared/material/latlong/testing/latlong.test.js +0 -70
- package/esm2015/src/app/shared/material/material.module.js +0 -93
- package/esm2015/src/app/shared/material/material.testing.module.js +0 -111
- package/esm2015/src/app/shared/material/numpad/numpad.append-to-input.directive.js +0 -96
- package/esm2015/src/app/shared/material/numpad/numpad.component.js +0 -73
- package/esm2015/src/app/shared/material/numpad/numpad.container.js +0 -149
- package/esm2015/src/app/shared/material/numpad/numpad.content.js +0 -14
- package/esm2015/src/app/shared/material/numpad/numpad.directive.js +0 -148
- package/esm2015/src/app/shared/material/numpad/numpad.dom-service.js +0 -37
- package/esm2015/src/app/shared/material/numpad/numpad.module.js +0 -39
- package/esm2015/src/app/shared/material/numpad/testing/numpad.test.js +0 -44
- package/esm2015/src/app/shared/material/paginator/material.paginator-i18n.js +0 -44
- package/esm2015/src/app/shared/material/stepper/material.stepper-i18n.js +0 -24
- package/esm2015/src/app/shared/material/swipe/material.swipe.js +0 -308
- package/esm2015/src/app/shared/material/swipe/swipe.module.js +0 -33
- package/esm2015/src/app/shared/material/swipe/testing/swipe.test.js +0 -68
- package/esm2015/src/app/shared/observables.js +0 -99
- package/esm2015/src/app/shared/pipes/arrays.pipe.js +0 -110
- package/esm2015/src/app/shared/pipes/date-diff-duration.pipe.js +0 -50
- package/esm2015/src/app/shared/pipes/date-format.pipe.js +0 -43
- package/esm2015/src/app/shared/pipes/file-size.pipe.js +0 -58
- package/esm2015/src/app/shared/pipes/form.pipes.js +0 -177
- package/esm2015/src/app/shared/pipes/highlight.pipe.js +0 -43
- package/esm2015/src/app/shared/pipes/latlong-format.pipe.js +0 -36
- package/esm2015/src/app/shared/pipes/maps.pipe.js +0 -48
- package/esm2015/src/app/shared/pipes/math.pipes.js +0 -44
- package/esm2015/src/app/shared/pipes/ng-init.pipe.js +0 -18
- package/esm2015/src/app/shared/pipes/pipes.module.js +0 -117
- package/esm2015/src/app/shared/pipes/property.pipes.js +0 -98
- package/esm2015/src/app/shared/pipes/string.pipes.js +0 -53
- package/esm2015/src/app/shared/pipes/translate-context.pipe.js +0 -36
- package/esm2015/src/app/shared/platforms.js +0 -45
- package/esm2015/src/app/shared/services/entity-service.class.js +0 -8
- package/esm2015/src/app/shared/services/job.utils.js +0 -96
- package/esm2015/src/app/shared/services/memory-entity-service.class.js +0 -342
- package/esm2015/src/app/shared/services/progress-bar.service.js +0 -30
- package/esm2015/src/app/shared/services/startable-observable-service.class.js +0 -124
- package/esm2015/src/app/shared/services/startable-service.class.js +0 -110
- package/esm2015/src/app/shared/services/storage.utils.js +0 -41
- package/esm2015/src/app/shared/services/translate-context.service.js +0 -83
- package/esm2015/src/app/shared/services/validator-service.class.js +0 -2
- package/esm2015/src/app/shared/services.js +0 -61
- package/esm2015/src/app/shared/shared-routing.module.js +0 -54
- package/esm2015/src/app/shared/shared.module.js +0 -135
- package/esm2015/src/app/shared/shared.testing.module.js +0 -33
- package/esm2015/src/app/shared/testing/tests.page.js +0 -34
- package/esm2015/src/app/shared/toast/toast.testing.js +0 -39
- package/esm2015/src/app/shared/toast/toast.testing.module.js +0 -33
- package/esm2015/src/app/shared/toast/toasts.js +0 -119
- package/esm2015/src/app/shared/toolbar/modal-toolbar.js +0 -53
- package/esm2015/src/app/shared/toolbar/toolbar.js +0 -213
- package/esm2015/src/app/shared/upload-file/testing/upload-file.testing.js +0 -59
- package/esm2015/src/app/shared/upload-file/testing/upload-file.testing.module.js +0 -33
- package/esm2015/src/app/shared/upload-file/upload-file-popover.component.js +0 -98
- package/esm2015/src/app/shared/upload-file/upload-file.component.js +0 -202
- package/esm2015/src/app/shared/upload-file/upload-file.model.js +0 -20
- package/esm2015/src/app/shared/validator/form-error-adapter.class.js +0 -99
- package/esm2015/src/app/shared/validator/validators.js +0 -537
- package/esm2015/src/app/social/job/job.model.js +0 -26
- package/esm2015/src/app/social/job/job.module.js +0 -25
- package/esm2015/src/app/social/job/job.service.js +0 -66
- package/esm2015/src/app/social/job/progression/job-progression.icon.js +0 -208
- package/esm2015/src/app/social/job/progression/job-progression.list.js +0 -20
- package/esm2015/src/app/social/job/testing/job-progression.testing.js +0 -49
- package/esm2015/src/app/social/job/testing/job-progression.testing.service.js +0 -52
- package/esm2015/src/app/social/job/testing/job.testing.module.js +0 -25
- package/esm2015/src/app/social/message/message.form.js +0 -73
- package/esm2015/src/app/social/message/message.modal.js +0 -96
- package/esm2015/src/app/social/message/message.model.js +0 -65
- package/esm2015/src/app/social/message/message.module.js +0 -25
- package/esm2015/src/app/social/message/message.service.js +0 -87
- package/esm2015/src/app/social/social.module.js +0 -28
- package/esm2015/src/app/social/social.testing.module.js +0 -39
- package/esm2015/src/app/social/user-event/notification/user-event-notification.icon.js +0 -106
- package/esm2015/src/app/social/user-event/notification/user-event-notification.list.js +0 -203
- package/esm2015/src/app/social/user-event/testing/user-event.testing.js +0 -230
- package/esm2015/src/app/social/user-event/testing/user-event.testing.model.js +0 -103
- package/esm2015/src/app/social/user-event/testing/user-event.testing.module.js +0 -25
- package/esm2015/src/app/social/user-event/testing/user-event.testing.service.js +0 -117
- package/esm2015/src/app/social/user-event/user-event.model.js +0 -2
- package/esm2015/src/app/social/user-event/user-event.module.js +0 -27
- package/esm2015/src/app/social/user-event/user-event.service.js +0 -509
- package/esm2015/src/environments/environment.class.js +0 -5
- package/esm2015/src/environments/environment.js +0 -81
- package/esm2015/sumaris-net.ngx-components.js +0 -21
- package/fesm2015/sumaris-net.ngx-components.js +0 -30297
- package/fesm2015/sumaris-net.ngx-components.js.map +0 -1
- package/src/app/core/form/properties.form.d.ts +0 -40
- package/src/app/shared/material/badge/badge-icon.directive.d.ts +0 -28
- package/src/app/shared/material/badge/badge-icon.module.d.ts +0 -2
- package/src/app/shared/material/badge/badge-icon.test.d.ts +0 -9
- package/src/app/shared/services/storage.utils.d.ts +0 -13
- package/sumaris-net.ngx-components.d.ts +0 -20
- package/sumaris-net.ngx-components.metadata.json +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/environments/environment.class.ts","../../src/app/shared/constants.ts","../../node_modules/tslib/tslib.es6.js","../../src/app/shared/functions.ts","../../src/app/shared/focusable.ts","../../src/app/shared/inputs.ts","../../src/app/shared/observables.ts","../../src/app/shared/events.ts","../../src/app/shared/material/material.animations.ts","../../src/app/shared/platforms.ts","../../src/app/shared/services.ts","../../src/app/shared/material/autocomplete/material.autocomplete.ts","../../src/app/shared/pipes/date-format.pipe.ts","../../src/app/shared/pipes/date-diff-duration.pipe.ts","../../src/app/shared/pipes/date-from-now.pipe.ts","../../src/app/shared/material/latlong/latlong.utils.ts","../../src/app/shared/pipes/latlong-format.pipe.ts","../../src/app/shared/pipes/number-format.pipe.ts","../../src/app/shared/pipes/highlight.pipe.ts","../../src/app/shared/pipes/file-size.pipe.ts","../../src/app/shared/dates.ts","../../src/app/shared/pipes/duration.pipe.ts","../../src/app/shared/pipes/math.pipes.ts","../../src/app/shared/pipes/arrays.pipe.ts","../../src/app/shared/pipes/maps.pipe.ts","../../src/app/shared/pipes/string.pipes.ts","../../src/app/shared/services/translate-context.service.ts","../../src/app/shared/pipes/translate-context.pipe.ts","../../src/app/shared/pipes/ng-init.pipe.ts","../../src/app/shared/validator/validators.ts","../../src/app/shared/forms.ts","../../src/app/core/form/form.utils.ts","../../src/app/shared/validator/form-error-adapter.class.ts","../../src/app/shared/pipes/form.pipes.ts","../../src/app/shared/pipes/property.pipes.ts","../../src/app/shared/pipes/pipes.module.ts","../../src/app/shared/directives/autofocus.directive.ts","../../src/app/shared/directives/ng-var.directive.ts","../../src/app/shared/directives/drag-and-drop.directive.ts","../../src/app/shared/directives/autotitle.directive.ts","../../src/app/shared/directives/directives.module.ts","../../src/app/shared/material/autocomplete/material.autocomplete.module.ts","../../src/app/shared/material/duration/duration.utils.ts","../../src/app/shared/material/latlong/material.latlong.ts","../../src/app/shared/material/latlong/material.latlong.module.ts","../../src/app/shared/material/datetime/material.date.ts","../../src/app/shared/material/datetime/material.datetime.ts","../../src/app/shared/material/datetime/material.dateshort.ts","../../src/app/shared/material/datetime/datetime.module.ts","../../src/app/shared/material/duration/material.duration.ts","../../src/app/shared/material/duration/duration.module.ts","../../src/app/shared/material/boolean/material.boolean.ts","../../src/app/shared/material/boolean/boolean.module.ts","../../src/app/shared/material/numpad/numpad.model.ts","../../src/app/shared/material/numpad/numpad.container.ts","../../src/app/shared/material/numpad/numpad.dom-service.ts","../../src/app/shared/material/numpad/numpad.component.ts","../../src/app/shared/material/numpad/numpad.directive.ts","../../src/app/shared/material/numpad/numpad.content.ts","../../src/app/shared/material/numpad/numpad.append-to-input.directive.ts","../../src/app/shared/material/numpad/numpad.module.ts","../../src/app/shared/material/swipe/material.swipe.ts","../../src/app/shared/material/swipe/swipe.module.ts","../../src/app/shared/material/chips/material.chips.ts","../../src/app/shared/material/chips/chips.module.ts","../../src/app/shared/material/badge/badge-icon.directive.ts","../../src/app/shared/material/badge/badge-icon.module.ts","../../src/app/shared/material/material.module.ts","../../src/app/shared/services/progress-bar.service.ts","../../src/app/shared/gesture/gesture-config.ts","../../src/app/shared/toolbar/toolbar.ts","../../src/app/shared/material/paginator/material.paginator-i18n.ts","../../src/app/shared/interceptors/progess.interceptor.ts","../../src/app/shared/graph/colors.utils.ts","../../src/app/shared/form/field.component.ts","../../src/app/shared/services/startable-service.class.ts","../../src/app/shared/audio/audio.ts","../../src/app/shared/hotkeys/dialog/hotkeys-dialog.component.ts","../../src/app/shared/hotkeys/hotkeys.service.ts","../../src/app/shared/hotkeys/shared-hotkeys.module.ts","../../src/app/shared/upload-file/upload-file.model.ts","../../src/app/shared/file/images.utils.ts","../../src/app/vendor.ts","../../src/app/shared/file/file.service.ts","../../src/app/shared/toolbar/modal-toolbar.ts","../../src/app/shared/form/loading-spinner.ts","../../src/app/core/services/base58.ts","../../src/app/core/services/crypto.service.ts","../../src/app/core/services/model/entity.model.ts","../../src/environments/environment.ts","../../src/app/core/services/model/entity.decorators.ts","../../src/app/core/services/model/peer.model.ts","../../src/app/shared/http/http.utils.ts","../../src/app/core/services/network.utils.ts","../../src/app/shared/version/versions.ts","../../src/app/core/peer/select-peer.modal.ts","../../src/app/core/services/local-settings.service.ts","../../src/app/shared/toast/toasts.ts","../../src/app/shared/services/startable-observable-service.class.ts","../../src/app/core/services/network.service.ts","../../src/app/core/services/errors.ts","../../src/app/core/services/storage/entity-store.class.ts","../../src/app/core/services/storage/entities-storage.service.ts","../../src/app/shared/services/storage.utils.ts","../../src/app/core/services/model/settings.model.ts","../../src/app/core/services/model/model.enum.ts","../../src/app/core/services/model/referential.model.ts","../../src/app/core/services/model/department.model.ts","../../src/app/core/services/model/person.model.ts","../../src/app/core/services/model/account.model.ts","../../src/app/core/graphql/graphql.utils.ts","../../src/app/core/graphql/graphql.service.ts","../../src/app/core/services/base-graphql-service.class.ts","../../src/app/core/services/account.service.ts","../../src/app/core/services/model/config.model.ts","../../src/app/core/services/config/core.config.ts","../../src/app/core/services/config.service.ts","../../src/app/shared/upload-file/upload-file-popover.component.ts","../../src/app/shared/file/file.utils.ts","../../src/app/shared/file/uri.utils.ts","../../src/app/core/services/platform.service.ts","../../src/app/shared/help/help.modal.ts","../../src/app/shared/material/stepper/material.stepper-i18n.ts","../../src/app/shared/upload-file/upload-file.component.ts","../../src/app/shared/testing/tests.page.ts","../../src/app/shared/shared.module.ts","../../src/app/shared/alerts.ts","../../src/app/shared/guard/component-dirty.guard.ts","../../src/app/shared/shared-routing.module.ts","../../src/app/shared/form/field.model.ts","../../src/app/core/form/form.class.ts","../../src/app/core/text-popover/text-form.component.ts","../../src/app/core/text-popover/text-popover.component.ts","../../src/app/shared/directives/resizable/resizable.directive.ts","../../src/app/shared/directives/resizable/resizable.component.ts","../../src/app/shared/directives/resizable/resizable.module.ts","../../src/app/core/services/model/filter.model.ts","../../src/app/shared/services/memory-entity-service.class.ts","../../src/app/shared/services/job.utils.ts","../../src/app/shared/file/csv.utils.ts","../../src/app/shared/graph/graph-colors.ts","../../src/app/core/register/modal/modal-register.ts","../../src/app/core/auth/form/form-auth.ts","../../src/app/core/auth/modal/modal-auth.ts","../../src/app/core/about/modal-about.ts","../../src/app/core/menu/menu.model.ts","../../src/app/core/home/home.ts","../../src/app/core/register/confirm/confirm.ts","../../src/app/core/services/validator/base.validator.class.ts","../../src/app/core/services/validator/user-settings.validator.ts","../../src/app/core/services/validator/account.validator.ts","../../src/app/core/account/account.ts","../../src/app/core/form/entity-metadata.component.ts","../../src/app/core/menu/menu.service.ts","../../src/app/core/form/form-buttons-bar.component.ts","../../src/app/core/table/table-select-columns.component.ts","../../src/app/core/register/form/form-register.ts","../../src/app/core/graphql/graphql.module.ts","../../src/app/core/services/validator/local-settings.validator.ts","../../src/app/core/settings/settings.page.ts","../../src/app/core/form/properties.form.ts","../../src/app/core/form/list.form.ts","../../src/app/core/services/pipes/usage-mode.pipes.ts","../../src/app/core/services/pipes/person-to-string.pipe.ts","../../src/app/core/install/install-upgrade-card.component.ts","../../src/app/core/services/pipes/account.pipes.ts","../../src/app/core/services/pipes/department-to-string.pipe.ts","../../src/app/core/table/actions-column.component.ts","../../src/app/core/menu/menu.component.ts","../../src/app/core/menu/menu.module.ts","../../src/app/core/offline/update-offline-mode-card.component.ts","../../src/app/core/icon/icon.component.ts","../../src/app/core/icon/icon.module.ts","../../src/app/core/core.module.ts","../../src/app/core/services/auth-guard.service.ts","../../src/app/core/services/base-entity-service.class.ts","../../src/app/core/table/table.utils.ts","../../src/app/core/table/entities-table-datasource.class.ts","../../src/app/core/table/table.class.ts","../../src/app/core/form/editor.class.ts","../../src/app/core/form/entity-editor.class.ts","../../src/app/core/form/entity-editor-modal.class.ts","../../src/app/core/table/memory-table.class.ts","../../src/app/social/social.errors.ts","../../src/app/social/user-event/user-event.service.ts","../../src/app/social/user-event/notification/user-event-notification.list.ts","../../src/app/social/user-event/notification/user-event-notification.icon.ts","../../src/app/social/user-event/user-event.module.ts","../../src/app/social/message/message.model.ts","../../src/app/social/message/message.modal.ts","../../src/app/social/message/message.form.ts","../../src/app/social/message/message.module.ts","../../src/app/social/job/job.model.ts","../../src/app/social/job/job.service.ts","../../src/app/social/job/progression/job-progression.list.ts","../../src/app/social/job/progression/job-progression.icon.ts","../../src/app/social/job/job.module.ts","../../src/app/social/social.module.ts","../../src/app/social/message/message.service.ts","../../src/app/admin/services/filter/person.filter.ts","../../src/app/admin/services/person.service.ts","../../src/app/admin/services/validator/person.validator.ts","../../src/app/admin/users/list/users.ts","../../src/app/admin/admin.module.ts","../../src/app/admin/admin-routing.module.ts","../../src/app/shared/material/autocomplete/testing/autocomplete.test.ts","../../src/app/shared/material/latlong/testing/latlong.test.ts","../../src/app/shared/material/swipe/testing/swipe.test.ts","../../src/app/shared/material/datetime/testing/mat-date-time.test.ts","../../src/app/shared/material/chips/testing/chips.test.ts","../../src/app/shared/material/badge/badge-icon.test.ts","../../src/app/shared/material/numpad/testing/numpad.test.ts","../../src/app/shared/material/datetime/testing/mat-date.test.ts","../../src/app/shared/material/material.testing.module.ts","../../src/app/shared/toast/toast.testing.ts","../../src/app/shared/toast/toast.testing.module.ts","../../src/app/shared/upload-file/testing/upload-file.testing.ts","../../src/app/shared/upload-file/testing/upload-file.testing.module.ts","../../src/app/shared/shared.testing.module.ts","../../src/app/core/services/testing/referential-filter.model.ts","../../src/app/core/services/testing/referential.validator.ts","../../src/app/core/table/testing/table.testing.ts","../../src/app/core/table/testing/table.testing.module.ts","../../src/app/core/text-popover/testing/text-popover.testing.ts","../../src/app/core/text-popover/testing/text-popover.testing.module.ts","../../src/app/core/core.testing.module.ts","../../src/app/social/job/testing/job-progression.testing.ts","../../src/app/social/job/testing/job.testing.module.ts","../../src/app/social/user-event/testing/user-event.testing.model.ts","../../src/app/social/user-event/testing/user-event.testing.service.ts","../../src/app/social/user-event/testing/user-event.testing.ts","../../src/app/social/user-event/testing/user-event.testing.module.ts","../../src/app/social/social.testing.module.ts","../../src/app/social/job/testing/job-progression.testing.service.ts","../../src/app/shared/services/entity-service.class.ts"],"names":["ENVIRONMENT","InjectionToken","DATE_ISO_PATTERN","DATE_PATTERN","DEFAULT_PLACEHOLDER_CHAR","PUBKEY_REGEXP","KEYBOARD_HIDE_DELAY_MS","extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","TypeError","String","__","this","constructor","create","__decorate","decorators","target","key","desc","c","arguments","length","r","getOwnPropertyDescriptor","Reflect","decorate","i","defineProperty","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__generator","body","f","y","t","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","n","v","op","pop","push","__values","o","s","m","__read","ar","error","__spread","concat","__makeTemplateObject","cooked","raw","isNil","obj","isNilOrBlank","trim","isNotNil","isNotNilOrBlank","isNotNilOrNaN","isNaN","isNilOrNaN","isNotEmptyArray","isEmptyArray","isNotNilBoolean","isNotNilString","isBlankString","arraySize","nullIfUndefined","undefined","toBoolean","defaultValue","toNumber","removeDuplicatesFromArray","property","filter","item","array","findIndex","startsWithUpperCase","input","search","toUpperCase","startsWith","matchUpperCase","regexp","match","noTrailingSlash","path","lastIndexOf","substring","removeEnd","end","endsWith","substr","changeCaseToUnderscore","replace","toLowerCase","removeDiacritics","text","normalize","joinPropertiesPath","properties","separator","Error","map","getPropertyByPath","join","propertiesPathComparator","keys","defaultValues","a","index","valueA","valueB","find","res","INTEGER_REGEXP","isInt","test","NUMBER_REGEXP","NUMBER_RANGE_REGEXP","isArray","indexOf","getProperty","getPropertyByPathAsString","sleep","ms","setTimeout","round","Math","Number","EPSILON","capitalizeFirstLetter","splitById","reduce","equals","o1","o2","keySet","t1","Beans","copy","source","dataType","forEach","isEmpty","data","opts","blankStringLikeEmpty","collectById","collectByProperty","propertyName","isFocusableElement","object","selectInputContent","event","defaultPrevented","selectRange","err","console","select","selectInputRange","startIndex","endIndex","setSelectionRange","getCaretPosition","selectionStart","selectionDirection","selectionEnd","moveInputCaretToSeparator","forward","caretPosition","separatorIndex","preventDefault","stopPropagation","filterNumberInput","allowDecimals","decimalSeparator","which","keyCode","focusInput","element","inputElement","asInputElement","focus","warn","setTabIndex","tabIndex","isInputElement","tabindex","nativeElement","tabindexComparator","canHaveFocus","disabled","hidden","minTabindex","maxTabindex","excludeEmptyInput","getFocusableInputElements","elements","assign","sortByTabIndex","filteredElements","included","debug","sort","decorateForFirst","obs","takeUntil$","stop","timeout","timer","stopError","merge","pipe","takeUntil","firstNotNil","first","firstTrue","firstFalse","firstFalsePromise","toPromise","firstNotNilPromise","chainPromises","defers","previous","defer","finalResult","jobRes","waitFor","predicate","period","checkPeriod","dueTime","_a","waitForTrue","observable","switchMap","waitForFalse","createPromiseEventEmitter","EventEmitter","createPromiseEvent","eventType","promise","initArg","detail","CustomEvent","emitPromiseEvent","emitter","success","emit","fromScrollEndEvent","threshold","isEnd","thresholdRatio_1","parseInt","slice","scrollTop","offsetHeight","scrollHeight","thresholdPx_1","fromEvent","fadeInAnimation","trigger","transition","style","opacity","animate","fadeInOutAnimation","slideInOutAnimation","state","position","top","left","right","bottom","slideUpDownAnimation","transform","_cache","mobile","cordova","matchMedia","win","query","matches","testUserAgent","expr","userAgent","navigator","vendor","window","opera","isWindows","isTouchUi","isIpad","isIOS","isAndroid","isCordova","isMobile","suggestFromArray","items","_this","searchAttribute","searchAttributes","total","filteredItems","excludedIds","includes","skipSort","pageData","offset","size","nextOffset","fetchMore","MatAutocompleteConfigHolder","options","fields","getUserAttributes","fieldName","defaultAttributes","add","suggestFn","service","suggest","attributes","attributesOrFn","displayWith","MatAutocompleteFieldUtils","createDisplayFn","multiple","defaultEquals","config","get","displayAttributes","id","noop","MatAutocompleteField","cd","formGroupDir","_onChangeCallback","_onTouchedCallback","logPrefix","formControlName","required","clearable","debounceTime","i18nPrefix","noResultMessage","itemSize","fetchMoreThreshold","suggestLengthThreshold","showLoadingSpinner","showSearchBar","stickySearchBar","clicked","blurred","focused","dropButtonClick","keydownEscape","keyupEnter","_readonly","$inputItems","BehaviorSubject","$filteredItems","displayValue","_fetchMore$","_subscription","Subscription","_$filter","_reload$","Subject","_itemCount","_onFetchMoreCallback","_moreItemsCount","markForCheck","_tabindex","_itemsSubscription","remove","unsubscribe","isObservable","subscribe","formControl","enabled","ngOnInit","form","displayColumnSizes","columnSizes","displayColumnNames","columnNames","showAllOnFocus","showPanelOnFocus","classList","class","highlightAccent","validator","Validators","attr","_b","split","panelWidth","matAutocompletePosition","suggestFromArrayFn_1","_e","thresholdFilterFn","filteredItemsChanges","tap","markAsLoading","valueChanges","startWith","matInputText","loading","distinctUntilChanged","v1","v2","mergeMap","updateImplicitValue","fetchMoreItemsChanges","canFetchMore","moreItems","value_1","_implicitValue","writeValue","markAsPending","emitEvent","onlySelf","updateValueAndValidity","checkIfTouched","closePanel","statusChanges","isOpen","ngOnDestroy","_openedSubscription","complete","autocomplete","reloadItems","matSelect","panelOpen","ionSearchbar","patchValue","registerOnChange","fn","registerOnTouched","setDisabledState","isDisabled","filterInputTextFocusEvent","relatedTarget","HTMLElement","tagName","returnValue","filterInputTextBlurEvent","ionSearchBarChanged","filterMatSelectFocusEvent","filterMatSelectBlurEvent","contains","clearValue","_initAutocompleteInfiniteScroll","scrollEnd$","_isOpen","opened","getAutocompletePanel","panel","closed","_initMatSelectInfiniteScroll","_openedStream","getMatSelectPanel","_closedStream","autocompleteTrigger","_c","_d","close","fetchMoreFn","_f","max","touched","ele","last","_getHostElement","parentElement","Component","args","selector","template","providers","provide","NG_VALUE_ACCESSOR","multi","useExisting","forwardRef","animations","changeDetection","ChangeDetectionStrategy","OnPush","ChangeDetectorRef","FormGroupDirective","type","Optional","Input","Output","ViewChild","MatAutocomplete","MatAutocompleteTrigger","DateFormatPipe","dateAdapter","translate","translations","instant","datePattern","dateTimePattern","dateTimeSecondsPattern","pattern","time","seconds","date","isMoment","parse","format","parseFormat","Pipe","name","Injectable","providedIn","MomentDateAdapter","TranslateService","moment","momentImported","DateDiffDurationPipe","dayUnit","startValue","endValue","startDate","endDate","duration","diff","asMinutes","withSeconds","timeDuration","hour","hours","minute","minutes","second","days","floor","asDays","toString","DateAdapter","DateFromNowPipe","fromNow","withoutSuffix","LAT_LONG_PATTERNS","DEFAULT_OPTIONS","maxDecimals","placeholderChar","DEFAULT_LATITUDE_OPTIONS","longitude","DEFAULT_LONGITUDE_OPTIONS","formatLatitude","formatToDDMMSS","formatToDDMM","formatToDD","formatLongitude","negative","degrees","roundFloat","sign","integerLength","hideSign","trunc","prefix","parseLatitudeOrLongitude","parts","RegExp","parseFloat","NaN","direction","powDecimal","pow","LatLongFormatPipe","NumberFormatPipe","val","fixedDecimals","toFixed","toLocaleString","HighlightPipe","searchText","withAccent","searchRegexp","cleanedSearchText","FileSizePipe","units","bytes","precision","isFinite","unit","MOMENT_NO_TIME_PROPERTY","DateUtils","min","date1","date2","isSameOrBefore","isSameOrAfter","isSame","granularity","d1","fromDateISOString","d2","resetTime","timezone","keepLocalTime","clone","tz","startOf","markNoTime","isNoTime","isAtDay","weekday","day","toDateISOString","toISOString","dateOnly","isValid","fromUnixMsTimestamp","timeInMs","toDuration","milliseconds","DurationPipe","padStart","MathAbsPipe","abs","EvenPipe","OddPipe","NotEmptyArrayPipe","EmptyArrayPipe","ArrayLengthPipe","lessThan","greaterThan","ArrayFirstPipe","ArrayPluckPipe","values","ArrayIncludesPipe","ArrayFilterPipe","filterFn","ArrayJoinPipe","MapGetPipe","MapKeysPipe","MapValuesPipe","IsNotNilOrBlankPipe","IsNilOrBlankPipe","ToStringPipe","StrLengthPipe","StrIncludesPipe","searchString","TranslateContextService","context","interpolateParams","contextualKeys","findFirstValid","inheritedContext","reverse","contextItem","contextualKey","keys_1","keys_1_1","TranslateContextPipe","TranslatablePipe","NgInitDirective","ngInit","Directive","SharedValidators","getDoubleRegexp","_DOUBLE_REGEXP_CACHE","NO_LIMIT","latitude","control","entity","empty","pubkey","integer","decimal","validDate","year","dateIsAfter","previousValue","errorParam","minDate","dateIsBefore","maxValue","maxDate","dateRangeEnd","startDateFieldName","msg","errorCode","dateRange","parent","startControl","clearError","dateRangeStart","endDateFieldName","endDateControl","copyParentErrors","errorNames","errors","hasError","getOwnPropertyNames","setErrors","1","2","3","I18N_ERROR_KEYS","minlength","maxlength","dateMinDuration","dateMaxDuration","double","email","unique","SharedFormGroupValidators","startDateField","endDateField","rangeError","group","endField","isAfter","maxDuration","durationUnit","maxDurationError","markAsTouched","minDuration","endFieldErrors","requiredIf","anotherFieldToCheck","anotherControl","AbstractControl","requiredIfTrue","requiredIfEmpty","propagateIfDirty","fieldNameToPropagate","valueToPropagate","controlToPropagate","dirty","setValue","validators","SharedFormArrayValidators","uniqueEntity","controlName","controls","fromGroup","occurrences_1","acc","error_1","returnError_1","requiredArrayMinLength","minLength","validSumMaxValue","sum","error_2","sumMaxValue","SharedAsyncValidators","validatorFn","DEBOUNCE_TIME_VALIDATOR_ID","$disposeSubject","disposeEvent$","dispose","now","Date","from","of","catchError","registerAsyncValidator","asyncValidator","$dispose","asyncValidatorFn","setAsyncValidators","subscription","clearAsyncValidators","copyEntity2Form","json","getFormValueFromEntity","adaptValueToControl","pathPrefix","FormGroup","FormArray","firstItemControl_1","at","FormControl","logFormErrors","valid","child","getFormErrors","recursive","getControlFromPath","disableControls","paths","disable","pushValueInArray","arrayControl","createControl","hasChanged","markAsDirty","patchValueInArray","removeAt","resizeArray","removeValueInArray","clearValueInArray","markAllAsTouched","markFormGroupAsTouched","markControlAsTouched","markAsUntouched","waitWhilePending","pending","waitIdle","AppNullForm","invalid","enable","markAsPristine","markAsLoaded","markAsReady","ready","AppFormProvider","getterFn","NULL_FORM","waitDelegate","content","delegate","untouched","FormArrayHelper","_formArray","_validators","helperProperty","FORMA_HELPER_PROPERTY","setAllowEmptyArray","allowEmptyArray","getOrCreateArray","formBuilder","arrayName","addControl","hasHelper","formArray","_allowEmptyArray","resize","clearAt","isLast","removeAllEmpty","ite","setValidators","AppFormUtils","isForm","isControlHasInput","calculatedSuffix","setCalculatedValue","resetCalculatedValue","addValueInArray","APP_FORM_ERROR_I18N_KEYS","FormErrorTranslator","errorI18nKeys","translateFormErrors","childControl","i18nPath","translateControlPath","columnErrors","errorKey","translateError","formError","translateErrors","pathErrors","controlPathTranslator","i18nKey","errorContent","i18nMessage","Inject","FormErrorTranslatePipe","adapter","_ref","_lastForm","_lastOptions","_updateValue","_dispose","_onFormStatusChanges","status","pure","FormGetPipe","FormGetControlPipe","FormGetArrayPipe","FormGetGroupPipe","FormGetValuePipe","_lastControl","listenStatusChanges","_lastPath","_onControlValueChanges","_onControlStatusChanges","PropertyGetPipe","PropertyFormatPipe","dateFormat","keyOrDefinition","definition","i18nYes","i18nNo","_i18nYes","_i18nNo","NgModule","imports","CommonModule","IonicModule","TranslateModule","declarations","LatitudeFormatPipe","LongitudeFormatPipe","exports","AutofocusDirective","platform","elementRef","keyboard","_timer","_elementRef","shouldFocusElement","timerDelay","_mobile","ngAfterContentInit","startFocusWorkflow","ngOnChanges","changes","stopFocusWorkflow","isVisible","clearTimeout","inputs","Platform","ElementRef","Keyboard","NgVarDirective","templateRef","vcRef","$implicit","ngVar","hasView","createEmbeddedView","TemplateRef","ViewContainerRef","DragAndDropDirective","fileDropped","onDragOver","fileOver","onDragLeave","ondrop","files","dataTransfer","HostBinding","HostListener","compatibleTagNames","AutoTitleDirective","ngAfterContentChecked","title","textContent","ScrollingModule","ReactiveFormsModule","SharedPipesModule","SharedDirectivesModule","MatCommonModule","MatAutocompleteModule","MatFormFieldModule","MatInputModule","MatIconModule","MatButtonModule","MatSelectModule","forChild","formatDuration","parseDuration","durationParts","MASKS","DDMMSS","DDMM","DD","MatLatLongField","_disabling","_writing","floatLabel","onBlur","onFocus","readonly","mask","showSignControl","_formatFn","_formatOptions","inputPlaceholder","textFormControl","textMaskConfig","keepCharPositions","signFormControl","existingValidators","onFormChange","strValue","defaultSign","_format","_onFocus","valueStr_1","caretIndex","_onBlur","moveCaretToSeparator","onKeypress","newValue","parsedValue","FormBuilder","TextMaskModule","DEFAULT_VALUE_ACCESSOR","MatDate","TEXT_MASK","compact","autofocus","locale","currentLang","defaultLang","updateTabIndex","_keyboardHideDelay","textControl","updatePattern","dayStr","onDatePickerChange","dateStr","millisecond","utc","openDatePickerIfMobile","datePicker","preventEvent","waitKeyboardHide","openDatePicker","open","matInputs","clear","formControlValue","waitKeyboardDelay","hide","onKeyboardHide","ViewChildren","MatDateTime","DAY_MASK","HOUR_REGEXP","HOUR_MASK","dayMask","hourMask","dayControl","hourControl","patterns","dayPattern","timeStr","onTimePickerChange","openTimePickerIfMobile","openTimePicker","timePicker","displayPattern","incompleteValue","hourParts","dateTime","emitChange","MatDateShort","writing","disabling","_value","keyboardHideDelay","$error","getValue","compose","dayValue","datePicker1","datePicker2","closeDatePicker","eventData","matDatepicker","MatDatepickerModule","MatMomentDateModule","NgxMaterialTimepickerModule","MatDuration","HOUR_TIME_PATTERN","MatRippleModule","MatBooleanField","showRadio","yesLabel","noLabel","showButtonIcons","yesIcon","noIcon","onPressEnter","buttonsColCount","_onFocusFakeInput","fakeInput","yesButton","checkboxButton","onRadioValueChanged","onCheckboxValueChanged","checked","_inputElement","noButton","MatRadioModule","MatCheckboxModule","AnimationState","DEFAULT_KEYMAP","icon","color","MatNumpadEvent","_super","init","inputTarget","KeyboardEvent","MatNumpadContainerComponent","backdropState","LEAVE","columnCount","filteredKeymap","keymap","disableAnimation","appendToInput","panelState","ENTER","modalState","noBackdrop","defineFilteredKeymap","row","onButtonClick","keyDef","customEvent","numpadRef","keypress","onKeydown","overlayClick","animationDone","phaseName","toState","background","MatNumpadDomService","cfr","appRef","injector","document","appendNumpadToBody","numpadType","componentRef","resolveComponentFactory","instance","attachView","hostView","domElement","rootNodes","appendChild","destroyNumpad","destroy","detachView","ComponentFactoryResolver","ApplicationRef","Injector","DOCUMENT","MatNumpadComponent","domService","_opened","_inputRef","registerInput","NumpadDirective","numpadSubscriptions","onTouched","onChange","numpad","registerNumpad","updateInputValue","updateValue","onClick","disableClick","_numpad","applyingKey","host","[disabled]","(click)","(change)","(blur)","AppendToInputDirective","renderer","getBoundingClientRect","height","_inputCords","isElementFit","innerHeight","width","offsetWidth","innerWidth","ngAfterViewInit","inputCords","_directionY","directionY","_directionX","directionX","append","changePosition","x","defineElementYByDirection","setStyle","defineElementXByDirection","inputTop","inputBottom","inputLeft","inputRight","Renderer2","MatNumpadContent","MatSwipeField","showSlides","$items","$loaded","loadItems","prevButton","slideTo","slideChanged","nextButton","updateSlides","slides","lockSwipes","updateButtons","slidePrev","slideNext","reachStart","reached","previousDisabled","reachEnd","nextDisabled","slidesLoaded","getActiveIndex","activeIndex","update","itemIndex","itemCount","getSlides","loaded","static","MatChipsField","chipColor","inputControl","option","splice","filterChipsFocusEvent","filteredData","item1","item2","removedItemCount","MatChipsModule","MatBadgeIconDirective","el","_$update","_size","updateView","_color","_fill","_matIcon","_ionIcon","immediate","badge","querySelector","fontSize","html","_html","innerHTML","display","alignItems","justifyContent","MatBadgeModule","modules","MatTableModule","MatSortModule","MatPaginatorModule","CdkTableModule","MatExpansionModule","MatToolbarModule","MatDialogModule","MatMenuModule","MatCardModule","MatTabsModule","MatListModule","MatStepperModule","MatButtonToggleModule","MatProgressSpinnerModule","MatProgressBarModule","MatSlideToggleModule","A11yModule","OverlayModule","MatDividerModule","MatTooltipModule","SharedMatAutocompleteModule","SharedMatLatLongModule","SharedMatDateTimeModule","SharedMatDurationModule","SharedMatBooleanModule","SharedMatNumpadModule","SharedMatSwipeModule","SharedMatChipsModule","SharedMatBadgeIconModule","ProgressBarService","_requestsRunning","onProgressChanged","list","increase","decrease","HAMMER_PRESS_TIME","AppGestureConfig","overrides","press","pinch","rotate","swipe","velocity","buildHammer","mc","Hammer","eventName","set","HammerGestureConfig","ToolbarComponent","route","router","routerOutlet","progressBarService","_closeTapCount","_validateTapCount","hasValidate","hasClose","canShowMenu","onValidate","onClose","onValidateAndClose","onBackClick","onSearch","progressBarMode$","mode","_backHref","canGoBack","_defaultBackHref","observers","hasSearch","toggleSearchBar","searchbar","setFocus","doBackClick","goBack","replaceUrl","navigate","relativeTo","navigateByUrl","tapClose","tapCount","srcEvent","tapValidate","ToolbarToken","ActivatedRoute","Router","IonRouterOutlet","MatPaginatorI18n","itemsPerPageLabel","nextPageLabel","previousPageLabel","getRangeLabel","page","pageSize","onLangChange","translateLabels","MatPaginatorIntl","ProgressInterceptor","intercept","req","handle","HttpResponse","rgbArrayToHex","rgb","componentToHex","hexToRgbArray","hex","exec","mixHex","color1","color2","weight","rgb1","rgb2","getColorContrast","bw","AppFormField","onKeyupEnter","_definition","checkAndResolveFormControl","placeholder","numberInputStep","computeNumberInputStep","computeValuesFromToken","filterAlphanumericalInput","matInput","getDisplayValueFn","maximumNumberDecimals","token","directives","StartableService","prerequisiteService","startSubject","stopSubject","_debug","_startByReadyFunction","_data","_started","_startPromise","_startPrerequisite","start","ngOnStart","catch","stopped","message","ngOnStop","err_1","restart","registerSubscription","sub","unregisterSubscription","SYSTEM_SOUNDS","assetPath","vibration","AudioProvider","nativeAudio","audioManagement","_audioMode","AudioManagement","AudioMode","NORMAL","_preloadedSounds","_htmlAudioCache","playBeepConfirm","play","vibrate","VIBRATE","playBeepError","playStartupSound","preload","sound","_audioType","info","preloadSimple","Audio","started","SILENT","promises","audio","vibrationTimes","all","unload","err_2","is","readAudioMode","getAudioMode","audioMode","NativeAudio","Vibration","HotkeysDialogComponent","hotkeys","MAT_DIALOG_DATA","Hotkeys","eventManager","dialog","modalController","popoverController","_hotkeys","Map","_defaults","addShortcut","openHelpModal","merged","description","Observable","observer","addEventListener","getTop","component","elementName","repeat","delete","EventManager","MatDialog","ModalController","PopoverController","UploadFile","File","HttpEventType","Response","statusText","isProgressEvent","UploadProgress","DownloadProgress","isResponseEvent","IMAGE_DEFAULTS","MAX_HEIGHT","MAX_WIDTH","THUMB_MAX_HEIGHT","THUMB_MAX_WIDTH","ImagesUtils","readAsDataURL","file","$progress","reader","FileReader","onprogress","onloadend","FileResponse","onerror","resizeBase64","asObservable","readAndResizeFromUrl","fileUrl","img","createElement","crossOrigin","createImageOnLoadResizeFn","src","dataUrl","ctx","maxWidth","thumbnail","maxHeight","canvas","getContext","xoffset","yoffset","drawImage","base64","toDataURL","momentTZImported","uuidv4","uuidv4Imported","FileService","http","environment","production","getImages","sources","getImage","outputType","canUseFileSystem","lastSlashIndex","fileName","targetFilePath","_imageDirectory","observe","responseType","reportProgress","blob","deps","HttpClient","ModalToolbarComponent","modalName","showSpinner","validateIcon","cancel","validate","canValidate","Base58","getAlphabetMap","alphabetMap","alphabet","charAt","encode","buffer","j","digits","carry","unshift","digit","decode","string","Uint8Array","scrypt","require","sha256","sha512","nacl","tweetnacl","box","hash","verify","util","constants","crypto_sign_BYTES","SEED_LENGTH","SCRYPT_PARAMS","SIMPLE","N","memory","DEFAULT","SECURE","HARDEST","EXTREME","CryptoService","scryptKeypair","salt","password","scryptParams","dkLen","encoding","derivedKey","seed","byteseed","decodeBase64","signKeypair","keyPair","fromSeed","publicKey","secretKey","keypair","decodeUTF8","signedMsg","sig","encodeBase64","signature","pub","detached","digest","Entity","__typename","updateDate","fromObject","asObject","keepTypename","keepLocalId","other","isInstanceOf","EntityUtils","isEntity","isNotEmpty","checkedAttribute","checkAttribute","getArrayAsMap","getMapAsArray","getPropertyArrayAsObject","copyIdAndUpdateDate","fillLocalIds","sequenceFactory","newItems","currentId","cleanIdAndUpdateDate","cleanIdsAndUpdateDates","sortBy","sortDirection","sortComparator","after","compare","value1","value2","compareValue","searchTextFilter","asPrefixPattern","anyMatchPattern","isSimplePath","searchAsPrefix","regexp_1","regexps_1","treeToArray","children","batch","listOfTreeToArray","treeFillParent","isLocal","isRemote","isLocalId","isRemoteId","freeze","version","baseUrl","defaultLocale","defaultLatLongFormat","apolloFetchPolicy","persistCache","peerMinVersion","defaultPeers","port","defaultAppName","defaultAndroidInstallUrl","storage","driverOrder","sourceUrl","reportIssueUrl","forumUrl","helpUrl","defaultAuthValues","username","account","enableListenChanges","listenIntervalInSeconds","entityEditor","EntityClasses","register","typename","entityClass","entityName","CLASSES_BY_NAME","EntityClass","fromObjectReuseStrategy","decoratedClass_1","TYPENAME","decoratedClass","Peer","Peer_1","parseUrl","peerUrl","url","URL","dns","hostname","useSsl","protocol","pathname","peer","_i","ipv4","ipv6","hostAndPort","HttpUtils","getText","uri","nocache","headers","HttpHeaders","JSON","stringify","code","getJson","NetworkUtils","getNodeInfo","POSITIVE_INTEGER","VERSION_PART_REGEXP","VersionUtils","compareVersionNumbers","v1parts","v2parts","validateParts","isNumber","isCompatible","minVersion","actualVersion","SelectPeerModal","viewCtrl","$peers","canCancel","allowSelectDownPeer","onRefresh","peers","refreshPeers","dismiss","selectPeer","reachable","softwareVersion","refresh","jobs","refreshPeer","summary","softwareName","nodeLabel","nodeName","SETTINGS_STORAGE_KEY","SETTINGS_TRANSIENT_PROPERTIES","DEFAULT_SETTINGS","accountInheritance","latLongFormat","pageHistoryMaxSize","APP_LOCAL_SETTINGS","APP_LOCAL_SETTINGS_OPTIONS","LocalSettingsService","defaultSettings","defaultOptionsMap","_optionDefs","resetData","usageMode","pageHistory","restoreLocally","isUsageMode","isOnFieldMode","settingsStr","restoredData_1","transientKey","setProperty","keyOrDef","getPropertyAsBoolean","getPropertyAsInt","getPropertyAsNumbers","getPropertyAsStrings","settings","persistImmediate","persistLocally","applyProperty","getPageSettings","pageId","pages","savePageSetting","getOfflineFeature","featureName","offlineFeatures","featurePrefix","feature","lastSyncDate","getOfflineFeatureLastSyncDate","hasOfflineFeature","saveOfflineFeature","existingIndex","markOfflineFeatureAsSync","removeOfflineFeatures","getFieldDisplayAttributes","getPageFieldDefaultValue","registerOption","def","registerOptions","defs","addToPageHistory","fillPageHistoryDefaults","existingPage","removedPages","removePageHistory","found","clearPageHistory","defaultPeer","_$persist","removeTitleSmallTag","tagIndex","removePathQueryParams","Storage","Environment","Toasts","show","toastController","IonicSafeString","messageParams","counter","currentOffset","stackSize","updateCounters","i18nKeys","header","showCloseButton","buttons","buttonIndex","role","closeButton","cssArray","cssClass","enterAnimation","start_1","end_1","baseEl","createAnimation","addElement","fromTo","toast","onWillPresent","present","onDidDismiss","StartableObservableService","dataSubject","NetworkRefreshTimerPeriod","NetworkService","_document","modalCtrl","cryptoService","cache","network","splashScreen","onPeerChanges","onNetworkStatusChanges","onResetNetworkCache","_listeners","_timerRefreshPeriod","_timerRefreshCondition","online","ngOnAfterStart","connectionType","_forceOffline","_deviceConnectionType","on","callback","addListener","tryOnline","showLoadingToast","showToast","loadingToast","checkPeerAlive","peerInfo","checkPeerCompatible","setForceOffline","showOnlineToast","showOfflineToast","showRetryButton","toastResult","showRetrySuccessToast","showRetryLoadingToast","onRetrySuccess","computePeerPath","getAppManifest","err_3","getAppVersion","appVersion","err_4","manifest","previousConnectionType","currentConnectionType","showSelectPeerModal","$onRefresh","peers$","getDefaultPeers","componentProps","keyboardClose","showBackdrop","modal","onWillDismiss","clearCache","clearAll","onDeviceConnectionChanged","startRefreshTimer","onDisconnect","onConnect","stopRefreshTimer","location","detectedPeer","_timerSubscription","lastInfo","alive","offline","getUri","hooks","CacheService","Network","SplashScreen","ToastController","ErrorCodes","UNKNOWN_ERROR","LOAD_ACCOUNT_ERROR","BAD_PASSWORD","UNKNOWN_ACCOUNT_EMAIL","EMAIL_ALREADY_REGISTERED","UNREACHABLE_NETWORK_ERROR","UNKNOWN_NETWORK_ERROR","SENT_CONFIRMATION_EMAIL_FAILED","CONFIRM_EMAIL_FAILED","SAVE_ACCOUNT_ERROR","ACCOUNT_NOT_EXISTS","SAVE_SETTINGS_ERROR","SUBSCRIBE_ACCOUNT_ERROR","ENTITY_STORAGE_MIGRATION_FAILED","LOAD_DATA_ERROR","SAVE_DATA_ERROR","DELETE_DATA_ERROR","SUBSCRIBE_DATA_ERROR","LOAD_PERSONS_ERROR","DATA_NOT_FOUND_ERROR","TABLE_INVALID_ROW_ERROR","TABLE_READ_ONLY","UNAUTHORIZED","AUTH_CHALLENGE_ERROR","AUTH_SERVER_ERROR","LOAD_CONFIG_ERROR","SAVE_CONFIG_ERROR","LOAD_TRASH_ENTITY_ERROR","DELETE_TRASH_ENTITY_ERROR","ServerErrorCodes","BAD_REQUEST","FORBIDDEN","NOT_FOUND","INTERNAL_SERVER_ERROR","DATA_LOCKED","BAD_UPDATE_DATE","DENY_DELETION","INVALID_EMAIL_CONFIRMATION","INVALID_QUERY_VARIABLES","ACCOUNT_ALREADY_EXISTS","BAD_APP_VERSION","ENTITIES_STORAGE_KEY_PREFIX","EntityStore","policy","_onChange","_dirty","reset","_loaded","_storageKey","_mapToLightEntity","createLightEntityMapFn","nextValue","_sequence","currentValue","load","fullLoad","loadFullEntity","loadCachedEntity","watchAll","variables","reduceAndSort","loadAll","save","_statusById","saveAll","entities","setEntities","isByIdMode","deleteMany","ids","deletedEntities","persist","skipIfPristine","dirtyIndexes","storageKeyById","restore","migration","storageKeys","oldKeysToClean","details","fullData","skipNonLocalEntities","lightFieldsExcludes","excludeAttributesMask","APP_LOCAL_STORAGE_TYPE_POLICIES","EntitiesStorage","typePolicies","_$save","_saving","_typePolicies","_saveTimerPeriod","storageSavePeriodMs","some","store","throttleTime","storeLocally","pause","storeName","trash","TRASH_PREFIX","getEntityStore","entityStore","entityOrName","detectEntityName","nextValues","entityCount","firstValue","deleteById","deletedEntity","deleteFromTrash","deleteFromTrashById","moveToTrash","trashName","moveManyToTrash","saveToTrash","clearTrash","typePolicy","entityNames","entitiesCount","count","currentEntityName","entityNameIndex","REMOTE_PREFIX","StorageUtils","to","deleteAfterCopy","driver","errorCount","getItem","setItem","removeItem","APP_LOCALES","UserSettings","UserSettings_1","minify","nonce","includesProperties","hasChanges","SETTINGS_PROPERTIES","asLocalSettings","StatusIds","DISABLE","ENABLE","TEMPORARY","DELETED","ALL","referentialToString","ɵ1","ɵ2","StatusList","ɵ0$a","StatusById","BaseReferential","keepEntityName","creationDate","comments","statusId","validityStatusId","levelId","parentId","Referential","ReferentialUtils","MINIFY_ENTITY_FOR_LOCAL_STORAGE","MINIFY_ENTITY_FOR_POD","departmentToString","departmentsToString","ReferentialRef","ReferentialRef_1","Department","Department_1","ENTITY_NAME","logo","siteUrl","PRIORITIZED_AUTHORITIES","Person","Person_1","department","firstName","lastName","profiles","mainProfile","PersonUtils","getMainProfile","usernameExtranet","avatar","getMainProfileIndex","hasUpperOrEqualsProfile","actualProfiles","expectedProfile","expectedProfileIndex","personToString","personsToString","accountToString","Account","Account_1","asPerson","person","_global","global","NativeWebSocket","WebSocket","MozWebSocket","AppWebSocket","protocols","isMutationOperation","operation","getMainDefinition","kind","isSubscriptionOperation","CLOSED","CLOSING","CONNECTING","OPEN","TRACKED_QUERIES_STORAGE_KEY","restoreTrackedQueries","trackedQuery","contextJSON","queryJSON","variablesJSON","apolloClient","mutate","mutation","optimisticResponse","APP_GRAPHQL_TYPE_POLICIES","GraphqlService","apollo","httpLink","connectionParams","onNetworkError","customErrors","_defaultFetchPolicy","_networkStatusChanged$","client","setAuthToken","authToken","setAuthBasic","basic","authBasic","addResolver","resolvers","addResolvers","fetchPolicy","toApolloError","watchQueryRef","watchQuery","notifyOnNetworkStatusChange","queryRefValuesChanges","queryRef","onApolloError","networkStatus","NetworkStatus","forceOffline","offlineResponse","optimisticResponseFn","res_1","extra","errorPolicy","useZone","insertIntoQueryCache","arrayFieldName","readQuery","sortFn","totalFieldName","writeQuery","addManyToQueryCache","data_1","equalsFn_1","equalsFn","inputValue","existingValue","removeFromCachedQueryById","deletedItem","evict","identify","removeFromCachedQueryByIds","data_2","deletedIndexes","updateToQueryCache","equalsFn_2","registerCustomError","enableTrackMutationQueries","wsUri","httpParams","wsParams","lazy","reconnect","webSocketImpl","IonicStorageWrapper","wsLink","WebSocketLink","retryLink","RetryLink","authLink","ApolloLink","authorization","setContext","InMemoryCache","debounce","mutationLinks","serializingLink","SerializingLink","onNetworkStatusChange","trackedQueriesUpdated","trackedQueriesById","networkStatusSubject","trackedQueries","trackerLink","tracked","serializationKey","operationName","cleanContext","nextOperation","queueLink_1","QueueLink","loggerLink","ApolloClient","link","connectToDevTools","resetClient","clearStore","defaultError","networkError","toAppError","createAppErrorByCode","graphQLErrors","originalError","stack","getI18nErrorMessageByCode","customErrorMessage","parseError","Apollo","HttpLink","BaseGraphqlService","graphql","_mutableWatchQueries","_mutableWatchQueriesMaxCount","_logPrefix","mutableWatchQuery","defaultFetchPolicy","mutableQuery","queryId","computeMutableWatchQueryId","exactMatchQueries","q","refetch","registerNewMutableWatchQuery","insertFilterFn","insertIntoMutableCachedQueries","queries","findMutableWatchQueries","removeFromMutableCachedQueriesByIds","refetchMutableWatchQueries","queryName","variablesKey","queryNames","removedWatchQueries","findRefetchQueries","BaseGraphqlServiceOptions","TOKEN_STORAGE_KEY","PUBKEY_STORAGE_KEY","SECKEY_STORAGE_KEY","ACCOUNT_STORAGE_KEY","DEFAULT_AVATAR_IMAGE","Fragments","gql","templateObject_1","templateObject_2","LoadQuery","templateObject_3","IsEmailExistsQuery","templateObject_4","AccountMutations","templateObject_5","templateObject_6","saveSettings","templateObject_7","SendConfirmEmailMutation","templateObject_8","ConfirmEmailMutation","templateObject_9","AuthQuery","templateObject_10","AuthChallengeQuery","templateObject_11","AccountSubscriptions","listenChanges","templateObject_12","AccountService","onLogin","onLogout","onAuthTokenChange","onAuthBasicChange","_listenChangesSubscription","_$additionalFields","_tokenType$","_enableListenChanges","_listenIntervalInSeconds","isLogin","listenSettings","hadAuthToken","hadAuthBasic","hadAuth","isAuth","hasMinProfile","userProfile","hasExactProfile","profile","hasProfileAndIsEnable","isAdmin","isSupervisor","isUser","isOnlyGuest","canUserWriteDataForDepartment","recorderDepartment","defaultDepartmentId","saveRemotely","authenticate","saveLocally","startListenRemoteChanges","tokenType","authenticateAndGetToken","login","error_3","previousToken","error_4","loadData","isEmailExists","error_5","reload","wasLogin","error_6","logout","checkEmailAvailable","sendConfirmationEmail","confirmEmail","confirmAccountEmail","getAdditionalField","registerAdditionalField","field","stopListenRemoteChanges","error_7","saveLocalSettingsRemotely","seckey","error_8","jsonAccount","accountStr","saveSettingsRemotely","isNew","existingAccount","copyIdAndUpdateDateSettings","challengeError","authChallenge","challenge","newToken","watchChanges","interval","intervalInSeconds","currentUpdateDate","remoteUpdateDate","Software","Software_1","Configuration","Configuration_1","partners","smallLogo","largeLogo","backgroundImages","CORE_CONFIG_OPTIONS","LOGO","FAVICON","DEFAULT_LOCALE","DEFAULT_LAT_LONG_FORMAT","REGISTRATION_ENABLE","AUTH_TOKEN_TYPE","GRAVATAR_ENABLE","GRAVATAR_URL","TESTING","APP_MIN_VERSION","HELP_URL","FORUM_URL","LOGO_LARGE","MENU_ITEMS","HOME_PARTNERS_DEPARTMENTS","HOME_BACKGROUND_IMAGE","COLOR_PRIMARY","COLOR_SECONDARY","COLOR_TERTIARY","COLOR_SUCCESS","COLOR_WARNING","COLOR_ACCENT","COLOR_DANGER","ANDROID_INSTALL_URL","DB_TIMEZONE","isTransient","CONFIGURATION_STORAGE_KEY","templateObject_1$1","templateObject_2$1","SaveMutation","templateObject_3$1","ClearCache","templateObject_4$1","CacheStatistics","templateObject_5$1","APP_CONFIG_OPTIONS","ConfigService","accountService","$data","loadOrRestoreLocally","loadDefault","canUserWrite","savedConfig","reloadedConfig","defaultConfig","getCacheStatistics","cacheStatistics","cacheName","jobs_1","imgUrl","index_1","dep","UploadFilePopover","uniqueFile","instantUpload","importing","uploader","resetError","uploadFiles","processedFiles","deleting","encapsulation","ViewEncapsulation","None","MimeTypes","ANDROID_APK","FilesUtils","showUploadPopover","backdropDismiss","translucent","readAsText","writeTextToFile","filename","charset","Blob","UTF8_BOM_CHAR","msSaveBlob","download","createObjectURL","setAttribute","visibility","click","removeChild","downloadUri","msLaunchUri","getFilenameFromUri","UriUtils","getFilename","queryParamIndex","AndroidOsEnvironment","DIRECTORY_DOWNLOADS","DIRECTORY_DOWNLOADS_OLD","PlatformService","cdkPlatform","entitiesStorage","networkService","configService","audioProvider","statusBar","browser","downloader","_downloadingJobs","platformName","_cordova","isAndroidCordova","_android","isIOSCordova","_ios","isApp","isWeb","isMobileWeb","configureClassList","configureCordovaPlugins","configureTranslate","storageReady","migrateStorage","configureCache","checkAppVersion","canReload","skip","canDownload","canOpenFile","checkIntervalMs","checkAppVersionIntervalInSeconds","checkAppVersionTimer","silent","onStartupError","features","getDownloadingJob","request","job$","subPath","destinationInExternalPublicDir","destinationInExternalFilesDir","mimeType","downloadRequest_1","visibleInDownloadsUi","notificationVisibility","NotificationVisibility","VisibleNotifyCompleted","dirType","openFile","filePath","fileMimeType","documentElement","styleDefault","overlaysWebView","hideFormAccessoryBar","setDefaultLang","lang","setLocale","use","accountSettings","cacheTTL","isOnline","setDefaultTTL","setOfflineInvalidate","canAutoReload","remoteVersion","reloadPath","href","side","handler","forage","WEBSQL","supports","INDEXEDDB","LOCALSTORAGE","oldForage","createInstance","dropInstance","toast_1","detailsMessage","FIREFOX","alert","CdkPlatform","StatusBar","InAppBrowser","Downloader","AppHelpModal","showError","onLoadError","MatStepperI18n","optionalLabel","MatStepperIntl","UploadFileComponent","progress","processingFiles","onFileDropped","prepareFilesList","fileBrowseHandler","deleteFile","deleteFn","FileList","fileDropEl","$processingFileCountChange","processingFilesCount","$changes","maxParallelUpload","file$","uploadFn","response","forkJoin","APP_TESTING_PAGES","SharedTestsPage","openPage","scrollFactory","overlay","scrollStrategies","SharedModule","forRoot","ngModule","useValue","OverlayContainer","useClass","FullscreenOverlayContainer","HTTP_INTERCEPTORS","MAT_AUTOCOMPLETE_SCROLL_STRATEGY","useFactory","Overlay","MAT_AUTOCOMPLETE_DEFAULT_OPTIONS","autoActiveFirstOption","MAT_SELECT_SCROLL_STRATEGY","ColorPickerModule","DragDropModule","MarkdownModule","SharedMaterialModule","SharedHotkeysModule","AppLoadingSpinner","Alerts","askSaveBeforeLeave","alertCtrl","confirm","askActionConfirmation","messageKey","askConfirmation","askDeleteConfirmation","askSaveBeforeAction","confirmed","titleKey","ComponentDirtyGuard","canDeactivate","currentRoute","currentState","nextState","can","AlertController","CustomReuseStrategy","shouldReuseRoute","future","curr","routeConfig","pathIdParam","currId","params","queryParams","futureId","IonicRouteStrategy","RouterModule","RouteReuseStrategy","FormFieldValuesHolder","getAsBoolean","getAsInt","getAsNumbers","getAsStrings","AppForm","_enable","i18nFieldPrefix","destroySubject","readySubject","loadingSubject","errorSubject","onCancel","onSubmit","setForm","errorTranslator","autocompleteHelper","autocompleteFields","setError","_form","errorTranslatorOptions","doSubmit","checkValid","setLoading","ngOnReady","i18nFieldName","getI18nFieldName","getFormError","registerAutocompleteField","TextForm","multiline","autoHeight","maxLength","textAreaChanges","textAreaChanged","containerResize","autosizeDirective","resizeToFitContent","textArea","textInput","CdkTextareaAutosize","TextPopover","editing","resizable","closest","clientX","fit","bufferWhen","ResizableComponent","columnDef","sizeChanged","minWidth","onResize","onFit","MatColumnDef","ResizableDirective","EntityFilter","asPodObject","countNotEmptyCriteria","isCriteriaNotEmpty","asFilterFn","filterFns","buildFilter","EntityFilterUtils","isEntityFilter","filterType","InMemoryEntitiesService","_hiddenData","dirtySubject","savingSubject","onSort","_sortFn","_onLoad","onLoad","_onSaveFn","onSave","_equalsFn","_filterFnFactory","filterFnFactory","asFilter","_sortByReplacement","sortByReplacement","markAsSaved","originalData","excludedDataByFilter","excludedDataByPagination","nextOffset_1","filterData","markAsSaving","deleteAll","dataToRemove","updatedData","entityToRemove","addSortByReplacement","waitWhileSaving","_filter","hiddenData","filteredData_1","connect","saving","JobUtils","runnableList","runnable","run","progression","maxProgression","fetchAllPages","loadPageFn","fetchSize","currentPageDataCount","pageCount","progressionStep","onPageLoaded","CsvUtils","exportToFile","rows","protectCellRegexp","k","cell","cellStr","parseFile","parseCSV","skipEmptyLine","line","rgbArrayMap","white","primary","secondary","tertiary","danger","light","medium","dark","red","green","blue","colorsMap","Color","_rgbArray","_opacity","_name","parseRgba","rgba","transparent","ColorScale","colorArray","nbIntervalBeforeUpper","upperMax","_min","_max","_rangeSize","_legendItems","computeLegendItems","default","custom","fix","colorName","valueOf","getLegendForValue","getLegendAtIndex","linearColorGradient","startColor","endColor","delta","mainColorIndex","mainColor","linearColorGradientWithIntermediate","RegisterModal","sending","AuthForm","canWorkOffline","showPwd","usernamePlaceholder","canRegister","AuthModal","APP_ABOUT_DEVELOPERS","APP_ABOUT_PARTNERS","AboutModal","developers","config$","setConfig","MenuItems","checkIfVisible","exactProfile","ifProperty","getRandomImage","random","APP_HOME_BUTTONS","HomePage","locales","waitingNetwork","accountName","$partners","loadingBanner","$filteredButtons","showAccountButton","changeLanguage","getPagePath","_h","onConfigLoaded","_g","onSettingsChanged","_config","appName","contentStyle","bgImage","background-image","primaryColor","background-color","refreshButtons","filteredButtons","titleProperty","moduleId","module","RegisterConfirmPage","activatedRoute","subscriptions","paramMap","doConfirm","emailAccount","AppValidatorService","getRowValidator","getFormGroup","getFormGroupConfig","getI18nFormErrors","getI18nErrors","getI18nError","ValidatorService","UserSettingsValidatorService","AccountValidatorService","formDef","additionalFields","getValidators","validatorFns","AccountPage","validatorService","settingsValidatorService","_super_1","notConfirmed","latLongFormats","submitted","settingsForm","settingsContentForm","$additionalFields","stopListenChanges","networkSubscription","startListenChanges","changesSubscription","newAccount","showRecorder","DEFAULT_MENU_SHOW_WHEN","MenuService","_$toggled","_$opened","_$splitPaneWhen","_$enabled","toggle","setSplitPaneShowWhen","toggleSplitPaneWhen","_markAsOpened","_markAsClosed","FormButtonsBarComponent","menu","disabledCancel","onNext","onBack","FormButtonsBarToken","TableSelectColumnsComponent","navParams","canHideColumns","columns","visible","canHide","onRenderItems","NavParams","RegisterForm","accountValidatorService","showConfirmPwd","forms","emailAvailability","equalsValidator","confirmPassword","formDetailDef","registration","emailStep","passwordStep","detailsStep","stepper","selectedIndex","isBeginning","otherControlName","availability","HttpClientModule","LocalSettingsValidatorService","getPropertiesArray","asyncValidators","peerAlive","getPropertyFormGroup","peerUrlControl","SettingsPage","usageModes","propertyDefinitionsByKey","propertyDefinitionsByIndex","propertiesFormHelper","propertyDefinitions","optionDefs","setAccountInheritance","getPropertyDefinition","updatePropertyDefinition","propertiesForm","removePropertyAt","peerChanged","getJsonValueToSave","userSettings","AppPropertiesForm","definitionsMapByKey","definitionsByIndex","definitions","formArrayName","helper","getDefinitionAt","updateDefinitionAt","isUnknownField","fieldForm","keyControl","AppListForm","selection","SelectionModel","displayWithFn","onNewItem","selectionChanges","allowMultipleSelection","isAllSelected","selected","masterToggle","onItemClick","ctrlKey","isSelected","onItemButtonClick","button","hasSelection","hasValue","onNewClick","deselect","IsOnFieldModePipe","IsNotOnFieldModePipe","PersonToStringPipe","AppInstallUpgradeCard","alertController","hasDownloader","downloading","showUpgradeWarning","showOfflineWarning","showInstallButton","checkNeedInstallOrUpdate","installLinks","upgradeLinks","listenDownloadJob","getPlatformName","asLink","links","getLinks","getCompatibleUpgradeLinks","l","listenDownloadJobs","getCompatibleInstallLinks","appMinVersionFromPod","versionMatches","job","showDownloadCompleteDialog","showDownloadFailedToast","IsLoginAccountPipe","AccountToStringPipe","DepartmentToStringPipe","ActionsColumnComponent","table","stickyEnd","optionsTitle","optionsClick","cancelOrDeleteClick","confirmAndAddClick","backward","detectChanges","addColumnDef","canDelete","canConfirmAndAdd","canBackward","canForward","dirtyIcon","removeColumnDef","MatTable","MatMenuTrigger","APP_MENU_ITEMS","APP_MENU_OPTIONS","MenuComponent","platformService","menuService","menuId","contentId","splitPane","splitPaneWhen","when","setSplitPaneWhen","accountAvatar","displayName","accountEmail","refreshMenuItems","skipRedirect","isEnabled","openAboutModal","toggleSplitPaneShow","doAction","action","onSwipeRight","pointerType","center","distance","configValue","before","MenuController","MenuOptions","AppUpdateOfflineModeCard","onUpdateClick","AppIconComponent","matIcon","matSvgIcon","CoreModule","CacheModule","IonicStorageModule","NgxJdenticonModule","AppGraphQLModule","AppMenuModule","AppIconModule","EntityMetadataComponent","AuthGuardService","canActivate","BaseEntityService","mutations","e1","e2","isNewFn","defaultSortBy","defaultSortDirection","watchQueriesUpdatePolicy","_typename","_logTypeName","watch","toEntity","withTotal","loadAllWithTotal","countAll","hasNewEntities","fillDefaultProperties","refetchQueries","getRefetchQueriesForMutation","awaitRefetchQueries","proxy","savedEntities","savedEntity","getLoadQueries","getTime","AppTableUtils","dataSource","logRowErrors","EntitiesTableDataSource","dataService","keepOriginalDataAfterConfirm","readOnly","saveOnlyDirtyRows","_creating","_fetchMoreFn","_stopWatchSubject","_entityName","suppressErrors","dataServiceOptions","watchAllOptions","saveAllOptions","serviceOptions","handleError","hasSomeEditingRow","updateDatasource","updateDatasourceFromRows","datasourceSubject","onlyDirtyRows","getRows","invalidRows","confirmEditCreate","dataToSave_1","currentData","dataConstructor","collectionViewer","viewer","disconnect","debounceTimeMs","confirmCreate","confirmEdit","startEdit","errorMsg","handleServiceError","getRow","getDataFromRows","rowNotDeleted","rowsSubject","createNew","insertAt","onRowCreated","getData","TableDataSource","SETTINGS_DISPLAY_COLUMNS","SETTINGS_SORTED_COLUMN","SETTINGS_FILTER","SETTINGS_PAGE_SIZE","DEFAULT_PAGE_SIZE_OPTIONS","RESERVED_START_COLUMNS","RESERVED_END_COLUMNS","DEFAULT_REQUIRED_COLUMNS","AppTable","_dataSource","_initialized","_cellValueChangesDefs","_enabled","allowRowDetail","excludesColumns","totalRowCount","touchedSubject","editedRow","i18nColumnPrefix","autoLoad","focusFirstColumn","confirmBeforeDelete","confirmBeforeCancel","undoableDeletion","propagateRowError","defaultPageSize","defaultPageSizeOptions","onOpenRow","onNewRow","onStartEditingRow","onConfirmEditCreateRow","onCancelOrDeleteRow","onBeforeDeleteRows","onBeforeCancelRows","onBeforeSave","onAfterDeletedRows","onDirty","onError","_paginator","Location","formErrorAdapter","_autocompleteConfigHolder","displayedColumns","setDatasource","setFilter","needEmitEvent","previouslyEditedRowId","cancelOrDelete","checkIfRowPristine","focusColumn","enableSort","disableSort","paginator","pageIndex","active","childPaginator","inlineEdition","saveBeforeDelete","saveBeforeSort","saveBeforeFilter","keepEditedRowOnSave","settingsId","generateTableId","getDisplayColumns","sortedColumn","getSortedColumn","getPageSize","combineLatest","pageOffset","sortActive","listenDatasourceLoading","listenSortAndPaginationEvents","col","stopCellValueChanges","visibleRowCount","datasource","resetDataSource","_dataSourceLoadingSubscription","column","saveBeforeAction","saved","applyFilter","confirmAndAdd","addRow","confirmAndBackward","previousRow","deleteNewRow","editRowById","lastUserColumn","editRow","confirmAndForward","firstUserColumn","getRowError","cancelExistingRow","deleteExistingRow","addRowToTable","openNewRowDetail","keepEditing","singleSelectedRow","previouslyEditedData","isOK","selectRowByIdOrData","interactive","canCancelRows","duplicateRow","newRow","skipProperties","newData_1","clickRow","deleteSelection","deleteRows","deleteRow","canDeleteRows","tempRows","deletedRows","selectRowById","selectRowByData","openRow","moveRow","move","openSelectColumnsModal","getCurrentColumns","hasTopModal","userColumns","trackByFn","doRefresh","hiddenColumns","getI18nColumnName","getRequiredColumns","escapeEditingRow","i18nColumnKey","err_5","askCancelConfirmation","saveAction","err_6","getUserColumns","disableClear","fixedStartColumns","fixedEndColumns","updateColumns","columnName","registerCellValueChanges","formPath","emitInitialValue","subject","startCellValueChanges","setShowColumn","getShowColumn","askRestoreConfirmation","markRowAsDirty","sortChange","EMPTY","restoreOriginalDataOnCancel","checkIfPristine","MatPaginator","MatSort","AppEditor","toolbar","formButtonsBar","editors","_children","addChildForm","addChildForms","removeChildForm","isNewData","reloadWithConfirmation","needConfirm","scrollToTop","logChildrenErrors","scrollToTop_1","setInterval","pos","pageYOffset","scrollTo","clearInterval","saveIfDirtyAndConfirm","cancel_1","path_1","path_2","path_3","IonContent","AppTabEditor","_selectedTabIndex","selectedTabIndexChange","tabCount","enableSwipe","tabGroupAnimationDuration","queryTabIndexParamName","setSelectedTabIndex","tabGroup","selectedTabIndex","realignInkBar","onTabChange","subtab","onSwipeTab","selectTabIndex","onSubTabChange","saveDirtyChildren","tables","AppTabEditorOptions","AppEditorOptions","AppEntityEditor","$title","onUpdateView","pathIdAttribute","autoUpdateRoute","_pathIdAttribute","_autoLoad","_autoLoadDelay","autoLoadDelay","_autoUpdateRoute","_autoOpenNextTab","autoOpenNextTab","i18nContext","suffix","_usageMode","historyIcon","registerForms","loadFromRoute","snapshot","computeUsageMode","onNewEntity","openTabIndex","onEntityLoaded","idChanged","previousDataId","updateRoute","updateViewState","updateTabAndRoute","updateTitle","tab","saveAndClose","openFirstInvalidTab","nextTabIndex","computeNextTabIndex","onEntitySaved","saveAndGetDataIfValid","Event","onEntityDeleted","defaultBackHref","userMessage","detailMessage","detailsCssClass","onBeforeEntityLoad","computeTitle","computePageHistory","computePageUrl","parentUrl","getParentPageUrl","withQueryParams","invalidTabIndex","getFirstInvalidTabIndex","commands","AppEntityEditorModalOptions","AppEntityEditorModal","i18nSuffix","environement","_isNewData","onAfterModalInit","saveBeforeLeave","onDelete","AppInMemoryTable","memoryDataService","canEdit","t2","SocialErrorCodes","LOAD_USER_EVENTS_ERROR","SAVE_USER_EVENT_ERROR","COUNT_USER_EVENT_ERROR","SEND_MESSAGE_ERROR","SUBSCRIBE_USER_EVENTS_ERROR","SUBSCRIBE_JOB_PROGRESSION_ERROR","APP_USER_EVENT_SERVICE","AbstractUserEventService","_countSubject","listeners","_subscriptions","watchPage","defaultFilter","recipients","recipient","defaultRecipient","withContent","loadAllWithContent","processUserEvent","loadPage","nextOffset_2","resetCountDate","listenCountChanges","excludeRead","listenAllChanges","deleteByIds","markAllAsRead","userEventWithoutReadListeners","onReadListeners","this_1","listener","onRead","accept","e_2","onReadListeners_1","onReadListeners_1_1","defaultMarkAsRead","registerListener","resetCount","startListenCountChanges","stopListenCountChanges","_listenSubscription","that","onReceived","listeners_1","listeners_1_1","userEvents","userEvent","readDate","localEntities","remoteEntities","markAsRead","unreadEvents","events","lastReadDate","lastDate","UserEventNotificationList","userEventService","_$pageSize","fetchingMore","$itemCount","enableInfiniteScroll","initInfiniteScroll","defaultAction","actions","executeAction","isDefaultAction","readEvent","unreadUserEvents","readEvents","_fetchMoreSubscription","ionContent","getScrollElement","IonItem","UserEventNotificationIcon","titleI18n","_readEvent","_readEvents","countSubject","autoHide","showList","MessageTypes","INBOX_MESSAGE","EMAIL","FEED","MessageTypeList","Message","issuer","MessageFilter","MessageModal","canSelectType","MessageForm","subjectMinLength","subjectMaxLength","bodyMaxLength","bodyAutoHeight","types","personAttributes","statusIds","isSamePerson","JobProgression","JobProgression_1","current","APP_JOB_PROGRESSION_SERVICE","QUERIES","templateObject_1$2","JobProgressionService","addJob","removeJob","JobProgressionList","JobProgressionIcon","jobProgressionService","jobFinished","jobProgressions","_subscriptionsById","autoHideDelay","autoRemove","autoRemoveDelay","getProgression","currentProgression","_listPopover","nbProgression","allIndeterminate","indeterminate","SocialModuleOptionsToken","UserEventModule","JobModule","MessageModule","Mutations","send","templateObject_1$3","MessageService","PersonFilter","PersonFilter_1","searchFilter","userProfiles","PersonFragments","templateObject_1$4","PersonQueries","templateObject_2$2","templateObject_3$2","PersonMutations","templateObject_4$2","templateObject_5$2","PersonService","loadAllLocally","executeImport","PersonValidatorService","formConfig","UsersPage","messageService","prependNewElements","statusList","statusById","filterCriteriaCount","useSticky","canSendMessage","filterForm","authTokenType","restoreFilterOrLoad","applyFilterAndClosePanel","filterExpansionPanel","resetFilter","clearControlValue","openComposeMessageModal","MatExpansionPanel","SocialModule","routes","pathMatch","SharedRoutingModule","AdminModule","FAKE_ENTITIES","deepCopy","AutocompleteTestPage","_items","_$items","memoryHide","memoryMobile","memoryAutocompleteFieldName","missingEntity","disableEntity","farEntity","entityToString","farEntityField","entitiesToString","toggleMode","stopMemoryTimer","startMemoryTimer","memoryTimer","updateFilter","autocompleteField","LatLongTestPage","disableFormGroup","geoPosition","SwipeTestPage","dateFormatPipe","$dates","_today","disabledEmpty","disabledDate","dates","displayDate","compareDate","DateTimeTestPage","showLogPanel","logContent","noTimeProperty","emptyRequired","noTime","disableControl","log","clearLogPanel","ChipsTestPage","appearance","entityInitial","$icon","$size","$fill","$color","NumpadTestPage","datetime","DateTestPage","nowAtMahe","SHARED_MATERIAL_TESTING_PAGES","divider","MatBadgeIconTestPage","ToastTestingPage","defaultOptions","showInfo","showWarning","toggleCloseButton","UploadFileTestingPage","showPopover","uploadFile","filenames","finalName","$stop","loadStep","SHARED_TESTING_PAGES","MaterialTestingModule","ToastTestingModule","UploadFileTestingModule","ReferentialFilter","searchTextFn","ReferentialValidatorService","getFormGroupOptions","controlsConfig","withDescription","withComments","TableTestPage","groupColumns","restoreFilter","stopTimer","filter_1","toggleTimer","startTimer","generateData","maxRowCount","IonInfiniteScroll","TextPopoverTestingPage","redirectTo","TableTestingModule","TextPopoverTestingModule","JobProgressionTestingPage","jobId","incrementJob","createJob","jobProgressionIcon","UserEventTest","UserEventTest_1","avatarIcon","UserEventTestFilter","levels","issuers","level","readSignature","UserEventTestService","$userEvents","$newUserEvents","toSave","UserEventTestingPage","translateService","customize","showMessage","addNotification","addError","addWarning","addDebug","addNotificationWithLink","iconRef","addNotificationWithAction","addMany","addRandom","addNotificationWithDefaultAction","JobTestingModule","UserEventTestingModule","JobProgressionTestService","jobsSubject","take","propertiesOrKeyFn","getKey","existingIds","Set","uniqueKey","has","rv","focusableInputs","timeInSec","Connection","NONE","ETHERNET","WIFI","CELL","CELL_2G","CELL_3G","CELL_4G","UNKNOWN","res1","res2","nbRemove","replacement","attribute","compareFn","Intl","Collator","str"],"mappings":"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","sourcesContent":["import { FetchPolicy } from '@apollo/client/core';\nimport { StorageConfig } from '@ionic/storage';\nimport { InjectionToken } from '@angular/core';\n\nexport const ENVIRONMENT = new InjectionToken<Environment>('ENV');\n\nexport class Environment {\n name: string;\n version: string;\n production: boolean;\n baseUrl: string;\n\n // A peer to use at startup (useful on a web site deployment)\n defaultPeer?: { host: string; port: number; useSsl?: boolean; path?: string } | undefined | null;\n\n // A list of peers, to select as peer, in settings\n defaultPeers?: { host: string; port: number; useSsl?: boolean; path?: string }[];\n\n // Min compatible version for the peer\n peerMinVersion?: string;\n\n // Interval to check if web page must be reload, in millis\n checkAppVersionIntervalInSeconds?: number;\n\n // Enable cache persistence ?\n persistCache?: boolean;\n\n // Force offline mode ? /!\\ For DEV only\n offline?: boolean;\n\n // Apollo (graphQL) config\n apolloFetchPolicy?: FetchPolicy;\n\n // Default values\n defaultLocale: string;\n defaultLatLongFormat?: 'DD' | 'DDMM' | 'DDMMSS';\n defaultDepartmentId?: number;\n defaultAppName?: string;\n defaultAndroidInstallUrl?: string;\n\n // Storage\n storage?: Partial<StorageConfig>;\n storageSavePeriodMs?: number;\n\n // About\n sourceUrl?: string;\n reportIssueUrl?: string;\n forumUrl?: string;\n helpUrl?: string;\n\n // Default authentication /!\\ For DEV only\n // (see values in the test database - XML files in Pod's module)\n defaultAuthValues?: {\n username?: string;\n password?: string;\n };\n\n // Account\n account?: {\n showAccountButton?: boolean; // Show account button in home page (if undefined = true)\n enableListenChanges?: boolean;\n // If undefined or 0, then listen only changes made by the pod\n // If greater than 0 : will check concurrent changes in the DB (e.g. changes mde by another software) AND changes made the pod\n listenIntervalInSeconds?: number;\n };\n\n entityEditor?: {\n enableListenChanges?: boolean;\n // If undefined or 0, then listen only changes made by the pod\n // If greater than 0 : will check concurrent changes in the DB (e.g. changes mde by another software) AND changes made the pod\n listenIntervalInSeconds?: number;\n };\n\n}\n","export const DATE_ISO_PATTERN = 'YYYY-MM-DDTHH:mm:ss.SSSZ';\nexport const DATE_PATTERN = 'YYYY-MM-DD';\nexport const DEFAULT_PLACEHOLDER_CHAR = '\\u005F';\nexport const PUBKEY_REGEXP = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}$/;\nexport const SPACE_PLACEHOLDER_CHAR = '\\u2000';\n\nexport const KEYBOARD_HIDE_DELAY_MS = 250; // 1s\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","import {KeysEnum, KeyValueType} from './types';\n\nexport function isNil<T>(obj: T | null | undefined): boolean {\n return obj === undefined || obj === null;\n}\nexport function isNilOrBlank<T>(obj: T | null | undefined): boolean {\n return obj === undefined || obj === null || (typeof obj === 'string' && obj.trim() === '');\n}\nexport function isNotNil<T>(obj: T | null | undefined): boolean {\n return obj !== undefined && obj !== null;\n}\nexport function isNotNilOrBlank<T>(obj: T | null | undefined): boolean {\n return obj !== undefined && obj !== null && (typeof obj !== 'string' || obj.trim() !== '');\n}\nexport function isNotNilOrNaN<T>(obj: T | null | undefined): boolean {\n return obj !== undefined && obj !== null && (typeof obj !== 'number' || !isNaN(obj));\n}\nexport function isNilOrNaN<T>(obj: T | null | undefined): boolean {\n return obj === undefined || obj === null || (typeof obj === 'number' && isNaN(obj));\n}\nexport function isNotEmptyArray<T>(obj: T[] | null | undefined): boolean {\n return obj !== undefined && obj !== null && obj.length > 0;\n}\nexport function firstArrayValue<T>(obj: T[] | null | undefined): T | undefined {\n return isNotEmptyArray(obj) ? obj[0] : undefined;\n}\nexport function isEmptyArray<T>(obj: T[] | null | undefined): boolean {\n return obj === undefined || obj === null || !obj.length;\n}\nexport function isNotNilBoolean(obj: any | null | undefined): obj is boolean {\n return obj !== undefined && obj !== null && typeof obj === 'boolean' || false;\n}\nexport function isNotNilString(obj: any | null | undefined): obj is string {\n return obj !== undefined && obj !== null && typeof obj === 'string' || false;\n}\nexport function isBlankString(obj: any | null | undefined): obj is string {\n return (typeof obj === 'string') && obj.trim().length === 0;\n}\nexport function notNilOrDefault<T>(obj: T | null | undefined, defaultValue: T): T {\n return (obj !== undefined && obj !== null) ? obj : defaultValue;\n}\nexport function arraySize<T>(obj: T[] | null | undefined): number {\n return isNotEmptyArray(obj) && obj.length || 0;\n}\nexport function arrayGroupBy<\n T = any,\n K extends keyof T = any,\n M extends { [key: string]: T[];\n} = { [key: string]: T[] }>(obj: T[], key: keyof T): M {\n if (isNil(obj)) return null;\n return obj.reduce((rv: any, x) => {\n (rv[x[key]] = rv[x[key]] || []).push(x);\n return rv;\n }, {});\n}\n\n/**\n * Remove duplicated value, in array. Will compute a unique key (from given properties, or given function)\n * @param values\n * @param propertiesOrKeyFn\n */\nexport function arrayDistinct<T = any>(values: T[], propertiesOrKeyFn?: string | string[] | ((obj: T) => string) ): T[] {\n if (isEmptyArray(values)) return values;\n const properties: string[] = (!propertiesOrKeyFn && Object.keys(values[0])) || (Array.isArray(propertiesOrKeyFn) && propertiesOrKeyFn);\n const getKey: (obj: T) => string =\n (typeof propertiesOrKeyFn === 'function' && propertiesOrKeyFn)\n || (typeof propertiesOrKeyFn === 'string' && ((obj) => getPropertyByPathAsString(obj, propertiesOrKeyFn)))\n || ((obj) => joinPropertiesPath(obj, properties, '|'));\n const existingIds = new Set<string>();\n return values.reduce((res, item) => {\n const uniqueKey = getKey(item);\n if (existingIds.has(uniqueKey)) return res; // Skip if duplicate\n existingIds.add(uniqueKey);\n return res.concat(item);\n }, []);\n}\nexport function nullIfUndefined<T>(obj: T | null | undefined): T | null {\n return obj === undefined ? null : obj;\n}\nexport function trimEmptyToNull<T>(str: string | null | undefined): string | null {\n const value = str && str.trim() || undefined;\n return value && value.length && value || null;\n}\nexport function toBoolean(obj: boolean | null | undefined | string, defaultValue?: boolean): boolean {\n return (obj !== undefined && obj !== null) ? (obj !== 'false' ? !!obj : false) : defaultValue;\n}\nexport function toNumber(obj: number | null | undefined, defaultValue?: number): number {\n return (obj !== undefined && obj !== null) ? +obj : defaultValue;\n}\nexport function toFloat(obj: string | null | undefined, defaultValue?: number): number | null {\n return (obj !== undefined && obj !== null) ? parseFloat(obj) : defaultValue;\n}\nexport function toInt(obj: string | null | undefined, defaultValue?: number): number | null {\n return (obj !== undefined && obj !== null) ? parseInt(obj, 0) : defaultValue;\n}\nexport function toNotNil<T = any>(obj: T, defaultValue?: T): any | null {\n return (obj !== undefined && obj !== null) ? obj : defaultValue;\n}\nexport function removeDuplicatesFromArray<T>(obj: T[] | null | undefined, property?: string): T[] | null | undefined {\n if (isEmptyArray(obj)) return obj;\n if (property) {\n return obj.filter((item, i, array) => array.findIndex(t => t && item && t[property] === item[property]) === i);\n }\n return obj.filter((item, i, array) => array.findIndex(t => t && item && t === item) === i);\n}\nexport function startsWithUpperCase(input: string, search: string): boolean {\n return input && input.toUpperCase().startsWith(search);\n}\nexport function matchUpperCase(input: string, regexp: string): boolean {\n return input && !!input.toUpperCase().match(regexp);\n}\n\n/**\n * Remove trailing slash if any. Examples :\n * - '/test/' -> '/test'\n * - '/' -> undefined\n */\nexport function noTrailingSlash(path: string): string {\n if (!path || path.trim() === '/') return undefined;\n if (path.trim().lastIndexOf('/') === path.length - 1) return path.substring(0, path.length - 1);\n return path;\n}\n\nexport function replaceAll(value: string, searchString: any, replacement): string | undefined {\n while (value && value.indexOf(searchString) !== -1) {\n value = value.replace(searchString, replacement);\n }\n return value;\n}\n\nexport function escapeRegExp(value: string) {\n return value.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nexport function removeEnd(value: string, end: string): string {\n return value?.endsWith(end || '') ? value.substr(0, value.length - end.length) : value;\n}\n\n/**\n * Replace case change by an underscore (.e.g 'myString' becomes 'my_string')\n *\n * @param value\n */\nexport function changeCaseToUnderscore(value: string): string {\n if (isNilOrBlank(value)) return value;\n return value.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();\n}\n\nexport function removeDiacritics(text: string): string {\n return text.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n}\n\nexport function suggestFromStringArray(values: string[], value: any, options?: {\n searchAttribute?: string;\n searchAttributes?: string[];\n}): string[] {\n value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;\n if (isNilOrBlank(value)) return values;\n\n // If wildcard, search using regexp\n if ((value as string).indexOf('*') !== -1) {\n value = (value as string).replace('*', '.*');\n return values.filter(v => matchUpperCase(v, value));\n }\n\n // If no wildcard, search using startsWith\n return values.filter(v => startsWithUpperCase(v, value));\n}\n\nexport function joinPropertiesPath<T = any>(obj: T, properties: string[], separator?: string): string | undefined {\n if (!obj) throw new Error('Could not display an undefined entity.');\n if (!properties) throw new Error('Missing \\'properties\\' argument');\n return properties\n .map(path => getPropertyByPath(obj, path))\n .filter(isNotNilOrBlank)\n .join(separator || ' - ');\n}\n\nexport function joinProperties<T = any, K extends keyof T = any>(obj: T, keys: K[], separator?: string): string | undefined {\n if (!obj) throw new Error('Could not display an undefined entity.');\n return keys\n .map(key => getProperty(obj, key))\n .filter(isNotNilOrBlank)\n .join(separator || ' - ');\n}\n\nexport function propertyPathComparator<T = any>(path: string|string[]): (a: T, b: T) => number {\n return (a: T, b: T) => {\n const valueA = getPropertyByPath(a, path);\n const valueB = getPropertyByPath(b, path);\n return valueA === valueB ? 0 : (valueA > valueB ? 1 : -1);\n };\n}\n\nexport function propertyComparator<T = any, K extends keyof T = any>(key: K, defaultValue?: any): (a: T, b: T) => number {\n return (a: T, b: T) => {\n const valueA = a[key] !== undefined ? a[key] : defaultValue;\n const valueB = b[key] ? b[key] : defaultValue;\n return valueA === valueB ? 0 : (valueA > valueB ? 1 : -1);\n };\n}\n\nexport function propertiesPathComparator<T = any>(keys: string[], defaultValues?: any[]): (a: T, b: T) => number {\n if (!keys || !keys.length || (defaultValues && keys.length > defaultValues.length)) {\n throw new Error('Invalid arguments: missing \\'keys\\' or array \\'defaultValues\\' has a bad length');\n }\n return (a: T, b: T) => keys.map((key, index) => {\n const valueA = getPropertyByPath(a, key, defaultValues && defaultValues[index]);\n const valueB = getPropertyByPath(b, key, defaultValues && defaultValues[index]);\n return valueA === valueB ? 0 : (valueA > valueB ? 1 : -1);\n })\n // Stop if not equals, otherwise continue with the next key\n .find(res => res !== 0) || 0;\n}\n\nexport function sort<T>(array: T[], attribute: string, opts?: Intl.CollatorOptions): T[] {\n if (isEmptyArray(array)) return array;\n const compareFn = opts\n ? new Intl.Collator(undefined, opts).compare\n : (v1, v2) => v1 === v2 ? 0 : v1 > v2 ? 1 : -1;\n return array\n .slice() // copy\n .sort((a, b) => compareFn(a[attribute], b[attribute]));\n}\nconst INTEGER_REGEXP = /^[-]?\\d+$/;\nexport function isInt(value: string): boolean {\n return isNotNil(value) && INTEGER_REGEXP.test(value);\n}\nconst NUMBER_REGEXP = /^[-]?\\d+(\\.\\d+)?$/;\nexport function isNumber(value: string): boolean {\n return isNotNil(value) && NUMBER_REGEXP.test(value);\n}\n\nconst NUMBER_RANGE_REGEXP = /^(\\d+-\\d+)|([><=]*\\d+)$/;\nexport function isNumberRange(value: string): boolean {\n return isNotNil(value) && NUMBER_RANGE_REGEXP.test(value);\n}\n\nexport function getPropertyByPath(obj: any, path: string|string[], defaultValue?: any): any {\n // Path is an array: convert path to string\n if (Array.isArray(path)) {\n return getPropertyByPath(obj, path.join('.'), defaultValue);\n }\n if (isNil(obj)) return defaultValue;\n if (isNilOrBlank(path)) return obj;\n const i = path.indexOf('.');\n // Simple property path\n if (i === -1) {\n const res = obj[path];\n return (isNotNil(res) || isNil(defaultValue)) ? res : defaultValue;\n }\n // Complex property path\n const key = path.substring(0, i);\n if (isNil(obj[key])) return defaultValue;\n if (typeof obj[key] === 'object') { // Object or Array\n // Recursive call\n return getPropertyByPath(obj[key], path.substring(i + 1));\n }\n throw new Error(`Invalid property path: '${key}' is not an valid object.`);\n}\n\nexport function getProperty<T = any, K extends keyof T = any>(obj: T, key: K): T[K] {\n if (isNil(obj)) return undefined;\n return obj[key]; // Inferred type is T[K]\n}\n\nexport function getPropertyByPathAsString(obj: any, path: string|string[]): string | undefined {\n const res = getPropertyByPath(obj, path);\n return (typeof res === 'string') ? res : ('' + res);\n}\n\nexport function sleep(ms: number): Promise<void> {\n if (ms <= 0) return;\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function round(value: number | undefined | null): number {\n if (isNotNilOrNaN(value)) {\n return Math.round((value + Number.EPSILON) * 100) / 100;\n }\n return value;\n}\n\nexport function equalsOrNil(value1: any, value2: any) {\n return (value1 === value2) || (isNil(value1) && isNil(value2));\n}\n\n/**\n * remove elements from an array\n *\n * @return the removed elements\n * @param array the array on which elements will be removed\n * @param predicate the selection predicate\n */\nexport function removeAll<T>(array: T[], predicate: (pmfm: T) => boolean): T[] {\n let nbRemove = 0;\n return array.slice().map((value, index) => {\n if (predicate(value)) {\n nbRemove++; // glitch counter to avoid index gap\n return array.splice(index - nbRemove + 1, 1)[0];\n }\n return null;\n }).filter(isNotNil);\n}\n\n/**\n * remove the first element from an array\n *\n * @return the removed element\n * @param array the array on which the element will be removed\n * @param predicate the selection predicate\n */\nexport function remove<T>(array: T[], predicate: (pmfm: T) => boolean): T {\n return array.slice().find((value, index) => {\n if (predicate(value)) {\n array.splice(index, 1);\n return true;\n }\n return false;\n });\n}\n\nexport function capitalizeFirstLetter(value: string) {\n if (!value || value.length === 0) return value;\n return value.substr(0, 1).toUpperCase() + value.substr(1);\n}\nexport function uncapitalizeFirstLetter(value: string) {\n if (!value || value.length === 0) return value;\n return value.substr(0, 1).toLowerCase() + value.substr(1);\n}\n\nexport function splitByProperty<T, M extends KeyValueType<T> = KeyValueType<T>>(array: T[] | readonly T[], propertyName: keyof T | string): M {\n return (array || []).reduce((res, value) => {\n const key = (value as unknown as any)?.[propertyName];\n if (isNotNil(key)) {\n res[key] = value;\n }\n return res;\n }, {}) as M;\n}\n\nexport function splitById<T, M extends KeyValueType<T> = KeyValueType<T>>(array: T[] | readonly T[]): M {\n return (array || []).reduce((res, value) => {\n const key = value?.['id'];\n if (isNotNil(key)) {\n res[key] = value;\n }\n return res;\n }, <M>{});\n}\n\n/**\n * Determines if two objects or two values are equivalent.\n *\n * Two objects or values are considered equivalent if at least one of the following is true:\n *\n * * Both objects or values pass `===` comparison.\n * * Both objects or values are of the same type and all of their properties are equal by\n * comparing them with `equals`.\n *\n * @param o1 Object or value to compare.\n * @param o2 Object or value to compare.\n * @returns true if arguments are equal.\n */\nexport function equals(o1: any, o2: any): boolean {\n if (o1 === o2) return true;\n if (o1 === null || o2 === null) return false;\n if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN\n let t1 = typeof o1, t2 = typeof o2, length: number, key: any, keySet: any;\n if (t1 == t2 && t1 == 'object') {\n if (Array.isArray(o1)) {\n if (!Array.isArray(o2)) return false;\n if ((length = o1.length) == o2.length) {\n for (key = 0; key < length; key++) {\n if (!equals(o1[key], o2[key])) return false;\n }\n return true;\n }\n } else {\n if (Array.isArray(o2)) {\n return false;\n }\n keySet = Object.create(null);\n for (key in o1) {\n if (!equals(o1[key], o2[key])) {\n return false;\n }\n keySet[key] = true;\n }\n for (key in o2) {\n if (!(key in keySet) && typeof o2[key] !== 'undefined') {\n return false;\n }\n }\n return true;\n }\n }\n return false;\n}\n\n// @dynamic\nexport class Beans {\n /**\n * Copy a source object, by including only properties of the given dataType.\n * IMPORTANT: extra properties that are NOT in the targetClass are NOT copied.\n *\n * @param source The source object to copy\n * @param dataType the class to use as target class\n * @param keys The keys to copy. If empty, will copy only NOT optional properties from the dataType\n */\n static copy<T>(source: T, dataType: new () => T, keys?: KeysEnum<T>): T {\n if (isNil(source)) return source;\n const target = new dataType();\n Object.keys(keys || target).forEach(key => {\n target[key] = source[key];\n });\n return target;\n }\n\n /**\n * Says if an object all all properties to nil\n */\n static isEmpty<T>(data: T, keys?: KeysEnum<T>|string[], opts?: {\n blankStringLikeEmpty?: boolean;\n }): boolean {\n return isNil(data) || (Array.isArray(keys) ? keys : Object.keys(keys || data))\n // Find index of the first NOT nil value\n .findIndex(key => {\n const value = data[key];\n if (value && typeof value === 'object') return !Beans.isEmpty(value, null, opts); // Loop\n if (opts && opts.blankStringLikeEmpty === true && typeof value === 'string') return isNotNilOrBlank(value);\n return isNotNil(value);\n }) === -1;\n }\n\n static collectById<T>(array: T[]): {[key: string]: T} {\n return this.collectByProperty(array, 'id' as keyof T);\n }\n\n static collectByProperty<T>(array: T[], propertyName: keyof T): {[key: string]: T} {\n return (array || []).reduce((res, item) => {\n res[''+propertyName] = item;\n return res;\n }, {});\n }\n}\n","export interface FocusableElement {\n focus();\n}\n\nexport function isFocusableElement(object: any): object is FocusableElement {\n if (!object) return false;\n return 'focus' in object;\n}\n\n\n","import {ElementRef, QueryList} from '@angular/core';\nimport {FocusableElement, isFocusableElement} from './focusable';\nimport {isNil, isNilOrBlank, isNotEmptyArray, isNotNil, toBoolean, toNumber} from './functions';\n\n\n\n\nexport function selectInputContent(event: UIEvent) {\n if (event.defaultPrevented) return false;\n const input = (event.target as any);\n if (!input) return true;\n\n // Nothing to select\n if (isNilOrBlank(input.value)) return false;\n\n if (typeof input.selectRange === 'function') {\n try {\n input.selectRange(input.value.length, 0);\n return true;\n } catch (err) {\n console.error('Could not select input content, using selectRange()', err);\n return false;\n }\n }\n\n if (input && typeof input.select === 'function') {\n try {\n input.select();\n return true;\n } catch (err) {\n console.error('Could not select input content, using select()', err);\n return false;\n }\n }\n return true;\n}\n\nexport function selectInputRange(input: any, startIndex: number, endIndex?: number) {\n if (input && typeof input.setSelectionRange === 'function') {\n\n // No content\n if (isNilOrBlank(input.value)) return false;\n\n try {\n input.setSelectionRange(startIndex, isNotNil(endIndex) ? endIndex : startIndex);\n } catch (err) {\n console.error('Could not select input range', err);\n return false;\n }\n }\n return true;\n}\n\nexport function getCaretPosition(input: any): number {\n if (input && input.selectionStart) {\n return input.selectionDirection ?\n (input.selectionDirection === 'backward' ? input.selectionStart : input.selectionEnd) : input.selectionStart;\n }\n return -1;\n}\n\nexport function moveInputCaretToSeparator(event: KeyboardEvent, separator: string, forward?: boolean) {\n if (event.defaultPrevented || !separator) return false;\n const input = (event.target as any);\n if (!input) return true;\n\n const caretPosition = getCaretPosition(input);\n\n // DEBUG\n //console.debug('caretPosition=', caretPosition);\n\n if (caretPosition === -1) return true; // Caret pos not found: skip\n\n // Get input value\n const value = input.value as string;\n\n // No content: skip\n if (isNilOrBlank(value)) return false;\n\n try {\n\n\n if (value && caretPosition <= value.length) {\n // DEBUG\n //console.debug(\"Input text value: \", value);\n //console.debug(\"Cursor at: \", caretPosition);\n //console.debug(\"Text after cursor: \", value.substr(caretPosition));\n //console.debug(\"Next separator at: \", value.indexOf(separator, caretPosition));\n\n forward = forward !== false;\n\n const separatorIndex = (forward ? value.indexOf(separator, caretPosition) : value.lastIndexOf(separator, caretPosition));\n if (separatorIndex !== -1 && ((forward && separatorIndex + 1 < value.length)\n || (!forward && separatorIndex > 0))) {\n if (input.setSelectionRange) {\n // Move after the next separator\n if (selectInputRange(input, separatorIndex + (forward ? 1 : -1))) {\n // Stop the keyboard event\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }\n }\n } catch (err) {\n console.error('Could not move caret to next separator', err);\n return false;\n }\n return true;\n}\n\nexport function filterNumberInput(event: KeyboardEvent, allowDecimals: boolean, decimalSeparator?: string) {\n //input number entered or one of the 4 direction up, down, left and right\n if ((event.which >= 48 && event.which <= 57) || (event.which >= 37 && event.which <= 40)) {\n //console.debug('input number entered :' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n // OK\n }\n // Decimal separator\n else if (allowDecimals && ((!decimalSeparator && (event.key === '.' || event.key === ','))\n || (decimalSeparator && event.key === decimalSeparator))) {\n //console.debug('input decimal separator entered :' + event.code);\n // OK\n } else {\n //input command entered of delete, backspace or one of the 4 direction up, down, left and right, or negative sign\n if ((event.keyCode >= 37 && event.keyCode <= 40) || event.keyCode == 46 || event.which == 8 || event.keyCode == 9 || event.keyCode == 45) {\n //console.debug('input command entered :' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n // OK\n }\n // Cancel other keyboard events\n else {\n //console.debug('input not number entered :' + event.which + ' ' + event.keyCode + ' ' + event.charCode + ' ' + event.code );\n event.preventDefault();\n }\n }\n}\n\nexport function focusInput(element: ElementRef) {\n const inputElement = asInputElement(element);\n if (inputElement)\n inputElement.focus();\n else {\n console.warn('Trying to focus on this element:', element);\n }\n}\n\nexport function setTabIndex(element: ElementRef, tabIndex: number) {\n if(isInputElement(element)) {\n element.tabindex = tabIndex;\n }\n else if (element && isInputElement(element.nativeElement)) {\n element.nativeElement.tabIndex = tabIndex;\n }\n else {\n console.warn('Trying to change tabindex on this element:', element);\n }\n}\n\nexport interface InputElement extends FocusableElement {\n tabindex?: number;\n tabIndex?: number;\n hidden?: boolean;\n disabled?: boolean;\n value: any;\n}\nexport function isInputElement(object: any): object is InputElement {\n return isFocusableElement(object)\n && ('value' in object\n // has value is not always set (neither tabindex) check on 2 properties with a logical OR\n || ('tabindex' in object || 'tabIndex' in object));\n}\n\nexport function asInputElement(object: ElementRef): InputElement|undefined {\n if (object) {\n if (isInputElement(object)) return object;\n if (object.nativeElement && isInputElement(object.nativeElement)) return object.nativeElement;\n }\n return undefined;\n}\n\nexport function tabindexComparator(a: InputElement, b: InputElement) {\n const valueA = a.tabindex || a.tabIndex;\n const valueB = b.tabindex || b.tabIndex;\n return valueA === valueB ? 0 : (valueA > valueB ? 1 : -1);\n}\n\nexport interface CanGainFocusOptions {\n minTabindex?: number;\n maxTabindex?: number;\n excludeEmptyInput?: boolean;\n}\n\nexport interface GetFocusableInputOptions extends CanGainFocusOptions {\n sortByTabIndex?: boolean;\n debug?: boolean;\n}\n\nexport function canHaveFocus(input: InputElement, opts?: CanGainFocusOptions): boolean {\n if (!input) return false;\n // Exclude disabled element\n return !toBoolean(input.disabled, false)\n // Exclude hidden element\n && !toBoolean(input.hidden, false)\n // Exclude minTabIndex < element.tabIndex\n && (isNil(opts.minTabindex) || toNumber(input.tabIndex, input.tabindex) > opts.minTabindex)\n // Exclude maxTabIndex > element.tabIndex\n && (isNil(opts.maxTabindex) || toNumber(input.tabIndex, input.tabindex) < opts.maxTabindex)\n // Exclude nil input value\n && (!opts.excludeEmptyInput || isNilOrBlank(input.value));\n}\n\nexport function getFocusableInputElements(elements: QueryList<ElementRef>, opts?: GetFocusableInputOptions): InputElement[] {\n opts = {sortByTabIndex: false, excludeEmptyInput: false, ...opts};\n\n // Focus to first input\n const filteredElements: InputElement[] = elements\n\n // Transform to input\n .map(asInputElement)\n\n .filter(input => {\n const included = canHaveFocus(input, opts);\n // DEBUG\n if (input && opts.debug) console.debug(`[inputs] Focusable input {canFocus: ${included}, tabIndex: ${input.tabIndex||input.tabindex}}`, input);\n return included;\n });\n\n // Sort by tabIndex\n if (opts.sortByTabIndex) {\n return filteredElements.sort(tabindexComparator);\n }\n\n return filteredElements;\n\n}\n\n\nexport function focusNextInput(event: UIEvent|undefined, elements: QueryList<ElementRef>, opts?: GetFocusableInputOptions): boolean {\n\n // Cancelling event (e.g. when emitted by (keydown.tab) )\n if (event) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n // Get current index\n const minTabindex = event && isInputElement(event.target) ? (event.target.tabIndex || event.target.tabindex) : undefined;\n\n // Get focusable input elements\n const focusableInputs: InputElement[] = getFocusableInputElements(elements, {minTabindex, ...opts});\n\n if (isNotEmptyArray(focusableInputs)) {\n // Focus on first inputs\n focusableInputs[0].focus();\n return true;\n }\n\n return false;\n}\n\nexport function focusPreviousInput(event: UIEvent|undefined, elements: QueryList<ElementRef>, opts?: GetFocusableInputOptions): boolean {\n\n // Cancelling event (e.g. when emitted by (keydown.tab) )\n if (event) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n // Get current index\n const maxTabindex = event && isInputElement(event.target) ? (event.target.tabIndex || event.target.tabindex) : undefined;\n\n // Get focusable input elements\n const focusableInputs: InputElement[] = getFocusableInputElements(elements, {maxTabindex, ...opts});\n\n if (isNotEmptyArray(focusableInputs)) {\n // Focus on last inputs\n focusableInputs[focusableInputs.length -1].focus();\n return true;\n }\n\n return false;\n}\n\n","import {merge, Observable, Subject, timer} from 'rxjs';\nimport { filter, first, map, switchMap, takeUntil } from 'rxjs/operators';\nimport { isNotNil } from './functions';\nimport {Predicate} from '@angular/core';\n\nexport declare interface FirstOptions {\n timeout?: number;\n stop?: Observable<any>;\n stopError?: boolean;\n}\n\nexport declare interface WaitForOptions extends FirstOptions{\n dueTime?: number;\n checkPeriod?: number;\n}\n\nexport function filterNotNil<T = any>(obs: Observable<T>): Observable<T> {\n return obs.pipe(filter(isNotNil));\n}\n\nexport function filterTrue(obs: Observable<boolean>): Observable<boolean> {\n return obs.pipe(filter((v) => v === true));\n}\nexport function filterFalse(obs: Observable<boolean>, opts?: FirstOptions): Observable<boolean> {\n return obs.pipe(filter((v) => v === false));\n}\n\nfunction decorateForFirst<T = any>(obs: Observable<T>, opts?: FirstOptions): Observable<T> {\n // Set take until notifier\n const takeUntil$ = opts?.stop || (opts?.timeout && timer(opts.timeout));\n if (takeUntil$) {\n\n // When stop, throw an error (useful when used with a toPromise())\n if (opts.stopError) {\n return merge(\n obs.pipe(\n takeUntil(takeUntil$)\n ),\n takeUntil$\n .pipe(map(() => {\n throw new Error(opts.timeout ? `Timeout ${opts.timeout}ms` : `Stop`);\n }))\n );\n }\n\n // Add a takeUntil\n return obs.pipe(\n takeUntil(takeUntil$)\n );\n }\n return obs;\n}\n\nexport function firstNotNil<T = any>(obs: Observable<T>, opts?: FirstOptions): Observable<T> {\n return decorateForFirst(obs, opts).pipe(first(isNotNil));\n}\nexport function firstTrue(obs: Observable<boolean>, opts?: FirstOptions): Observable<void> {\n return decorateForFirst(obs, opts).pipe(\n first((v) => v === true),\n map(_ => {}) // Convert to void\n );\n}\nexport function firstFalse(obs: Observable<boolean>, opts?: FirstOptions): Observable<void> {\n return decorateForFirst(obs, opts).pipe(\n first((v) => v === false),\n map(_ => {}) // Convert to void\n );\n}\nexport function firstTruePromise(obs: Observable<boolean>, opts?: FirstOptions): Promise<void> {\n return firstTrue(obs, {stopError: true, ...opts}).toPromise();\n}\nexport function firstFalsePromise(obs: Observable<boolean>, opts?: FirstOptions): Promise<void> {\n return firstFalse(obs, {stopError: true, ...opts}).toPromise();\n}\nexport function firstNotNilPromise<T = any>(obs: Observable<T>, opts?: FirstOptions): Promise<T> {\n return firstNotNil(obs, {stopError: true, ...opts}).toPromise();\n}\nexport function chainPromises<T = any>(defers: (() => Promise<any>)[]): Promise<T[]> {\n return (defers || []).reduce((previous: Promise<any> | null, defer) => {\n // First job\n if (!previous) {\n return defer()\n // Init the final result array, with the first result\n .then(jobRes => [jobRes]);\n }\n // Other jobs\n return previous\n .then((finalResult) => defer()\n // Add job result to final result array\n .then(jobRes => finalResult.concat(jobRes)));\n }, null);\n}\n\n/**\n * Wait form a predicate return true. This need to implement AppFormUtils.waitWhilePending(), AppFormUtils.waitIdle()\n * @param predicate\n * @param opts\n */\nexport async function waitFor(predicate: Predicate<void>, opts?: WaitForOptions): Promise<void> {\n if (predicate()) return Promise.resolve();\n\n const period = opts && opts.checkPeriod || 300;\n const dueTime = opts && opts.dueTime || period;\n let wait$: Observable<boolean> = timer(dueTime, period)\n .pipe(\n // For DEBUG :\n //tap(() => console.debug(\"Waiting form idle...\", form)),\n filter(_ => predicate()),\n map(_ => true)\n );\n\n await firstNotNilPromise(wait$, opts);\n}\n\nexport function waitForTrue(observable: Observable<boolean>, opts?: WaitForOptions): Promise<void> {\n opts = {stopError: true, ...opts};\n // dueTime (without timeout)\n if (opts && opts.dueTime > 0) {\n return timer(opts.dueTime)\n .pipe(switchMap(() => firstTrue(observable, opts)))\n .toPromise();\n }\n return firstTrue(observable, opts).toPromise();\n}\n\nexport function waitForFalse(observable: Observable<boolean>, opts?: WaitForOptions): Promise<void> {\n return waitForTrue(\n // Inverse the logic\n observable.pipe(map(v => v === false)\n ), opts);\n}\n","import {EventEmitter} from '@angular/core';\nimport {fromEvent, merge, Observable, timer} from 'rxjs';\nimport {filter, startWith} from 'rxjs/operators';\n\nexport interface PromiseEventPayload<T = any> {\n success: (T) => void;\n error: (err: any) => void;\n}\n\nexport type PromiseEvent<T = any, D = void> = CustomEvent<PromiseEventPayload<T> & D>;\n\nexport function createPromiseEventEmitter<T = any, D = void>(): EventEmitter<PromiseEvent<T, D>> {\n return new EventEmitter<PromiseEvent<T, D>>(true);\n}\n\nexport function createPromiseEvent<T = void, D = void>(eventType: string,\n promise: PromiseEventPayload<T>,\n initArg?: CustomEventInit<D>\n ): PromiseEvent<T, D> {\n\n const detail = <PromiseEventPayload & D>{\n ...(initArg && initArg.detail || {}),\n ...promise\n };\n return new CustomEvent<PromiseEventPayload<T> & D>(eventType, {detail});\n}\n\nexport function emitPromiseEvent<T = any, D = void>(emitter: EventEmitter<PromiseEvent<T, D>>,\n eventType: string,\n initArg?: CustomEventInit<D>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const event = createPromiseEvent(eventType, {\n success: resolve,\n error: reject\n }, initArg);\n emitter.emit(event);\n });\n}\n\nexport interface CompletableEvent extends Event {\n target: EventTarget & { complete?: () => void };\n}\n\n/**\n * Listen end of scroll.\n * <p>\n * The threshold distance from the bottom of the content to call the infinite output event when scrolled.\n * The threshold value can be either a percent, or in pixels.\n * For example, use the value of 10% for the infinite output event to get called when the user has scrolled\n * 10% from the bottom of the page. Use the value 100px when the scroll is within 100 pixels from the bottom of the page.\n * </p>\n * @param element\n * @param threshold default to '15%'\n */\nexport function fromScrollEndEvent(element: HTMLElement, threshold?: string, dueTime?: number): Observable<any> {\n\n threshold = threshold || '15%';\n let isEnd: () => boolean;\n\n // Listen using percentage\n if (threshold.endsWith('%')) {\n const thresholdRatio = parseInt(threshold.slice(0, threshold.length - 1)) / 100;\n isEnd = () => {\n const endPosRatio = 1 - (element.scrollTop + element.offsetHeight) / element.scrollHeight;\n return endPosRatio < thresholdRatio;\n };\n }\n\n // Listen using pixels\n else if (threshold.endsWith('px')) {\n const thresholdPx = parseInt(threshold.slice(0, threshold.length - 2));\n isEnd = () => {\n const endPosPx = element.scrollHeight - (element.scrollTop + element.offsetHeight);\n return endPosPx < thresholdPx;\n };\n }\n else {\n throw new Error('Invalid argument \\'threshold\\'. Expected value unit: \\'px\\' or \\'%\\' ')\n }\n\n // Check bottom reach, even if NO scroll event (e.g. when already reach the bottom)\n if (dueTime > 0) {\n return merge(\n fromEvent(element, 'scroll'),\n timer(dueTime)\n )\n .pipe(\n filter(() => isEnd())\n );\n }\n\n return fromEvent(element, 'scroll')\n .pipe(\n filter(() => isEnd())\n );\n}\n","// import the required animation functions from the angular animations module\nimport {animate, state, style, transition, trigger} from '@angular/animations';\n\nexport const fadeInAnimation =\n // trigger name for attaching this animation to an element using the [@triggerName] syntax\n trigger('fadeInAnimation', [\n\n // route 'enter' transition\n transition(':enter', [\n\n // css styles at start of transition\n style({ opacity: 0 }),\n\n // animation and styles at end of transition\n animate('.3s', style({ opacity: 1 }))\n ]),\n ]);\n\nexport const fadeInOutAnimation =\n // trigger name for attaching this animation to an element using the [@triggerName] syntax\n trigger('fadeInOutAnimation', [\n\n // route 'enter' transition\n transition(':enter', [\n\n // css styles at start of transition\n style({ opacity: 0 }),\n\n // animation and styles at end of transition\n animate('.3s', style({ opacity: 1 }))\n ]),\n\n // route 'leave' transition\n transition(':leave', [\n // animation and styles at end of transition\n animate('.5s ease-in-out', style({\n opacity: 0\n }))\n ]),\n ]);\n\nexport const slideInOutAnimation =\n // trigger name for attaching this animation to an element using the [@triggerName] syntax\n trigger('slideInOutAnimation', [\n\n // end state styles for route container (host)\n state('*', style({\n // the view covers the whole screen with a semi tranparent background\n position: 'relative',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n opacity: 1\n })),\n\n // route 'enter' transition\n transition(':enter', [\n\n // styles at start of transition\n style({\n // start with the content positioned off the right of the screen,\n // -400% is required instead of -100% because the negative position adds to the width of the element\n left: '400%',\n\n // start with background opacity set to 0 (invisible)\n opacity: 0\n }),\n\n // animation and styles at end of transition\n animate('.3s ease-in-out', style({\n // transition the right position to 0 which slides the content into view\n left: 0,\n\n // transition the background opacity to 0.8 to fade it in\n opacity: 0.8\n }))\n ]),\n\n // route 'leave' transition\n transition(':leave', [\n // animation and styles at end of transition\n animate('.5s ease-in-out', style({\n // transition the right position to -400% which slides the content out of view\n left: '400%',\n\n // transition the background opacity to 0 to fade it out\n opacity: 0\n }))\n ])\n ]);\n\nexport const slideUpDownAnimation =\n // trigger name for attaching this animation to an element using the [@triggerName] syntax\n trigger('slideUpDownAnimation', [\n\n // end state styles for route container (host)\n state('*', style({\n transform: 'translateY(0)',\n opacity: 1\n })),\n\n // route 'enter' transition\n transition(':enter', [\n\n // styles at start of transition\n style({\n transform: 'translateY(-400%)',\n opacity: 0\n }),\n\n // animation and styles at end of transition\n animate('.3s ease-in-out', style({\n transform: 'translateY(0)',\n opacity: 1\n }))\n ]),\n\n // route 'leave' transition\n transition(':leave', [\n // animation and styles at end of transition\n animate('.5s ease-in-out', style({\n transform: 'translateY(-100%)',\n opacity: 0\n }))\n ])\n ]);\n","/* ---\n * Source: https://github.com/ionic-team/ionic-framework/blob/b0d53ca73619585671d8cf4dc24e47f826495a0a/core/src/utils/platform.ts\n * --- */\n\nconst _cache = {\n mobile: null,\n cordova: null\n};\n\nexport const matchMedia = (win: Window, query: string): boolean =>\n win.matchMedia(query).matches;\n\nexport const testUserAgent = (win: Window, expr: RegExp) => {\n const userAgent: string = win.navigator.userAgent || win.navigator.vendor || (window as any).opera;\n return expr.test(userAgent);\n}\n\nexport const isWindows = (win?: Window) =>\n testUserAgent(win, /windows/i);\n\nexport const isTouchUi = (win?: Window) =>\n matchMedia(win, '(any-pointer:coarse)');\n\nconst isIpad = (win: Window) => {\n // iOS 12 and below\n if (testUserAgent(win, /iPad/i)) {\n return true;\n }\n\n // iOS 13+\n if (testUserAgent(win, /Macintosh/i) && isTouchUi(win)) {\n return true;\n }\n\n return false;\n};\n\nexport const isIOS = (win: Window) =>\n testUserAgent(win, /iPhone|iPod/i) || isIpad(win);\n\nexport const isAndroid = (win: Window) =>\n testUserAgent(win, /android|sink/i);\n\nexport const isCordova = (win: any): boolean => {\n if (_cache.cordova === null || _cache.cordova === undefined) {\n _cache.cordova = !!(win['cordova'] || win['phonegap'] || win['PhoneGap']);\n }\n return _cache.cordova;\n}\n\nexport const isMobile = (win: Window) => {\n if (_cache.mobile === null || _cache.mobile === undefined) {\n _cache.mobile = isCordova(window)\n || isAndroid(win) || isIOS(window)\n // Workaround, for MS Windows touch screen (detected as mobile, but forced as desktop)\n || (isTouchUi(win) && !isWindows(win));\n }\n return _cache.mobile;\n}\n","import {LoadResult} from './services/entity-service.class';\nimport {\n getPropertyByPathAsString,\n isNotEmptyArray,\n isNotNil,\n isNotNilOrBlank,\n matchUpperCase,\n propertiesPathComparator,\n startsWithUpperCase\n} from './functions';\n\nexport function suggestFromArray<T = any>(items: T[], value: any, opts?: {\n offset?: number;\n size?: number;\n searchAttribute?: string;\n searchAttributes?: string[];\n excludedIds?: number[];\n skipSort?: boolean;\n}): LoadResult<T> {\n if (isNotNil(value) && typeof value === 'object') return {data: [value]};\n\n value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;\n\n const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];\n\n if (!items) {\n return {data: [], total: 0};\n }\n\n // Filter items\n let filteredItems = items;\n if (isNotNilOrBlank(value)) {\n\n // If wildcard, search using regexp\n if ((value as string).indexOf('*') !== -1) {\n value = (value as string).replace(/[*]+/g, '.*');\n filteredItems = filteredItems.filter(v => keys.findIndex(key => matchUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);\n }\n // Else (no wildcard), search using startsWith\n else {\n filteredItems = filteredItems.filter(v => keys.findIndex(key => startsWithUpperCase(getPropertyByPathAsString(v, key), value)) !== -1);\n }\n }\n\n // Exclude ids\n if (isNotEmptyArray(opts?.excludedIds)) {\n filteredItems = filteredItems.filter(v => !opts.excludedIds.includes(+v['id']));\n }\n\n // Sort\n if (!opts || opts.skipSort !== true) {\n\n // Make to copy input items, before sorting (if not yet already done)\n if (filteredItems === items) filteredItems = filteredItems.slice();\n\n // Sort by keys\n filteredItems.sort(propertiesPathComparator(keys));\n }\n\n const total = filteredItems.length || 0;\n\n // Pagination (truncate if need)\n let pageData = filteredItems;\n if (opts) {\n if ((opts.offset || 0) > 0) {\n pageData = pageData.slice(opts.offset);\n }\n if (isNotNil(opts.size) && pageData.length > opts.size) {\n pageData = pageData.slice(0, opts.size);\n }\n }\n\n const result: LoadResult<T> = {\n data: pageData,\n total\n };\n\n // Add fetch more capability, if total was fetched\n const nextOffset = (opts && opts.offset || 0) + pageData.length;\n if (nextOffset < total) {\n result.fetchMore = async (_) => suggestFromArray(filteredItems, undefined /*OPTIMISATION: already applied*/,\n {\n ...opts,\n offset: nextOffset,\n skipSort: true, // OPTIMISATION: already sorted\n excludedIds: undefined // OPTIMISATION: already filtered\n });\n }\n\n return result;\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, OnInit, Optional, Output, ViewChild} from '@angular/core';\nimport {ControlValueAccessor, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR, Validators} from '@angular/forms';\nimport {BehaviorSubject, isObservable, merge, Observable, Subject, Subscription, timer} from 'rxjs';\nimport {debounceTime, distinctUntilChanged, filter, map, mergeMap, startWith, switchMap, takeUntil, takeWhile, tap} from 'rxjs/operators';\nimport {FetchMoreFn, LoadResult, SuggestFn, SuggestService} from '../../services/entity-service.class';\nimport {\n changeCaseToUnderscore,\n isBlankString,\n isNil,\n isNilOrBlank,\n isNotNil,\n isNotNilBoolean,\n isNotNilOrBlank,\n isNotNilString,\n joinPropertiesPath,\n toBoolean,\n toNumber\n} from '../../functions';\nimport {focusInput, InputElement, selectInputRange} from '../../inputs';\nimport {firstNotNilPromise} from '../../observables';\nimport {DisplayFn, EqualsFn} from '../../form/field.model';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport {MatSelect} from '@angular/material/select';\nimport {MatAutocomplete, MatAutocompleteTrigger} from '@angular/material/autocomplete';\nimport {fromScrollEndEvent} from '../../events';\nimport {IonSearchbar} from '@ionic/angular';\nimport {slideInOutAnimation} from '../material.animations';\nimport {isMobile} from '../../platforms';\nimport {suggestFromArray} from \"../../services\";\n\n\nexport declare interface MatAutocompleteFieldConfig<T = any, F = any> {\n attributes: string[];\n suggestFn?: (value: any, options?: any) => Promise<T[] | LoadResult<T>>;\n filter?: Partial<F>;\n items?: Observable<T[]> | T[];\n columnSizes?: (number | 'auto' | undefined)[];\n columnNames?: (string | undefined)[];\n multiple?: boolean;\n displayWith?: DisplayFn;\n equals?: EqualsFn; // Used by <mat-chips-field>\n showAllOnFocus?: boolean;\n showPanelOnFocus?: boolean;\n class?: string;\n mobile?: boolean;\n debounceTime?: number;\n suggestLengthThreshold?: number;\n highlightAccent?: boolean;\n}\n\nexport declare interface MatAutocompleteFieldAddOptions<T = any, F = any> extends Partial<MatAutocompleteFieldConfig<T, F>> {\n service?: SuggestService<T, F>;\n}\n\nexport class MatAutocompleteConfigHolder {\n fields: {\n [key: string]: MatAutocompleteFieldConfig;\n } = {};\n\n getUserAttributes: (fieldName: string, defaultAttributes?: string[]) => string[];\n\n constructor(private options?: {\n getUserAttributes: (fieldName: string, defaultAttributes?: string[]) => string[];\n }) {\n // Store the function from options (e.g. get from user settings)\n // or create a default function\n this.getUserAttributes = options?.getUserAttributes ||\n ((fieldName, defaultAttributes) => defaultAttributes || ['label', 'name']);\n }\n\n add<T = any, F = any>(fieldName: string, options?: MatAutocompleteFieldAddOptions<T, F>): MatAutocompleteFieldConfig<T, F> {\n if (!fieldName) {\n throw new Error('Unable to add config, with name: ' + (fieldName || 'undefined'));\n }\n options = options || <MatAutocompleteFieldAddOptions>{};\n const suggestFn: SuggestFn<T, F> = options.suggestFn\n || (options.service && ((v, f) => options.service.suggest(v, f)))\n || undefined;\n const attributes = (this.getUserAttributes(fieldName, options.attributes) || ['label', 'name']);\n // Keep original the function from options, when exists\n const attributesOrFn = attributes.map((a, index) => typeof a === 'function' && options.attributes[index] || a);\n const filter: Partial<F> = {\n searchAttribute: attributes.length === 1 ? attributes[0] : undefined,\n searchAttributes: attributes.length > 1 ? attributes : undefined,\n ...options.filter\n };\n const displayWith = options.displayWith || MatAutocompleteFieldUtils.createDisplayFn(attributes, options.multiple);\n const equals = options.equals || MatAutocompleteFieldUtils.defaultEquals;\n\n const config: MatAutocompleteFieldConfig = {\n ...options,\n attributes: attributesOrFn,\n suggestFn,\n filter,\n displayWith,\n equals\n };\n\n this.fields[fieldName] = config;\n return config;\n }\n\n get<T = any>(fieldName: string): MatAutocompleteFieldConfig<T> {\n if (!fieldName) {\n throw new Error('Unable to add config, with name: ' + (fieldName || 'undefined'));\n }\n return this.fields[fieldName] || this.add(fieldName) as MatAutocompleteFieldConfig<T>;\n }\n}\n\nclass MatAutocompleteFieldUtils {\n static createDisplayFn(displayAttributes: string[], multiple?: boolean) {\n // if multiple (manage array)\n if (multiple) {\n return (value) => {\n return Array.isArray(value)\n ? (value || []).map(obj => obj && joinPropertiesPath(obj, displayAttributes)).join(', ')\n : value && joinPropertiesPath(value, displayAttributes)\n }\n }\n // Join properties\n return (obj) => obj && joinPropertiesPath(obj, displayAttributes);\n }\n\n static defaultEquals(o1: any, o2: any) {\n return isNotNil(o1?.id) && o1.id === o2?.id;\n }\n}\n\nconst noop = (_?: any) => {};\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'mat-autocomplete-field',\n styleUrls: ['./material.autocomplete.scss'],\n templateUrl: './material.autocomplete.html',\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: forwardRef(() => MatAutocompleteField)\n }],\n animations: [slideInOutAnimation],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatAutocompleteField implements OnInit, OnDestroy, InputElement, ControlValueAccessor {\n\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n\n @Input() equals: EqualsFn;\n @Input() logPrefix = '[mat-autocomplete] ';\n @Input() formControl: FormControl;\n @Input() formControlName: string = null;\n @Input() floatLabel: FloatLabelType;\n @Input() appearance: MatFormFieldAppearance;\n @Input() placeholder: string;\n @Input() suggestFn: SuggestFn<any, any>;\n @Input() required = false;\n @Input() mobile: boolean;\n @Input() clearable = false;\n @Input() debounceTime: number = null;\n @Input() displayWith: DisplayFn | null;\n @Input() displayAttributes: string[];\n @Input() displayColumnSizes: (number | 'auto' | undefined)[];\n @Input() displayColumnNames: string[];\n @Input() highlightAccent: boolean;\n @Input() showAllOnFocus: boolean;\n @Input() showPanelOnFocus: boolean;\n @Input() autofocus: boolean;\n @Input() config: MatAutocompleteFieldConfig;\n @Input() i18nPrefix = 'REFERENTIAL.';\n @Input() noResultMessage = 'COMMON.NO_RESULT';\n @Input('class') classList: string;\n @Input() panelWidth: string;\n @Input() matAutocompletePosition: 'auto' | 'above' | 'below';\n @Input() multiple: boolean;\n\n @Input() itemSize = '48px';\n @Input() fetchMoreThreshold: string = '15%';\n @Input() suggestLengthThreshold: number = null;\n @Input() showLoadingSpinner = true;\n @Input() debug = false;\n @Input() showSearchBar = true;\n @Input() stickySearchBar = false;\n\n @Output('click') clicked = new EventEmitter<MouseEvent>();\n @Output('blur') blurred = new EventEmitter<FocusEvent>();\n @Output('focus') focused = new EventEmitter<FocusEvent>();\n @Output() dropButtonClick = new EventEmitter<UIEvent>(true);\n @Output('keydown.escape') keydownEscape = new EventEmitter<any>();\n @Output('keyup.enter') keyupEnter = new EventEmitter<any>();\n\n @ViewChild('matSelect') matSelect: MatSelect;\n @ViewChild('ionSearchbar') ionSearchbar: IonSearchbar;\n @ViewChild('matInputText') matInputText: ElementRef;\n @ViewChild(MatAutocomplete) autocomplete: MatAutocomplete;\n @ViewChild(MatAutocompleteTrigger) autocompleteTrigger: MatAutocompleteTrigger;\n\n _readonly = false;\n _tabindex: number;\n $inputItems = new BehaviorSubject<any[]>(undefined);\n $filteredItems = new BehaviorSubject<any[]>(undefined);\n displayValue = '';\n _moreItemsCount: number;\n _fetchMore$ = new EventEmitter<Event>();\n\n private _onFetchMoreCallback: FetchMoreFn<LoadResult<any>>;\n private _implicitValue: any;\n private _subscription = new Subscription();\n private _itemsSubscription: Subscription;\n private _openedSubscription: Subscription;\n private _$filter = new BehaviorSubject<any>(undefined);\n private _itemCount: number;\n private _reload$ = new Subject<any>();\n\n constructor(\n protected cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n }\n\n get itemCount(): number {\n return this._itemCount;\n }\n\n get canFetchMore(): boolean {\n return this._onFetchMoreCallback && this._moreItemsCount > 0;\n }\n\n @Input() set filter(value: any) {\n if (value !== this._$filter.value) {\n // DEBUG\n //console.debug(this.logPrefix + \" Setting filter:\", value);\n this._$filter.next(value);\n }\n }\n\n get filter(): any {\n return this._$filter.value;\n }\n\n @Input() set readonly(value: boolean) {\n this._readonly = value;\n this.markForCheck();\n }\n\n get readonly(): boolean {\n return this._readonly;\n }\n\n @Input() set tabindex(value: number) {\n this._tabindex = value;\n this.markForCheck();\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n @Input() set items(value: Observable<any[]> | any[]) {\n // Remove previous subscription on items, (if exits)\n if (this._itemsSubscription) {\n console.warn(this.logPrefix + ' Items received twice !');\n this._subscription.remove(this._itemsSubscription);\n this._itemsSubscription.unsubscribe();\n }\n\n if (isObservable<any[]>(value)) {\n this._itemsSubscription = this._subscription.add(\n value.subscribe(v => {\n //console.warn(this.logPrefix + \" Received items: \", v);\n this.$inputItems.next(v);\n })\n );\n } else {\n if (value !== this.$inputItems.value) {\n this.$inputItems.next(value as any[]);\n }\n }\n }\n\n get items(): Observable<any[]> | any[] {\n return this.$inputItems;\n }\n\n get value(): any {\n return this.formControl.value;\n }\n\n get disabled(): boolean {\n return this._readonly || this.formControl.disabled;\n }\n\n get enabled(): boolean {\n return !this._readonly && this.formControl.enabled;\n }\n\n get loading(): boolean {\n return isNil(this.$filteredItems.value);\n }\n\n get desktop(): boolean {\n return !this.mobile && !this.multiple;\n }\n\n ngOnInit() {\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-autocomplete-field>.');\n\n // Configuration from config object\n if (this.config) {\n this.suggestFn = this.suggestFn || this.config.suggestFn;\n if (!this.suggestFn && this.config.items) {\n this.items = this.config.items;\n }\n this.filter = this.filter || this.config.filter;\n this.displayAttributes = this.displayAttributes || this.config.attributes;\n this.displayColumnSizes = this.displayColumnSizes || this.config.columnSizes;\n this.displayColumnNames = this.displayColumnNames || this.config.columnNames;\n this.displayWith = this.displayWith || this.config.displayWith;\n this.equals = this.equals || this.config.equals;\n this.multiple = toBoolean(this.multiple, this.config.multiple);\n this.mobile = toBoolean(this.mobile, this.config.mobile);\n this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold);\n this.showAllOnFocus = toBoolean(this.showAllOnFocus, this.config.showAllOnFocus);\n this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, this.config.showPanelOnFocus);\n this.classList = this.classList || this.config.class;\n this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);\n this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));\n }\n\n // Default values\n this.required = isNotNilBoolean(this.required) ? this.required : (this.formControl.validator === Validators.required || isBlankString(this.required));\n this.multiple = toBoolean(this.multiple, false);\n this.mobile = isNotNil(this.mobile) ? this.mobile : (this.multiple || isMobile(window));\n this.displayAttributes = this.displayAttributes || this.filter?.attributes || ['label', 'name'];\n this.displayWith = this.displayWith || MatAutocompleteFieldUtils.createDisplayFn(this.displayAttributes, this.multiple);\n this.equals = this.equals || MatAutocompleteFieldUtils.defaultEquals;\n\n this.displayColumnSizes = this.displayColumnSizes\n // if only column: auto size\n || (this.displayAttributes.length === 1 && [undefined])\n // Computed column size:\n // - if label then col size = 2\n // - if rankOrder then col size = 1\n // - ese => auto size\n || this.displayAttributes.map(attr =>\n attr && (attr.endsWith('label') ? 3\n : (attr.endsWith('rankOrder') ? 2\n : undefined)));\n this.displayColumnNames = this.displayAttributes.map((attr, index) => this.displayColumnNames && this.displayColumnNames[index] ||\n (this.i18nPrefix + changeCaseToUnderscore(attr).toUpperCase()));\n const classList = this.classList?.split(' ');\n this.panelWidth = this.panelWidth || (classList && (\n (classList.includes('min-width-medium') && '300px')\n || (classList.includes('min-width-large') && '400px')\n || (classList.includes('min-width-xlarge') && '450px')\n || (classList.includes('mat-autocomplete-panel-full-size') && '100vw')\n ));\n this.suggestLengthThreshold = this.suggestLengthThreshold || 0;\n this.showAllOnFocus = toBoolean(this.showAllOnFocus, this.mobile && this.suggestLengthThreshold <= 0);\n this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, true);\n this.debounceTime = toNumber(this.debounceTime, this.mobile ? 650 : 250);\n this.highlightAccent = toBoolean(this.highlightAccent, false);\n this.matAutocompletePosition = this.matAutocompletePosition || 'auto';\n\n // No suggestFn: filter on the given items\n if (!this.suggestFn) {\n const suggestFromArrayFn: SuggestFn<any, any> = async (value, filter) => {\n // DEBUG\n //console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);\n\n return suggestFromArray(this.$inputItems.value, value, {\n searchAttributes: this.displayAttributes,\n ...filter\n });\n };\n // Wait (once) that items are loaded, then call suggest from array fn\n this.suggestFn = async (value, filter) => {\n if (isNil(this.$inputItems.value)) {\n // DEBUG\n //console.debug(this.logPrefix + \" Waiting items to be set...\");\n\n await firstNotNilPromise(this.$inputItems);\n\n // DEBUG\n //console.debug(this.logPrefix + \" Received items:\", this.inputItems$.value);\n }\n this.suggestFn = suggestFromArrayFn;\n return this.suggestFn(value, filter); // Loop\n };\n }\n // Suggest + mobile\n // => Manually fill input items, from the given suggest function\n else if (this.mobile || this.multiple) {\n /*this._subscription.add(\n this._$filter.pipe(\n startWith<any, any>(this.filter),\n debounceTime(250),\n filter(_ => this.suggestLengthThreshold <= 0),\n switchMap((filter) => this.suggest('*', filter))\n )\n .subscribe(items => this.$inputItems.next(items))\n );*/\n }\n\n // Send value to suggest when :\n // - is nil and '*', and no min length threshold\n // - is not nil and not a string type (e.g. object)\n // - is not nil and is a string, and has enough character\n const thresholdFilterFn = (value) => this.suggestLengthThreshold <= 0 || (\n isNotNil(value) && (\n !(typeof value === 'string')\n || (value !== '*' && value.trim().length >= this.suggestLengthThreshold)\n )\n );\n\n const filteredItemsChanges = merge(\n\n // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)\n this._reload$\n .pipe(\n filter(() => this.enabled),\n filter(thresholdFilterFn),\n tap(_ => this.showLoadingSpinner && this.markAsLoading())\n ),\n\n // Search text (no distinctUntilChanged() because of the debounceTime() pipe)\n this.formControl.valueChanges\n .pipe(\n filter(value => this.enabled && isNotNilString(value)),\n // Mark as loading (to show loading spinner) - as soon as possible, and before debounceTime\n tap(_ => this.showLoadingSpinner && this.markAsLoading()),\n // Filter if not enough character\n filter(value => {\n if ((value?.length || 0) < this.suggestLengthThreshold) {\n // Update display value, to enable the message \"not enough characters\"\n this.displayValue = value;\n return false;\n }\n return true;\n }),\n // Wait a debounce time\n debounceTime(this.debounceTime)\n // DEBUG\n //,tap((value) => this.debug && console.debug(this.logPrefix + ' Search text changes:', value))\n ),\n\n // Object set: use it (no distinctUntilChanged() pipe need)\n this.formControl.valueChanges\n .pipe(\n startWith<any, any>(this.formControl.value),\n filter(value => (isNotNil(value) && typeof value === 'object')),\n tap(value => {\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' control object changes:', value);\n\n // Update the display value (if need)\n const displayValue = this.displayWith(value) || '';\n if (this.displayValue !== displayValue) {\n this.displayValue = displayValue;\n\n // Apply to the input[type=text] field\n if (this.matInputText?.nativeElement) {\n this.matInputText.nativeElement.value = this.displayValue;\n }\n this.markForCheck();\n }\n }),\n\n // If multiple: do not recompute items (only for the first time, when loading)\n // when formControl value changes\n filter(() => !this.multiple || this.loading),\n\n map(value => this.showAllOnFocus && this.suggestLengthThreshold <= 0 ? '*' : value)\n // DEBUG\n //,tap(value => this.debug && console.debug(this.logPrefix + ' Received an control object value: ', value))\n ),\n\n // Merge some observables, with a common distinctUntilChanged() pipe\n merge(\n // On dropdown button click (no debounceTime)\n this.dropButtonClick\n .pipe(\n filter(event => (!event || !event.defaultPrevented))\n ),\n // Focus or click => Load all (no debounceTime)\n merge(this.focused, this.clicked),\n // DEBUG\n //.pipe(tap(_ => this.debug && console.debug(this.logPrefix + ' Received focused or clicked event'))),\n // Input items or filter changes\n merge(this.$inputItems, this._$filter)\n // DEBUG\n .pipe(\n filter(_ => !this.loading)\n //,tap(_ => this.debug && console.debug(this.logPrefix + ' Received $inputItems or filter event'))\n )\n )\n .pipe(\n filter(_ => this.enabled),\n map(_ => this.showAllOnFocus ? '*' : this.formControl.value),\n // Distinguish changes\n distinctUntilChanged((v1, v2) =>\n // If loading (not loaded yet), simulate that value changed to force load\n this.loading ? false : (v1 === v2 || this.equals(v1, v2))\n ),\n // Make sure there is enough characters\n filter(thresholdFilterFn)\n // DEBUG\n //,tap(value => this.debug && console.debug(this.logPrefix + ' Received update event from observables: ', value))\n )\n )\n\n .pipe(\n // Suggest values\n mergeMap(value => this.suggest(value, this.filter)),\n // DEBUG\n //tap(items => this.debug && console.debug(this.logPrefix + ' Received from suggest: ', items)),\n\n // Store implicit value (will use it onBlur if not other value selected)\n tap(items => !this.multiple && !this.mobile && this.updateImplicitValue(items))\n );\n\n // Fetch more events\n const fetchMoreItemsChanges = this._fetchMore$\n .pipe(\n tap(event => event?.preventDefault()), // Avoid to close the mat-select\n filter(() => this.canFetchMore),\n mergeMap(() => this.fetchMore()),\n\n // DEBUG\n //tap(moreItems => console.debug(this.logPrefix + ' Received from fetch More: ', moreItems)),\n\n // Concat to existing items\n map(moreItems => (this.$filteredItems.value || []).concat(moreItems))\n );\n\n // Update filtered items\n this._subscription.add(\n merge(\n this.$inputItems,\n\n // Update items events\n filteredItemsChanges,\n\n // Fetch more events\n fetchMoreItemsChanges\n )\n .subscribe(items => {\n // Make sure control value is inside (mat-select)\n if (items && (this.mobile || this.multiple)) {\n const value = this.formControl.value;\n\n // If form value is missing: append to list\n if (isNotNil(value)) {\n if (this.multiple && Array.isArray(value)) {\n items = items.concat(\n value.filter(v => items.findIndex(item => this.equals(item, v)) === -1)\n );\n } else if (typeof value === 'object' && items.findIndex(item => this.equals(item, value)) === -1) {\n items = items.concat(value);\n }\n }\n }\n // Emit items\n this.$filteredItems.next(items);\n }));\n\n // Applying implicit value, on blur\n this._subscription.add(\n this.blurred\n .pipe(\n // Skip if multiple (no implicit value) or disable\n filter(_ => !this.multiple && !this.mobile && this.enabled),\n // DEBUG\n //,tap(_ => this.debug && console.debug(this.logPrefix + ' Received blurred event')),\n map(_ => this.formControl.value)\n )\n .subscribe(value => {\n // When leave component without object, use implicit value if :\n // - an explicit value\n // - field is not empty (user fill something)\n // - OR field empty but is required\n if (this._implicitValue && ((this.required && isNilOrBlank(value)) || (isNotNilOrBlank(value) && typeof value !== 'object'))) {\n this.writeValue(this._implicitValue);\n this.formControl.markAsPending({emitEvent: false, onlySelf: true});\n this.formControl.updateValueAndValidity({emitEvent: false, onlySelf: true});\n this.checkIfTouched();\n this.$filteredItems.next([this._implicitValue]);\n } else if (isNilOrBlank(value)) {\n this.writeValue(null);\n this.formControl.markAsPending({emitEvent: false, onlySelf: true});\n this.formControl.updateValueAndValidity({emitEvent: false, onlySelf: true});\n this.checkIfTouched();\n this.markAsLoading();\n }\n this._implicitValue = null; // reset the implicit value\n this.closePanel(); // Clone panel\n }));\n\n // Listen form control status change\n this._subscription.add(\n this.formControl.statusChanges\n .pipe(\n distinctUntilChanged()\n )\n // Update component state\n .subscribe(() => this.checkIfTouched())\n );\n\n this._subscription.add(\n this.keydownEscape.subscribe(event => {\n if (this.isOpen) {\n // Avoid form or page to manage escape event\n event?.stopPropagation();\n event?.preventDefault();\n\n // DEBUG\n //console.debug(this.logPrefix + \" Closing the panel (keydown.escape)\");\n\n this.closePanel();\n }\n })\n );\n }\n\n ngOnDestroy(): void {\n this._subscription.unsubscribe();\n if (this._itemsSubscription) {\n this._itemsSubscription.unsubscribe();\n }\n if (this._openedSubscription) {\n this._openedSubscription.unsubscribe();\n }\n this.$inputItems.complete();\n this.$inputItems.unsubscribe();\n this.$filteredItems.complete();\n this.$filteredItems.unsubscribe();\n this._reload$.complete();\n this._$filter.complete();\n\n this.dropButtonClick.complete();\n this.clicked.complete();\n this.blurred.complete();\n this.focused.complete();\n this.keydownEscape.complete();\n this.keyupEnter.complete();\n this._fetchMore$.complete();\n\n this._implicitValue = undefined;\n this.formControl = null;\n this.displayWith = null;\n this.equals = null;\n this.suggestFn = null;\n this.$filteredItems = null;\n this.config = null;\n this.classList = null;\n\n this._onChangeCallback = null;\n this._onTouchedCallback = null;\n this._onFetchMoreCallback = null;\n\n // Destroy the 'autocomplete' instance, to avoid memory leak\n if (this.autocomplete) {\n this.autocomplete.ngOnDestroy();\n }\n }\n\n /**\n * Allow to reload content. Useful when filter has been changed but not detected\n */\n reloadItems(value?: any) {\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + \" Asking to reloadItems()\");\n // Force a refresh\n this._reload$.next(value || (this.showAllOnFocus && this.suggestLengthThreshold <= 0 ? '*' : this.formControl.value));\n\n // Clear the search bar (if hidden)\n if (this.mobile && !this.matSelect.panelOpen && this.ionSearchbar) {\n this.ionSearchbar.value = null;\n }\n }\n\n writeValue(value: any): void {\n // DEBUG\n // if (this.debug) console.debug(this.logPrefix + ' Writing value: ', value);\n\n if (value !== this.formControl.value) {\n this.formControl.patchValue(value, {emitEvent: false});\n this.displayValue = this.displayWith(value);\n this._onChangeCallback(value);\n }\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (isDisabled && this.autocomplete?.isOpen) {\n this.closePanel();\n }\n this.cd.markForCheck();\n }\n\n focus() {\n if (this.mobile) {\n this.matSelect.focus();\n } else {\n focusInput(this.matInputText);\n }\n }\n\n filterInputTextFocusEvent(event: FocusEvent) {\n if (!event || event.defaultPrevented) return;\n\n // Ignore event from mat-option\n if (event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') {\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Cancelling focus event');\n\n return false;\n }\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Select input content');\n const hasContent = isNotNilOrBlank((event.target as any)?.value);\n\n // If combo is empty, or if has content but should force to show panel on focus\n if (!hasContent || this.showPanelOnFocus || this.showAllOnFocus) {\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Emit focus event');\n\n this.focused.emit();\n return true;\n }\n return false;\n }\n\n filterInputTextBlurEvent(event: FocusEvent) {\n if (!event || event.defaultPrevented) return;\n\n // Ignore event from mat-option\n if (event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') {\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + \" Cancelling blur event\");\n\n return false;\n }\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Blur: move caret to the beginning');\n\n // Move caret to the beginning (fix issue IMAGINE-469)\n selectInputRange(event.target as any, 0, 0);\n\n this.blurred.emit(event);\n return true;\n }\n\n ionSearchBarChanged(event: CustomEvent<any>, value: string) {\n if (!event || event.defaultPrevented || !this.matSelect.panelOpen) return;\n event.preventDefault();\n event.stopPropagation();\n\n // DEBUG\n //console.debug(this.logPrefix + \" Received <ion-searchbar> changes\", );\n\n if (this.multiple) {\n this.reloadItems(value);\n }\n else {\n this.displayValue = value;\n this.reloadItems(value);\n }\n\n // TODO Find a way to avoid mat-select to give focus to an option, when typing\n /*if (this.multiple) {\n this.matSelect._elementRef;\n }*/\n }\n\n filterMatSelectFocusEvent(event: FocusEvent) {\n if (!event || event.defaultPrevented) return;\n // DEBUG\n // console.debug(this.logPrefix + \" Received <mat-select> focus event\", event);\n this.focused.emit(event);\n }\n\n filterMatSelectBlurEvent(event: FocusEvent) {\n if (!event || event.defaultPrevented) return;\n\n // DEBUG\n // console.debug(this.logPrefix + \" Received <mat-select> blur event\", event);\n\n\n if (event.relatedTarget instanceof HTMLElement && (\n // Ignore event from mat-option\n (event.relatedTarget.tagName === 'MAT-OPTION')\n || (event.relatedTarget.tagName === 'INPUT') && event.relatedTarget.classList.contains('searchbar-input'))) {\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n // DEBUG\n // console.debug(this.logPrefix + \" Cancelling <mat-select> blur event\");\n return false;\n }\n\n this.blurred.emit(event);\n return true;\n }\n\n clearValue(event: UIEvent) {\n this.writeValue(null);\n event.stopPropagation();\n if (this.ionSearchbar) {\n this.ionSearchbar.value = null;\n }\n this.markAsLoading();\n }\n\n _initAutocompleteInfiniteScroll(threshold?: string) {\n if (!this.autocomplete) return; // Skip\n\n // DEBUG\n //console.debug(this.logPrefix + ' Init autocomplete scroll listener');\n\n if (this._openedSubscription) {\n this._openedSubscription.unsubscribe();\n this._subscription.remove(this._openedSubscription);\n }\n\n const opened$: Observable<any> = this.autocomplete._isOpen\n ? timer(0)\n : this.autocomplete.opened.pipe(debounceTime(200));\n const scrollEnd$ = opened$\n .pipe(\n map((_) => this.getAutocompletePanel()),\n filter(isNotNil),\n switchMap((panel) => fromScrollEndEvent(panel, threshold)\n .pipe(\n takeUntil(this.autocomplete.closed)\n )\n )\n );\n\n // Trigger fetch more, end end scroll reached\n this._openedSubscription = scrollEnd$\n .subscribe(() => this._fetchMore$.emit());\n\n // Register subscription\n this._subscription.add(this._openedSubscription);\n }\n\n _initMatSelectInfiniteScroll(threshold?: string) {\n if (!this.matSelect) return; // Skip\n\n // DEBUG\n //console.debug(this.logPrefix + ' Init mat-select scroll listener');\n\n if (this._openedSubscription) {\n this._openedSubscription.unsubscribe();\n this._subscription.remove(this._openedSubscription);\n }\n\n const opened$: Observable<any> = this.matSelect.panelOpen\n ? timer(0)\n : this.matSelect._openedStream.pipe(debounceTime(200));\n const scrollEnd$ = opened$\n .pipe(\n map((_) => this.getMatSelectPanel()),\n filter(isNotNil),\n switchMap((panel) => fromScrollEndEvent(panel, threshold)\n .pipe(\n takeUntil(this.matSelect._closedStream)\n )\n )\n );\n\n // Trigger fetch more, end end scroll reached\n this._openedSubscription = scrollEnd$\n .pipe(\n filter(_ => this._moreItemsCount > 0)\n )\n .subscribe(() => this._fetchMore$.emit());\n\n // Register subscription\n this._subscription.add(this._openedSubscription);\n }\n\n get isOpen(): boolean {\n return (!this.mobile && this.autocomplete?.isOpen)\n || (this.matSelect?.panelOpen)\n || false;\n }\n\n closePanel() {\n if (this.autocomplete?.isOpen) {\n this.autocompleteTrigger?.closePanel();\n return;\n }\n if (this.matSelect?.panelOpen) {\n this.matSelect?.close();\n }\n }\n\n /* -- private method -- */\n\n private async suggest(value: any, filter?: any): Promise<any[]> {\n // Call suggestion function\n let res = await this.suggestFn(value, filter);\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);\n\n if (!res) {\n this._itemCount = 0;\n this._onFetchMoreCallback = undefined;\n this._moreItemsCount = 0;\n }\n else if (Array.isArray(res)) {\n this._itemCount = (res as any[]).length || 0;\n this._onFetchMoreCallback = undefined;\n this._moreItemsCount = 0;\n }\n else {\n const {data, total, fetchMore} = res as LoadResult<any>;\n this._itemCount = toNumber(total, data && data.length || 0);\n this._onFetchMoreCallback = fetchMore;\n this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;\n res = data;\n }\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);\n\n return res as any[];\n }\n\n private async fetchMore(): Promise<any[]> {\n if (!this._onFetchMoreCallback) return [];\n\n // Save then remove fetch function (to avoid multi-call)\n const fetchMoreFn = this._onFetchMoreCallback;\n this._onFetchMoreCallback = undefined;\n\n const {data, total, fetchMore} = await fetchMoreFn();\n this._itemCount = total || this._itemCount;\n this._onFetchMoreCallback = fetchMore;\n this._moreItemsCount = Math.max(0, this._moreItemsCount - data.length); // Borne min = 0\n return data;\n }\n\n private updateImplicitValue(items: any[]) {\n if (!this.multiple) {\n // Store implicit value (will use it onBlur if not other value selected)\n if (items && items.length === 1) {\n this._implicitValue = items[0];\n //this.formControl.setErrors(null);\n } else {\n this._implicitValue = undefined;\n }\n }\n }\n\n private checkIfTouched() {\n if (this.formControl.touched) {\n this.cd.markForCheck();\n this._onTouchedCallback();\n }\n }\n\n private getAutocompletePanel(): HTMLElement {\n const ele = this.autocomplete?.options.last?._getHostElement().parentElement;\n if (!ele) {\n // DEBUG\n console.warn(this.logPrefix + ' Unable to find the autocomplete div...');\n }\n return ele;\n }\n\n private getMatSelectPanel(): HTMLElement {\n const ele = this.matSelect.options.last?._getHostElement().parentElement;\n if (!ele) {\n // DEBUG\n console.warn(this.logPrefix + ' Unable to find the mat-select container...');\n }\n return ele;\n }\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n\n markAsLoading() {\n if (this.$filteredItems.value) {\n this.$filteredItems.next(undefined);\n this._itemCount = undefined;\n this._implicitValue = undefined;\n this._onFetchMoreCallback = undefined;\n this._moreItemsCount = 0;\n this.markForCheck();\n }\n }\n}\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {isMoment, Moment} from 'moment';\nimport {DATE_ISO_PATTERN} from '../constants';\nimport {TranslateService} from '@ngx-translate/core';\nimport {MomentDateAdapter} from '@angular/material-moment-adapter';\n\n@Pipe({\n name: 'dateFormat'\n})\n@Injectable({providedIn: 'root'})\nexport class DateFormatPipe implements PipeTransform {\n\n private readonly datePattern: string;\n private readonly dateTimePattern: string;\n private readonly dateTimeSecondsPattern: string;\n\n constructor(\n private dateAdapter: MomentDateAdapter,\n private translate: TranslateService\n ) {\n\n const translations = translate.instant(['COMMON.DATE_PATTERN', 'COMMON.DATE_TIME_PATTERN', 'COMMON.DATE_TIME_SECONDS_PATTERN']);\n this.datePattern = translations['COMMON.DATE_PATTERN'];\n this.dateTimePattern = translations['COMMON.DATE_TIME_PATTERN'];\n this.dateTimeSecondsPattern = translations['COMMON.DATE_TIME_SECONDS_PATTERN'];\n }\n\n transform(value: string | Moment | Date, args?: { pattern?: string; time?: boolean; seconds?: boolean } ): string {\n const pattern = args && args.pattern ||\n (args && args.time ? (args.seconds ? this.dateTimeSecondsPattern : this.dateTimePattern) : this.datePattern);\n // Keep original moment object, if possible (to avoid a conversion)\n const date: Moment = isMoment(value) ? value : this.dateAdapter.parse(value, DATE_ISO_PATTERN);\n return date && this.dateAdapter.format(date, pattern) || '';\n }\n\n format(date: Moment, pattern: any): string {\n return this.dateAdapter.format(date, pattern);\n }\n\n parse(value: string, parseFormat: any): Moment {\n return isMoment(value) ? value : this.dateAdapter.parse(value, parseFormat || DATE_ISO_PATTERN);\n }\n}\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\nimport * as momentImported from 'moment';\nimport { Moment } from 'moment';\nimport { DateAdapter } from '@angular/material/core';\nimport { DATE_ISO_PATTERN } from '../constants';\nimport { TranslateService } from '@ngx-translate/core';\n\nconst moment = momentImported;\n\n@Pipe({\n name: 'dateDiffDuration'\n})\n@Injectable({providedIn: 'root'})\nexport class DateDiffDurationPipe implements PipeTransform {\n\n protected dayUnit: string;\n\n constructor(\n private dateAdapter: DateAdapter<Moment>,\n private translate: TranslateService) {\n\n this.dayUnit = translate.instant('COMMON.DAY_UNIT');\n translate.get('COMMON.DAY_UNIT').subscribe(dayUnit => this.dayUnit = dayUnit);\n }\n\n transform(value: { startValue: string | Moment; endValue: string | Moment }, args?: { seconds?: boolean }): string | Promise<string> {\n if (!value.startValue || !value.endValue) return '';\n\n const startDate = this.dateAdapter.parse(value.startValue, DATE_ISO_PATTERN);\n const endDate = this.dateAdapter.parse(value.endValue, DATE_ISO_PATTERN);\n\n return this.format(startDate, endDate, args);\n }\n\n format(startDate: Moment, endDate: Moment, args: { seconds?: boolean }): string {\n const duration = moment.duration(endDate.diff(startDate));\n if (duration.asMinutes() < 0) return '';\n const withSeconds = args?.seconds;\n\n const timeDuration = moment(0)\n .hour(duration.hours())\n .minute(duration.minutes());\n if (withSeconds) {\n timeDuration.second(duration.seconds());\n }\n\n const days = Math.floor(duration.asDays());\n return (days > 0 ? days.toString() + (this.dayUnit + ' ') : '') + timeDuration.format(withSeconds ? 'HH:mm:ss' : 'HH:mm');\n }\n}\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {isMoment, Moment} from 'moment';\nimport {DATE_ISO_PATTERN} from '../constants';\nimport {MomentDateAdapter} from '@angular/material-moment-adapter';\n\n@Pipe({\n name: 'dateFromNow'\n})\n@Injectable({providedIn: 'root'})\nexport class DateFromNowPipe implements PipeTransform {\n\n constructor(\n private dateAdapter: MomentDateAdapter) {\n }\n\n transform(value: string | Moment, args?: any): string | Promise<string> {\n const date: Moment = isMoment(value) ? value as Moment : this.dateAdapter.parse(value, DATE_ISO_PATTERN);\n return date ? date.fromNow(args && args.withoutSuffix) : '';\n }\n}\n","import {DEFAULT_PLACEHOLDER_CHAR} from '../../constants';\n\nexport declare type LatLongPattern = 'DDMMSS' | 'DDMM' | 'DD';\nexport const LAT_LONG_PATTERNS: LatLongPattern[] = ['DDMMSS', 'DDMM', 'DD'];\n\nexport declare class LatLongFormatOptions {\n pattern: LatLongPattern;\n maxDecimals?: number;\n placeholderChar?: string;\n hideSign?: boolean;\n}\nexport declare type LatLongFormatFn = (value: number | null, opts?: LatLongFormatOptions) => string;\nexport const LAT_LONG_DEFAULT_MAX_DECIMALS = 3;\n\n\nconst DEFAULT_OPTIONS = <LatLongFormatOptions>{\n pattern: 'DDMM',\n maxDecimals: LAT_LONG_DEFAULT_MAX_DECIMALS,\n placeholderChar: DEFAULT_PLACEHOLDER_CHAR\n};\nconst DEFAULT_LATITUDE_OPTIONS: LatLongFormatOptions & { longitude: boolean } = {\n ...DEFAULT_OPTIONS,\n longitude: false\n};\nconst DEFAULT_LONGITUDE_OPTIONS: LatLongFormatOptions & { longitude: boolean } = {\n ...DEFAULT_OPTIONS,\n longitude: true\n};\nexport function formatLatitude(value: number | null, opts?: Partial<LatLongFormatOptions>): string {\n if (value === undefined || value === null) return null;\n\n switch(opts.pattern) {\n case 'DDMMSS':\n return formatToDDMMSS(value, { ...DEFAULT_LATITUDE_OPTIONS, ...opts });\n case 'DDMM':\n return formatToDDMM(value, { ...DEFAULT_LATITUDE_OPTIONS, ...opts });\n case 'DD':\n default:\n return formatToDD(value, { ...DEFAULT_LATITUDE_OPTIONS, ...opts });\n }\n}\n\nexport function formatLongitude(value: number | null, opts?: Partial<LatLongFormatOptions>): string {\n if (value === undefined || value === null) return null;\n\n switch(opts.pattern) {\n case 'DDMMSS':\n return formatToDDMMSS(value, { ...DEFAULT_LONGITUDE_OPTIONS, ...opts });\n case 'DDMM':\n return formatToDDMM(value, { ...DEFAULT_LONGITUDE_OPTIONS, ...opts });\n case 'DD':\n default:\n return formatToDD(value, { ...DEFAULT_LONGITUDE_OPTIONS, ...opts });\n }\n}\n\nfunction formatToDD(value: number, opts: LatLongFormatOptions & {longitude: boolean}): string {\n // opts.pattern === DD\n let negative = value < 0;\n if (negative) value *= -1;\n\n // Fix longitude when outside [-180, 180]\n if (opts.longitude) {\n while (value > 180) {\n value = (value - 180);\n negative = value < 0;\n if (negative) value *= -1;\n }\n }\n // Fix latitude when outside [-90, 90]\n else {\n while (value > 90) {\n value = (value - 90);\n negative = value < 0;\n if (negative) value *= -1;\n }\n }\n\n let degrees = roundFloat(value, opts.maxDecimals).toString();\n\n // Add sign\n let sign = negative ? '-' : '+';\n\n if (opts.placeholderChar) {\n if (opts.longitude) {\n if (value < 100) {\n degrees = opts.placeholderChar + degrees;\n }\n }\n else {\n sign += ' '; // Add space after the sign\n }\n if (value < 10) {\n degrees = opts.placeholderChar + degrees;\n }\n // Add decimal separator\n const integerLength = (opts.longitude && 3 || 2);\n if (degrees.length === integerLength) {\n degrees += '.';\n }\n // Add trailing placeholder chars\n while ((degrees.length < opts.maxDecimals + integerLength)) {\n degrees += opts.placeholderChar;\n }\n }\n return (opts.hideSign ? '' : sign) + degrees + '°';\n}\n\nfunction formatToDDMMSS(value: number, opts: LatLongFormatOptions & {longitude: boolean}): string {\n let negative = value < 0;\n if (negative) value *= -1;\n\n // Fix longitude when outside [-180, 180]\n if (opts.longitude) {\n while (value > 180) {\n value = (value - 180);\n negative = value < 0;\n if (negative) value *= -1;\n }\n }\n // Fix latitude when outside [-90, 90]\n else {\n while (value > 90) {\n value = (value - 90);\n negative = value < 0;\n if (negative) value *= -1;\n }\n }\n\n let degrees: number = Math.trunc(value);\n let minutes: number | string = Math.trunc((value - degrees) * 60);\n let seconds: number | string = roundFloat(((value - degrees) * 60 - minutes) * 60, opts.maxDecimals);\n\n while (seconds >= 60) {\n seconds -= 60;\n minutes += 1;\n }\n while (minutes >= 60) {\n minutes -= 60;\n degrees += 1;\n }\n const sign = opts.longitude ? (negative ? 'W' : 'E') : (negative ? 'S' : 'N');\n\n // Force spacer\n let prefix = '';\n if (opts.placeholderChar) {\n if (opts.longitude && degrees < 100) {\n prefix += opts.placeholderChar;\n }\n if (degrees < 10) {\n prefix += opts.placeholderChar;\n }\n\n if (minutes < 10) {\n minutes = opts.placeholderChar + minutes;\n }\n\n if (seconds < 10) {\n seconds = opts.placeholderChar + seconds;\n }\n else {\n seconds = seconds.toString(); // convert to string - required for the next while\n }\n if (opts.maxDecimals > 0) {\n // Add decimal separator\n if (seconds.length === 2) {\n seconds += '.';\n }\n // Add trailing placeholder chars\n while ((seconds.length < opts.maxDecimals + 3)) {\n seconds += opts.placeholderChar;\n }\n }\n }\n\n const output = prefix + degrees + '° ' + minutes + '\\' ' + seconds + '\"'\n + (opts.hideSign ? '' : ' ' + sign);\n\n // DEBUG\n //console.debug(\"formatToDDMMSS: \" + value + \" -> \" + output);\n\n\n return output;\n}\n\nfunction formatToDDMM(value: number, opts: LatLongFormatOptions & {longitude: boolean}): string {\n let negative = value < 0;\n if (negative) value *= -1;\n\n // Fix longitude when outside [-180, 180]\n if (opts.longitude) {\n while (value > 180) {\n value = (value - 180);\n negative = value < 0;\n if (negative) value *= -1;\n }\n }\n // Fix latitude when outside [-90, 90]\n else {\n while (value > 90) {\n value = (value - 90);\n negative = value < 0;\n if (negative) value *= -1;\n }\n }\n\n let degrees: number | string = Math.trunc(value);\n let minutes: number | string = roundFloat((value - degrees) * 60, opts.maxDecimals);\n while (minutes >= 60) {\n minutes -= 60;\n degrees += 1;\n }\n const sign = opts.longitude ? (negative ? 'W' : 'E') : (negative ? 'S' : 'N');\n\n // Add placeholderChar\n let prefix = '';\n if (opts.placeholderChar) {\n if (opts.longitude && degrees < 100) {\n prefix += opts.placeholderChar;\n }\n if (degrees < 10) {\n prefix += opts.placeholderChar;\n }\n\n if (minutes < 10) {\n minutes = opts.placeholderChar + minutes;\n }\n else {\n minutes = minutes.toString(); // convert to string - required for the next while\n }\n if (opts.maxDecimals > 0) {\n // Add decimal separator\n if (minutes.length === 2) {\n minutes += '.';\n }\n // Add trailing placeholder chars\n while ((minutes.length < opts.maxDecimals + 3)) {\n minutes += opts.placeholderChar;\n }\n }\n }\n const output = prefix + degrees + '° ' + minutes + '\\''\n + (opts.hideSign ? '' : ' ' + sign);\n\n // DEBUG\n //console.debug('formatToDDMM output:', output);\n\n return output;\n}\n\n// 36°57'9\" N = 36.9525000\n// 10°4'21\" W = -10.0725000\nexport function parseLatitudeOrLongitude(input: string, pattern: string, maxDecimals?: number, placeholderChar?: string): number | null {\n // Remove all placeholder (= trim on each parts)\n const inputFix = input.trim().replace(new RegExp('[ +' + (placeholderChar || DEFAULT_PLACEHOLDER_CHAR) + ']+', 'g'), '');\n //DEBUG console.debug(\"Parsing lat= \" + inputFix);\n const parts = inputFix.split(/[^-\\d\\w.,]+/);\n let degrees = parseFloat(parts[0].replace(/,/g, '.'));\n if (isNaN(degrees)) {\n console.debug('parseLatitudeOrLongitude ' + input + ' -> Invalid degrees (NaN). Parts found:', parts);\n return NaN;\n }\n\n if (pattern === 'DD') return roundFloat(degrees, maxDecimals);\n\n const minutes = (pattern === 'DDMMSS' || pattern === 'DDMM') && parts[1] && parseFloat(parts[1].replace(/,/g, '.')) || 0;\n const seconds = (pattern === 'DDMMSS') && parts[2] && parseFloat(parts[2].replace(/,/g, '.')) || 0;\n const direction = ((pattern === 'DDMMSS') && parts[3]) || ((pattern === 'DDMM') && parts[2]) || undefined;\n const sign = (direction && (direction === 's' || direction === 'S' || direction === 'w' || direction === 'W')) ? -1 : 1;\n\n degrees = sign * (degrees + minutes / 60 + seconds / (60 * 60));\n\n return roundFloat(degrees, maxDecimals);\n}\n\nfunction roundFloat(input: number, maxDecimals?: number): number {\n if (maxDecimals > 0) {\n\n const powDecimal = Math.pow(10, maxDecimals);\n return Math.trunc(input * powDecimal + 0.5) / powDecimal;\n }\n // no decimals: round to integer\n else if (maxDecimals === 0) {\n return Math.trunc(input + 0.5);\n }\n return input;\n}\n","import {Pipe, PipeTransform} from '@angular/core';\nimport {formatLatitude, formatLongitude, LatLongFormatOptions} from '../material/latlong/latlong.utils';\n\n\n@Pipe({\n name: 'latitudeFormat'\n})\nexport class LatitudeFormatPipe implements PipeTransform {\n transform = formatLatitude;\n}\n\n@Pipe({\n name: 'longitudeFormat'\n})\nexport class LongitudeFormatPipe implements PipeTransform {\n transform = formatLongitude;\n}\n\n@Pipe({\n name: 'latLongFormat'\n})\n/**\n * @deprecated use 'latitudeFormat' or 'longitudeFormat' instead\n */\nexport class LatLongFormatPipe implements PipeTransform {\n\n transform(value: number, opts?: Partial<LatLongFormatOptions> & {type: 'latitude'|'longitude'}): string | Promise<string> {\n return ((!opts || opts?.type !== 'latitude') ? formatLongitude : formatLatitude)(value, opts);\n }\n}\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'numberFormat'\n})\n@Injectable({providedIn: 'root'})\nexport class NumberFormatPipe implements PipeTransform {\n\n transform(val: number, opts?: Intl.NumberFormatOptions & {fixedDecimals?: number}): string | Promise<string> {\n // Format the output to display any way you want here.\n // For instance:\n if (val !== undefined && val !== null) {\n if (opts?.fixedDecimals) {\n return val.toFixed(opts.fixedDecimals);\n }\n return val.toLocaleString(undefined, opts);\n } else {\n return '';\n }\n }\n}\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\nimport { removeDiacritics, toBoolean } from '../functions';\n\n@Pipe({\n name: 'highlight'\n})\n@Injectable({providedIn: 'root'})\nexport class HighlightPipe implements PipeTransform {\n\n // Replace search text by bold representation\n transform(value: any, args?: string | { search: string; withAccent?: boolean } ): string {\n if (typeof value !== 'string' || !args) return value;\n const searchText = (typeof args === 'string' ? args : args.search);\n const withAccent = (typeof args !== 'string') ? toBoolean(args?.withAccent, false) : false;\n if (typeof searchText !== 'string') return value;\n const searchRegexp = searchText\n .replace(/[.]/g, '[.]')\n .replace(/[*]+/g, '.*');\n if (searchRegexp === '.*') return value; // skip if can match everything\n\n if (withAccent) {\n // Remove all accent characters to allow versatile comparison\n const cleanedSearchText = removeDiacritics(searchRegexp).toUpperCase();\n const index = removeDiacritics(value.toUpperCase()).indexOf(cleanedSearchText);\n if (index !== -1) {\n return value.substring(0, index - 1) +\n '<b>' + value.substring(index, cleanedSearchText.length) + '</b>' +\n value.substring(index + cleanedSearchText.length);\n }\n return value;\n } else {\n // Default behaviour\n const regexp = new RegExp('[ ]?' + searchRegexp, 'gi');\n return ('' + value).replace(regexp, '<b>$&</b>');\n }\n }\n}\n","/**\n * @license\n * Copyright (c) 2019 Jonathan Catmull.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport {Pipe, PipeTransform} from '@angular/core';\n\n/*\n * Convert bytes into largest possible unit.\n * Takes an precision argument that defaults to 2.\n * Usage:\n * bytes | fileSize:precision\n * Example:\n * {{ 1024 | fileSize}}\n * formats to: 1 KB\n*/\n@Pipe({name: 'fileSize'})\nexport class FileSizePipe implements PipeTransform {\n\n private units = [\n 'bytes',\n 'KB',\n 'MB',\n 'GB',\n 'TB',\n 'PB'\n ];\n\n transform(bytes: number = 0, precision: number = 2 ): string {\n if ( isNaN( parseFloat( String(bytes) )) || ! isFinite( bytes ) ) return '?';\n\n let unit = 0;\n\n while ( bytes >= 1024 ) {\n bytes /= 1024;\n unit ++;\n }\n\n return bytes.toFixed( + precision ) + ' ' + this.units[ unit ];\n }\n}\n","import * as momentImported from 'moment';\nimport { Duration, isMoment, Moment, unitOfTime } from 'moment';\nimport { DATE_ISO_PATTERN, DATE_PATTERN } from './constants';\n\nconst moment = momentImported;\n\nexport const DATE_UNIX_TIMESTAMP = 'X';\nexport const DATE_UNIX_MS_TIMESTAMP = 'x';\nexport const MOMENT_NO_TIME_PROPERTY = '_hasNoTime';\n\nexport class DateUtils {\n static toDateISOString = toDateISOString;\n static fromDateISOString = fromDateISOString;\n static toDuration = toDuration;\n\n static min(date1: Moment, date2: Moment): Moment {\n return date1 && (!date2 || date1.isSameOrBefore(date2)) ? date1 : date2;\n }\n\n static max(date1: Moment, date2: Moment): Moment {\n return date1 && (!date2 || date1.isSameOrAfter(date2)) ? date1 : date2;\n }\n\n static equals(date1: Moment | string, date2: Moment | string): boolean {\n return DateUtils.isSame(date1, date2);\n }\n\n static isSame(date1: Moment | string, date2: Moment | string, granularity?: unitOfTime.StartOf): boolean {\n const d1 = fromDateISOString(date1);\n const d2 = fromDateISOString(date2);\n return (!d1 && !d2) || d1.isSame(d2, granularity);\n }\n\n /**\n * Create a copy of a date, without time fields (always return a new Moment object, or undefined).\n * Same implementation as the Java class Dates.resetTime() (see any SUMARiS like Pod)\n * @param value\n * @param timezone a timezone (see https://momentjs.com/timezone/)\n * @param keepLocalTime if true, only the timezone (and offset) is updated, keeping the local time same. Consequently, it will now point to a different point in time if the offset has changed.\n */\n static resetTime(value: Moment|string, timezone?: string, keepLocalTime?: boolean): Moment | undefined {\n if (!value) return undefined;\n const date = fromDateISOString(value);\n // No timezone\n if (!timezone) {\n return date.clone().startOf('day');\n }\n // Use timezone\n return date.clone() // clone the original date\n .tz(timezone, keepLocalTime)\n .startOf('day');\n }\n\n static markNoTime(value: Moment): Moment | undefined {\n if (!value) return undefined;\n value[MOMENT_NO_TIME_PROPERTY] = true;\n return value;\n }\n\n static isNoTime(value: Moment): boolean {\n return value?.[MOMENT_NO_TIME_PROPERTY] === true;\n }\n\n /**\n * Test if a date is on the given day of week\n * @param date\n * @param weekday\n * @param timezone\n */\n static isAtDay(date: string|Moment, weekday: number, timezone?: string): boolean {\n date = date && fromDateISOString(date);\n if (!date) return null;\n if (timezone) date = date.clone().tz(timezone).startOf('day');\n return date.day() === weekday;\n }\n}\n\nexport function toDateISOString(value: any): string | undefined {\n if (!value) return undefined;\n\n // Already a valid ISO date time string (without timezone): use it\n if (typeof value === 'string'\n && value.indexOf('+') === -1\n && value.lastIndexOf('Z') === value.length - 1) {\n\n return value;\n }\n // Make sure to have a Moment object\n const date = fromDateISOString(value);\n if (!date) return undefined;\n return DateUtils.isNoTime(date)\n ? date.toISOString(true /* important ! */).substr(0, 10)\n : date.toISOString();\n}\n\nexport function fromDateISOString(value: any): Moment | undefined {\n // Already a moment object: use it\n if (!value || isMoment(value)) return value;\n\n if (typeof value === 'string' && value.length === 10) {\n // Parse the input value, as a date only\n const dateOnly: Moment = moment(value, DATE_PATTERN);\n if (dateOnly.isValid()) return DateUtils.markNoTime(dateOnly);\n }\n\n // Parse the input value, as a ISO date time\n const date: Moment = moment(value, DATE_ISO_PATTERN);\n if (date.isValid()) return date;\n\n // Not valid: trying to convert from unix timestamp\n if (typeof value === 'string') {\n console.warn('Wrong date format - Trying to convert from local time: ' + value);\n if (value.length === 10) {\n return moment(value, DATE_UNIX_TIMESTAMP);\n }\n else if (value.length === 13) {\n return moment(value, DATE_UNIX_MS_TIMESTAMP);\n }\n }\n\n console.warn('Unable to parse date: ' + value);\n return undefined;\n}\n\nexport function fromUnixTimestamp(timeInSec: number) {\n return moment(timeInSec, DATE_UNIX_TIMESTAMP);\n}\nexport function fromUnixMsTimestamp(timeInMs: number) {\n return moment(timeInMs, DATE_UNIX_MS_TIMESTAMP);\n}\n\nexport function toDuration(value: number, unit?: moment.unitOfTime.DurationConstructor): Duration {\n if (!value) return undefined;\n\n const duration = moment.duration(value, unit);\n\n // fix 990+ ms\n if (duration.milliseconds() >= 990) {\n duration.add(1000 - duration.milliseconds(), 'ms');\n }\n // fix 59 s\n if (duration.seconds() >= 59) {\n duration.add(60 - duration.seconds(), 's');\n }\n\n return duration;\n}\n\n\n","import {Pipe, Injectable, PipeTransform} from '@angular/core';\nimport {TranslateService} from '@ngx-translate/core';\nimport {toDuration} from '../dates';\n\n@Pipe({\n name: 'duration'\n})\n@Injectable({providedIn: 'root'})\nexport class DurationPipe implements PipeTransform {\n\n protected dayUnit: string;\n\n constructor(\n private translate: TranslateService\n ) {\n this.dayUnit = translate.instant('COMMON.DAY_UNIT');\n }\n\n transform(value: number, args?: any): string {\n if (!value) return '';\n const unit = args && args.unit || 'hours';\n\n // try with moment\n const duration = toDuration(value, unit);\n\n const days = duration.days();\n const hour = duration.hours().toString().padStart(2, '0');\n const minute = duration.minutes().toString().padStart(2, '0');\n\n return (days > 0 ? days.toString() + (this.dayUnit + ' ') : '') + hour + ':' + minute;\n\n }\n}\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\n\n@Pipe({\n name: 'mathAbs'\n})\n@Injectable({providedIn: 'root'})\nexport class MathAbsPipe implements PipeTransform {\n\n transform(val: number): any {\n if (val !== undefined && val !== null) {\n return Math.abs(val);\n } else {\n return val;\n }\n }\n}\n\n@Pipe({\n name: 'even'\n})\n@Injectable({providedIn: 'root'})\nexport class EvenPipe implements PipeTransform {\n\n transform(val: number): any {\n return val % 2 === 0;\n }\n}\n\n@Pipe({\n name: 'odd'\n})\n@Injectable({providedIn: 'root'})\nexport class OddPipe implements PipeTransform {\n\n transform(val: number): any {\n return val % 2 !== 0;\n }\n}\n\n","import {Pipe, PipeTransform} from '@angular/core';\nimport {getPropertyByPath, isNotNil} from '../functions';\n\n@Pipe({\n name: 'isNotEmptyArray'\n})\nexport class NotEmptyArrayPipe implements PipeTransform {\n\n transform(val: any[]): boolean {\n if (val === undefined || val === null) {\n return false;\n }\n return val.length > 0;\n }\n}\n\n\n@Pipe({\n name: 'isEmptyArray'\n})\nexport class EmptyArrayPipe implements PipeTransform {\n\n transform(val: any[]): boolean {\n if (val === undefined || val === null) {\n return true;\n }\n return val.length === 0;\n }\n}\n\n\n@Pipe({\n name: 'isArrayLength'\n})\nexport class ArrayLengthPipe implements PipeTransform {\n\n transform(val: any[], args?: { greaterThan?: number; equals?: number; lessThan?: number }): boolean {\n args = args || {};\n const size = (val === undefined || val === null) ? 0 : val.length;\n if (isNotNil(args.lessThan)) {\n return size < args.lessThan;\n }\n if (isNotNil(args.greaterThan)) {\n return size > args.greaterThan;\n }\n if (isNotNil(args.equals)) {\n return size === args.equals;\n }\n return false;\n }\n}\n\n@Pipe({\n name: 'arrayFirst'\n})\nexport class ArrayFirstPipe implements PipeTransform {\n\n transform<T>(val: T[]): T | undefined {\n return val && val.length > 0 ? val[0] : undefined;\n }\n}\n\n@Pipe({\n name: 'arrayPluck'\n})\nexport class ArrayPluckPipe implements PipeTransform {\n\n /**\n *\n * @param values\n * @param opts property to get, or options\n */\n transform<T>(values: T[], opts: string | string[] | { property: string|string[]; omitNil?: boolean }): any[] {\n if (!opts || !values) return values;\n const property = (typeof opts === 'string') || Array.isArray(opts) ? opts as string|string[] : opts.property;\n return (opts['omitNil'] !== true) ?\n values.map(value => getPropertyByPath(value, property)) :\n values.map(value => getPropertyByPath(value, property)).filter(isNotNil);\n }\n}\n\n@Pipe({\n name: 'arrayIncludes'\n})\nexport class ArrayIncludesPipe implements PipeTransform {\n\n transform<T>(val: T[], args): boolean {\n return val && val.includes(args) || false;\n }\n}\n\n\n@Pipe({\n name: 'arrayFilter'\n})\nexport class ArrayFilterPipe implements PipeTransform {\n\n transform<T>(val: T[], filterFn: (T) => boolean): T[] {\n return val && val.filter(filterFn);\n }\n}\n\n@Pipe({\n name: 'arrayJoin'\n})\nexport class ArrayJoinPipe implements PipeTransform {\n\n transform<T>(val: T[], separator: string): string {\n return val && val.join(separator) || '';\n }\n}\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'mapGet'\n})\n@Injectable({providedIn: 'root'})\nexport class MapGetPipe implements PipeTransform {\n\n transform(val: any, args: string | number | {key: string | number} ): any {\n if (!val) return null;\n const key = (args && typeof args === 'object' ? args.key : args) as any;\n if (!key) return null;\n return val[key];\n }\n}\n\n@Pipe({\n name: 'mapKeys'\n})\n@Injectable({providedIn: 'root'})\nexport class MapKeysPipe implements PipeTransform {\n\n transform(map: any): any[] {\n if (!map) return null;\n return Object.keys(map);\n }\n}\n\n@Pipe({\n name: 'mapValues'\n})\n@Injectable({providedIn: 'root'})\nexport class MapValuesPipe implements PipeTransform {\n\n transform(map: any): any[] {\n if (!map) return null;\n return Object.values(map);\n }\n}\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {isNilOrBlank, isNotNilOrBlank} from '../functions';\n\n@Pipe({\n name: 'isNotNilOrBlank'\n})\nexport class IsNotNilOrBlankPipe implements PipeTransform {\n transform(value: string): boolean {\n return isNotNilOrBlank(value);\n }\n}\n\n@Pipe({\n name: 'isNilOrBlank'\n})\nexport class IsNilOrBlankPipe implements PipeTransform {\n transform(value: string): boolean {\n return isNilOrBlank(value);\n }\n}\n\n@Pipe({\n name: 'toString'\n})\nexport class ToStringPipe implements PipeTransform {\n transform(value: number): string {\n return (value !== null && value !== undefined) ? value.toString() : '';\n }\n}\n\n\n@Pipe({\n name: 'strLength'\n})\nexport class StrLengthPipe implements PipeTransform {\n transform(value: string): number {\n return value && value.length || 0;\n }\n}\n\n\n@Pipe({\n name: 'strIncludes'\n})\nexport class StrIncludesPipe implements PipeTransform {\n transform(value: string, searchString: string, position?: number): boolean {\n return value?.includes(searchString, position) || false;\n }\n}\n","import {Injectable} from '@angular/core';\nimport {TranslateService} from '@ngx-translate/core';\nimport {map, mergeMap} from 'rxjs/operators';\nimport {Observable, of} from 'rxjs';\nimport {isNil, isNilOrBlank, isNotNilOrBlank} from '../functions';\n\n\n@Injectable({providedIn: 'root'})\nexport class TranslateContextService {\n\n constructor(\n protected translate: TranslateService\n ) {\n }\n\n\n get(key: string, context?: string, interpolateParams?: Object): Observable<any> {\n // No context: do a normal translate\n if (!key || !isNil(context)) return this.translate.get(key, interpolateParams);\n\n // Compute a contextual i18n key, using the context as suffix\n const contextualKeys = this.contextualKeys(key, context);\n\n // Return the contextual translation, or default of not exists\n return this.translate.get(contextualKeys, interpolateParams)\n .pipe(\n map(translations => this.findFirstValid(contextualKeys, translations))\n );\n }\n\n instant(key: string, context?: string, interpolateParams?: Object): any {\n // No context: do a normal translate\n if (!key || isNilOrBlank(context)) return this.translate.instant(key, interpolateParams);\n\n // Compute a contextual i18n key, using the context as suffix\n const contextualKeys = this.contextualKeys(key, context);\n const translations = this.translate.instant(contextualKeys, interpolateParams);\n\n\n return this.findFirstValid(contextualKeys, translations);\n }\n\n /**\n * Compute contextual i18n keys, using the context as suffix.<br>\n * Suffix can be simple name (like 'aaa' - will return ['<key>.aaa']) or complexe (like 'aaa.bbb' - will return ['<key>.aaa.bbb', '<key>.aaa']\n *\n * @param key\n * @param context\n * @private\n */\n contextualKeys(key: string, context: string): string[] {\n return context.split('.')\n .filter(isNotNilOrBlank)\n .reduce((res, item) => {\n const inheritedContext = res.length > 0 ? (res[res.length - 1] + '.') : '';\n return res.concat( inheritedContext + item)\n }, [])\n .reverse() // Start with children, ends with parent key\n .map(contextItem => this.contextualKey(key, contextItem))\n .concat(key)\n }\n\n /**\n * Compute a contextual i18n key, using the context as suffix\n *\n * @param key\n * @param context\n * @private\n */\n contextualKey(key: string, context: string): string {\n\n // Append a dot on context if missing\n if (!context.endsWith('.')) {\n context = context + '.';\n }\n\n // Compute a contextual i18n key, using the context as suffix\n const parts = key.split('.');\n return (parts.length === 1)\n ? `${context}${key}`\n : parts.slice(0, parts.length - 1).concat(context + parts[parts.length - 1]).join('.');\n }\n\n private findFirstValid(keys: string[], translations: { [key: string]: string }): string {\n // For eac contextual key: try to find translation, then use the first valid\n for (let key of keys) {\n if (translations[key] !== key) return translations[key];\n }\n return translations[keys[keys.length-1]]; // Return the last keys translation\n }\n}\n","import {ChangeDetectorRef, Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {TranslateContextService} from '../services/translate-context.service';\nimport {changeCaseToUnderscore, equals, equalsOrNil} from '../functions';\n\n@Injectable()\n@Pipe({\n name: 'translateContext'\n})\nexport class TranslateContextPipe implements PipeTransform {\n\n constructor(\n private translate: TranslateContextService\n ) {\n }\n\n transform(query: string, context?: string, interpolateParams?: Object): string {\n if (!query || !query.length) return query;\n return this.translate.instant(query, context, interpolateParams);\n }\n}\n\n\n@Pipe({\n name: 'translatable'\n})\n@Injectable()\nexport class TranslatablePipe implements PipeTransform {\n transform(value: string): string {\n // transform a string to a i18n compatible string (ex: QualitativeValue -> QUALITATIVE_VALUE)\n return changeCaseToUnderscore(value)?.toUpperCase();\n }\n}\n\n","import {Directive, OnInit, Output, EventEmitter} from '@angular/core';\n\n@Directive({\n selector: '[ngInit]'\n})\nexport class NgInitDirective implements OnInit {\n\n @Output()\n ngInit = new EventEmitter<any>();\n\n ngOnInit() {\n this.ngInit.emit();\n }\n}\n","import {AbstractControl, AsyncValidatorFn, FormArray, FormControl, FormGroup, ValidationErrors, ValidatorFn} from '@angular/forms';\nimport * as momentImported from 'moment';\nimport {Moment, unitOfTime} from 'moment';\nimport {DATE_ISO_PATTERN, PUBKEY_REGEXP} from '../constants';\nimport {isEmptyArray, isNil, isNilOrBlank, isNotNil, isNotNilOrBlank, isNotNilOrNaN, toBoolean, toNumber} from '../functions';\nimport {fromDateISOString} from '../dates';\nimport {from, isObservable, merge, Observable, of, Subject, Subscription, timer} from 'rxjs';\nimport {catchError, first, switchMap, takeUntil, tap} from 'rxjs/operators';\n\nconst moment = momentImported;\n\n// @dynamic\nexport class SharedValidators {\n\n private static _DOUBLE_REGEXP_CACHE = {\n NO_LIMIT: /^-?\\d+([.,]\\d*)?$/,\n 1: /^-?\\d+([.,]\\d)?$/, // 1 decimal max\n 2: /^-?\\d+([.,]\\d{1,2})?$/, // 2 decimals max\n 3: /^-?\\d+([.,]\\d{1,3})?$/ // 3 decimals max\n }\n\n private static getDoubleRegexp(maxDecimals: number): RegExp {\n if (isNil(maxDecimals))\n return this._DOUBLE_REGEXP_CACHE.NO_LIMIT;\n\n if (maxDecimals < 0) throw new Error(`Invalid maxDecimals value: ${maxDecimals}`);\n const regexp = this._DOUBLE_REGEXP_CACHE[maxDecimals];\n if (regexp) return regexp;\n\n // New: add to cache\n this._DOUBLE_REGEXP_CACHE[maxDecimals] = new RegExp(`^-?\\\\d+([.,]\\\\d{1,${maxDecimals}})?$`);\n return this._DOUBLE_REGEXP_CACHE[maxDecimals];\n }\n\n\n static readonly I18N_ERROR_KEYS = {\n required: 'ERROR.FIELD_REQUIRED',\n min: 'ERROR.FIELD_MIN',\n max: 'ERROR.FIELD_MAX',\n minlength:'ERROR.FIELD_MIN_LENGTH',\n maxlength:'ERROR.FIELD_MAX_LENGTH',\n pubkey: 'ERROR.FIELD_NOT_VALID_PUBKEY',\n validDate: 'ERROR.FIELD_NOT_VALID_DATE',\n dateIsAfter: 'ERROR.FIELD_NOT_VALID_DATE_AFTER',\n dateIsBefore: 'ERROR.FIELD_NOT_VALID_DATE_BEFORE',\n dateRange: 'ERROR.FIELD_NOT_VALID_DATE_RANGE',\n dateMinDuration: 'ERROR.FIELD_NOT_VALID_DATE_MIN_DURATION',\n dateMaxDuration: 'ERROR.FIELD_NOT_VALID_DATE_MAX_DURATION',\n maxDecimals: 'ERROR.FIELD_MAXIMUM_DECIMALS',\n double: 'ERROR.FIELD_NOT_VALID_DOUBLE',\n integer: 'ERROR.FIELD_NOT_VALID_INTEGER',\n email: 'ERROR.FIELD_NOT_VALID_EMAIL',\n latitude: 'ERROR.FIELD_NOT_VALID_LATITUDE',\n longitude: 'ERROR.FIELD_NOT_VALID_LONGITUDE',\n pattern: 'ERROR.FIELD_NOT_VALID_PATTERN',\n unique: 'ERROR.FIELD_NOT_UNIQUE',\n entity: 'ERROR.FIELD_INVALID'\n }\n\n static latitude(control: FormControl): ValidationErrors | null {\n const value = control.value;\n if (isNotNil(value) && (value < -90 || value > 90)) {\n return {latitude: true};\n }\n return null;\n }\n\n static longitude(control: FormControl): ValidationErrors | null {\n const value = control.value;\n if (isNotNil(value) && (value < -180 || value > 180)) {\n return {longitude: true};\n }\n return null;\n }\n\n static object(control: FormControl): ValidationErrors | null {\n const value = control.value;\n if (value && typeof value !== 'object') {\n return {object: true};\n }\n return null;\n }\n\n static entity(control: FormControl): ValidationErrors | null {\n const value = control.value;\n if (value && (typeof value !== 'object' || value.id === undefined || value.id === null)) {\n return {entity: true};\n }\n return null;\n }\n\n static empty(control: FormControl): ValidationErrors | null {\n if (isNotNilOrBlank(control.value)) {\n return {empty: true};\n }\n return null;\n }\n\n static pubkey(control: FormControl): ValidationErrors | null {\n const value = control.value;\n if (value && (typeof value !== 'string' || !PUBKEY_REGEXP.test(value))) {\n return {pubkey: true};\n }\n return null;\n }\n\n static integer(control: FormControl): ValidationErrors | null {\n if (isNilOrBlank(control.value))\n return null;\n const value = parseFloat(control.value);\n if (isNaN(value) || (value | 0) !== value) {\n return {integer: true};\n }\n return null;\n }\n\n /**\n * @deprecated use decimal\n */\n static double = SharedValidators.decimal;\n\n static decimal(opts?: { maxDecimals?: number }): ValidatorFn {\n const regexp = this.getDoubleRegexp(opts?.maxDecimals);\n return (control: FormControl): ValidationErrors | null => {\n let value = control.value;\n if (Number.isNaN(value)) {\n //console.log(\"WARN: Getting a NaN value !\");\n return null;\n }\n if (isNotNil(value) && value !== '' && !regexp.test(value as string)) {\n return isNotNil(opts?.maxDecimals) ? {maxDecimals: {maxDecimals: opts.maxDecimals} } : {decimal: true};\n }\n return null;\n };\n }\n\n static validDate(control: FormControl): ValidationErrors | null {\n const value = control.value;\n const date = !value || moment.isMoment(value) ? value : moment(value, DATE_ISO_PATTERN);\n if (date && (!date.isValid() || date.year() < 1970)) {\n return {validDate: true};\n }\n return null;\n }\n\n static dateIsAfter(previousValue: Moment, errorParam: string, granularity?: unitOfTime.StartOf): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const value = fromDateISOString(control.value);\n if (isNotNil(value) && isNotNil(previousValue) && value.isSameOrBefore(previousValue, granularity)) {\n // Return the error\n return {dateIsAfter: {minDate: errorParam}};\n }\n return null;\n };\n }\n\n static dateIsBefore(maxValue: Moment, errorParam: string, granularity?: unitOfTime.StartOf): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const value = fromDateISOString(control.value);\n if (isNotNil(value) && isNotNil(maxValue) && value.isSameOrAfter(maxValue, granularity)) {\n // Return the error\n return {dateIsBefore: {maxDate: errorParam}};\n }\n return null;\n };\n }\n\n static dateRangeEnd(startDateFieldName: string, msg?: string): ValidatorFn {\n const errorCode = msg ? 'msg': 'dateRange';\n const error = msg ? {msg} : {dateRange: true};\n return (control: AbstractControl): ValidationErrors | null => {\n // Form group not created yet: skip\n if (!control.parent) return null;\n\n const startControl = control.parent.get(startDateFieldName);\n if (!startControl) {\n console.warn(`Cannot find brother control '${startDateFieldName}' in the parent form`);\n return null;\n }\n const startDate = fromDateISOString(startControl.value);\n const endDate = fromDateISOString(control.value);\n // Error if value <= beforeDate\n if (isNotNil(endDate) && isNotNil(startDate) && endDate.isSameOrBefore(startDate)) {\n return error;\n }\n // OK: clear existing errors\n SharedValidators.clearError(control, errorCode);\n return null;\n };\n }\n\n static dateRangeStart(endDateFieldName: string, msg?: string): ValidatorFn {\n const errorCode = msg ? 'msg': 'dateRange';\n const error = msg ? {msg} : {dateRange: true};\n return (control: AbstractControl): ValidationErrors | null => {\n // Form group not created yet: skip\n if (!control.parent) return null;\n\n const endDateControl = control.parent.get(endDateFieldName);\n if (!endDateControl) {\n console.warn(`Cannot find control '${endDateFieldName}' in the parent form`);\n return null;\n }\n const endDate = fromDateISOString(endDateControl.value);\n const startDate = fromDateISOString(control.value);\n // Error if value <= beforeDate\n if (isNotNil(startDate) && isNotNil(endDate) && startDate.isSameOrAfter(endDate)) {\n return error;\n }\n // OK: clear existing errors\n SharedValidators.clearError(control, errorCode);\n return null;\n };\n }\n\n static copyParentErrors(errorNames?: string[]): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n // Skip if control already has some errors\n if (control.errors) return null;\n // Skip if parent form group not created yet\n if (!control.parent) return null;\n\n // Form group not created yet\n if (!control.parent) return null;\n\n const errors = control.parent.errors;\n\n // No errors, or copy all errors\n if (!errors || isEmptyArray(errorNames)) return errors;\n\n // Copy only expected errors\n return Object.keys(errors).reduce((res, key) => {\n if (errorNames.includes(key)) {\n res[key] = errors[key];\n }\n return res;\n }, {});\n };\n }\n\n static clearError(control: AbstractControl, errorCode: string) {\n if (control.hasError(errorCode)) {\n const errors = control.errors;\n if (errors && errors[errorCode]) {\n // Only one error: reset errors\n if (Object.getOwnPropertyNames(errors).length === 1) {\n control.setErrors(null);\n }\n // Other errors exists: just remove this error\n else {\n delete errors[errorCode];\n control.setErrors(errors);\n }\n }\n }\n }\n\n\n}\n\n// @dynamic\nexport class SharedFormGroupValidators {\n\n static dateRange(startDateField: string, endDateField: string, msg?: string ): ValidatorFn {\n const errorCode = isNotNilOrBlank(msg) ? 'msg' : 'dateRange';\n const rangeError = msg ? {msg} : {dateRange: true};\n return (group: FormGroup): ValidationErrors | null => {\n const startDate = fromDateISOString(group.get(startDateField).value);\n const endField = group.get(endDateField);\n const endDate = fromDateISOString(endField.value);\n if (isNotNil(startDate) && isNotNil(endDate) && startDate.isAfter(endDate)) {\n // Update end field\n endField.markAsPending();\n endField.setErrors({\n ...endField.errors,\n ...rangeError\n });\n // Return the error (should be apply to the parent form)\n return rangeError;\n }\n // OK: remove the existing on the end field\n SharedValidators.clearError(endField, errorCode);\n return null;\n };\n }\n\n static dateMaxDuration(startDateField: string, endDateField: string, maxDuration: number, durationUnit?: moment.unitOfTime.Diff): ValidatorFn {\n const maxDurationError = {dateMaxDuration: true};\n return (group: FormGroup): ValidationErrors | null => {\n const startDate = fromDateISOString(group.get(startDateField).value);\n const endField = group.get(endDateField);\n const endDate = fromDateISOString(endField.value);\n if (isNotNil(startDate) && isNotNil(endDate) && Math.abs(startDate.diff(endDate, durationUnit)) > maxDuration) {\n // Update end field\n endField.markAsTouched({onlySelf: true});\n endField.markAsPending();\n endField.setErrors({\n ...endField.errors,\n ...maxDurationError\n });\n // Return the error (should be apply to the parent form)\n return maxDurationError;\n }\n // OK: remove the existing on the end field\n SharedValidators.clearError(endField, 'dateMaxDuration');\n return null;\n };\n }\n\n static dateMinDuration(startDateField: string, endDateField: string, minDuration: number, durationUnit?: moment.unitOfTime.Diff): ValidatorFn {\n return (group: FormGroup): ValidationErrors | null => {\n const endField = group.get(endDateField);\n const startDate = fromDateISOString(group.get(startDateField).value);\n const endDate = fromDateISOString(endField.value);\n if (isNotNil(startDate) && isNotNil(endDate) && Math.abs(startDate.diff(endDate, durationUnit)) < minDuration) {\n // Update end field\n const endFieldErrors: ValidationErrors = endField.errors || {};\n endFieldErrors['dateMinDuration'] = true;\n endField.setErrors(endFieldErrors);\n endField.markAsTouched({onlySelf: true});\n // Return the error (should be apply to the parent form)\n return {dateMinDuration: true};\n }\n // OK: remove the existing on the end field\n else {\n SharedValidators.clearError(endField, 'dateMinDuration');\n }\n return null;\n };\n }\n\n static requiredIf(fieldName: string, anotherFieldToCheck: string | AbstractControl): ValidatorFn {\n return (group: FormGroup): ValidationErrors | null => {\n const control = group.get(fieldName);\n const anotherControl = (anotherFieldToCheck instanceof AbstractControl) ? anotherFieldToCheck : group.get(anotherFieldToCheck);\n if (!anotherControl) throw new Error('Unable to find field to check!');\n if (isNilOrBlank(control.value) && isNotNilOrBlank(anotherControl.value)) {\n const error = {required: true};\n control.setErrors(error);\n control.markAsTouched({onlySelf: true});\n return error;\n }\n SharedValidators.clearError(control, 'required');\n return null;\n };\n }\n\n static requiredIfTrue(fieldName: string, anotherFieldToCheck: string | AbstractControl): ValidatorFn {\n return (group: FormGroup): ValidationErrors | null => {\n const control = group.get(fieldName);\n const anotherControl = (anotherFieldToCheck instanceof AbstractControl) ? anotherFieldToCheck : group.get(anotherFieldToCheck);\n if (!anotherControl) throw new Error('Unable to find field to check!');\n if (isNilOrBlank(control.value) && toBoolean(anotherControl.value, false)) {\n const error = {required: true};\n control.setErrors(error);\n control.markAsTouched({onlySelf: true});\n return error;\n }\n SharedValidators.clearError(control, 'required');\n return null;\n };\n }\n\n static requiredIfEmpty(fieldName: string, anotherFieldToCheck: string): ValidatorFn {\n return (group: FormGroup): ValidationErrors | null => {\n const control = group.get(fieldName);\n if (isNilOrBlank(control.value) && isNilOrBlank(group.get(anotherFieldToCheck).value)) {\n const error = {required: true};\n control.setErrors(error);\n control.markAsTouched({onlySelf: true});\n return error;\n }\n SharedValidators.clearError(control, 'required');\n return null;\n };\n }\n\n static propagateIfDirty(fieldName: string, fieldNameToPropagate: string, valueToPropagate: any): ValidatorFn {\n return (group: FormGroup): null => {\n const control = group.get(fieldName);\n const controlToPropagate = group.get(fieldNameToPropagate);\n if (control.dirty && controlToPropagate.value !== valueToPropagate) {\n controlToPropagate.setValue(valueToPropagate);\n }\n return null;\n };\n }\n\n /**\n * Same as compose, but keep only the first errors (instead of the union)\n * @param validators\n */\n first(validators: (ValidatorFn | null | undefined)[]): ValidationErrors | null {\n return (control) => validators\n .filter(isNotNil)\n .map(validator => validator(control))\n .find(isNotNil) || null;\n }\n}\n\n// @dynamic\nexport class SharedFormArrayValidators {\n\n /**\n * Validate uniqueness of an entity in a FormArray\n *\n * @param controlName the name of the control in FormArray\n */\n static uniqueEntity(controlName: string): ValidatorFn {\n return (array: FormArray): ValidationErrors | null => {\n const controls: AbstractControl[] = [];\n if (array.length) {\n // gather controls in array with valid entity\n for (const control of array.controls) {\n const fromGroup = control as FormGroup;\n if (fromGroup.controls[controlName]) {\n const value = fromGroup.controls[controlName].value;\n if (!!value && !!value.id)\n controls.push(fromGroup.controls[controlName]);\n }\n }\n // get occurrences of entity by id\n const occurrences = controls.reduce((acc, control) => {\n const id = control.value.id;\n acc[id] ? acc[id]++ : acc[id] = 1;\n return acc;\n }, {});\n // get controls with value occurrences > 1\n const error = {uniqueEntity: true};\n let returnError = false;\n controls.filter(control => occurrences[control.value.id] > 1)\n .forEach(control => {\n let errors: ValidationErrors = control.errors || {};\n errors = {...errors, ...error};\n control.setErrors(errors);\n control.markAsTouched({onlySelf: true});\n returnError = true;\n });\n if (returnError)\n return error;\n }\n controls.forEach(control => SharedValidators.clearError(control, 'uniqueEntity'));\n return null;\n };\n }\n\n static requiredArrayMinLength(minLength?: number): ValidatorFn {\n minLength = minLength || 1;\n return (array: FormArray): ValidationErrors | null => {\n if (!array || array.length < minLength) {\n return {required: true};\n }\n return null;\n };\n }\n\n /**\n * Validate the sum of control values in an FormArray not overflow the max value\n *\n * @param controlName the name of the control in FormArray\n * @param max the maximum value\n */\n static validSumMaxValue(controlName: string, max: number): ValidatorFn {\n return (array: FormArray): ValidationErrors | null => {\n const controls: AbstractControl[] = [];\n if (array.length) {\n for (const control of array.controls) {\n const fromGroup = control as FormGroup;\n if (fromGroup.controls[controlName] && isNotNilOrNaN(fromGroup.controls[controlName].value)) {\n controls.push(fromGroup.controls[controlName]);\n }\n }\n if (controls.reduce((sum, control) => sum + control.value, 0) > max) {\n const error = {sumMaxValue: true};\n controls.forEach(control => {\n let errors: ValidationErrors = control.errors || {};\n errors = {...errors, ...error};\n control.setErrors(errors);\n control.markAsTouched({onlySelf: true});\n });\n return error;\n }\n }\n controls.forEach(control => SharedValidators.clearError(control, 'sumMaxValue'));\n return null;\n };\n }\n\n}\n\nexport declare type ObservableValidatorFn = (control: AbstractControl) => Observable<ValidationErrors | null>\nexport declare type PromiseValidatorFn = (control: AbstractControl) => Promise<ValidationErrors | null>\n\n// @dynamic\nexport class SharedAsyncValidators {\n\n private static DEBOUNCE_TIME_VALIDATOR_ID = 0;\n\n /**\n * Add a debounce time to a validator.\n * @param form\n * @param validatorFn\n * @param opts Use opts.stopSubject to stop the validator, before end\n */\n static debounceTime(validatorFn: ValidatorFn | AsyncValidatorFn,\n opts?: {\n dispose?: Observable<any>;\n debounceTime?: number;\n markForCheck?: () => void;\n debug?: boolean;\n }): ObservableValidatorFn {\n\n // DEBUG only\n const debug = opts?.debug || false ;\n const logPrefix = debug && `[debounceTime-validator] #${SharedAsyncValidators.DEBOUNCE_TIME_VALIDATOR_ID++} - `;\n const debounceTime = toNumber(opts?.debounceTime, 250);\n\n // DEBUG\n if (debug) console.debug(logPrefix + `New validator with a debounceTime at ${debounceTime}ms`);\n\n const $disposeSubject = new Subject();\n const disposeEvent$ = opts?.dispose\n ? merge($disposeSubject, opts?.dispose)\n : $disposeSubject;\n\n // DEBUG\n if (debug && opts?.dispose) {\n opts?.dispose.pipe(first()).subscribe(() => {\n console.debug(logPrefix + 'Stopping');\n });\n }\n\n return (control) => {\n if (debug) console.debug(logPrefix + 'Form ask validation...');\n\n // Stop previous observables\n $disposeSubject.next();\n let now: number;\n\n // Add a delay before execution\n return timer(debounceTime)\n .pipe(\n // DEBUG\n tap(_ => {\n if (debug) {\n console.debug(logPrefix + 'Executing...');\n now = Date.now();\n }\n }),\n switchMap((_) => {\n // Call the validator\n const res = validatorFn(control);\n // Make sure to return an Observable\n if (isObservable(res)) return res;\n if (res instanceof Promise) return from(res);\n return of(res);\n }),\n // DEBUG\n tap(res => debug && console.debug(logPrefix + `Finished in ${Date.now() - now}ms (${res ? 'with errors' : 'no error'})`, res)),\n catchError(error => {\n console.error('[debounceTime-validator] Error while executing validator. Stopping job', error);\n $disposeSubject.next();\n throw error;\n }),\n // Refresh UI, after a successful execution\n tap(() => opts?.markForCheck && opts?.markForCheck()),\n // Make sure to stop, because of the switchMap\n takeUntil(disposeEvent$)\n )\n };\n }\n\n /**\n * Add an async validator, that can be disposed by the returned subscription\n * @param form\n * @param validatorFn the validator or job to execute\n * @param opts\n */\n static registerAsyncValidator(form: AbstractControl,\n validatorFn: ValidatorFn | AsyncValidatorFn,\n opts?: {\n debounceTime?: number;\n markForCheck?: () => void;\n debug?: boolean;\n }): Subscription {\n if (form.asyncValidator) throw Error('Form already have an async validator. Cannot configure job');\n\n const debounceTime = toNumber(opts?.debounceTime, 250);\n const $dispose = new Subject();\n\n const asyncValidatorFn = SharedAsyncValidators.debounceTime(validatorFn, {...opts, debounceTime, dispose: $dispose });\n form.setAsyncValidators(asyncValidatorFn);\n\n const subscription = new Subscription();\n\n // When unsubscribing, remove async validator\n subscription.add(() => {\n // Clear added validator. Must be done NOW (without delay) because generally a new Job is given just after\n form.clearAsyncValidators();\n\n // Stop the job, with a delay to let the last execution finished\n setTimeout(() => {\n $dispose.next();\n $dispose.unsubscribe();\n }, debounceTime);\n });\n\n return subscription;\n }\n}\n","import {AbstractControl, FormArray, FormControl, FormGroup, ValidationErrors} from '@angular/forms';\nimport {isMoment} from 'moment';\nimport {isNil, isNilOrBlank, isNotEmptyArray, isNotNil, nullIfUndefined} from './functions';\nimport {toDateISOString} from './dates';\nimport {waitFor, WaitForOptions} from './observables';\nimport {Predicate} from '@angular/core';\n\nexport interface FormErrors {\n [key: string]: ValidationErrors;\n}\n\n/**\n * Fill a form using a source entity\n *\n * @param target\n * @param entity\n * @param opts\n */\nexport function copyEntity2Form(entity: any, target: FormGroup, opts?: { emitEvent?: boolean; onlySelf?: boolean }) {\n const json = getFormValueFromEntity(entity, target);\n target.patchValue(json, opts);\n}\n\nexport function getFormValueFromEntity(entity: any|undefined, form: FormGroup): { [key: string]: any } {\n return adaptValueToControl(entity, form) as { [key: string]: any };\n}\n\n/**\n * Transform an entity into a simple object, compatible with the given form\n *\n * @param source an entity (or subentity)\n * @param control\n * @param path\n */\nexport function adaptValueToControl(source: any|undefined, control: AbstractControl, path?: string): any {\n const pathPrefix = path ? path + '.' : '';\n\n // Form group\n if (control instanceof FormGroup) {\n const result = {};\n // eslint-disable-next-line guard-for-in\n for (const key in control.controls) {\n result[key] = adaptValueToControl(source && source[key], control.controls[key], pathPrefix + key);\n }\n return result;\n }\n\n // Array\n if (control instanceof FormArray) {\n\n // Split, if many values in a string\n if (typeof source === 'string') {\n source = source.split('|');\n }\n\n // Skip if value is not an array\n if (!Array.isArray(source) || control.length === 0) {\n if (isNotEmptyArray(source)) console.warn(`WARN: please resize the FormArray '${path}' to the same length of the input array`);\n return [];\n }\n\n // Use the first form group, as model\n const firstItemControl = control.at(0);\n let result = source.map((item, index) => adaptValueToControl(item, firstItemControl, pathPrefix + '#' + index)) as any[];\n\n // Truncate if too many values\n if (result.length > control.length) {\n if (firstItemControl instanceof FormControl) {\n for (let i = control.length; i < result.length; i++) {\n control.push(new FormControl(null, firstItemControl.validator));\n }\n }\n else {\n console.warn(`WARN: please resize the FormArray '${path||''}' to the same length of the input array`);\n result = result.slice(0, control.length);\n }\n }\n\n // Add values if not enought\n else if (result.length < control.length) {\n //console.warn(`WARN: Adding null value to array values`);\n for (let i = result.length; i < control.length; i++) {\n result.push(null);\n }\n }\n return result;\n }\n\n // Form control\n if (control instanceof FormControl) {\n // Date\n if (isMoment(source)) {\n return toDateISOString(source);\n }\n // Any other control: replace undefined by null value\n // because Undefined is not authorized as control value\n else {\n return nullIfUndefined(source);\n }\n }\n\n}\n\nexport function logFormErrors(control: AbstractControl, logPrefix?: string, path?: string) {\n if (!control || control.valid) return;\n logPrefix = logPrefix || '';\n // Form group\n if (control instanceof FormGroup) {\n if (!path) console.warn(`${logPrefix} Form errors:`);\n if (control.errors) {\n Object.keys(control.errors).forEach(error =>\n console.warn(`${logPrefix} -> ${path || ''} (${error})`)\n );\n }\n if (control.controls) {\n Object.keys(control.controls).forEach(child =>\n logFormErrors(control.controls[child], logPrefix, (path ? `${path}.${child}` : child)) // Recursive call\n );\n }\n }\n // Form array\n else if (control instanceof FormArray) {\n if (control.errors) {\n Object.keys(control.errors).forEach(error =>\n console.warn(`${logPrefix} -> ${path || ''} (${error})`)\n );\n }\n control.controls.forEach((child, index) => {\n logFormErrors(child, logPrefix, (path ? `${path}.${index}` : `${index}`)); // Recursive call\n });\n }\n // Other control's errors\n else if (control.errors) {\n Object.keys(control.errors).forEach(error =>\n console.warn(`${logPrefix} -> ${path || ''} (${error})`)\n );\n }\n}\n\nexport function getFormErrors(control: AbstractControl, opts?: {\n controlName?: string;\n result?: FormErrors;\n recursive?: boolean;\n}): FormErrors {\n if (!control || control.valid) return undefined;\n\n opts = opts || {};\n opts.result = opts.result || {};\n\n // Form group\n if (control instanceof FormGroup) {\n // Copy errors\n if (control.errors) {\n if (opts.controlName) {\n opts.result[opts.controlName] = {\n ...control.errors\n };\n }\n else {\n opts.result = {\n ...opts.result,\n ...control.errors\n };\n }\n }\n\n if (!opts || opts.recursive !== false) {\n // Loop on children controls\n for (const key in control.controls) {\n const child = control.controls[key];\n if (child && child.enabled) {\n getFormErrors(child, {\n ...opts,\n controlName: opts.controlName ? [opts.controlName, key].join('.') : key,\n result: opts.result // Make sure to keep the same result object\n });\n }\n }\n }\n }\n\n // Form array\n else if (control instanceof FormArray) {\n control.controls.forEach((child, index) => {\n getFormErrors(child, {\n ...opts,\n controlName: (opts.controlName || '') + '.' + index,\n result: opts.result // Make sure to keep the same result object\n });\n });\n }\n\n // Other type of control (e.g simple control)\n else if (control.errors) {\n if (opts.controlName) {\n opts.result[opts.controlName] = {\n ...control.errors\n };\n }\n else {\n opts.result = {\n ...opts.result,\n ...control.errors\n };\n }\n }\n return opts.result;\n}\n\nexport function getControlFromPath(form: FormGroup, path: string): AbstractControl {\n const i = path.indexOf('.');\n if (i === -1) {\n return form.controls[path];\n }\n const key = path.substring(0, i);\n if (form.controls[key] instanceof FormGroup) {\n return getControlFromPath((form.controls[key] as FormGroup), path.substring(i + 1));\n }\n throw new Error(`Invalid form path: '${key}' should be a form group.`);\n}\n\n\nexport function disableControls(form: FormGroup, paths: string[], opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n (paths || []).forEach(path => {\n const control = getControlFromPath(form, path);\n if (control) control.disable(opts);\n });\n}\n\n\nexport function pushValueInArray(arrayControl: FormArray,\n createControl: (value?: any) => AbstractControl,\n equals: (v1: any, v2: any) => boolean,\n isEmpty: (value: any) => boolean,\n value: any,\n options?: { emitEvent: boolean }): boolean {\n options = options || {emitEvent: true};\n\n let hasChanged = false;\n let index = -1;\n\n // Search if value already exists\n if (!isEmpty(value)) {\n index = (arrayControl.value || []).findIndex(v => equals(value, v));\n }\n\n // If value not exists, but last value is empty: use it\n if (index === -1 && arrayControl.length && isEmpty(arrayControl.at(arrayControl.length - 1).value)) {\n index = arrayControl.length - 1;\n }\n\n // Replace the existing value\n if (index !== -1) {\n if (!isEmpty(value)) {\n arrayControl.at(index).patchValue(value, options);\n hasChanged = true;\n }\n } else {\n const control = createControl(value);\n arrayControl.push(control);\n hasChanged = true;\n }\n\n if (hasChanged) {\n if (isNil(options.emitEvent) || options.emitEvent) {\n // Mark array control dirty\n if (!isEmpty(value)) {\n arrayControl.markAsDirty();\n }\n }\n }\n\n return hasChanged;\n}\n\n/**\n * Patch an array using given default values. Each default value will be pass to the 'createControl()' function\n * @param arrayControl\n * @param createControl\n * @param values\n */\nexport function patchValueInArray(arrayControl: FormArray,\n createControl: (value?: any) => AbstractControl,\n defaultValues: any[]): boolean {\n let hasChanged = false;\n while (arrayControl.length > 0) {\n arrayControl.removeAt(arrayControl.length - 1);\n hasChanged = true;\n }\n (defaultValues || []).forEach(value => {\n const control = createControl(value);\n arrayControl.push(control);\n hasChanged = true;\n });\n return hasChanged;\n}\n\nexport function resizeArray(arrayControl: FormArray,\n createControl: () => AbstractControl,\n length: number): boolean {\n const hasChanged = arrayControl.length !== length;\n\n // Increase size\n if (arrayControl.length < length) {\n while (arrayControl.length < length) {\n arrayControl.push(createControl());\n }\n }\n\n // Or reduce\n else if (arrayControl.length > length) {\n while (arrayControl.length > length) {\n arrayControl.removeAt(arrayControl.length - 1);\n }\n }\n\n return hasChanged;\n}\n\nexport function removeValueInArray(arrayControl: FormArray,\n isEmpty: (value: any) => boolean,\n index: number): boolean {\n arrayControl.removeAt(index);\n arrayControl.markAsDirty();\n return true;\n}\n\nexport function clearValueInArray(arrayControl: FormArray,\n isEmpty: (value: any) => boolean,\n index: number): boolean {\n\n const control = arrayControl.at(index);\n if (isEmpty(control.value)) return false; // skip (not need to clear)\n\n if (control instanceof FormGroup) {\n copyEntity2Form({}, control);\n }\n else if (control instanceof FormArray) {\n control.setValue([]);\n }\n else {\n control.setValue(null);\n }\n arrayControl.markAsDirty();\n return true;\n}\n\nexport function markAllAsTouched(control: AbstractControl, opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (!control) return;\n if (control instanceof FormGroup) {\n markFormGroupAsTouched(control, {...opts, onlySelf: true}); // recursive call\n }\n else if (control instanceof FormArray) {\n control.markAsTouched({onlySelf: true});\n (control.controls || []).forEach(c => markControlAsTouched(c, {...opts, onlySelf: true})); // recursive call\n }\n else {\n control.markAsTouched({onlySelf: true});\n control.updateValueAndValidity({...opts, onlySelf: true});\n }\n}\n\nexport function markFormGroupAsTouched(form: FormGroup, opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (!form) return;\n form.markAsTouched(opts);\n Object.keys(form.controls)\n .map(key => form.controls[key])\n .filter(control => control.enabled)\n .forEach(control => markControlAsTouched(control, opts));\n form.updateValueAndValidity({...opts, onlySelf: true});\n}\n\nexport function markControlAsTouched(control: AbstractControl, opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (!control) return;\n if (control instanceof FormGroup) {\n markAllAsTouched(control, { ...opts, onlySelf: true}); // recursive call\n }\n else if (control instanceof FormArray) {\n (control.controls || []).forEach(c => markControlAsTouched(c, { ...opts, onlySelf: true})); // recursive call\n }\n else {\n control.markAsTouched({onlySelf: true});\n control.updateValueAndValidity({...opts, onlySelf: true});\n }\n}\n\nexport function updateValueAndValidity(form: FormGroup, opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (!form) return;\n form.updateValueAndValidity(opts);\n Object.keys(form.controls)\n .map(key => form.controls[key])\n .filter(control => control.enabled)\n .forEach(control => {\n if (control instanceof FormGroup) {\n updateValueAndValidity(control, {...opts, onlySelf: true}); // recursive call\n }\n else {\n control.updateValueAndValidity({...opts, onlySelf: true});\n }\n });\n}\n\nexport function markAsUntouched(form: FormGroup, opts?: {onlySelf?: boolean }) {\n if (!form) return;\n form.markAsUntouched(opts);\n Object.getOwnPropertyNames(form.controls)\n .forEach(key => {\n const control = form.get(key);\n if (control instanceof FormGroup) {\n markAsUntouched(control, {onlySelf: true}); // recursive call\n }\n else {\n control.markAsUntouched({onlySelf: true});\n control.setErrors(null);\n }\n });\n}\n\n/**\n * Wait end of async validation (not pending). This need to implement {pending: boolean}\n * return false\n */\nexport function waitWhilePending<T extends { pending: boolean }>(form: T, opts?: WaitForOptions): Promise<void> {\n const predicate: Predicate<void> = () => form.pending !== true;\n return waitFor(predicate, opts);\n}\n\n/**\n * Wait form is idle (not loading). This need to implement {loading: boolean}\n * @param form\n * @param opts\n */\nexport function waitIdle<T extends { loading: boolean }>(form: T, opts?: WaitForOptions): Promise<void> {\n const predicate: Predicate<void> = () => form.loading !== true;\n return waitFor(predicate, opts);\n}\n","import {AbstractControl, FormArray, FormBuilder, FormGroup, ValidationErrors, ValidatorFn} from '@angular/forms';\nimport {Entity} from '../services/model/entity.model';\nimport {SharedFormArrayValidators} from '../../shared/validator/validators';\nimport {round, toBoolean} from '../../shared/functions';\nimport {filterNumberInput, selectInputContent} from '../../shared/inputs';\nimport {waitFor, WaitForOptions} from '../../shared/observables';\nimport {\n pushValueInArray, clearValueInArray,\n copyEntity2Form,\n disableControls,\n getControlFromPath, getFormErrors,\n getFormValueFromEntity,\n logFormErrors,\n markAllAsTouched,\n markAsUntouched, removeValueInArray, resizeArray,\n updateValueAndValidity,\n waitIdle,\n waitWhilePending, patchValueInArray\n} from '../../shared/forms';\n\nexport declare type IAppFormGetter = () => IAppForm;\n\nexport declare interface OnReady {\n ngOnReady();\n}\n\nexport interface IAppForm {\n // From Angular form\n invalid: boolean;\n valid: boolean;\n dirty: boolean;\n pending: boolean;\n error: string;\n enabled: boolean;\n disabled: boolean;\n touched: boolean;\n untouched: boolean;\n\n // Specific to IAppForm\n empty?: boolean;\n loading?: boolean;\n ready(): Promise<void>;\n waitIdle(opts?: WaitForOptions): Promise<any>;\n\n disable(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n enable(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n\n markAsPristine(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n markAsUntouched(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n markAsTouched(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n markAllAsTouched(opts?: {emitEvent?: boolean});\n markAsDirty(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n markAsLoading(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n markAsLoaded(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n markAsReady(opts?: {onlySelf?: boolean; emitEvent?: boolean;});\n}\n\n\n/**\n * A form that do nothing\n */\nexport class AppNullForm implements IAppForm {\n readonly invalid = false;\n readonly valid = false;\n readonly dirty = false;\n readonly empty = true;\n readonly pending = false;\n readonly error = null;\n readonly enabled = false;\n readonly loading = false;\n readonly touched = false;\n get disabled(): boolean {\n return !this.enabled;\n }\n get untouched(): boolean {\n return !this.touched;\n }\n\n disable(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n enable(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n\n markAsPristine(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n markAsUntouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n markAsTouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n markAllAsTouched(opts?: { emitEvent?: boolean }) {}\n markAsDirty(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n markAsLoading(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n markAsLoaded(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n markAsReady(opts?: {onlySelf?: boolean; emitEvent?: boolean }){}\n\n waitIdle(opts?: WaitForOptions): Promise<any> {\n return Promise.reject(false);\n }\n ready(): Promise<any> {\n return Promise.reject(true);\n }\n}\n\n\nexport class AppFormProvider<F extends IAppForm = IAppForm> implements IAppForm {\n static NULL_FORM = new AppNullForm();\n\n constructor(private getterFn: () => F) {\n }\n\n private get delegate(): IAppForm {\n return this.getterFn() || AppFormProvider.NULL_FORM;\n }\n\n waitDelegate(opts?: WaitForOptions): Promise<F> {\n let content: F;\n return waitFor(() => {\n content = this.getterFn();\n return !!content;\n }, opts).then(_ => content);\n }\n\n /* -- delegated methods -- */\n\n get enabled(): boolean {\n return this.delegate.enabled;\n }\n get disabled(): boolean {\n return this.delegate.disabled;\n }\n get error(): string {\n return this.delegate.error;\n }\n get invalid(): boolean {\n return this.delegate.invalid;\n }\n get valid(): boolean {\n return this.delegate.valid;\n }\n get dirty(): boolean {\n return this.delegate.dirty;\n }\n get empty(): boolean {\n return this.delegate.empty;\n }\n get pending(): boolean {\n return this.delegate.pending;\n }\n get loading(): boolean {\n return this.delegate.loading;\n }\n get touched(): boolean {\n return this.delegate.touched;\n }\n get untouched(): boolean {\n return this.delegate.untouched;\n }\n ready(): Promise<any> {\n return this.delegate.ready();\n }\n waitIdle(opts?: WaitForOptions): Promise<any> {\n return this.delegate.waitIdle();\n }\n disable(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.disable(opts);\n }\n enable(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.enable(opts);\n }\n markAsPristine(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsPristine(opts);\n }\n markAsUntouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsUntouched(opts);\n }\n markAsTouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsTouched(opts);\n }\n markAllAsTouched(opts?: { emitEvent?: boolean }) {\n return this.delegate.markAllAsTouched(opts);\n }\n markAsDirty(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsDirty(opts);\n }\n markAsLoading(opts?: { onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsLoading(opts);\n }\n markAsLoaded(opts?: { onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsLoaded(opts);\n }\n markAsReady(opts?: { onlySelf?: boolean; emitEvent?: boolean }) {\n return this.delegate.markAsReady(opts);\n }\n}\n\nexport interface FormArrayHelperOptions {\n allowEmptyArray: boolean;\n validators?: ValidatorFn[];\n helperProperty?: boolean;\n}\n\nexport class FormArrayHelper<T = Entity<any>, C extends AbstractControl = AbstractControl> {\n\n static FORMA_HELPER_PROPERTY = '_helper';\n\n static getOrCreateArray(\n formBuilder: FormBuilder,\n form: FormGroup,\n arrayName: string): FormArray {\n let arrayControl = form.get(arrayName) as FormArray;\n if (!arrayControl) {\n arrayControl = formBuilder.array([]);\n form.addControl(arrayName, arrayControl);\n }\n return arrayControl;\n }\n\n static hasHelper(formArray: FormArray): formArray is FormArray & {_helper: FormArrayHelper<any>} {\n return formArray && !!formArray[this.FORMA_HELPER_PROPERTY];\n }\n\n private _allowEmptyArray: boolean;\n private readonly _validators: ValidatorFn[];\n\n get allowEmptyArray(): boolean {\n return this._allowEmptyArray;\n }\n\n set allowEmptyArray(value: boolean) {\n this.setAllowEmptyArray(value);\n }\n\n get formArray(): FormArray {\n return this._formArray;\n }\n\n constructor(\n private readonly _formArray: FormArray,\n private createControl: (value?: T) => C,\n private equals: (v1: T, v2: T) => boolean,\n private isEmpty: (value: T) => boolean,\n options?: FormArrayHelperOptions\n ) {\n this._validators = options && options.validators;\n\n // Register into the form array\n if (options?.helperProperty) {\n _formArray[FormArrayHelper.FORMA_HELPER_PROPERTY] = this;\n }\n\n // empty array not allow by default\n this.setAllowEmptyArray(toBoolean(options && options.allowEmptyArray, false));\n }\n\n /**\n * @param value\n * @param options\n * @deprecated Use push() instead\n */\n add(value?: T, options?: { emitEvent: boolean }): boolean {\n return pushValueInArray(this._formArray, this.createControl, this.equals, this.isEmpty, value, options);\n }\n\n push(value?: T, options?: { emitEvent: boolean }): boolean {\n return pushValueInArray(this._formArray, () => this.createControl(value), this.equals, this.isEmpty, value, options);\n }\n\n removeAt(index: number) {\n // Do not remove if last criterion\n if (!this._allowEmptyArray && this._formArray.length === 1) {\n return clearValueInArray(this._formArray, this.isEmpty, index);\n }\n else {\n return removeValueInArray(this._formArray, this.isEmpty, index);\n }\n }\n\n resize(length: number): boolean {\n return resizeArray(this._formArray, this.createControl, length);\n }\n\n clearAt(index: number): boolean {\n return clearValueInArray(this._formArray, this.isEmpty, index);\n }\n\n isLast(index: number): boolean {\n return (this._formArray.length - 1) === index;\n }\n\n removeAllEmpty() {\n let index = this._formArray.controls.findIndex(c => this.isEmpty(c.value));\n while(index !== -1) {\n this.removeAt(index);\n index = this._formArray.controls.findIndex(c => this.isEmpty(c.value));\n }\n }\n\n size(): number {\n return this._formArray.length;\n }\n\n at(index: number): C {\n return this._formArray.at(index) as C;\n }\n\n /**\n * Patch a FormArray, using default values\n * @param values default values to apply.\n * @param opts\n * @return true if form arry has been changed\n */\n patchValue(values: T[]): boolean {\n return patchValueInArray(this._formArray, this.createControl, values);\n }\n\n disable(opts?: {\n onlySelf?: boolean;\n emitEvent?: boolean;\n }) {\n this._formArray.controls.forEach(c => c.disable(opts));\n }\n\n enable(opts?: {\n onlySelf?: boolean;\n emitEvent?: boolean;\n }) {\n this._formArray.controls.forEach(c => c.enable(opts));\n }\n\n forEach(ite: (control: C) => void ) {\n const size = this.size();\n for(let i = 0; i < size; i++) {\n const control = this._formArray.at(i) as C;\n if (control) ite(control);\n }\n }\n\n /* -- internal methods -- */\n\n protected setAllowEmptyArray(value: boolean) {\n if (this._allowEmptyArray === value) return; // Skip if same\n\n this._allowEmptyArray = value;\n\n // Set required (or reste) min length validator\n if (this._allowEmptyArray) {\n this._formArray.setValidators(this._validators || null);\n }\n else {\n this._formArray.setValidators((this._validators || []).concat(SharedFormArrayValidators.requiredArrayMinLength(1)));\n }\n }\n}\n\n\n// TODO continue to use this kind of declaration ?\nexport class AppFormUtils {\n static copyEntity2Form = copyEntity2Form;\n static getFormValueFromEntity = getFormValueFromEntity;\n static logFormErrors = logFormErrors;\n static getControlFromPath = getControlFromPath;\n static filterNumberInput = filterNumberInput;\n static disableControls = disableControls;\n static selectInputContent = selectInputContent;\n /**\n * @deprecated use markAllAsTouched() instead (naming was wrong)\n */\n static markAsTouched = markAllAsTouched;\n\n /**\n * Marks the control and all its descendant controls as touched.\n * See also:\n * - `markAsTouched()`\n */\n static markAllAsTouched = markAllAsTouched;\n static markAsUntouched = markAsUntouched;\n static waitWhilePending = waitWhilePending;\n static waitIdle = waitIdle;\n static updateValueAndValidity = updateValueAndValidity;\n\n static getFormErrors = getFormErrors;\n\n static isForm(object: any): object is IAppForm {\n return object instanceof AppFormProvider\n || 'dirty' in object && 'enabled' in object && 'valid' in object;\n }\n\n // ArrayForm\n static addValueInArray = pushValueInArray;\n static removeValueInArray = removeValueInArray;\n static resizeArray = resizeArray;\n static clearValueInArray = clearValueInArray;\n\n // Calculated fields\n static calculatedSuffix = 'Calculated';\n static isControlHasInput = isControlHasInput;\n static setCalculatedValue = setCalculatedValue;\n static resetCalculatedValue = resetCalculatedValue;\n}\n\n\nexport function isControlHasInput(controls: { [key: string]: AbstractControl}, controlName: string): boolean {\n // true if the control has a value and its 'calculated' control has the value 'false'\n return controls[controlName].value && !toBoolean(controls[controlName + AppFormUtils.calculatedSuffix].value, false);\n}\n\nexport function setCalculatedValue(controls: { [key: string]: AbstractControl}, controlName: string, value: number | undefined) {\n // set value to control\n controls[controlName].setValue(round(value));\n // set 'calculated' control to 'true'\n controls[controlName + AppFormUtils.calculatedSuffix].setValue(true);\n}\n\nexport function resetCalculatedValue(controls: { [key: string]: AbstractControl}, controlName: string) {\n if (!isControlHasInput(controls, controlName)) {\n // set undefined only if control already calculated\n AppFormUtils.setCalculatedValue(controls, controlName, undefined);\n }\n}\n\n","import {changeCaseToUnderscore, isEmptyArray, isNil} from '../functions';\nimport {Inject, Injectable, InjectionToken, Optional} from '@angular/core';\nimport {TranslateService} from '@ngx-translate/core';\nimport {AbstractControl} from '@angular/forms';\nimport {AppFormUtils} from '../../core/form/form.utils';\nimport {SharedValidators} from './validators';\nimport {ObjectMap} from '../types';\nimport {FormErrors} from '../forms';\n\n\nexport const APP_FORM_ERROR_I18N_KEYS = new InjectionToken<ObjectMap<string>>('appFormErrorKeys');\n\nexport interface IFormControlPathTranslator {\n translateControlPath: (controlPath: string) => string;\n}\n\nexport interface FormErrorTranslatorOptions {\n i18nPrefix?: string;\n controlPathTranslator?: IFormControlPathTranslator;\n separator?: string;\n recursive?: boolean;\n}\n\n@Injectable({providedIn: 'root'})\nexport class FormErrorTranslator implements IFormControlPathTranslator {\n\n private readonly errorI18nKeys: ObjectMap<string>;\n\n constructor(\n private translate: TranslateService,\n @Optional() @Inject(APP_FORM_ERROR_I18N_KEYS) errorI18nKeys: ObjectMap<string>\n ) {\n this.errorI18nKeys = {\n ...SharedValidators.I18N_ERROR_KEYS,\n ...errorI18nKeys\n };\n }\n\n translateFormErrors(control: AbstractControl, opts?: FormErrorTranslatorOptions): string {\n if (!control || !control.invalid) return '';\n\n const separator = opts && opts.separator || ', ';\n const recursive = !opts || opts.recursive !== false\n const errors = AppFormUtils.getFormErrors(control, {recursive});\n return errors && Object.keys(errors).reduce((res, path) => {\n\n const childControl = control.get(path);\n // Should be a control map of errors\n if (childControl) {\n // Try to convert the control path\n const i18nPath = this.translateControlPath(path, opts);\n\n // OK, we have a field name: use it\n const columnErrors = Object.keys(childControl.errors).map(errorKey => this.translateError(errorKey, childControl.errors[errorKey]));\n if (isEmptyArray(columnErrors)) return res;\n // Add separator\n if (res.length) res += separator;\n return res + i18nPath + \": \" + columnErrors.join(separator);\n }\n\n // Or try as global form error\n const formError = this.translateError(path, errors[path]);\n if (isNil(formError)) return res;\n return res + (res.length ? separator : '') + formError;\n }, \"\");\n }\n\n translateErrors(errors: FormErrors, opts?: FormErrorTranslatorOptions): string {\n\n const separator = opts && opts.separator || ', ';\n return errors && Object.keys(errors).reduce((res, path) => {\n\n const pathErrors = errors[path];\n // Should be a control map of errors\n\n if (pathErrors) {\n // Try to convert the control path\n const i18nPath = this.translateControlPath(path, opts);\n\n // OK, we have a field name: use it\n const columnErrors = Object.keys(pathErrors).map(errorKey => this.translateError(errorKey, pathErrors[errorKey]));\n if (isEmptyArray(columnErrors)) return res;\n // Add separator\n if (res.length) res += separator;\n return res + i18nPath + \": \" + columnErrors.join(separator);\n }\n\n // Or try as global form error\n const formError = this.translateError(path, pathErrors);\n if (isNil(formError)) return res;\n return res + (res.length ? separator : '') + formError;\n }, \"\");\n }\n\n translateControlPath(path: string, opts?: FormErrorTranslatorOptions): string{\n if (opts?.controlPathTranslator) {\n return opts?.controlPathTranslator.translateControlPath(path);\n }\n const i18nKey = (opts && opts.i18nPrefix || '') + changeCaseToUnderscore(path).toUpperCase();\n return this.translate.instant(i18nKey);\n }\n\n translateError(errorKey: string, errorContent?: any) {\n\n const i18nKey = this.errorI18nKeys[errorKey]\n // Try to generate a standard error key, like 'ERROR.FIELD_xxx_xxx'\n || ('ERROR.FIELD_' + changeCaseToUnderscore(errorKey).toUpperCase());\n\n let i18nMessage = this.translate.instant(i18nKey, errorContent);\n if (i18nKey !== i18nMessage) return i18nMessage;\n\n // Try to use the error content, as an i18n key\n if (typeof errorContent === 'string') {\n i18nMessage = this.translate.instant(errorContent);\n if (errorContent !== i18nMessage) return i18nMessage;\n }\n\n // Not translated: show error\n console.error(`[form-error-adapter] Cannot translate error key '${errorKey}'. Please add more formErrorsKey into APP_FORM_ERROR_I18N_KEYS injection token`);\n\n return errorKey;\n }\n}\n","import {ChangeDetectorRef, OnDestroy, Pipe, PipeTransform} from '@angular/core';\nimport {AbstractControl, FormArray, FormControl, FormGroup} from '@angular/forms';\nimport {FormErrorTranslator, FormErrorTranslatorOptions} from '../validator/form-error-adapter.class';\nimport {Subscription} from 'rxjs';\nimport {equals, isNotNil} from '../functions';\n\n@Pipe({\n name: 'translateFormError',\n pure: false\n})\nexport class FormErrorTranslatePipe implements PipeTransform, OnDestroy {\n\n value: string = '';\n\n private _lastForm: FormGroup | null = null;\n private _lastOptions: FormErrorTranslatorOptions | null = null;\n private _onFormStatusChanges: Subscription | undefined;\n\n constructor(\n private adapter: FormErrorTranslator,\n private _ref: ChangeDetectorRef\n ) {\n }\n\n transform(form: FormGroup, opts?: FormErrorTranslatorOptions): string {\n if (!form) {\n this._dispose();\n return '';\n }\n\n // if we ask another time for the same form and opts, return the last value\n if (form === this._lastForm && equals(opts, this._lastOptions)) {\n return this.value;\n }\n\n // store the query, in case it changes\n this._lastForm = form;\n\n // store the params, in case they change\n this._lastOptions = opts;\n\n // set the value\n this._updateValue(form, opts);\n\n // if there is a subscription to onLangChange, clean it\n this._dispose();\n\n // subscribe to onTranslationChange event, in case the translations change\n if (!this._onFormStatusChanges) {\n this._onFormStatusChanges = form.statusChanges.subscribe((status) => {\n this._updateValue(form, opts, status);\n });\n }\n\n return this.value;\n }\n\n ngOnDestroy(): void {\n this._dispose();\n }\n\n private _updateValue(form: FormGroup, opts?: FormErrorTranslatorOptions, status?: any) {\n if (status === 'INVALID' || form.invalid) {\n this.value = this.adapter.translateFormErrors(form, opts);\n this._ref.markForCheck();\n }\n else if (this.value !== undefined) {\n this.value = undefined;\n this._ref.markForCheck();\n }\n }\n\n /**\n * Clean any existing subscription to change events\n */\n private _dispose(): void {\n this._onFormStatusChanges?.unsubscribe();\n this._onFormStatusChanges = undefined;\n }\n}\n\n@Pipe({\n name: 'formGet'\n})\nexport class FormGetPipe implements PipeTransform {\n\n transform(form: AbstractControl, path: Array<string | number> | string ): AbstractControl {\n return form.get(path);\n }\n}\n\n@Pipe({\n name: 'formGetControl'\n})\nexport class FormGetControlPipe implements PipeTransform {\n\n transform(form: AbstractControl, path?: Array<string | number> | string ): FormControl {\n return (form && isNotNil(path) && form.get(path) || form) as FormControl;\n }\n}\n\n@Pipe({\n name: 'formGetArray'\n})\nexport class FormGetArrayPipe implements PipeTransform {\n\n transform(form: AbstractControl, path?: Array<string | number> | string ): FormArray {\n return (form && path && form.get(path) || form) as FormArray;\n }\n}\n\n@Pipe({\n name: 'formGetGroup'\n})\nexport class FormGetGroupPipe implements PipeTransform {\n\n transform(form: AbstractControl, path?: Array<string | number> | string ): FormGroup {\n return (form && path && form.get(path) || form) as FormGroup;\n }\n}\n\n@Pipe({\n name: 'formGetValue',\n pure: false\n})\nexport class FormGetValuePipe implements PipeTransform, OnDestroy {\n\n value: any = undefined;\n\n private _lastControl: AbstractControl | null = null;\n private _lastPath: Array<string | number> | string;\n private _onControlValueChanges: Subscription | undefined;\n private _onControlStatusChanges: Subscription | undefined;\n\n constructor(\n private _ref: ChangeDetectorRef\n ) {\n }\n\n transform(form: AbstractControl, path?: Array<string | number> | string, listenStatusChanges = false): any {\n if (!form) {\n this._dispose();\n return undefined;\n }\n\n // if we ask another time for the same form and opts, return the last value\n if (form === this._lastControl && equals(path, this._lastPath)) {\n return this.value;\n }\n\n // store the query, in case it changes\n this._lastControl = form;\n\n // store the params, in case they change\n this._lastPath = path;\n\n // set the value\n const control = path ? form.get(path) : form;\n this.value = control?.value;\n\n // if there is a subscription to onLangChange, clean it\n this._dispose();\n\n if (control) {\n // subscribe to valueChanges event\n this._onControlValueChanges = control.valueChanges.subscribe((value) => {\n if (value !== this.value) {\n this.value = value;\n this._ref.markForCheck();\n }\n });\n\n // subscribe to statusChanges event\n if (listenStatusChanges) {\n this._onControlStatusChanges = control.statusChanges.subscribe((status) => {\n const value = control.value;\n if (value !== this.value) {\n this.value = value;\n this._ref.markForCheck();\n }\n });\n }\n }\n\n\n\n return this.value;\n }\n\n ngOnDestroy(): void {\n this._dispose();\n }\n\n /**\n * Clean any existing subscription to change events\n */\n private _dispose(): void {\n this._onControlValueChanges?.unsubscribe();\n this._onControlValueChanges = undefined;\n this._onControlStatusChanges?.unsubscribe();\n this._onControlStatusChanges = undefined;\n }\n\n}\n","import {Injectable, OnDestroy, Pipe, PipeTransform} from '@angular/core';\nimport {getPropertyByPath, isNil, isNotNil, joinPropertiesPath} from '../functions';\nimport {DateFormatPipe} from './date-format.pipe';\nimport {FormFieldDefinition} from '../form/field.model';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Subscription} from 'rxjs';\n\n@Pipe({\n name: 'propertyGet'\n})\nexport class PropertyGetPipe implements PipeTransform {\n\n transform(obj: any, args: string | {key: string; defaultValue?: any } ): any {\n return getPropertyByPath(obj,\n // Path\n args && (typeof args === 'string' ? args : args.key),\n // Default value\n args && (args as any).defaultValue);\n }\n}\n\n\n@Pipe({\n name: 'propertyFormat'\n})\n@Injectable({providedIn: 'root'})\nexport class PropertyFormatPipe implements PipeTransform, OnDestroy {\n\n private _subscription: Subscription;\n private _i18nYes: string;\n private _i18nNo: string;\n\n constructor(private dateFormat: DateFormatPipe, private translate: TranslateService) {\n\n }\n\n ngOnDestroy(): void {\n this._subscription?.unsubscribe();\n }\n\n transform(obj: any, keyOrDefinition: string|FormFieldDefinition): string | Promise<string> {\n if (!obj) return '';\n const definition = keyOrDefinition && (typeof keyOrDefinition === 'object') && keyOrDefinition;\n const key = definition?.key || keyOrDefinition as string;\n if (!key) {\n // Should never occur\n console.warn('Invalid use of pipe \\'formatProperty\\': missing key or definition');\n return '';\n }\n const value = obj[key];\n if (isNil(value)) return value;\n const type = definition?.type || typeof value;\n switch (type) {\n case 'date':\n return this.dateFormat.transform(value) as string;\n case 'dateTime':\n return this.dateFormat.transform(value, {time: true}) as string;\n case 'enum':\n {\n // DEBUG\n // console.debug('formatProperty by definition (type='enum', key=' +definition.key+ '):', value );\n const item = (definition.values as any[] || [value]).find(item => (isNotNil(item.key) ? item.key : item) === value);\n return item.value || item;\n }\n case 'entity':\n {\n if (definition.autocomplete?.displayWith) {\n return definition.autocomplete.displayWith(value)\n }\n return joinPropertiesPath(value, definition.autocomplete?.attributes || ['label', 'name']) || undefined;\n }\n case 'boolean':\n return (obj === 1 || obj === true || obj === 'true') ? this.i18nYes : this.i18nNo;\n case 'integer':\n case 'double':\n case 'string':\n default:\n return value;\n }\n }\n\n get i18nYes(): string {\n if (!this._i18nYes) {\n this._i18nYes = this.translate.instant('COMMON.YES');\n }\n return this._i18nYes;\n }\n\n get i18nNo(): string {\n if (!this._i18nNo) {\n this._i18nNo = this.translate.instant('COMMON.NO');\n }\n return this._i18nNo;\n }\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {IonicModule} from '@ionic/angular';\nimport {DateFormatPipe} from './date-format.pipe';\nimport {DateDiffDurationPipe} from './date-diff-duration.pipe';\nimport {DateFromNowPipe} from './date-from-now.pipe';\nimport {LatitudeFormatPipe, LatLongFormatPipe, LongitudeFormatPipe} from './latlong-format.pipe';\nimport {NumberFormatPipe} from './number-format.pipe';\nimport {HighlightPipe} from './highlight.pipe';\nimport {FileSizePipe} from './file-size.pipe';\nimport {DurationPipe} from './duration.pipe';\nimport {EvenPipe, MathAbsPipe, OddPipe} from './math.pipes';\nimport {ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayJoinPipe, ArrayLengthPipe, ArrayPluckPipe, EmptyArrayPipe, NotEmptyArrayPipe} from './arrays.pipe';\nimport {MapGetPipe, MapKeysPipe, MapValuesPipe} from './maps.pipe';\nimport {IsNilOrBlankPipe, IsNotNilOrBlankPipe, StrIncludesPipe, StrLengthPipe, ToStringPipe} from './string.pipes';\nimport {TranslatablePipe, TranslateContextPipe} from './translate-context.pipe';\nimport {NgInitDirective} from './ng-init.pipe';\nimport {FormErrorTranslatePipe, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe} from './form.pipes';\nimport {PropertyFormatPipe, PropertyGetPipe} from './property.pipes';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n TranslateModule\n ],\n declarations: [\n PropertyGetPipe,\n PropertyFormatPipe,\n DateFormatPipe,\n DateDiffDurationPipe,\n DurationPipe,\n DateFromNowPipe,\n LatLongFormatPipe,\n LatitudeFormatPipe,\n LongitudeFormatPipe,\n HighlightPipe,\n NumberFormatPipe,\n FileSizePipe,\n MathAbsPipe,\n OddPipe,\n EvenPipe,\n NotEmptyArrayPipe,\n EmptyArrayPipe,\n ArrayLengthPipe,\n ArrayFirstPipe,\n ArrayPluckPipe,\n ArrayIncludesPipe,\n ArrayFilterPipe,\n ArrayJoinPipe,\n MapGetPipe,\n MapKeysPipe,\n MapValuesPipe,\n IsNilOrBlankPipe,\n IsNotNilOrBlankPipe,\n ToStringPipe,\n StrLengthPipe,\n StrIncludesPipe,\n TranslateContextPipe,\n TranslatablePipe,\n NgInitDirective,\n FormErrorTranslatePipe,\n FormGetPipe,\n FormGetControlPipe,\n FormGetArrayPipe,\n FormGetGroupPipe,\n FormGetValuePipe,\n PropertyFormatPipe\n ],\n exports: [\n PropertyGetPipe,\n PropertyFormatPipe,\n DateFormatPipe,\n DateFromNowPipe,\n DateDiffDurationPipe,\n DurationPipe,\n LatLongFormatPipe,\n LatitudeFormatPipe,\n LongitudeFormatPipe,\n HighlightPipe,\n NumberFormatPipe,\n FileSizePipe,\n MathAbsPipe,\n OddPipe,\n EvenPipe,\n NotEmptyArrayPipe,\n EmptyArrayPipe,\n ArrayLengthPipe,\n ArrayFirstPipe,\n ArrayPluckPipe,\n ArrayJoinPipe,\n MapGetPipe,\n MapKeysPipe,\n MapValuesPipe,\n IsNilOrBlankPipe,\n IsNotNilOrBlankPipe,\n ToStringPipe,\n StrLengthPipe,\n StrIncludesPipe,\n ArrayIncludesPipe,\n ArrayFilterPipe,\n TranslateContextPipe,\n TranslatablePipe,\n NgInitDirective,\n FormErrorTranslatePipe,\n FormGetPipe,\n FormGetControlPipe,\n FormGetArrayPipe,\n FormGetGroupPipe,\n FormGetValuePipe\n ]\n})\nexport class SharedPipesModule {\n\n}\n","// Import the core angular services.\nimport {AfterContentInit, Directive, ElementRef, OnChanges, OnDestroy, Optional, SimpleChanges} from '@angular/core';\nimport {Platform} from '@ionic/angular';\nimport {Keyboard} from '@ionic-native/keyboard/ngx';\nimport Timeout = NodeJS.Timeout;\nimport {isMobile, isWindows} from '../platforms';\n\n// ----------------------------------------------------------------------------------- //\n// ----------------------------------------------------------------------------------- //\n\nconst BASE_TIMER_DELAY = 100;\n\n@Directive({\n selector: '[autofocus], input[appAutofocus]',\n inputs: [\n 'shouldFocusElement: appAutofocus',\n 'timerDelay: autofocusDelay'\n ]\n})\nexport class AutofocusDirective implements AfterContentInit, OnChanges, OnDestroy {\n\n public shouldFocusElement: any;\n public timerDelay: number;\n\n private readonly _elementRef: ElementRef;\n private readonly _mobile: boolean;\n private _timer: Timeout = null;\n\n // I initialize the autofocus directive.\n constructor(\n platform: Platform,\n elementRef: ElementRef,\n @Optional() protected keyboard: Keyboard ) {\n\n this._elementRef = elementRef;\n\n this.shouldFocusElement = '';\n this._timer = null;\n this.timerDelay = BASE_TIMER_DELAY;\n this._mobile = isMobile(window);\n }\n\n // I get called once after the contents have been fully initialized.\n ngAfterContentInit() {\n\n // Because this directive can act on the stand-only \"autofocus\" attribute or\n // the more specialized \"appAutofocus\" property, we need to check to see if the\n // \"shouldFocusElement\" input property is the empty string. This will signify\n // that the focus it not being data-driven and should be performed automatically.\n if ( this.shouldFocusElement === '' ) {\n this.startFocusWorkflow();\n }\n }\n\n // I get called every time the input bindings are updated.\n ngOnChanges( changes: SimpleChanges ) {\n\n // If the timer delay is being passed-in as a string (ie, someone is using\n // attribute-input syntax, not property-input syntax), let's coalesce the\n // attribute to a numeric value so that our type-annotations are consistent.\n if ( changes.timerDelay && ( typeof( this.timerDelay ) !== 'number' ) ) {\n\n // If the coalesce fails, just fall-back to a sane value.\n if ( isNaN( this.timerDelay = +this.timerDelay ) ) {\n this.timerDelay = BASE_TIMER_DELAY;\n }\n }\n\n // If the focus input is being data-driven, then we either need to start the\n // focus workflow if focus is required; or, clear any existing workflow if focus\n // is no longer required (so that we don't steal focus from another element).\n if ( changes.shouldFocusElement ) {\n\n ( this. shouldFocusElement )\n ? this.startFocusWorkflow()\n : this.stopFocusWorkflow()\n ;\n }\n }\n\n // I get called once when the directive is being unmounted.\n ngOnDestroy() {\n this.stopFocusWorkflow();\n }\n\n /* --- private functions -- */\n\n // I start the timer-based workflow that will focus the current element.\n private startFocusWorkflow() {\n\n // if touch UI: do NOT focus when keyboard hide\n if (this._mobile && this.keyboard && this.keyboard.isVisible === false) return;\n\n // If there is already a timer running for this element, just let it play out -\n // resetting it at this point will only push-out the time at which the focus is\n // applied to the element.\n if ( this._timer ) return;\n\n this._timer = setTimeout(\n () => {\n this._timer = null;\n this._elementRef.nativeElement.focus();\n },\n this.timerDelay\n );\n\n }\n\n // I stop the timer-based workflow, preventing focus from taking place.\n private stopFocusWorkflow() {\n clearTimeout( this._timer );\n this._timer = null;\n }\n\n}\n","import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';\n\n@Directive({\n selector: '[ngVar]',\n})\nexport class NgVarDirective {\n\n @Input()\n set ngVar(context: unknown) {\n this.context.$implicit = this.context.ngVar = context;\n\n if (!this.hasView) {\n this.vcRef.createEmbeddedView(this.templateRef, this.context);\n this.hasView = true;\n }\n }\n\n private context: {\n $implicit: unknown;\n ngVar: unknown;\n } = {\n $implicit: null,\n ngVar: null,\n };\n\n private hasView: boolean = false;\n\n constructor(\n private templateRef: TemplateRef<any>,\n private vcRef: ViewContainerRef\n ) {}\n}\n","import { Directive, EventEmitter, HostBinding, HostListener, Output } from '@angular/core';\nimport {isNotEmptyArray} from '../functions';\n\ninterface DropEvent extends Event {\n dataTransfer?: {\n files?: File[]\n }\n}\n\n@Directive({\n selector: '[appDragAndDrop]',\n})\nexport class DragAndDropDirective {\n\n @HostBinding('class.fileover') fileOver: boolean;\n\n @Output() fileDropped = new EventEmitter<File[]>();\n\n // Dragover listener\n @HostListener('dragover', ['$event'])\n onDragOver(event: Event) {\n event.preventDefault();\n event.stopPropagation();\n this.fileOver = true;\n }\n\n // Dragleave listener\n @HostListener('dragleave', ['$event'])\n public onDragLeave(event: Event) {\n event.preventDefault();\n event.stopPropagation();\n this.fileOver = false;\n }\n\n // Drop listener\n @HostListener('drop', ['$event'])\n public ondrop(event: DropEvent) {\n event.preventDefault();\n event.stopPropagation();\n this.fileOver = false;\n const files = event.dataTransfer?.files;\n\n if (isNotEmptyArray(files)) {\n this.fileDropped.emit(files);\n }\n }\n}\n","import { AfterContentChecked, Directive, ElementRef, Inject } from '@angular/core';\n\nconst compatibleTagNames = ['ion-label', 'mat-label'];\n\n@Directive({\n selector: '[appAutoTitle]',\n})\nexport class AutoTitleDirective implements AfterContentChecked {\n private readonly element: HTMLElement;\n\n constructor(@Inject(ElementRef) private readonly elementRef: ElementRef<HTMLElement>) {\n // Check compatible tag\n if (compatibleTagNames.includes(elementRef.nativeElement.tagName?.toLowerCase())) {\n this.element = elementRef.nativeElement;\n }\n }\n\n ngAfterContentChecked(): void {\n // Update title if different\n if (this.element && this.element.title !== this.element.textContent) {\n this.element.title = this.element.textContent;\n }\n }\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {AutofocusDirective} from './autofocus.directive';\nimport {NgVarDirective} from './ng-var.directive';\nimport {DragAndDropDirective} from './drag-and-drop.directive';\nimport {AutoTitleDirective} from './autotitle.directive';\n\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule\n ],\n declarations: [\n AutofocusDirective,\n NgVarDirective,\n DragAndDropDirective,\n AutoTitleDirective\n ],\n exports: [\n AutofocusDirective,\n NgVarDirective,\n DragAndDropDirective,\n AutoTitleDirective\n ]\n})\nexport class SharedDirectivesModule {\n}\n","import {NgModule} from '@angular/core';\nimport {MatCommonModule} from '@angular/material/core';\nimport {MatAutocompleteModule} from '@angular/material/autocomplete';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {MatIconModule} from '@angular/material/icon';\nimport {MatButtonModule} from '@angular/material/button';\nimport {MatSelectModule} from '@angular/material/select';\nimport {MatAutocompleteField} from './material.autocomplete';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {SharedPipesModule} from '../../pipes/pipes.module';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {SharedDirectivesModule} from '../../directives/directives.module';\nimport {ScrollingModule} from '@angular/cdk/scrolling';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ScrollingModule,\n ReactiveFormsModule,\n SharedPipesModule,\n SharedDirectivesModule,\n MatCommonModule,\n MatAutocompleteModule,\n MatFormFieldModule,\n MatInputModule,\n MatIconModule,\n MatButtonModule,\n MatSelectModule,\n TranslateModule.forChild()\n ],\n exports: [\n MatAutocompleteModule,\n MatAutocompleteField\n ],\n declarations: [\n MatAutocompleteField\n ]\n})\nexport class SharedMatAutocompleteModule {\n}\n\n","export const DEFAULT_MAX_DECIMALS = 2;\n\nexport function formatDuration(value: number | null): string {\n if (value === undefined || value === null) return null;\n\n const hour = Math.floor(value);\n const minute = Math.round((value - hour) * 60);\n return [\n hour.toString().padStart(3, '0'),\n minute.toString().padStart(2, '0')\n ].join(':');\n}\n\n// 111:11 = 111.18 (with maxDecimals=2)\nexport function parseDuration(input: string, maxDecimals?: number, placeholderChar?: string): number | null {\n\n let duration = input || '';\n // Make to remove placeholder chars\n while (duration.indexOf(placeholderChar) !== -1) {\n duration = duration.replace(placeholderChar, '');\n }\n\n const durationParts = duration.split(':');\n const hour = parseInt(durationParts[0] || '0');\n const minute = parseInt(durationParts[1] || '0');\n\n const value = hour + (minute + 0.5) / 60;\n return roundFloat(value, maxDecimals);\n}\n\nfunction roundFloat(input: number, maxDecimals?: number): number {\n if (maxDecimals > 0) {\n const powDecimal = Math.pow(10, maxDecimals);\n return Math.trunc(input * powDecimal + 0.5) / powDecimal;\n }\n // no decimals: round to integer\n else if (maxDecimals === 0) {\n return Math.trunc(input + 0.5);\n }\n return input;\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, OnInit, Optional, Output, ViewChild } from '@angular/core';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport { ControlValueAccessor, FormBuilder, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';\nimport { SharedValidators } from '../../validator/validators';\nimport { formatLatitude, formatLongitude, LAT_LONG_DEFAULT_MAX_DECIMALS, LatLongFormatFn, LatLongFormatOptions, LatLongPattern, parseLatitudeOrLongitude } from './latlong.utils';\nimport { DEFAULT_PLACEHOLDER_CHAR } from '../../constants';\nimport { filter } from 'rxjs/operators';\nimport {isNil, isNilOrNaN, isNotNil, isNotNilOrBlank} from '../../functions';\nimport { getCaretPosition, moveInputCaretToSeparator, selectInputContent, selectInputRange } from '../../inputs';\nimport { merge, Subscription } from 'rxjs';\nimport { TextMaskConfig } from 'angular2-text-mask';\nimport { DEFAULT_MAX_DECIMALS } from '../duration/duration.utils';\n\nconst MASKS: {\n [key: string]: {\n [pattern: string]: Array<string|RegExp>;\n };\n} = {\n latitude: {\n DDMMSS: [' ', /\\d/, /\\d/, '°', ' ', /\\d/, /\\d/, '\\'', ' ', /\\d/, /\\d/, '.', /\\d/, /\\d/, '\"'],\n DDMM: [' ', /\\d/, /\\d/, '°', ' ', /\\d/, /\\d/, '.', /\\d/, /\\d/, /\\d/, '\\''],\n DD: [/[+-]/, ' ', /\\d/, /\\d/, '.', /\\d/, /\\d/, /\\d/, /\\d/, /\\d/, /\\d/, /\\d/, '°']\n },\n longitude: {\n DDMMSS: [/\\d/, /\\d/, /\\d/, '°', ' ', /\\d/, /\\d/, '\\'', ' ', /\\d/, /\\d/, '.', /\\d/, /\\d/, '\"'],\n DDMM: [/\\d/, /\\d/, /\\d/, '°', ' ', /\\d/, /\\d/, '.', /\\d/, /\\d/, /\\d/, '\\''],\n DD: [/[+-]/, /\\d/, /\\d/, /\\d/, '.', /\\d/, /\\d/, /\\d/, /\\d/, /\\d/, /\\d/, /\\d/, '°']\n }\n};\n\nconst noop = () => {\n};\n\n@Component({\n selector: 'mat-latlong-field',\n templateUrl: './material.latlong.html',\n styleUrls: ['./material.latlong.scss'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: forwardRef(() => MatLatLongField),\n }\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatLatLongField implements OnInit, OnDestroy, ControlValueAccessor {\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private _subscription = new Subscription();\n private _formatOptions: LatLongFormatOptions;\n private _disabling = false;\n private _writing = false;\n\n _readonly = false;\n _formatFn: LatLongFormatFn;\n textMaskConfig: TextMaskConfig;\n textFormControl: FormControl;\n signFormControl: FormControl;\n mask: Array<string | RegExp> | ((raw: string) => Array<string | RegExp>) | false;\n inputPlaceholder: string;\n showSignControl: boolean;\n\n get disabled(): any {\n return this.readonly || this.formControl.disabled;\n }\n\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() type: 'latitude' | 'longitude';\n @Input('latLongPattern') pattern: LatLongPattern;\n @Input() required = false;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() appearance: MatFormFieldAppearance;\n @Input() placeholder: string;\n @Input() tabindex: number;\n @Input() defaultSign: '-' | '+';\n @Input() maxDecimals: number = LAT_LONG_DEFAULT_MAX_DECIMALS;\n @Input() placeholderChar: string = DEFAULT_PLACEHOLDER_CHAR;\n\n @Input() set readonly(value: boolean){\n this._readonly = value;\n this.markForCheck();\n }\n\n get readonly(): boolean {\n return this._readonly;\n }\n\n @Output() onBlur = new EventEmitter<FocusEvent>();\n @Output() onFocus = new EventEmitter<FocusEvent>();\n\n @ViewChild('inputElement') inputElement: ElementRef;\n\n constructor(\n private formBuilder: FormBuilder,\n private cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n }\n\n ngOnInit() {\n this.type = this.type || 'latitude';\n this.pattern = this.pattern || 'DDMM';\n this.mask = MASKS[this.type] && MASKS[this.type][this.pattern];\n if (!this.mask) {\n console.error('Invalid attribute value. Expected: type: \\'latitude|longitude\\' and latlongPattern: \\'DD|DDMM|DDMMSS\\'');\n this.type = 'latitude';\n this.pattern = 'DDMM';\n this.mask = MASKS[this.type][this.pattern];\n }\n\n // Remove max decimals in the DDMMSS format\n if (this.pattern === 'DD') {\n console.warn(`Invalid attribute 'maxDecimals' - Must be '0' when using the 'DDMMSS' pattern.`);\n this.maxDecimals = 7;\n }\n else if (this.pattern === 'DDMMSS') {\n console.warn(`Invalid attribute 'maxDecimals' - Must be '0' when using the 'DDMMSS' pattern.`);\n this.maxDecimals = 0;\n }\n else if (isNil(this.maxDecimals)) {\n this.maxDecimals = DEFAULT_MAX_DECIMALS;\n }\n else if (this.maxDecimals < 0) {\n console.error('Invalid attribute \\'maxDecimals\\'. Must a positive value.');\n this.maxDecimals = DEFAULT_MAX_DECIMALS;\n }\n else if (this.maxDecimals !== DEFAULT_MAX_DECIMALS) {\n console.warn(`Invalid attribute 'maxDecimals' - Expected value: ${DEFAULT_MAX_DECIMALS} but get: ${this.maxDecimals}. Other value not implemented.`);\n this.maxDecimals = DEFAULT_MAX_DECIMALS;\n }\n\n this.showSignControl = this.pattern !== 'DD';\n\n this._formatFn = this.type === 'latitude' ? formatLatitude : formatLongitude;\n this._formatOptions = {pattern: this.pattern, maxDecimals: this.maxDecimals, hideSign: this.showSignControl};\n\n this.inputPlaceholder = 'COMMON.LAT_LONG.' + (this.type === 'longitude' && 'D' || '') + this.pattern + '_PLACEHOLDER';\n\n this.textFormControl = this.formBuilder.control(\n this.required ? [null, Validators.required] : [null]\n );\n this.textMaskConfig = {mask: this.mask, keepCharPositions: true, placeholderChar: this.placeholderChar};\n\n this.signFormControl = this.formBuilder.control(\n this.required ? [null, Validators.required] : [null]\n );\n\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-latlong-field>.');\n\n const existingValidators = this.formControl.validator;\n if (existingValidators) {\n this.formControl.setValidators([\n existingValidators,\n this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude\n ]);\n }\n else {\n this.formControl.setValidators(this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude);\n }\n\n this._subscription.add(\n merge(\n this.textFormControl.valueChanges,\n this.signFormControl.valueChanges\n )\n .subscribe((_) => this.onFormChange(this.textFormControl.value))\n );\n\n // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)\n this._subscription.add(\n this.formControl.statusChanges\n .pipe(\n filter((_) => !this.readonly && !this._writing && !this._disabling) // Skip\n )\n .subscribe((_) => this.markForCheck())\n );\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n }\n\n writeValue(obj: any): void {\n if (this._writing) return;\n\n const value = (typeof obj === 'string') ? parseFloat(obj.replace(/,/g, '.')) : obj;\n this._writing = true;\n const strValue = this._formatFn(value, {...this._formatOptions, placeholderChar: this.placeholderChar});\n const sign = isNotNil(value) ? (value < 0 ? -1 : 1) :\n // Use default sign, if any\n (this.defaultSign ? (this.defaultSign === '-' ? -1 : 1) : null);\n\n // DEBUG\n // console.debug(\"strValue: \" + strValue)\n // console.debug(\"sign: \" + sign)\n\n this.textFormControl.patchValue(strValue, {emitEvent: false});\n this.signFormControl.patchValue(sign, {emitEvent: false});\n this._writing = false;\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this._disabling) return;\n\n this._disabling = true;\n if (isDisabled) {\n this.textFormControl.disable({onlySelf: true, emitEvent: false});\n this.signFormControl.disable({onlySelf: true, emitEvent: false});\n } else {\n this.textFormControl.enable({onlySelf: true, emitEvent: false});\n this.signFormControl.enable({onlySelf: true, emitEvent: false});\n }\n this._disabling = false;\n this.markForCheck();\n }\n\n /**\n * Format value to display as string (no placeholder char, and show sign)\n * @param value\n * @param opts\n */\n _format(value: number, opts?: Partial<LatLongFormatOptions>) {\n return this._formatFn(value, {\n ...this._formatOptions, hideSign: false, placeholderChar: ''\n });\n }\n\n _onFocus(event: FocusEvent) {\n\n // Apply the default sign, when pattern is DD and field is empty\n const value = this.formControl.value;\n if (isNilOrNaN(value)) {\n if (this.defaultSign) {\n // Compute the text value, using the default sign\n const defaultSign = this.defaultSign === '-' ? -1 : 1;\n\n if (this.pattern === 'DD') {\n let valueStr = this._formatFn(defaultSign, {...this._formatOptions, placeholderChar: this.placeholderChar});\n // Keep only the sign ('+' or '-') and placeholder chars, but NOT the '1'\n valueStr = valueStr && valueStr.replace('1', this.placeholderChar);\n\n // Wait end of focus animation (label should move to top)\n setTimeout(() => {\n // Set the value\n this.inputElement.nativeElement.value = valueStr;\n\n // Move cursor after the sign\n const caretIndex = (this.type === 'latitude') ? 2 : 1;\n selectInputRange(event.target, caretIndex);\n }, 250);\n }\n else {\n this.signFormControl.setValue(defaultSign);\n }\n }\n }\n\n // Select the content (if there is a value)\n else {\n selectInputContent(event);\n }\n\n this.onFocus.emit(event);\n return true;\n }\n\n _onBlur(event: FocusEvent) {\n const touched = this.checkIfTouched();\n if (touched && isNil(this.formControl?.value)) {\n this.inputElement.nativeElement.value = '';\n }\n this.onBlur.emit(event);\n }\n\n moveCaretToSeparator(event: any, forward: boolean): boolean {\n // Move to the space separator\n return moveInputCaretToSeparator(event, ' ', forward);\n }\n\n onKeypress(event: KeyboardEvent) {\n // Number entered or one of the 4 direction up, down, left and right\n if ((event.which >= 48 && event.which <= 57) || (event.which >= 37 && event.which <= 40)) {\n //console.debug('input number entered :' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n // OK\n }\n // Decimal separator entered\n else if (event.key === '.' || event.key === ',') {\n // DEBUG\n // console.debug('input decimal separator entered :' + event.code);\n\n // Move caret after point\n moveInputCaretToSeparator(event, '.');\n\n // OK\n } else {\n // Command entered (delete, backspace or one of the 4 direction up, down, left and right)\n if ((event.keyCode >= 37 && event.keyCode <= 40) || event.keyCode == 46 || event.which == 8 || event.keyCode == 9) {\n // DEBUG\n //console.debug('input command entered:' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n\n // OK\n }\n // Sign entered ('+' or '-')\n else if (event.keyCode === 43 || event.keyCode === 45) {\n // DEBUG\n // console.debug('input sign entered:' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n const caretPosition = getCaretPosition(event.target);\n if (this.pattern === 'DD' && caretPosition > 0) {\n const sign = event.key;\n // Wait key apply\n const value = this.inputElement.nativeElement.value;\n if (value && !value.startsWith(sign)) {\n const newValue = sign + (value.length > 1 ? value.substr(1) : '');\n\n // DEBUG\n // console.debug(\"sign entered. Updating input value to:\", newValue);\n\n this.inputElement.nativeElement.value = newValue;\n selectInputRange(this.inputElement.nativeElement, caretPosition);\n }\n event.preventDefault();\n }\n\n // OK\n }\n // Direction char (capitalized)\n else if (event.key === 'N' || event.key === 'S' || event.key === 'E' || event.key === 'W') {\n // DEBUG\n // console.debug('input direction entered:' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n\n // OK\n }\n // Direction char\n else if (event.key === 'n' || event.key === 's' || event.key === 'e' || event.key === 'w') {\n // DEBUG\n // console.debug('input direction entered:' + event.which + ' ' + event.keyCode + ' ' + event.charCode);\n\n // Capitalize (with a delay, to be sure the key has been applied to input text)\n setTimeout(() => {\n this.inputElement.nativeElement.value = this.inputElement.nativeElement.value.toUpperCase();\n }, 10);\n\n // OK\n }\n\n // Any other keyboard events\n else {\n // DEBUG\n //console.debug('input not number entered :' + event.which + ' ' + event.keyCode + ' ' + event.charCode + ' ' + event.code );\n\n // KO: cancel the event\n event.preventDefault();\n }\n }\n }\n\n\n private onFormChange(strValue): void {\n if (this._writing) return; // Skip if call by self\n this._writing = true;\n\n if (this.textFormControl.invalid || this.signFormControl.invalid) {\n this.formControl.markAsPending();\n this.formControl.setErrors({\n ...this.formControl.errors,\n ...this.textFormControl.errors,\n ...this.signFormControl.errors\n });\n this._writing = false;\n return;\n }\n\n const parsedValue = isNotNilOrBlank(strValue) ? parseLatitudeOrLongitude(strValue, this.pattern, 7 /*=precision of the converted double value */, this.placeholderChar) : null;\n\n // DEBUG\n //console.debug('parsedValue=', parsedValue);\n\n if (isNaN(parsedValue)) {\n this.formControl.markAsPending();\n this.formControl.setErrors(this.type === 'latitude' ? {latitude: true} : {longitude: true});\n this._writing = false;\n return;\n }\n const sign = (this.pattern === 'DD') ? 1 /*ignore sign*/ : (this.signFormControl.value || 1);\n const value = isNotNil(parsedValue) ? sign * parsedValue : null;\n\n // Get the model value\n //console.debug(\"[mat-latlon] Setting value {\" + value + \"} parsed from {\" + strValue + \"}\");\n this.formControl.patchValue(value, {emitEvent: false});\n this._writing = false;\n this.markForCheck();\n\n this._onChangeCallback(value);\n }\n\n private checkIfTouched(): boolean {\n if (this.formControl.touched || this.textFormControl.touched) {\n this.markForCheck();\n this._onTouchedCallback();\n return true;\n }\n return false;\n }\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n}\n\n","import {NgModule} from '@angular/core';\nimport {MatCommonModule} from '@angular/material/core';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {MatIconModule} from '@angular/material/icon';\nimport {MatButtonModule} from '@angular/material/button';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {SharedPipesModule} from '../../pipes/pipes.module';\nimport {MatLatLongField} from './material.latlong';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {TextMaskModule} from 'angular2-text-mask';\nimport {MatSelectModule} from '@angular/material/select';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n SharedPipesModule,\n MatCommonModule,\n MatFormFieldModule,\n MatInputModule,\n MatIconModule,\n MatButtonModule,\n TextMaskModule,\n TranslateModule.forChild(),\n MatSelectModule\n ],\n exports: [\n MatLatLongField\n ],\n declarations: [\n MatLatLongField\n ]\n})\nexport class SharedMatLatLongModule {\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, Optional, Provider, QueryList, ViewChild, ViewChildren} from '@angular/core';\nimport {ControlValueAccessor, FormBuilder, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR, Validators} from '@angular/forms';\nimport {TranslateService} from '@ngx-translate/core';\nimport {isMoment, Moment} from 'moment';\nimport {DEFAULT_PLACEHOLDER_CHAR, KEYBOARD_HIDE_DELAY_MS} from '../../constants';\nimport {SharedValidators} from '../../validator/validators';\nimport {isBlankString, isNil, isNotNil, isNotNilBoolean, isNotNilOrBlank, sleep} from '../../functions';\nimport {Keyboard} from '@ionic-native/keyboard/ngx';\nimport {filter, first} from 'rxjs/operators';\nimport {InputElement, setTabIndex} from '../../inputs';\nimport {Subscription} from 'rxjs';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport {DateFilterFn, MatDatepicker, MatDatepickerInputEvent} from '@angular/material/datepicker';\nimport {isFocusableElement} from '../../focusable';\nimport {fromDateISOString, toDateISOString} from '../../dates';\nimport {isMobile} from '../../platforms';\nimport {MomentDateAdapter} from '@angular/material-moment-adapter';\n\nconst DEFAULT_VALUE_ACCESSOR: Provider = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MatDate),\n multi: true\n};\n\nconst TEXT_MASK = [/\\d/, /\\d/, '/', /\\d/, /\\d/, '/', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst noop = () => {};\n\n@Component({\n selector: 'mat-date-field',\n templateUrl: './material.date.html',\n styleUrls: ['./material.date.scss'],\n providers: [\n DEFAULT_VALUE_ACCESSOR,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatDate implements OnInit, OnDestroy, ControlValueAccessor, InputElement {\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private _subscription = new Subscription();\n private _writing = true;\n private _disabling = false;\n private _tabindex: number;\n private _keyboardHideDelay: number;\n\n _readonly = false;\n textControl: FormControl;\n datePattern: string;\n locale: string;\n readonly mask = TEXT_MASK;\n\n @Input() mobile: boolean;\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() placeholder: string;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() appearance: MatFormFieldAppearance;\n @Input() required: boolean;\n @Input() compact = false;\n @Input() placeholderChar: string = DEFAULT_PLACEHOLDER_CHAR;\n @Input() autofocus = false;\n @Input() startDate: Moment | null = null;\n @Input() clearable = false;\n @Input() timezone: string = null;\n @Input() datePickerFilter: DateFilterFn<Moment>;\n\n @Input() set readonly(value: boolean){\n this._readonly = value;\n this.markForCheck();\n }\n\n get readonly(): boolean {\n return this._readonly;\n }\n\n @Input() set tabindex(value: number) {\n if (this._tabindex !== value) {\n this._tabindex = value;\n if (!this._writing) this.updateTabIndex();\n }\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n get value(): any {\n return this.formControl.value;\n }\n\n @ViewChild('datePicker') datePicker: MatDatepicker<Moment>;\n @ViewChildren('matInput') matInputs: QueryList<ElementRef>;\n\n constructor(\n private dateAdapter: MomentDateAdapter,\n private translate: TranslateService,\n private formBuilder: FormBuilder,\n private cd: ChangeDetectorRef,\n @Optional() private keyboard: Keyboard,\n @Optional() private formGroupDir: FormGroupDirective,\n ) {\n this.locale = (translate.currentLang || translate.defaultLang).substr(0, 2);\n }\n\n ngOnInit() {\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-date-field>.');\n\n this.mobile = isNotNil(this.mobile) ? this.mobile : isMobile(window);\n // Workaround because ion-datetime has issue (do not returned a ISO date)\n this._keyboardHideDelay = this.mobile && KEYBOARD_HIDE_DELAY_MS || 0;\n\n this.required = isNotNilBoolean(this.required) ? this.required : (this.formControl.validator === Validators.required || isBlankString(this.required));\n\n // Add 'validDate' validator (when existing validator are null or required, to be sure to keep it)\n if (!this.formControl.validator || this.formControl.validator === Validators.required) {\n this.formControl.setValidators(this.required ? [Validators.required, SharedValidators.validDate] : SharedValidators.validDate);\n }\n else {\n this.formControl.setValidators(this.required ? [this.formControl.validator, Validators.required, SharedValidators.validDate] :\n [this.formControl.validator, SharedValidators.validDate]);\n }\n\n // Create the text control\n this.textControl = this.formBuilder.control(null,\n // Important: should copy errors from the model formControl\n () => this.formControl.errors\n );\n\n // Get patterns to display date\n this.updatePattern(this.translate.instant('COMMON.DATE_PATTERN'));\n this._subscription.add(\n this.translate.get('COMMON.DATE_PATTERN')\n .subscribe((pattern) => this.updatePattern(pattern))\n );\n\n this._subscription.add(\n this.textControl.valueChanges\n .subscribe((value) => this.onFormChange(value)));\n\n // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)\n this._subscription.add(\n this.formControl.statusChanges\n .pipe(\n filter((_) => !this.readonly && !this._writing && !this._disabling) // Skip\n )\n .subscribe(() => {\n this.textControl.updateValueAndValidity({emitEvent: false});\n if (this.formControl.touched && !this.textControl.touched) {\n this.textControl.markAsTouched();\n }\n this.markForCheck();\n })\n );\n\n this.updateTabIndex();\n\n this._writing = false;\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n }\n\n writeValue(value: any): void {\n if (this._writing) return; // Skip\n this._writing = true;\n\n // DEBUG\n //console.debug(\"[mat-date] writeValue() with:\", value);\n\n // Convert into date\n // Important: do a clone()\n let date = isMoment(value) ? value.clone() : fromDateISOString(value);\n\n if (!date || !date.isValid()) {\n this.textControl.patchValue(null, {emitEvent: false});\n if (this.formControl.value) {\n this.formControl.patchValue(null, {emitEvent: false});\n this._onChangeCallback(null);\n }\n }\n else {\n // Move to the expected TZ (keeping local hour - e.g. midnight)\n date = (this.timezone && date.tz(this.timezone) || date)\n // Reset hour\n .startOf('day');\n\n const dayStr = this.dateAdapter.format(date, this.datePattern);\n\n if (this.textControl.value !== dayStr) {\n // Update day control\n this.textControl.patchValue(dayStr, {emitEvent: false});\n }\n }\n\n this._writing = false;\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this._disabling) return;\n\n this._disabling = true;\n if (isDisabled) {\n this.textControl.disable({emitEvent: false});\n } else {\n this.textControl.enable({emitEvent: false});\n }\n this._disabling = false;\n\n this.markForCheck();\n }\n\n onDatePickerChange(event: MatDatepickerInputEvent<Moment>): void {\n // Make sure event is valid\n if (!event || (event.value !== null && !isMoment(event.value))) {\n console.warn('Invalid MatDatepicker event. Skipping', event);\n return; // Skip\n }\n\n let dateStr = null;\n if (event.value) {\n let date = event.value\n .locale(this.locale) // set as time as locale time\n .minute(0).seconds(0).millisecond(0) // Reset hour\n .utc(true);\n\n dateStr = this.dateAdapter.format(date, this.datePattern) || null;\n }\n\n if (this.textControl.value !== dateStr) {\n // DEBUG\n //console.debug(\"[mat-date] onDatePickerChange() new value:\", dateStr);\n\n this.textControl.setValue(dateStr, {\n emitEvent: true // Will call onFormChange\n });\n }\n }\n\n async openDatePickerIfMobile(event: UIEvent, datePicker?: MatDatepicker<any>) {\n if (!this.mobile || event.defaultPrevented) return;\n\n this.preventEvent(event);\n\n // Make sure the keyboard is closed\n await this.waitKeyboardHide(false);\n\n // Open the picker\n this.openDatePicker(null, datePicker);\n }\n\n public openDatePicker(event?: UIEvent, datePicker?: MatDatepicker<any>) {\n datePicker = datePicker || this.datePicker;\n if (datePicker) {\n\n if (event) this.preventEvent(event);\n\n if (!datePicker.opened) {\n datePicker.open();\n }\n }\n }\n\n preventEvent(event: UIEvent) {\n if (!event) return;\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n }\n\n focus() {\n if (!this.matInputs.length) return;\n\n setTimeout(() => {\n const elementRef = this.matInputs[0]; // get the first element\n if (isFocusableElement(elementRef)) {\n elementRef.focus();\n }\n });\n }\n\n clear() {\n this.textControl.patchValue(null, {emitEvent: false});\n this.formControl.setValue(null, {emitEvent: false});\n this._onChangeCallback(null);\n this.markAsTouched();\n this.markAsDirty();\n }\n\n /* -- private method -- */\n\n private updatePattern(pattern: string) {\n pattern = pattern !== 'COMMON.DATE_PATTERN' ? pattern : 'L';\n if (this.datePattern !== pattern) {\n this.datePattern = pattern;\n this.markForCheck();\n }\n }\n\n checkIfTouched(opts?: {emitEvent?: boolean}) {\n if (this.textControl.touched) {\n this._onTouchedCallback();\n\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n private onFormChange(value: string): void {\n if (this._writing) return; // Skip if call by self\n this._writing = true;\n\n // DEBUG\n //console.debug(`[mat-date-time] onFormChange() from event: ${event} - controls values: `, [dayStr, time]);\n\n /*if (this.dayControl.invalid) {\n this.formControl.markAsPending({onlySelf: true});\n this.formControl.setErrors({\n ...this.formControl.errors,\n ...this.dayControl.errors\n });\n this.formControl.markAsDirty();\n this._writing = false;\n return;\n }*/\n\n if (value) {\n // Make to remove placeholder chars\n while (value.indexOf(this.placeholderChar) !== -1) {\n value = value.replace(this.placeholderChar, '');\n }\n\n // Force '0' for empty month (otherwise moment will use the current month)\n value = value.replace('//', '/0/')\n // Force '0' for empty year (otherwise moment will use the current year)\n .replace(/\\/$/, '/0');\n }\n\n // Parse date (strict = false)\n let date: Moment = isNotNilOrBlank(value) && this.dateAdapter.parse(value, this.datePattern) || null;\n\n // Move to the expected TZ, and keep the local hour (= midnight) to have midnight at local time\n date = date && (this.timezone ? date.tz(this.timezone, true) : date) || null;\n\n date = date && date\n .startOf('day') // Reset hour\n .utc() // Convert to UTC (avoid TZ offset in final string)\n || null;\n\n // Convert to model value (ISO date string)\n // IMPORTANT: If date is invalid, then keep the invalid string value\n // to allow SharedValidators.validDate() to raise an error\n const formControlValue = date && date.isValid() ? toDateISOString(date) : (value || null);\n\n if (this.formControl.value !== formControlValue) {\n\n // DEBUG\n //console.debug('[mat-date] Emit new value: ' + dateStr);\n\n // Apply to form control. => Will call writeValue()\n // NOT NEED, because a formControl should NOT be used by multiple fields\n //this.formControl.setValue(dateStr, {emitEvent: false})\n\n // Changes comes from inside function: use the callback\n this._onChangeCallback(formControlValue);\n\n // Check if need to update controls\n this.checkIfTouched();\n }\n\n // Force the day control to update its validity (same errors as formControl - see ngOnInit())\n this.textControl.updateValueAndValidity();\n\n this._writing = false;\n }\n\n private async waitKeyboardHide(waitKeyboardDelay: boolean) {\n\n if (!this.keyboard || !this.keyboard.isVisible) return; // ok, already hidden (or not accessible)\n\n // Force keyboard to be hide\n this.keyboard.hide();\n\n // Wait hide occur\n await this.keyboard.onKeyboardHide().pipe(first()).toPromise();\n\n // Wait an additional delay if need (depending on the OS)\n if (this._keyboardHideDelay > 0 && waitKeyboardDelay) {\n await sleep(this._keyboardHideDelay);\n }\n }\n\n private updateTabIndex() {\n if (isNil(this._tabindex) || this._tabindex === -1) return; // skip\n\n // Focus to first input\n setTimeout(() => {\n this.matInputs.forEach((elementRef, index) => {\n setTabIndex(elementRef, this._tabindex + index);\n });\n this.markForCheck();\n });\n }\n\n private markAsTouched(opts?: {onlySelf?: boolean}) {\n this.textControl.markAsTouched(opts);\n this._onTouchedCallback();\n this.markForCheck();\n }\n\n private markAsDirty(opts?: any) {\n this.formControl.markAsDirty(opts);\n }\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n}\n\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, Optional, Provider, QueryList, ViewChild, ViewChildren } from '@angular/core';\nimport { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field';\nimport { ControlValueAccessor, FormBuilder, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';\nimport { TranslateService } from '@ngx-translate/core';\nimport { isMoment, Moment } from 'moment';\nimport { DEFAULT_PLACEHOLDER_CHAR, KEYBOARD_HIDE_DELAY_MS } from '../../constants';\nimport { SharedValidators } from '../../validator/validators';\nimport { Keyboard } from '@ionic-native/keyboard/ngx';\nimport { filter, first } from 'rxjs/operators';\nimport { InputElement, setTabIndex } from '../../inputs';\nimport { isFocusableElement } from '../../focusable';\nimport { merge, Subscription } from 'rxjs';\nimport { DateFilterFn, MatDatepicker, MatDatepickerInputEvent } from '@angular/material/datepicker';\nimport { isBlankString, isNil, isNilOrBlank, isNotNil, isNotNilBoolean, sleep } from '../../functions';\nimport { DateUtils, fromDateISOString, toDateISOString } from '../../dates';\nimport { isMobile } from '../../platforms';\nimport { MomentDateAdapter } from '@angular/material-moment-adapter';\n\nconst DEFAULT_VALUE_ACCESSOR: Provider = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MatDateTime),\n multi: true\n};\n\nconst DAY_MASK = [/\\d/, /\\d/, '/', /\\d/, /\\d/, '/', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst HOUR_REGEXP = /^[012][0-9][:][012345][0-9]$/;\nconst HOUR_MASK = [/[012]/, /\\d/, ':', /[012345]/, /\\d/];\n\nconst noop = () => {};\n\ndeclare interface NgxTimePicker {\n selectedHour: { time: number };\n selectedMinute: { time: number };\n open();\n close();\n}\n\n@Component({\n selector: 'mat-date-time-field',\n templateUrl: './material.datetime.html',\n styleUrls: ['./material.datetime.scss'],\n providers: [\n DEFAULT_VALUE_ACCESSOR,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatDateTime implements OnInit, OnDestroy, ControlValueAccessor, InputElement {\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private _subscription = new Subscription();\n private _writing = true;\n private _disabling = false;\n private _tabindex: number;\n private _keyboardHideDelay: number;\n\n _readonly = false;\n dayControl: FormControl;\n hourControl: FormControl;\n displayPattern: string;\n dayPattern: string;\n locale: string;\n readonly dayMask = DAY_MASK;\n readonly hourMask = HOUR_MASK;\n\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() placeholder: string;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() appearance: MatFormFieldAppearance;\n @Input() required: boolean;\n @Input() mobile: boolean;\n @Input() compact = false;\n @Input() placeholderChar: string = DEFAULT_PLACEHOLDER_CHAR;\n @Input() autofocus = false;\n @Input() startDate: Moment | null = null;\n @Input() clearable = false;\n @Input() datePickerFilter: DateFilterFn<Moment>;\n\n @Input() set readonly(value: boolean){\n this._readonly = value;\n this.markForCheck();\n }\n\n get readonly(): boolean {\n return this._readonly;\n }\n\n @Input() set tabindex(value: number) {\n if (this._tabindex !== value) {\n this._tabindex = value;\n if (!this._writing) this.updateTabIndex();\n }\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n get value(): any {\n return this.formControl.value;\n }\n\n @ViewChild('datePicker') datePicker: MatDatepicker<Moment>;\n @ViewChild('timePicker') timePicker: NgxTimePicker;\n @ViewChildren('matInput') matInputs: QueryList<ElementRef>;\n\n constructor(\n private dateAdapter: MomentDateAdapter,\n private translate: TranslateService,\n private formBuilder: FormBuilder,\n private cd: ChangeDetectorRef,\n @Optional() private keyboard: Keyboard,\n @Optional() private formGroupDir: FormGroupDirective,\n ) {\n this.locale = (translate.currentLang || translate.defaultLang).substr(0, 2);\n }\n\n ngOnInit() {\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-date-time-field>.');\n\n this.mobile = isNotNil(this.mobile) ? this.mobile : isMobile(window);\n // Workaround because ion-datetime has issue (do not returned a ISO date)\n this._keyboardHideDelay = this.mobile && KEYBOARD_HIDE_DELAY_MS || 0;\n\n this.required = isNotNilBoolean(this.required) ? this.required : (this.formControl.validator === Validators.required || isBlankString(this.required));\n\n // Add 'validDate' validator (when existing validator are null or required, to be sure to keep)\n if (!this.formControl.validator || this.formControl.validator === Validators.required) {\n this.formControl.setValidators(this.required ? [Validators.required, SharedValidators.validDate] : SharedValidators.validDate);\n }\n else {\n this.formControl.setValidators(this.required ? [this.formControl.validator, Validators.required, SharedValidators.validDate] :\n [this.formControl.validator, SharedValidators.validDate]);\n }\n\n // Create the day control\n this.dayControl = this.formBuilder.control(null);\n\n // Create the hour control\n this.hourControl = this.formBuilder.control(null, this.mobile ? null : Validators.pattern(HOUR_REGEXP));\n\n // Get patterns to display date and date+time\n this._subscription.add(\n this.translate.get(['COMMON.DATE_PATTERN', 'COMMON.DATE_TIME_PATTERN'])\n .subscribe((patterns) => this.updatePattern(patterns))\n );\n\n this._subscription.add(\n merge(\n this.dayControl.valueChanges,\n this.hourControl.valueChanges\n )\n .subscribe((_) => this.onFormChange())\n );\n\n // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)\n this._subscription.add(\n this.formControl.statusChanges\n .pipe(\n filter((_) => !this.readonly && !this._writing && !this._disabling) // Skip\n )\n .subscribe(() => this.markForCheck())\n );\n\n this.updateTabIndex();\n\n this._writing = false;\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n }\n\n writeValue(value: any): void {\n if (this._writing) return; // Skip\n this._writing = true;\n\n // DEBUG\n // console.debug(\"[mat-date-time] writeValue() with:\", value);\n\n const date = fromDateISOString(value);\n\n if (!date || !date.isValid()) {\n this.dayControl.patchValue(null, {emitEvent: false});\n this.hourControl.patchValue(null, {emitEvent: false});\n }\n else {\n // Format day\n const day = date.clone().startOf('day');\n const dayStr = this.dateAdapter.format(day, this.dayPattern);\n\n // Format time\n let timeStr;\n if (DateUtils.isNoTime(date)) {\n // Clear time\n timeStr = null;\n } else {\n // - Format hh\n let hour: number | string = date.hour();\n hour = hour < 10 ? ('0' + hour) : hour;\n // - Format mm\n let minutes: number | string = date.minutes();\n minutes = minutes < 10 ? ('0' + minutes) : minutes;\n timeStr = `${hour}:${minutes}`;\n }\n\n // Update controls\n this.dayControl.patchValue(dayStr, {emitEvent: false});\n this.hourControl.patchValue(timeStr, {emitEvent: false});\n }\n\n this._writing = false;\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this._disabling) return; // Skip\n\n this._disabling = true;\n if (isDisabled) {\n this.dayControl.disable({emitEvent: false});\n this.hourControl.disable({emitEvent: false});\n } else {\n this.dayControl.enable({emitEvent: false});\n this.hourControl.enable({emitEvent: false});\n }\n this._disabling = false;\n\n this.markForCheck();\n }\n\n onDatePickerChange(event: MatDatepickerInputEvent<Moment>): void {\n // Make sure event is valid\n if (!event || (event.value !== null && !isMoment(event.value))) {\n console.warn('Invalid MatDatepicker event. Skipping', event);\n return; // Skip\n }\n\n // Convert to usable date, then convert to day pattern (e.g DD/MM/YYYY)\n const day = event.value && event.value\n .locale(this.locale) // set locale\n .hour(0).minute(0).seconds(0).millisecond(0) // Reset hour\n .utc(true);\n const dayStr = day && this.dateAdapter.format(day, this.dayPattern) || null;\n\n // Update the day control\n if (this.dayControl.value !== dayStr) {\n\n // DEBUG\n // console.debug(\"[mat-date-time] onDatePickerChange() new value:\", dayStr);\n\n this.dayControl.setValue(dayStr, {\n emitEvent: true // Will call onFormChange\n });\n }\n }\n\n\n onTimePickerChange(timeStr: string) {\n // Update the time control, if need\n if (this.hourControl.value !== timeStr) {\n\n // DEBUG\n // console.debug(\"[mat-date-time] onTimePickerChange() new value:\", timeStr);\n\n this.hourControl.setValue(timeStr, {\n emitEvent: true // Will call onFormChange\n });\n }\n }\n\n async openDatePickerIfMobile(event: UIEvent, datePicker?: MatDatepicker<any>) {\n if (!this.mobile || event.defaultPrevented) return;\n\n this.preventEvent(event);\n\n // Make sure the keyboard is closed\n await this.waitKeyboardHide(false);\n\n // Open the picker\n this.openDatePicker(null, datePicker);\n }\n\n public openDatePicker(event?: UIEvent, datePicker?: MatDatepicker<any>) {\n datePicker = datePicker || this.datePicker;\n if (datePicker) {\n\n if (event) this.preventEvent(event);\n\n if (!datePicker.opened) {\n datePicker.open();\n }\n }\n }\n\n async openTimePickerIfMobile(event: UIEvent) {\n if (!this.mobile || event.defaultPrevented) return;\n\n this.preventEvent(event);\n\n // Make sure the keyboard is closed\n await this.waitKeyboardHide(true);\n\n // Open the picker\n this.openTimePicker(null);\n }\n\n openTimePicker(event: UIEvent) {\n if (!this.timePicker) return; // Skip\n\n this.preventEvent(event);\n\n this.timePicker.open();\n }\n\n preventEvent(event: UIEvent) {\n if (!event) return;\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n }\n\n focus() {\n if (!this.matInputs.length) return;\n\n setTimeout(() => {\n const elementRef = this.matInputs[0]; // get the first element\n if (isFocusableElement(elementRef)) {\n elementRef.focus();\n }\n });\n }\n\n clear() {\n this.formControl.setValue(null);\n this.markAsTouched();\n this.markAsDirty();\n }\n\n /* -- private method -- */\n\n private updatePattern(patterns: {[key: string]: string}) {\n this.displayPattern = (patterns['COMMON.DATE_TIME_PATTERN'] !== 'COMMON.DATE_TIME_PATTERN' ? patterns['COMMON.DATE_TIME_PATTERN'] : 'L LT');\n this.dayPattern = (patterns['COMMON.DATE_PATTERN'] !== 'COMMON.DATE_PATTERN' ? patterns['COMMON.DATE_PATTERN'] : 'L');\n }\n\n checkIfTouched() {\n if (this.dayControl.touched || this.hourControl.touched) {\n this._onTouchedCallback();\n this.markForCheck();\n }\n }\n\n private onFormChange() {\n if (this._writing) return; // Skip if call by self\n this._writing = true;\n\n let dayStr = this.dayControl.value;\n const time = this.hourControl.value;\n\n // DEBUG\n //console.debug(`[mat-date-time] onFormChange() from event: ${event} - controls values: `, [dayStr, time]);\n\n const incompleteValue = isNilOrBlank(time) !== isNilOrBlank(dayStr);\n if (incompleteValue || this.dayControl.invalid || this.hourControl.invalid) {\n this.formControl.markAsPending({onlySelf: true});\n this.formControl.setErrors({\n validDate: incompleteValue,\n ...this.formControl.errors,\n ...this.dayControl.errors,\n ...this.hourControl.errors\n });\n if (this.dayControl.dirty || this.hourControl.dirty) {\n this.formControl.markAsDirty();\n }\n this._writing = false;\n return;\n }\n\n // Make to remove placeholder chars\n while (dayStr && dayStr.indexOf(this.placeholderChar) !== -1) {\n dayStr = dayStr.replace(this.placeholderChar, '');\n }\n\n // Parse day\n const day: Moment = dayStr && this.dateAdapter.parse(dayStr, this.dayPattern) || null;\n\n // Parse time\n const hourParts = (time || '').split(':');\n const hour = parseInt(hourParts[0] || 0);\n const minutes = parseInt(hourParts[1] || 0);\n const dateTime = day && day\n .locale(this.locale) // set as time as locale time\n .hour(hour).minute(minutes)// Set local hour\n .seconds(0).millisecond(0) // Reset seconds/millisecond\n .utc(); // Convert to UTC (avoid TZ offset in final string)\n\n // Set model value\n this.emitChange(dateTime);\n this._writing = false;\n }\n\n private async waitKeyboardHide(waitKeyboardDelay: boolean) {\n\n if (!this.keyboard || !this.keyboard.isVisible) return; // ok, already hidden (or not accessible)\n\n // Force keyboard to be hide\n this.keyboard.hide();\n\n // Wait hide occur\n await this.keyboard.onKeyboardHide().pipe(first()).toPromise();\n\n // Wait an additional delay if need (depending on the OS)\n if (this._keyboardHideDelay > 0 && waitKeyboardDelay) {\n await sleep(this._keyboardHideDelay);\n }\n }\n\n private emitChange(value: Moment) {\n\n // Get the model value\n const dateStr = toDateISOString(value) || null;\n\n if (this.formControl.value !== dateStr) {\n\n // DEBUG\n //console.debug('[mat-date-time] Emit new value: ' + dateStr);\n\n // Apply to form control. => Will call writeValue()\n // NOT NEED, because a formControl should NOT be used by multiple fields\n //this.formControl.setValue(dateStr, {emitEvent: false});\n\n // Changes comes from inside function: use the callback\n this._onChangeCallback(dateStr);\n\n // Check if need to update controls\n this.checkIfTouched();\n }\n }\n\n\n private updateTabIndex() {\n if (isNil(this._tabindex) || this._tabindex === -1) return; // skip\n\n // Focus to first input\n setTimeout(() => {\n this.matInputs.forEach((elementRef, index) => {\n setTabIndex(elementRef, this._tabindex + index);\n });\n this.markForCheck();\n });\n }\n\n private markAsTouched(opts?: {onlySelf?: boolean}) {\n this.dayControl.markAsTouched(opts);\n this.hourControl.markAsTouched(opts);\n this._onTouchedCallback();\n this.markForCheck();\n }\n\n private markAsDirty(opts?: any) {\n this.formControl.markAsDirty(opts);\n }\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnInit, Optional, Provider, QueryList, ViewChild, ViewChildren} from '@angular/core';\nimport {AbstractControl, ControlValueAccessor, FormBuilder, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR, ValidationErrors, Validators} from '@angular/forms';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Moment} from 'moment/moment';\nimport {DATE_ISO_PATTERN, DEFAULT_PLACEHOLDER_CHAR, KEYBOARD_HIDE_DELAY_MS} from '../../constants';\nimport {SharedValidators} from '../../validator/validators';\nimport {isBlankString, isNil, isNilOrBlank, isNotNil, isNotNilBoolean, sleep, toBoolean} from '../../functions';\nimport {toDateISOString} from '../../dates';\nimport {Keyboard} from '@ionic-native/keyboard/ngx';\nimport {first} from 'rxjs/operators';\nimport {InputElement, setTabIndex} from '../../inputs';\nimport {BehaviorSubject} from 'rxjs';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport {MatDatepicker} from '@angular/material/datepicker';\nimport {DateAdapter} from '@angular/material/core';\nimport {isFocusableElement} from '../../focusable';\nimport {isMobile} from '../../platforms';\n\nconst DEFAULT_VALUE_ACCESSOR: Provider = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MatDateShort),\n multi: true\n};\n\nconst DAY_MASK = [/\\d/, /\\d/, /\\d/, /\\d/];\n\nconst noop = () => {\n};\n\n@Component({\n selector: 'mat-date-short-field',\n templateUrl: './material.dateshort.html',\n styleUrls: ['./material.dateshort.scss'],\n providers: [\n DEFAULT_VALUE_ACCESSOR,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatDateShort implements OnInit, ControlValueAccessor, InputElement {\n\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n protected writing = true;\n protected disabling = false;\n protected _tabindex: number;\n protected keyboardHideDelay: number;\n\n dayControl: AbstractControl;\n displayPattern: string;\n dayPattern: string;\n _value: Moment;\n locale: string;\n dayMask = DAY_MASK;\n\n @Input() mobile: boolean;\n @Input() disabled = false;\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() placeholder: string;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() appearance: MatFormFieldAppearance;\n @Input() readonly = false;\n @Input() required: boolean;\n @Input() compact = false;\n @Input() placeholderChar: string = DEFAULT_PLACEHOLDER_CHAR;\n\n @Input() set tabindex(value: number) {\n if (this._tabindex !== value) {\n this._tabindex = value;\n setTimeout(() => this.updateTabIndex());\n }\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n @Input() startDate: Date;\n\n @Input() clearable = false;\n\n @ViewChild('datePicker1') datePicker1: MatDatepicker<Moment>;\n @ViewChild('datePicker2') datePicker2: MatDatepicker<Moment>;\n\n @ViewChildren('matInput') matInputs: QueryList<ElementRef>;\n\n get value(): any {\n return toDateISOString(this._value);\n }\n\n constructor(\n private dateAdapter: DateAdapter<Moment>,\n private translate: TranslateService,\n private formBuilder: FormBuilder,\n private cd: ChangeDetectorRef,\n @Optional() private keyboard: Keyboard,\n @Optional() private formGroupDir: FormGroupDirective,\n ) {\n\n this.locale = (translate.currentLang || translate.defaultLang).substr(0, 2);\n }\n\n ngOnInit() {\n\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-date-short-field>.');\n\n this.mobile = isNotNil(this.mobile) ? this.mobile : isMobile(window);\n // Workaround because ion-datetime has issue (do not returned a ISO date)\n this.keyboardHideDelay = this.mobile && KEYBOARD_HIDE_DELAY_MS || 0;\n\n // Redirect errors from main control, into day sub control\n const $error = new BehaviorSubject<ValidationErrors>(null);\n this.required = isNotNilBoolean(this.required) ? this.required : (this.formControl.validator === Validators.required || isBlankString(this.required));\n this.dayControl = this.formBuilder.control(null, () => $error.getValue());\n\n // Add custom 'validDate' validator\n this.formControl.setValidators(this.required ? Validators.compose([Validators.required, SharedValidators.validDate]) : SharedValidators.validDate);\n\n // Get patterns to display date\n const patterns = this.translate.instant(['COMMON.DATE_YEAR_PATTERN']);\n this.updatePattern(patterns);\n\n this.dayControl.valueChanges\n .subscribe((value) => this.onFormChange(value));\n\n // Listen status changes outside the component (e.g. when setErrors() is calling on the formControl)\n this.formControl.statusChanges\n .subscribe((status) => {\n if (this.readonly || this.writing || this.disabling) return; // Skip\n if (status === 'INVALID') {\n $error.next(this.formControl.errors);\n }\n else if (status === 'VALID') {\n $error.next(null);\n }\n this.dayControl.updateValueAndValidity({onlySelf: true, emitEvent: false});\n this.markForCheck();\n });\n\n this.updateTabIndex();\n\n this.writing = false;\n }\n\n writeValue(obj: any): void {\n if (this.writing) return;\n\n if (isNilOrBlank(obj)) {\n this.writing = true;\n this.dayControl.patchValue(null, {emitEvent: false});\n this._value = undefined;\n if (this.formControl.value) {\n this.formControl.patchValue(null, {emitEvent: false});\n this._onChangeCallback(null);\n }\n this.writing = false;\n this.markForCheck();\n return;\n }\n\n this._value = this.dateAdapter.parse(obj, DATE_ISO_PATTERN);\n if (!this._value) { // invalid date\n return;\n }\n\n this.writing = true;\n\n //console.log(\"call writeValue()\", this.date, this.formControl);\n // Set form value\n this.dayControl.patchValue(this._value.clone().startOf('day').format(this.dayPattern), {emitEvent: false});\n this.writing = false;\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this.disabling) return;\n\n this.disabling = true;\n this.disabled = isDisabled;\n if (isDisabled) {\n this.dayControl.disable({onlySelf: true, emitEvent: false});\n } else {\n this.dayControl.enable({onlySelf: true, emitEvent: false});\n }\n this.disabling = false;\n\n this.markForCheck();\n }\n\n onDatePickerChange(event: any): void {\n //console.debug(\"onDatePickerChange called !!\")\n if (this.writing || !(event && event.value)) return; // Skip if call by self\n this.writing = true;\n\n let date = event.value;\n date = typeof date === 'string' && this.dateAdapter.parse(date, DATE_ISO_PATTERN) || date;\n let day;\n\n // avoid to have TZ offset\n date = date && date.utc(true).hour(0).minute(0).seconds(0).millisecond(0);\n day = date && date.clone().startOf('day');\n\n // update day value\n this.dayControl.setValue(day && day.format(this.dayPattern), {emitEvent: false});\n\n // Get the model value\n const dateStr = date && date.format(DATE_ISO_PATTERN).replace('+00:00', 'Z');\n this.formControl.patchValue(dateStr, {emitEvent: false});\n this.writing = false;\n this.markForCheck();\n\n this._onChangeCallback(dateStr);\n }\n\n private updatePattern(patterns: string[]) {\n this.displayPattern =\n (this.displayPattern = patterns['COMMON.DATE_YEAR_PATTERN'] !== 'COMMON.DATE_YEAR_PATTERN' ? patterns['COMMON.DATE_YEAR_PATTERN'] : 'L');\n this.dayPattern = (patterns['COMMON.DATE_YEAR_PATTERN'] !== 'COMMON.DATE_YEAR_PATTERN' ? patterns['COMMON.DATE_YEAR_PATTERN'] : 'L');\n }\n\n private onFormChange(dayValue): void {\n if (this.writing) return; // Skip if call by self\n this.writing = true;\n\n if (this.dayControl.invalid) {\n this.formControl.markAsPending();\n this.formControl.setErrors(Object.assign({}, this.dayControl.errors));\n this.writing = false;\n return;\n }\n\n // Make to remove placeholder chars\n while (dayValue && dayValue.indexOf(this.placeholderChar) !== -1) {\n dayValue = dayValue.replace(this.placeholderChar, '');\n }\n let date: Moment;\n\n // Parse day string\n date = dayValue && this.dateAdapter.parse(dayValue, this.dayPattern) || null;\n\n // Reset time\n date = date && date.utc(true).hour(0).minute(0).seconds(0).millisecond(0);\n\n // update date picker\n this._value = date && this.dateAdapter.parse(date.clone(), DATE_ISO_PATTERN);\n\n // Get the model value\n const dateStr = date && date.isValid() && date.format(DATE_ISO_PATTERN).replace('+00:00', 'Z') || date;\n //console.debug(\"[mat-date-time] Setting date: \", dateStr);\n this.formControl.patchValue(dateStr, {emitEvent: false});\n //this.formControl.updateValueAndValidity();\n this.writing = false;\n this.markForCheck();\n\n this._onChangeCallback(dateStr);\n }\n\n\n\n public checkIfTouched() {\n if (this.dayControl.touched) {\n this.markForCheck();\n this._onTouchedCallback();\n // this.writeValue(this.dayControl.value);\n this.onDatePickerChange(this.dayControl);\n }\n }\n\n async openDatePickerIfMobile(event: UIEvent, datePicker?: MatDatepicker<any>) {\n if (!this.mobile || event.defaultPrevented) return;\n\n this.preventEvent(event);\n\n // Make sure the keyboard is closed\n await this.waitKeyboardHide(false);\n\n // Open the picker\n this.openDatePicker(null, datePicker);\n }\n\n public openDatePicker(event?: UIEvent, datePicker?: MatDatepicker<any>) {\n\n datePicker = this.datePicker1 || this.datePicker2;\n if (datePicker) {\n\n if (event) this.preventEvent(event);\n\n if (!datePicker.opened) {\n\n // datePicker.startView = \"multi-year\";\n datePicker.open();\n }\n }\n }\n\n // select only year\n closeDatePicker(eventData: any, matDatepicker?: any) {\n this.formControl.setValue(eventData);\n matDatepicker.close();\n }\n\n\n preventEvent(event: UIEvent) {\n if (!event) return;\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n }\n\n focus() {\n if (!this.matInputs.length) return;\n\n setTimeout(() => {\n const elementRef = this.matInputs[0]; // get the first element\n if (isFocusableElement(elementRef)) {\n elementRef.focus();\n }\n });\n }\n\n /* -- protected method -- */\n\n protected async waitKeyboardHide(waitKeyboardDelay: boolean) {\n\n if (!this.keyboard || !this.keyboard.isVisible) return; // ok, already hidden (or not accessible)\n\n // Force keyboard to be hide\n this.keyboard.hide();\n\n // Wait hide occur\n await this.keyboard.onKeyboardHide().pipe(first()).toPromise();\n\n // Wait an additional delay if need (depending on the OS)\n if (this.keyboardHideDelay > 0 && waitKeyboardDelay) {\n await sleep(this.keyboardHideDelay);\n }\n }\n\n protected updateTabIndex() {\n if (isNil(this._tabindex) || this._tabindex === -1) return; // skip\n\n // Focus to first input\n setTimeout(() => {\n this.matInputs.forEach((elementRef, index) => {\n setTabIndex(elementRef, this._tabindex + index);\n });\n this.markForCheck();\n });\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n","import {NgModule} from '@angular/core';\nimport {MatCommonModule} from '@angular/material/core';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {MatIconModule} from '@angular/material/icon';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {SharedPipesModule} from '../../pipes/pipes.module';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {MatDate} from './material.date';\nimport {MatDateTime} from './material.datetime';\nimport {TextMaskModule} from 'angular2-text-mask';\nimport {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';\nimport {MatDatepickerModule} from '@angular/material/datepicker';\nimport {MatButtonModule} from '@angular/material/button';\nimport {MatDateShort} from './material.dateshort';\nimport {SharedDirectivesModule} from '../../directives/directives.module';\nimport {MatMomentDateModule} from '@angular/material-moment-adapter';\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n SharedPipesModule,\n MatCommonModule,\n MatFormFieldModule,\n MatInputModule,\n MatIconModule,\n MatButtonModule,\n MatDatepickerModule,\n MatMomentDateModule,\n TextMaskModule,\n NgxMaterialTimepickerModule,\n TranslateModule.forChild(),\n SharedDirectivesModule\n ],\n exports: [\n MatIconModule,\n MatDate,\n MatDateTime,\n MatDateShort\n ],\n declarations: [\n MatDate,\n MatDateTime,\n MatDateShort\n ]\n})\nexport class SharedMatDateTimeModule {\n}\n\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n forwardRef,\n Input,\n OnDestroy,\n OnInit,\n Optional, Provider,\n QueryList,\n ViewChildren\n} from '@angular/core';\nimport {Platform} from '@ionic/angular';\nimport {DateAdapter} from '@angular/material/core';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport {\n ControlValueAccessor,\n FormBuilder,\n FormControl,\n FormGroupDirective,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validators\n} from '@angular/forms';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Moment} from 'moment';\nimport {DEFAULT_PLACEHOLDER_CHAR} from '../../constants';\nimport {isBlankString, isNil, isNotNilBoolean, toBoolean} from '../../functions';\nimport {InputElement, moveInputCaretToSeparator, setTabIndex} from '../../inputs';\nimport {isFocusableElement} from '../../focusable';\nimport {DEFAULT_MAX_DECIMALS, formatDuration, parseDuration} from './duration.utils';\nimport {BehaviorSubject, Subscription} from 'rxjs';\nimport {filter} from 'rxjs/operators';\n\nconst DEFAULT_VALUE_ACCESSOR: Provider = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MatDuration),\n multi: true\n};\n\nconst HOUR_TIME_PATTERN = /[0-9]\\d\\d:[0-5]\\d/;\nconst HOUR_MASK = [/\\d/, /\\d/, /\\d/, ':', /[0-5]/, /\\d/];\n\nconst noop = () => {\n};\n\n@Component({\n selector: 'mat-duration-field',\n templateUrl: './material.duration.html',\n styleUrls: ['./material.duration.scss'],\n providers: [\n DEFAULT_VALUE_ACCESSOR,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatDuration implements OnInit, OnDestroy, ControlValueAccessor, InputElement {\n private _subscription = new Subscription();\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private writing = true;\n private disabling = false;\n private _tabindex: number;\n private _value: number;\n\n textControl: FormControl;\n hourMask = HOUR_MASK;\n\n @Input() disabled = false;\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() placeholder: string;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() appearance: MatFormFieldAppearance;\n @Input() readonly = false;\n @Input() required: boolean;\n @Input() compact = false;\n @Input() maxDecimals: number = DEFAULT_MAX_DECIMALS;\n @Input() placeholderChar: string = DEFAULT_PLACEHOLDER_CHAR;\n\n @Input() set tabindex(value: number) {\n if (this._tabindex !== value) {\n this._tabindex = value;\n setTimeout(() => this.updateTabIndex());\n }\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n @Input() clearable = false;\n\n @ViewChildren('matInput') matInputs: QueryList<ElementRef>;\n\n get value(): any {\n return this._value;\n }\n\n constructor(\n platform: Platform,\n private dateAdapter: DateAdapter<Moment>,\n private translate: TranslateService,\n private formBuilder: FormBuilder,\n private cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective,\n ) {\n }\n\n ngOnInit() {\n\n if (this.maxDecimals) {\n if (this.maxDecimals < 0) {\n console.error('Invalid attribute \\'maxDecimals\\'. Must a positive value.');\n this.maxDecimals = DEFAULT_MAX_DECIMALS;\n }\n else if (this.maxDecimals < DEFAULT_MAX_DECIMALS) {\n console.warn(`Invalid attribute 'maxDecimals' - Value should be more than ${DEFAULT_MAX_DECIMALS}, otherwise the round trip conversion will lose minutes.`);\n this.maxDecimals = DEFAULT_MAX_DECIMALS;\n }\n }\n\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-duration-field>.');\n\n this.required = isNotNilBoolean(this.required) ? this.required : (this.formControl.validator === Validators.required || isBlankString(this.required));\n\n // Redirect errors from main control, into day sub control\n const $error = new BehaviorSubject<ValidationErrors>(null);\n this.textControl = this.formBuilder.control(null, null);\n this.textControl.setValidators(this.required ? [Validators.required, () => $error.getValue(), Validators.pattern(HOUR_TIME_PATTERN)] :\n [() => $error.getValue(), Validators.pattern(HOUR_TIME_PATTERN)]);\n\n this._subscription.add(\n this.textControl.valueChanges\n .subscribe((value) => this.onFormChange(value))\n );\n\n // Listen status changes outside the component (e.g. when setErrors() is calling on the formControl)\n this._subscription.add(\n this.formControl.statusChanges\n .pipe(filter(() => !this.readonly && !this.writing && !this.disabling)) // Skip\n .subscribe((status) => {\n if (status === 'INVALID') {\n $error.next(this.formControl.errors);\n }\n else if (status === 'VALID') {\n $error.next(null);\n }\n this.textControl.updateValueAndValidity({onlySelf: true, emitEvent: false});\n this.markForCheck();\n }));\n\n this.updateTabIndex();\n\n this.writing = false;\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n }\n\n writeValue(obj: any): void {\n if (this.writing) return;\n\n // console.debug('[mat-duration] writeValue:', obj);\n\n if (isNil(obj)) {\n this.writing = true;\n this.textControl.patchValue(null, {emitEvent: false});\n this._value = undefined;\n if (this.formControl.value) {\n this.formControl.patchValue(null, {emitEvent: false});\n this._onChangeCallback(null);\n }\n this.writing = false;\n this.markForCheck();\n return;\n }\n\n this._value = obj;\n if (isNaN(this._value)) { // invalid value\n return;\n }\n\n this.writing = true;\n\n console.debug(`[mat-duration] Formatted hour: ${this._value} to ${formatDuration(this._value)}`);\n\n // Set form value\n this.textControl.patchValue(formatDuration(this._value), {emitEvent: false});\n this.writing = false;\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this.disabling) return;\n\n this.disabling = true;\n this.disabled = isDisabled;\n if (isDisabled) {\n this.textControl.disable({onlySelf: true, emitEvent: false});\n } else {\n this.textControl.enable({onlySelf: true, emitEvent: false});\n }\n this.disabling = false;\n\n this.markForCheck();\n }\n\n private onFormChange(value): void {\n if (this.writing) return; // Skip if call by self\n this.writing = true;\n\n console.debug('[mat-duration] onFormChange:', value);\n\n if (this.textControl.hasError('pattern') || this.textControl.hasError('required')) {\n this.formControl.markAsPending();\n this.formControl.setErrors({\n pattern: this.textControl.errors.pattern,\n required: this.textControl.errors.required\n });\n this.writing = false;\n return;\n }\n\n this._value = parseDuration(value || '', this.maxDecimals, this.placeholderChar);\n\n console.debug('[mat-duration] Setting duration: ', this._value);\n this.formControl.patchValue(this._value, {emitEvent: false});\n //this.formControl.updateValueAndValidity();\n this.writing = false;\n this.markForCheck();\n\n this._onChangeCallback(this._value);\n }\n\n checkIfTouched() {\n if (this.textControl.touched) {\n this.markForCheck();\n this._onTouchedCallback();\n }\n }\n\n preventEvent(event: UIEvent) {\n if (!event) return;\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n }\n\n focus() {\n if (!this.matInputs.length) return;\n\n setTimeout(() => {\n const elementRef = this.matInputs[0]; // get the first element\n if (isFocusableElement(elementRef)) {\n elementRef.focus();\n }\n });\n }\n\n moveCaretToSeparator(event: any, forward: boolean): boolean {\n // Move to the next separator\n return moveInputCaretToSeparator(event, ':', forward);\n }\n\n /* -- protected method -- */\n\n protected updateTabIndex() {\n if (isNil(this._tabindex) || this._tabindex === -1) return; // skip\n\n // Focus to first input\n setTimeout(() => {\n this.matInputs.forEach((elementRef, index) => {\n setTabIndex(elementRef, this._tabindex + index);\n });\n this.markForCheck();\n });\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n\n","import {NgModule} from '@angular/core';\nimport {MatCommonModule, MatRippleModule} from '@angular/material/core';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {SharedPipesModule} from '../../pipes/pipes.module';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {TextMaskModule} from 'angular2-text-mask';\nimport {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';\nimport {MatDuration} from './material.duration';\nimport {MatMomentDateModule} from '@angular/material-moment-adapter';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n SharedPipesModule,\n MatCommonModule,\n MatFormFieldModule,\n MatInputModule,\n TextMaskModule,\n NgxMaterialTimepickerModule,\n MatRippleModule,\n MatMomentDateModule,\n TranslateModule.forChild()\n ],\n exports: [\n MatDuration\n ],\n declarations: [\n MatDuration\n ]\n})\nexport class SharedMatDurationModule {\n}\n\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Optional, Output, Provider, ViewChild } from '@angular/core';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport { ControlValueAccessor, FormBuilder, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { TranslateService } from '@ngx-translate/core';\nimport { isNil, isNotNil, toNumber } from '../../functions';\nimport { InputElement } from '../../inputs';\nimport { MatRadioButton, MatRadioChange } from '@angular/material/radio';\nimport { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox';\n\nconst DEFAULT_VALUE_ACCESSOR: Provider = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MatBooleanField),\n multi: true\n};\n\n\nconst noop = () => {\n};\n\n@Component({\n selector: 'mat-boolean-field',\n templateUrl: './material.boolean.html',\n styleUrls: ['./material.boolean.scss'],\n providers: [\n DEFAULT_VALUE_ACCESSOR\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatBooleanField implements OnInit, ControlValueAccessor, InputElement {\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private _writing = false;\n\n _value: boolean;\n _tabindex: number;\n\n showRadio = false;\n\n @Input() disabled = false;\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() placeholder: string;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() appearance: MatFormFieldAppearance;\n @Input() readonly = false;\n @Input() required = false;\n @Input() compact = false;\n @Input() style: 'radio' | 'checkbox' | 'button';\n @Input() buttonsColCount: number;\n @Input('class') classList: string;\n @Input() yesLabel = 'COMMON.YES';\n @Input() noLabel = 'COMMON.NO';\n @Input() showButtonIcons = true;\n @Input() yesIcon = 'checkmark';\n @Input() noIcon = 'close';\n\n @Output('keyup.enter')\n onPressEnter = new EventEmitter<any>();\n\n @Output()\n onBlur = new EventEmitter<FocusEvent>();\n\n @Input() set tabindex(value: number) {\n if (this._tabindex !== value) {\n this._tabindex = value;\n setTimeout(() => this.updateTabIndex());\n }\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n get value(): any {\n return this._value;\n }\n\n @Input()\n set value(v: any) {\n if (v !== this._value) {\n this._value = v;\n this._onChangeCallback(v);\n }\n }\n\n @ViewChild('yesButton') yesButton: MatRadioButton;\n @ViewChild('noButton') noButton: MatRadioButton;\n @ViewChild('checkboxButton') checkboxButton: MatCheckbox;\n @ViewChild('fakeInput') fakeInput: ElementRef;\n\n constructor(\n private translate: TranslateService,\n private formBuilder: FormBuilder,\n private cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) { }\n\n ngOnInit() {\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-boolean-field>.');\n\n this.style = this.style || (this.compact ? 'checkbox' : 'radio');\n\n if (this.style === 'button') {\n this.buttonsColCount = toNumber(this.buttonsColCount, 2);\n }\n\n // Force show radio if label always on top\n this.showRadio = this.showRadio || this.floatLabel === 'always';\n\n this.updateTabIndex();\n }\n\n writeValue(value: any, event?: UIEvent): void {\n if (this._writing) return;\n\n this._writing = true;\n if (value !== this._value) {\n this._value = value;\n this.showRadio = this.floatLabel === 'always' || isNotNil(this._value);\n if (isNotNil(this.tabindex)) {\n setTimeout(() => this.updateTabIndex());\n }\n }\n this._writing = false;\n\n if (this.style === 'button') {\n if (value !== this.formControl.value) {\n this.formControl.patchValue(value, {emitEvent: false});\n this._onChangeCallback(value);\n }\n if (event) this.onPressEnter.emit(event);\n }\n\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n\n _onBlur(event: FocusEvent) {\n this.checkIfTouched();\n this.onBlur.emit(event);\n }\n\n _onFocusFakeInput(event: FocusEvent) {\n event.preventDefault();\n\n // Hide the fake input\n if (this.fakeInput) {\n this.fakeInput.nativeElement.classList.add('hidden');\n this.fakeInput.nativeElement.tabIndex = -1;\n }\n\n // Focus on first button\n this.focus();\n }\n\n focus() {\n this.showRadio = true;\n setTimeout(() => {\n if (this.yesButton) {\n this.yesButton.focus();\n }\n else if (this.checkboxButton) {\n this.checkboxButton.focus();\n }\n this.updateTabIndex();\n });\n this.markForCheck();\n }\n\n onRadioValueChanged(event: MatRadioChange): void {\n if (this._writing) return; // Skip if call by self\n this._writing = true;\n this._value = event.value;\n this.checkIfTouched();\n this._onChangeCallback(event.value);\n this._writing = false;\n }\n\n onCheckboxValueChanged(event: MatCheckboxChange): void {\n if (this._writing) return; // Skip if call by self\n this._writing = true;\n this._value = event.checked;\n this.checkIfTouched();\n this._onChangeCallback(event.checked);\n this._writing = false;\n }\n\n /* -- private method -- */\n\n private checkIfTouched() {\n if (this.formControl.touched) {\n this.markForCheck();\n this._onTouchedCallback();\n }\n }\n\n /**\n * This is a special case, because, this component has a temporary component displayed before the first focus event\n */\n private updateTabIndex() {\n if (isNil(this._tabindex) || this._tabindex === -1) return;\n\n if (this.fakeInput) {\n if (this.showRadio) {\n this.fakeInput.nativeElement.classList.add('hidden');\n this.fakeInput.nativeElement.tabIndex = -1;\n } else {\n this.fakeInput.nativeElement.classList.remove('hidden');\n this.fakeInput.nativeElement.tabIndex = this._tabindex;\n }\n }\n if (this.yesButton) {\n this.yesButton._inputElement.nativeElement.tabIndex = this.showRadio ? this._tabindex : -1;\n this.noButton._inputElement.nativeElement.tabIndex = this.showRadio ? this._tabindex + 1 : -1;\n } else if (this.checkboxButton) {\n this.checkboxButton._inputElement.nativeElement.tabIndex = this.showRadio ? this._tabindex : -1;\n }\n this.markForCheck();\n }\n\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n}\n\n","import {NgModule} from '@angular/core';\nimport {MatCommonModule} from '@angular/material/core';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {SharedPipesModule} from '../../pipes/pipes.module';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {TextMaskModule} from 'angular2-text-mask';\nimport {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';\nimport {MatBooleanField} from './material.boolean';\nimport {MatRadioModule} from '@angular/material/radio';\nimport {MatCheckboxModule} from '@angular/material/checkbox';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n SharedPipesModule,\n MatCommonModule,\n MatFormFieldModule,\n MatInputModule,\n MatRadioModule,\n MatCheckboxModule,\n TextMaskModule,\n NgxMaterialTimepickerModule,\n TranslateModule.forChild()\n ],\n exports: [\n MatBooleanField\n ],\n declarations: [\n MatBooleanField\n ]\n})\nexport class SharedMatBooleanModule {\n}\n\n","import {EventEmitter} from '@angular/core';\n\nexport interface MatNumpadRef {\n\n keypress: EventEmitter<KeyboardEvent>;\n\n close(): void;\n}\n\nexport interface MatNumpadConfig {\n inputElement: any;\n keymap: MatNumpadKey[][];\n numpadRef: MatNumpadRef;\n decimal: boolean;\n disableAnimation: boolean;\n noBackdrop: boolean;\n position: string;\n\n appendToInput: boolean;\n // TODO\n //cssClass width = scope.settings.width || '100%';\n //scope.align = scope.settings.align || 'center';\n // animation: 'slide-up' | 'pop'\n // resizeContent: true\n // animationDuration = 150;\n}\n\nexport interface MatNumpadKey {\n key: string;\n label?: string | number;\n color?: string;\n matIcon?: string;\n icon?: string;\n}\n\nexport declare type MatNumpadKeymap = MatNumpadKey[][];\n\nexport const DEFAULT_KEYMAP: MatNumpadKeymap = [\n [{key: '1'}, {key: '2'}, {key: '3'}, {key: 'Backspace', icon: 'backspace', color: 'light'}],\n [{key: '4'}, {key: '5'}, {key: '6'}, {key: 'Tab', label: 'COMMON.BTN_NEXT_SHORT', color: 'light'}],\n [{key: '7'}, {key: '8'}, {key: '9'}, {key: '.', label: 'COMMON.BTN_DECIMAL_SEPARATOR', color: 'light'}],\n [null, {key: '0'}, null, {key: 'Enter', icon: 'checkmark', color: 'tertiary'}]\n];\n\n//export declare type MatNumpadEventDetail = MatNumpadKey & {target: any};\n//export declare type MatNumpadEvent = CustomEvent<MatNumpadEventDetail>\n\nexport class MatNumpadEvent extends KeyboardEvent {\n inputTarget: any;\n constructor(type: string, init: KeyboardEventInit & {target: any}) {\n super(type, init);\n this.inputTarget = init && init.target;\n }\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit} from '@angular/core';\nimport {MatNumpadConfig, MatNumpadEvent, MatNumpadKey, MatNumpadKeymap, MatNumpadRef} from './numpad.model';\nimport {BehaviorSubject} from 'rxjs';\nimport {animate, AnimationEvent, state, style, transition, trigger} from '@angular/animations';\n\nexport enum AnimationState {\n ENTER = 'enter',\n ENTER_INPUT = 'enter-input',\n LEAVE = 'leave'\n}\n@Component({\n selector: 'mat-numpad-container',\n templateUrl: './numpad.container.html',\n styleUrls: ['./numpad.container.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n // Backdrop animation\n trigger('numpadBackdrop', [\n state('*', style({opacity: 0, background: 'transparent'})),\n state(AnimationState.ENTER, style({opacity: 1})),\n state(AnimationState.LEAVE, style({opacity: 0})),\n transition(`* => ${AnimationState.ENTER}`, [\n style({opacity: 0}),\n animate('0.4s cubic-bezier(0.25, 0.8, 0.25, 1)')\n ]),\n transition(`${AnimationState.ENTER} => ${AnimationState.LEAVE}`, [\n style({ opacity: 1}),\n animate('0.2s cubic-bezier(0.25, 0.8, 0.25, 1)')\n ])\n ]),\n\n // Fade in\n trigger('numpadFadeIn', [\n state('*', style({opacity: 1, transform: 'scale(1)'})),\n state(AnimationState.ENTER, style({opacity: 1, transform: 'scale(1)'})),\n state(AnimationState.LEAVE, style({opacity: 0, transform: 'scale(0.9)'})),\n // Modal\n transition(`* => ${AnimationState.ENTER}`, [\n style({opacity: 0, transform: 'scale(0.6)'}),\n animate('0.2s ease-out')\n ]),\n transition(`${AnimationState.ENTER} => ${AnimationState.LEAVE}`, [\n animate('0.2s ease-out')\n ]) ]),\n\n // Panel expansion\n trigger('numpadPanelExpansion', [\n state('*', style({opacity: 1, transform: 'scaleY(0) translateY(-50%)'})),\n state(AnimationState.ENTER, style({opacity: 1, transform: 'scale(1) translateY(0)'})),\n state(AnimationState.LEAVE, style({opacity: 0, transform: 'scale(1) translateY(0)'})),\n\n // Attach to input\n transition(`* => ${AnimationState.ENTER}`, [\n animate('0.2s ease-out')\n ]),\n transition(`${AnimationState.ENTER} => ${AnimationState.LEAVE}`, [\n animate('0.2s ease-out')\n ])\n ])\n ]\n})\nexport class MatNumpadContainerComponent implements OnInit, OnDestroy, MatNumpadConfig {\n\n private debug = true;\n\n backdropState: AnimationState = AnimationState.LEAVE;\n modalState: AnimationState;\n panelState: AnimationState;\n numpadRef: MatNumpadRef;\n inputElement: any;\n columnCount = 4;\n\n filteredKeymap = new BehaviorSubject<MatNumpadKeymap>(undefined);\n\n // Config options\n decimal: boolean;\n disabled: boolean;\n appendToInput: boolean;\n keymap: MatNumpadKeymap;\n disableAnimation: boolean;\n noBackdrop: boolean;\n position: string;\n\n constructor(\n protected cd: ChangeDetectorRef\n ) {\n if (this.debug) console.debug('[numpad-container] Creating component');\n }\n\n ngOnInit(): void {\n if (!this.keymap || !this.keymap.length) {\n throw new Error('An invalid \\'keymap\\' was sent to numpad container');\n }\n\n\n if (!this.disableAnimation) {\n if (this.appendToInput) {\n this.panelState = AnimationState.ENTER;\n }\n else {\n this.modalState = AnimationState.ENTER;\n }\n }\n\n this.noBackdrop = this.noBackdrop || this.appendToInput;\n if (!this.noBackdrop) {\n this.backdropState = AnimationState.ENTER;\n }\n\n const keymap = this.defineFilteredKeymap();\n this.filteredKeymap.next(keymap);\n\n // Count columns\n this.columnCount = keymap.reduce((res, row) => row && Math.max(res, row.length), 0);\n if (this.debug) console.debug('[numpad-container] columnCount=' + this.columnCount);\n\n //this.markForCheck();\n }\n\n ngOnDestroy(): void {\n }\n\n onButtonClick(event: UIEvent, keyDef: MatNumpadKey) {\n if (this.debug) console.debug('[numpad-container] onKeyPress() ', keyDef.key);\n\n const customEvent = new MatNumpadEvent('keypress', {key: keyDef.key, target: this.inputElement});\n\n //{detail: {...keyDef, target: this.inputElement}})\n this.numpadRef.keypress.next(customEvent);\n }\n\n @HostListener('window:keydown', ['$event'])\n onKeydown(event: KeyboardEvent) {\n //if (this.debug)\n console.debug('[numpad-container] onKeypress()', event);\n this.numpadRef.keypress.next(event);\n }\n\n overlayClick(event: UIEvent) {\n\n this.close();\n }\n\n close(): void {\n if (this.disableAnimation) {\n this.numpadRef.close();\n return;\n }\n\n if (this.modalState) this.modalState = AnimationState.LEAVE;\n if (this.panelState) this.panelState = AnimationState.LEAVE;\n if (this.backdropState) this.backdropState = AnimationState.LEAVE;\n this.markForCheck();\n }\n\n animationDone(event: AnimationEvent): void {\n if (event.phaseName === 'done' && event.toState === AnimationState.LEAVE) {\n this.numpadRef.close();\n }\n }\n\n protected defineFilteredKeymap(): MatNumpadKeymap {\n let keymap = this.keymap;\n\n // Replace decimal separator button, by empty\n if (!this.decimal) {\n keymap = keymap.map(row => row.map(item => item && item.key !== '.' && item.key !== ',' ? item : null));\n }\n\n return keymap;\n }\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n}\n","import {\n ApplicationRef,\n ComponentFactoryResolver,\n ComponentRef,\n EmbeddedViewRef,\n Inject,\n Injectable,\n Injector,\n Optional,\n Type\n} from '@angular/core';\nimport {DOCUMENT} from '@angular/common';\nimport {MatNumpadContainerComponent} from './numpad.container';\nimport {MatNumpadConfig} from './numpad.model';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MatNumpadDomService {\n\n private componentRef: ComponentRef<MatNumpadContainerComponent>;\n\n constructor(private cfr: ComponentFactoryResolver,\n private appRef: ApplicationRef,\n private injector: Injector,\n @Optional() @Inject(DOCUMENT) private document: any) {\n }\n\n appendNumpadToBody(numpadType: Type<MatNumpadContainerComponent>, config: MatNumpadConfig): void {\n this.componentRef = this.cfr.resolveComponentFactory(numpadType).create(this.injector);\n\n Object.keys(config).forEach(key => this.componentRef.instance[key] = config[key]);\n\n this.appRef.attachView(this.componentRef.hostView);\n\n const domElement: HTMLElement = (this.componentRef.hostView as EmbeddedViewRef<MatNumpadContainerComponent>)\n .rootNodes[0];\n\n this.document.body.appendChild(domElement);\n }\n\n destroyNumpad(): void {\n this.componentRef.destroy();\n this.appRef.detachView(this.componentRef.hostView);\n }\n}\n","import {DEFAULT_KEYMAP, MatNumpadEvent, MatNumpadKeymap, MatNumpadRef} from './numpad.model';\nimport {Component, EventEmitter, Input, Output} from '@angular/core';\nimport {NumpadDirective} from './numpad.directive';\nimport {MatNumpadContainerComponent} from './numpad.container';\nimport {MatNumpadDomService} from './numpad.dom-service';\n\n@Component({\n selector: 'mat-numpad',\n template: '',\n})\nexport class MatNumpadComponent implements MatNumpadRef {\n\n private _inputRef: NumpadDirective;\n private _opened = false;\n\n @Input() keymap: MatNumpadKeymap = DEFAULT_KEYMAP;\n\n @Input() decimal = true;\n\n @Input() appendToInput: boolean;\n @Input() disableAnimation = false;\n @Input() noBackdrop = false;\n @Input() position = 'bottom';\n\n @Output() keypress = new EventEmitter<KeyboardEvent>();\n @Output() closed = new EventEmitter<null>();\n\n get opened(): boolean {\n return this._opened;\n }\n\n get inputElement(): any {\n return this._inputRef && this._inputRef.element;\n }\n\n constructor(\n private domService: MatNumpadDomService\n ) {\n }\n\n registerInput(input: NumpadDirective) {\n if (this._inputRef) {\n throw new Error('A Numpad can only be registered to one input.');\n }\n this._inputRef = input;\n }\n\n open() {\n // Already open. Skip.\n if (this._opened) return;\n\n console.debug('[numpad] Opening numpad...');\n\n this.domService.appendNumpadToBody(MatNumpadContainerComponent, {\n numpadRef: this,\n decimal: this.decimal,\n keymap: this.keymap,\n inputElement: this.inputElement,\n appendToInput: this.appendToInput,\n disableAnimation: this.disableAnimation,\n noBackdrop: this.noBackdrop,\n position: this.position\n });\n\n this._opened = true;\n }\n\n close() {\n console.debug('[numpad] Closing numpad...');\n this.domService.destroyNumpad();\n this._opened = false;\n\n // Emit close event\n this.closed.next();\n }\n\n\n}\n","import {Directive, ElementRef, HostListener, Input, OnChanges, OnDestroy, SimpleChanges} from '@angular/core';\nimport {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';\nimport {Subscription} from 'rxjs';\nimport {MatNumpadKeymap} from './numpad.model';\nimport {MatNumpadComponent} from './numpad.component';\n\n@Directive({\n selector: '[matNumpad]',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: NumpadDirective,\n multi: true\n }\n ],\n host: {\n '[disabled]': 'disabled',\n // '[decimal]': 'decimal',\n '(click)': 'onClick($event)',\n '(change)': 'updateValue($event.target.value)',\n '(blur)': 'onTouched()'\n },\n})\nexport class NumpadDirective implements ControlValueAccessor, OnDestroy, OnChanges {\n\n private _numpad: MatNumpadComponent;\n\n @Input() keymap: MatNumpadKeymap;\n\n @Input('matNumpad')\n set numpad(numpad: MatNumpadComponent) {\n this.registerNumpad(numpad);\n }\n\n @Input()\n set value(value: string) {\n this._value = value || '';\n this.updateInputValue();\n return;\n }\n\n get value(): string {\n if (!this._value) {\n return '';\n }\n return this._value;\n }\n\n private _value = '';\n\n @Input() disabled: boolean;\n @Input() decimal: boolean;\n @Input() disableClick: boolean;\n\n private numpadSubscriptions: Subscription[] = [];\n\n onTouched = () => {\n };\n\n private onChange: (value: any) => void = () => {\n };\n\n constructor(private elementRef: ElementRef) {\n }\n\n get element(): any {\n return this.elementRef && this.elementRef.nativeElement;\n }\n\n updateValue(value: string) {\n console.debug('[numpad-directive] updateValue()', value);\n this.value = value;\n this.onChange(value);\n }\n\n ngOnChanges(changes: SimpleChanges){\n /*if (changes['value'] && changes['value'].currentValue) {\n this.defaultValue = changes['value'].currentValue;\n }*/\n }\n\n @HostListener('click', ['$event'])\n onClick(event: UIEvent) {\n if (!this.disableClick) {\n this._numpad.open();\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n writeValue(value: string): void {\n this.value = value;\n if (value) {\n //this.defaultValue = value;\n }\n }\n\n\n registerOnChange(fn: (value: any) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n ngOnDestroy() {\n this.numpadSubscriptions.forEach(s => s.unsubscribe());\n }\n\n private registerNumpad(numpad: MatNumpadComponent): void {\n if (numpad) {\n console.debug('[numpad-directive] Registering numpad', numpad);\n this._numpad = numpad;\n this._numpad.registerInput(this);\n this.numpadSubscriptions.push(this._numpad.keypress\n .pipe(\n //filter(event => event.inputTarget === this.element)\n )\n .subscribe(event => this.applyingKey(event))\n );\n\n } else {\n throw new Error('MatNumpadComponent is not defined.' +\n ' Please make sure you passed the numpad to matNumpad directive');\n }\n }\n\n private applyingKey(event: KeyboardEvent) {\n console.debug('[numpad-directive] Receiving key=' + event.key);\n let value = this.value !== null && this.value !== undefined ? this.value : '';\n // Remove french decimal separator\n value = (typeof value === 'number') ? ('' + value) : value.replace(',', '.');\n if (event.key === '.' || event.key === ',') {\n if (value.indexOf('.') === -1) {\n value += '.';\n }\n }\n\n else if (event.key === 'Backspace') {\n // Remove last character\n value = value.length > 1 ? value.substr(0, value.length - 1) : '';\n }\n else if (event.key === 'Enter' || event.keyCode === 13) {\n this._numpad.close();\n return;\n }\n else if (event.key === 'Tab') {\n // TODO goto next input ?\n return; // Skip\n }\n else if (event.key === 'Escape') {\n this._numpad.close();\n return;\n }\n else {\n value += (event.key || '');\n }\n\n this.updateValue(value);\n this.onTouched();\n }\n\n private updateInputValue(): void {\n this.elementRef.nativeElement.value = this.value;\n }\n\n}\n\n","import {Component, Input} from '@angular/core';\n\n@Component({\n selector: 'mat-numpad-content',\n templateUrl: './numpad.content.html',\n})\nexport class MatNumpadContent {\n @Input() appendToInput: boolean;\n @Input() inputElement: any;\n}\n","import {AfterViewInit, Directive, ElementRef, HostListener, Input, Renderer2} from '@angular/core';\n\ntype TimepickerDirectionY = 'top' | 'center' | 'bottom';\ntype TimepickerDirectionX = 'start' | 'center' | 'end';\n\n@Directive({\n selector: '[appendNumpadToInput]'\n})\nexport class AppendToInputDirective implements AfterViewInit {\n\n @Input('appendNumpadToInput') inputElement: any;\n\n private _directionY: TimepickerDirectionY;\n private _directionX: TimepickerDirectionX;\n private _inputCords: ClientRect;\n private readonly element: HTMLElement;\n\n constructor(elementRef: ElementRef<HTMLElement>,\n private renderer: Renderer2) {\n this.element = elementRef.nativeElement;\n }\n\n private get inputCords(): ClientRect {\n return this.inputElement.getBoundingClientRect();\n }\n\n private get directionY(): TimepickerDirectionY {\n const height = this.element.offsetHeight;\n const {bottom, top} = this._inputCords;\n const isElementFit = (window && window.innerHeight) - bottom < height;\n const isTop = isElementFit && top > height;\n const isCenter = isElementFit && top < height;\n\n if (isTop) {\n return 'top';\n } else if (isCenter) {\n return 'center';\n }\n return 'bottom';\n }\n\n private get directionX(): TimepickerDirectionX {\n const width = this.element.offsetWidth;\n const {left, right} = this._inputCords;\n const isElementFit = (window && window.innerWidth) - left < width;\n const isEnd = isElementFit && right > width;\n const isCenter = isElementFit && right < width;\n\n if (isEnd) {\n return 'end';\n } else if (isCenter) {\n return 'center';\n }\n return 'start';\n }\n\n ngAfterViewInit(): void {\n this._inputCords = this.inputCords;\n this._directionY = this.directionY;\n this._directionX = this.directionX;\n\n this.append();\n }\n\n @HostListener('window:scroll')\n changePosition(): void {\n const {left, right, bottom, top} = this.inputCords;\n const x = this.defineElementYByDirection(left, right);\n const y = this.defineElementYByDirection(top, bottom);\n this.setStyle('left', `${x}px`);\n this.setStyle('top', `${y}px`);\n }\n\n private append(): void {\n const {left, right, bottom, top} = this._inputCords;\n\n const x = this.defineElementXByDirection(left, right);\n const y = this.defineElementYByDirection(top, bottom);\n\n this.setStyle('position', 'fixed');\n this.setStyle('left', `${x}px`);\n this.setStyle('top', `${y}px`);\n }\n\n private setStyle(style: string, value: string): void {\n this.renderer.setStyle(this.element, style, value);\n }\n\n private defineElementYByDirection(inputTop: number, inputBottom: number): number {\n if (this._directionY === 'top') {\n return inputTop - this.element.offsetHeight;\n } else if (this._directionY === 'center') {\n return inputTop - (this.element.offsetHeight / 2);\n }\n return inputBottom;\n }\n\n private defineElementXByDirection(inputLeft: number, inputRight: number) {\n // DEBUG\n //console.log(\"defineElementXByDirection \", inputLeft, inputRight);\n\n if (this._directionX === 'end') {\n return inputRight - this.element.offsetWidth;\n } else if (this._directionX === 'center') {\n return inputRight - (this.element.offsetWidth / 2);\n }\n return inputLeft;\n }\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {MatNumpadComponent} from './numpad.component';\nimport {MatButtonModule} from '@angular/material/button';\nimport {MatIconModule} from '@angular/material/icon';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {NumpadDirective} from './numpad.directive';\nimport {MatNumpadContainerComponent} from './numpad.container';\nimport {MatNumpadContent} from './numpad.content';\nimport {AppendToInputDirective} from './numpad.append-to-input.directive';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n MatButtonModule,\n MatIconModule,\n TranslateModule.forChild()\n ],\n exports: [\n MatNumpadComponent,\n NumpadDirective,\n MatNumpadContainerComponent,\n MatNumpadContent,\n AppendToInputDirective\n ],\n declarations: [\n MatNumpadContainerComponent,\n MatNumpadComponent,\n MatNumpadContent,\n NumpadDirective,\n AppendToInputDirective\n ]\n})\nexport class SharedMatNumpadModule {\n}\n\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, OnInit, Optional, Output, Provider, ViewChild } from '@angular/core';\nimport { ControlValueAccessor, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { BehaviorSubject, isObservable, noop, Observable, Subscription } from 'rxjs';\nimport { isNil, isNotNil, joinPropertiesPath, toBoolean } from '../../functions';\nimport { InputElement, selectInputContent } from '../../inputs';\nimport { EqualsFn, DisplayFn } from '../../form/field.model';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport { IonSlides } from '@ionic/angular';\nimport { MatButton } from '@angular/material/button';\nimport { firstNotNilPromise } from '../../observables';\nimport { filter } from 'rxjs/operators';\nimport {isMobile} from '../../platforms';\n\nconst DEFAULT_VALUE_ACCESSOR: Provider = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MatSwipeField),\n multi: true\n};\n\n@Component({\n selector: 'mat-swipe-field',\n styleUrls: ['./material.swipe.scss'],\n templateUrl: './material.swipe.html',\n providers: [DEFAULT_VALUE_ACCESSOR],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatSwipeField implements OnInit, InputElement, OnDestroy, ControlValueAccessor {\n\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private _value: any;\n private _subscription = new Subscription();\n private _itemsSubscription: Subscription;\n private _writing = false;\n private _tabindex: number;\n previousDisabled: boolean;\n nextDisabled: boolean;\n showSlides = false;\n $items = new BehaviorSubject<any[]>(undefined);\n $loaded = new BehaviorSubject<boolean>(false);\n\n slidesOptions: {\n speed: 100; // FIXME: seems it's not working\n };\n\n @Input() logPrefix = '[mat-swipe-field]';\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() floatLabel: FloatLabelType;\n @Input() appearance: MatFormFieldAppearance;\n @Input() placeholder: string;\n @Input() debug = false;\n @Input() required = false;\n @Input() mobile: boolean;\n @Input() clearable = false;\n @Input() equals: EqualsFn | null;\n @Input() displayWith: DisplayFn | null;\n @Input() displayAttributes: string[];\n @Input() appAutofocus: boolean;\n @Input('class') classList: string;\n\n @Input() set tabindex(value: number) {\n if (this._tabindex !== value) {\n this._tabindex = value;\n setTimeout(() => this.updateTabIndex());\n }\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n @Input() set items(value: Observable<any[]> | any[]) {\n // Remove previous subscription on items, (if exits)\n if (this._itemsSubscription) {\n console.warn(`${this.logPrefix} Items received twice !`);\n this._subscription.remove(this._itemsSubscription);\n this._itemsSubscription.unsubscribe();\n }\n\n if (isObservable<any[]>(value)) {\n this._itemsSubscription = this._subscription.add(\n value.subscribe(v => {\n this.loadItems(v);\n })\n );\n } else {\n if (value !== this.$items.getValue()) {\n this.loadItems(value as any[]);\n }\n }\n }\n\n get items(): Observable<any[]> | any[] {\n return this.$items.getValue();\n }\n\n get itemCount(): number {\n return (this.$items.getValue() || []).length;\n }\n\n @Output('click') onClick = new EventEmitter<MouseEvent>();\n @Output('blur') blurred = new EventEmitter<FocusEvent>();\n @Output('focus') focused = new EventEmitter<FocusEvent>();\n\n @ViewChild('fakeInput') fakeInput: ElementRef;\n @ViewChild('slides', {static: true}) slides: IonSlides;\n @ViewChild('prevButton') prevButton: MatButton;\n @ViewChild('nextButton') nextButton: MatButton;\n\n get value(): any {\n return this._value;\n }\n\n get disabled(): any {\n return this.formControl.disabled;\n }\n\n get enabled(): any {\n return this.formControl.enabled;\n }\n\n constructor(\n protected cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n }\n\n ngOnInit() {\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-swipe-field>.');\n\n // Default values\n this.displayAttributes = this.displayAttributes || ['label', 'name'];\n this.displayWith = this.displayWith || ((obj) => obj && joinPropertiesPath(obj, this.displayAttributes));\n this.equals = this.equals || ((o1: any, o2: any) => o1 && o2 && o1.id === o2.id);\n this.mobile = isNotNil(this.mobile) ? this.mobile : isMobile(window);\n }\n\n ngOnDestroy(): void {\n this._subscription.unsubscribe();\n this._value = undefined;\n this.$items.complete();\n }\n\n _onFocusFakeInput(event: FocusEvent) {\n event.preventDefault();\n\n // Hide the fake input\n if (this.fakeInput) {\n this.fakeInput.nativeElement.classList.add('hidden');\n this.fakeInput.nativeElement.tabIndex = -1;\n }\n\n // Focus on first button\n this.focus();\n }\n\n focus() {\n // show slides component\n this.showSlides = true;\n\n setTimeout(() => {\n if (this.prevButton) {\n this.prevButton.focus();\n }\n this.updateTabIndex();\n });\n\n if (isNil(this._value)) {\n // Slide to first and affect value\n this.slideTo(0);\n this.slideChanged();\n }\n\n this.markForCheck();\n }\n\n /**\n * This is a special case, because, this component has a temporary component displayed before the first focus event\n */\n private updateTabIndex() {\n if (isNil(this._tabindex) || this._tabindex === -1) return;\n\n if (this.fakeInput) {\n if (this.showSlides) {\n this.fakeInput.nativeElement.classList.add('hidden');\n this.fakeInput.nativeElement.tabIndex = -1;\n } else {\n this.fakeInput.nativeElement.classList.remove('hidden');\n this.fakeInput.nativeElement.tabIndex = this._tabindex;\n }\n }\n if (this.prevButton && this.nextButton) {\n this.prevButton._elementRef.nativeElement.tabIndex = this.showSlides ? this._tabindex : -1;\n this.nextButton._elementRef.nativeElement.tabIndex = this.showSlides ? this._tabindex + 1 : -1;\n }\n this.markForCheck();\n }\n\n writeValue(value: any): void {\n if (this._writing) return;\n\n this._writing = true;\n if (!this.equals(value, this._value)) {\n this._value = value;\n this.showSlides = isNotNil(this._value);\n this.updateSlides();\n setTimeout(() => this.updateTabIndex());\n }\n this._writing = false;\n\n this.markForCheck();\n }\n\n clearValue(event: UIEvent) {\n event.stopPropagation();\n this._writing = true;\n if (this.debug) console.debug(`${this.logPrefix} clear value`);\n this._value = undefined;\n this.formControl.patchValue(null, {emitEvent: false});\n this.showSlides = false;\n setTimeout(() => {\n this.updateTabIndex();\n this.slideTo(0);\n setTimeout(() => {\n this._writing = false;\n }, 100);\n });\n this._onChangeCallback(null);\n this.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.slides.lockSwipes(isDisabled).then(() => this.updateButtons());\n this.cd.markForCheck();\n }\n\n selectInputContent = selectInputContent;\n\n previous() {\n this.slides.slidePrev();\n }\n\n next() {\n this.slides.slideNext();\n }\n\n reachStart(reached: boolean) {\n this.previousDisabled = reached;\n }\n\n reachEnd(reached: boolean) {\n this.nextDisabled = reached;\n }\n\n slidesLoaded() {\n this.$loaded.next(true);\n }\n\n slideChanged() {\n this.slides.getActiveIndex()\n .then(activeIndex => {\n if (this._writing) return;\n this._writing = true;\n const value = (this.$items.getValue() || [])[activeIndex] || undefined;\n if (this.debug) console.debug(`${this.logPrefix} slide changed ActiveIndex:${activeIndex}, new value:${value}`);\n this.formControl.patchValue(value, {emitEvent: false});\n this._writing = false;\n this.checkIfTouched();\n this._onChangeCallback(value);\n });\n }\n\n /* -- protected method -- */\n\n private loadItems(items: any[]) {\n this.$loaded.next(false);\n this.$items.next(items);\n this.ready().then(() => this.slides.update());\n }\n\n private checkIfTouched() {\n if (this.formControl.touched) {\n this.markForCheck();\n this._onTouchedCallback();\n }\n }\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n\n private updateSlides() {\n if (this.showSlides) {\n const itemIndex = (this.$items.getValue() || []).findIndex(value => this.equals(value, this._value));\n if (itemIndex >= 0) {\n this.slideTo(itemIndex);\n } else {\n console.warn(`${this.logPrefix} Item not found`, this._value);\n this.slideTo(0);\n }\n }\n }\n\n private slideTo(index: number) {\n this.slides.slideTo(index, 0, false).then(() =>\n this.slides.update().then(() =>\n this.updateButtons()\n )\n );\n }\n\n private async updateButtons() {\n const activeIndex = await this.slides.getActiveIndex();\n if (this.debug) console.debug(`${this.logPrefix} update buttons ActiveIndex:${activeIndex}`);\n this.previousDisabled = activeIndex === 0 || this.disabled;\n this.nextDisabled = activeIndex === this.itemCount - 1 || this.disabled;\n }\n\n\n // not used ...\n async getSlides(): Promise<IonSlides> {\n await this.ready();\n return this.slides;\n }\n\n async ready(): Promise<void> {\n // Wait pmfms load, and controls load\n if (this.$loaded.getValue() === false) {\n if (this.debug) console.debug(`${this.logPrefix} waiting slides to be ready...`);\n await firstNotNilPromise(this.$loaded\n .pipe(\n filter((loaded) => loaded === true)\n ));\n }\n }\n\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {MatButtonModule} from '@angular/material/button';\nimport {MatIconModule} from '@angular/material/icon';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {MatSwipeField} from './material.swipe';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {MatInputModule} from '@angular/material/input';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n MatButtonModule,\n MatIconModule,\n TranslateModule.forChild(),\n MatFormFieldModule,\n ReactiveFormsModule,\n MatInputModule,\n ],\n exports: [\n MatSwipeField\n ],\n declarations: [\n MatSwipeField\n ]\n})\nexport class SharedMatSwipeModule {\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, OnInit, Optional, Output, ViewChild, ViewEncapsulation} from '@angular/core';\nimport {ControlValueAccessor, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR} from '@angular/forms';\nimport {BehaviorSubject, isObservable, merge, Observable, Subject, Subscription, timer} from 'rxjs';\nimport {FloatLabelType, MatFormFieldAppearance} from '@angular/material/form-field';\nimport {debounceTime, distinctUntilChanged, filter, map, mergeMap, startWith, switchMap, takeUntil, tap} from 'rxjs/operators';\nimport {MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger} from '@angular/material/autocomplete';\nimport {focusInput, InputElement, selectInputContent, selectInputRange} from '../../inputs';\nimport {FetchMoreFn, LoadResult, SuggestFn} from '../../services/entity-service.class';\nimport {DisplayFn, EqualsFn} from '../../form/field.model';\nimport {MatAutocompleteFieldConfig} from '../autocomplete/material.autocomplete';\nimport {changeCaseToUnderscore, isNil, isNilOrBlank, isNotNil, isNotNilOrBlank, isNotNilString, joinPropertiesPath, toBoolean, toNumber} from '../../functions';\nimport {firstNotNilPromise} from '../../observables';\nimport {fromScrollEndEvent} from '../../events';\nimport {PredefinedColors} from '@ionic/core';\nimport {ThemePalette} from '@angular/material/core';\nimport {suggestFromArray} from \"../../services\";\n\nconst noop = () => {};\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'mat-chips-field',\n styleUrls: ['./material.chips.scss'],\n templateUrl: './material.chips.html',\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: forwardRef(() => MatChipsField)\n }],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MatChipsField implements OnInit, OnDestroy, InputElement, ControlValueAccessor {\n\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n\n @Input() equals: EqualsFn;\n @Input() logPrefix = '[mat-chips] ';\n @Input() formControl: FormControl;\n @Input() formControlName: string = null;\n @Input() floatLabel: FloatLabelType;\n @Input() appearance: MatFormFieldAppearance;\n @Input() placeholder: string;\n @Input() suggestFn: SuggestFn<any, any>;\n @Input() required = false;\n @Input() mobile: boolean;\n @Input() readonly = false;\n @Input() clearable = false;\n @Input() debounceTime: number = null;\n @Input() displayWith: DisplayFn | null;\n @Input() displayAttributes: string[];\n @Input() displayColumnSizes: (number | 'auto' | undefined)[];\n @Input() displayColumnNames: string[];\n @Input() highlightAccent: boolean;\n @Input() showAllOnFocus: boolean;\n @Input() showPanelOnFocus: boolean;\n @Input() autofocus: boolean;\n @Input() config: MatAutocompleteFieldConfig;\n @Input() i18nPrefix = 'REFERENTIAL.';\n @Input() noResultMessage = 'COMMON.NO_RESULT';\n @Input('class') classList: string;\n @Input() panelWidth: string;\n @Input() matAutocompletePosition: 'auto' | 'above' | 'below';\n @Input() itemSize = '48px';\n @Input() fetchMoreThreshold: string = '15%';\n @Input() suggestLengthThreshold: number = null;\n @Input() showLoadingSpinner = true;\n @Input() chipColor: ThemePalette | PredefinedColors = null;\n @Input() debug = false;\n\n @Output('click') clicked = new EventEmitter<MouseEvent>();\n @Output('blur') blurred = new EventEmitter<FocusEvent>();\n @Output('focus') focused = new EventEmitter<FocusEvent>();\n @Output() dropButtonClick = new EventEmitter<UIEvent>(true);\n @Output('keydown.escape') keydownEscape = new EventEmitter<any>();\n @Output('keyup.enter') keyupEnter = new EventEmitter<any>();\n\n @ViewChild('matInputText') matInputText: ElementRef;\n @ViewChild(MatAutocomplete) autocomplete: MatAutocomplete;\n @ViewChild(MatAutocompleteTrigger) autocompleteTrigger: MatAutocompleteTrigger;\n\n _tabindex: number;\n $inputItems = new BehaviorSubject<any[]>(undefined);\n $filteredItems = new BehaviorSubject<any[]>(undefined);\n inputControl = new FormControl();\n _moreItemsCount: number;\n _fetchMore$ = new EventEmitter<Event>();\n\n private _onFetchMoreCallback: FetchMoreFn<LoadResult<any>>;\n private _implicitValue: any;\n private _subscription = new Subscription();\n private _itemsSubscription: Subscription;\n private _openedSubscription: Subscription;\n private _$filter = new BehaviorSubject<any>(undefined);\n private _itemCount: number;\n private _reload$ = new Subject<any>();\n\n constructor(\n protected cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n }\n\n get itemCount(): number {\n return this._itemCount;\n }\n\n get canFetchMore(): boolean {\n return this._onFetchMoreCallback && this._moreItemsCount > 0;\n }\n\n @Input() set filter(value: any) {\n if (value !== this._$filter.value) {\n // DEBUG\n //console.debug(this.logPrefix + \" Setting filter:\", value);\n this._$filter.next(value);\n }\n }\n\n get filter(): any {\n return this._$filter.value;\n }\n\n\n @Input() set tabindex(value: number) {\n this._tabindex = value;\n this.markForCheck();\n }\n\n get tabindex(): number {\n return this._tabindex;\n }\n\n @Input() set items(value: Observable<any[]> | any[]) {\n // Remove previous subscription on items, (if exits)\n if (this._itemsSubscription) {\n console.warn(this.logPrefix + ' Items received twice !');\n this._subscription.remove(this._itemsSubscription);\n this._itemsSubscription.unsubscribe();\n }\n\n if (isObservable<any[]>(value)) {\n this._itemsSubscription = this._subscription.add(\n value.subscribe(v => {\n //console.warn(this.logPrefix + \" Received items: \", v);\n this.$inputItems.next(v);\n })\n );\n } else {\n if (value !== this.$inputItems.value) {\n this.$inputItems.next(value as any[]);\n }\n }\n }\n\n get items(): Observable<any[]> | any[] {\n return this.$inputItems;\n }\n\n get value(): any[] {\n return this.formControl.value || [];\n }\n\n get disabled(): boolean {\n return this.readonly || this.formControl.disabled;\n }\n\n get enabled(): boolean {\n return !this.readonly && this.formControl.enabled;\n }\n\n get loading(): boolean {\n return isNil(this.$filteredItems.value);\n }\n\n ngOnInit() {\n this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName) as FormControl;\n if (!this.formControl) throw new Error('Missing mandatory attribute \\'formControl\\' or \\'formControlName\\' in <mat-chips-field>.');\n\n // Configuration from config object\n if (this.config) {\n this.suggestFn = this.suggestFn || this.config.suggestFn;\n if (!this.suggestFn && this.config.items) {\n this.items = this.config.items;\n }\n this.filter = this.filter || this.config.filter;\n this.displayAttributes = this.displayAttributes || this.config.attributes;\n this.displayColumnSizes = this.displayColumnSizes || this.config.columnSizes;\n this.displayColumnNames = this.displayColumnNames || this.config.columnNames;\n this.displayWith = this.displayWith || this.config.displayWith;\n this.equals = this.equals || this.config.equals;\n this.mobile = toBoolean(this.mobile, this.config.mobile);\n this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);\n this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));\n this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));\n this.classList = this.classList || this.config.class;\n this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);\n this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));\n }\n\n // Default values\n this.displayAttributes = this.displayAttributes || this.filter?.attributes || ['label', 'name'];\n this.displayWith = this.displayWith || ((obj) => obj && joinPropertiesPath(obj, this.displayAttributes));\n this.displayColumnSizes = this.displayColumnSizes\n // if only column: auto size\n || (this.displayAttributes.length === 1 && [undefined])\n // Computed column size:\n // - if label then col size = 2\n // - if rankOrder then col size = 1\n // - ese => auto size\n || this.displayAttributes.map(attr =>\n attr && (attr.endsWith('label') ? 3\n : (attr.endsWith('rankOrder') ? 2\n : undefined)));\n this.displayColumnNames = this.displayAttributes.map((attr, index) => this.displayColumnNames && this.displayColumnNames[index] ||\n (this.i18nPrefix + changeCaseToUnderscore(attr).toUpperCase()));\n this.mobile = toBoolean(this.mobile, false);\n this.equals = this.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);\n const classList = this.classList?.split(' ');\n this.panelWidth = this.panelWidth || (classList && (\n (classList.includes('min-width-medium') && '300px')\n || (classList.includes('min-width-large') && '400px')\n || (classList.includes('min-width-xlarge') && '450px')\n || (classList.includes('mat-autocomplete-panel-full-size') && '100vw')\n ));\n this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, true);\n this.debounceTime = toNumber(this.debounceTime, 250);\n this.highlightAccent = toBoolean(this.highlightAccent, false);\n this.suggestLengthThreshold = this.suggestLengthThreshold || 0;\n this.matAutocompletePosition = this.matAutocompletePosition || (this.mobile ? 'above' : 'auto'); // On mobile, set position to above (because of bottom keyboard)\n\n // No suggestFn: filter on the given items\n if (!this.suggestFn) {\n const suggestFromArrayFn: SuggestFn<any, any> = async (value, filter) => {\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Calling suggestFromArray with value=', value);\n\n return suggestFromArray(this.$inputItems.value, value, {\n searchAttributes: this.displayAttributes,\n ...filter\n });\n };\n // Wait (once) that items are loaded, then call suggest from array fn\n this.suggestFn = async (value, filter) => {\n if (isNil(this.$inputItems.value)) {\n // DEBUG\n //if (this.debug) console.debug('[mat-chips] Waiting items to be set...');\n\n await firstNotNilPromise(this.$inputItems);\n\n // DEBUG\n //if (this.debug) console.debug('[mat-chips] Received items:', this.$inputItems.value);\n }\n this.suggestFn = suggestFromArrayFn;\n return this.suggestFn(value, filter); // Loop\n };\n }\n\n // Send value to suggest when :\n // - is nil and '*', and no min length threshold\n // - is not nil and not a string type (e.g. object)\n // - is not nil and is a string, and has enough character\n const thresholdFilterFn = (value) => (isNilOrBlank(value) || (value === '*')\n ? (this.suggestLengthThreshold <= 0)\n : (!(typeof value === 'string')\n || value.length >= this.suggestLengthThreshold)\n );\n\n const filteredItemsChanges = merge(\n\n // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)\n this._reload$,\n\n this.inputControl.valueChanges\n .pipe(\n filter(value => this.enabled && isNotNilString(value)),\n // Mark as loading (to show loading spinner) - earlier as possible, so before the debounce time\n tap(_ => this.showLoadingSpinner && this.markAsLoading()),\n // Filter if not enough character\n filter(value => value.length >= this.suggestLengthThreshold),\n // Wait a debounce time\n debounceTime(this.debounceTime)\n // DEBUG\n //,tap((value) => this.debug && console.debug(this.logPrefix + ' Search text changes:', value))\n ),\n\n // Object set: use it (no distinctUntilChanged() pipe need)\n this.inputControl.valueChanges\n .pipe(\n startWith<any, any>(this.inputControl.value),\n filter(value => isNotNil(value) && typeof value === 'object'),\n // DEBUG\n //tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))\n ),\n\n // On dropdown button click (no distinctUntilChanged(), nor debounceTime)\n this.dropButtonClick\n .pipe(\n filter(event => this.enabled && (!event || !event.defaultPrevented)),\n tap(_ => this.matInputText.nativeElement.focus()),\n map(_ => this.showAllOnFocus ? '*' : this.formControl.value),\n // Make sure there is enough characters\n filter(thresholdFilterFn)\n ),\n\n // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime\n merge(\n // Focus or click => Load all\n merge(this.focused, this.clicked)\n .pipe(\n filter(_ => this.enabled),\n map((_) => this.showAllOnFocus ? '*' : this.inputControl.value)\n\n // DEBUG\n //,tap(value => this.debug && console.debug(this.logPrefix + ' Received focused or clicked event: ', value))\n ),\n merge(this.$inputItems, this._$filter)\n .pipe(\n filter(_ => this.enabled),\n map(_ => this.inputControl.value),\n\n // DEBUG\n //tap(value => this.debug && console.debug(this.logPrefix + ' Received $inputItems or filter event: ', value))\n )\n )\n .pipe(\n // Make sure there is enough characters\n filter(thresholdFilterFn),\n // Distinguish changes\n // - do NOT filter if loading, to force update after a blur event\n distinctUntilChanged((v1, v2) => !this.loading && (v1 === v2 || this.equals(v1, v2)))\n // DEBUG\n //,tap(value => this.debug && console.debug(this.logPrefix + ' Received update event: ', value))\n )\n )\n .pipe(\n\n // Suggest values\n mergeMap(value => this.suggest(value, this.filter)),\n // DEBUG\n //tap(items => this.debug && console.debug(this.logPrefix + ' Received from suggest: ', items)),\n\n // Store implicit value (will use it onBlur if not other value selected)\n tap(items => this.updateImplicitValue(items))\n );\n\n // Fetch more events\n const fetchMoreItemsChanges = this._fetchMore$\n .pipe(\n tap(event => event?.preventDefault()), // Avoid to close the mat-select\n filter(() => this.canFetchMore),\n mergeMap(() => this.fetchMore()),\n\n // DEBUG\n //tap(moreItems => console.debug(this.logPrefix + ' Received from fetch More: ', moreItems)),\n\n // Concat to existing items\n map(moreItems => (this.$filteredItems.value || []).concat(moreItems))\n );\n\n // Update filtered items\n this._subscription.add(\n merge(\n this.$inputItems,\n\n // Update items events\n filteredItemsChanges,\n\n // Fetch more events\n fetchMoreItemsChanges\n )\n // Emit items\n .subscribe(items => this.$filteredItems.next(items))\n );\n\n // Applying implicit value, on blur\n this._subscription.add(\n this.blurred\n .pipe(\n map(_ => this.formControl.value)\n // DEBUG\n //,tap(value => this.debug && console.debug(this.logPrefix + ' Received blurred event: ', value)),\n )\n .subscribe(value => {\n // When leave component without object, use implicit value if :\n // - an explicit value\n // - field is not empty (user fill something)\n // - OR field empty but is required\n if (this._implicitValue && ((this.required && isNilOrBlank(value)) || (isNotNilOrBlank(value) && typeof value !== 'object'))) {\n this.writeValue(this._implicitValue);\n this.formControl.markAsPending({emitEvent: false, onlySelf: true});\n this.formControl.updateValueAndValidity({emitEvent: false, onlySelf: true});\n this.checkIfTouched();\n this.$filteredItems.next([this._implicitValue]);\n } else if (isNilOrBlank(value)) {\n this.writeValue(null);\n this.formControl.markAsPending({emitEvent: false, onlySelf: true});\n this.formControl.updateValueAndValidity({emitEvent: false, onlySelf: true});\n this.checkIfTouched();\n this.$filteredItems.next(undefined);\n }\n this._implicitValue = null; // reset the implicit value\n this.closePanel(); // Clone panel\n }));\n\n // Listen form control status change\n this._subscription.add(\n this.formControl.statusChanges\n .pipe(\n //filter(() => this.enabled),\n distinctUntilChanged()\n )\n // Update component state\n .subscribe(() => this.checkIfTouched())\n );\n\n this._subscription.add(\n this.keydownEscape.subscribe(event => {\n if (this.isOpen) {\n // Avoid form or page to manage escape event\n event?.stopPropagation();\n event?.preventDefault();\n\n // DEBUG\n //console.debug(this.logPrefix + \" Closing the panel (keydown.escape)\");\n\n this.closePanel();\n }\n })\n );\n }\n\n ngOnDestroy(): void {\n this._subscription.unsubscribe();\n if (this._itemsSubscription) {\n this._itemsSubscription.unsubscribe();\n }\n if (this._openedSubscription) {\n this._openedSubscription.unsubscribe();\n }\n this.$inputItems.complete();\n this.$inputItems.unsubscribe();\n this.$filteredItems.complete();\n this.$filteredItems.unsubscribe();\n this._reload$.complete();\n this._$filter.complete();\n\n this.dropButtonClick.complete();\n this.clicked.complete();\n this.blurred.complete();\n this.focused.complete();\n this.keydownEscape.complete();\n this.keyupEnter.complete();\n this._fetchMore$.complete();\n\n this._implicitValue = undefined;\n this.formControl = null;\n this.displayWith = null;\n this.equals = null;\n this.suggestFn = null;\n this.$filteredItems = null;\n this.config = null;\n this.classList = null;\n\n this._onChangeCallback = null;\n this._onTouchedCallback = null;\n this._onFetchMoreCallback = null;\n\n // Destroy the 'autocomplete' instance, to avoid memory leak\n if (this.autocomplete) {\n this.autocomplete.ngOnDestroy();\n }\n }\n\n /**\n * Add item to chips\n *\n * @param event\n */\n add(event: MatAutocompleteSelectedEvent) {\n\n if (this.debug) console.debug(`${this.logPrefix}select`, event);\n\n const item = event.option.value;\n this.writeValue([...this.value, item]);\n this.matInputText.nativeElement.value = '';\n this.inputControl.setValue('');\n\n }\n\n /**\n * Remove item from chips\n *\n * @param item\n */\n remove(item: any) {\n const value = this.value;\n const index = value ? value.indexOf(item) : -1;\n if (index !== -1) {\n const newValue = value.slice();\n newValue.splice(index, 1);\n this.writeValue(newValue);\n this.closePanel();\n }\n }\n\n /**\n * Allow to reload content. Useful when filter has been changed but not detected\n */\n reloadItems(value?: any) {\n // Force a refresh\n this._reload$.next(value || '*');\n }\n\n writeValue(value: any[]): void {\n // DEBUG\n // if (this.debug) console.debug(this.logPrefix + ' Writing value: ', value);\n\n if (value && !Array.isArray(value)) {\n value = [value];\n }\n if (value !== this.formControl.value) {\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Writing value: ', value);\n\n this.formControl.patchValue(value, {emitEvent: false});\n this._onChangeCallback(value);\n }\n else {\n this.markForCheck();\n }\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (isDisabled && this.autocomplete?.isOpen) {\n this.closePanel();\n }\n this.cd.markForCheck();\n }\n\n focus() {\n focusInput(this.matInputText);\n }\n\n filterInputTextFocusEvent(event: FocusEvent) {\n if (!event || event.defaultPrevented) return;\n\n // Ignore event from mat-option\n if (event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') {\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Cancelling focus event');\n\n return false;\n }\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Select input content');\n const hasContent = selectInputContent(event);\n\n // If combo is empty, or if has content but should force to show panel on focus\n if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Emit focus event');\n\n this.focused.emit(event);\n return true;\n }\n return false;\n }\n\n filterInputTextBlurEvent(event: FocusEvent) {\n if (!event || event.defaultPrevented) return;\n\n // Ignore event from mat-option\n if (event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') {\n event.preventDefault();\n if (event.stopPropagation) event.stopPropagation();\n event.returnValue = false;\n\n //DEBUG\n //if (this.debug) console.debug(this.logPrefix + \" Cancelling blur event\");\n\n return false;\n }\n\n // DEBUG\n //if (this.debug) console.debug(this.logPrefix + ' Blur: move caret to the beginning');\n\n // Move caret to the beginning (fix issue IMAGINE-469)\n selectInputRange(event.target as any, 0, 0);\n\n this.blurred.emit(event);\n return true;\n }\n\n filterChipsFocusEvent(event: FocusEvent){\n // DEBUG\n if (this.debug) console.debug(this.logPrefix + ' Focus in chips list', event);\n\n // Ignore event in button\n\n this.matInputText.nativeElement.focus();\n }\n\n clearValue(event: UIEvent) {\n this.writeValue(null);\n event.stopPropagation();\n }\n\n _initAutocompleteInfiniteScroll(threshold?: string) {\n if (!this.autocomplete) return; // Skip\n\n // DEBUG\n //console.debug(this.logPrefix + ' Init autocomplete scroll listener');\n\n if (this._openedSubscription) {\n this._openedSubscription.unsubscribe();\n this._subscription.remove(this._openedSubscription);\n }\n\n const opened$: Observable<any> = this.autocomplete._isOpen\n ? timer(0)\n : this.autocomplete.opened.pipe(debounceTime(200));\n const scrollEnd$ = opened$\n .pipe(\n map((_) => this.getAutocompletePanel()),\n filter(isNotNil),\n switchMap((panel) => fromScrollEndEvent(panel, threshold)\n .pipe(\n takeUntil(this.autocomplete.closed)\n )\n )\n );\n\n // Trigger fetch more, end end scroll reached\n this._openedSubscription = scrollEnd$\n .subscribe(() => this._fetchMore$.emit());\n\n // Register subscription\n this._subscription.add(this._openedSubscription);\n }\n\n get isOpen(): boolean {\n return this.autocomplete?.isOpen || false;\n }\n\n closePanel() {\n if (this.autocomplete?.isOpen) {\n this.autocompleteTrigger?.closePanel();\n return;\n }\n }\n\n /* -- private method -- */\n\n private async suggest(value: any, filter?: any): Promise<any[]> {\n // Call suggestion function\n let res = await this.suggestFn(value, filter);\n\n // DEBUG\n //console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);\n if (!res) {\n this._itemCount = 0;\n res = [];\n }\n else if (Array.isArray(res)) {\n res = res as any[];\n this._itemCount = res.length || 0;\n }\n else {\n const {data, total, fetchMore} = res as LoadResult<any>;\n this._itemCount = toNumber(total, data && data.length || 0);\n this._onFetchMoreCallback = fetchMore;\n this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;\n res = data;\n }\n\n // Filter out existing items\n const filteredData = (res || []).slice().filter(item1 => this.value.findIndex(item2 => this.equals(item1, item2)) === -1);\n const removedItemCount = ((res?.length || 0) - (filteredData?.length || 0));\n\n // Decrease the item count, with delta\n this._itemCount -= removedItemCount;\n\n if (this.debug) console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);\n\n return res as any[];\n }\n\n private async fetchMore(): Promise<any[]> {\n if (!this._onFetchMoreCallback) return [];\n\n // Save then remove fetch function (to avoid multi-call)\n const fetchMoreFn = this._onFetchMoreCallback;\n this._onFetchMoreCallback = undefined;\n\n const {data, total, fetchMore} = await fetchMoreFn();\n this._itemCount = total || this._itemCount;\n this._onFetchMoreCallback = fetchMore;\n this._moreItemsCount = Math.max(0, this._moreItemsCount - data.length); // Borne min = 0\n return data;\n }\n\n private updateImplicitValue(items: any[]) {\n // Store implicit value (will use it onBlur if not other value selected)\n if (items && items.length === 1) {\n this._implicitValue = items[0];\n //this.formControl.setErrors(null);\n } else {\n this._implicitValue = undefined;\n }\n }\n\n private checkIfTouched() {\n if (this.formControl.touched) {\n this.cd.markForCheck();\n this._onTouchedCallback();\n }\n }\n\n private getAutocompletePanel(): HTMLElement {\n const ele = this.autocomplete?.options.last?._getHostElement().parentElement;\n if (!ele) {\n // DEBUG\n console.warn(this.logPrefix + ' Unable to find the autocomplete div...');\n }\n return ele;\n }\n\n\n private markForCheck() {\n this.cd.markForCheck();\n }\n\n private markAsLoading() {\n if (this.$filteredItems.value) {\n this.$filteredItems.next(undefined);\n this._itemCount = undefined;\n this._implicitValue = undefined;\n this._onFetchMoreCallback = undefined;\n this._moreItemsCount = 0;\n this.markForCheck();\n }\n }\n}\n","import {NgModule} from '@angular/core';\nimport {MatChipsField} from './material.chips';\nimport {MatChipsModule} from '@angular/material/chips';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {SharedPipesModule} from '../../pipes/pipes.module';\nimport {SharedDirectivesModule} from '../../directives/directives.module';\nimport {MatCommonModule} from '@angular/material/core';\nimport {MatAutocompleteModule} from '@angular/material/autocomplete';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {MatIconModule} from '@angular/material/icon';\nimport {MatButtonModule} from '@angular/material/button';\nimport {MatSelectModule} from '@angular/material/select';\nimport {TranslateModule} from '@ngx-translate/core';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n SharedPipesModule,\n SharedDirectivesModule,\n MatCommonModule,\n MatAutocompleteModule,\n MatFormFieldModule,\n MatInputModule,\n MatIconModule,\n MatButtonModule,\n MatSelectModule,\n MatChipsModule,\n TranslateModule.forChild(),\n ],\n declarations: [\n MatChipsField\n ],\n exports: [\n MatChipsField\n ]\n})\nexport class SharedMatChipsModule {\n\n}\n","import {Directive, ElementRef, HostBinding, Input, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core';\nimport {MatBadgeSize} from '@angular/material/badge';\nimport {PredefinedColors} from '@ionic/core';\nimport {ThemePalette} from '@angular/material/core';\nimport {Subject, Subscription} from 'rxjs';\nimport {debounceTime} from 'rxjs/operators';\n\nexport declare type MatBadgeFill = 'clear' | 'solid';\n\n@Directive({\n selector: '[matBadgeIcon], [ionBadgeIcon]',\n inputs: [\n 'size: matBadgeSize',\n 'color: matBadgeColor',\n 'fill: matBadgeFill',\n ]\n})\nexport class MatBadgeIconDirective implements OnInit, OnDestroy {\n\n @Input('matBadgeSize') set size(value: MatBadgeSize) {\n if (this._size !== value) {\n this._size = value;\n this.updateView();\n }\n }\n\n get size(): MatBadgeSize {\n return this._size;\n }\n\n @Input('matBadgeColor') set color(value: PredefinedColors | ThemePalette) {\n if (this._color !== value) {\n this._color = value;\n this.updateView();\n }\n }\n\n get color(): PredefinedColors | ThemePalette {\n return this._color;\n }\n\n @Input('matBadgeFill') set fill(value: MatBadgeFill) {\n if (this._fill !== value) {\n this._fill = value;\n this.updateView();\n }\n }\n\n get fill(): MatBadgeFill {\n return this._fill;\n }\n\n @Input('matBadgeIcon') set matIcon(icon: string) {\n if (this._matIcon !== icon) {\n this._matIcon = icon;\n this.updateView();\n }\n }\n @Input('ionBadgeIcon') set ionIcon(icon: string){\n if (this._ionIcon !== icon) {\n this._ionIcon = icon;\n this.updateView();\n }\n }\n\n private _size: MatBadgeSize;\n private _color: PredefinedColors | ThemePalette;\n private _fill: MatBadgeFill;\n private _matIcon: string;\n private _ionIcon: string;\n\n private _html: string;\n private _subscription: Subscription = null;\n private _$update = new Subject();\n\n constructor(private el: ElementRef) {}\n\n ngOnInit() {\n // Default value\n this._size = this._size || 'medium';\n this._color = this._color || 'primary';\n if (this._color === 'warn') this._color = 'warning';\n\n this.updateView(true);\n\n this._subscription = this._$update\n .pipe(debounceTime(100))\n .subscribe(() => this.updateView(true));\n }\n\n ngOnDestroy() {\n this._subscription?.unsubscribe();\n }\n\n private updateView(immediate?: boolean) {\n\n // Async by default\n if (!immediate) {\n this._$update.next();\n return;\n }\n\n const badge: HTMLSpanElement = this.el.nativeElement.querySelector('.mat-badge-content');\n if (!badge) return;\n\n let fontSize;\n switch (this._size) {\n case 'large':\n fontSize = '24px';\n break;\n case 'medium':\n fontSize = '22px';\n break;\n case 'small':\n fontSize = '16px';\n break;\n }\n let html = '';\n if (this._matIcon) {\n html = `<i class=\"material-icons\" style=\"font-size: ${fontSize};\">${this._matIcon}</i>`;\n }\n else if (this._ionIcon) {\n html = `<ion-icon style=\"font-size: ${fontSize}; pointer-events: none;\" name=\"${this._ionIcon}\"></ion-icon>`;\n }\n if (this._html !== html) {\n this._html = html;\n badge.innerHTML = html;\n }\n\n // Update style\n // fill: 'clear'\n if (this._fill === 'clear') {\n badge.style.color = `var(--ion-color-${this._color})`;\n badge.style.background = 'transparent';\n }\n // fill: 'solid' (default value)\n else {\n badge.style.background = `var(--ion-color-${this._color})`;\n badge.style.color = `var(--ion-color-${this._color}-contrast)`;\n }\n\n if (badge.style.display !== 'inline-block') badge.style.display = 'inline-block';\n if (badge.style.alignItems !== 'center') badge.style.alignItems = 'center';\n if (badge.style.justifyContent !== 'center') badge.style.justifyContent = 'center';\n }\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {IonicModule} from '@ionic/angular';\nimport {MatBadgeIconDirective} from './badge-icon.directive';\nimport {MatBadgeModule} from '@angular/material/badge';\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n MatBadgeModule,\n ],\n exports: [\n MatBadgeIconDirective\n ],\n declarations: [\n MatBadgeIconDirective\n ]\n})\nexport class SharedMatBadgeIconModule {\n}\n\n","import {NgModule, Type} from '@angular/core';\nimport {CdkTableModule} from '@angular/cdk/table';\n\nimport {A11yModule} from '@angular/cdk/a11y';\nimport {OverlayModule} from '@angular/cdk/overlay';\nimport {ScrollingModule} from '@angular/cdk/scrolling';\nimport {MatCommonModule, MatRippleModule} from '@angular/material/core';\nimport {MatTableModule} from '@angular/material/table';\nimport {MatSortModule} from '@angular/material/sort';\nimport {MatPaginatorModule} from '@angular/material/paginator';\nimport {MatFormFieldModule} from '@angular/material/form-field';\nimport {MatInputModule} from '@angular/material/input';\nimport {MatCheckboxModule} from '@angular/material/checkbox';\nimport {MatExpansionModule} from '@angular/material/expansion';\nimport {MatToolbarModule} from '@angular/material/toolbar';\nimport {MatIconModule} from '@angular/material/icon';\nimport {MatButtonModule} from '@angular/material/button';\nimport {MatMenuModule} from '@angular/material/menu';\nimport {MatSelectModule} from '@angular/material/select';\nimport {MatCardModule} from '@angular/material/card';\nimport {MatTabsModule} from '@angular/material/tabs';\nimport {MatStepperModule} from '@angular/material/stepper';\nimport {MatListModule} from '@angular/material/list';\nimport {MatButtonToggleModule} from '@angular/material/button-toggle';\nimport {MatProgressSpinnerModule} from '@angular/material/progress-spinner';\nimport {MatProgressBarModule} from '@angular/material/progress-bar';\nimport {MatRadioModule} from '@angular/material/radio';\nimport {MatBadgeModule} from '@angular/material/badge';\nimport {MatSlideToggleModule} from '@angular/material/slide-toggle';\nimport {MatDialogModule} from '@angular/material/dialog';\nimport {SharedMatAutocompleteModule} from './autocomplete/material.autocomplete.module';\nimport {SharedMatLatLongModule} from './latlong/material.latlong.module';\nimport {SharedMatDateTimeModule} from './datetime/datetime.module';\nimport {SharedMatDurationModule} from './duration/duration.module';\nimport {SharedMatBooleanModule} from './boolean/boolean.module';\nimport {SharedMatNumpadModule} from './numpad/numpad.module';\nimport {SharedMatSwipeModule} from './swipe/swipe.module';\nimport {MatDividerModule} from '@angular/material/divider';\nimport {MatTooltipModule} from '@angular/material/tooltip';\nimport {SharedMatChipsModule} from './chips/chips.module';\nimport {SharedMatBadgeIconModule} from './badge/badge-icon.module';\nimport {BrowserAnimationsModule} from '@angular/platform-browser/animations';\n\nconst modules: Array<Type<any> | any[]> = [\n // Angular material components\n MatCommonModule,\n MatTableModule,\n MatSortModule,\n MatPaginatorModule,\n MatFormFieldModule,\n MatInputModule,\n CdkTableModule,\n MatCheckboxModule,\n MatExpansionModule,\n MatToolbarModule,\n MatDialogModule,\n MatIconModule,\n MatButtonModule,\n MatMenuModule,\n MatSelectModule,\n MatCardModule,\n MatTabsModule,\n MatListModule,\n MatStepperModule,\n MatButtonToggleModule,\n MatProgressSpinnerModule,\n MatProgressBarModule,\n MatRadioModule,\n MatBadgeModule,\n MatSlideToggleModule,\n A11yModule, // Used for focus trap\n OverlayModule,\n ScrollingModule,\n MatRippleModule,\n MatDividerModule,\n MatTooltipModule,\n // Custom components\n SharedMatAutocompleteModule,\n SharedMatLatLongModule,\n SharedMatDateTimeModule,\n SharedMatDurationModule,\n SharedMatBooleanModule,\n SharedMatNumpadModule,\n SharedMatSwipeModule,\n SharedMatChipsModule,\n SharedMatBadgeIconModule\n];\n\n@NgModule({\n imports: modules,\n exports: modules\n})\nexport class SharedMaterialModule {\n}\n\n","import {EventEmitter, Injectable} from '@angular/core';\n\nexport declare type ProgressMode = 'determinate' | 'indeterminate' | 'buffer' | 'query' | 'none';\n\n@Injectable({providedIn: 'root'})\nexport class ProgressBarService {\n private _requestsRunning = 0;\n\n onProgressChanged = new EventEmitter<ProgressMode>();\n\n list(): number {\n return this._requestsRunning;\n }\n\n increase(): void {\n this._requestsRunning++;\n if (this._requestsRunning === 1) {\n this.onProgressChanged.emit('query');\n }\n }\n\n decrease(): void {\n if (this._requestsRunning > 0) {\n this._requestsRunning--;\n }\n if (this._requestsRunning === 0) {\n this.onProgressChanged.emit('none');\n }\n }\n\n\n}\n","import {Injectable} from '@angular/core';\nimport {HammerGestureConfig} from '@angular/platform-browser';\n\nexport const HAMMER_TAP_TIME = 250;\nexport const HAMMER_PRESS_TIME = 400; // Increase need for double tap (default: 251 ms)\n/**\n * @hidden\n * This class overrides the default Angular gesture config.\n *\n */\n@Injectable({providedIn: 'root'})\nexport class AppGestureConfig extends HammerGestureConfig {\n\n // Override HammerJS default settings\n overrides = <any>{\n press: {\n time: HAMMER_PRESS_TIME\n },\n pinch: {\n enable: false\n },\n rotate: {\n enable: false\n },\n // see https://hammerjs.github.io/recognizer-swipe/\n swipe: {\n threshold: 30, // Minimal distance required before recognizing.\n velocity: 0.4 //Minimal velocity required before recognizing, unit is in px per ms.\n }\n };\n\n buildHammer(element: HTMLElement) {\n\n // DEBUG\n console.debug('[gesture] Applying HammerJS config to ', element.tagName);\n\n const mc = new (<any>window).Hammer(element);\n\n for (const eventName in this.overrides) {\n if (eventName) mc.get(eventName).set(this.overrides[eventName]);\n }\n\n return mc;\n }\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Input, OnDestroy,\n OnInit, Optional,\n Output,\n ViewChild\n} from '@angular/core';\nimport {ProgressBarService, ProgressMode} from '../services/progress-bar.service';\nimport {ActivatedRoute, Router} from '@angular/router';\nimport {IonRouterOutlet, IonSearchbar} from '@ionic/angular';\nimport {isNotNil, isNotNilOrBlank, toBoolean} from '../functions';\nimport {debounceTime, distinctUntilChanged, startWith, tap} from 'rxjs/operators';\nimport {Observable} from 'rxjs';\nimport {HammerTapEvent} from '../gesture/hammer.utils';\nimport {HAMMER_PRESS_TIME} from '../gesture/gesture-config';\nimport {PredefinedColors} from '@ionic/core';\nimport {IonMenuToggle} from '@ionic/angular';\n\nexport abstract class ToolbarToken {\n abstract onBackClick: Observable<Event>;\n abstract doBackClick(event: Event);\n abstract goBack(): Promise<void>;\n abstract canGoBack: boolean;\n}\n\n@Component({\n selector: 'app-toolbar',\n templateUrl: 'toolbar.html',\n styleUrls: ['./toolbar.scss'],\n providers: [\n {provide: ToolbarToken, useExisting: ToolbarComponent}\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ToolbarComponent implements ToolbarToken, OnInit, OnDestroy {\n\n private _closeTapCount = 0;\n private _validateTapCount = 0;\n private _defaultBackHref: string;\n private _backHref: string;\n\n @Input() title: String = '';\n\n @Input() color: PredefinedColors = 'primary';\n\n @Input()\n class = '';\n\n @Input() set backHref(value: string) {\n if (value !== this._backHref) {\n this._backHref = value;\n this.canGoBack = this.canGoBack || isNotNil(value);\n this.cd.markForCheck();\n }\n }\n\n get backHref(): string {\n return this._backHref;\n }\n\n @Input() set defaultBackHref(value: string) {\n if (value !== this._defaultBackHref) {\n this._defaultBackHref = value;\n this.canGoBack = this.canGoBack || isNotNil(value);\n this.cd.markForCheck();\n }\n }\n\n get defaultBackHref(): string {\n return this._defaultBackHref;\n }\n\n @Input() hasValidate = false;\n @Input() hasClose = false;\n @Input() hasSearch: boolean;\n @Input() canGoBack: boolean;\n @Input() canShowMenu = true;\n\n @Output() onValidate = new EventEmitter<Event>();\n @Output() onClose = new EventEmitter<Event>();\n @Output() onValidateAndClose = new EventEmitter<Event>();\n @Output() onBackClick = new EventEmitter<Event>();\n @Output() onSearch = new EventEmitter<CustomEvent>();\n\n progressBarMode$: Observable<ProgressMode>;\n showSearchBar = false;\n\n @ViewChild('searchbar', {static: true}) searchbar: IonSearchbar;\n @ViewChild('menuToggle', {static: true}) menuToggle: IonMenuToggle;\n\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private routerOutlet: IonRouterOutlet,\n private cd: ChangeDetectorRef,\n @Optional() progressBarService: ProgressBarService\n ) {\n\n // Listen progress bar service mode\n if (progressBarService) {\n this.progressBarMode$ = progressBarService.onProgressChanged\n .pipe(\n startWith<ProgressMode, ProgressMode>('none' as ProgressMode),\n tap((mode) => '[toolbar] Updating progressBarMode: ' + mode),\n debounceTime(100), // wait 100ms, to group changes\n distinctUntilChanged()\n );\n }\n }\n\n ngOnInit() {\n this.hasValidate = toBoolean(this.hasValidate, this.onValidate.observers.length > 0);\n this.canGoBack = toBoolean(this.canGoBack, this.routerOutlet.canGoBack()\n || isNotNilOrBlank(this._backHref)\n || isNotNilOrBlank(this._defaultBackHref));\n this.hasSearch = toBoolean(this.hasSearch, this.onSearch.observers.length > 0);\n }\n\n ngOnDestroy() {\n this.onBackClick.complete();\n this.onBackClick.unsubscribe();\n this.onValidate.complete();\n this.onValidate.unsubscribe();\n this.onClose.complete();\n this.onClose.unsubscribe();\n this.onValidateAndClose.complete();\n this.onValidateAndClose.unsubscribe();\n this.onSearch.complete();\n this.onSearch.unsubscribe();\n }\n\n async toggleSearchBar() {\n this.showSearchBar = !this.showSearchBar;\n if (this.showSearchBar && this.searchbar) {\n setTimeout(async () => {\n await this.searchbar.setFocus();\n }, 300);\n }\n }\n\n doBackClick(event: Event) {\n\n this.onBackClick.emit(event);\n\n // Stop propagation, if need (can be cancelled by onBackClick observers)\n if (event.defaultPrevented) return;\n\n // Execute the back action\n this.goBack();\n }\n\n async goBack(): Promise<void> {\n console.debug('[toolbar] calling goBack()');\n if (this._backHref) {\n const replaceUrl = !this.routerOutlet.canGoBack();\n // Relative href\n if (this._backHref.startsWith('.')) {\n await this.router.navigate([this._backHref], {relativeTo: this.route, replaceUrl});\n }\n else {\n await this.router.navigateByUrl(this._backHref, {replaceUrl});\n }\n }\n else if (this.routerOutlet.canGoBack()) {\n await this.routerOutlet.pop();\n }\n else if (this._defaultBackHref) {\n // Relative href\n if (this._defaultBackHref.startsWith('.')) {\n await this.router.navigate([this._defaultBackHref], {relativeTo: this.route, replaceUrl: true});\n }\n else {\n await this.router.navigateByUrl(this._defaultBackHref, {\n replaceUrl: true\n });\n }\n\n }\n else {\n console.error('[toolbar] Cannot go back. Missing attribute \\'defaultBackHref\\' or \\'backHref\\'');\n }\n }\n\n tapClose(event: HammerTapEvent) {\n // DEV only\n // console.debug(\"[toolbar] tapClose\", event.tapCount);\n if (this._validateTapCount > 0) return;\n\n // Distinguish simple and double tap\n this._closeTapCount = event.tapCount;\n setTimeout(() => {\n // Event is obsolete (a new tap event occur)\n if (event.tapCount < this._closeTapCount) {\n // Ignore event\n }\n\n // If event still the last tap event: process it\n else {\n this.onClose.emit(event.srcEvent || event);\n\n // Reset tab count\n this._closeTapCount = 0;\n }\n }, 500);\n }\n\n tapValidate(event: HammerTapEvent) {\n // DEV only\n //console.debug(\"[toolbar] tapValidate\", event.tapCount);\n\n if (!this.onValidateAndClose.observers.length) {\n this.onValidate.emit(event.srcEvent || event);\n }\n\n // Distinguish simple and double tap\n else {\n this._validateTapCount = event.tapCount;\n setTimeout(() => {\n // Event is obsolete (a new tap event occur)\n if (event.tapCount < this._validateTapCount) {\n // Ignore event\n }\n\n // If event still the last tap event: process it\n else {\n if (this._validateTapCount === 1) {\n this.onValidate.emit(event.srcEvent || event);\n }\n else if (this._validateTapCount >= 2) {\n this.onValidateAndClose.emit(event.srcEvent || event);\n }\n\n // Reset tab count\n this._validateTapCount = 0;\n }\n }, HAMMER_PRESS_TIME+10);\n }\n }\n}\n","\nimport { TranslateService } from '@ngx-translate/core';\nimport {MatPaginatorIntl} from '@angular/material/paginator';\nimport {Injectable} from '@angular/core';\n\n@Injectable({providedIn: 'root'})\nexport class MatPaginatorI18n extends MatPaginatorIntl {\n itemsPerPageLabel = 'Items per page';\n nextPageLabel = 'Next page';\n previousPageLabel = 'Previous page';\n getRangeLabel = function(page, pageSize, length) {\n const of = this.translate ? this.translate.instant('COMMON.PAGINATOR.OF') : 'of';\n if (length === 0 || pageSize === 0) {\n return '0 ' + of + ' ' + length;\n }\n length = Math.max(length, 0);\n const startIndex = page * pageSize;\n // If the start index exceeds the list length, do not try and fix the end index to the end.\n const endIndex = startIndex < length ?\n Math.min(startIndex + pageSize, length) :\n startIndex + pageSize;\n return startIndex + 1 + ' - ' + endIndex + ' ' + of + ' ' + length;\n };\n\n constructor(private translate: TranslateService) {\n super();\n this.translate = translate;\n\n translate.onLangChange.subscribe(() => this.translateLabels());\n\n this.translateLabels();\n }\n\n private translateLabels() {\n //console.debug(\"[i18n] Update pagination translations\");\n this.itemsPerPageLabel = this.translate.instant('COMMON.PAGINATOR.ITEMS_PER_PAGE');\n this.nextPageLabel = this.translate.instant('COMMON.PAGINATOR.NEXT_PAGE');\n this.previousPageLabel = this.translate.instant('COMMON.PAGINATOR.PREVIOUS_PAGE');\n }\n\n}\n","import {catchError, tap} from 'rxjs/operators';\nimport {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';\nimport {Observable} from 'rxjs';\nimport {ProgressBarService} from '../services/progress-bar.service';\n\nexport class ProgressInterceptor implements HttpInterceptor {\n constructor(private progressBarService: ProgressBarService) {\n }\n\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n this.progressBarService.increase();\n return next.handle(req)\n .pipe(\n tap(event => {\n if (event instanceof HttpResponse) {\n this.progressBarService.decrease();\n }\n }),\n catchError((err, event) => {\n this.progressBarService.decrease();\n throw err;\n }));\n }\n}\n","export function rgbToHex(r: number, g: number, b: number): string {\n return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b);\n}\n\nexport function rgbArrayToHex(rgb: number[]): string {\n return '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);\n}\n\nexport function hexToRgbArray(hex: string): number[] {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? [\n parseInt(result[1], 16),\n parseInt(result[2], 16),\n parseInt(result[3], 16)\n ] : null;\n}\n\nexport function hexToRgb(hex: string): {r: number; g: number; b: number} {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n}\n\nfunction componentToHex(c: number): string {\n const hex = c.toString(16);\n return hex.length === 1 ? ('0' + hex) : hex;\n}\n\n// See mix in file ionic.functions.color.scss\nexport function mixHex(color1: string, color2: string, weight?: number) {\n\n weight = weight ? (weight / 100) : 0.5;\n\n const rgb1 = hexToRgbArray(color1);\n if (!rgb1) throw Error('Invalid hex color:' + color1);\n\n const rgb2 = hexToRgbArray(color2);\n if (!rgb2) throw Error('Invalid hex color:' + color2);\n\n const rgbAverage = rgb1.map((v, index) => Math.round((v * weight + rgb2[index] * (1 - weight))) );\n return rgbArrayToHex(rgbAverage);\n}\n\n// 12% darker version of the base color (mix with black)\nexport function getColorShade(color: string) {\n return mixHex('#000000', color, 12);\n}\n\n// 10% lighter version of the base color (mix with white)\nexport function getColorTint(color: string) {\n return mixHex('#ffffff', color, 10);\n}\n\n/**\n *\n * @param color\n * @param bw if true, will use black or white color, instead of the exact inverse\n */\nexport function getColorContrast(color: string, bw?: boolean) {\n const rgb = hexToRgbArray(color);\n if (!rgb) throw Error('Invalid hex color:' + color);\n\n if (bw === true) {\n // http://stackoverflow.com/a/3943023/112731\n return (rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) > 186\n ? '#000000'\n : '#FFFFFF';\n }\n\n return rgbArrayToHex(rgb.map(v => 255 - v));\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n EventEmitter,\n forwardRef, InjectionToken, Injector,\n Input,\n OnInit,\n Optional,\n Output,\n ViewChild\n} from '@angular/core';\nimport {ControlValueAccessor, FormControl, FormGroupDirective, NG_VALUE_ACCESSOR, Validators} from '@angular/forms';\nimport {FloatLabelType} from '@angular/material/form-field';\nimport {isBlankString, isNilOrBlank, isNotNilBoolean, isNotNilOrBlank, joinPropertiesPath, toBoolean} from '../functions';\nimport { DisplayFn, FormFieldDefinition, FormFieldType } from './field.model';\nimport {TranslateService} from '@ngx-translate/core';\nimport {getColorContrast} from '../graph/colors.utils';\nimport {asInputElement, filterNumberInput, selectInputContent} from '../inputs';\nimport {toDateISOString} from '../dates';\n\nconst noop = () => {\n};\n\n@Component({\n selector: 'app-form-field',\n styleUrls: ['./field.component.scss'],\n templateUrl: './field.component.html',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => AppFormField),\n multi: true\n }\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppFormField implements OnInit, ControlValueAccessor {\n\n private _onChangeCallback: (_: any) => void = noop;\n private _onTouchedCallback: () => void = noop;\n private _definition: FormFieldDefinition;\n\n type: FormFieldType;\n numberInputStep: string;\n\n @Input()\n set definition(value: FormFieldDefinition) {\n if (this._definition === value) return;\n this._definition = value;\n this.type = value?.type;\n this.cd.markForCheck();\n }\n\n get definition(): FormFieldDefinition {\n return this._definition;\n }\n\n @Input() required: boolean;\n @Input() readonly = false;\n @Input() disabled: boolean;\n @Input() formControl: FormControl;\n @Input() formControlName: string;\n @Input() placeholder: string;\n @Input() compact = false;\n @Input() floatLabel: FloatLabelType = 'auto';\n @Input() tabindex: number;\n @Input() autofocus: boolean;\n\n @Input('class') classList: string;\n\n @Output('keyup.enter')\n onKeyupEnter = new EventEmitter<any>();\n\n get value(): any {\n return this.formControl.value;\n }\n\n @ViewChild('matInput') matInput: ElementRef;\n\n constructor(\n protected translate: TranslateService,\n protected cd: ChangeDetectorRef,\n protected injector: Injector,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n\n }\n\n ngOnInit() {\n\n if (!this._definition) throw new Error('Missing mandatory attribute \\'definition\\' in <app-form-field>.');\n if (typeof this._definition !== 'object') throw new Error('Invalid attribute \\'definition\\' in <app-form-field>. Should be an object.');\n if (!this.type) throw new Error('Invalid attribute \\'definition\\' in <app-form-field>. Missing type !');\n\n this.checkAndResolveFormControl();\n\n this.placeholder = this.placeholder || (this._definition.label && this.translate.instant(this._definition.label));\n this.required = isNotNilBoolean(this.required) ? this.required : (this._definition.required || this.formControl.validator === Validators.required || isBlankString(this.required));\n this.disabled = toBoolean(this.disabled, toBoolean(this._definition.disabled, false));\n\n this.updateTabIndex();\n\n if (this.type === 'double') {\n this.numberInputStep = this.computeNumberInputStep(this._definition);\n } else if (this.type === 'enum' && this._definition.values instanceof InjectionToken) {\n this._definition.values = this.computeValuesFromToken(this._definition.values);\n }\n }\n\n writeValue(obj: any): void {\n if ((this.type === 'integer' || this.type === 'double') && Number.isNaN(obj)) {\n //console.log(\"WARN: trying to set NaN value, in a config option field ! \" + this.constructor.name);\n obj = null;\n }\n else if (this.type === 'boolean' && typeof obj === 'string') {\n obj = (obj !== 'false');\n }\n else if (this.type === 'date') {\n obj = toDateISOString(obj);\n }\n else if (this.type === 'entity' && isNilOrBlank(obj)) {\n obj = null;\n }\n if (obj !== this.formControl.value) {\n //console.debug(\"Set config value \", this.formControl.value, obj);\n this.formControl.patchValue(obj, {emitEvent: false});\n this._onChangeCallback(obj);\n }\n\n this.cd.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this._onChangeCallback = fn;\n }\n\n registerOnTouched(fn: any): void {\n this._onTouchedCallback = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this.disabled === isDisabled) return;\n this.disabled = isDisabled;\n this.cd.markForCheck();\n }\n\n public markAsTouched() {\n if (this.formControl.touched) {\n this.cd.markForCheck();\n this._onTouchedCallback();\n }\n }\n\n filterAlphanumericalInput(event: KeyboardEvent) {\n if (event.keyCode === 13 /*=Enter*/ && this.onKeyupEnter.observers.length) {\n this.onKeyupEnter.emit(event);\n return;\n }\n // Add features (e.g. check against a pattern)\n }\n\n focus() {\n if (this.matInput) this.matInput.nativeElement.focus();\n }\n\n filterNumberInput = filterNumberInput;\n selectInputContent = selectInputContent;\n\n getDisplayValueFn(definition: FormFieldDefinition): DisplayFn {\n if (definition.autocomplete && definition.autocomplete.displayWith) {\n return (obj: any) => definition.autocomplete.displayWith(obj);\n }\n const attributes = definition.autocomplete && definition.autocomplete.attributes || ['label', 'name'];\n return (obj: any) => obj && joinPropertiesPath(obj, attributes);\n }\n\n getColorContrast(color: string): string | undefined {\n return isNotNilOrBlank(color) ? getColorContrast(color, true) : undefined;\n }\n\n /* -- protected method -- */\n\n protected computeNumberInputStep(definition: FormFieldDefinition): string {\n\n if (definition.maximumNumberDecimals > 0) {\n let step = '0.';\n if (definition.maximumNumberDecimals > 1) {\n for (let i = 0; i < definition.maximumNumberDecimals - 1; i++) {\n step += '0';\n }\n }\n step += '1';\n return step;\n } else {\n return '1';\n }\n }\n\n protected computeValuesFromToken(token: InjectionToken<any>): any[] {\n const values = this.injector.get(token);\n return Array.isArray(values) ? values : [];\n }\n\n protected checkAndResolveFormControl() {\n if (this.formControl) return; // OK, there is a control\n\n if (this.formGroupDir) {\n // Try to find using definition.key, as formControlName\n if (!this.formControlName && this._definition.key) {\n this.formControlName = this._definition.key;\n }\n const formControlName = (this.formGroupDir.directives || []).find(d => this.formControlName && d.name === this.formControlName);\n this.formControl = formControlName && formControlName.control;\n if (!this.formControl) {\n this.formControl = this.formGroupDir.form.get(this.formControlName) as FormControl;\n }\n }\n\n if (!this.formControl) {\n throw new Error('Missing attribute \\'formControl\\' or \\'formControlName\\' in <app-form-field> component.');\n }\n }\n\n protected updateTabIndex() {\n if (this.tabindex && this.tabindex !== -1) {\n setTimeout(() => {\n const element = asInputElement(this.matInput);\n if (element) {\n element.tabIndex = this.tabindex;\n this.cd.markForCheck();\n }\n });\n }\n }\n}\n","import {Optional} from '@angular/core';\nimport {BehaviorSubject, EmptyError, Observable, Subject, Subscription} from 'rxjs';\nimport {filter, takeUntil} from 'rxjs/operators';\n\nexport interface IStartableService<T = any> {\n started: boolean;\n start(): Promise<T>;\n stop(): Promise<void>;\n ready(): Promise<T>;\n}\n\nexport abstract class StartableService<T = any, O = any> implements IStartableService<T> {\n\n readonly startSubject = new Subject<T>();\n readonly stopSubject = new Subject<void>();\n\n protected _debug = false;\n protected _startByReadyFunction = true; // should start when calling ready() ?\n protected _data: T = null;\n\n private _started = false;\n private _startPromise: Promise<T> = null;\n private _startPrerequisite: () => Promise<any> = null;\n private _subscription: Subscription = null;\n\n protected constructor(\n @Optional() prerequisiteService?: { ready: () => Promise<any> }\n ) {\n this._startPrerequisite = prerequisiteService\n ? () => prerequisiteService.ready()\n : () => Promise.resolve();\n }\n\n start(opts?: O): Promise<T> {\n if (this._startPromise) return this._startPromise;\n if (this._started) return Promise.resolve(this._data);\n\n this._startPromise = this._startPrerequisite()\n .then(() => this.ngOnStart(opts))\n .then(data => {\n this._data = data;\n\n this._started = true;\n this._startPromise = undefined;\n\n this.startSubject.next(data);\n\n return data;\n })\n .catch(err => {\n if (!this.stopped) {\n console.error('Failed to start a service: ' + (err && err.message || err), err);\n this._startPromise = null;\n this._started = false;\n }\n return null;\n });\n return this._startPromise;\n }\n\n ready(): Promise<T> {\n if (this._started) return Promise.resolve(this._data);\n if (this._startPromise) return this._startPromise;\n if (this._startByReadyFunction) return this.start();\n\n return this.startSubject\n .pipe(takeUntil(this.stopSubject))\n .toPromise();\n }\n\n async stop() {\n try {\n this.unsubscribe();\n await this.ngOnStop();\n }\n catch (err) {\n console.error('Failed to stop a service: ' + (err && err.message || err), err);\n }\n finally {\n this._data = null;\n this._started = false;\n this._startPromise = undefined;\n this.stopSubject.next();\n }\n }\n\n async restart(opts?: O): Promise<T> {\n if (this._startPromise) await this._startPromise; // Wait end of previous loading\n if (this._started) await this.stop(); // Then stop if started\n return this.start(opts); // Then start again\n }\n\n get started(): boolean {\n return this._started;\n }\n\n get starting(): boolean {\n return !!this._startPromise;\n }\n\n get stopped(): boolean {\n return !this._started && !this._startPromise;\n }\n\n protected registerSubscription(sub: Subscription): Subscription {\n this._subscription = this._subscription || new Subscription();\n return this._subscription.add(sub);\n }\n\n protected unregisterSubscription(sub: Subscription): void {\n this._subscription?.remove(sub);\n }\n\n protected unsubscribe() {\n this._subscription?.unsubscribe();\n this._subscription = null;\n }\n\n protected ngOnStop(): Promise<void> | void {\n // Can be overwritten by subclasses\n }\n\n protected abstract ngOnStart(opts?: O): Promise<T>;\n}\n","import {Injectable, Optional} from '@angular/core';\nimport {NativeAudio} from '@ionic-native/native-audio/ngx';\nimport {Vibration} from '@ionic-native/vibration/ngx';\nimport {Platform} from '@ionic/angular';\nimport {AudioManagement} from '@ionic-native/audio-management/ngx';\nimport {Subject} from 'rxjs';\nimport {isNil, toBoolean} from '../functions';\nimport {StartableService} from '../services/startable-service.class';\n\nexport type AudioType = 'html5' | 'native';\nexport interface Sound {\n id: string;\n assetPath: string;\n vibration?: number|number[];\n}\n\nconst SYSTEM_SOUNDS: Sound[] = [\n {id: 'beep-confirm', assetPath: 'assets/audio/beep-confirm.mp3', vibration: 250},\n {id: 'beep-error', assetPath: 'assets/audio/beep-error.mp3', vibration: 1000},\n {id: 'startup', assetPath: 'assets/audio/unfa-ping.mp3', vibration: [1, 500, 250, 750]},\n];\n\n@Injectable({providedIn: 'root'})\nexport class AudioProvider extends StartableService<void> {\n\n private _audioType: AudioType;\n private _audioMode: AudioManagement.AudioMode = AudioManagement.AudioMode.NORMAL;\n\n private _preloadedSounds: {[id: string]: Sound} = {};\n private _htmlAudioCache: {[id: string]: HTMLAudioElement} = {};\n\n constructor(\n protected platform: Platform,\n @Optional() private nativeAudio: NativeAudio,\n @Optional() private vibration: Vibration,\n @Optional() private audioManagement: AudioManagement\n ) {\n super(platform);\n\n this.start();\n }\n\n playBeepConfirm(): Promise<any> {\n return this.play('beep-confirm', {\n // Vibrate only if in vibration mode\n vibrate: this._audioMode === AudioManagement.AudioMode.VIBRATE\n });\n }\n\n playBeepError(): Promise<any> {\n return this.play('beep-error', {\n // Vibrate only if in vibration mode\n vibrate: true\n });\n }\n\n async playStartupSound(): Promise<any> {\n return this.play('startup');\n }\n\n async preload(sound: Sound) {\n if (isNil(this._audioType)) await this.ready();\n\n if (this._audioType === 'native') {\n console.info(`[audio] Preloading audio file '${sound.assetPath}'...`);\n try {\n await this.nativeAudio.preloadSimple(sound.id, sound.assetPath);\n console.info(`[audio] Preloading audio file '${sound.assetPath}' [OK]`);\n }\n catch (err) {\n console.error(`[audio] Unable to preload audio file '${sound.assetPath}': ${err && err.message || err}`, err);\n }\n }\n else {\n this._htmlAudioCache[sound.id] = new Audio(sound.assetPath);\n }\n\n // Add to map\n this._preloadedSounds[sound.id] = sound;\n }\n\n async play(id: string, opts?: {vibrate?: boolean; vibrationTimes?: number|number[]}) {\n\n // Make sure provider is ready\n if (!this.started) await this.ready();\n\n const sound = this._preloadedSounds[id];\n if (!sound) {\n throw Error('Unable to find audio with id: ' + id + '. Please call preload() before playing a sound.');\n }\n\n // If silent: skip\n if (this._audioMode === AudioManagement.AudioMode.SILENT) return;\n\n const promises: Promise<any>[] = [];\n\n // Normal mode = can play the sound\n if (this._audioMode === AudioManagement.AudioMode.NORMAL) {\n // Use native audio\n if (this._audioType === 'native') {\n promises.push(this.nativeAudio.play(sound.id));\n }\n // Or HTML 5 audio\n else {\n const audio = this._htmlAudioCache[id] || new Audio(sound.assetPath);\n promises.push(audio.play());\n }\n }\n\n // Vibrate mode: by default make vibration is enable\n else if (isNil(sound.vibration) && isNil(opts && opts.vibrate)) {\n opts = opts || {};\n opts.vibrate = true;\n }\n\n // Do vibration (if sound as default vibration, or if user ask for it)\n if (toBoolean(opts && opts.vibrate, !!sound.vibration)) {\n promises.push(this.vibrate(opts && opts.vibrationTimes || sound.vibration));\n }\n\n return (promises.length === 1 ? promises[0] : Promise.all(promises))\n .catch(err => {\n console.error(`[audio] Error while playing audio sound '${id}': ${err && err.message || err}`, err);\n });\n }\n\n async unload(id: string) {\n if (isNil(this._audioType)) await this.ready();\n\n // Remove from map\n this._preloadedSounds[id] = undefined;\n\n // Native unload\n if (this._audioType === 'native') {\n try {\n await this.nativeAudio.unload(id);\n }\n catch (err) {\n console.error(`[audio] Unable to unload audio '${id}': ${err && err.message || err}`, err);\n }\n }\n // HTML5 audio unload\n else {\n this._htmlAudioCache[id].remove();\n this._htmlAudioCache[id] = undefined;\n }\n }\n\n async vibrate(timeInMs?: number|number[]) {\n if (!this.started) await this.ready();\n\n if (!this.vibration) return; // Skip if vibrate plugin\n\n this.vibration.vibrate(timeInMs || 250);\n }\n\n /* -- protected methods -- */\n\n async ngOnStart(): Promise<void> {\n\n let cordova = this.platform.is('cordova');\n this._audioType = cordova && this.nativeAudio ? 'native' : 'html5';\n console.info(`[audio] Starting audio provider {${this._audioType}}...`);\n\n // Listen audio mode changed\n if (cordova && this.audioManagement) {\n await this.readAudioMode();\n }\n\n // Pre-loading system sounds\n console.debug('[audio] Preloading audio sounds...');\n await Promise.all(SYSTEM_SOUNDS.map(s => {\n // Disable vibration is cordova not enabled\n if (!cordova) s.vibration = undefined;\n return this.preload(s);\n }));\n }\n\n protected async readAudioMode() {\n const value = await this.audioManagement.getAudioMode();\n this._audioMode = value && value.audioMode || AudioManagement.AudioMode.NORMAL;\n console.debug(`[audio] Detected device audio mode {${value.label}} (${this._audioMode})`);\n }\n\n}\n","import { Component, OnInit, Inject } from '@angular/core';\nimport {MAT_DIALOG_DATA} from '@angular/material/dialog';\n\n@Component({\n templateUrl: './hotkeys-dialog.component.html',\n styleUrls: ['./hotkeys-dialog.component.scss']\n})\nexport class HotkeysDialogComponent implements OnInit {\n hotkeys = Array.from(this.data);\n\n constructor(@Inject(MAT_DIALOG_DATA) protected data) { }\n\n ngOnInit() {\n }\n\n}\n","import { Inject, Injectable } from '@angular/core';\nimport { EventManager } from '@angular/platform-browser';\nimport { Observable } from 'rxjs';\nimport { DOCUMENT } from '@angular/common';\nimport { MatDialog } from '@angular/material/dialog';\nimport { HotkeysDialogComponent } from './dialog/hotkeys-dialog.component';\nimport { isNotNilOrBlank } from '../functions';\nimport { ModalController, PopoverController } from '@ionic/angular';\n\ninterface Options {\n element: any;\n elementName: string;\n description: string | undefined;\n keys: string;\n preventDefault: boolean;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class Hotkeys {\n\n private _debug = false;\n private _hotkeys = new Map();\n\n private _defaults: Partial<Options> = {\n element: this.document,\n preventDefault: true\n };\n\n constructor(private eventManager: EventManager,\n private dialog: MatDialog,\n @Inject(DOCUMENT) private document: any,\n private modalController: ModalController,\n private popoverController: PopoverController) {\n if (this._debug) console.debug('[hotkeys] Starting hotkeys service... Press Shift+? to get help modal.');\n\n this.addShortcut({keys: 'shift.?'})\n .subscribe(() => this.openHelpModal());\n\n // For DEV only\n //this._debug = !environment.production;\n }\n\n addShortcut(options: Partial<Options>): Observable<UIEvent> {\n\n const merged = {...this._defaults, ...options};\n const event = `keydown.${merged.keys}`;\n\n if (isNotNilOrBlank(merged.description)) {\n if (this._debug) console.debug(`[hotkeys] Add shortcut {${options.keys}}: ${merged.description}`);\n this._hotkeys.set(merged.keys, merged.description);\n } else {\n if (this._debug) console.debug(`[hotkeys] Add shortcut {${options.keys}}`);\n }\n\n return new Observable(observer => {\n const handler = async (e: UIEvent) => {\n\n // Get top component from ModalController\n const top = await this.modalController.getTop() || await this.popoverController.getTop();\n // If modal present, check its component name against hotkey element name (fix #181)\n if (top && top.component['name'] !== merged.elementName) {\n e.preventDefault();\n return;\n }\n if (e instanceof KeyboardEvent && e.repeat) return; // skip when repeated\n if (merged.preventDefault) e.preventDefault();\n if (this._debug) console.debug(`[hotkeys] Shortcut {${options.keys}} detected...`);\n observer.next(e);\n };\n\n const dispose = this.eventManager.addEventListener(merged.element, event, handler);\n\n return () => {\n dispose();\n this._hotkeys.delete(merged.keys);\n };\n });\n }\n\n openHelpModal() {\n this.dialog.open(HotkeysDialogComponent, {\n width: '500px',\n data: this._hotkeys\n });\n }\n\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {Hotkeys} from './hotkeys.service';\nimport {HotkeysDialogComponent} from './dialog/hotkeys-dialog.component';\nimport {MatDialogModule} from '@angular/material/dialog';\nimport {MatCommonModule} from '@angular/material/core';\n\n@NgModule({\n imports: [\n CommonModule,\n MatCommonModule,\n MatDialogModule,\n TranslateModule.forChild()\n ],\n exports: [\n HotkeysDialogComponent\n ],\n declarations: [\n HotkeysDialogComponent\n ],\n providers: [\n Hotkeys\n ]\n})\nexport class SharedHotkeysModule {\n}\n","import {Observable} from 'rxjs';\nimport {HttpEvent, HttpEventType, HttpProgressEvent, HttpResponse} from '@angular/common/http';\nimport {isNotNil} from '../functions';\n\nexport class UploadFile<T> extends File {\n progress?: number;\n deleting?: boolean;\n error?: string;\n\n response?: FileResponse<T> | HttpResponse<T>;\n}\n\nexport type FileUploadFn<T> = (file: File) => Observable<FileEvent<T> | HttpEvent<T>>;\nexport type FileDeleteFn<T> = (file: UploadFile<T>) => Promise<boolean>;\nexport interface FileProgressEvent {\n type: HttpEventType.DownloadProgress | HttpEventType.UploadProgress;\n loaded: number;\n total?: number;\n statusText?: string;\n}\nexport class FileResponse<T> {\n readonly body: T|null;\n readonly type = HttpEventType.Response;\n readonly status: number;\n readonly statusText: string;\n constructor(init?: {body?: T|null; statusText?: string; status?: number}) {\n this.body = isNotNil(init?.body) ? init.body : null;\n this.status = init?.status || 0;\n this.statusText = init?.statusText || 'OK';\n }\n}\n\nexport declare type FileEvent<T> = HttpProgressEvent | HttpResponse<T> | FileProgressEvent | FileResponse<T> ;\n\nexport function isProgressEvent(event: HttpEvent<any> | FileEvent<any>): event is HttpProgressEvent | FileProgressEvent {\n return event && (event.type === HttpEventType.UploadProgress\n || event.type === HttpEventType.DownloadProgress);\n}\nexport function isResponseEvent<T>(event: HttpEvent<T> | FileEvent<T>): event is HttpResponse<T> | FileResponse<T> {\n return event && event.type === HttpEventType.Response;\n}\n","import {isNilOrBlank} from '../functions';\nimport {Observable, Subject} from 'rxjs';\nimport {FileEvent, FileResponse} from '../upload-file/upload-file.model';\nimport {HttpEventType} from '@angular/common/http';\nimport {mergeMap} from 'rxjs/operators';\n\nexport const IMAGE_DEFAULTS = {\n MAX_HEIGHT: 480,\n MAX_WIDTH: 640,\n THUMB_MAX_HEIGHT: 200,\n THUMB_MAX_WIDTH: 200\n};\n\nexport declare interface ImageResizeOptions {\n maxWidth?: number;\n maxHeight?: number;\n thumbnail?: boolean;\n}\n\n// @dynamic\nexport class ImagesUtils {\n\n static readAsDataURL(file: File, opts?: ImageResizeOptions): Observable<FileEvent<string>> {\n\n const $progress = new Subject<FileEvent<string>>();\n const reader = new FileReader();\n\n // Listen progress\n reader.onprogress = (e: ProgressEvent) => {\n const total = e.total || 1;\n const loaded = e.total || 0;\n if (loaded < total) $progress.next({type: HttpEventType.UploadProgress, loaded, total});\n }\n\n // Listen end\n reader.onloadend = (e: ProgressEvent) => {\n const body = reader.result;\n if (typeof body === 'string') {\n $progress.next(new FileResponse({body}));\n $progress.complete();\n }\n else {\n console.error(`[image-utils] Cannot read file '${file.name}' as text`);\n $progress.error(`Cannot read file as text`);\n }\n }\n\n // Listen error\n reader.onerror = (event: ProgressEvent) => {\n console.error('[image-utils] Error while reading file:', event);\n $progress.error(event);\n }\n\n // Start reading the file\n reader.readAsDataURL(file);\n\n // Resize image, if need\n if (opts) {\n return $progress.pipe(\n mergeMap(async (event) => {\n if (event instanceof FileResponse) {\n const body = await ImagesUtils.resizeBase64(event.body, opts);\n return new FileResponse({body})\n }\n return event;\n })\n );\n }\n\n return $progress.asObservable();\n }\n\n static async readAndResizeFromUrl(fileUrl: string, opts?: ImageResizeOptions): Promise<string> {\n if (isNilOrBlank(fileUrl)) throw new Error('Illegal argument: missing fileUrl');\n\n // Create the temporary image element\n const img = document.createElement('img');\n\n // Need to avoid CORS error\n // (see https://stackoverflow.com/questions/22710627/tainted-canvases-may-not-be-exported)\n img.crossOrigin = 'anonymous';\n\n try {\n return await new Promise<string>((resolve, reject) => {\n img.addEventListener('load', ImagesUtils.createImageOnLoadResizeFn(resolve, reject, opts), false);\n img.addEventListener('error', reject);\n img.src = fileUrl;\n });\n }\n catch (err) {\n throw new Error(`Failed to load and resize image {${fileUrl}}`);\n }\n finally {\n img.remove();\n }\n }\n\n\n static async resizeBase64(dataUrl: string, opts?: ImageResizeOptions): Promise<string> {\n // Create the temporary image element\n const img = document.createElement('img');\n\n // Need to avoid CORS error\n // (see https://stackoverflow.com/questions/22710627/tainted-canvases-may-not-be-exported)\n img.crossOrigin = 'anonymous';\n\n try {\n return await new Promise<string>((resolve, reject) => {\n img.addEventListener('load', ImagesUtils.createImageOnLoadResizeFn(resolve, reject, opts), false);\n img.addEventListener('error', reject);\n img.src = dataUrl;\n });\n }\n finally {\n img.remove();\n }\n }\n\n protected static createImageOnLoadResizeFn(resolve, reject, opts?: ImageResizeOptions) {\n return function(event) {\n const\n maxWidth = (opts && opts.thumbnail ? IMAGE_DEFAULTS.THUMB_MAX_WIDTH : (opts && opts.maxWidth || IMAGE_DEFAULTS.MAX_WIDTH));\n const maxHeight = (opts && opts.thumbnail ? IMAGE_DEFAULTS.THUMB_MAX_HEIGHT : (opts && opts.maxHeight || IMAGE_DEFAULTS.MAX_HEIGHT));\n let width = event.target.width;\n let height = event.target.height;\n\n const canvas = document.createElement('canvas');\n let ctx;\n\n try {\n // Thumbnail: resize and crop (to the expected size)\n if (opts && opts.thumbnail) {\n\n // landscape\n if (width > height) {\n width *= maxHeight / height;\n height = maxHeight;\n }\n\n // portrait\n else {\n height *= maxWidth / width;\n width = maxWidth;\n }\n canvas.width = maxWidth;\n canvas.height = maxHeight;\n ctx = canvas.getContext('2d');\n const xoffset = Math.trunc((maxWidth - width) / 2 + 0.5);\n const yoffset = Math.trunc((maxHeight - height) / 2 + 0.5);\n ctx.drawImage(event.target,\n xoffset, // x1\n yoffset, // y1\n maxWidth + -2 * xoffset, // x2\n maxHeight + -2 * yoffset // y2\n );\n }\n\n // Resize, but keep the full image\n else {\n\n // landscape\n if (width > height) {\n if (width > maxWidth) {\n height *= maxWidth / width;\n width = maxWidth;\n }\n }\n\n // portrait\n else {\n if (height > maxHeight) {\n width *= maxHeight / height;\n height = maxHeight;\n }\n }\n\n canvas.width = width;\n canvas.height = height;\n ctx = canvas.getContext('2d');\n\n // Resize the whole image\n ctx.drawImage(event.target, 0, 0, canvas.width, canvas.height);\n }\n\n // Get image content as data URL\n const base64 = canvas.toDataURL();\n resolve(base64);\n }\n catch (err) {\n reject(err);\n }\n finally {\n canvas.remove();\n }\n\n };\n }\n}\n","import 'tweetnacl';\nimport 'tweetnacl-util';\nimport 'scrypt-async';\n\n// Import Hammer JS (need to manage 'tap' events)\nimport 'hammerjs';\n\n// Force moment-timezone to be loaded, otherwise moment().tz() will failed\nimport * as momentImported from 'moment';\nimport { Moment } from 'moment';\nimport * as momentTZImported from 'moment-timezone';\nconst moment = momentImported;\nconst tz = momentTZImported;\nexport { moment, tz, Moment }\n\n// Import uuid\nimport * as uuidv4Imported from 'uuid/v4';\nconst uuidv4 = uuidv4Imported;\nexport {uuidv4};\n","import {Inject, Injectable} from '@angular/core';\nimport {Platform} from '@ionic/angular';\nimport {ImagesUtils, ImageResizeOptions} from './images.utils';\nimport {chainPromises, firstNotNilPromise} from '../observables';\nimport {HttpClient} from '@angular/common/http';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {uuidv4} from '../../vendor';\n\n@Injectable({\n providedIn: 'root',\n deps: [\n Platform,\n HttpClient\n ]\n})\nexport class FileService {\n\n private readonly _debug: boolean;\n private _started = false;\n\n private _imageDirectory: string;\n\n get canUseFileSystem(): boolean {\n return false;\n // FIXME: seems not working well\n //return !!this.file.dataDirectory;\n }\n\n constructor(\n private platform: Platform,\n //private transfer: FileTransfer,\n //@Optional() private file: File,\n private http: HttpClient,\n @Inject(ENVIRONMENT) protected environment) {\n\n this._debug = !environment.production;\n\n platform.ready().then(() => this.start());\n }\n\n getImages(sources: string[], opts?: ImageResizeOptions & {\n outputType?: 'fileUrl' | 'dataUrl';\n }): Promise<string[]> {\n if (!this._started) throw new Error('Platform must be started first!');\n\n //const fileTransfer = this.canUseFileSystem ? this.transfer.create() : undefined;\n //const jobsFactories = (sources || []).map(source => () => this.getImage(source, {...opts, fileTransfer}));\n\n const jobsFactories = (sources || []).map(source => () => this.getImage(source, {...opts}));\n return chainPromises<string>(jobsFactories);\n }\n\n async getImage(fileUrl: string, opts?: ImageResizeOptions & {\n outputType?: 'fileUrl' | 'dataUrl';\n }): Promise<string> {\n\n let outputType = opts && opts.outputType || (this.canUseFileSystem ? 'fileUrl' : 'dataUrl');\n\n const debug = this._debug /*&& (!opts || !opts.fileTransfer)*/;\n const now = debug && Date.now();\n if (debug) console.debug(`[file] Fetching image {${fileUrl}} into ${outputType}...`);\n\n // Read the filename\n const lastSlashIndex = fileUrl.lastIndexOf('/');\n if (lastSlashIndex === -1) throw new Error('Invalid URL: ' + fileUrl);\n const fileName = lastSlashIndex < (fileUrl.length - 1) && fileUrl.substring(lastSlashIndex + 1) || uuidv4();\n\n\n // Download into the file system\n if (outputType === 'fileUrl' && this.canUseFileSystem) {\n console.warn(`WARN: [file] Downloading image {${fileUrl}} in local filesystem...`);\n const targetFilePath = this._imageDirectory + fileName;\n try {\n const blob: Blob = await firstNotNilPromise(this.http.get(fileUrl, {\n observe: 'body',\n responseType: 'blob',\n reportProgress: false\n }));\n console.debug('[file] Getting blob :' + blob.type);\n\n //await this.file.writeFile(this._imageDirectory, fileName, blob, {replace: true});\n\n //const fileTransfer = (opts && opts.fileTransfer) || this.transfer.create();\n //await fileTransfer.download(source, targetFilePath);\n if (debug) console.debug(`[file] Fetching image {${fileUrl}} into ${outputType} [OK] in ${Date.now() - now}ms`);\n return targetFilePath;\n }\n catch (err) {\n console.error(`[file] Error while download ${fileUrl}: ${err && err.message || err}`);\n\n // Continue (fallback to data Url)\n outputType = 'dataUrl';\n }\n }\n\n if (outputType === 'dataUrl') {\n // Get as data url (e.g. 'data:image/png:...')\n const dataUrl = await ImagesUtils.readAndResizeFromUrl(fileUrl, opts);\n if (debug) console.debug(`[file] Fetching image {${fileUrl}} into ${outputType} [OK] in ${Date.now() - now}ms`);\n return dataUrl;\n }\n\n // Keep original URL\n return fileUrl;\n }\n\n /* -- protected methods -- */\n\n protected start() {\n\n // File system exists\n if (this.canUseFileSystem) {\n //console.info(\"[file] Application directory: \", this.file.applicationDirectory);\n //console.info(\"[file] Application storage directory: \", this.file.applicationStorageDirectory);\n //console.info(\"[file] Data directory: \", this.file.dataDirectory);\n\n // this.file.createDir(this.file.dataDirectory, 'images', false)\n // .then((dir) => {\n // this._imageDirectory = this.file.dataDirectory + 'images/';\n // console.info(\"[file] Images directory: \", dir.fullPath);\n // })\n // .catch(err => {\n // console.error(\"[file] Cannot create the images directory: \" + (this.file.dataDirectory + 'images/ : ' + (err && err.message || err)));\n // this._imageDirectory = this.file.dataDirectory;\n // });\n }\n\n this._started = true;\n }\n\n}\n","import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';\nimport {toBoolean} from '../functions';\nimport {Subscription} from 'rxjs';\nimport {Hotkeys} from '../hotkeys/hotkeys.service';\nimport {IconRef} from '../types';\nimport {filter} from 'rxjs/operators';\n\n@Component({\n selector: 'app-modal-toolbar',\n templateUrl: 'modal-toolbar.html',\n styleUrls: ['./modal-toolbar.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ModalToolbarComponent implements OnInit, OnDestroy {\n\n private _subscription = new Subscription();\n\n @Input()\n modalName = 'modal-toolbar';\n\n @Input()\n title = '';\n\n @Input()\n color = 'primary';\n\n @Input()\n showSpinner = false;\n\n @Input()\n canValidate: boolean;\n\n @Input() validateIcon: IconRef = {icon: 'checkmark'};\n\n @Output()\n cancel = new EventEmitter<UIEvent>();\n\n @Output()\n validate = new EventEmitter<UIEvent>();\n\n constructor(private hotkeys: Hotkeys) {}\n\n ngOnInit() {\n this.canValidate = toBoolean(this.canValidate, this.validate.observers.length > 0);\n\n // Ctrl+S\n this._subscription.add(\n this.hotkeys.addShortcut({keys: 'control.s', description: 'COMMON.BTN_VALIDATE', elementName: this.modalName})\n .pipe(filter(() => this.canValidate))\n .subscribe((event) => this.validate.emit(event)));\n\n // Escape\n this._subscription.add(\n this.hotkeys.addShortcut({keys: 'escape', description: 'COMMON.BTN_CLOSE', elementName: this.modalName})\n .subscribe((event) => this.cancel.emit(event)));\n\n }\n\n ngOnDestroy(): void {\n this._subscription.unsubscribe();\n }\n\n}\n","import {Component, Input} from '@angular/core';\n\n@Component({\n selector: 'app-loading-spinner',\n template: `\n <ion-spinner *ngIf=\"loading; else content\" [color]=\"color\" [name]=\"name\"></ion-spinner>\n <ng-template #content>\n <ng-content></ng-content>\n </ng-template>\n `\n})\nexport class AppLoadingSpinner {\n @Input() loading = false;\n @Input() color: string | undefined = 'secondary';\n @Input() name: 'bubbles' | 'circles' | 'circular' | 'crescent' | 'dots' | 'lines' | 'lines-small' | undefined;\n}\n","// Base58 encoding/decoding\n// Originally written by Mike Hearn for BitcoinJ\n// Copyright (c) 2011 Google Inc\n// Ported to JavaScript by Stefan Thomas\n// Merged Buffer refactorings from base58-native by Stephen Pair\n// Copyright (c) 2013 BitPay Inc\n// Rewritten in TypeScript by Ludovic Pecquot\n\n// @dynamic\nexport class Base58 {\n\n private static alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n private static alphabetMap;\n\n private static getAlphabetMap() {\n if (!Base58.alphabetMap){\n this.alphabetMap = {};\n for (let i = 0; i < Base58.alphabet.length; i++) {\n Base58.alphabetMap[Base58.alphabet.charAt(i)] = i;\n }\n }\n return Base58.alphabetMap;\n }\n\n public static encode(buffer: Uint8Array): string {\n if (buffer.length === 0) return '';\n\n let i; let j; const digits = [0];\n for (i = 0; i < buffer.length; i++) {\n for (j = 0; j < digits.length; j++) digits[j] <<= 8;\n digits[digits.length - 1] += buffer[i];\n\n let carry = 0;\n for (j = digits.length - 1; j >= 0; j--){\n digits[j] += carry;\n carry = (digits[j] / 58) | 0;\n digits[j] %= 58;\n }\n\n while (carry) {\n digits.unshift(carry);\n carry = (digits[0] / 58) | 0;\n digits[0] %= 58;\n }\n }\n\n // deal with leading zeros\n for (i = 0; i < buffer.length - 1 && buffer[i] === 0; i++) digits.unshift(0);\n\n return digits.map(function(digit) { return Base58.alphabet[digit]; }).join('');\n }\n\n public static decode(string: string): Uint8Array {\n if (string.length === 0) return (new Uint8Array());\n\n const input = string.split('').map(function(c){\n return Base58.getAlphabetMap()[c];\n });\n\n let i; let j; const bytes = [0];\n for (i = 0; i < input.length; i++) {\n for (j = 0; j < bytes.length; j++) bytes[j] *= 58;\n bytes[bytes.length - 1] += input[i];\n\n let carry = 0;\n for (j = bytes.length - 1; j >= 0; j--){\n bytes[j] += carry;\n carry = bytes[j] >> 8;\n bytes[j] &= 0xff;\n }\n\n while (carry) {\n bytes.unshift(carry);\n carry = bytes[0] >> 8;\n bytes[0] &= 0xff;\n }\n }\n\n // deal with leading zeros\n for (i = 0; i < input.length - 1 && input[i] === 0; i++) bytes.unshift(0);\n return (new Uint8Array(bytes));\n }\n}\n","import {Injectable} from '@angular/core';\nimport {box, sign, verify, hash} from 'tweetnacl';\nimport {Base58} from './base58';\n\nconst scrypt = require('scrypt-async');\nconst sha256 = require('hash.js/lib/hash/sha/256');\nconst sha512 = require('hash.js/lib/hash/sha/512');\n\nconst nacl = {\n sign,\n box,\n hash,\n verify,\n util: require('tweetnacl-util'),\n constants: {\n crypto_sign_BYTES: 64,\n SEED_LENGTH: 32, // Length of the key\n SCRYPT_PARAMS: {\n SIMPLE: {\n N: 2048,\n r: 8,\n p: 1,\n memory: -1 // default\n },\n DEFAULT: {\n N: 4096,\n r: 16,\n p: 1,\n memory: -1 // default\n },\n SECURE: {\n N: 16384,\n r: 32,\n p: 2,\n memory: -1 // default\n },\n HARDEST: {\n N: 65536,\n r: 32,\n p: 4,\n memory: -1 // default\n },\n EXTREME: {\n N: 262144,\n r: 64,\n p: 8,\n memory: -1 // default\n }\n }\n }\n};\n\nexport interface CryptoSaltParams {\n N: number;\n r: number;\n p: number;\n}\nexport interface KeyPair {\n publicKey: Uint8Array;\n secretKey: Uint8Array;\n}\n\n@Injectable({providedIn: 'root'})\nexport class CryptoService {\n\n /**\n * Generate sign keypair, sugin scrypt, from a salt and a password\n *\n * @param salt\n * @param password\n * @param scryptParams\n */\n public scryptKeypair(salt: string, password: string, scryptParams?: CryptoSaltParams): Promise<KeyPair> {\n\n return new Promise((resolve) => {\n scrypt(password, salt, {\n N: scryptParams && scryptParams.N || nacl.constants.SCRYPT_PARAMS.DEFAULT.N,\n r: scryptParams && scryptParams.r || nacl.constants.SCRYPT_PARAMS.DEFAULT.r,\n p: scryptParams && scryptParams.p || nacl.constants.SCRYPT_PARAMS.DEFAULT.p,\n dkLen: nacl.constants.SEED_LENGTH,\n encoding: 'base64'\n }, function(derivedKey) {\n resolve(derivedKey);\n });\n })\n .then((seed) => {\n const byteseed = nacl.util.decodeBase64(seed);\n const signKeypair = nacl.sign.keyPair.fromSeed(byteseed);\n return {\n publicKey: signKeypair.publicKey,\n secretKey: signKeypair.secretKey\n };\n });\n }\n\n /**\n * Sign a message, from a key pair\n */\n public sign(message: string, keypair: KeyPair): Promise<string> {\n return new Promise((resolve) => {\n const m = nacl.util.decodeUTF8(message);\n const signedMsg = nacl.sign(m, keypair.secretKey);\n const sig = new Uint8Array(nacl.constants.crypto_sign_BYTES);\n for (let i = 0; i < sig.length; i++) sig[i] = signedMsg[i];\n const signature = nacl.util.encodeBase64(sig);\n resolve(signature);\n });\n }\n\n /**\n * Sign a message, from a key pair\n */\n public verify(message: string, signature: string, pubkey: string): Promise<boolean> {\n return new Promise((resolve) => {\n const m = nacl.util.decodeUTF8(message);\n const sig = nacl.util.decodeBase64(signature);\n const pub = Base58.decode(pubkey);\n const res = nacl.sign.detached.verify(m, sig, pub);\n resolve(res);\n });\n }\n\n /**\n * Hash (using SHA256) a message\n */\n sha256(message: string): string {\n return sha256().update(message).digest('hex');\n }\n\n /**\n * Hash (using SHA512) a message\n */\n sha512(message: string): string {\n return sha512().update(message).digest('hex');\n }\n\n encodeBase64(message: string): string {\n const m = nacl.util.decodeUTF8(message);\n return nacl.util.encodeBase64(m);\n }\n}\n","import { Moment } from 'moment';\nimport { isEmptyArray, isNil, isNilOrBlank, isNotNil, joinPropertiesPath } from '../../../shared/functions';\nimport { FilterFn } from '../../../shared/services/entity-service.class';\nimport { ObjectMap, ObjectMapEntry, PropertiesArray, PropertiesMap } from '../../../shared/types';\nimport { StoreObject } from '@apollo/client/core';\nimport { fromDateISOString, toDateISOString } from '../../../shared/dates';\n\n\nexport declare interface Cloneable<T> {\n clone(): T;\n}\n\nexport function entityToString(obj: Entity<any> | any, properties?: string[]): string | undefined {\n return obj && obj.id && joinPropertiesPath(obj, properties || ['name']) || undefined;\n}\n\nexport interface EntityAsObjectOptions {\n minify?: boolean;\n keepTypename?: boolean; // true by default\n keepLocalId?: boolean; // true by default\n}\n\nexport interface IEntity<T,\n ID = number,\n AO extends EntityAsObjectOptions = EntityAsObjectOptions,\n FO = any\n >\n extends Cloneable<T> {\n id: ID;\n updateDate: Moment;\n __typename: string;\n equals(other: T): boolean;\n clone(opts?: AO & FO): T;\n copy(target: T, opts?: AO & FO);\n asObject(opts?: AO): any;\n fromObject(source: any, opts?: FO);\n}\n\nexport declare interface ITreeItemEntity<\n T extends IEntity<T, ID>,\n ID = number\n > {\n parentId: ID;\n parent: T;\n children: T[];\n}\n\n//@dynamic\nexport abstract class Entity<\n T extends Entity<T, ID, AO, FO>,\n ID = number,\n AO extends EntityAsObjectOptions = EntityAsObjectOptions,\n FO = any>\n implements IEntity<T, ID, AO, FO> {\n\n // The GraphQL typename (injected by @EntityClass())\n static TYPENAME: string;\n\n id: ID = null;\n updateDate: Moment = null;\n __typename: string;\n\n constructor(__typename?: string) {\n this.__typename = __typename || null;\n }\n\n clone(opts?: AO & FO): T {\n const target = new (this.constructor as any)() as T;\n this.copy(target, opts);\n return target;\n }\n\n copy(target: T, opts?: AO & FO) {\n target.fromObject(this.asObject(opts), opts);\n }\n\n asObject(opts?: AO): StoreObject {\n const target: any = Object.assign({}, this); //= {...this};\n if (!opts || opts.keepTypename !== true) delete target.__typename;\n if (target.id == null || (opts && opts.keepLocalId === false && target.id < 0)) delete target.id;\n target.updateDate = toDateISOString(this.updateDate);\n return target;\n }\n\n fromObject(source: any, opts?: FO) {\n this.id = (source.id || source.id === 0) ? source.id : undefined;\n this.updateDate = fromDateISOString(source.updateDate);\n this.__typename = source.__typename || this.__typename; // Keep original type (can be set in constructor)\n }\n\n equals(other: T): boolean {\n return other && this.id === other.id;\n }\n}\n\n/**\n * @deprecated use standard instanceof instead\n * @param obj\n * @param constructor\n */\nexport function isInstanceOf<T>(obj: any, constructor: new (...args: any[]) => T): obj is T {\n if (!obj) return false;\n\n return obj instanceof constructor;\n}\n\n// @dynamic\nexport abstract class EntityUtils {\n\n // Check that the object has a NOT nil attribute (ID by default)\n static isEntity<T extends IEntity<any>>(obj: T|any): obj is T {\n return isNotNil(obj.__typename) && (typeof obj.fromObject === 'function') && (typeof obj.asObject === 'function');\n }\n\n // Check that the object has a NOT nil attribute (ID by default)\n static isNotEmpty<T extends IEntity<any> | any>(obj: T, checkedAttribute: keyof T): boolean {\n return !!obj && obj[checkedAttribute] !== null && obj[checkedAttribute] !== undefined;\n }\n\n static isEmpty<T extends IEntity<any> | any>(obj: T, checkedAttribute: keyof T): boolean {\n return !obj || obj[checkedAttribute] === null || obj[checkedAttribute] === undefined;\n }\n\n static equals<T extends IEntity<any> | any>(o1: T, o2: T, checkAttribute?: keyof T): boolean {\n checkAttribute = checkAttribute || 'id' as keyof T;\n return (o1 === o2) || (isNil(o1) && isNil(o2)) || (o1 && o2 && o1[checkAttribute] === o2[checkAttribute]);\n }\n\n static getPropertyByPath(obj: any | IEntity<any>, path: string): any {\n if (isNil(obj)) return undefined;\n const i = path.indexOf('.');\n if (i === -1) {\n return obj[path];\n }\n const key = path.substring(0, i);\n if (isNil(obj[key])) return undefined;\n if (obj[key] && typeof obj[key] === 'object') {\n return EntityUtils.getPropertyByPath(obj[key], path.substring(i + 1));\n }\n throw new Error(`Invalid form path: '${key}' is not an valid object.`);\n }\n\n static getArrayAsMap<T = any>(source?: ObjectMapEntry<T>[]): ObjectMap<T> {\n return (source || []).reduce((res, item) => {\n res[item.key] = item.value;\n return res;\n }, {});\n }\n\n static getMapAsArray<T = any>(source?: ObjectMap<T>): ObjectMapEntry<T>[] {\n if (Array.isArray(source)) return source;\n return Object.getOwnPropertyNames(source || {})\n .map(key => ({\n key,\n value: source[key]\n }));\n }\n\n static getPropertyArrayAsObject(source?: PropertiesArray): PropertiesMap {\n return (source || []).reduce((res, item) => {\n res[item.key] = item.value;\n return res;\n }, {});\n }\n\n static copyIdAndUpdateDate<T extends Entity<any, any, any>>(source: T, target: T) {\n if (!source) return;\n\n // Update (id and updateDate)\n target.id = isNotNil(source.id) ? source.id : target.id;\n target.updateDate = fromDateISOString(source.updateDate) || target.updateDate;\n\n // Update creation Date, if exists\n if (source['creationDate']) {\n target['creationDate'] = fromDateISOString(source['creationDate']);\n }\n }\n\n\n static async fillLocalIds<T extends IEntity<T>>(items: T[], sequenceFactory: (firstEntity: T, incrementSize: number) => Promise<number>) {\n const newItems = (items || []).filter(item => isNil(item.id) || item.id === 0);\n if (isEmptyArray(newItems)) return;\n // Get the sequence\n let currentId = await sequenceFactory(newItems[0], newItems.length) + 1;\n // Take the min (sequence, id), in case the sequence is corrupted\n currentId = items.filter(item => isNotNil(item.id) && item.id < 0).reduce((res, item) => Math.min(res, item.id), currentId);\n newItems.forEach(item => item.id = --currentId);\n }\n\n static cleanIdAndUpdateDate<T extends IEntity<T>>(source: T) {\n if (!source) return; // Skip\n source.id = null;\n source.updateDate = null;\n }\n\n static cleanIdsAndUpdateDates<T extends IEntity<T>>(items: T[]) {\n (items || []).forEach(EntityUtils.cleanIdAndUpdateDate);\n }\n\n static sort<T extends IEntity<T> | any>(data: T[], sortBy?: string, sortDirection?: string): T[] {\n if (!data || data.length <= 1 || !sortBy) return data;\n return data.sort(this.sortComparator(sortBy, sortDirection));\n }\n\n static sortComparator<T extends IEntity<T> | any>(sortBy?: string, sortDirection?: string): (a: T, b: T) => number {\n const after = (!sortDirection || sortDirection === 'asc') ? 1 : -1;\n const property = sortBy || 'id';\n return (a, b) => {\n const valueA = EntityUtils.getPropertyByPath(a, property);\n const valueB = EntityUtils.getPropertyByPath(b, property);\n return EntityUtils.compare(valueA, valueB, after);\n };\n }\n\n static compare<T extends IEntity<any>>(value1: T, value2: T, direction: 1 | -1, checkAttribute?: keyof T): number {\n checkAttribute = checkAttribute || 'id';\n if (EntityUtils.isNotEmpty(value1, checkAttribute) && EntityUtils.isNotEmpty(value2, checkAttribute)) {\n return EntityUtils.equals(value1, value2, checkAttribute) ? 0 : (value1[checkAttribute] > value2[checkAttribute] ? direction : (-1 * direction));\n }\n return value1 === value2 ? 0 : (value1 > value2 ? direction : (-1 * direction));\n }\n\n static compareValue<T>(value1: T, value2: T, direction: 1 | -1): number {\n return value1 === value2 ? 0 : (value1 > value2 ? direction : (-1 * direction));\n }\n\n static filter<T extends IEntity<T> | any>(data: T[],\n searchAttribute: string,\n searchText: string): T[] {\n const filterFn = this.searchTextFilter(searchAttribute, searchText);\n return data.filter(filterFn);\n }\n\n static searchTextFilter<T extends IEntity<T> | any>(searchAttribute: string | string[],\n searchText: string): FilterFn<T> {\n if (isNilOrBlank(searchAttribute) || isNilOrBlank(searchText)) return undefined; // filter not need\n\n const searchRegexp = searchText\n // Escape special characters\n .replace(/[-\\/\\\\^$+.()|[\\]{}]/g, '\\\\$&')\n // Interpret * as any text\n .replace(/[*]+/g, '.*')\n // Interpret ? as one character\n .replace(/[?]/g, '.');\n if (searchRegexp === '.*') return undefined; // filter not need\n\n const flags = 'i'; // don't use global regex search\n const asPrefixPattern = '^' + searchRegexp;\n const anyMatchPattern = '^.*' + searchRegexp;\n\n // Only one search attributes\n if (typeof searchAttribute === 'string') {\n const isSimplePath = !searchAttribute || searchAttribute.indexOf('.') === -1;\n const searchAsPrefix = searchAttribute.toLowerCase().endsWith('label') || searchAttribute.toLowerCase().endsWith('code');\n const regexp = new RegExp(searchAsPrefix && asPrefixPattern || anyMatchPattern, flags);\n if (isSimplePath) {\n return a => regexp.test( a[searchAttribute]);\n }\n else {\n return a => regexp.test(EntityUtils.getPropertyByPath(a, searchAttribute));\n }\n }\n\n // many search attributes\n else {\n const regexps = searchAttribute.map(path => {\n const searchAsPrefix = path.toLowerCase().endsWith('label') || path.toLowerCase().endsWith('code');\n return new RegExp( searchAsPrefix && asPrefixPattern || anyMatchPattern, flags);\n });\n return a => searchAttribute.findIndex((path, index) => regexps[index].test(EntityUtils.getPropertyByPath(a, path))) !== -1;\n }\n }\n\n /**\n * Transform a batch entity tree into a array list. This method keep links parent/children.\n *\n * Method used to find batch without id (e.g. before local storage)\n *\n * @param source\n */\n static treeToArray<T extends ITreeItemEntity<any>>(source: T): T[] {\n if (!source) return null;\n return (source.children || []).reduce((res, batch) => {\n batch.parent = source;\n return res.concat(this.treeToArray(batch)); // recursive call\n }, [source]);\n }\n\n static listOfTreeToArray<T extends ITreeItemEntity<any>>(sources: T[]): T[] {\n if (!sources || !sources.length) return null;\n return sources.reduce((res, source) => res.concat(this.treeToArray<T>(source)), []);\n }\n\n /**\n * Fill parent attribute, of all children found in the tree\n *\n * @param source\n */\n static treeFillParent<T extends ITreeItemEntity<any>>(source: T): T[] {\n if (!source) return null;\n (source.children || []).forEach(child => {\n child.parent = source;\n this.treeFillParent(child); // Loop\n });\n }\n\n static isLocal(entity: IEntity<any, any> | Entity<any, any>): boolean {\n return entity && (isNotNil(entity.id) && +entity.id < 0);\n }\n\n static isRemote(entity: IEntity<any, any> | Entity<any, any>): boolean {\n return entity && !EntityUtils.isLocal(entity);\n }\n\n static isLocalId(id: number): boolean {\n return isNotNil(id) && +id < 0;\n }\n\n static isRemoteId(id: number): boolean {\n return isNotNil(id) && +id >= 0;\n }\n\n}\n","// This file can be replaced during build by using the `fileReplacements` array.\n// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.\n// The list of file replacements can be found in `angular.json`.\n\nimport {Environment} from './environment.class';\n\nexport const environment: Environment = Object.freeze({\n name: '@sumaris-net/ngx-components', // overridden by ENVIRONMENT token\n version: undefined, // overridden by ENVIRONMENT token\n production: true, // let to true ! because used by packager\n baseUrl: '/',\n defaultLocale: 'fr',\n defaultLatLongFormat: 'DDMM',\n apolloFetchPolicy: 'cache-first',\n\n // FIXME: enable cache\n persistCache: false,\n\n // TODO: make this works\n //offline: true,\n\n peerMinVersion: '1.8.0',\n\n defaultPeers: [\n {\n host: 'localhost',\n port: 8080\n },\n {\n host: 'localhost',\n port: 8081\n },\n {\n host: '192.168.0.45',\n port: 8080\n },\n {\n host: '192.168.0.24',\n port: 8080\n },\n {\n host: '192.168.0.29',\n port: 8080\n },\n {\n host: 'sih.sfa.sc',\n port: 80\n },\n {\n host: 'test.sumaris.net',\n port: 443\n }\n ],\n defaultAppName: 'SUMARiS',\n defaultAndroidInstallUrl: 'https://play.google.com/store/apps/details?id=net.sumaris.app',\n\n // Storage\n storage: {\n driverOrder: ['sqlite', 'indexeddb', 'websql', 'localstorage']\n },\n\n // About\n sourceUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components',\n reportIssueUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/issues',\n forumUrl: 'https://forum.sumaris.net',\n helpUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/blob/master/user-manual/index_fr.md',\n\n // Development\n defaultAuthValues: {\n\n // Basic auth (using Person.username)\n // username: 'admq2', password: 'q22006'\n\n // Token auth (using Person.pubkey)\n username: 'admin@sumaris.net', password: 'admin',\n },\n\n account: {\n enableListenChanges: true,\n listenIntervalInSeconds: 60\n },\n\n entityEditor: {\n enableListenChanges: true,\n listenIntervalInSeconds: 60\n }\n});\n\n/*\n * In development mode, to ignore zone related error stack frames such as\n * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can\n * import the following file, but please comment it out in production mode\n * because it will have performance impact when throw error\n */\nimport 'zone.js/dist/zone-error';\n","import { environment } from '../../../../environments/environment';\nimport { Entity } from './entity.model';\nimport { removeEnd } from '../../../shared/functions';\n\ndeclare type Constructor = new(...args: any[]) => any;\n\nexport class EntityClasses {\n static CLASSES_BY_NAME = new Map<string, Constructor>();\n\n static register(typename: string, entityClass: Constructor) {\n // Convert to extract entityName\n const entityName = removeEnd(typename, 'VO');\n // DEBUG\n //console.debug('[entity-classes] Detected entity class ' + entityName);\n\n // Add to map\n EntityClasses.CLASSES_BY_NAME.set(entityName, entityClass);\n }\n\n static get<T extends Entity<T>>(entityName: string): Constructor {\n const entityClass = EntityClasses.CLASSES_BY_NAME.get(entityName);\n if (!entityClass) {\n throw new Error('Cannot found entity class \\'' + entityName + '\\'. Make sure it exists and has the @EntityClass decorator.');\n }\n return entityClass;\n }\n\n static fromObject<T extends Entity<T>>(value: any, opts?: {\n [key: string]: any;\n typename?: string;\n entityName?: string;\n }): T {\n if (!value) return value;\n const entityName = (opts && opts.entityName) || removeEnd(value.__typename || opts?.typename, 'VO');\n if (!entityName) throw new Error('Missing one of \\'value.__typename\\', \\'opts.entityName\\', or \\'opts.typename\\'.');\n const entityClass = EntityClasses.get(entityName) as any;\n if (typeof entityClass.fromObject !== 'function') {\n throw new Error('Cannot found the static function \\'' + entityName + '.fromObject()\\'. Make sure this function has been declared and the entity class has the @EntityClass decorator');\n }\n return entityClass.fromObject(value, opts) as T;\n }\n}\n\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function EntityClass(opts: {\n typename: string;\n fromObjectAlwaysNew?: boolean;\n fromObjectReuseStrategy?: 'default' | 'clone';\n}) {\n\n opts = {\n fromObjectReuseStrategy: 'default',\n ...opts\n };\n\n // eslint-disable-next-line prefer-arrow/prefer-arrow-functions\n return function <T extends Constructor>(constructor: T) {\n\n // Make sure the class extends Entity\n if (!environment.production) {\n const obj = new constructor();\n if (!(obj instanceof Entity)) {\n throw new Error(`Class ${constructor.name} must extends <<Entity>> to be able to use @FromObject!`);\n }\n }\n\n const typename = opts.typename || `${constructor.name}VO`;\n\n if (opts.fromObjectReuseStrategy === 'clone') {\n const decoratedClass = class extends constructor {\n static TYPENAME = typename;\n static fromObject(source: any, opts?: any): T {\n if (!source) return undefined;\n if (source instanceof decoratedClass) return (source as any).clone(opts) as T;\n const target: any = new decoratedClass();\n target.fromObject(source, opts);\n return target as T;\n }\n static asObject(source: any, opts?: any): any {\n if (!source) return undefined;\n if (source instanceof decoratedClass) return source.asObject(opts);\n return Object.assign({}, source);\n }\n };\n\n // Register the entity class\n EntityClasses.register(typename, decoratedClass);\n\n return decoratedClass;\n }\n\n const decoratedClass = class extends constructor {\n static TYPENAME = typename;\n static fromObject(source: any, opts?: any): T {\n if (!source) return undefined;\n if (source instanceof decoratedClass) {\n // DEBUG\n //console.debug('@EntityClass() fromObject() => will recycle existing object: ', source);\n return source as T;\n }\n const target: any = new decoratedClass();\n target.fromObject(source, opts);\n return target as T;\n }\n static asObject(source: any, opts?: any): any {\n if (!source) return undefined;\n if (source instanceof decoratedClass) {\n return source.asObject(opts);\n }\n // DEBUG\n //console.debug('@EntityClass() asObject() => will recycle existing object: ', source);\n return source;\n }\n };\n\n // Register the entity class\n EntityClasses.register(typename, decoratedClass);\n\n return decoratedClass;\n };\n}\n","/* -- Network -- */\n\nimport {isNilOrBlank, isNotNil, isNotNilOrBlank, noTrailingSlash} from '../../../shared/functions';\nimport {Cloneable, Entity, EntityAsObjectOptions} from './entity.model';\nimport {EntityClass} from './entity.decorators';\n\n// @dynamic\n@EntityClass({typename: 'PeerVO'})\nexport class Peer extends Entity<Peer> implements Cloneable<Peer> {\n\n static fromObject: (source: any, opts?: any) => Peer;\n\n static parseUrl(peerUrl: string) {\n const url = new URL(peerUrl);\n return Peer.fromObject({\n dns: url.hostname,\n port: isNilOrBlank(url.port) ? undefined : url.port,\n useSsl: url.protocol && (url.protocol.startsWith('https') || url.protocol.startsWith('wss')),\n path: noTrailingSlash(url.pathname)\n });\n }\n static path(peer: Peer, ...paths: string[]): string {\n if (!peer) throw new Error('Missing required argument \\'peer\\'!');\n // Remove starting slashes\n paths = (paths || []).map(path => {\n if (path.startsWith('./')) return path.substring(2);\n if (path.startsWith('/')) return path.substring(1);\n return path;\n }).filter(isNotNilOrBlank);\n return [noTrailingSlash(Peer.fromObject(peer).url)].concat(...paths).join('/');\n }\n\n dns: string;\n ipv4: string;\n ipv6: string;\n port: number;\n useSsl: boolean;\n pubkey: string;\n path?: string;\n\n favicon: string;\n status: 'UP' | 'DOWN';\n softwareName: string;\n softwareVersion: string;\n label: string;\n name: string;\n\n constructor() {\n super(Peer.TYPENAME);\n }\n\n asObject(options?: EntityAsObjectOptions): any {\n return super.asObject(options);\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.dns = source.dns || source.host;\n this.ipv4 = source.ipv4;\n this.ipv6 = source.ipv6;\n this.port = isNotNil(source.port) ? +source.port : undefined;\n this.pubkey = source.pubkey;\n this.useSsl = source.useSsl || (this.port === 443);\n this.path = source.path || '';\n }\n\n equals(other: Peer): boolean {\n return super.equals(other) && this.pubkey === other.pubkey && this.url === other.url;\n }\n\n /**\n * Return the peer URL (without trailing slash)\n */\n get url(): string {\n return (this.useSsl ? 'https://' : 'http://') + this.hostAndPort + (this.path || '');\n }\n\n get hostAndPort(): string {\n return (this.dns || this.ipv4 || this.ipv6) +\n ((this.port && this.port !== 80 && this.port !== 443) ? ':' + this.port : '');\n }\n\n get reachable(): boolean {\n return this.status && this.status === 'UP';\n }\n}\n","import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';\n\nexport class HttpUtils {\n static async getText(http: HttpClient,\n uri: string,\n opts?: {\n nocache?: boolean;\n headers?: HttpHeaders | {\n [header: string]: string | string[];\n };\n params?: HttpParams | {\n [param: string]: string | string[];\n };\n reportProgress?: boolean;\n responseType?: 'text';\n withCredentials?: boolean;\n }): Promise<string> {\n\n // Add headers\n opts = opts || {responseType: 'text'};\n\n // Force no cache\n if (opts.nocache === true) {\n opts.headers = (opts.headers instanceof HttpHeaders ? opts.headers : new HttpHeaders(opts.headers));\n opts.headers\n .append('Cache-Control', 'no-cache')\n .append('Pragma', 'no-cache');\n }\n\n // Use web http client\n try {\n return (await http.get(uri, {...opts, responseType: 'text'}).toPromise());\n }\n catch (err) {\n if (err && err.message) {\n console.error(`[network] Error on get request ${uri}: ${err.message}`, err);\n }\n else {\n console.error(`[network] Error on get request ${uri}: ${err && err.statusText} - ${JSON.stringify(err)}`);\n }\n throw {code: err.status, message: 'ERROR.UNKNOWN_NETWORK_ERROR'};\n }\n }\n\n static async getJson<T>(http: HttpClient,\n uri: string,\n opts?: {\n nocache?: boolean;\n headers?: HttpHeaders | {\n [header: string]: string | string[];\n };\n params?: HttpParams | {\n [param: string]: string | string[];\n };\n reportProgress?: boolean;\n responseType?: 'json';\n withCredentials?: boolean;\n }): Promise<T> {\n\n // Add headers\n opts = opts || {};\n\n // Force no cache\n if (opts.nocache === true) {\n opts.headers = (opts.headers instanceof HttpHeaders ? opts.headers : new HttpHeaders(opts.headers));\n opts.headers\n .append('Cache-Control', 'no-cache')\n .append('Pragma', 'no-cache');\n }\n\n // Use web http client\n try {\n return (await http.get(uri, {...opts, responseType: 'json'}).toPromise()) as T;\n }\n catch (err) {\n if (err && err.message) {\n console.error(`[network] Error on get request ${uri}: ${err.message}`, err);\n }\n else {\n console.error(`[network] Error on get request ${uri}: ${err && err.statusText} - ${JSON.stringify(err)}`);\n }\n throw {code: err.status, message: 'ERROR.UNKNOWN_NETWORK_ERROR'};\n }\n }\n}\n\n\n\n","import {HttpClient, HttpHeaders} from '@angular/common/http';\nimport {HttpUtils} from '../../shared/http/http.utils';\nimport {Peer} from './model/peer.model';\n\nexport interface NodeInfo {\n softwareName: string;\n softwareVersion: string;\n nodeLabel?: string;\n nodeName?: string;\n}\n\nexport interface AppManifest {\n // mandatory\n manifest_version: number;\n name: string;\n version: string;\n\n // App start (required by platform service)\n start_url: string;\n\n // optional\n short_name?: string;\n description?: string;\n version_name?: string;\n author?: string;\n default_locale?: string;\n\n // optional UI\n icons?: any | any[];\n background_color?: string;\n theme_color?: string;\n display?: string;\n}\n\n\nexport class NetworkUtils {\n static getNodeInfo = getNodeInfo;\n}\n\nexport async function getNodeInfo(\n http: HttpClient,\n peer: string|Peer,\n opts?: {\n headers?: HttpHeaders | {\n [header: string]: string | string[];\n };\n responseType?: 'json'\n }): Promise<NodeInfo> {\n\n if (!peer) throw Error('Missing argument \\'peer\\'.');\n\n let peerUrl = (peer instanceof Peer) ? peer.url : (peer as string);\n // Remove trailing slash\n if (peerUrl.endsWith('/')) {\n peerUrl = peerUrl.substr(0, peerUrl.length -1);\n }\n\n return HttpUtils.getJson(http, peerUrl + '/api/node/info', opts);\n}\n","\nconst regexp = {\n POSITIVE_INTEGER: /^\\d+$/,\n VERSION_PART_REGEXP: /^[0-9]+|alpha[0-9]+|beta[0-9]+|rc[0-9]+|[0-9]+-SNAPSHOT$/\n};\n\n\nexport class VersionUtils {\n static compare = compareVersionNumbers;\n static isCompatible = isVersionCompatible;\n static isSame = isSameVersion;\n}\n\n/**\n * Compare two software version numbers (e.g. 1.7.1)\n * Returns:\n *\n * 0 if they're identical\n * negative if v1 < v2\n * positive if v1 > v2\n * Nan if they in the wrong format\n *\n * E.g.:\n *\n * assert(version_number_compare(\"1.7.1\", \"1.6.10\") > 0);\n * assert(version_number_compare(\"1.7.1\", \"1.7.10\") < 0);\n *\n * \"Unit tests\": http://jsfiddle.net/ripper234/Xv9WL/28/\n *\n * Taken from http://stackoverflow.com/a/6832721/11236\n */\n export function compareVersionNumbers(v1, v2){\n const v1parts = v1.split('.');\n const v2parts = v2.split('.');\n\n // First, validate both numbers are true version numbers\n\n if (!validateParts(v1parts) || !validateParts(v2parts)) {\n return NaN;\n }\n\n for (let i = 0; i < v1parts.length; ++i) {\n if (v2parts.length === i) {\n return 1;\n }\n\n if (v1parts[i] === v2parts[i]) {\n continue;\n }\n if (v1parts[i] > v2parts[i]) {\n return 1;\n }\n return -1;\n }\n\n if (v1parts.length != v2parts.length) {\n return -1;\n }\n\n return 0;\n}\n\nfunction validateParts(parts) {\n for (let i = 0; i < parts.length; i++) {\n let isNumber = regexp.POSITIVE_INTEGER.test(parts[i]);\n // First part MUST be an integer\n if (i === 0 && !isNumber) return false;\n // If not integer, should be 'alpha', 'beta', etc.\n if (!isNumber) {\n if (!regexp.VERSION_PART_REGEXP.test(parts[i])) return false;\n // Remove '-SNAPSHOT', as it should never be in prod\n parts[i] = parts[i].replace('-SNAPSHOT', '');\n // Check again if numeric\n isNumber = regexp.POSITIVE_INTEGER.test(parts[i]);\n }\n\n // Convert string to int (need by compare operators)\n if (isNumber) parts[i] = parseInt(parts[i]);\n }\n return true;\n}\n\nexport function isVersionCompatible(minVersion, actualVersion): boolean {\n // DEV ONLY\n //console.debug(`[http] Checking actual version {${actualVersion}} is compatible with min expected version {${minVersion}}`);\n return compareVersionNumbers(minVersion, actualVersion) <= 0;\n}\n\nexport function isSameVersion(v1, v2): boolean {\n return compareVersionNumbers(v1, v2) === 0;\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n Input,\n OnDestroy,\n EventEmitter,\n Output,\n Inject\n} from '@angular/core';\nimport {ModalController} from '@ionic/angular';\nimport {Peer} from '../services/model/peer.model';\nimport {Observable, Subject, Subscription} from 'rxjs';\nimport {fadeInAnimation} from '../../shared/material/material.animations';\nimport {HttpClient} from '@angular/common/http';\nimport {NetworkUtils, NodeInfo} from '../services/network.utils';\nimport {VersionUtils} from '../../shared/version/versions';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\n\n@Component({\n selector: 'select-peer-modal',\n templateUrl: 'select-peer.modal.html',\n styleUrls: [ './select-peer.modal.scss' ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [fadeInAnimation]\n})\nexport class SelectPeerModal implements OnDestroy {\n\n private _subscription = new Subscription();\n loading = true;\n $peers = new Subject<Peer[]>();\n peerMinVersion = this.environment.peerMinVersion;\n\n @Input() canCancel = true;\n @Input() allowSelectDownPeer = true;\n @Input() onRefresh = new EventEmitter<UIEvent>();\n\n constructor(\n\n private viewCtrl: ModalController,\n private cd: ChangeDetectorRef,\n private http: HttpClient,\n @Inject(ENVIRONMENT) protected environment\n ) {\n }\n\n set peers(peers: Observable<Peer[]>) {\n this._subscription.add(\n peers.subscribe(res => this.refreshPeers(res))\n );\n }\n\n cancel() {\n this.viewCtrl.dismiss();\n }\n\n ngOnDestroy(): void {\n this._subscription.unsubscribe();\n }\n\n selectPeer(peer: Peer) {\n if (this.allowSelectDownPeer || (peer.reachable && this.isCompatible(peer))) {\n console.debug(`[select-peer-modal] Selected peer: {url: '${peer.url}'}`);\n this.viewCtrl.dismiss(peer);\n }\n }\n\n\n /**\n * Check the min pod version, defined by the app\n *\n * @param peer\n */\n isCompatible(peer: Peer): boolean {\n return !this.peerMinVersion || (peer && peer.softwareVersion && VersionUtils.isCompatible(this.peerMinVersion, peer.softwareVersion));\n }\n\n refresh(event: UIEvent) {\n this.loading = true;\n this.onRefresh.emit(event);\n }\n\n /* -- protected methods -- */\n\n async refreshPeers(peers: Peer[]) {\n peers = peers || [];\n\n const data: Peer[] = [];\n const jobs = Promise.all(\n peers.map(async (peer) => {\n await this.refreshPeer(peer);\n\n if (this._subscription.closed) return; // component destroyed\n\n data.push(peer);\n\n // Sort (by reachable, then host)\n data.sort((a, b) => {\n if (a.reachable && !b.reachable) return -1;\n if (!a.reachable && b.reachable) return 1;\n if (a.hostAndPort < b.hostAndPort) return -1;\n if (a.hostAndPort > b.hostAndPort) return 1;\n return 0;\n });\n\n this.$peers.next(data);\n return peer;\n }));\n\n this._subscription.add(\n this.$peers\n .subscribe(() => this.cd.markForCheck())\n );\n\n try {\n await jobs;\n }\n catch(err) {\n if (!this._subscription.closed) console.error(err);\n }\n this.loading = false;\n this.cd.markForCheck();\n }\n\n protected async refreshPeer(peer: Peer): Promise<Peer> {\n try {\n const summary: NodeInfo = await NetworkUtils.getNodeInfo(this.http, peer.url);\n peer.status = 'UP';\n peer.softwareName = summary.softwareName;\n peer.softwareVersion = summary.softwareVersion;\n peer.label = summary.nodeLabel;\n peer.name = summary.nodeName;\n } catch (err) {\n if (!this._subscription.closed) {\n if (err && err.message) {\n console.error('[select-peer] ' + err.message, err);\n }\n }\n peer.status = 'DOWN';\n }\n return peer;\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n","import {EventEmitter, Inject, Injectable, InjectionToken, Optional} from '@angular/core';\nimport {LocalSettings, OfflineFeature, UsageMode} from './model/settings.model';\nimport {Peer} from './model/peer.model';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Storage} from '@ionic/storage';\n\nimport {equals, getPropertyByPath, isEmptyArray, isNil, isNotEmptyArray, isNotNil, isNotNilOrBlank} from '../../shared/functions';\nimport {Subject} from 'rxjs';\nimport {Platform} from '@ionic/angular';\nimport {FormFieldDefinition, FormFieldDefinitionMap} from '../../shared/form/field.model';\nimport * as momentImported from 'moment';\nimport {Moment} from 'moment';\nimport {debounceTime, filter} from 'rxjs/operators';\nimport {LatLongPattern} from '../../shared/material/latlong/latlong.utils';\nimport {Environment, ENVIRONMENT} from '../../../environments/environment.class';\nimport {environment} from '../../../environments/environment';\nimport {fromDateISOString} from '../../shared/dates';\nimport {HistoryPageReference} from './model/history.model';\nimport {StartableService} from '../../shared/services/startable-service.class';\nimport {isAndroid, isCordova, isIOS, isMobile} from '../../shared/platforms';\n\nconst moment = momentImported;\n\nexport const SETTINGS_STORAGE_KEY = 'settings';\nexport const SETTINGS_TRANSIENT_PROPERTIES = ['mobile', 'touchUi'/*deprecated*/];\n\n// fixme: this constant points to static environment\nconst DEFAULT_SETTINGS: LocalSettings = {\n accountInheritance: true,\n locale: environment.defaultLocale,\n latLongFormat: environment.defaultLatLongFormat || 'DDMM',\n pageHistoryMaxSize: 3\n};\n\nexport const APP_LOCAL_SETTINGS = new InjectionToken<Partial<LocalSettings>>('DefaultLocalSettings');\nexport const APP_LOCAL_SETTINGS_OPTIONS = new InjectionToken<FormFieldDefinitionMap>('LocalSettingsOptions');\n\nexport declare interface AddToPageHistoryOptions {\n removePathQueryParams?: boolean;\n removeTitleSmallTag?: boolean;\n emitEvent?: boolean;\n}\n\n@Injectable({\n providedIn: 'root'\n //deps: [APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS]\n})\nexport class LocalSettingsService extends StartableService<LocalSettings> {\n\n onChange = new Subject<LocalSettings>();\n\n private readonly _optionDefs: FormFieldDefinition[];\n private _$persist: EventEmitter<any>;\n\n get settings(): LocalSettings {\n return this._data || this.defaultSettings;\n }\n\n get locale(): string {\n return this._data && this._data.locale || this.translate.currentLang || this.translate.defaultLang;\n }\n\n get latLongFormat(): LatLongPattern {\n return this._data && this._data.latLongFormat || 'DDMM';\n }\n\n get usageMode(): UsageMode {\n if (isNil(this._data?.usageMode)) {\n console.warn(\"[settings] Accessing to property 'usageMode' BEFORE service started! Please use ready()\");\n return isCordova(window) ? 'FIELD' : 'DESK';\n }\n return this._data.usageMode;\n }\n\n get mobile(): boolean {\n if (isNil(this._data?.mobile)) {\n console.warn(\"[settings] Accessing to property 'mobile' BEFORE service started! Please use ready()\");\n this._data.mobile = isMobile(window);\n }\n return this._data.mobile;\n }\n\n set mobile(value: boolean) {\n this._data.mobile = value;\n }\n\n get pageHistory(): HistoryPageReference[] {\n return (this._data && this._data.pageHistory || []);\n }\n\n constructor(\n private translate: TranslateService,\n private platform: Platform,\n private storage: Storage,\n @Inject(ENVIRONMENT) protected readonly environment: Environment,\n @Optional() @Inject(APP_LOCAL_SETTINGS) private readonly defaultSettings: LocalSettings,\n @Optional() @Inject(APP_LOCAL_SETTINGS_OPTIONS) defaultOptionsMap: FormFieldDefinitionMap\n ) {\n super(platform);\n this.defaultSettings = {...DEFAULT_SETTINGS, ...this.defaultSettings};\n\n this._optionDefs = Object.values(defaultOptionsMap);\n\n this.resetData();\n\n this._debug = !environment.production;\n if (this._debug) console.debug('[settings] Creating service');\n }\n\n ngOnStart(): Promise<LocalSettings> {\n\n console.info('[settings] Starting service...');\n\n // Restoring local settings\n this._data.mobile = isNotNil(this._data.mobile) ? this._data.mobile : (isCordova(window) || isMobile(window));\n this._data.usageMode = (isAndroid(window) || isIOS(window)) ? 'FIELD' : 'DESK'; // FIELD by default if Android or iOS\n\n // Restoring local settings\n return this.restoreLocally();\n }\n\n isUsageMode(mode: UsageMode): boolean {\n return this.usageMode === mode;\n }\n\n isOnFieldMode(value?: UsageMode): boolean {\n return (value || this.usageMode) === 'FIELD';\n }\n\n async restoreLocally(): Promise<LocalSettings | undefined> {\n let data = this._data || <LocalSettings>{};\n\n // Restore from storage\n const settingsStr = await this.storage.get(SETTINGS_STORAGE_KEY);\n\n // Restore local settings (or keep old settings)\n if (isNotNilOrBlank(settingsStr)) {\n console.info('[settings] Restoring previous settings...');\n\n const restoredData = JSON.parse(settingsStr);\n\n // Avoid to override transient properties\n SETTINGS_TRANSIENT_PROPERTIES.forEach(transientKey => {\n delete restoredData[transientKey];\n });\n\n // Merge into existing data\n data = Object.assign(data, restoredData);\n }\n\n // Emit event\n this.onChange.next(data);\n\n return data;\n }\n\n setProperty<T = string>(keyOrDef: string|FormFieldDefinition, value: T){\n if (!this._data || !keyOrDef) return;\n if (typeof keyOrDef === 'object') {\n this.setProperty(keyOrDef.key, value);\n return;\n }\n this._data.properties = this._data.properties || {};\n this._data.properties[keyOrDef] = isNil(value) ? undefined : value.toString();\n }\n\n getProperty(keyOrDef: string|FormFieldDefinition, defaultValue?: any): any {\n if (typeof keyOrDef === 'object') {\n return this.getProperty(keyOrDef.key, isNil(defaultValue) ? keyOrDef.defaultValue : defaultValue);\n }\n const value = this._data && this._data.properties && this._data.properties[keyOrDef];\n return isNotNil(value) ? value : defaultValue;\n }\n\n getPropertyAsBoolean(definition: FormFieldDefinition, defaultValue?: boolean): boolean {\n const value = this.getProperty(definition, defaultValue);\n return isNotNil(value) ? (value && value !== 'false') : undefined;\n }\n\n getPropertyAsInt(definition: FormFieldDefinition, defaultValue?: number): number {\n const value = this.getProperty(definition, defaultValue);\n return isNotNil(value) ? parseInt(value) : undefined;\n }\n\n getPropertyAsNumbers(definition: FormFieldDefinition, defaultValue?: number[]): number[] {\n const value = this.getProperty(definition, defaultValue);\n if (typeof value === 'string') return value.split(',').map(parseFloat) || undefined;\n return isNotNil(value) ? [parseFloat(value)] : undefined;\n }\n\n getPropertyAsStrings(definition: FormFieldDefinition, defaultValue?: string[]): string[] {\n const value = this.getProperty(definition, defaultValue);\n return value && value.split(',') || undefined;\n }\n\n async apply(settings: Partial<LocalSettings>, opts?: { emitEvent?: boolean; persistImmediate?: boolean }) {\n if (!this.started) await this.ready();\n\n const data = { ...this._data, ...settings};\n\n if (equals(data, this._data)) return; // Skip if no changes\n\n this._data = data;\n\n // Save locally\n if (opts && opts.persistImmediate) {\n await this.persistLocally(true);\n }\n else {\n this.persistLocally(); // No AWAIT\n }\n\n // Emit event\n if (!opts || opts.emitEvent !== false) {\n this.onChange.next(this._data);\n }\n }\n\n async applyProperty(key: keyof LocalSettings, value: any, opts?: { emitEvent?: boolean; persistImmediate?: boolean }) {\n const changes = {};\n changes[key] = value;\n await this.apply(changes, opts);\n }\n\n getPageSettings<T = any>(pageId: string, propertyName?: string): T {\n if (!this._data || !this._data.pages) return undefined;\n const key = pageId.replace(/[/]/g, '__');\n if (isNotNilOrBlank(propertyName)) {\n return getPropertyByPath(this._data.pages, key + '.' + propertyName);\n }\n return this._data.pages[key];\n }\n\n async savePageSetting(pageId: string, value: any, propertyName?: string) {\n this._data = this._data || this.defaultSettings;\n this._data.pages = this._data.pages || {};\n\n const key = pageId.replace(/[/]/g, '__');\n if (propertyName) {\n this._data.pages[key] = this._data.pages[key] || {};\n this._data.pages[key][propertyName] = value;\n }\n else {\n this._data.pages[key] = value;\n }\n\n // Update local settings\n this.persistLocally();\n }\n\n\n getOfflineFeature(featureName: string): OfflineFeature {\n if (!this._data || !this._data.offlineFeatures || isEmptyArray(this._data.offlineFeatures))\n return undefined;\n if (!featureName) throw Error('Missing \\'featureName\\' argument');\n\n featureName = featureName.toLowerCase();\n const featurePrefix = featureName + '#';\n const feature = this._data.offlineFeatures.find(f => {\n if (typeof f === 'string') return f.toLowerCase().startsWith(featurePrefix);\n if (f && typeof f === 'object' && f.name) return f.name === featureName;\n return false;\n });\n if (!feature) return; // Not found\n if (typeof feature === 'string') {\n const lastSyncDate = feature.substring(featurePrefix.length);\n console.debug(`[${featureName}] Last synchronization date: ${lastSyncDate}`);\n return {\n name: featureName,\n lastSyncDate\n };\n }\n return feature;\n }\n\n getOfflineFeatureLastSyncDate(featureName: string): Moment {\n const feature = this.getOfflineFeature(featureName);\n return feature && fromDateISOString(feature.lastSyncDate);\n }\n\n hasOfflineFeature(featureName?: string): boolean {\n if (featureName) return isNotNil(this.getOfflineFeature(featureName));\n return this._data && isNotEmptyArray(this._data.offlineFeatures);\n }\n\n saveOfflineFeature(feature: OfflineFeature) {\n this._data = this._data || this.defaultSettings;\n this._data.offlineFeatures = this._data.offlineFeatures || [];\n\n feature.name = feature.name.toLowerCase();\n\n const featurePrefix = feature.name + '#';\n const existingIndex = this._data.offlineFeatures.findIndex(f => {\n if (typeof f === 'string') return f.toLowerCase().startsWith(featurePrefix);\n if (f && typeof f === 'object' && f.name) return f.name === feature.name;\n return false;\n });\n if (existingIndex !== -1) {\n this._data.offlineFeatures[existingIndex] = feature;\n }\n else {\n this._data.offlineFeatures.push(feature);\n }\n\n // Update local settings\n this.persistLocally();\n }\n\n markOfflineFeatureAsSync(featureName: string) {\n let feature = this.getOfflineFeature(featureName);\n\n if (!feature) {\n feature = <OfflineFeature>{\n name: featureName.toLowerCase(),\n lastSyncDate: moment().toISOString()\n };\n }\n else {\n feature.lastSyncDate = moment().toISOString();\n }\n\n this.saveOfflineFeature(feature);\n }\n\n removeOfflineFeatures() {\n if (this._data && this._data.offlineFeatures) {\n this._data.offlineFeatures = [];\n\n // Update local settings\n this.persistLocally();\n }\n }\n\n getFieldDisplayAttributes(fieldName: string, defaultAttributes?: string[]): string[] {\n const value = this._data && this._data.properties && this._data.properties[`sumaris.field.${fieldName}.attributes`];\n // Nothing found in settings: return defaults\n if (!value) return defaultAttributes || ['label', 'name'];\n\n return value.split(',');\n }\n\n getPageFieldDefaultValue(pageId: string, fieldName: string): any {\n return this.getPageSettings(pageId, `field.${fieldName}.defaultValue`);\n }\n\n get optionDefs(): FormFieldDefinition[] {\n return this._optionDefs;\n }\n\n registerOption(def: FormFieldDefinition) {\n if (this._optionDefs.findIndex(f => f.key === def.key) !== -1) {\n throw new Error(`Additional additional property {${def.key}} already define.`);\n }\n if (this._debug) console.debug(`[settings] Adding additional property {${def.key}}`, def);\n this._optionDefs.push(def);\n }\n\n registerOptions(defs: FormFieldDefinition[]) {\n (defs || []).forEach(def => this.registerOption(def));\n }\n\n async addToPageHistory(page: HistoryPageReference,\n opts?: AddToPageHistoryOptions,\n pageHistory?: HistoryPageReference[] // used for recursive call to children\n ) {\n // If not inside recursive call: fill page history defaults\n if (!pageHistory) this.fillPageHistoryDefaults(page, opts);\n\n pageHistory = pageHistory || this._data.pageHistory;\n\n const index = pageHistory.findIndex(p => (\n // same path\n p.path === page.path\n // or sub-path\n || page.path.startsWith(p.path + '/'))\n );\n\n // New page: insert it\n if (index === -1) {\n //if (this._debug)\n console.debug('[settings] Adding page to history: ', page);\n\n // Prepend to list\n pageHistory.splice(0, 0, page);\n }\n\n else {\n const existingPage = pageHistory[index];\n\n // Same path: replace existing page\n if (pageHistory[index].path === page.path) {\n //if (this._debug)\n console.debug('[settings] Updating existing page in history: ', page);\n pageHistory.splice(index, 1);\n\n // Copy exiting children\n page.children = existingPage.children || [];\n\n // Prepend to list\n pageHistory.splice(0, 0, page);\n }\n\n // Not same path (should be a parent page)\n else {\n // Create parent's children array, if not exists\n existingPage.children = existingPage.children || [];\n\n // Update the parent time\n existingPage.time = page.time;\n\n // Add page as parent's children (recursive call)\n await this.addToPageHistory(page, opts, existingPage.children);\n }\n }\n\n // Save locally (only if not a recursive execution)\n if (pageHistory === this._data.pageHistory) {\n\n // If max has been reached, remove old pages\n if (this._data.pageHistory.length > this._data.pageHistoryMaxSize) {\n const removedPages = pageHistory.splice(this._data.pageHistoryMaxSize, pageHistory.length - this._data.pageHistoryMaxSize);\n console.debug('[settings] Pages removed from history: ', removedPages);\n }\n\n // Apply new value\n await this.applyProperty('pageHistory', pageHistory);\n }\n }\n\n async removePageHistory(path: string,\n opts?: {emitEvent?: boolean },\n pageHistory?: HistoryPageReference[] // used for recursive call to children)\n ) {\n pageHistory = pageHistory || this._data.pageHistory;\n\n const index = pageHistory.findIndex(p => p.path === path);\n let found = index !== -1;\n if (found) {\n console.debug('[settings] Remove page history: ', path);\n // Remove value\n pageHistory.splice(index, 1);\n }\n else {\n // Search path on children (stop when found)\n found = pageHistory\n .map(p => p.children)\n .filter(isNotEmptyArray)\n .findIndex(children => this.removePageHistory(path, opts, children)) !== -1;\n }\n\n // Save locally (only if not a recursive execution)\n if (found && pageHistory === this._data.pageHistory) {\n // Apply changes\n await this.applyProperty('pageHistory', this._data.pageHistory);\n }\n\n return found;\n }\n\n async clearPageHistory() {\n // Reset all page history\n await this.applyProperty('pageHistory', [], {persistImmediate: true});\n }\n\n /* -- Protected methods -- */\n\n private resetData() {\n this._data = {...this._data, ...this.defaultSettings};\n\n this._data.locale = this.translate.currentLang || this.translate.defaultLang;\n this._data.mobile = undefined;\n this._data.usageMode = undefined;\n this._data.pageHistory = [];\n\n const defaultPeer = this.environment.defaultPeer && Peer.fromObject(this.environment.defaultPeer);\n this._data.peerUrl = defaultPeer && defaultPeer.url || undefined;\n\n if (this.started) this.onChange.next(this._data);\n }\n\n private persistLocally(immediate?: boolean): Promise<any> {\n\n // Execute immediate\n if (immediate) {\n if (!this._data) {\n console.debug('[settings] Removing local settings from storage');\n return this.storage.remove(SETTINGS_STORAGE_KEY);\n }\n else {\n console.debug('[settings] Store local settings', this._data);\n return this.storage.set(SETTINGS_STORAGE_KEY, JSON.stringify(this._data));\n }\n }\n\n // Execute with delay\n else {\n\n // Create the event emitter\n if (!this._$persist) {\n this._$persist = new EventEmitter<any>(true);\n this._$persist\n .pipe(\n debounceTime(2000), // add a delay of 2s\n filter(() => this.started)\n )\n .subscribe(() => this.persistLocally(true));\n }\n\n this._$persist.emit();\n }\n }\n\n private fillPageHistoryDefaults(page: HistoryPageReference, opts?: {\n removePathQueryParams?: boolean;\n removeTitleSmallTag?: boolean;\n }): HistoryPageReference {\n if (!page || !page.title || !page.path) throw Error('Missing required argument \\'page\\', \\'page.path\\' or \\'page.title\\'');\n\n // Set time\n page.time = page.time || moment();\n\n // Clean the title (remove <small> tags)\n if (!opts || opts.removeTitleSmallTag !== false) {\n const tagIndex = page.title.indexOf('</small>');\n if (tagIndex !== -1) {\n page.title = page.title.substring(tagIndex + '</small>'.length);\n }\n page.title = page.title.replace(/[ ]*class='hidden-xs hidden-sm'/g, '');\n }\n\n // Remove query params\n if (!opts || opts.removePathQueryParams !== false) {\n page.path = page.path.replace(/[?].*$/, '');\n }\n\n return page;\n }\n}\n","import {createAnimation, IonicSafeString, ToastController} from '@ionic/angular';\nimport {TranslateService} from '@ngx-translate/core';\nimport {OverlayEventDetail, ToastOptions} from '@ionic/core';\nimport {ToastButton} from '@ionic/core/dist/types/components/toast/toast-interface';\nimport {isEmptyArray, isNotNil} from '../functions';\n\nconst TOAST_MAX_HEIGHT_PX = 75;\nconst TOAST_MAX_STACK_SIZE = 4;\n\nexport declare interface ShowToastOptions extends ToastOptions {\n type?: 'error'|'warning'|'info';\n messageParams?: any;\n showCloseButton?: boolean;\n onWillPresent?: (toast: HTMLIonToastElement) => void;\n}\n\nexport class Toasts {\n static counter = 0;\n static stackSize = 0;\n\n static async show<T = any>(\n toastController: ToastController,\n translate: TranslateService,\n opts: ShowToastOptions\n ): Promise<OverlayEventDetail<T>> {\n if (!toastController || !translate) {\n console.error('Missing required argument \\'toastController\\' or \\'translate\\'');\n if (opts.message instanceof IonicSafeString) console.info('[toasts] message: ' + (translate && translate.instant(opts.message.value) || opts.message.value));\n else if (typeof opts.message === 'string') console.info('[toasts] message: ' + (translate && translate.instant(opts.message, opts.messageParams) || opts.message));\n return Promise.resolve({});\n }\n\n this.counter++; // Increment toast counter\n let currentOffset = this.stackSize;\n if (this.stackSize < TOAST_MAX_STACK_SIZE) {\n this.stackSize++; // Increment stack offset\n }\n else {\n this.stackSize = 1; // Reset the stack\n currentOffset = 0;\n }\n const updateCounters = () => {\n // Decrease counter\n this.counter--;\n // If all toast closed: reset the stack offset\n if (this.counter === 0) {\n this.stackSize = 0;\n }\n // If current toast is the last one, decrease the offset\n else if (this.stackSize == currentOffset + 1){\n this.stackSize--;\n }\n };\n\n\n const message = opts.message && opts.message instanceof IonicSafeString ? opts.message.value : opts.message as string;\n const i18nKeys = [message];\n if (opts.header) i18nKeys.push(opts.header);\n\n let closeButton: ToastButton;\n if (opts.showCloseButton) {\n opts.buttons = opts.buttons || [];\n const buttonIndex = opts.buttons\n .map(b => typeof b === 'object' && b as ToastButton || undefined)\n .filter(isNotNil)\n .findIndex(b => b.role === 'close');\n if (buttonIndex !== -1) {\n closeButton = opts.buttons[buttonIndex] as ToastButton;\n } else {\n closeButton = {role: 'close'};\n opts.buttons.push(closeButton);\n }\n closeButton.text = closeButton.text || 'COMMON.BTN_OK';\n i18nKeys.push(closeButton.text);\n }\n\n // Read CSS\n const cssArray = opts.cssClass && typeof opts.cssClass === 'string' && opts.cssClass.split(',') || (opts.cssClass as Array<string>) || [];\n\n // Add 'error' class, if need\n if (opts.type) {\n switch (opts.type) {\n case 'error':\n opts.header = 'ERROR';\n cssArray.push('danger');\n break;\n case 'warning':\n cssArray.push('accent');\n break;\n case 'info':\n cssArray.push('secondary');\n break;\n }\n }\n\n opts.cssClass = cssArray;\n\n const translations = translate.instant(i18nKeys);\n if (opts.messageParams) {\n translations[message] = translate.instant(message, opts.messageParams);\n }\n\n if (closeButton) {\n closeButton.text = translations[closeButton.text];\n }\n\n // Retrieve the toast position\n const position = opts.position || (opts.mode === 'ios' ? 'bottom' : 'top');\n\n if (!opts.enterAnimation && position !== 'middle') {\n // Compute positions, using the stack offset\n const direction = position === 'top' ? 1 : -1;\n const start = (currentOffset) * TOAST_MAX_HEIGHT_PX - direction * TOAST_MAX_HEIGHT_PX;\n const end = direction * (currentOffset) * TOAST_MAX_HEIGHT_PX;\n opts.enterAnimation = (baseEl: any, opts?: any) => createAnimation()\n .addElement(baseEl.querySelector('.toast-wrapper'))\n .duration(250)\n .fromTo('transform', `translateY(${start}px)`, `translateY(${end}px)`)\n .fromTo('opacity', '0', '1');\n }\n\n const toast = await toastController.create({\n // Default values\n position,\n duration: opts.showCloseButton ? 10000 : 4000,\n ...opts,\n message: translations[message],\n header: opts.header && translations[opts.header] || undefined\n });\n\n if (opts.onWillPresent) opts.onWillPresent(toast);\n\n await toast.present();\n\n if (isEmptyArray(opts.buttons)) {\n // Not need to wait dismiss (no 'await')\n toast.onDidDismiss().then(updateCounters);\n return null; // no result\n }\n\n else {\n // Wait for button result\n const result = await toast.onDidDismiss();\n\n updateCounters();\n\n return result;\n }\n }\n}\n","import {Optional} from '@angular/core';\nimport {BehaviorSubject, Observable, Subject, Subscription} from 'rxjs';\nimport {filter, takeUntil} from 'rxjs/operators';\nimport {IStartableService} from './startable-service.class';\n\n/**\n * Same as StartableService, bu with a dataSubject instead of a simple 'data' property\n */\nexport abstract class StartableObservableService<T = any, O = any> implements IStartableService<T> {\n\n readonly dataSubject = new BehaviorSubject<T>(null);\n readonly startSubject = new Subject<T>();\n readonly stopSubject = new Subject<void>();\n\n protected _debug = false;\n protected _startByReadyFunction = true; // should start when calling ready() ?\n\n private _started = false;\n private _startPromise: Promise<T> = null;\n private _startPrerequisite: () => Promise<any> = null;\n private _subscription: Subscription = null;\n\n protected constructor(\n @Optional() prerequisiteService?: { ready: () => Promise<any> }\n ) {\n this._startPrerequisite = prerequisiteService\n ? () => prerequisiteService.ready()\n : () => Promise.resolve();\n }\n\n start(opts?: O): Promise<T> {\n if (this._startPromise) return this._startPromise;\n if (this._started) return Promise.resolve(this.dataSubject.value);\n\n this._startPromise = this._startPrerequisite()\n .then(() => this.ngOnStart(opts))\n .then(data => {\n\n this._started = true;\n this._startPromise = undefined;\n\n // Should be done AFTER 'this._started = true', because of the 'filter' operator, inside ready() function\n this.dataSubject.next(data);\n this.startSubject.next(data);\n\n return data;\n })\n .catch(err => {\n if (!this.stopped) {\n console.error('Failed to start a service: ' + (err && err.message || err), err);\n this._started = false;\n this._startPromise = null;\n }\n return null;\n });\n return this._startPromise;\n }\n\n ready(): Promise<T> {\n if (this._started) return Promise.resolve(this.dataSubject.value);\n if (this._startPromise) return this._startPromise;\n if (this._startByReadyFunction) return this.start();\n\n return this.dataSubject\n .pipe(\n takeUntil(this.stopSubject),\n // Wait start() to be called, to exclude the initial 'null' value\n filter(_ => this._started)\n )\n .toPromise();\n }\n\n async stop() {\n\n try {\n this.unsubscribe();\n await this.ngOnStop();\n }\n catch (err) {\n console.error('Failed to stop a service: ' + (err && err.message || err), err);\n }\n finally {\n this._started = false;\n this._startPromise = undefined;\n this.stopSubject.next(); // Stop all running observables\n this.dataSubject.next(null); // Reset data\n }\n }\n\n async restart(opts?: O): Promise<T> {\n if (this._startPromise) await this._startPromise; // Wait end of previous loading\n if (this._started) await this.stop(); // Then stop if started\n return this.start(opts); // Then start again\n }\n\n get started(): boolean {\n return this._started;\n }\n\n get starting(): boolean {\n return !!this._startPromise;\n }\n\n get stopped(): boolean {\n return !this._started && !this._startPromise;\n }\n\n protected get data(): T {\n return this.dataSubject.value;\n }\n\n protected set data(value: T) {\n if (this.dataSubject.value !== value) {\n this.dataSubject.next(value);\n }\n }\n\n protected registerSubscription(sub: Subscription): Subscription {\n this._subscription = this._subscription || new Subscription();\n return this._subscription.add(sub);\n }\n\n protected unregisterSubscription(sub: Subscription): void {\n this._subscription?.remove(sub);\n }\n\n protected unsubscribe() {\n this._subscription?.unsubscribe();\n this._subscription = null;\n }\n\n protected ngOnStop(): Promise<void> | void {\n // Can be overwritten by subclasses\n }\n\n protected abstract ngOnStart(opts?: O): Promise<T>;\n}\n","import {EventEmitter, Inject, Injectable, Optional} from '@angular/core';\nimport {CryptoService} from './crypto.service';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Storage} from '@ionic/storage';\nimport {Peer} from './model/peer.model';\nimport {LocalSettings} from './model/settings.model';\nimport {ModalController, Platform, ToastController} from '@ionic/angular';\nimport {SelectPeerModal} from '../peer/select-peer.modal';\nimport {BehaviorSubject, Subscription, timer} from 'rxjs';\nimport {LocalSettingsService, SETTINGS_STORAGE_KEY} from './local-settings.service';\nimport {SplashScreen} from '@ionic-native/splash-screen/ngx';\nimport {HttpClient, HttpHeaders} from '@angular/common/http';\nimport {isNotEmptyArray, isNotNilOrBlank, sleep, toBoolean} from '../../shared/functions';\nimport {Connection, Network} from '@ionic-native/network/ngx';\nimport {DOCUMENT} from '@angular/common';\nimport {CacheService} from 'ionic-cache';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {distinctUntilChanged, filter, map, mergeMap, tap} from 'rxjs/operators';\nimport {OverlayEventDetail} from '@ionic/core';\nimport {AppManifest, NodeInfo} from './network.utils';\nimport {HttpUtils} from '../../shared/http/http.utils';\nimport {VersionUtils} from '../../shared/version/versions';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {StartableObservableService} from '../../shared/services/startable-observable-service.class';\n\nexport type ConnectionType = 'none' | 'wifi' | 'ethernet' | 'cell' | 'unknown' ;\n\nexport type AuthTokenType = 'token' | 'basic' | 'basic-and-token';\n\nexport function getConnectionType(type: Connection): ConnectionType {\n switch (type) {\n case Connection.NONE:\n return 'none';\n case Connection.ETHERNET:\n return 'ethernet';\n case Connection.WIFI:\n return 'wifi';\n case Connection.CELL:\n case Connection.CELL_2G:\n case Connection.CELL_3G:\n case Connection.CELL_4G:\n return 'cell';\n case Connection.UNKNOWN:\n return 'unknown';\n default:\n return 'ethernet';\n }\n}\n\nexport declare type NetworkEventType = 'start'|'peerChanged'|'statusChanged'|'resetCache'|'beforeTryOnlineFinish';\n\nconst NetworkRefreshTimerPeriod = {\n MOBILE: 1000 * 60 * 10 /* every 10 min */,\n DESKTOP: 1000 * 60 * 5 /* every 5 min */\n};\n\n/* -- DEV only (to debug refresh timer)\nconst NetworkRefreshTimerPeriod = {\n MOBILE: 1000,\n DESKTOP: 1000\n}*/\n\n@Injectable({providedIn: 'root'})\nexport class NetworkService extends StartableObservableService<Peer, Peer> {\n\n onPeerChanges = this.startSubject.pipe(\n map(peer => peer?.url),\n filter(isNotNilOrBlank),\n distinctUntilChanged<string>()\n );\n onNetworkStatusChanges = new BehaviorSubject<ConnectionType>(null);\n onResetNetworkCache = new EventEmitter(true);\n\n private readonly _mobile: boolean;\n private _timerSubscription: Subscription;\n private readonly _timerRefreshPeriod: number;\n private readonly _timerRefreshCondition: () => boolean;\n private _deviceConnectionType: ConnectionType;\n private _forceOffline: boolean;\n private _listeners: {\n [key: string]: ((data?: any) => Promise<void>)[];\n } = {};\n\n get online(): boolean {\n return this.connectionType !== 'none';\n }\n\n get offline(): boolean {\n return this.connectionType === 'none';\n }\n\n get connectionType(): ConnectionType{\n // If force offline: return 'none'\n return this._forceOffline && 'none'\n // Else, return device connection type (or unknown)\n || (this.started && this._deviceConnectionType || 'unknown');\n }\n\n get peer(): Peer {\n return this.dataSubject.value?.clone();\n }\n\n set peer(peer: Peer) {\n this.restart(peer);\n }\n\n constructor(\n @Inject(DOCUMENT) private _document: any,\n private platform: Platform,\n private modalCtrl: ModalController,\n private cryptoService: CryptoService,\n private storage: Storage,\n private settings: LocalSettingsService,\n private cache: CacheService,\n private http: HttpClient,\n @Inject(ENVIRONMENT) protected environment,\n @Optional() private network: Network,\n @Optional() private splashScreen: SplashScreen,\n @Optional() private translate: TranslateService,\n @Optional() private toastController: ToastController\n ) {\n super(platform);\n this._mobile = this.settings.mobile;\n\n if (this._mobile) {\n this._timerRefreshPeriod = NetworkRefreshTimerPeriod.MOBILE;\n this._timerRefreshCondition = () => this.online; // Check only when online, and stop when offline\n }\n else {\n this._timerRefreshPeriod = NetworkRefreshTimerPeriod.DESKTOP;\n this._timerRefreshCondition = () => true; // Always check\n }\n\n this.startSubject.subscribe(peer => this.ngOnAfterStart(peer));\n\n // For DEV only\n this._debug = !environment.production;\n\n }\n\n /**\n * Register to network event\n *\n * @param eventType\n * @param callback\n */\n on<T= any>(eventType: NetworkEventType, callback: (data?: T) => Promise<any>): Subscription {\n switch (eventType) {\n case 'start':\n return this.startSubject.subscribe(() => callback());\n\n case 'peerChanged':\n return this.onPeerChanges.subscribe(() => callback());\n\n case 'statusChanged':\n return this.onNetworkStatusChanges.subscribe((type) => callback(type as unknown as T));\n\n case 'resetCache':\n return this.onResetNetworkCache.subscribe(() => callback());\n\n default:\n return this.addListener(eventType, callback);\n }\n }\n\n async tryOnline(opts?: {\n showOfflineToast?: boolean;\n showOnlineToast?: boolean;\n showLoadingToast?: boolean;\n afterRetryDelay?: number;\n afterRetryPromise?: () => Promise<any>;\n }): Promise<boolean> {\n // If offline mode not forced, and device says there is no connection: skip\n if (!this._forceOffline || this._deviceConnectionType === 'none') return false;\n\n // SHow loading toast\n const now = Date.now();\n const showLoadingToast = !opts || opts.showLoadingToast !== false;\n let loadingToast: HTMLIonToastElement;\n if (showLoadingToast) {\n await this.showToast({message: 'NETWORK.INFO.RETRY_TO_CONNECT',\n duration: 10000,\n onWillPresent: t => loadingToast = t});\n }\n\n try {\n console.info('[network] Checking connection to pod...');\n const settings: LocalSettings = await this.settings.ready();\n\n if (!settings.peerUrl) return false; // No peer define. Skip\n\n const peer = Peer.parseUrl(settings.peerUrl);\n const peerInfo = await this.checkPeerAlive(peer);\n const peerAliveAndCompatible = peerInfo && await this.checkPeerCompatible(peerInfo);\n if (peerAliveAndCompatible) {\n\n // Disable the offline mode\n this.setForceOffline(false);\n\n // Restart\n await this.restart(peer);\n\n // Wait a promise, before recheck\n await this.emit('beforeTryOnlineFinish', this.online);\n\n }\n }\n catch (err) {\n console.error(err && err.message || err);\n // Continue\n }\n\n // Close loading toast (with a minimal display duration of 2s)\n if (showLoadingToast) {\n await sleep(2000 - (Date.now() - now));\n if (loadingToast) await loadingToast.dismiss();\n }\n\n // Recheck network status\n const online = this.online;\n\n // Display a toast to user\n if (online) {\n if (!opts || opts.showOnlineToast !== false) {\n // Display toast (without await, because not need to wait toast close event)\n this.showToast({message: 'NETWORK.INFO.ONLINE', type: 'info'});\n }\n }\n else if (opts && opts.showOfflineToast === true) {\n // Display toast (without await, because not need to wait toast close event)\n return this.showOfflineToast({showRetryButton: false});\n }\n\n return this.started && online;\n }\n\n async showOfflineToast(opts?: {\n message?: string;\n showCloseButton?: boolean;\n showRetryButton?: boolean;\n showRetrySuccessToast?: boolean;\n showRetryLoadingToast?: boolean;\n onRetrySuccess?: () => void;\n }): Promise<boolean> {\n if (this.online) return; // Skip if online\n\n // Toast with a retry button\n if (!opts || opts.showRetryButton !== false) {\n\n const toastResult = await this.showToast({\n message: (opts && opts.message || 'ERROR.NETWORK_REQUIRED'),\n type: 'warning',\n showCloseButton: true,\n duration: 100000,\n buttons: [\n // reconnect button\n {\n role: 'refresh',\n text: this.translate.instant('NETWORK.BTN_CHECK_ALIVE')\n }\n ]\n });\n\n // User don't click reconnect: return\n if (!toastResult || toastResult.role !== 'refresh') return false;\n\n // if network state changed to online: exit here\n if (this.online) return true;\n\n // Try to reconnect\n const online = await this.tryOnline({\n showOfflineToast: false,\n showOnlineToast: toBoolean(opts && opts.showRetrySuccessToast, true),\n showLoadingToast: toBoolean(opts && opts.showRetryLoadingToast, true)\n });\n if (online) {\n // Call success callback (async)\n if (opts && opts.onRetrySuccess) {\n setTimeout(opts.onRetrySuccess);\n }\n return true;\n }\n\n opts = {\n ...opts,\n showRetryButton: false,\n showCloseButton: true\n };\n }\n\n // Simple toast, without 'await', because not need to wait toast's dismiss\n this.showToast({\n message: 'ERROR.NETWORK_REQUIRED',\n type: 'error',\n ...opts\n });\n\n return false;\n }\n\n\n /**\n * Check if the peer is alive\n *\n * @param peer\n * @param opts\n */\n async checkPeerAlive(peer?: string | Peer, opts?: { checkCompatible?: boolean; displayToast?: boolean } ): Promise<NodeInfo> {\n peer = peer || this.peer;\n if (!peer) {\n const settings: LocalSettings = await this.settings.ready();\n if (!settings.peerUrl) return undefined; // No peer define. Skip\n peer = Peer.parseUrl(settings.peerUrl);\n }\n\n try {\n return await this.getNodeInfo(peer);\n } catch (err) {\n console.debug('[network] Cannot get /api/node/info from peer: ' + (err && err.message || err), err);\n return undefined;\n }\n }\n\n async checkPeerCompatible(peerInfo: NodeInfo, opts?: { showToast?: boolean }): Promise<boolean> {\n if (!this.environment.peerMinVersion) return true; // Skip compatibility check\n\n // Check the min pod version, defined by the app\n const isCompatible = peerInfo && peerInfo.softwareVersion && VersionUtils.isCompatible(this.environment.peerMinVersion, peerInfo.softwareVersion);\n\n // Display toast, if not compatible\n if (!isCompatible && (!opts || opts.showToast !== false)) {\n await this.showToast({\n type: 'error',\n message: 'NETWORK.ERROR.NOT_COMPATIBLE_PEER',\n messageParams: {\n version: this.environment.peerMinVersion\n },\n showCloseButton: true\n });\n }\n return isCompatible;\n }\n\n getNodeInfo(peer?: string | Peer): Promise<NodeInfo> {\n const path = this.computePeerPath(peer, '/api/node/info');\n return this.get(path);\n }\n\n async getAppManifest(peer?: string | Peer, opts?: {nocache?: boolean}): Promise<AppManifest|undefined> {\n try {\n let path = this.computePeerPath(peer, 'manifest.json');\n if (opts?.nocache) {\n path += '?t=' + Date.now();\n }\n return await this.get(path, opts);\n }\n catch (err) {\n if (this.environment.production) console.error('[network] Cannot load file \\'manifest.json\\'. Please make sure webserver config allow CORS access', err);\n else console.error('[network] Cannot load file \\'manifest.json\\'.', err);\n // Continue\n }\n }\n\n async getAppVersion(peer?: string | Peer, opts = {nocache: true}): Promise<string|undefined> {\n try {\n let path = this.computePeerPath(peer, 'version.appup');\n if (opts.nocache) {\n path += '?t=' + Date.now();\n }\n const appVersion: string = await this.getText(path, opts);\n if (isNotNilOrBlank(appVersion)) return appVersion;\n }\n catch (err) {\n if (this.environment.production) console.error('[network] Cannot load file \\'version.appup\\'. Please make sure webserver config allow CORS access');\n else console.error('[network] Cannot load file \\'version.appup\\'.', err);\n // Continue\n }\n\n // Try loading manifest.json\n const manifest = await this.getAppManifest(peer, opts);\n return manifest?.version;\n }\n\n computePeerPath(peer: string | Peer | undefined, path: string): string | undefined {\n peer = peer || this.peer;\n if (!peer) return undefined;\n\n let peerUrl = (peer instanceof Peer) ? peer.url : (peer as string);\n\n // Remove trailing slash\n if (peerUrl.endsWith('/')) {\n peerUrl = peerUrl.substr(0, peerUrl.length - 1);\n }\n\n // Add first path\n if (!path.startsWith('/')) {\n path = '/' + path;\n }\n\n // Concat peer URL and path\n return peerUrl + path;\n }\n\n\n /**\n * Allow to force offline mode\n */\n setForceOffline(value?: boolean, opts?: {\n showToast?: boolean; // Display a toast, when offline ?\n }) {\n value = toBoolean(value, true);\n if (this._forceOffline !== value) {\n const previousConnectionType = this.connectionType;\n this._forceOffline = value;\n const currentConnectionType = this.connectionType;\n\n if (previousConnectionType !== currentConnectionType) {\n console.info(`[network] Connection changed to {${currentConnectionType}}`);\n this.onNetworkStatusChanges.next(currentConnectionType);\n\n // Offline mode: alert the user\n if (currentConnectionType === 'none' && (!opts || opts.showToast !== false)) {\n this.showToast({message: 'NETWORK.INFO.OFFLINE_HELP', type: 'warning'});\n }\n }\n }\n }\n\n async showSelectPeerModal(opts?: {allowSelectDownPeer?: boolean; canCancel?: boolean}): Promise<Peer | undefined> {\n\n opts = opts || {};\n\n const $onRefresh = new EventEmitter<UIEvent>();\n const peers$ = $onRefresh.pipe(\n mergeMap((_) => this.getDefaultPeers()),\n map(peers => peers || [])\n );\n\n const modal = await this.modalCtrl.create({\n component: SelectPeerModal,\n componentProps: {\n onRefresh: $onRefresh,\n peers: peers$,\n canCancel: toBoolean(opts.canCancel, true),\n allowSelectDownPeer: toBoolean(opts.allowSelectDownPeer, true)\n },\n keyboardClose: true,\n showBackdrop: true\n });\n await modal.present();\n $onRefresh.emit();\n\n const { data } = await modal.onWillDismiss();\n $onRefresh.complete();\n\n return data && (data as Peer) || undefined;\n }\n\n async clearCache(opts?: { emitEvent?: boolean }): Promise<void> {\n\n const now = this._debug && Date.now();\n\n console.info('[network] Clearing all caches...');\n return this.cache.clearAll()\n .then(() => {\n // Emit event\n if (!opts || opts.emitEvent !== false && this.onResetNetworkCache.observers.length) {\n this.onResetNetworkCache.emit();\n\n // Wait observers clean their caches, if need\n return sleep(500);\n }\n })\n .then(() => {\n if (this._debug) console.debug(`[network] All cache cleared, in ${Date.now() - now}ms`);\n });\n }\n\n /* -- protected functions -- */\n\n protected async ngOnStart(peer?: Peer): Promise<Peer> {\n\n console.info('[network] Starting network...');\n\n // Restoring local settings\n peer = peer || (await this.restoreLocally());\n\n // Make sure to hide the splashscreen, before open the modal\n if (!peer && this.splashScreen) this.splashScreen.hide();\n\n // No peer in settings: ask user to choose\n while (!peer) {\n console.debug('[network] No peer defined. Asking user to choose a peer.');\n peer = await this.showSelectPeerModal({allowSelectDownPeer: false});\n }\n\n console.info(`[network] Starting service [OK] {peer: '${peer.url}', online: ${this.online}}`);\n\n return peer;\n }\n\n protected async ngOnAfterStart(peer: Peer) {\n\n // Wait settings starts, then save peer in settings\n await this.settings.apply({peerUrl: peer.url});\n\n this.onDeviceConnectionChanged(this.network?.type || 'unknown');\n\n // Start the refresh timer\n this.startRefreshTimer();\n\n // Listen for device network changes\n if (this.network) {\n this.registerSubscription(this.network.onDisconnect().subscribe(() => this.onDeviceConnectionChanged('none')));\n this.registerSubscription(this.network.onConnect().subscribe(() => this.onDeviceConnectionChanged(this.network.type)));\n }\n }\n\n protected ngOnStop() {\n // Stop timer, if cannot refresh anymore\n if (this._timerRefreshCondition() === false) {\n this.stopRefreshTimer();\n }\n }\n\n /**\n * Try to restore peer from the local storage\n */\n protected async restoreLocally(): Promise<Peer | undefined> {\n\n // Restore from storage\n const settingsStr = await this.storage.get(SETTINGS_STORAGE_KEY);\n const settings = settingsStr && JSON.parse(settingsStr) || undefined;\n if (settings && settings.peerUrl) {\n console.debug(`[network] Use peer {${settings.peerUrl}} (found in the local storage)`);\n return Peer.parseUrl(settings.peerUrl);\n }\n\n // Else, use default peer in env, if exists\n if (this.environment.defaultPeer) {\n return Peer.fromObject(this.environment.defaultPeer);\n }\n\n // Else, if App is hosted, try the web site as a peer\n const location = this._document && this._document.location;\n if (location && location.protocol && location.protocol.startsWith('http')) {\n const hostname = this._document.location.host;\n const detectedPeer = Peer.parseUrl(`${this._document.location.protocol}${hostname}${this.environment.baseUrl}`);\n if (await this.checkPeerAlive(detectedPeer)) {\n return detectedPeer;\n }\n }\n\n return undefined;\n }\n\n /**\n * Stop to network state\n *\n * @protected\n */\n protected stopRefreshTimer() {\n if (this._timerSubscription) {\n this._timerSubscription.unsubscribe();\n this._timerSubscription = undefined;\n }\n }\n\n /**\n * Refresh the network state\n *\n * @protected\n */\n protected startRefreshTimer(){\n if (this._timerSubscription) return; // Already running: skip\n\n console.info(`[network] Starting refresh timer, every ${this._timerRefreshPeriod}ms...`);\n\n let lastInfo: NodeInfo;\n this._timerSubscription = timer(this._timerRefreshPeriod, this._timerRefreshPeriod)\n .pipe(\n // Skip some timer event (see constructor)\n filter(this._timerRefreshCondition),\n\n // Checkin if peer alive\n tap(() => console.debug('[network] Checking connection to pod...')),\n mergeMap(() => this.checkPeerAlive(this.peer)),\n\n // Filter to keep only changes\n filter(info => !!info !== !!lastInfo),\n tap(info => lastInfo = info),\n\n // Check compatibility\n mergeMap((info) => this.checkPeerCompatible(info, {showToast: true})),\n )\n .subscribe(alive => {\n if (alive && this.offline) {\n this.setForceOffline(false);\n\n // Restart the service (to force re auth)\n this.restart();\n }\n else if (!alive && this.online){\n this.setForceOffline(true);\n\n // Stop the service\n this.stop();\n }\n });\n\n this._timerSubscription.add(() => console.debug('[network] Refresh timer stopped'));\n }\n\n\n protected async getText(path: string, opts?: {\n headers?: HttpHeaders | {\n [header: string]: string | string[];\n };\n responseType?: 'text';\n nocache?: boolean;\n }): Promise<string> {\n\n let uri = this.getUri(path);\n return HttpUtils.getText(this.http, uri, opts);\n }\n\n protected async get<T>(path: string, opts?: {\n headers?: HttpHeaders | {\n [header: string]: string | string[];\n };\n responseType?: 'json';\n nocache?: boolean;\n }): Promise<T> {\n\n let uri = this.getUri(path);\n return HttpUtils.getJson<T>(this.http, uri, opts);\n }\n\n /* -- Protected methods -- */\n\n protected getUri(path: string): string {\n let uri = path;\n\n // If path is not an URI: prepend with peer URL\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n let peerUrl = (this.peer && this.peer.url);\n\n // Remove trailing slash\n if (peerUrl.endsWith('/')) {\n peerUrl = peerUrl.substr(0, peerUrl.length - 1 );\n }\n\n // Add first path\n if (!path.startsWith('/')) {\n path = '/' + path;\n }\n\n // Create the URI: concat peer URL and path\n uri = peerUrl + path;\n }\n return uri;\n }\n protected onDeviceConnectionChanged(connectionType?: string) {\n connectionType = (connectionType || 'unknown').toLowerCase();\n if (connectionType.startsWith('cell')) connectionType = 'cell';\n if (connectionType !== this._deviceConnectionType) {\n this._deviceConnectionType = connectionType as ConnectionType;\n\n // If NOT already forced as offline, emit event\n if (!this._forceOffline) {\n console.info(`[network] Connection changed to {${this._deviceConnectionType}}`);\n this.onNetworkStatusChanges.next(this._deviceConnectionType);\n\n // Change to offline\n if (this._deviceConnectionType === 'none') {\n if (this._mobile) {\n // Force offline mode\n this._forceOffline = true;\n\n // Alert the user\n this.showToast({message: 'NETWORK.INFO.OFFLINE_HELP', type: 'warning'});\n }\n else {\n // Alert the user\n this.showToast({message: 'NETWORK.INFO.OFFLINE', type: 'warning'});\n }\n\n // Stop the network service\n this.stop();\n }\n }\n }\n }\n\n /**\n * Get default peers, from environment\n */\n protected async getDefaultPeers(): Promise<Peer[]> {\n const peers = (this.environment.defaultPeers || []).map(Peer.fromObject);\n return Promise.resolve(peers);\n }\n\n protected showToast<T = any>(opts: ShowToastOptions): Promise<OverlayEventDetail<T>> {\n return Toasts.show(this.toastController, this.translate, opts);\n }\n\n protected addListener<T= any>(name: NetworkEventType, callback: (data?: T) => Promise<void>): Subscription {\n this._listeners[name] = this._listeners[name] || [];\n this._listeners[name].push(callback);\n\n // When unsubscribe, remove from the listener\n return new Subscription(() => {\n const index = this._listeners[name].indexOf(callback);\n if (index !== -1) {\n this._listeners[name].splice(index, 1);\n }\n });\n }\n\n protected async emit<T= any>(name: NetworkEventType, data?: T) {\n const hooks = this._listeners[name];\n if (isNotEmptyArray(hooks)) {\n console.info(`[network-service] Trigger ${name} hook: Executing ${hooks.length} callbacks...`);\n\n return Promise.all(hooks.map(callback => {\n const promise = callback(data);\n if (!promise) return;\n return promise.catch(err => console.error('Error while executing hook ' + name, err));\n }));\n }\n }\n}\n","\nexport declare interface ServiceError {\n code: number;\n message: string;\n reject?: (err) => void;\n}\n\nexport const ErrorCodes = {\n\n UNKNOWN_ERROR: 0,\n\n LOAD_ACCOUNT_ERROR: 1,\n BAD_PASSWORD: 2,\n UNKNOWN_ACCOUNT_EMAIL: 3,\n EMAIL_ALREADY_REGISTERED: 4,\n UNREACHABLE_NETWORK_ERROR: 4,\n UNKNOWN_NETWORK_ERROR: 5,\n SENT_CONFIRMATION_EMAIL_FAILED: 6,\n CONFIRM_EMAIL_FAILED: 7,\n SAVE_ACCOUNT_ERROR: 8,\n ACCOUNT_NOT_EXISTS: 9,\n SAVE_SETTINGS_ERROR: 8,\n SUBSCRIBE_ACCOUNT_ERROR: 10,\n ENTITY_STORAGE_MIGRATION_FAILED: 11,\n\n LOAD_DATA_ERROR: 12,\n SAVE_DATA_ERROR: 13,\n DELETE_DATA_ERROR: 14,\n SUBSCRIBE_DATA_ERROR: 15,\n\n // DATA errors (load error)\n LOAD_PERSONS_ERROR: 100,\n DATA_NOT_FOUND_ERROR: 104,\n\n TABLE_INVALID_ROW_ERROR: 350,\n TABLE_READ_ONLY: 351,\n\n UNAUTHORIZED: 401,\n AUTH_CHALLENGE_ERROR: 601,\n AUTH_SERVER_ERROR: 602,\n\n LOAD_CONFIG_ERROR: 700,\n SAVE_CONFIG_ERROR: 701,\n\n LOAD_TRASH_ENTITY_ERROR: 800,\n DELETE_TRASH_ENTITY_ERROR: 801\n};\n\nexport const ServerErrorCodes = {\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401, // not authenticated\n FORBIDDEN: 403, // authenticated but no access right\n NOT_FOUND: 404,\n\n // sumaris-core-shared errors\n INTERNAL_SERVER_ERROR: 500,\n DATA_LOCKED: 520,\n BAD_UPDATE_DATE: 521,\n DENY_DELETION: 522,\n\n // sumaris-server errors\n INVALID_EMAIL_CONFIRMATION: 550,\n INVALID_QUERY_VARIABLES: 551,\n ACCOUNT_ALREADY_EXISTS: 552,\n BAD_APP_VERSION: 553\n};\n","import {BehaviorSubject, Observable} from 'rxjs';\nimport {Storage} from '@ionic/storage';\nimport {map, mergeMap} from 'rxjs/operators';\nimport {Entity, EntityUtils, IEntity} from '../model/entity.model';\nimport {isEmptyArray, isNil, isNotEmptyArray, isNotNil} from '../../../shared/functions';\nimport {IEntitiesService, LoadResult} from '../../../shared/services/entity-service.class';\nimport {chainPromises} from '../../../shared/observables';\nimport {ErrorCodes} from '../errors';\n\nexport const ENTITIES_STORAGE_KEY_PREFIX = 'entities';\n\nexport type EntityStoreTypePolicyMode = 'default' | 'by-id';\n\nexport declare interface EntityStoreTypePolicy<T extends Entity<T, any> = Entity<any, any>, K = keyof T> {\n mode?: EntityStoreTypePolicyMode; // 'default' by default\n skipNonLocalEntities?: boolean; // False by default\n lightFieldsExcludes?: K[]; // none by default\n}\n\nexport declare interface EntityStorageLoadOptions {\n fullLoad?: boolean;\n}\n\ndeclare interface EntityStatus {\n index: number;\n dirty?: boolean;\n}\n\nexport class EntityStore<\n T extends IEntity<T, ID>,\n ID = number,\n O extends EntityStorageLoadOptions = EntityStorageLoadOptions> {\n\n private readonly _storageKey: string;\n private readonly _onChange = new BehaviorSubject(true);\n private readonly _mapToLightEntity: (T) => T;\n private _cache: T[];\n private _statusById: Map<ID, EntityStatus>;\n private _sequence: number;\n private _dirty = false;\n private _loaded: boolean;\n\n readonly policy: EntityStoreTypePolicy<T>;\n\n get length(): number {\n return this._cache?.length || 0;\n }\n\n get cache(): T[] {\n return this._cache;\n }\n\n get dirty(): boolean {\n return this._dirty;\n }\n\n protected get isByIdMode(): boolean {\n return this.policy.mode === 'by-id';\n }\n\n protected get storageKeyById(): string {\n return this._storageKey + '#ids';\n }\n\n constructor(\n protected readonly name: string,\n protected readonly storage: Storage,\n policy?: EntityStoreTypePolicy<T>) {\n this.policy = policy || {};\n this.reset({emitEvent: false});\n this._dirty = false;\n this._loaded = false;\n this._storageKey = ENTITIES_STORAGE_KEY_PREFIX + '#' + name;\n this._mapToLightEntity = this.createLightEntityMapFn(this.policy);\n }\n\n nextValue(): ID {\n this._sequence = this._sequence - 1;\n this._dirty = true;\n return this._sequence as unknown as ID;\n }\n\n currentValue(): number {\n return this._sequence;\n }\n\n async load(id: ID, opts?: EntityStorageLoadOptions): Promise<T> {\n if (this._mapToLightEntity && (!opts || opts.fullLoad !== false)) {\n return await this.loadFullEntity(id, opts);\n }\n return this.loadCachedEntity(id, opts);\n }\n\n /**\n * Watch a set of entities\n *\n * @param variables\n * @param opts\n */\n watchAll(variables: {\n offset?: number;\n size?: number;\n sortBy?: string;\n sortDirection?: string;\n filter?: (T) => boolean;\n }, opts?: O): Observable<LoadResult<T>> {\n\n // If need full entities, but use light entities in the entities array\n if (this._mapToLightEntity && (opts && opts.fullLoad === true)) {\n console.warn('[entity-store] WARN: Watching full entities, splited by id in entity store. This can be long! Please make sure you need full entities here.');\n return this._onChange\n .pipe(\n // Apply filter on cache\n map((_) => this.reduceAndSort(this._cache, variables)),\n\n // Then convert into full entities (using parallel jobs - /!\\ can use lot of memory)\n mergeMap((res) => Promise.all((res.data || [])\n .map(e => this.loadFullEntity(e.id, opts))).then(data => ({\n data,\n total: res.total\n }))\n )\n );\n }\n\n // Load using entities array\n return this._onChange\n .pipe(\n map((_) => this.reduceAndSort(this._cache, variables))\n );\n }\n\n /**\n * WIll apply a filter, then a sort, then a page slice\n *\n * @param variables\n * @param opts\n */\n async loadAll(variables: {\n offset?: number;\n size?: number;\n sortBy?: string;\n sortDirection?: string;\n filter?: (T) => boolean;\n }, opts?: O): Promise<LoadResult<T>> {\n\n const res = this.reduceAndSort(this._cache, variables);\n\n // If store by ID: make sure to full the full entities\n if (this._mapToLightEntity && isNotEmptyArray(res.data) && (opts && opts.fullLoad === true)) {\n // Load full entities, one by one\n res.data = await chainPromises((res.data || []).map(e => () => this.load(e.id)));\n }\n\n return res ;\n }\n\n save(entity: T, opts?: {emitEvent?: boolean}): T {\n const status = isNotNil(entity.id) && this._statusById.get(entity.id) || {index: undefined};\n const isNew = isNil(status.index);\n if (isNew) {\n if (isNil(entity.id)) {\n entity.id = this.nextValue();\n }\n else if (+entity.id < 0 && +entity.id > this._sequence) {\n console.warn('Trying to save a local entity with an id > sequence. Will replace id by sequence next value');\n entity.id = this.nextValue();\n }\n else {\n // OK: use a valid id :\n // - id >= 0 (should be a remote id)\n // - OR < sequence, and not exists in the index map\n }\n\n this._statusById.set(entity.id, status);\n status.index = this._cache.push(entity) - 1;\n }\n else {\n this._cache[status.index] = entity;\n }\n\n // Mark entity as dirty\n status.dirty = true;\n\n // Mark storage as dirty\n this._dirty = true;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n\n return entity;\n }\n\n saveAll(entities: T[], opts?: { emitEvent?: boolean; reset?: boolean }): T[] {\n if (isEmptyArray(entities) && (!opts || opts.reset !== true)) return entities; // Skip (Nothing to save)\n\n let result: T[];\n\n console.info(`[entity-storage] Saving ${entities.length} ${this.name}(s)`);\n\n // First save, or reset using given entities\n if (isEmptyArray(this._cache) || (opts && opts.reset)) {\n this.setEntities(entities, {emitEvent: false});\n }\n else {\n result = entities.map((entity) => this.save(entity, {emitEvent: false}));\n }\n\n // Mark as dirty\n this._dirty = true;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n\n return result || this._cache.slice();\n }\n\n delete(id: ID, opts?: { emitEvent?: boolean }): T | undefined {\n const status = isNotNil(id) ? this._statusById.get(id) : undefined;\n const index = status ? status.index : undefined;\n if (isNil(index)) return undefined;\n\n const entity = this._cache[index];\n if (!entity) return undefined;\n\n // Remove from cache\n this._cache[index] = undefined;\n this._statusById.delete(entity.id);\n\n // Remove full entity, by id\n if (this.isByIdMode) {\n this.storage.remove(this._storageKey + '#' + id);\n }\n\n // Mark as dirty\n this._dirty = true;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n\n return entity as T;\n }\n\n deleteMany(ids: ID[], opts?: {emitEvent?: boolean}): T[] {\n\n // Delete by id, but NOT emit event on each deletion\n const deletedEntities = (ids || [])\n .map(id => this.delete(id, {emitEvent: false}))\n .filter(isNotNil);\n\n // No changes: exit\n if (!deletedEntities.length) return [];\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n\n return deletedEntities;\n }\n\n reset(opts?: {emitEvent?: boolean}) {\n this._cache = [];\n this._sequence = 0;\n this._statusById = new Map<ID, any>();\n\n this._dirty = true;\n this._loaded = true;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n }\n\n /**\n *\n * @param opts\n * opts.skipIfPristine = false persist all entities, even if not dirty\n */\n async persist(opts = { skipIfPristine: true }): Promise<number> {\n\n // Skip is not dirty\n if (opts.skipIfPristine && !this._dirty) {\n console.debug(`[entity-storage] Persisting ${this.name} not need. Skip`);\n return this._cache.length;\n }\n\n // Copy some data, BEFORE to call markAsPristine() to allow parallel changes\n const dirtyIndexes = this.isByIdMode && Array.from(this._statusById.values())\n .filter(s => !opts.skipIfPristine || (s && s.dirty))\n .map(s => s.index);\n const entities = this._cache.slice(); // Copy cached entities\n\n // Mark all (entities and status) as pristine\n this.markAsPristine({emitEvent: false});\n\n // Convert dirty entities into light entities (/!\\ AFTER the previous copy)\n // and update the cache (but NOT the 'entities' variable)\n if (dirtyIndexes && this._mapToLightEntity) {\n dirtyIndexes.forEach(index => this._cache[index] = this._mapToLightEntity(entities[index]));\n }\n\n // If no entity found\n if (isEmptyArray(entities)) {\n\n // Clean the local storage\n await this.storage.remove(this._storageKey);\n }\n else {\n\n // Save each entity into a unique key (advanced mode)\n if (this.isByIdMode) {\n // Save ids\n await this.storage.set(this.storageKeyById, entities.filter(isNotNil).map(e => e.id));\n\n // Saved dirty entities\n await Promise.all(\n dirtyIndexes\n .map(index => {\n const entity = entities[index];\n console.debug(`[entity-storage] Persisting ${this.name}#${entity.id}...`);\n return this.storage.set(this._storageKey + '#' + entity.id, entity);\n }));\n\n console.info(`[entity-storage] Persisting ${dirtyIndexes.length}/${entities.length} ${this.name}(s)...`);\n }\n\n // Save all entities in a single key (default)\n else {\n\n console.info(`[entity-storage] Persisting ${entities.length} ${this.name}(s)...`);\n await this.storage.set(this._storageKey, entities);\n }\n }\n\n return entities.length;\n }\n\n async restore(opts?: { emitEvent?: boolean }): Promise<number> {\n let entities: T[];\n\n const res = await Promise.all([\n this.storage.get(this._storageKey),\n this.storage.get(this.storageKeyById)\n ]);\n const values = res[0] && Array.isArray(res[0]) ? res[0] : null;\n const ids = res[1] && Array.isArray(res[1]) ? res[1] : null;\n let migration = false;\n let oldKeysToClean: string[];\n\n // \"Split by id\" mode\n if (this.isByIdMode) {\n if (isNotNil(ids)) {\n // Load entity by id (one by one)\n const storageKeys = ids.map(id => this._storageKey + '#' + id);\n entities = await chainPromises<T>(storageKeys.map(key => () => this.storage.get(key)));\n }\n // Migrate from the standard mode\n else if (isNotNil(values)) {\n entities = values.filter(e => e && isNotNil(e.id));\n migration = true;\n oldKeysToClean = [this._storageKey];\n }\n }\n\n // Else (default mode)\n else {\n if (isNotNil(values)) {\n entities = values.filter(e => e && isNotNil(e.id));\n }\n else if (isNotNil(ids)) {\n const storageKeys = ids.map(id => this._storageKey + '#' + id);\n // Load entity by id (one by one)\n entities = await chainPromises<T>(storageKeys.map(key => () => this.storage.get(key)));\n migration = true;\n oldKeysToClean = [...storageKeys, this.storageKeyById];\n }\n }\n\n // OK, there is something in storage...\n if (isNotEmptyArray(entities)) {\n if (entities.length >= 1000) {\n console.warn(`[entity-storage] - Restoring ${entities.length} ${this.name}. Check if not too many elements?!`);\n }\n\n // Map entities into light element (if if not need to persist, because of migration\n if (this._mapToLightEntity && !migration) {\n entities = entities.map(this._mapToLightEntity);\n }\n }\n\n this.setEntities(entities || [], {...opts, emitEvent: false });\n this._dirty = false;\n\n // Finish the migration\n if (migration) {\n try {\n console.warn(`[entity-storage] - Migrate ${this.name} into {mode: '${this.policy.mode}'}...`);\n\n // Force to persist, using the new mode\n await this.persist({skipIfPristine: false /* force persist using the new mode */ });\n\n // Clean old storage keys (one by one)\n if (isNotEmptyArray(oldKeysToClean)) await chainPromises(oldKeysToClean.map(key => () => this.storage.remove(key)));\n }\n catch (err) {\n console.error(err);\n throw {code: ErrorCodes.ENTITY_STORAGE_MIGRATION_FAILED, message: 'ERROR.ENTITY_STORAGE_MIGRATION_FAILED', details: err};\n }\n }\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n\n return this._cache.length;\n }\n\n markAsDirty(opts?: { emitEvent?: boolean }) {\n this._dirty = true;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n }\n\n markAsPristine(opts?: { emitEvent?: boolean }) {\n\n for (const s of this._statusById.values()) {\n if (isNotNil(s)) {\n s.dirty = false;\n }\n }\n this._dirty = false;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n }\n\n /* -- protected methods -- */\n\n private loadCachedEntity(id: ID, opts?: EntityStorageLoadOptions): T {\n const status = this._statusById.get(id);\n const index = status && status.index;\n if (isNil(index)) return undefined; // not exists\n return Object.freeze(this._cache[index]);\n }\n\n private async loadFullEntity(id: ID, opts?: EntityStorageLoadOptions): Promise<T> {\n const status = this._statusById.get(id);\n const index = status && status.index;\n if (isNil(index)) return undefined; // not exists\n\n // Reload from storage, if need (e.g. some attributes has been excluded in light elements)\n if (status.dirty === false) {\n console.debug(`[entity-storage] Full reloading ${this.name}#${id}...`);\n const fullData = await this.storage.get(this._storageKey + '#' + id);\n if (fullData) return fullData;\n // Not found by id, continue from cache (version prior to 1.5.3)\n }\n\n // Load from the cache, if dirty OR if storage is not splited by id\n return this._cache[index];\n }\n\n private setEntities(entities: T[], opts?: {emitEvent?: boolean }) {\n // Filter non nil (and if need non local) entities\n entities = (entities || [])\n .filter(item => isNotNil(item)\n && (!this.policy.skipNonLocalEntities || +item.id < 0)\n );\n\n this._cache = entities;\n\n // Update the sequence with min(id) of all temporary ids\n this._sequence = this._cache.reduce((res, item) => +item.id < 0 ? Math.min(res, +item.id) : res, 0);\n\n this._statusById.clear();\n this._cache.forEach((item, index) => {\n this._statusById.set(item.id, <EntityStatus>{\n index,\n dirty: false\n });\n });\n\n this._loaded = true;\n\n // Emit update event\n if (!opts || opts.emitEvent !== false) {\n this.emitEvent();\n }\n }\n\n\n /**\n * WIll apply a filter, then a sort, then a page slice\n *\n * @param data\n * @param variables\n */\n private reduceAndSort(data: T[],\n variables: {\n offset?: number;\n size?: number;\n sortBy?: string;\n sortDirection?: string;\n filter?: (T) => boolean;\n }): LoadResult<T> {\n if (isEmptyArray(data)) {\n return {data: [], total: 0};\n }\n\n // Remove nil values\n data = data.filter(isNotNil);\n\n if (!variables) {\n // Return all (but array has been filtered, and copied)\n return {data, total: data.length};\n }\n\n // Apply the filter, if any\n if (variables.filter) {\n data = data.filter(variables.filter);\n }\n\n // Compute the total length\n const total = data.length;\n\n // If page size=0 (e.g. only need total)\n if (variables.size === 0) return {data: [], total};\n\n // Sort by\n if (variables.sortBy) {\n EntityUtils.sort(data, variables.sortBy, variables.sortDirection);\n }\n\n // Slice in a page (using offset and size)\n if (variables.offset > 0) {\n\n // Offset after the end: no result\n if (variables.offset >= data.length || variables.size === 0) {\n data = [];\n }\n else {\n data = (variables.size > 0 && ((variables.offset + variables.size) < data.length)) ?\n // Slice using limit to size\n data.slice(variables.offset, variables.offset + variables.size) :\n // Slice without limit\n data.slice(variables.offset);\n }\n }\n\n // Apply a limit\n else if (variables.size > 0){\n data = data.slice(0, variables.size);\n }\n // No limit:\n else if (variables.size === -1){\n // Keep all data\n }\n\n return {data, total};\n }\n\n private createLightEntityMapFn(policy: EntityStoreTypePolicy<T>): (T) => T {\n if (policy.mode !== 'by-id') return undefined; // Only need for the 'by-id' mode\n if (isEmptyArray(policy.lightFieldsExcludes)) return undefined; // skip\n\n // Create a immutable mask object, use to clean some properties\n const excludeAttributesMask = Object.freeze(this.policy.lightFieldsExcludes.reduce((res, attr) => {\n res[attr] = undefined;\n return res;\n }, <T>{}));\n\n return (entity) => entity ? Object.assign(<T>{}, entity, excludeAttributesMask) : undefined;\n }\n\n /**\n * Update the entitiesSubject.\n *\n * Before wending items, a filter is apply, to remove null value.\n * This filter will create a array copy.\n */\n private emitEvent() {\n this._onChange.next(true);\n }\n}\n","import {defer, merge, Observable, timer} from 'rxjs';\nimport {EventEmitter, Inject, Injectable, InjectionToken, Optional} from '@angular/core';\nimport {Storage} from '@ionic/storage';\nimport {Platform} from '@ionic/angular';\nimport {first, switchMap, throttleTime} from 'rxjs/operators';\nimport {Entity, IEntity} from '../model/entity.model';\nimport {isEmptyArray, isNilOrBlank} from '../../../shared/functions';\nimport {LoadResult} from '../../../shared/services/entity-service.class';\nimport {ENTITIES_STORAGE_KEY_PREFIX, EntityStorageLoadOptions, EntityStore, EntityStoreTypePolicy} from './entity-store.class';\nimport {ProgressBarService} from '../../../shared/services/progress-bar.service';\nimport {Environment, ENVIRONMENT} from '../../../../environments/environment.class';\nimport {StartableService} from '../../../shared/services/startable-service.class';\nimport {chainPromises} from '../../../shared/observables';\n\n\nexport interface EntitiesStorageTypePolicies {\n [__typename: string]: EntityStoreTypePolicy;\n}\n\nexport const APP_LOCAL_STORAGE_TYPE_POLICIES = new InjectionToken<EntitiesStorageTypePolicies>('localStorageTypePolicies');\n\ndeclare interface EntityStorageMap { [key: string]: EntityStore<any, any> };\n\n@Injectable({providedIn: 'root'})\nexport class EntitiesStorage extends StartableService<EntityStorageMap> {\n\n static readonly TRASH_PREFIX = 'Trash#';\n static readonly REMOTE_PREFIX = 'Remote#';\n\n private readonly _typePolicies: EntitiesStorageTypePolicies;\n private readonly _saveTimerPeriod;\n\n private _$save = new EventEmitter(true);\n private _dirty = false;\n private _saving = false;\n\n get dirty(): boolean {\n return this._dirty || Object.values(this._data).some(store => store.dirty);\n }\n\n public constructor(\n private platform: Platform,\n private progressBarService: ProgressBarService,\n private storage: Storage,\n @Inject(ENVIRONMENT) protected environment: Environment,\n @Optional() @Inject(APP_LOCAL_STORAGE_TYPE_POLICIES) typePolicies: EntitiesStorageTypePolicies\n ) {\n super(platform);\n this._typePolicies = typePolicies || {};\n this._saveTimerPeriod = environment.storageSavePeriodMs || 10000 /* = 10s */;\n this._data = {};\n\n // For DEV only\n this._debug = !environment.production;\n if (this._debug) console.debug('[entities-storage] Creating service');\n }\n\n\n async ngOnStart(): Promise<EntityStorageMap> {\n const now = Date.now();\n console.info(`[entities-storage] Starting entity storage...`);\n\n // Restore stores\n await this.restoreLocally();\n\n // Start a save timer\n this.registerSubscription(\n merge(\n this._$save,\n timer(this._saveTimerPeriod, this._saveTimerPeriod)\n )\n .pipe(\n // Avoid to many call (e.g. when $save AND timer are triggered\n throttleTime(this._saveTimerPeriod)\n )\n .subscribe(() => this.storeLocally({skipIfPristine: true}))\n );\n\n // Save, when platform is in pause\n this.registerSubscription(\n this.platform.pause.subscribe(async () => {\n console.warn(`[entities-storage] Platform will pause: saving...`);\n await this.storeLocally({skipIfPristine: true});\n console.warn(`[entities-storage] Platform will pause: saving [OK]`);\n })\n );\n\n console.info(`[entities-storage] Starting [OK] in ${Date.now() - now}ms`);\n\n return this._data;\n }\n\n protected async ngOnStop() {\n await this.storeLocally({skipIfPristine: true});\n }\n\n watchAll<T extends Entity<T>>(entityName: string,\n variables: {\n offset?: number;\n size?: number;\n sortBy?: string;\n sortDirection?: string;\n trash?: boolean;\n filter?: (T) => boolean;\n },\n opts?: EntityStorageLoadOptions): Observable<LoadResult<T>> {\n // Make sure store is ready\n if (!this.started) {\n return defer(() => this.ready())\n .pipe(switchMap(() => this.watchAll<T>(entityName, variables, opts))); // Loop\n }\n\n this.progressBarService.increase();\n const storeName = variables && variables.trash ? (EntitiesStorage.TRASH_PREFIX + entityName) : entityName;\n const result = this.getEntityStore<T>(storeName, {create: true})\n .watchAll(variables, opts);\n\n result.pipe(first()).subscribe(() => this.progressBarService.decrease());\n\n return result;\n }\n\n async loadAll<T extends Entity<T>>(entityName: string,\n variables?: {\n offset?: number;\n size?: number;\n sortBy?: string;\n sortDirection?: string;\n filter?: (T) => boolean;\n },\n opts?: EntityStorageLoadOptions): Promise<LoadResult<T>> {\n\n // Make sure store is ready\n if (!this.started) await this.ready();\n\n try {\n this.progressBarService.increase();\n if (this._debug) console.debug(`[entities-storage] Loading ${entityName}...`);\n\n const entityStore = this.getEntityStore<T>(entityName, {create: false});\n if (!entityStore) return {data: [], total: 0}; // No store for this entity name\n\n return entityStore.loadAll(variables, opts);\n }\n finally {\n this.progressBarService.decrease();\n }\n }\n\n async load<T extends Entity<T>>(id: number, entityName: string, opts?: EntityStorageLoadOptions): Promise<T> {\n await this.ready();\n\n try {\n this.progressBarService.increase();\n\n const entityStore = this.getEntityStore<T>(entityName, {create: false});\n if (!entityStore) return undefined;\n return await entityStore.load(id, opts);\n }\n finally {\n this.progressBarService.decrease();\n }\n }\n\n async nextValue(entityOrName: string | any): Promise<number> {\n await this.ready();\n this._dirty = true;\n return this.getEntityStore(this.detectEntityName(entityOrName)).nextValue();\n }\n\n async nextValues(entityOrName: string | any, entityCount: number): Promise<number> {\n await this.ready();\n this._dirty = true;\n const entityName = this.detectEntityName(entityOrName);\n const store = this.getEntityStore(entityName);\n const firstValue = store.nextValue();\n for (let i = 0; i < entityCount - 1; i++) {\n store.nextValue();\n }\n if (this._debug) console.debug(`[entities-storage] Reserving range [${firstValue},${store.currentValue()}] for ${entityName}'s sequence`);\n return firstValue;\n }\n\n async currentValue(entityOrName: string | any): Promise<number> {\n await this.ready();\n return this.getEntityStore(this.detectEntityName(entityOrName)).currentValue();\n }\n\n async save<T extends Entity<T>>(entity: T, opts?: {\n entityName?: string;\n emitEvent?: boolean;\n }): Promise<T> {\n if (!entity) return; // skip\n\n if (!this.started) await this.ready();\n\n try {\n this.progressBarService.increase();\n\n this._dirty = true;\n const storeName = opts && opts.entityName || this.detectEntityName(entity);\n this.getEntityStore<T>(storeName)\n .save(entity, opts);\n\n // Ask to save\n this._$save.emit();\n\n return entity;\n }\n finally {\n this.progressBarService.decrease();\n }\n }\n\n async saveAll<T extends Entity<T>>(entities: T[], opts?: {\n entityName?: string;\n reset?: boolean;\n emitEvent?: boolean;\n }): Promise<T[]> {\n if (isEmptyArray(entities) && (!opts || opts.reset !== true)) return entities; // Skip (nothing to save)\n\n if (!this.started) await this.ready();\n\n try {\n this.progressBarService.increase();\n\n this._dirty = true;\n const entityName = opts && opts.entityName || this.detectEntityName(entities[0]);\n return this.getEntityStore<T>(entityName).saveAll(entities, opts);\n }\n finally {\n this.progressBarService.decrease();\n }\n }\n\n async delete<T extends Entity<T, ID>, ID = number>(entity: T, opts?: {\n entityName?: string;\n }): Promise<T> {\n if (!entity) return undefined; // skip\n\n if (!this.started) await this.ready();\n\n return this.deleteById(entity.id, {\n ...opts,\n entityName: opts && opts.entityName || this.detectEntityName(entity)\n });\n }\n\n async deleteById<T extends IEntity<T, ID>, ID = number>(id: ID, opts: {\n entityName: string;\n emitEvent?: boolean;\n }): Promise<T> {\n if (!this.started) await this.ready();\n\n if (!opts || isNilOrBlank(opts.entityName)) throw new Error('Missing argument \\'opts\\' or \\'entityName\\'');\n //if (id >= 0) throw new Error('Invalid id a local entity (not a negative number): ' + id);\n\n try {\n this.progressBarService.increase();\n const entityStore = this.getEntityStore<T, ID>(opts.entityName, {create: false});\n if (!entityStore) return undefined;\n\n const deletedEntity = entityStore.delete(id, opts);\n\n // If something deleted\n if (deletedEntity) {\n\n // Mark as dirty\n this._dirty = true;\n\n // Ask to save\n this._$save.emit();\n }\n\n return deletedEntity;\n }\n finally {\n this.progressBarService.decrease();\n }\n }\n\n async deleteMany<T extends Entity<T>>(ids: number[], opts: {\n entityName: string;\n emitEvent?: boolean;\n }): Promise<T[]> {\n if (!this.started) await this.ready();\n\n if (!opts || isNilOrBlank(opts.entityName)) throw new Error('Missing argument \\'opts\\' or \\'opts.entityName\\'');\n\n try {\n this.progressBarService.increase();\n const entityStore = this.getEntityStore<T>(opts.entityName, {create: false});\n if (!entityStore) return undefined;\n\n // Do deletion\n const deletedEntities = entityStore.deleteMany(ids, opts);\n\n // If something deleted\n if (deletedEntities.length > 0) {\n\n // Mark as dirty\n this._dirty = true;\n\n // Mark as save need\n this._$save.emit();\n\n }\n\n return deletedEntities;\n } finally {\n this.progressBarService.decrease();\n }\n }\n\n async deleteFromTrash<T extends Entity<T>>(entity: T, opts?: {\n entityName?: string;\n }): Promise<T> {\n if (!entity) return undefined; // skip\n\n if (!this.started) await this.ready();\n\n return this.deleteFromTrashById(entity.id, {\n ...opts,\n entityName: opts && opts.entityName || this.detectEntityName(entity)\n });\n }\n\n async deleteFromTrashById<T extends Entity<T>>(id: number, opts: {\n entityName: string;\n emitEvent?: boolean;\n }): Promise<T> {\n await this.ready();\n\n if (!opts || isNilOrBlank(opts.entityName)) throw new Error('Missing argument \\'opts\\' or \\'entityName\\'');\n\n return this.deleteById(id, {\n ...opts,\n entityName: EntitiesStorage.TRASH_PREFIX + opts.entityName\n });\n }\n\n async moveToTrash<T extends Entity<T>>(entity: T, opts?: {\n entityName?: string;\n emitEvent?: boolean;\n }): Promise<T> {\n if (!entity) return undefined; // skip\n\n if (!this.started) await this.ready();\n\n const entityName = opts && opts.entityName || this.detectEntityName(entity);\n\n // Delete entity by id, if exists\n const entityStore = this.getEntityStore<T>(entityName);\n if (entityStore) entityStore.delete(entity.id, opts);\n\n // Clean id (a new id will be set by the trash store)\n entity.id = undefined;\n\n // Add to trash\n const trashName = EntitiesStorage.TRASH_PREFIX + entityName;\n this.getEntityStore<T>(trashName).save(entity, opts);\n\n this._$save.emit();\n\n return entity;\n }\n\n async moveManyToTrash<T extends Entity<T>>(ids: number[], opts: {\n entityName: string;\n emitEvent?: boolean;\n }): Promise<T[]> {\n if (!this.started) await this.ready();\n\n if (!opts || isNilOrBlank(opts.entityName)) throw new Error('Missing argument \\'opts.entityName\\'');\n\n const entityStore = this.getEntityStore<T>(opts.entityName, {create: false});\n if (!entityStore) return undefined;\n\n // Do deletion\n const deletedEntities = entityStore.deleteMany(ids, opts);\n\n // If something deleted\n if (deletedEntities.length > 0) {\n\n // Clean ids (new ids will be set by the trash store)\n deletedEntities.forEach(e => e.id = undefined);\n\n const trashName = EntitiesStorage.TRASH_PREFIX + opts.entityName;\n this.getEntityStore<T>(trashName, {create: true})\n .saveAll(deletedEntities, opts);\n\n // Mark as dirty\n this._dirty = true;\n\n // Mark as save need\n this._$save.emit();\n }\n\n return deletedEntities;\n }\n\n async saveToTrash<T extends Entity<T>>(entity: T, opts?: {\n entityName?: string;\n emitEvent?: boolean;\n }): Promise<T> {\n if (!entity) return undefined; // skip\n\n if (!this.started) await this.ready();\n\n const entityName = opts && opts.entityName || this.detectEntityName(entity);\n const trashName = EntitiesStorage.TRASH_PREFIX + entityName;\n this.getEntityStore<T>(trashName).save(entity, opts);\n\n this._$save.emit();\n\n return entity;\n }\n\n async clearTrash(entityName: string) {\n if (!this.started) await this.ready();\n\n const trashName = EntitiesStorage.TRASH_PREFIX + entityName;\n const entityStore = this.getEntityStore(trashName, {create: false});\n if (!entityStore) return; // Skip\n\n entityStore.reset();\n this._dirty = true;\n\n this._$save.emit();\n }\n\n persist(opts = {skipIfPristine: true}): Promise<void> {\n return this.storeLocally(opts);\n }\n\n /* -- protected methods -- */\n\n protected getEntityStore<T extends IEntity<T, ID>, ID = number>(name: string, opts?: {\n create?: boolean;\n }): EntityStore<T, ID> {\n let store = this._data[name];\n if (!store && (!opts || opts.create !== false)) {\n if (this._debug) console.debug(`[entities-storage] Creating store ${name}`);\n const typePolicy = this._typePolicies[name];\n store = new EntityStore<T, ID>(name, this.storage, typePolicy);\n this._data[name] = store;\n }\n return store;\n }\n\n protected detectEntityName(entityOrName: string | Entity<any, any>): string {\n if (!entityOrName) throw Error('Unable to detect entityName of object: ' + entityOrName);\n if (typeof entityOrName === 'string') return entityOrName;\n if (entityOrName.__typename) {\n return entityOrName.__typename;\n }\n return entityOrName.constructor.name + 'VO';\n }\n\n protected async restoreLocally() {\n\n const entityNames = await this.storage.get(ENTITIES_STORAGE_KEY_PREFIX);\n if (!entityNames) return;\n\n const now = this._debug && Date.now();\n if (this._debug) console.info('[entities-storage] Restoring entities...');\n const entitiesCount = (await Promise.all<number>(\n entityNames\n .map(name => this.getEntityStore<any>(name))\n .map((store: EntityStore<any>) => store.restore()))\n ).reduce((res, count) => (res + count), 0);\n\n if (this._debug) console.debug(`[entities-storage] Restoring entities [OK] ${entitiesCount} entities found in ${Date.now() - now}ms`);\n }\n\n protected async storeLocally(opts = {skipIfPristine: true}): Promise<void> {\n if (opts.skipIfPristine && !this.dirty) return; // skip\n\n // Saving progress: report this save later\n if (this._saving) {\n if (this._debug) console.debug('[entities-storage] Previous persist not finished. Waiting...');\n this._$save.emit();\n return;\n }\n\n this._saving = true;\n this._dirty = false;\n this.progressBarService.increase();\n const entityNames = this._data && Object.keys(this._data) || [];\n\n const now = Date.now();\n if (this._debug) console.debug('[entities-storage] Persisting...');\n\n let currentEntityName;\n return chainPromises(\n entityNames.map(entityName => () => {\n currentEntityName = entityName;\n const entityStore = this.getEntityStore(entityName, {create: false});\n\n if (!entityStore) {\n console.warn(`[entities-storage] Persisting ${entityName}: store not found!`);\n return;\n }\n\n // SKip store if pristine\n if (opts.skipIfPristine && !entityStore.dirty) return Promise.resolve();\n\n // Persist store\n return entityStore.persist(opts)\n .then(count => {\n // If no entity found, remove from the entity names array\n if (!count) {\n const entityNameIndex = entityNames.findIndex(e => e === entityName);\n if (entityNameIndex !== -1) entityNames.splice(entityNameIndex, 1);\n }\n });\n }))\n .then(() => {\n currentEntityName = undefined;\n return isEmptyArray(entityNames) ?\n this.storage.remove(ENTITIES_STORAGE_KEY_PREFIX) :\n this.storage.set(ENTITIES_STORAGE_KEY_PREFIX, entityNames);\n })\n .then(() => {\n if (this._debug) console.debug(`[entities-storage] Persisting [OK] ${entityNames.length} stores saved in ${Date.now() - now}ms...`);\n this._saving = false;\n this.progressBarService.decrease();\n })\n .catch(err => {\n this._saving = false;\n this.progressBarService.decrease();\n if (currentEntityName) {\n console.error(`[entities-storage] Error while persisting ${currentEntityName}`, err);\n } else {\n console.error(`[entities-storage] Error while persisting: ${err && err.message || err}`, err);\n }\n throw err;\n });\n }\n\n}\n","import {isEmptyArray} from '../functions';\nimport {chainPromises} from '../observables';\n\nexport class StorageUtils {\n\n /**\n * Copy one storage content, into anthoer\n *\n * @param from\n * @param to\n */\n static async copy(from: LocalForage, to: LocalForage, options?: {\n keys: string[];\n deleteAfterCopy?: boolean;\n }) {\n if (!from || !to || from === to) throw new Error('Invalid \\'from\\' or \\'to\\' arguments. Must be not null storage');\n\n options = {deleteAfterCopy: false, ...options};\n\n // Get keys to copy\n const keys = options.keys || (await from.keys());\n if (isEmptyArray(keys)) return Promise.resolve(); // Nothing to copy\n\n const now = Date.now();\n console.info(`[storage-utils] Copying ${keys.length} keys from '${from.driver()}' to '${to.driver()}'... {deleteAfterCopy: ${options.deleteAfterCopy}`);\n let errorCount = 0;\n\n return chainPromises(\n keys.map(key => () => from.getItem(key)\n .then((data) => to.setItem(key, data))\n .then(() => options.deleteAfterCopy && from.removeItem(key))\n .catch((err) => {\n console.error(`[storage-utils] Error during migration of key '${key}'`, err);\n errorCount++;\n }))\n )\n .then(() => {\n if (errorCount === 0) {\n console.info(`[storage-utils] Migrating data [OK] in ${Date.now() - now}ms`);\n }\n else {\n throw {message: 'ERROR.COPY_STORAGE_ERROR'};\n }\n });\n }\n}\n\n","import {equals, isNil} from '../../../shared/functions';\nimport {Entity, EntityAsObjectOptions} from './entity.model';\nimport {LatLongPattern} from '../../../shared/material/latlong/latlong.utils';\nimport {PropertiesMap, Property} from '../../../shared/types';\nimport {InjectionToken} from '@angular/core';\nimport {EntityClass} from './entity.decorators';\nimport {HistoryPageReference} from './history.model';\n\nexport type UsageMode = 'DESK' | 'FIELD';\n\nexport declare interface LocaleConfig extends Property {\n country?: string;\n}\n\nexport const APP_LOCALES = new InjectionToken<LocaleConfig[]>('locales');\n\nexport declare interface OfflineFeature {\n name: string;\n lastSyncDate?: string;\n filter?: any;\n}\n\nexport declare interface LocalSettings {\n pages?: any;\n peerUrl?: string;\n latLongFormat: 'DDMMSS' | 'DDMM' | 'DD';\n accountInheritance?: boolean;\n locale: string;\n usageMode?: UsageMode;\n mobile?: boolean;\n properties?: PropertiesMap;\n pageHistory?: HistoryPageReference[];\n offlineFeatures?: (string | OfflineFeature)[];\n pageHistoryMaxSize: number;\n}\n\n\n// @dynamic\n@EntityClass({typename: 'UserSettingsVO'})\nexport class UserSettings extends Entity<UserSettings> {\n\n static SETTINGS_PROPERTIES = [<keyof UserSettings>'locale', <keyof UserSettings>'latLongFormat'] as string[];\n static fromObject: (source: any, opts?: any) => UserSettings;\n\n locale: string;\n latLongFormat: LatLongPattern;\n content: {};\n nonce: string;\n\n constructor() {\n super(UserSettings.TYPENAME);\n }\n\n asObject(opts?: EntityAsObjectOptions): any {\n const target = super.asObject(opts);\n if (opts?.minify) {\n // Stringify content\n target.content = this.content && JSON.stringify(target.content) || undefined;\n }\n return target;\n }\n\n fromObject(source: any, opts?: any) {\n super.fromObject(source);\n this.locale = source.locale;\n this.latLongFormat = source.latLongFormat as LatLongPattern;\n if (isNil(source.content) || typeof source.content === 'object') {\n this.content = source.content || {};\n } else {\n this.content = source.content && JSON.parse(source.content) || {};\n }\n this.nonce = source.nonce;\n }\n\n merge<S = LocalSettings>(source: S, includesProperties: (keyof S)[]): boolean {\n if (!source) return; // Skip\n\n // Reset content\n this.content = {};\n let hasChanges = false;\n\n // For each property of source object\n Object.keys(source)\n .forEach(key => {\n // If property exists in UserSettings class: store it directly\n if (UserSettings.SETTINGS_PROPERTIES.includes(key)) {\n if (!equals(this[key], source[key])) {\n this[key] = source[key];\n hasChanges = true;\n }\n }\n // Else, store property into the 'content' map\n else if (includesProperties && includesProperties.includes(key as keyof S)){\n if (!equals(this.content[key], source[key])) {\n this.content[key] = Object.assign({}, source[key]);\n hasChanges = true;\n }\n }\n });\n return hasChanges;\n }\n\n asLocalSettings(): Partial<LocalSettings> {\n const target = {};\n UserSettings.SETTINGS_PROPERTIES.forEach(key => {\n target[key] = this[key];\n });\n Object.keys(this.content).forEach(key => {\n target[key] = this.content[key];\n });\n return target;\n }\n}\n","\n// TODO: rename to STATUS_ID_MAP\n// then declare a type like this :\n// > export declare type StatusIds = keyof typeof STATUS_ID_MAP;\nexport const StatusIds = {\n DISABLE: 0,\n ENABLE: 1,\n TEMPORARY: 2,\n DELETED: 3,\n ALL: 99\n};\n","import {Moment} from 'moment';\nimport { joinPropertiesPath, splitById, toNumber } from '../../../shared/functions';\nimport {Entity, EntityAsObjectOptions, EntityUtils, IEntity} from './entity.model';\nimport {StatusIds} from './model.enum';\nimport {fromDateISOString, toDateISOString} from '../../../shared/dates';\nimport {EntityClass} from './entity.decorators';\n\nexport function referentialToString(obj: Referential | any, properties?: string[]): string | undefined {\n return obj && obj.id && joinPropertiesPath(obj, properties || ['label', 'name']) || undefined;\n}\nexport function referentialsToString(values: Referential[], properties?: string[], separator?: string): string {\n return (values || []).map(v => referentialToString(v, properties)).join(separator || ', ');\n}\n\nexport declare interface IStatus {\n id: number;\n icon?: string;\n label: string;\n}\n\nexport const StatusList: Readonly<IStatus[]> = Object.freeze([\n {\n id: StatusIds.ENABLE,\n icon: 'checkmark',\n label: 'REFERENTIAL.STATUS_ENUM.ENABLE'\n },\n {\n id: StatusIds.DISABLE,\n icon: 'close',\n label: 'REFERENTIAL.STATUS_ENUM.DISABLE'\n },\n {\n id: StatusIds.TEMPORARY,\n icon: 'help',\n label: 'REFERENTIAL.STATUS_ENUM.TEMPORARY'\n }\n]);\n\nexport const StatusById = Object.freeze(splitById(StatusList));\n\nexport declare interface IReferentialRef<\n T extends IEntity<T, ID> = IEntity<any, any>,\n ID = number\n >\n extends IEntity<T, ID> {\n label: string;\n name: string;\n description?: string;\n levelId?: number;\n statusId: number;\n entityName: string;\n}\n\n//@dynamic\nexport abstract class BaseReferential<\n T extends BaseReferential<T, ID, AO>,\n ID = number,\n AO extends ReferentialAsObjectOptions = ReferentialAsObjectOptions,\n FO = any\n >\n extends Entity<T, ID, AO, FO>\n implements IReferentialRef<T, ID> {\n\n label: string;\n name: string;\n description: string;\n comments: string;\n creationDate: Date | Moment;\n statusId: number;\n validityStatusId: number;\n levelId: number;\n parentId: number;\n entityName: string;\n\n constructor(__typename?: string) {\n super(__typename);\n }\n\n asObject(opts?: AO): any {\n if (opts && opts.minify) {\n return {\n id: this.id,\n entityName: opts.keepEntityName && this.entityName || undefined, // Don't keep by default\n __typename: opts.keepTypename && this.__typename || undefined\n };\n }\n const target: any = super.asObject(opts);\n target.creationDate = toDateISOString(this.creationDate);\n if (opts && opts.keepTypename === false) delete target.entityName;\n return target;\n }\n\n fromObject(source: any, opts?: FO) {\n super.fromObject(source, opts);\n this.label = source.label;\n this.name = source.name;\n this.description = source.description;\n this.comments = source.comments;\n this.statusId = source.statusId;\n this.validityStatusId = source.validityStatusId;\n this.levelId = source.levelId && source.levelId !== 0 ? source.levelId : undefined; // Do not set as null (need for account.department, when register)\n this.parentId = source.parentId;\n this.creationDate = fromDateISOString(source.creationDate);\n this.entityName = source.entityName;\n }\n\n equals(other: T): boolean {\n return super.equals(other) && this.entityName === other.entityName;\n }\n}\n\n// @dynamic\n@EntityClass({typename: 'ReferentialVO'})\nexport class Referential<\n T extends Referential<T, any> = Referential<any>,\n ID = number\n >\n extends BaseReferential<T, ID> {\n\n static fromObject: (source: any, opts?: any) => Referential;\n}\n\nexport class ReferentialUtils {\n // FIXME: remove this\n static fromObject(source: any): Referential {\n if (!source || source instanceof Referential) return source;\n const res = new Referential();\n res.fromObject(source);\n return res as Referential;\n }\n\n static isNotEmpty<T extends IReferentialRef<T>>(obj: T|any): boolean {\n // A referential entity should always have a 'id' filled (can be negative is local and temporary)\n return EntityUtils.isNotEmpty(obj, 'id');\n }\n\n static isEmpty<T extends IReferentialRef<T>>(obj: T|any): boolean {\n return EntityUtils.isEmpty(obj, 'id');\n }\n\n static equals<T extends IReferentialRef<T>>(o1: T|any, o2: T|any): boolean {\n return EntityUtils.equals(o1, o2, 'id');\n }\n}\n\n\nexport interface ReferentialAsObjectOptions extends EntityAsObjectOptions {\n keepEntityName?: boolean;\n}\n\n/**\n * Used to store an entity locally\n */\nexport const MINIFY_ENTITY_FOR_LOCAL_STORAGE: ReferentialAsObjectOptions = Object.freeze({\n minify: true,\n keepTypename: true,\n keepEntityName: true,\n keepLocalId: true\n});\n\n/**\n * Used to send an entity to a pod\n */\nexport const MINIFY_ENTITY_FOR_POD: ReferentialAsObjectOptions = Object.freeze({\n minify: true,\n keepTypename: false,\n keepEntityName: false,\n keepLocalId: false\n});\n\n// @dynamic\n@EntityClass({typename: 'ReferentialVO'})\nexport class ReferentialRef<\n T extends ReferentialRef<any, ID> = ReferentialRef<any, any>,\n ID = number,\n O extends ReferentialAsObjectOptions = ReferentialAsObjectOptions,\n FO = any\n >\n extends Entity<T, ID, O, FO>\n implements IReferentialRef<T, ID> {\n\n static fromObject: (source: any, opts?: any) => ReferentialRef;\n\n label: string;\n name: string;\n description: string;\n statusId: number;\n levelId: number;\n entityName: string;\n\n constructor() {\n super(ReferentialRef.TYPENAME);\n }\n\n asObject(opts?: O): any {\n if (opts && opts.minify) {\n return {\n id: this.id,\n entityName: opts.keepEntityName && this.entityName || undefined, // Don't keep by default\n __typename: opts.keepTypename && this.__typename || undefined\n };\n }\n const target: any = super.asObject(opts);\n if (opts && opts.keepEntityName === false) delete target.entityName;\n\n return target;\n }\n\n fromObject(source: any, opts?: FO) {\n super.fromObject(source);\n this.entityName = source.entityName || this.entityName;\n this.label = source.label;\n this.name = source.name;\n this.description = source.description;\n this.statusId = source.statusId;\n this.levelId = source.levelId;\n }\n}\n","import {BaseReferential} from './referential.model';\nimport {EntityClass} from './entity.decorators';\n\n// @dynamic\n@EntityClass({typename: 'DepartmentVO'})\nexport class Department extends BaseReferential<Department> {\n\n static ENTITY_NAME = 'Department';\n static fromObject: (source: any, opts?: any) => Department;\n\n logo: string;\n siteUrl: string;\n\n constructor() {\n super(Department.TYPENAME);\n this.entityName = Department.ENTITY_NAME;\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.entityName = source.entityName || Department.ENTITY_NAME;\n this.logo = source.logo;\n this.siteUrl = source.siteUrl;\n delete this.entityName; // not need\n }\n}\n\nexport function departmentToString(obj: Department): string {\n return obj && obj.id && (obj.name) || undefined;\n}\n\nexport function departmentsToString(data: Department[], separator?: string): string {\n return (data || []).map(departmentToString).join(separator || ', ');\n}\n","import {Moment} from 'moment';\nimport {ReferentialAsObjectOptions} from './referential.model';\nimport {Entity} from './entity.model';\nimport {Department} from './department.model';\nimport {fromDateISOString, toDateISOString} from '../../../shared/dates';\nimport {EntityClass} from './entity.decorators';\nimport {isEmptyArray} from '../../../shared/functions';\n\n\nexport type UserProfileLabel = 'ADMIN' | 'USER' | 'SUPERVISOR' | 'GUEST';\nexport const PRIORITIZED_AUTHORITIES: Readonly<UserProfileLabel[]> = Object.freeze(['ADMIN', 'SUPERVISOR', 'USER', 'GUEST']);\n\n// @dynamic\n@EntityClass({typename: 'PersonVO'})\nexport class Person<\n T extends Person<any> = Person<any>\n > extends Entity<T, number, ReferentialAsObjectOptions> {\n\n static fromObject: (source: any, opts?: any) => Person;\n\n firstName: string;\n lastName: string;\n email: string;\n pubkey: string;\n avatar: string;\n creationDate: Date | Moment;\n statusId: number;\n department: Department = null;\n username: string;\n usernameExtranet: string;\n profiles: string[];\n mainProfile: string;\n\n constructor(__typename?: string) {\n super(__typename || Person.TYPENAME);\n }\n\n asObject(opts?: ReferentialAsObjectOptions): any {\n if (opts && opts.minify) {\n return {\n id: this.id,\n __typename: opts.keepTypename && this.__typename || undefined,\n firstName: this.firstName,\n lastName: this.lastName\n };\n }\n const target: any = super.asObject(opts);\n target.department = this.department && this.department.asObject(opts) || undefined;\n target.profiles = this.profiles && this.profiles.slice(0) || [];\n // Set profile list from the main profile\n target.profiles = this.mainProfile && [this.mainProfile] || target.profiles;\n target.creationDate = toDateISOString(this.creationDate);\n\n if (!opts || opts.minify !== true) target.mainProfile = PersonUtils.getMainProfile(target.profiles);\n return target;\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.firstName = source.firstName;\n this.lastName = source.lastName;\n this.email = source.email;\n this.creationDate = fromDateISOString(source.creationDate);\n this.pubkey = source.pubkey;\n this.username = source.username;\n this.usernameExtranet = source.usernameExtranet;\n this.avatar = source.avatar;\n this.statusId = source.statusId;\n this.department = source.department && Department.fromObject(source.department) || undefined;\n this.profiles = source.profiles && source.profiles.slice(0) || [];\n // Add main profile to the list, if need\n if (source.mainProfile && !this.profiles.find(p => p === source.mainProfile)) {\n this.profiles = this.profiles.concat(source.mainProfile);\n }\n this.mainProfile = PersonUtils.getMainProfile(this.profiles);\n }\n}\n\nexport class PersonUtils {\n static getMainProfile(profiles?: string[]): UserProfileLabel {\n if (isEmptyArray(profiles)) return 'GUEST';\n return PRIORITIZED_AUTHORITIES.find(label => profiles.includes(label)) || 'GUEST';\n }\n\n static getMainProfileIndex(profiles?: string[]): number {\n if (isEmptyArray(profiles)) return PRIORITIZED_AUTHORITIES.length - 1; // return last (lower) profile\n const index = PRIORITIZED_AUTHORITIES.findIndex(label => profiles.includes(label));\n return (index !== -1) ? index : (PRIORITIZED_AUTHORITIES.length - 1);\n }\n\n static hasUpperOrEqualsProfile(actualProfiles: string[], expectedProfile: UserProfileLabel): boolean {\n const expectedProfileIndex = PRIORITIZED_AUTHORITIES.indexOf(expectedProfile);\n return expectedProfileIndex !== -1 && PersonUtils.getMainProfileIndex(actualProfiles) <= expectedProfileIndex;\n }\n\n static personToString(obj: Person): string {\n if (!obj || !obj.id) return undefined;\n return obj.lastName + ' ' + obj.firstName;\n }\n\n static personsToString(data: Person[], separator?: string): string {\n return (data || []).map(PersonUtils.personToString).join(separator || ', ');\n }\n\n}\n\n\n\n\n\n\n\n","import {LocalSettings, UserSettings} from './settings.model';\nimport {Person} from './person.model';\nimport {EntityAsObjectOptions} from './entity.model';\nimport {EntityClass} from './entity.decorators';\n\n/**\n * A user account\n */\n// @dynamic\n@EntityClass({typename: 'AccountVO'})\nexport class Account extends Person<Account> {\n\n static fromObject: (source: any, opts?: any) => Account;\n\n settings: UserSettings = null;\n\n constructor() {\n super(Account.TYPENAME);\n }\n\n asObject(opts?: EntityAsObjectOptions): any {\n const target: any = super.asObject({...opts, minify: false /*disable Person minify (too restrictive) */});\n target.settings = this.settings && this.settings.asObject(opts) || undefined;\n if (opts?.minify) {\n delete target.mainProfile; // Not known on server\n }\n return target;\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.settings = source.settings && UserSettings.fromObject(source.settings);\n }\n\n /**\n * Convert into a Person. This will fill __typename with a right value, for data cache\n */\n asPerson(): Person {\n const person = Person.fromObject(this.asObject({\n keepTypename: true // This is need for the department object\n }));\n person.__typename = Person.TYPENAME; // Do not keep AccountVO as typename\n return person;\n }\n\n get displayName(): string {\n return accountToString(this);\n }\n\n}\n\n\nexport function accountToString(data: Account): string {\n return data &&\n ((data.firstName && (data.firstName + ' ') || '') +\n (data.lastName || '')) || '';\n}\n","import {ApolloClient, ApolloLink, NextLink, Operation} from '@apollo/client/core';\nimport {EventEmitter} from '@angular/core';\nimport {debounceTime, filter, switchMap} from 'rxjs/operators';\nimport {BehaviorSubject, Observable} from 'rxjs';\nimport {getMainDefinition} from '@apollo/client/utilities';\nimport {PersistentStorage} from 'apollo3-cache-persist';\nimport {ConnectionType} from '../services/network.service';\nimport {uuidv4} from '../../vendor';\n\ndeclare let window: any;\nconst _global = typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : {});\nexport const NativeWebSocket = _global.WebSocket || _global.MozWebSocket;\n\n/**\n * AppWebSocket class.\n * With a hack on default Websocket, to avoid the use of protocol\n */\nexport const AppWebSocket = function(url: string, protocols?: string | string[]) {\n return new NativeWebSocket(url/*no protocols*/);\n} as any;\nAppWebSocket.CLOSED = NativeWebSocket.CLOSED;\nAppWebSocket.CLOSING = NativeWebSocket.CLOSING;\nAppWebSocket.CONNECTING = NativeWebSocket.CONNECTING;\nAppWebSocket.OPEN = NativeWebSocket.OPEN;\n\nexport function isMutationOperation(operation: Operation) {\n const def = getMainDefinition(operation.query);\n return def.kind === 'OperationDefinition' && def.operation === 'mutation';\n}\n\nexport function isSubscriptionOperation(operation: Operation) {\n const def = getMainDefinition(operation.query);\n return def.kind === 'OperationDefinition' && def.operation === 'subscription';\n}\n\n\nexport interface TrackedQuery {\n id: string;\n name: string;\n queryJSON: string;\n variablesJSON: string;\n contextJSON: string;\n}\n\nexport const TRACKED_QUERIES_STORAGE_KEY = 'apollo-tracker-persist';\n\nexport function createTrackerLink(opts: {\n storage?: PersistentStorage<string>;\n onNetworkStatusChange: Observable<ConnectionType>;\n debounce?: number;\n debug?: boolean;\n }): ApolloLink {\n\n const trackedQueriesUpdated = new EventEmitter();\n const trackedQueriesById: {[id: string]: TrackedQuery} = {};\n\n const networkStatusSubject = new BehaviorSubject<string>('none');\n opts.onNetworkStatusChange.subscribe(type => networkStatusSubject.next(type));\n\n // Save pending and tracked queries in storage\n trackedQueriesUpdated.pipe(\n debounceTime(opts.debounce || 1000),\n switchMap(() => networkStatusSubject),\n // Continue if offline\n filter((type) => type === 'none' && !!opts.storage)\n ).subscribe(() => {\n const trackedQueries = Object.getOwnPropertyNames(trackedQueriesById)\n .map(key => trackedQueriesById[key])\n .filter(value => value !== undefined);\n if (opts.debug) console.debug('[apollo-tracker-link] Saving tracked queries to storage', trackedQueries);\n return opts.storage.setItem(TRACKED_QUERIES_STORAGE_KEY, JSON.stringify(trackedQueries));\n });\n\n return new ApolloLink((operation: Operation, forward: NextLink) => {\n const context = operation.getContext();\n\n // Skip if not tracked\n if (!context || !context.tracked) return forward(operation);\n\n const id = context.serializationKey || uuidv4();\n console.debug(`[apollo-tracker-link] Watching tracked query {${operation.operationName}#${id}}`);\n\n // Clean context, before calling JSON.stringify (remove unused attributes)\n const cleanContext = { ...context, ...{optimisticResponse: null, cache: null} };\n\n const trackedQuery: TrackedQuery = {\n id,\n name: operation.operationName,\n queryJSON: JSON.stringify(operation.query),\n variablesJSON: JSON.stringify(operation.variables),\n contextJSON: JSON.stringify(cleanContext)\n };\n\n // Add to map\n trackedQueriesById[id] = trackedQuery;\n trackedQueriesUpdated.emit();\n\n const nextOperation = forward(operation)\n .map(data => {\n console.debug(`[apollo-tracker-link] Query {${operation.operationName}#${id}} succeed!`, data);\n delete trackedQueriesById[id];\n trackedQueriesUpdated.emit(trackedQueriesById); // update\n\n return data;\n });\n\n // If offline, return the optimistic response\n if (networkStatusSubject.getValue() === 'none') {\n if (context.optimisticResponse) {\n console.debug(`[apollo-tracker-link] Query {${operation.operationName}#${id}} has optimistic response: `, context.optimisticResponse);\n }\n else {\n console.warn(`[apollo-tracker-link] Query {${operation.operationName}#${id}} missing 'context.optimisticResponse': waiting network UP before to continue...`);\n }\n }\n\n return nextOperation;\n });\n}\n\nexport async function restoreTrackedQueries(opts: {\n apolloClient: ApolloClient<any>;\n storage: PersistentStorage<any>;\n debug?: boolean;\n}) {\n\n const list = JSON.parse(await opts.storage.getItem(TRACKED_QUERIES_STORAGE_KEY)) as TrackedQuery[];\n\n if (!list) return;\n if (opts.debug) console.debug('[apollo-tracker-link] Restoring tracked queries', list);\n\n const promises = (list || []).map(trackedQuery => {\n const context = JSON.parse(trackedQuery.contextJSON);\n const query = JSON.parse(trackedQuery.queryJSON);\n const variables = JSON.parse(trackedQuery.variablesJSON);\n return opts.apolloClient.mutate({\n context,\n mutation: query,\n optimisticResponse: context.optimisticResponse,\n //update: updateHandlerByName[trackedQuery.name],\n variables,\n });\n });\n\n return Promise.all(promises);\n}\n","import { Observable, of, Subject } from 'rxjs';\nimport { Apollo, ExtraSubscriptionOptions, QueryRef } from 'apollo-angular';\nimport {\n ApolloCache,\n ApolloClient,\n ApolloLink,\n ApolloQueryResult,\n FetchPolicy,\n InMemoryCache,\n MutationUpdaterFn,\n NetworkStatus,\n OperationVariables,\n TypePolicies,\n WatchQueryFetchPolicy\n} from '@apollo/client/core';\nimport { ErrorCodes, ServerErrorCodes, ServiceError } from '../services/errors';\nimport { catchError, distinctUntilChanged, filter, first, map, mergeMap, throttleTime } from 'rxjs/operators';\n\nimport { Inject, Injectable, InjectionToken, Optional } from '@angular/core';\nimport { ConnectionType, NetworkService } from '../services/network.service';\nimport { WebSocketLink } from '@apollo/client/link/ws';\nimport { AppWebSocket, createTrackerLink, isMutationOperation, isSubscriptionOperation, restoreTrackedQueries } from './graphql.utils';\nimport { Storage } from '@ionic/storage';\nimport { RetryLink } from '@apollo/client/link/retry';\nimport QueueLink from 'apollo-link-queue';\nimport SerializingLink from 'apollo-link-serialize';\nimport loggerLink from 'apollo-link-logger';\nimport { Platform } from '@ionic/angular';\nimport { EntityUtils, IEntity } from '../services/model/entity.model';\nimport { isNil, isNotNil, toNumber } from '../../shared/functions';\nimport { Resolvers } from '@apollo/client/core/types';\nimport { HttpHeaders } from '@angular/common/http';\nimport { EmptyObject } from 'apollo-angular/types';\nimport { HttpLink, Options } from 'apollo-angular/http';\nimport { IonicStorageWrapper, persistCache, PersistentStorage } from 'apollo3-cache-persist';\nimport { ErrorPolicy, MutationBaseOptions } from '@apollo/client/core/watchQueryOptions';\nimport { Cache } from '@apollo/client/cache/core/types/Cache';\nimport { ENVIRONMENT } from '../../../environments/environment.class';\nimport { CryptoService } from '../services/crypto.service';\nimport { ConnectionParamsOptions } from 'subscriptions-transport-ws/dist/client';\nimport { PropertiesMap } from '../../shared/types';\nimport { StartableService } from '../../shared/services/startable-service.class';\nimport {isMobile, isWindows} from '../../shared/platforms';\n\nexport interface WatchQueryOptions<V> {\n query: any;\n variables?: V;\n error?: ServiceError;\n fetchPolicy?: WatchQueryFetchPolicy;\n}\n\nexport interface MutateQueryOptions<T, V = OperationVariables> extends MutationBaseOptions<T, V> {\n mutation: any;\n variables?: V;\n error?: ServiceError;\n context?: {\n serializationKey?: string;\n tracked?: boolean;\n timeout?: number;\n };\n optimisticResponse?: T;\n offlineResponse?: T | ((context: any) => Promise<T>);\n update?: MutationUpdaterFn<T>;\n forceOffline?: boolean;\n}\n\nexport const APP_GRAPHQL_TYPE_POLICIES = new InjectionToken<TypePolicies>('graphqlTypePolicies');\n\n\n@Injectable({\n providedIn: 'root'\n})\nexport class GraphqlService extends StartableService<ApolloClient<any>> {\n\n private readonly _networkStatusChanged$: Observable<ConnectionType>;\n\n private httpParams: Options;\n private wsParams: WebSocketLink.Configuration;\n private connectionParams: ConnectionParamsOptions & {\n authToken?: string;\n authBasic?: string;\n } = {};\n private readonly _defaultFetchPolicy: WatchQueryFetchPolicy;\n private onNetworkError = new Subject();\n private customErrors: PropertiesMap = {};\n\n get client(): ApolloClient<any> {\n return this._data;\n }\n\n get cache(): ApolloCache<any> {\n return this.apollo.client.cache;\n }\n\n get defaultFetchPolicy(): WatchQueryFetchPolicy {\n return this._defaultFetchPolicy;\n }\n\n constructor(\n private platform: Platform,\n private apollo: Apollo,\n private httpLink: HttpLink,\n private network: NetworkService,\n private storage: Storage,\n private cryptoService: CryptoService,\n @Inject(ENVIRONMENT) protected environment,\n @Optional() @Inject(APP_GRAPHQL_TYPE_POLICIES) private typePolicies: TypePolicies\n ) {\n super(platform); // Wait network\n\n this._debug = !environment.production;\n this._defaultFetchPolicy = environment.apolloFetchPolicy;\n\n // Listen network status\n this._networkStatusChanged$ = network.onNetworkStatusChanges\n .pipe(\n filter(isNotNil),\n distinctUntilChanged()\n );\n\n // When getting network error: try to ping peer, and toggle to offline\n this.onNetworkError\n .pipe(\n throttleTime(300),\n filter(() => this.network.online),\n mergeMap(() => this.network.checkPeerAlive()),\n filter(alive => !alive)\n )\n .subscribe(() => this.network.setForceOffline(true, {showToast: true}));\n\n }\n\n setAuthToken(token: string) {\n if (token) {\n console.debug('[graphql] Apply token authentication to headers');\n this.connectionParams.authToken = token;\n }\n // Clean auth token\n else if (this.connectionParams.authToken) {\n console.debug('[graphql] Remove token authentication from headers');\n delete this.connectionParams.authToken;\n // Clear cache\n this.clearCache();\n }\n }\n\n setAuthBasic(basic: string) {\n if (basic) {\n console.debug('[graphql] Apply basic authentication to headers');\n this.connectionParams.authBasic = basic;\n }\n // Clean auth basic\n else if (this.connectionParams.authBasic) {\n console.debug('[graphql] Remove basic authentication from headers');\n delete this.connectionParams.authBasic;\n // Clear cache\n this.clearCache();\n }\n }\n\n /**\n * Allow to add a field resolver\n * (see doc: https://www.apollographql.com/docs/react/data/local-state/#handling-client-fields-with-resolvers)\n *\n * @param resolvers\n */\n async addResolver(resolvers: Resolvers | Resolvers[]) {\n if (!this.started) await this.ready();\n this.apollo.client.addResolvers(resolvers);\n }\n\n async query<T, V = EmptyObject>(opts: {\n query: any;\n variables?: V;\n error?: ServiceError;\n fetchPolicy?: FetchPolicy;\n }): Promise<T> {\n if (!this.started) await this.ready();\n let res;\n try {\n res = await this.client.query<ApolloQueryResult<T>, V>({\n query: opts.query,\n variables: opts.variables,\n fetchPolicy: opts.fetchPolicy || (this._defaultFetchPolicy as FetchPolicy) || undefined\n });\n } catch (err) {\n res = this.toApolloError<T>(err, opts.error);\n }\n if (res.errors) {\n throw res.errors[0];\n }\n return res.data;\n }\n\n watchQueryRef<T, V = EmptyObject>(opts: WatchQueryOptions<V>): QueryRef<T, V> {\n return this.apollo.watchQuery<T, V>({\n query: opts.query,\n variables: opts.variables,\n fetchPolicy: opts.fetchPolicy || (this._defaultFetchPolicy as FetchPolicy) || undefined,\n notifyOnNetworkStatusChange: true\n });\n }\n\n queryRefValuesChanges<T, V = EmptyObject>(queryRef: QueryRef<T, V>, opts: WatchQueryOptions<V>): Observable<T> {\n return queryRef\n .valueChanges\n .pipe(\n catchError(error => this.onApolloError<T>(error, opts.error)),\n filter(value => value.networkStatus === NetworkStatus.ready || value.networkStatus === NetworkStatus.error),\n map(({data, errors}) => {\n if (errors) {\n throw errors[0];\n }\n return data;\n })\n );\n }\n\n watchQuery<T, V = EmptyObject>(opts: WatchQueryOptions<V>): Observable<T> {\n const queryRef: QueryRef<T, V> = this.watchQueryRef(opts);\n return this.queryRefValuesChanges(queryRef, opts);\n }\n\n async mutate<T, V = EmptyObject>(opts: MutateQueryOptions<T, V>): Promise<T> {\n\n // If offline, compute an optimistic response for tracked queries\n if ((opts.forceOffline || this.network.offline) && opts.offlineResponse) {\n if (typeof opts.offlineResponse === 'function') {\n opts.context = opts.context || {};\n const optimisticResponseFn = (opts.offlineResponse as ((context: any) => Promise<T>));\n opts.optimisticResponse = await optimisticResponseFn(opts.context);\n if (this._debug) console.debug('[graphql] [offline] Using an optimistic response: ', opts.optimisticResponse);\n }\n else {\n opts.optimisticResponse = opts.offlineResponse as T;\n }\n if (opts.forceOffline) {\n const res = {data: opts.optimisticResponse};\n if (opts.update) {\n opts.update(this.apollo.client.cache, res);\n }\n return res.data;\n }\n }\n\n const res = await this.apollo.mutate<ApolloQueryResult<T>, V>({\n mutation: opts.mutation,\n variables: opts.variables,\n context: opts.context,\n optimisticResponse: opts.optimisticResponse as any,\n update: opts.update as any\n })\n .pipe(\n catchError(error => this.onApolloError<T>(error, opts.error)),\n first(),\n // To debug, if need:\n //tap((res) => (!res) && console.error('[graphql] Unknown error during mutation. Check errors in console (may be an invalid generated cache id ?)'))\n ).toPromise();\n if (Array.isArray(res.errors)) {\n throw res.errors[0];\n }\n return res.data as T;\n }\n\n subscribe<T, V = EmptyObject>(opts: {\n query: any;\n variables: V;\n fetchPolicy?: FetchPolicy;\n errorPolicy?: ErrorPolicy;\n error?: ServiceError;\n }, extra?: ExtraSubscriptionOptions): Observable<T> {\n\n return this.apollo.subscribe<T>({\n query: opts.query,\n fetchPolicy: opts && opts.fetchPolicy || 'network-only',\n errorPolicy: opts && opts.errorPolicy || undefined,\n variables: opts.variables\n }, {\n useZone: true,\n ...extra\n })\n .pipe(\n catchError(error => this.onApolloError<T>(error, opts.error)),\n map(({data, errors}) => {\n if (errors) {\n throw errors[0];\n }\n return data;\n })\n );\n }\n\n insertIntoQueryCache<T, V = EmptyObject>(cache: ApolloCache<any>,\n opts: Cache.ReadQueryOptions<V, any> & {\n arrayFieldName: string;\n totalFieldName?: string;\n data: T;\n sortFn?: (d1: T, d2: T) => number;\n size?: number;\n }) {\n\n cache = cache || this.apollo.client.cache;\n opts.arrayFieldName = opts.arrayFieldName || 'data';\n\n try {\n let data = cache.readQuery<any, V>({query: opts.query, variables: opts.variables});\n\n if (data && data[opts.arrayFieldName]) {\n // Copy because immutable\n data = { ...data };\n\n // Append to result array\n data[opts.arrayFieldName] = [ ...data[opts.arrayFieldName], {...opts.data}];\n\n // Resort, if need\n if (opts.sortFn) {\n data[opts.arrayFieldName].sort(opts.sortFn);\n }\n\n // Exclude if exceed max size\n const size = toNumber(opts.variables && opts.variables['size'], -1);\n if (size > 0 && data[opts.arrayFieldName].length > size) {\n data[opts.arrayFieldName].splice(size, data[opts.arrayFieldName].length - size);\n }\n\n // Increment total\n if (isNotNil(opts.totalFieldName)) {\n if (isNotNil(data[opts.totalFieldName])) {\n data[opts.totalFieldName] += 1;\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);\n }\n }\n\n cache.writeQuery({\n query: opts.query,\n variables: opts.variables,\n data\n });\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);\n }\n } catch (err) {\n // continue\n // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940\n if (this._debug) console.error('[graphql] Error while updating cache: ', err);\n }\n }\n\n addManyToQueryCache<T = any, V = EmptyObject>(cache: ApolloCache<any>,\n opts: Cache.ReadQueryOptions<V, any> & {\n arrayFieldName: string;\n totalFieldName?: string;\n data: T[];\n equalsFn?: (d1: T, d2: T) => boolean;\n sortFn?: (d1: T, d2: T) => number;\n }) {\n\n if (!opts.data || !opts.data.length) return; // nothing to process\n\n cache = cache || this.apollo.client.cache;\n opts.arrayFieldName = opts.arrayFieldName || 'data';\n\n try {\n let data = cache.readQuery<any, V>({query: opts.query, variables: opts.variables});\n\n if (data && data[opts.arrayFieldName]) {\n // Copy because immutable\n data = { ...data };\n\n // Keep only not existing res\n const equalsFn = opts.equalsFn || ((d1, d2) => d1['id'] === d2['id'] && d1['entityName'] === d2['entityName']);\n const newItems = opts.data.filter(inputValue => data[opts.arrayFieldName].findIndex(existingValue => equalsFn(inputValue, existingValue)) === -1);\n\n if (!newItems.length) return; // No new value\n\n // Append to array\n data[opts.arrayFieldName] = [ ...data[opts.arrayFieldName], ...newItems];\n\n // Resort, if need\n if (opts.sortFn) {\n data[opts.arrayFieldName].sort(opts.sortFn);\n }\n\n // Exclude if exceed max size\n const size = toNumber(opts.variables && opts.variables['size'], -1);\n if (size > 0 && data[opts.arrayFieldName].length > size) {\n data[opts.arrayFieldName].splice(size, data[opts.arrayFieldName].length - size);\n }\n\n // Increment the total\n if (isNotNil(opts.totalFieldName)) {\n if (isNotNil(data[opts.totalFieldName])) {\n data[opts.arrayFieldName] += newItems.length;\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);\n }\n }\n\n // Write to cache\n cache.writeQuery({\n query: opts.query,\n variables: opts.variables,\n data\n });\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);\n }\n } catch (err) {\n // continue\n // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940\n if (this._debug) console.warn('[graphql] Error while updating cache: ', err);\n }\n }\n\n /**\n * Remove from cache, and return if removed or not\n *\n * @param cache\n * @param opts\n */\n removeFromCachedQueryById<V = EmptyObject, ID = number>(cache: ApolloCache<any>,\n opts: Cache.ReadQueryOptions<V, any> & {\n arrayFieldName: string;\n totalFieldName?: string;\n ids: ID; // Do NOT use 'id', as already used by the Apollo API\n }): boolean {\n\n cache = cache || this.apollo.client.cache;\n opts.arrayFieldName = opts.arrayFieldName || 'data';\n\n try {\n let data = cache.readQuery<any, V>({query: opts.query, variables: opts.variables});\n\n if (data && data[opts.arrayFieldName]) {\n // Copy because immutable\n data = { ...data };\n\n const index = data[opts.arrayFieldName].findIndex(item => item['id'] === opts.ids);\n if (index === -1) return false; // Skip (nothing removed)\n\n // Copy, then remove deleted item\n data[opts.arrayFieldName] = data[opts.arrayFieldName].slice();\n const deletedItem = data[opts.arrayFieldName].splice(index, 1)[0];\n cache.evict({id: cache.identify(deletedItem)});\n\n // Decrement the total\n if (isNotNil(opts.totalFieldName)) {\n if (isNotNil(data[opts.totalFieldName])) {\n data[opts.totalFieldName] -= 1;\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);\n }\n }\n\n // Write to cache\n cache.writeQuery({\n query: opts.query,\n variables: opts.variables,\n data\n });\n return true;\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);\n return false;\n }\n } catch (err) {\n // continue\n // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940\n if (this._debug) console.warn('[graphql] Error while removing from cache: ', err);\n return false;\n }\n }\n\n /**\n * Remove ids from cache, and return the number of items removed\n *\n * @param cache\n * @param opts\n */\n removeFromCachedQueryByIds<V = EmptyObject, ID = number>(cache: ApolloCache<any>,\n opts: Cache.ReadQueryOptions<V, any> & {\n arrayFieldName: string;\n totalFieldName?: string;\n ids: ID[];\n }): number {\n\n cache = cache || this.apollo.client.cache;\n opts.arrayFieldName = opts.arrayFieldName || 'data';\n\n try {\n let data = cache.readQuery(opts);\n\n if (data && data[opts.arrayFieldName]) {\n // Copy because immutable\n data = { ...data };\n\n const deletedIndexes = data[opts.arrayFieldName].reduce((res, item, index) => opts.ids.includes(item['id']) ? res.concat(index) : res, []);\n\n if (deletedIndexes.length <= 0) return 0; // Skip (nothing removed)\n\n // Query has NO total\n if (isNil(opts.totalFieldName)) {\n\n // Evict each object\n deletedIndexes\n .map(index => data[opts.arrayFieldName][index])\n .map(item => cache.identify(item))\n .forEach(id => cache.evict({id}));\n\n }\n // Query has a total\n else {\n // Copy the array\n data[opts.arrayFieldName] = data[opts.arrayFieldName].slice();\n\n // remove from array, then evict\n deletedIndexes\n // Reverse: to keep valid index\n .reverse()\n // Remove from the array\n .map(index => data[opts.arrayFieldName].splice(index, 1)[0])\n // Evict from cache\n .map(item => cache.identify(item))\n .forEach(id => cache.evict({id}));\n\n if (isNotNil(data[opts.totalFieldName])) {\n data[opts.totalFieldName] -= deletedIndexes.length; // Remove deletion count\n }\n else {\n console.warn('[graphql] Unable to update the total in cached query. Unknown result part: ' + opts.totalFieldName);\n }\n\n cache.writeQuery({\n query: opts.query,\n variables: opts.variables,\n data\n });\n\n return deletedIndexes.length;\n }\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.arrayFieldName);\n return 0;\n }\n } catch (err) {\n // continue\n // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940\n if (this._debug) console.warn('[graphql] Error while removing from cache: ', err);\n return 0;\n }\n }\n\n updateToQueryCache<T extends IEntity<any>,\n V = EmptyObject>(cache: ApolloCache<any>,\n opts: Cache.ReadQueryOptions<V, any> & {\n arrayFieldName: string;\n totalFieldName?: string;\n data: T;\n equalsFn?: (d1: T, d2: T) => boolean;\n }) {\n cache = cache || this.apollo.client.cache;\n opts.arrayFieldName = opts.arrayFieldName || 'data';\n\n try {\n let data: any = cache.readQuery(opts);\n\n if (data && data[opts.arrayFieldName]) {\n // Copy because immutable\n data = { ...data };\n\n const equalsFn = opts.equalsFn || ((d1, d2) => EntityUtils.equals(d1, d2, 'id'));\n\n // Update if exists, or insert\n const index = data[opts.arrayFieldName].findIndex(v => equalsFn(opts.data, v));\n if (index !== -1) {\n data[opts.arrayFieldName] = data[opts.arrayFieldName].slice().splice(index, 1, opts.data);\n }\n else {\n data[opts.arrayFieldName] = [ ...data[opts.arrayFieldName], opts.data];\n }\n\n // Increment total (if changed)\n if (isNotNil(opts.totalFieldName) && index === -1) {\n if (isNotNil(data[opts.totalFieldName])) {\n data[opts.totalFieldName] += 1;\n }\n else {\n console.warn('[graphql] Unable to update cached query. Unknown result part: ' + opts.totalFieldName);\n }\n }\n\n cache.writeQuery({\n query: opts.query,\n variables: opts.variables,\n data\n });\n return; // OK: stop here\n }\n } catch (err) {\n // continue\n // read in cache is not guaranteed to return a result. see https://github.com/apollographql/react-apollo/issues/1776#issuecomment-372237940\n if (this._debug) console.warn('[graphql] Error while updating cache: ', err);\n }\n }\n\n async clearCache(client?: ApolloClient<any>): Promise<void> {\n client = (client || this.client) as ApolloClient<any>;\n if (client) {\n console.info('[graphql] Cleaning cache... ');\n const now = this._debug && Date.now();\n\n // Clearing the cache\n await client.cache.reset();\n\n if (this._debug) console.debug(`[graphql] Cleaning cache [OK] in ${Date.now() - now}ms`);\n }\n }\n\n registerCustomError(error: PropertiesMap) {\n this.customErrors = {...this.customErrors, ...error};\n }\n\n /* -- protected methods -- */\n\n protected async ngOnStart(): Promise<ApolloClient<any>> {\n\n await this.network.ready();\n\n console.info('[graphql] Starting graphql...');\n const mobile = isMobile(window);\n const enableTrackMutationQueries = !mobile;\n\n const peer = this.network.peer;\n if (!peer) throw Error('[graphql] Missing peer. Unable to start graphql service');\n\n const uri = peer.url + '/graphql';\n const wsUri = uri.replace(/^http(s)?:/, 'ws$1:') + '/websocket';\n console.info('[graphql] Base uri: ' + uri);\n console.info('[graphql] Subscription uri: ' + wsUri);\n\n this.httpParams = this.httpParams || {};\n this.httpParams.uri = uri;\n\n this.wsParams = {\n ...this.wsParams,\n options: {\n lazy: true,\n reconnect: true,\n connectionParams: this.connectionParams\n },\n webSocketImpl: AppWebSocket,\n uri: wsUri\n };\n\n // Create a storage configuration\n const storage: PersistentStorage<string> = new IonicStorageWrapper(this.storage);\n\n let client = this.apollo.client;\n if (!client) {\n console.debug('[apollo] Creating GraphQL client...');\n\n // Websocket link\n const wsLink = new WebSocketLink(this.wsParams);\n\n // Retry when failed link\n const retryLink = new RetryLink();\n const authLink = new ApolloLink((operation, forward) => {\n\n const authorization = [];\n if (this.connectionParams.authToken) {\n authorization.push(`token ${this.connectionParams.authToken}`);\n }\n if (this.connectionParams.authBasic) {\n authorization.push(`Basic ${this.connectionParams.authBasic}`);\n }\n const headers = new HttpHeaders()\n .append('Authorization', authorization);\n\n // Use the setContext method to set the HTTP headers.\n operation.setContext({\n ...operation.getContext(),\n ...{headers}\n });\n\n // Call the next link in the middleware chain.\n return forward(operation);\n });\n\n // Http link\n const httpLink = this.httpLink.create(this.httpParams);\n\n // Cache\n const cache = new InMemoryCache({\n typePolicies: this.typePolicies\n });\n\n // Add cache persistence\n if (this.environment.persistCache) {\n console.debug('[graphql] Starting persistence cache...');\n await persistCache({\n cache,\n storage,\n trigger: this.platform.is('android') ? 'background' : 'write',\n debounce: 1000,\n debug: true\n });\n }\n\n let mutationLinks: Array<ApolloLink>;\n\n // Add queue to store tracked queries, when offline\n if (enableTrackMutationQueries) {\n const serializingLink = new SerializingLink();\n const trackerLink = createTrackerLink({\n storage,\n onNetworkStatusChange: this._networkStatusChanged$,\n debounce: 1000,\n debug: true\n });\n // Creating a mutation queue\n const queueLink = new QueueLink();\n this.registerSubscription(this._networkStatusChanged$\n .subscribe(type => {\n // Network is offline: start buffering into queue\n if (type === 'none') {\n console.info('[graphql] offline mode: enable mutations buffer');\n queueLink.close();\n }\n // Network is online\n else {\n console.info('[graphql] online mode: disable mutations buffer');\n queueLink.open();\n }\n }));\n mutationLinks = [\n loggerLink,\n queueLink,\n trackerLink,\n queueLink,\n serializingLink,\n retryLink,\n authLink,\n httpLink\n ];\n }\n else {\n mutationLinks = [\n retryLink,\n authLink,\n httpLink\n ];\n }\n\n // create Apollo\n client = new ApolloClient({\n cache,\n link:\n ApolloLink.split(\n // Handle mutations\n isMutationOperation,\n ApolloLink.from(mutationLinks),\n\n ApolloLink.split(\n // Handle subscriptions\n isSubscriptionOperation,\n wsLink,\n\n // Handle queries\n ApolloLink.from([\n retryLink,\n authLink,\n httpLink\n ])\n )\n ),\n connectToDevTools: !this.environment.production\n });\n\n this.apollo.client = client;\n }\n\n // Enable tracked queries persistence\n if (enableTrackMutationQueries && this.environment.persistCache) {\n\n try {\n await restoreTrackedQueries({\n apolloClient: client,\n storage,\n debug: true\n });\n } catch (err) {\n console.error('[graphql] Failed to restore tracked queries from storage: ' + (err && err.message || err), err);\n }\n }\n\n // Listen for network restart\n this.registerSubscription(\n this.network.on('start', () => this.restart())\n );\n\n // Listen for clear cache request, from network\n this.registerSubscription(\n this.network.on('resetCache', () => this.clearCache())\n );\n\n console.info('[graphql] Starting graphql [OK]');\n return client;\n }\n\n protected async ngOnStop() {\n console.info('[graphql] Stopping graphql service...');\n await this.resetClient();\n }\n\n protected async resetClient(client?: ApolloClient<any>) {\n client = (client || this.apollo.client) as ApolloClient<any>;\n if (!client) return;\n\n console.info('[graphql] Resetting Apollo client...');\n client.stop();\n await Promise.all([\n client.clearStore(),\n this.clearCache(client)\n ]);\n }\n\n private onApolloError<T>(err: any, defaultError?: any): Observable<ApolloQueryResult<T>> {\n return of(this.toApolloError(err, defaultError));\n }\n\n private toApolloError<T>(err: any, defaultError?: any): ApolloQueryResult<T> {\n let error =\n // If network error: try to convert to App (read as JSON), or create an UNKNOWN_NETWORK_ERROR\n (err.networkError && (\n (err.networkError.error && this.toAppError(err.networkError.error))\n || this.toAppError(err.networkError)\n || (err.networkError.error && this.createAppErrorByCode(err.networkError.error.status))\n || this.createAppErrorByCode(ErrorCodes.UNKNOWN_NETWORK_ERROR)\n )\n )\n // If graphQL: try to convert the first error found\n || (err.graphQLErrors && err.graphQLErrors.length && this.toAppError(err.graphQLErrors[0]))\n || this.toAppError(err)\n || this.toAppError(err.originalError)\n || (err.graphQLErrors && err.graphQLErrors[0])\n || err;\n console.error('[graphql] ' + (error && error.message || error), error.stack || '');\n if (error && error.code === ErrorCodes.UNKNOWN_NETWORK_ERROR && err.networkError && err.networkError.message) {\n console.error('[graphql] original error: ' + err.networkError.message);\n this.onNetworkError.next(error);\n }\n if ((!error || !error.code) && defaultError) {\n error = {...defaultError, details: error, stack: err.stack};\n }\n return {\n data: null,\n errors: [error],\n loading: false,\n networkStatus: NetworkStatus.error\n };\n }\n\n private createAppErrorByCode(errorCode: number): any | undefined {\n const message = this.getI18nErrorMessageByCode(errorCode);\n if (message) {\n return {\n code: errorCode,\n message: this.getI18nErrorMessageByCode(errorCode)\n };\n }\n return undefined;\n }\n\n private getI18nErrorMessageByCode(errorCode: number): string | undefined {\n\n // look in registered error codes\n const customErrorMessage = this.customErrors[errorCode];\n if (customErrorMessage) {\n return customErrorMessage;\n }\n\n // Default, switch on error code\n switch (errorCode) {\n case ServerErrorCodes.UNAUTHORIZED:\n return 'ERROR.UNAUTHORIZED';\n case ServerErrorCodes.FORBIDDEN:\n return 'ERROR.FORBIDDEN';\n case ErrorCodes.UNKNOWN_NETWORK_ERROR:\n return 'ERROR.UNKNOWN_NETWORK_ERROR';\n case ServerErrorCodes.BAD_UPDATE_DATE:\n return 'ERROR.BAD_UPDATE_DATE';\n case ServerErrorCodes.DATA_LOCKED:\n return 'ERROR.DATA_LOCKED';\n case ServerErrorCodes.BAD_APP_VERSION:\n return 'ERROR.BAD_APP_VERSION';\n }\n\n return undefined;\n }\n\n private toAppError(err: any): any | undefined {\n let error = err;\n const message = err && err.message || err;\n if (typeof message === 'string' && message.trim().indexOf('{\"code\":') === 0) {\n try {\n error = JSON.parse(message\n // Remove special characters before parsing (e.g. SQL errors from an Oracle database)\n .replace('\\n', ' ')\n .replace('\\r', ''));\n }\n catch (parseError) {\n console.error('Unable to parse error as JSON: ', parseError);\n }\n }\n if (error && error.code) {\n return this.createAppErrorByCode(error.code) || error && error.message || error;\n }\n return undefined;\n }\n\n}\n","import {GraphqlService, MutateQueryOptions, WatchQueryOptions} from '../graphql/graphql.service';\nimport {Page} from '../../shared/services/entity-service.class';\nimport {EmptyObject} from 'apollo-angular/types';\nimport {Observable} from 'rxjs';\nimport {FetchResult} from '@apollo/client/link/core';\nimport {EntityUtils} from './model/entity.model';\nimport {ApolloCache, InternalRefetchQueriesInclude} from '@apollo/client/core';\nimport {isNotEmptyArray, isNotNil, toBoolean} from '../../shared/functions';\nimport {environment} from '../../../environments/environment';\nimport {Directive, Optional} from '@angular/core';\nimport {QueryRef} from 'apollo-angular';\nimport {PureQueryOptions} from '@apollo/client/core/types';\nimport {DocumentNode} from 'graphql';\nimport {StartableService} from '../../shared/services/startable-service.class';\n\nconst sha256 = require('hash.js/lib/hash/sha/256');\n\nexport interface QueryVariables<F= any> extends Partial<Page> {\n filter?: F;\n [key: string]: any;\n}\n\nexport interface MutateQueryWithCacheUpdateOptions<T = any, V = EmptyObject> extends MutateQueryOptions<T, V> {\n cacheInsert?: {\n query: any;\n fetchData: (variables: V, mutationResult: FetchResult<T>) => any;\n }[];\n\n cacheRemove?: {\n query: any;\n fetchIds: (variables: V) => number | number[];\n }[];\n}\n\nexport interface MutableWatchQueryOptions<D, T = any, V = EmptyObject> extends WatchQueryOptions<V> {\n queryName: string;\n arrayFieldName: keyof D;\n totalFieldName?: keyof D ;\n insertFilterFn?: (data: T) => boolean;\n sortFn?: (a: T, b: T) => number;\n}\n\nexport interface MutableWatchQueryDescription<D, T = any, V = EmptyObject> extends PureQueryOptions {\n id?: string;\n query: DocumentNode;\n queryRef: QueryRef<D, V>;\n variables: V;\n arrayFieldName: keyof D;\n totalFieldName?: keyof D;\n insertFilterFn?: (data: T) => boolean;\n sortFn?: (a: T, b: T) => number;\n counter: number;\n}\n\nexport interface FindMutableWatchQueriesOptions {\n query?: DocumentNode;\n queries?: DocumentNode[];\n queryName?: string;\n queryNames?: string[];\n}\n\nexport class BaseGraphqlServiceOptions {\n production?: boolean;\n}\n\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class BaseGraphqlService<T = any, F = any, ID = any, S = void> extends StartableService<S> {\n\n protected _logPrefix: string;\n protected _mutableWatchQueries: MutableWatchQueryDescription<any>[] = [];\n\n // Max updated queries, for this entity.\n // - Can be override by subclasses (in constructor)\n // - Use value -1 for no max size\n // - Default value to 3, because it usually enough (e.g. OperationService and LandingService need at least 2)\n protected _mutableWatchQueriesMaxCount = 3;\n\n protected constructor(\n protected graphql: GraphqlService,\n @Optional() options?: BaseGraphqlServiceOptions\n ) {\n super(graphql);\n\n // for DEV only\n this._debug = toBoolean(options && !options.production, !environment.production);\n this._logPrefix = `[base-graphql-service] `;\n }\n\n mutableWatchQuery<D, V = EmptyObject>(opts: MutableWatchQueryOptions<D, T, V>): Observable<D> {\n opts.fetchPolicy = opts.fetchPolicy || this.graphql.defaultFetchPolicy;\n\n // Standard query (no cache)\n if (opts.fetchPolicy === 'no-cache') {\n return this.graphql.watchQuery(opts);\n }\n\n // No arrayFieldName\n if (!opts.arrayFieldName) {\n if (this._debug) console.warn(this._logPrefix + '̀Missing \\'opts.arrayFieldName\\' : unable to create a mutable watch query');\n return this.graphql.watchQuery(opts);\n }\n\n // Create the query id\n const queryId = this.computeMutableWatchQueryId(opts);\n const exactMatchQueries = this._mutableWatchQueries.filter(q => q.id === queryId);\n\n let mutableQuery: MutableWatchQueryDescription<D, T, V>;\n let queryRef: QueryRef<D, V>;\n\n if (exactMatchQueries.length === 1) {\n mutableQuery = exactMatchQueries[0] as MutableWatchQueryDescription<D, T, V>;\n mutableQuery.counter += 1;\n queryRef = mutableQuery.queryRef;\n if (this._debug) console.debug(this._logPrefix + `Find same mutable watch query (same variables) {${queryId}}. Skip register`);\n\n // Refetch if need data from network\n if (opts.fetchPolicy === 'network-only' || opts.fetchPolicy === 'cache-and-network') {\n console.warn(this._logPrefix + ' Mutable query already exists, and fetchPolicy=' + opts.fetchPolicy + '. Force refetch query...');\n queryRef.refetch(mutableQuery.variables);\n }\n //if (mutableQuery.counter > 3) {\n // console.warn(this._debugPrefix + 'TODO: clean previous queries with name: ' + queryName);\n //}\n }\n else {\n queryRef = this.graphql.watchQueryRef<D, V>(opts);\n this.registerNewMutableWatchQuery({\n id: queryId,\n query: opts.query,\n queryRef,\n variables: opts.variables,\n arrayFieldName: opts.arrayFieldName,\n totalFieldName: opts.totalFieldName,\n insertFilterFn: opts.insertFilterFn,\n sortFn: opts.sortFn,\n counter: 1\n });\n }\n\n return this.graphql.queryRefValuesChanges(queryRef, opts);\n }\n\n insertIntoMutableCachedQueries(cache: ApolloCache<any>, opts: FindMutableWatchQueriesOptions & {\n data: T[] | T;\n }) {\n const queries = this.findMutableWatchQueries(opts);\n if (!queries.length) return;\n\n queries.forEach(query => {\n\n if (Array.isArray(opts.data)) {\n // Filter values, if a filter function exists\n const data = query.insertFilterFn ? opts.data.filter(i => query.insertFilterFn(i)) : opts.data;\n if (isNotEmptyArray(data)) {\n if (this._debug) console.debug(`[base-data-service] Inserting data into watching query: `, query.id);\n this.graphql.addManyToQueryCache(cache, {\n query: query.query,\n variables: query.variables,\n arrayFieldName: query.arrayFieldName as string,\n totalFieldName: query.totalFieldName as string,\n sortFn: query.sortFn,\n data\n });\n }\n }\n // Filter value, if a filter function exists\n else if (!query.insertFilterFn || query.insertFilterFn(opts.data)) {\n if (this._debug) console.debug(`[base-data-service] Inserting data into watching query: `, query.id);\n this.graphql.insertIntoQueryCache(cache, {\n query: query.query,\n variables: query.variables,\n arrayFieldName: query.arrayFieldName as string,\n totalFieldName: query.totalFieldName as string,\n sortFn: query.sortFn,\n data: opts.data\n });\n }\n });\n }\n\n removeFromMutableCachedQueriesByIds(cache: ApolloCache<any>, opts: FindMutableWatchQueriesOptions & {\n ids: ID|ID[];\n }): number {\n const queries = this.findMutableWatchQueries(opts);\n if (!queries.length) return;\n\n console.debug(`[base-data-service] Removing data from watching queries: `, queries);\n return queries.map(query => {\n if (Array.isArray(opts.ids)) {\n return this.graphql.removeFromCachedQueryByIds(cache, {\n query: query.query,\n variables: query.variables,\n arrayFieldName: query.arrayFieldName as string,\n totalFieldName: query.totalFieldName as string,\n ids: opts.ids\n });\n }\n else {\n return this.graphql.removeFromCachedQueryById(cache, {\n query: query.query,\n variables: query.variables,\n arrayFieldName: query.arrayFieldName as string,\n totalFieldName: query.totalFieldName as string,\n ids: opts.ids\n }) ? 1 : 0;\n }\n })\n // Sum\n .reduce((res, count) => res + count, 0);\n }\n\n async refetchMutableWatchQueries(opts: FindMutableWatchQueriesOptions & { variables?: any }): Promise<void> {\n // Retrieve queries to refetch\n const queries = this.findMutableWatchQueries(opts);\n\n // Skip if nothing to refetch\n if (!queries.length) return;\n\n try {\n await Promise.all(queries.map(query => {\n if (this._debug) console.debug(this._logPrefix + `Refetching mutable watch query {${query.id}}`);\n return query.queryRef.refetch({...query.variables, ...opts.variables});\n }));\n }\n catch (err) {\n console.error(this._logPrefix + 'Error while refetching mutable watch queries', err);\n }\n }\n\n /* -- protected methods -- */\n\n protected computeMutableWatchQueryId<D, T, V = EmptyObject>(opts: MutableWatchQueryOptions<D, T, V>) {\n const queryName = opts.queryName || sha256().update(JSON.stringify(opts.query)).digest('hex').substring(0, 8);\n const variablesKey = opts.variables && sha256().update(JSON.stringify(opts.variables)).digest('hex').substring(0, 8) || '';\n return [queryName, opts.arrayFieldName, variablesKey].join('|');\n }\n\n protected findMutableWatchQueries(opts: FindMutableWatchQueriesOptions): MutableWatchQueryDescription<any>[] {\n // Search by queryName\n if (opts.queryName) {\n return this._mutableWatchQueries.filter(q => q.id.startsWith(opts.queryName + '|'));\n }\n if (opts.queryNames) {\n return opts.queryNames.map(queryName => this._mutableWatchQueries.filter(q => q.id.startsWith(queryName + '|')))\n // flatMap\n .reduce((res, array) => res.concat(...array), []);\n }\n\n // Search by query\n if (opts.query) {\n return this._mutableWatchQueries.filter(q => q.query === opts.query);\n }\n if (opts.queries) {\n return opts.queries\n .filter(isNotNil)\n .map(query => this._mutableWatchQueries.filter(q => q.query === query))\n // flatMap\n .reduce((res, array) => res.concat(...array), []);\n }\n throw Error('Invalid options: only one property must be set');\n }\n\n protected registerNewMutableWatchQuery(mutableQuery: MutableWatchQueryDescription<any>) {\n\n if (this._debug) console.debug(this._logPrefix + `Register new mutable watch query {${mutableQuery.id}}`);\n\n // If exceed the max size of mutable queries: remove some\n if (this._mutableWatchQueriesMaxCount > 0 && this._mutableWatchQueries.length >= this._mutableWatchQueriesMaxCount) {\n const removedWatchQueries = this._mutableWatchQueries.splice(0, 1 + this._mutableWatchQueries.length - this._mutableWatchQueriesMaxCount);\n\n // Warn, as it shouldn't be happen often, when max is correctly set\n console.warn(this._logPrefix + `Removing older mutable watching queries (stack exceed max of ${this._mutableWatchQueriesMaxCount}): `,\n removedWatchQueries.map(q => q.id));\n }\n\n // Define the sort function (to be used in insertIntoMutableCachedQuery())\n if (!mutableQuery.sortFn && mutableQuery.variables && mutableQuery.variables.sortBy) {\n mutableQuery.sortFn = mutableQuery.variables && mutableQuery.variables.sortBy\n && EntityUtils.sortComparator(mutableQuery.variables.sortBy, mutableQuery.variables.sortDirection || 'asc');\n }\n\n // Add the new mutable query to array\n this._mutableWatchQueries.push(mutableQuery);\n }\n\n protected findRefetchQueries(opts: FindMutableWatchQueriesOptions): InternalRefetchQueriesInclude {\n return this.findMutableWatchQueries(opts)\n // Workaround, to make refetch queries works: transform into a simple {query, variables}\n .map(({query, variables}) => {\n return { query, variables };\n });\n }\n\n protected ngOnStart(): Promise<S> {\n return Promise.resolve(null as S);\n }\n}\n","import {Inject, Injectable, Optional} from '@angular/core';\nimport {CryptoService, KeyPair} from './crypto.service';\nimport {Department} from './model/department.model';\nimport {Account} from './model/account.model';\nimport {Person, PersonUtils, UserProfileLabel} from './model/person.model';\nimport {LocalSettings, UsageMode, UserSettings} from './model/settings.model';\nimport {BehaviorSubject, from, Observable, Subject, Subscription} from 'rxjs';\nimport {FetchPolicy, gql} from '@apollo/client/core';\nimport {Storage} from '@ionic/storage';\n\nimport {isNil, sleep, toNumber} from '../../shared/functions';\nimport {BaseGraphqlService} from './base-graphql-service.class';\nimport {ErrorCodes, ServerErrorCodes} from './errors';\nimport {GraphqlService} from '../graphql/graphql.service';\nimport {LocalSettingsService} from './local-settings.service';\nimport {FormFieldDefinition} from '../../shared/form/field.model';\nimport {AuthTokenType, NetworkService} from './network.service';\nimport {FileService} from '../../shared/file/file.service';\nimport {MINIFY_ENTITY_FOR_POD, Referential, ReferentialUtils} from './model/referential.model';\nimport {StatusIds} from './model/model.enum';\nimport {Base58} from './base58';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {fromDateISOString} from '../../shared/dates';\nimport {firstNotNilPromise} from '../../shared/observables';\nimport {debounceTime, filter, map, switchMap, takeUntil} from 'rxjs/operators';\nimport {BaseEntityGraphqlMutations, BaseEntityGraphqlSubscriptions} from './base-entity-service.class';\nimport {Moment} from 'moment';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {OverlayEventDetail} from '@ionic/core';\nimport {ToastController} from '@ionic/angular';\nimport {TranslateService} from '@ngx-translate/core';\n\n\nexport declare interface AccountDetails {\n loaded: boolean;\n keypair: KeyPair;\n authToken: string;\n authBasic?: string;\n pubkey: string;\n person: Person;\n department: Department;\n mainProfile: String;\n}\nexport interface AuthData {\n username: string;\n password: string;\n offline?: boolean;\n}\nexport interface RegisterData extends AuthData {\n account: Account;\n}\n\nconst TOKEN_STORAGE_KEY = 'token';\nconst PUBKEY_STORAGE_KEY = 'pubkey';\nconst SECKEY_STORAGE_KEY = 'seckey';\nconst ACCOUNT_STORAGE_KEY = 'account';\n\nconst DEFAULT_AVATAR_IMAGE = 'assets/img/person.png';\n\n\n/* ------------------------------------\n * GraphQL queries\n * ------------------------------------*/\nconst Fragments = {\n account: gql`\n fragment AccountFragment on AccountVO {\n id\n firstName\n lastName\n email\n pubkey\n avatar\n statusId\n updateDate\n creationDate\n profiles\n settings {\n ...UserSettingsFragment\n }\n department {\n id\n label\n name\n __typename\n }\n __typename\n }`,\n\n settings: gql`fragment UserSettingsFragment on UserSettingsVO {\n id\n locale\n latLongFormat\n content\n nonce\n updateDate\n __typename\n }`\n};\n\n// Load account query\nconst LoadQuery: any = gql`\n query Account {\n data: account {\n ...AccountFragment\n }\n }\n ${Fragments.account}\n ${Fragments.settings}\n`;\n\n// Check email query\nconst IsEmailExistsQuery: any = gql`\n query IsEmailExists($email: String, $hash: String){\n isEmailExists(email: $email, hash: $hash)\n }\n`;\nexport declare interface IsEmailExistsVariables {\n email: string;\n hash: string;\n}\n\n// Save (create or update) account mutation\nconst AccountMutations: Partial<BaseEntityGraphqlMutations> & { create: any, saveSettings: any; } = {\n save: gql` mutation SaveAccount($data:AccountVOInput){\n data: saveAccount(account: $data){\n ...AccountFragment\n }\n }\n ${Fragments.account}\n ${Fragments.settings}`,\n\n create: gql`mutation CreateAccount($data:AccountVOInput){\n data: createAccount(account: $data){\n ...AccountFragment\n }\n }\n ${Fragments.account}\n ${Fragments.settings}`,\n\n saveSettings: gql`mutation SaveSettings($data:UserSettingsVOInput){\n data: saveSettings(settings: $data){\n ...UserSettingsFragment\n }\n }\n ${Fragments.settings}`\n};\n\n// Sent confirmation email\nconst SendConfirmEmailMutation: any = gql`\n mutation sendAccountConfirmationEmail($email:String, $locale:String){\n sendAccountConfirmationEmail(email: $email, locale: $locale)\n }\n`;\n\n// Confirm account email\nconst ConfirmEmailMutation: any = gql`\n mutation confirmAccountEmail($email:String, $code:String){\n confirmAccountEmail(email: $email, code: $code)\n }\n`;\n\n// Authentication query\nconst AuthQuery: any = gql`\n query Auth($token: String){\n authenticate(token: $token)\n }\n`;\n\n// New auth challenge query\nconst AuthChallengeQuery: any = gql`\n query AuthChallenge{\n authChallenge{\n challenge\n pubkey\n signature\n }\n }\n`;\n\nconst AccountSubscriptions: BaseEntityGraphqlSubscriptions = {\n listenChanges: gql`subscription updateAccount($interval: Int){\n data: updateAccount(interval: $interval) {\n id\n updateDate\n }\n }`\n};\n\nexport interface AccountWatchOptions {\n intervalInSeconds?: number;\n}\n\n@Injectable({providedIn: 'root', deps: [ ENVIRONMENT ]})\nexport class AccountService extends BaseGraphqlService<Account, any, number, Account> {\n\n onLogin = new Subject<Account>();\n onLogout = new Subject<any>();\n onChange = new Subject<Account>();\n onAuthTokenChange = new Subject<string | undefined>();\n onAuthBasicChange = new Subject<string | undefined>();\n\n private _listenChangesSubscription: Subscription = null;\n private readonly _enableListenChanges: boolean;\n private readonly _listenIntervalInSeconds: number;\n private _cache: AccountDetails = {\n loaded: false,\n keypair: null,\n authToken: null,\n authBasic: null,\n pubkey: null,\n mainProfile: null,\n person: null,\n department: null\n };\n private _$additionalFields = new BehaviorSubject<FormFieldDefinition[]>([]);\n private _tokenType$ = new BehaviorSubject<AuthTokenType>(undefined);\n\n get account(): Account {\n return this._cache.loaded ? this._data : undefined;\n }\n\n get person(): Person {\n if (this._cache.loaded && !this._cache.person) {\n this._cache.person = this._cache.loaded ? this._data.asPerson() : undefined;\n }\n return this._cache.person;\n }\n\n get department(): Department {\n if (this._cache.loaded && !this._cache.department) {\n this._cache.department = this._cache.loaded ? this._data.asPerson().department : undefined;\n }\n return this._cache.department;\n }\n\n get tokenType(): AuthTokenType {\n return this._tokenType$.value;\n }\n\n set tokenType(value: AuthTokenType) {\n if (this._tokenType$.value !== value) {\n console.info('[account] Using authentication token type: ' + value);\n this._tokenType$.next(value);\n // Reset values\n this._cache.authToken = undefined;\n this.onAuthTokenChange.next(undefined);\n this._cache.authBasic = undefined;\n this.onAuthBasicChange.next(undefined);\n }\n }\n\n constructor(\n private cryptoService: CryptoService,\n protected network: NetworkService,\n protected graphql: GraphqlService,\n protected settings: LocalSettingsService,\n protected storage: Storage,\n protected file: FileService,\n @Optional() private translate: TranslateService,\n @Optional() private toastController: ToastController,\n @Inject(ENVIRONMENT) protected environment\n ) {\n super(graphql, environment);\n this._enableListenChanges = (!environment.account || environment.account.enableListenChanges !== false); // True by default\n this._listenIntervalInSeconds = toNumber(environment.account && environment.account.listenIntervalInSeconds, 0); // no timer by default\n\n this._debug = !environment.production;\n if (this._debug) console.debug('[account-service] Creating service');\n\n this.resetData();\n\n // Send auth token to the graphql layer, when changed\n this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));\n this.onAuthBasicChange.subscribe((basic) => this.graphql.setAuthBasic(basic));\n\n // Force network to wait account service, after getting connection to the peer\n this.network.on('beforeTryOnlineFinish', async (online) => {\n // If online, wait a full restart, because it can force offline mode\n if (online && (!this.started || this.isLogin())) {\n console.debug('[account] Force networkService.tryOnline() to wait, that graphql and account service is restarted...');\n await sleep(500); // wait graphql service to be restarted\n if (!this.started) await this.ready();\n }\n });\n }\n\n\n async ngOnStart(): Promise<Account> {\n\n await Promise.all([\n this.settings.ready(),\n // Wait token type to be set\n firstNotNilPromise(this._tokenType$)\n ]);\n\n // Listen graphql start (or restart)\n this.registerSubscription(\n this.graphql.stopSubject.subscribe(() => {\n if (this.started && this.isLogin()) {\n console.debug('[account] Restarting, to retry to authenticate...');\n this.restart();\n }\n })\n );\n\n await this.restoreLocally();\n await this.listenSettings();\n\n return this._data;\n }\n\n protected async ngOnStop(): Promise<void> {\n const hadAuthToken = this._cache.authToken && true;\n const hadAuthBasic = this._cache.authBasic && true;\n const hadAuth = hadAuthToken || hadAuthBasic;\n this.resetData();\n if (hadAuth) {\n this.onLogout.next();\n this.onChange.next(undefined);\n if (hadAuthToken) this.onAuthTokenChange.next(undefined);\n if (hadAuthBasic) this.onAuthBasicChange.next(undefined);\n }\n }\n\n isLogin(): boolean {\n return !!(this._cache.pubkey && this._cache.loaded);\n }\n\n isAuth(): boolean {\n return !!(this._cache.pubkey && this._cache.keypair && this._cache.keypair.secretKey);\n }\n\n hasMinProfile(userProfile: UserProfileLabel): boolean {\n // should be login, and status ENABLE or TEMPORARY\n if (!this._data || !this._data.pubkey ||\n (this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY)) {\n return false;\n }\n return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, userProfile);\n }\n\n hasExactProfile(label: UserProfileLabel): boolean {\n // should be login, and status ENABLE or TEMPORARY\n if (!this._data || !this._data.pubkey ||\n (this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY))\n return false;\n return this._data.profiles.some(profile => profile === label);\n }\n\n hasProfileAndIsEnable(userProfile: UserProfileLabel): boolean {\n // should be login, and status ENABLE\n if (!this._data || !this._data.pubkey || this._data.statusId !== StatusIds.ENABLE) return false;\n return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, userProfile);\n }\n\n isAdmin(): boolean {\n return this.hasProfileAndIsEnable('ADMIN');\n }\n\n isSupervisor(): boolean {\n return this.hasProfileAndIsEnable('SUPERVISOR');\n }\n\n isUser(): boolean {\n return this.hasProfileAndIsEnable('USER');\n }\n\n /**\n * @deprecated\n * @param mode\n */\n isUsageMode(mode: UsageMode): boolean {\n return this.settings.isUsageMode(mode);\n }\n\n isOnlyGuest(): boolean {\n // Should be login, and status ENABLE or TEMPORARY\n if (!this._data || !this._data.pubkey ||\n (this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY))\n return false;\n // Profile less then user\n return !PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, 'USER');\n }\n\n canUserWriteDataForDepartment(recorderDepartment: Referential | any): boolean {\n if (ReferentialUtils.isEmpty(recorderDepartment)) {\n return this.isAdmin();\n }\n\n // Should be login, and status ENABLE\n if (!this._data || !this._data.pubkey || this._data.statusId !== StatusIds.ENABLE) return false;\n\n if (!this._data.department || !this._data.department.id) {\n console.warn('User account has no department ! Unable to check write right against recorderDepartment');\n return false;\n }\n\n // Same recorder department: OK, user can write\n if (this._data.department.id === recorderDepartment.id) return true;\n\n // Else, check if supervisor (or more)\n return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, 'SUPERVISOR');\n }\n\n async register(data: RegisterData): Promise<Account> {\n if (this.isLogin()) {\n throw new Error('User already login. Please logout before register.');\n }\n if (!data.username || !data.password) throw new Error('Missing required username or password');\n\n if (this._debug) console.debug('[account] Register new user account...', data.account);\n this._cache.loaded = false;\n const now = Date.now();\n\n try {\n const keypair = await this.cryptoService.scryptKeypair(data.username, data.password);\n data.account.pubkey = Base58.encode(keypair.publicKey);\n\n // Default values\n data.account.settings = data.account.settings || new UserSettings();\n data.account.settings.locale = this.settings.locale;\n data.account.settings.latLongFormat = this.settings.latLongFormat;\n data.account.settings.content = data.account.settings.content || {};\n data.account.department.id = data.account.department.id || this.environment.defaultDepartmentId;\n\n this._cache.keypair = keypair;\n const account = await this.saveRemotely(data.account, keypair);\n\n // Default values\n account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);\n this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);\n\n this._data = account;\n this._cache.pubkey = account.pubkey;\n\n // Try to auth on pod\n await this.authenticate(data);\n\n this._cache.loaded = true;\n\n await this.saveLocally();\n\n console.debug(`[account] Account successfully registered in ${Date.now() - now}ms`);\n\n // Emit events\n this.onLogin.next(this._data);\n this.onChange.next(this._data);\n\n // Listen remote changes\n if (this._enableListenChanges) this.startListenRemoteChanges();\n\n return this._data;\n }\n catch (error) {\n console.error(error && error.message || error);\n this.resetData();\n throw error;\n }\n }\n\n async authenticate(data?: AuthData) {\n // Wait the auth token, then continue\n const tokenType = await firstNotNilPromise(this._tokenType$);\n\n // Basic auth\n if (tokenType === 'basic' || tokenType === 'basic-and-token') {\n\n // Generate the authBasic, if used\n if (!this._cache.authBasic) {\n // Skip if token already provided\n if (!(this._cache.authToken && tokenType === 'basic-and-token')) {\n if (!data || !data.username || !data.password) throw new Error('Missing username and password');\n this._cache.authBasic = this.cryptoService.encodeBase64(`${data.username}:${data.password}`);\n }\n }\n this.onAuthBasicChange.next(this._cache.authBasic);\n }\n\n // Generate the authToken, if used\n if (tokenType === 'token' || tokenType === 'basic-and-token') {\n try {\n this._cache.authToken = await this.authenticateAndGetToken(this._cache.authToken);\n } catch (error) {\n // Never authenticate, or not ready for offline mode => exit\n console.error(error);\n this.resetData();\n throw error;\n }\n }\n\n // Forget authBasic, to switch to authToken\n if (tokenType === 'basic-and-token') {\n this._cache.authBasic = undefined;\n this.onAuthBasicChange.next(undefined);\n }\n }\n\n async login(data: AuthData): Promise<Account> {\n if (!data || !data.username || !data.password) throw new Error('Missing required username or password');\n\n console.debug('[account] Login...');\n\n let keypair;\n try {\n keypair = await this.cryptoService.scryptKeypair(data.username, data.password);\n } catch (error) {\n console.error(error);\n this.resetData();\n throw { code: ErrorCodes.UNKNOWN_ERROR, message: 'ERROR.SCRYPT_ERROR' };\n }\n\n // Store pubkey+keypair\n this._cache.pubkey = Base58.encode(keypair.publicKey);\n this._cache.keypair = keypair;\n\n // Try to load previous token\n let previousToken: string = await this.storage.get(TOKEN_STORAGE_KEY);\n previousToken = previousToken && previousToken.startsWith(this._cache.pubkey) && previousToken || null;\n\n // Offline mode\n const offline = this.settings.hasOfflineFeature() && (this.network.offline || data.offline === true);\n if (offline) {\n this._cache.authToken = previousToken;\n\n // Make sure network if set as offline\n this.network.setForceOffline(true, {showToast: false});\n console.info(`[account] Login [OK] {pubkey: ${this._cache.pubkey.substr(0, 8)}}, {offline: true}`);\n }\n\n // Online mode: try to auth on pod\n else {\n\n try {\n await this.authenticate(data);\n } catch (error) {\n // Never authenticate, or not ready for offline mode => exit\n console.error(error);\n this.resetData();\n throw error;\n }\n }\n\n // Load account data\n try {\n await this.loadData({offline, fetchPolicy: 'network-only'});\n }\n catch (err) {\n // If account not found, check if email is valid\n if (err && +(err.code) === ErrorCodes.LOAD_ACCOUNT_ERROR) {\n\n // Check email exists\n if (data.username.indexOf('@') !== -1) {\n let isEmailExists;\n try {\n isEmailExists = await this.isEmailExists(data.username);\n } catch (otherError) {\n throw err; // resend the first error\n }\n\n // Email not exists (no account)\n if (!isEmailExists) {\n throw { code: ErrorCodes.UNKNOWN_ACCOUNT_EMAIL, message: 'ERROR.UNKNOWN_ACCOUNT_EMAIL' };\n }\n }\n\n // Email exists, so error = 'bad password'\n throw { code: ErrorCodes.BAD_PASSWORD, message: 'ERROR.BAD_PASSWORD' };\n }\n\n throw err; // resend the first error\n }\n\n try {\n // Store to local storage\n await this.saveLocally();\n }\n catch (error) {\n console.error(error);\n this.resetData();\n throw error;\n }\n\n // Emit event to observers\n this.onLogin.next(this._data);\n this.onChange.next(this._data);\n\n if (this._enableListenChanges) this.startListenRemoteChanges();\n\n return this._data;\n }\n\n async reload(opts?: {showToast?: boolean}): Promise<Account> {\n if (!this._cache.pubkey) throw new Error('User not logged');\n if (this.network.offline) throw new Error('Cannot check account in offline mode');\n\n const now = Date.now();\n console.debug(`[account] Reloading account...`);\n const wasLogin = this.isLogin();\n\n try {\n\n await this.loadData();\n await this.saveLocally();\n\n console.debug(`[account] Reloading account [OK] in ${Date.now() - now}ms`);\n\n // Emit login event to subscribers\n this.onLogin.next(this._data);\n this.onChange.next(this._data);\n\n // Display toast (without await, because not need to wait toast close event)\n if (!opts || opts.showToast !== false) {\n this.showToast({message: 'ACCOUNT.INFO.RELOADED', type: 'info'});\n }\n\n return this._data;\n }\n catch (error) {\n // Cannot reload but was login: force to logout\n if (wasLogin && !this.isLogin()) {\n console.error(`[account] Reloading account failed. Will force logout...`, error);\n await this.logout();\n }\n else {\n throw error;\n }\n }\n }\n\n /**\n * Create or update an user account, to the remote storage\n *\n * @param account\n */\n async save(account: Account): Promise<Account> {\n if (!this._cache.pubkey) return Promise.reject('User not logged');\n if (this._cache.pubkey !== account.pubkey) return Promise.reject('Not user account');\n\n account = await this.saveRemotely(account, this._cache.keypair);\n\n // Set defaults\n account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);\n this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);\n\n this._data = account;\n this._cache.loaded = true;\n\n // Save locally (in storage)\n await this.saveLocally();\n\n // Send event\n this.onLogin.next(this._data);\n this.onChange.next(this._data);\n\n return this._data;\n }\n\n async logout(): Promise<void> {\n\n const hadAuthToken = this._cache.authToken && true;\n const hadAuthBasic = this._cache.authBasic && true;\n const pubkey = this._cache && this._cache.pubkey;\n\n this.resetData();\n\n if (!this.settings.hasOfflineFeature()) {\n\n // Remove all data from the local storage\n await Promise.all([\n this.storage.remove(PUBKEY_STORAGE_KEY),\n this.storage.remove(TOKEN_STORAGE_KEY),\n this.storage.remove(ACCOUNT_STORAGE_KEY),\n pubkey && this.storage.remove(ACCOUNT_STORAGE_KEY + '#' + pubkey) || Promise.resolve(),\n this.storage.remove(SECKEY_STORAGE_KEY)\n ]);\n }\n\n // Offline features enable: need to keep some data\n else {\n // Always remove only secret key\n // But keep:\n // - account by pubkey\n // - auth token\n await Promise.all([\n this.storage.remove(PUBKEY_STORAGE_KEY),\n this.storage.remove(ACCOUNT_STORAGE_KEY),\n this.storage.remove(SECKEY_STORAGE_KEY)\n ]);\n }\n\n // Clean page history, in local settings\n await this.settings.clearPageHistory();\n\n // Notify observers\n this.onLogout.next();\n if (hadAuthToken) this.onAuthTokenChange.next(undefined);\n if (hadAuthBasic) this.onAuthBasicChange.next(undefined);\n this.onChange.next(undefined);\n }\n\n /**\n * Load a account\n *\n * @param opts\n */\n async load(opts?: {\n offline?: boolean;\n fetchPolicy?: FetchPolicy;\n }): Promise<Account | undefined> {\n\n const now = this._debug && Date.now();\n if (this._debug) console.debug(`[account] Loading account...`);\n let json: any;\n\n // Load locally\n const offline = this.network.offline\n && (!opts || (opts.fetchPolicy !== 'network-only' && opts.fetchPolicy !== 'no-cache'))\n || (opts && opts.offline === true);\n if (offline) {\n json = await this.storage.get(ACCOUNT_STORAGE_KEY);\n json = json && (typeof json === 'string') && JSON.parse(json) || json;\n json = json && this._cache.pubkey && (json.pubkey === this._cache.pubkey) && json || null;\n if (!json && this._cache.pubkey) {\n json = await this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this._cache.pubkey);\n json = json && (typeof json === 'string') && JSON.parse(json) || json;\n }\n }\n\n // Load remotely\n else {\n const {data} = await this.graphql.query<{ data: any }>({\n query: LoadQuery,\n error: { code: ErrorCodes.LOAD_ACCOUNT_ERROR, message: 'ERROR.LOAD_ACCOUNT_ERROR' },\n fetchPolicy: opts && opts.fetchPolicy || 'no-cache' || undefined\n });\n json = data;\n }\n\n if (json) {\n const account = Account.fromObject(json);\n if (this._debug) console.debug(`[account] Account loaded in ${Date.now() - now}ms`, account);\n return account;\n }\n else {\n console.warn(`[account] Account not found !`);\n return undefined;\n }\n }\n\n\n /**\n * Check if email is available for new account registration.\n * Throw an error if not available\n *\n * @param email\n */\n async checkEmailAvailable(email: string): Promise<void> {\n const isEmailExists = await this.isEmailExists(email);\n if (isEmailExists) {\n throw { code: ErrorCodes.EMAIL_ALREADY_REGISTERED, message: 'ERROR.EMAIL_ALREADY_REGISTERED' };\n }\n }\n\n /**\n * Check if email is exists in server.\n *\n * @param email\n */\n async isEmailExists(email: string): Promise<boolean> {\n\n if (this._debug) console.debug('[account] Checking if {' + email + '} exists...');\n\n const data = await this.graphql.query<{ isEmailExists: boolean }, IsEmailExistsVariables>({\n query: IsEmailExistsQuery,\n variables: {\n email,\n hash: undefined\n }\n });\n\n if (this._debug) console.debug('[account] Email exist: ' + (data && data.isEmailExists));\n\n return data && data.isEmailExists;\n }\n\n async sendConfirmationEmail(email: string, locale?: string): Promise<boolean> {\n\n locale = locale || this.settings.locale;\n console.debug('[account] Sending confirmation email to {' + email + '} with locale {' + locale + '}...');\n\n return await this.graphql.mutate<boolean>({\n mutation: SendConfirmEmailMutation,\n variables: {\n email,\n locale\n },\n error: {\n code: ErrorCodes.SENT_CONFIRMATION_EMAIL_FAILED,\n message: 'ERROR.SENT_ACCOUNT_CONFIRMATION_EMAIL_FAILED'\n }\n });\n }\n\n async confirmEmail(email: String, code: String): Promise<boolean> {\n\n console.debug('[account] Sendng confirm request for email {' + email + '} with code {' + code + '}...');\n\n const res = await this.graphql.mutate<{ confirmAccountEmail: boolean }>({\n mutation: ConfirmEmailMutation,\n variables: {\n email,\n code\n },\n error: {\n code: ErrorCodes.CONFIRM_EMAIL_FAILED,\n message: 'ERROR.CONFIRM_ACCOUNT_EMAIL_FAILED'\n }\n });\n return res && res.confirmAccountEmail;\n }\n\n listenChanges(opts?: AccountWatchOptions): Subscription {\n if (this._enableListenChanges) return new Subscription(); // Already started: skip\n\n return this.startListenRemoteChanges(opts);\n }\n\n get additionalFields(): FormFieldDefinition[] {\n return this._$additionalFields.getValue();\n }\n\n get $additionalFields(): Observable<FormFieldDefinition[]> {\n return this._$additionalFields.asObservable();\n }\n\n getAdditionalField(key: string): FormFieldDefinition | undefined {\n return this._$additionalFields.getValue().find(f => f.key === key);\n }\n\n registerAdditionalField(field: FormFieldDefinition) {\n const values = this._$additionalFields.getValue();\n if (!!values.find(f => f.key === field.key)) {\n throw new Error(`Additional account field {key: ${field.key}} already define.`);\n }\n if (this._debug) console.debug(`[account] Found additional account's field {key: ${field.key}}`);\n this._$additionalFields.next(values.concat(field));\n }\n\n /* -- protected method -- */\n\n protected resetData() {\n this.stopListenRemoteChanges();\n this._cache.loaded = false;\n this._cache.keypair = null;\n this._cache.authToken = null;\n this._cache.authBasic = null;\n this._cache.pubkey = null;\n this._cache.mainProfile = null;\n this._cache.person = null;\n this._cache.department = null;\n this._data = new Account();\n }\n\n protected async loadData(opts?: {\n offline?: boolean;\n fetchPolicy?: FetchPolicy;\n }): Promise<Account> {\n if (!this._cache.pubkey) throw new Error('User not logged');\n\n this._cache.loaded = false;\n\n try {\n const account = (await this.load(opts)) || new Account();\n\n // Set defaults\n account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);\n account.settings = account.settings || new UserSettings();\n account.settings.locale = account.settings.locale || this.settings.locale;\n account.settings.latLongFormat = account.settings.latLongFormat || this.settings.latLongFormat || 'DDMM';\n account.settings.content = account.settings.content || {};\n\n // Read main profile\n this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);\n\n // Update, instead of replace it\n if (this._data) {\n this._data.fromObject(account);\n }\n else {\n this._data = account;\n }\n this._cache.loaded = true;\n\n // Apply settings, found in remote account\n if (account.settings) {\n const settings = {\n ...this.settings.settings,\n ...account.settings.asLocalSettings()\n }\n await this.settings.apply(settings);\n }\n\n return this._data;\n }\n catch (error) {\n this.resetData();\n if (error.code && error.message) throw error;\n\n console.error(error);\n throw {\n code: ErrorCodes.LOAD_ACCOUNT_ERROR,\n message: 'ERROR.LOAD_ACCOUNT_ERROR'\n };\n }\n }\n\n protected async listenSettings(): Promise<void>{\n // When settings changed: save it remotely\n this.registerSubscription(\n this.settings.onChange\n .pipe(\n debounceTime(1000),\n filter(() => this.isLogin() && this.network.online)\n )\n .subscribe(settings => this.saveLocalSettingsRemotely(settings)));\n }\n\n protected async restoreLocally(): Promise<Account | undefined> {\n\n // Restore from storage\n const values = await Promise.all([\n this.storage.get(PUBKEY_STORAGE_KEY),\n this.storage.get(TOKEN_STORAGE_KEY),\n this.storage.get(SECKEY_STORAGE_KEY)\n ]);\n const pubkey = values[0];\n const token = values[1];\n const seckey = values[2];\n\n // Quit if no pubkey (not logged)\n if (!pubkey) return;\n\n // Quit if could not auth on pod\n const canRemoteAuth = token || seckey || false;\n if (!canRemoteAuth) return;\n\n if (this._debug) console.debug(`[account] Account restoration...`);\n\n this._cache.authToken = token;\n this._cache.pubkey = pubkey;\n this._cache.keypair = seckey && {\n publicKey: Base58.decode(pubkey),\n secretKey: Base58.decode(seckey)\n } || null;\n\n // Online mode: try to connect to pod\n if (this.network.online) {\n try {\n await this.authenticate();\n if (!this._cache.authToken && !this._cache.authBasic) throw new Error('Authentication failed');\n }\n catch (error) {\n // Offline feature are enable: continue in offline mode\n if (this.settings.hasOfflineFeature()) {\n console.warn('[account] Unable to authenticate on pod: forcing offline mode');\n this.network.setForceOffline(true, {showToast: false});\n // Continue\n }\n // No offline features enable (=offline mode not allowed)\n else {\n console.error(error);\n this.logout();\n return;\n }\n\n }\n }\n\n // Get the account, from pubkey\n let jsonAccount = await this.storage.get(`${ACCOUNT_STORAGE_KEY}#${pubkey}`);\n if (!jsonAccount) {\n // Try using the old storage key\n const accountStr = await this.storage.get(ACCOUNT_STORAGE_KEY);\n jsonAccount = accountStr && ((typeof accountStr === 'string') && JSON.parse(jsonAccount) || accountStr);\n }\n\n // Invalid account: do not use it\n if (!jsonAccount || jsonAccount.pubkey !== pubkey) return;\n\n // Transform to entity\n const account = Account.fromObject(jsonAccount);\n\n // Update data\n this._data = account;\n this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);\n this._cache.loaded = true;\n\n // Emit event\n this.onLogin.next(this._data);\n this.onChange.next(this._data);\n\n if (this._enableListenChanges) this.startListenRemoteChanges();\n\n if (this._debug) console.debug(`[account] Account restoration [OK] {pubkey: ${pubkey.substr(0, 8)}}, {profile: ${this._cache.mainProfile}}`);\n\n return account;\n }\n\n /**\n * Save account into the local storage\n */\n protected async saveLocally(): Promise<void> {\n if (!this._cache.pubkey) throw new Error('User not logged');\n\n if (this._debug) console.debug(`[account] Saving account {${this._cache.pubkey.substring(0, 6)}} in local storage...`);\n\n // Convert account to json\n const json = this._data.asObject({keepTypename: true});\n const seckey = this._cache.keypair && this._cache.keypair.secretKey && Base58.encode(this._cache.keypair.secretKey) || null;\n\n // Convert avatar URL to dataUrl (e.g. 'data:image/png:<base64 content>')\n const hasAvatarUrl = json.avatar && !json.avatar.endsWith(DEFAULT_AVATAR_IMAGE) &&\n (json.avatar.startsWith('http://') || (json.avatar.startsWith('https://')));\n if (hasAvatarUrl && this.network.online) {\n await this.file.getImage(json.avatar, {\n thumbnail: true,\n outputType: 'dataUrl'\n })\n .then(dataUrl => {\n if (dataUrl && this._debug) console.debug('[account] Image fetched: ', dataUrl.substring(0, 50));\n\n // TODO: make sure to display Base64 image in the menu top header\n //jsonAccount.avatar = dataUrl;\n })\n .catch(err => {\n console.error(`[account] Error while fetching image: ${json.avatar}: ${err}`);\n });\n }\n\n try {\n await Promise.all([\n this.storage.set(PUBKEY_STORAGE_KEY, this._cache.pubkey),\n this.storage.set(TOKEN_STORAGE_KEY, this._cache.authToken),\n this.storage.set(`${ACCOUNT_STORAGE_KEY}#${this._cache.pubkey}`, json),\n // Secret key (optional)\n seckey && this.storage.set(SECKEY_STORAGE_KEY, seckey) || this.storage.remove(SECKEY_STORAGE_KEY),\n // Remove old storage key\n this.storage.remove(ACCOUNT_STORAGE_KEY)\n ]);\n\n if (this._debug) console.debug('[account] Account saved in local storage');\n }\n catch(err) {\n console.error('[account] Error while saving account locally: ' + (err && err.message || err), err);\n }\n }\n\n async saveLocalSettingsRemotely(source: LocalSettings){\n if (!source || !this.isLogin() || source.accountInheritance === false) return; // Skip\n const account = this.account;\n\n // Merge local settings into account's settings\n const settings = UserSettings.fromObject(account.settings) || new UserSettings();\n const changed = settings.merge(source, ['locale', 'latLongFormat', 'properties']);\n\n if (!changed) return; // Skip if unchanged\n\n // Save remotely\n this.account.settings = settings;\n await this.saveSettingsRemotely(settings);\n }\n\n /**\n * Create or update an user account\n *\n * @param account\n * @param keyPair\n */\n protected async saveRemotely(account: Account, keyPair?: KeyPair): Promise<Account> {\n account.pubkey = account.pubkey || (keyPair && Base58.encode(keyPair.publicKey));\n if (!account.pubkey) throw new Error('Missing account pubkey');\n\n const now = this._debug && Date.now();\n if (this._debug) console.debug(`[account] Saving account remotely...`);\n\n const isNew = isNil(account.id);\n\n // If this is an update: get existing account's updateDate, to avoid 'version error' when saving\n if (!isNew) {\n const existingAccount = await this.load({ fetchPolicy: 'network-only' });\n if (!existingAccount || !existingAccount.updateDate) {\n throw { code: ErrorCodes.ACCOUNT_NOT_EXISTS, message: 'ERROR.ACCOUNT_NOT_EXISTS' };\n }\n this.copyIdAndUpdateDate(existingAccount, account);\n }\n\n const json = account.asObject(MINIFY_ENTITY_FOR_POD);\n\n // User not allow to change his profiles\n delete json.profiles;\n\n // Execute mutation\n const { data } = await this.graphql.mutate<{ data: Account }>({\n mutation: isNew ? AccountMutations.create : AccountMutations.save,\n variables: { data: json },\n error: {\n code: ErrorCodes.SAVE_ACCOUNT_ERROR,\n message: 'ERROR.SAVE_ACCOUNT_ERROR'\n }\n });\n\n // Copy update properties\n this.copyIdAndUpdateDate(data, account);\n\n if (this._debug) console.debug(`[account] Account remotely saved in ${Date.now() - now}ms`);\n\n return account;\n }\n\n /**\n * Create or update user settings\n *\n * @param settings\n */\n protected async saveSettingsRemotely(settings: UserSettings) {\n\n const now = this._debug && Date.now();\n if (this._debug) console.debug(`[account] Saving settings remotely...`);\n\n const json = settings.asObject(MINIFY_ENTITY_FOR_POD);\n\n // Execute mutation\n const { data } = await this.graphql.mutate<{ data: UserSettings }>({\n mutation: AccountMutations.saveSettings,\n variables: { data: json },\n error: {\n code: ErrorCodes.SAVE_SETTINGS_ERROR,\n message: 'ERROR.SAVE_SETTINGS_ERROR'\n }\n });\n\n // Copy update properties\n this.copyIdAndUpdateDateSettings(data, settings);\n\n if (this._debug) console.debug(`[account] Settings remotely saved in ${Date.now() - now}ms`);\n\n // Save into account\n if (this.account) this.account.settings = settings;\n }\n\n protected async authenticateAndGetToken(token?: string, counter?: number): Promise<string> {\n if (!this._cache.pubkey) throw new Error('User not logged');\n\n if (!counter) console.info('[account] Authentication on pod...');\n\n if (counter > 4) {\n if (this._debug) console.debug(`[account] Failed to authentication on pod (after ${counter} attempts)`);\n throw { code: ErrorCodes.AUTH_SERVER_ERROR, message: 'ERROR.AUTH_SERVER_ERROR' };\n }\n\n // Check if valid\n if (token) {\n const data = await this.graphql.query<{ authenticate: boolean }, { token: string }>({\n query: AuthQuery,\n variables: {\n token\n },\n error: {\n code: ErrorCodes.UNAUTHORIZED,\n message: 'ERROR.UNAUTHORIZED'\n },\n fetchPolicy: 'no-cache'\n });\n\n // Token is accepted by the server\n if (data && data.authenticate) {\n // Store the token\n this.onAuthTokenChange.next(token);\n\n console.info(`[account] Authentication on pod [OK] {pubkey: '${this._cache.pubkey.substr(0, 8)}'}`);\n return token; // return the token\n }\n\n // Continue (will retry with another challenge)\n }\n\n // Generate a new token\n const challengeError = {\n code: ErrorCodes.AUTH_CHALLENGE_ERROR,\n message: 'ERROR.AUTH_CHALLENGE_ERROR'\n };\n const data = await this.graphql.query<{\n authChallenge: {\n pubkey: string;\n challenge: string;\n signature: string;\n };\n }>({\n query: AuthChallengeQuery,\n variables: {},\n error: challengeError,\n fetchPolicy: 'network-only'\n });\n\n // Check challenge\n if (!data || !data.authChallenge) throw challengeError; // Should never occur\n\n // Check server signature\n const signatureOK = await this.cryptoService.verify(\n data.authChallenge.challenge,\n data.authChallenge.signature,\n data.authChallenge.pubkey\n );\n if (!signatureOK) {\n console.warn('FIXME: Bad peer signature on auth challenge !', data.authChallenge);\n }\n // TODO: check server pubkey as a valid certificate\n\n // Do the challenge\n const signature = await this.cryptoService.sign(data.authChallenge.challenge, this._cache.keypair);\n const newToken = `${this._cache.pubkey}:${data.authChallenge.challenge}|${signature}`;\n\n // iterate with the new token\n return await this.authenticateAndGetToken(newToken, (counter || 1) + 1 /* increment */);\n }\n\n protected startListenRemoteChanges(opts?: AccountWatchOptions): Subscription {\n if (this._listenChangesSubscription) this.stopListenRemoteChanges(); // Stop previous subscription\n if (this.network.offline) return new Subscription(); // Offline: skip\n\n this._listenChangesSubscription = this.watchChanges(opts)\n .subscribe({\n next: (data) => {\n console.debug(`[account] Remote update detected at ${data.updateDate}`);\n this.reload();\n },\n error: (err) => {\n if (err && +err.code === ServerErrorCodes.NOT_FOUND) {\n console.info('[account] [WS] Account not exists anymore: force user to logout...', err);\n this.logout();\n } else if (err && +err.code === ServerErrorCodes.UNAUTHORIZED) {\n console.info('[account] [WS] Account not authorized: force user to logout...', err);\n this.logout();\n } else {\n console.warn('[account] [WS] Received error:', err);\n }\n }\n });\n this._listenChangesSubscription.add(() => {\n console.debug(`[account] Stop watching remote changes`);\n this._listenChangesSubscription = null\n });\n return this._listenChangesSubscription;\n }\n\n protected stopListenRemoteChanges() {\n this._listenChangesSubscription?.unsubscribe();\n }\n\n protected watchChanges(opts?: AccountWatchOptions): Observable<Account> {\n\n if (!this.started) {\n // Wait service ready, then loop\n return from(this.ready())\n .pipe(switchMap(() => this.watchChanges(opts)));\n }\n\n if (!this._cache.pubkey) throw new Error('Not logged in');\n if (this.network.offline) throw new Error('Cannot watch account changes: network is offline.');\n\n const variables = {\n interval: toNumber(opts && opts.intervalInSeconds, this._listenIntervalInSeconds)\n };\n\n console.debug(`[account] Watching remote changes, every ${variables.interval}s`);\n\n return this.graphql.subscribe<{data: any}>({\n query: AccountSubscriptions.listenChanges,\n variables,\n error: {\n code: ErrorCodes.SUBSCRIBE_ACCOUNT_ERROR,\n message: 'ERROR.ACCOUNT.SUBSCRIBE_ERROR'\n }\n }).pipe(\n map(({data}) => data),\n // Keep only if newer\n filter(data => {\n const currentUpdateDate: Moment = fromDateISOString(this._data?.updateDate);\n const remoteUpdateDate: Moment = fromDateISOString(data?.updateDate);\n return (remoteUpdateDate && (!currentUpdateDate || !remoteUpdateDate.isSame(currentUpdateDate, 'millisecond')));\n })\n );\n }\n\n protected copyIdAndUpdateDate(source: Account | undefined, target: Account) {\n if (!source) return;\n\n target.id = source.id || target.id;\n target.updateDate = source.updateDate || target.updateDate;\n\n this.copyIdAndUpdateDateSettings(source.settings, target.settings);\n }\n\n protected copyIdAndUpdateDateSettings(source: UserSettings | undefined, target: UserSettings) {\n if (!source) return;\n\n target.id = source.id || target.id;\n target.updateDate = source.updateDate || target.updateDate;\n }\n\n protected showToast<T = any>(opts: ShowToastOptions): Promise<OverlayEventDetail<T>> {\n return Toasts.show(this.toastController, this.translate, opts);\n }\n}\n","import {Moment} from 'moment';\nimport {FormFieldDefinition} from '../../../shared/form/field.model';\nimport {Entity, EntityAsObjectOptions, EntityUtils, IEntity} from './entity.model';\nimport {Department} from './department.model';\nimport {PropertiesMap} from '../../../shared/types';\nimport {fromDateISOString, toDateISOString} from '../../../shared/dates';\nimport {isNotNil} from '../../../shared/functions';\nimport {EntityClass} from './entity.decorators';\n\n// @dynamic\n@EntityClass({typename: 'SoftwareVO'})\nexport class Software<\n T extends Software<any> = Software<any>\n >\n extends Entity<T, number>\n implements IEntity<T, number> {\n\n static fromObject: (source: any, opts?: any) => Software;\n\n label: string;\n name: string;\n description: string;\n comments: string;\n creationDate: Date | Moment;\n statusId: number;\n properties: PropertiesMap;\n\n constructor(__typename?: string) {\n super(__typename || Software.TYPENAME);\n }\n\n asObject(options?: EntityAsObjectOptions): any {\n const target: any = super.asObject(options);\n target.creationDate = toDateISOString(this.creationDate);\n target.properties = this.properties;\n return target;\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.label = source.label;\n this.name = source.name;\n this.description = source.description;\n this.comments = source.comments;\n this.creationDate = fromDateISOString(source.creationDate);\n this.statusId = source.statusId;\n\n if (source.properties && Array.isArray(source.properties)) {\n this.properties = EntityUtils.getPropertyArrayAsObject(source.properties);\n } else {\n this.properties = {...source.properties};\n }\n }\n}\n\n// @dynamic\n@EntityClass({typename: 'ConfigurationVO'})\nexport class Configuration extends Software<Configuration> {\n\n static fromObject: (source: any, opts?: any) => Configuration;\n\n smallLogo: string;\n largeLogo: string;\n backgroundImages: string[];\n partners: Department[];\n\n constructor() {\n super(Configuration.TYPENAME);\n }\n\n clone(): Configuration {\n return this.copy(new Configuration());\n }\n\n copy(target: Configuration): Configuration {\n target.fromObject(this);\n return target;\n }\n\n asObject(options?: EntityAsObjectOptions): any {\n const target: any = super.asObject(options);\n target.partners = this.partners && this.partners.map(p => p.asObject(options)) || undefined;\n return target;\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.smallLogo = source.smallLogo;\n this.largeLogo = source.largeLogo;\n this.backgroundImages = source.backgroundImages;\n this.partners = source.partners && source.partners.map(Department.fromObject) || undefined;\n }\n\n getPropertyAsBoolean(definition: FormFieldDefinition): boolean {\n const value = this.getProperty(definition);\n return isNotNil(value) ? (value && value !== 'false') : undefined;\n }\n\n getPropertyAsInt(definition: FormFieldDefinition): number {\n const value = this.getProperty(definition);\n return isNotNil(value) ? parseInt(value) : undefined;\n }\n\n getPropertyAsNumbers(definition: FormFieldDefinition): number[] {\n const value = this.getProperty(definition);\n if (typeof value === 'string') return value.split(',').map(parseFloat) || undefined;\n return isNotNil(value) ? [parseFloat(value)] : undefined;\n }\n\n getPropertyAsStrings(definition: FormFieldDefinition): string[] {\n const value = this.getProperty(definition);\n return value && value.split(',') || undefined;\n }\n\n getProperty<T = string>(definition: FormFieldDefinition): T {\n return isNotNil(this.properties[definition.key]) ? this.properties[definition.key] : (definition.defaultValue || undefined);\n }\n}\n","// TODO: rename to CONFIG_OPTIONS_MAP\n// then declare a type like this :\n// > export declare type ConfigOptions = key of CONFIG_OPTIONS_MAP\nimport { FormFieldDefinition } from '../../../shared/form/field.model';\nimport { APP_LOCALES } from '../model/settings.model';\nimport { AuthTokenType } from '../network.service';\n\nexport const CORE_CONFIG_OPTIONS = Object.freeze({\n LOGO: <FormFieldDefinition>{\n key: 'sumaris.logo',\n label: 'CONFIGURATION.OPTIONS.LOGO',\n type: 'string'\n },\n FAVICON: <FormFieldDefinition>{\n key: 'sumaris.favicon',\n label: 'CONFIGURATION.OPTIONS.FAVICON',\n type: 'string'\n },\n DEFAULT_LOCALE: <FormFieldDefinition>{\n key: 'sumaris.defaultLocale',\n label: 'CONFIGURATION.OPTIONS.DEFAULT_LOCALE',\n type: 'enum',\n values: APP_LOCALES\n },\n DEFAULT_LAT_LONG_FORMAT: <FormFieldDefinition>{\n key: 'sumaris.defaultLatLongFormat',\n label: 'CONFIGURATION.OPTIONS.DEFAULT_LATLONG_FORMAT',\n type: 'enum',\n values: [\n {\n key: 'DDMMSS',\n value: 'COMMON.LAT_LONG.DDMMSS_PLACEHOLDER'\n },\n {\n key: 'DDMM',\n value: 'COMMON.LAT_LONG.DDMM_PLACEHOLDER'\n },\n {\n key: 'DD',\n value: 'COMMON.LAT_LONG.DD_PLACEHOLDER'\n }\n ]\n },\n REGISTRATION_ENABLE: <FormFieldDefinition>{\n key: 'sumaris.registration.enable',\n label: 'CONFIGURATION.OPTIONS.HOME.ENABLE_REGISTRATION',\n type: 'boolean',\n defaultValue: true\n },\n AUTH_TOKEN_TYPE: <FormFieldDefinition>{\n key: 'sumaris.auth.token.type',\n label: 'CONFIGURATION.OPTIONS.AUTH_TOKEN_TYPE_PLACEHOLDER',\n type: 'enum',\n values: [\n {\n key: <AuthTokenType>'token',\n value: 'CONFIGURATION.OPTIONS.AUTH_TOKEN_TYPE.TOKEN'\n },\n {\n key: <AuthTokenType>'basic',\n value: 'CONFIGURATION.OPTIONS.AUTH_TOKEN_TYPE.BASIC'\n },\n {\n key: <AuthTokenType>'basic-and-token',\n value: 'CONFIGURATION.OPTIONS.AUTH_TOKEN_TYPE.BASIC_AND_TOKEN'\n }\n ],\n defaultValue: <AuthTokenType>'token'\n },\n GRAVATAR_ENABLE: <FormFieldDefinition>{\n key: 'sumaris.gravatar.enable',\n label: 'CONFIGURATION.OPTIONS.ENABLE_GRAVATAR',\n type: 'boolean',\n defaultValue: false\n },\n GRAVATAR_URL: <FormFieldDefinition>{\n key: 'sumaris.gravatar.url',\n label: 'CONFIGURATION.OPTIONS.GRAVATAR_URL',\n type: 'string',\n defaultValue: 'https://www.gravatar.com/avatar/{md5}'\n },\n TESTING: <FormFieldDefinition>{\n key: 'sumaris.testing.enable',\n label: 'CONFIGURATION.OPTIONS.TESTING',\n type: 'boolean'\n },\n APP_MIN_VERSION: <FormFieldDefinition>{\n key: 'sumaris.app.version.min',\n label: 'CONFIGURATION.OPTIONS.APP_MIN_VERSION',\n type: 'string'\n },\n HELP_URL: <FormFieldDefinition>{\n key: 'sumaris.help.url',\n label: 'CONFIGURATION.OPTIONS.HELP_URL',\n type: 'string'\n },\n FORUM_URL: <FormFieldDefinition>{\n key: 'sumaris.forum.url',\n label: 'CONFIGURATION.OPTIONS.FORUM_URL',\n type: 'string'\n },\n LOGO_LARGE: <FormFieldDefinition>{\n key: 'sumaris.logo.large',\n label: 'CONFIGURATION.OPTIONS.HOME.LOGO_LARGE',\n type: 'string'\n },\n MENU_ITEMS: <FormFieldDefinition>{\n key: 'sumaris.menu.items',\n label: 'CONFIGURATION.OPTIONS.MENU.ITEMS',\n type: 'string'\n // -- FOR DEV\n /*,defaultValue: JSON.stringify([\n {title: \"Item #1\", path: \"/settings\", icon: \"people\", after: \"MENU.HOME\"},\n {title: \"Item #2\", path: \"/settings\", icon: \"people\", before: \"MENU.LOGOUT\"}\n ])*/\n },\n HOME_PARTNERS_DEPARTMENTS: <FormFieldDefinition>{\n key: 'sumaris.partner.departments',\n label: 'CONFIGURATION.OPTIONS.HOME.PARTNER_DEPARTMENTS',\n type: 'string'\n },\n HOME_BACKGROUND_IMAGE: <FormFieldDefinition>{\n key: 'sumaris.background.images',\n label: 'CONFIGURATION.OPTIONS.HOME.BACKGROUND_IMAGES',\n type: 'string'\n },\n COLOR_PRIMARY: <FormFieldDefinition>{\n key: 'sumaris.color.primary',\n label: 'CONFIGURATION.OPTIONS.COLORS.PRIMARY',\n type: 'color'\n },\n COLOR_SECONDARY: <FormFieldDefinition>{\n key: 'sumaris.color.secondary',\n label: 'CONFIGURATION.OPTIONS.COLORS.SECONDARY',\n type: 'color'\n },\n COLOR_TERTIARY: <FormFieldDefinition>{\n key: 'sumaris.color.tertiary',\n label: 'CONFIGURATION.OPTIONS.COLORS.TERTIARY',\n type: 'color'\n },\n COLOR_SUCCESS: <FormFieldDefinition>{\n key: 'sumaris.color.success',\n label: 'CONFIGURATION.OPTIONS.COLORS.SUCCESS',\n type: 'color'\n },\n COLOR_WARNING: <FormFieldDefinition>{\n key: 'sumaris.color.warning',\n label: 'CONFIGURATION.OPTIONS.COLORS.WARNING',\n type: 'color'\n },\n COLOR_ACCENT: <FormFieldDefinition>{\n key: 'sumaris.color.accent',\n label: 'CONFIGURATION.OPTIONS.COLORS.ACCENT',\n type: 'color'\n },\n COLOR_DANGER: <FormFieldDefinition>{\n key: 'sumaris.color.danger',\n label: 'CONFIGURATION.OPTIONS.COLORS.DANGER',\n type: 'color'\n },\n ANDROID_INSTALL_URL: <FormFieldDefinition>{\n key: 'sumaris.android.install.url',\n label: 'CONFIGURATION.OPTIONS.ANDROID_INSTALL_URL',\n type: 'string'\n },\n DB_TIMEZONE: <FormFieldDefinition>{\n key: 'sumaris.persistence.db.timezone',\n label: 'DB Timezone (readonly)',\n type: 'string',\n isTransient: true // ONly on server, cannot be set\n }\n});\n","import {Inject, Injectable, InjectionToken, Optional} from '@angular/core';\nimport {gql} from '@apollo/client/core';\nimport {Configuration} from './model/config.model';\nimport {Storage} from '@ionic/storage';\nimport {BehaviorSubject, Observable, Subject} from 'rxjs';\nimport {ErrorCodes} from './errors';\nimport {GraphqlService} from '../graphql/graphql.service';\nimport {FormFieldDefinition, FormFieldDefinitionMap} from '../../shared/form/field.model';\nimport {isNotEmptyArray, isNotNil} from '../../shared/functions';\nimport {FileService} from '../../shared/file/file.service';\nimport {NetworkService} from './network.service';\nimport {CORE_CONFIG_OPTIONS} from './config/core.config';\nimport {Platform, ToastController} from '@ionic/angular';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {TranslateService} from '@ngx-translate/core';\nimport {filter} from 'rxjs/operators';\nimport {EntityServiceLoadOptions, IEntityService} from '../../shared/services/entity-service.class';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {BaseGraphqlService} from './base-graphql-service.class';\nimport {IStartableService} from '../../shared/services/startable-service.class';\nimport {AccountService} from './account.service';\nimport {isMobile, isWindows} from '../../shared/platforms';\n\n\nconst CONFIGURATION_STORAGE_KEY = 'configuration';\n\n/* ------------------------------------\n * GraphQL queries\n * ------------------------------------*/\nexport const Fragments = {\n config: gql`\n fragment ConfigFragment on ConfigurationVO {\n id\n label\n name\n description\n comments\n properties\n smallLogo\n largeLogo\n backgroundImages\n partners {\n id\n label\n name\n logo\n siteUrl\n __typename\n }\n updateDate\n creationDate\n statusId\n __typename\n }\n `\n};\n\nconst LoadQuery: any = gql`\nquery Configuration{\n data: configuration{\n ...ConfigFragment\n }\n}\n ${Fragments.config}\n`;\n\n// Save (create or update) account mutation\nconst SaveMutation: any = gql`\n mutation SaveConfiguration($data: ConfigurationVOInput){\n data: saveConfiguration(config: $data){\n ...ConfigFragment\n }\n }\n ${Fragments.config}\n`;\n\nconst ClearCache: any = gql`\n query ClearCache($name: String) {\n clearCache(name: $name)\n }\n`;\n\nconst CacheStatistics: any = gql`\n query CacheStatistics {\n cacheStatistics\n }\n`;\n\nexport const APP_CONFIG_OPTIONS = new InjectionToken<FormFieldDefinitionMap>('defaultOptions');\n\n@Injectable({\n providedIn: 'root',\n deps: [APP_CONFIG_OPTIONS]\n})\nexport class ConfigService\n extends BaseGraphqlService<Configuration, any, number, Configuration>\n implements IEntityService<Configuration>, IStartableService<Configuration> {\n\n private _optionDefs: FormFieldDefinition[];\n private $data = new BehaviorSubject<Configuration>(null);\n\n get config(): Observable<Configuration> {\n // If first call: start loading\n if (!this.started) this.start();\n return this.$data.pipe(filter(isNotNil));\n }\n\n constructor(\n protected platform: Platform,\n protected graphql: GraphqlService,\n protected storage: Storage,\n protected network: NetworkService,\n protected file: FileService,\n protected toastController: ToastController,\n protected translate: TranslateService,\n protected accountService: AccountService,\n @Inject(ENVIRONMENT) protected environment,\n @Optional() @Inject(APP_CONFIG_OPTIONS) defaultOptionsMap: FormFieldDefinitionMap\n ) {\n super(graphql, environment);\n\n this._debug = !environment.production;\n if (this._debug) console.debug('[config] Creating service');\n\n this._optionDefs = Object.values({...CORE_CONFIG_OPTIONS, ...defaultOptionsMap});\n\n }\n\n protected async ngOnStart(): Promise<Configuration> {\n console.info('[config] Starting configuration...');\n\n const data = await this.loadOrRestoreLocally();\n this.$data.next(data);\n\n // Restart if graphql service restart\n this.registerSubscription(\n this.graphql.stopSubject.subscribe(() => this.restart())\n );\n\n return data;\n }\n\n async loadDefault(\n opts?: EntityServiceLoadOptions): Promise<Configuration> {\n const now = Date.now();\n console.debug('[config] Loading Pod configuration...');\n\n const query = opts && opts.query || LoadQuery;\n const variables = opts && opts.variables || undefined;\n const res = await this.graphql.query<{ data: any }>({\n query,\n variables,\n error: {code: ErrorCodes.LOAD_CONFIG_ERROR, message: 'ERROR.LOAD_CONFIG_ERROR'},\n fetchPolicy: opts && opts.fetchPolicy || undefined/*default*/\n });\n\n const data = res && res.data ? Configuration.fromObject(res.data) : undefined;\n console.info(`[config] Pod configuration loaded in ${Date.now() - now}ms:`, data);\n return data;\n }\n\n async load(\n id: number,\n opts?: EntityServiceLoadOptions & { query?: any }): Promise<Configuration> {\n console.warn('[config] Invalid call of configService.load(id). Please use loadDefault() instead');\n\n return this.loadDefault();\n }\n\n canUserWrite(data: Configuration, opts?: any): boolean {\n return this.accountService.isAdmin();\n }\n\n /**\n * Save a configuration\n *\n * @param config\n */\n async save(config: Configuration): Promise<Configuration> {\n\n console.debug('[config] Saving Pod configuration...', config);\n\n const json = config.asObject();\n\n // Execute mutation\n const res = await this.graphql.mutate<{ data: any }>({\n mutation: SaveMutation,\n variables: {\n data: json\n },\n error: {\n code: ErrorCodes.SAVE_CONFIG_ERROR,\n message: 'ERROR.SAVE_CONFIG_ERROR'\n }\n });\n\n const savedConfig = res && res.data;\n\n // Copy update properties\n config.id = savedConfig && savedConfig.id || config.id;\n config.updateDate = savedConfig && savedConfig.updateDate || config.updateDate;\n\n console.debug('[config] Pod configuration saved!');\n\n const reloadedConfig = await this.loadDefault({fetchPolicy: 'network-only'});\n\n // If this is the default config\n const defaultConfig = this.$data.value;\n if (isNotNil(defaultConfig) && reloadedConfig.label === defaultConfig.label) {\n\n // Emit update event when is default config\n this.$data.next(reloadedConfig);\n }\n\n return reloadedConfig;\n }\n\n async getCacheStatistics(): Promise<string> {\n\n const now = Date.now();\n console.debug('[config] Loading server cache statistics...');\n\n const res = await this.graphql.query<{ cacheStatistics: any }>({\n query: CacheStatistics,\n variables: null,\n error: {code: ErrorCodes.LOAD_CONFIG_ERROR, message: 'ERROR.LOAD_CONFIG_ERROR'},\n fetchPolicy: 'network-only'\n });\n\n const data = res && res.cacheStatistics || undefined;\n console.info(`[config] Server cache statistics loaded in ${Date.now() - now}ms:`, data);\n return data;\n }\n\n async clearCache(opts?: {cacheName?: string}) {\n const now = Date.now();\n console.debug('[config] Clear server cache...');\n\n const variables = opts && opts.cacheName && {name: opts.cacheName} || undefined;\n\n const res = await this.graphql.query<{ clearCache: boolean }>({\n query: ClearCache,\n variables,\n error: {code: ErrorCodes.LOAD_CONFIG_ERROR, message: 'ERROR.LOAD_CONFIG_ERROR'},\n fetchPolicy: 'no-cache'\n });\n\n const data = res && res.clearCache || undefined;\n console.info(`[config] Clear server cache in ${Date.now() - now}ms:`, data);\n return data;\n }\n\n delete(data: Configuration, options?: any): Promise<any> {\n throw new Error('Not implemented yet!');\n }\n\n listenChanges(id: number, options?: any): Observable<Configuration | undefined> {\n return new Subject(); // TODO\n }\n\n get optionDefs(): FormFieldDefinition[] {\n return this._optionDefs;\n }\n\n /* -- protected method -- */\n\n private async loadOrRestoreLocally(): Promise<Configuration> {\n let data;\n let wasJustLoaded = false;\n try {\n data = await this.loadDefault({ fetchPolicy: 'network-only' });\n wasJustLoaded = true;\n } catch (err) {\n // Log, then continue\n console.error(err && err.message || err, err);\n }\n\n // Save it into local storage, for next startup\n if (data) {\n setTimeout(() => this.storeLocally(data), 1000);\n }\n\n // If not loaded remotely: try to restore it\n else {\n data = await this.restoreLocally();\n }\n\n // Make sure label has been filled\n data.label = data.label || this.environment.name;\n\n // Reset name (if same as label)\n data.name = (data.name !== data.label) ? data.name : undefined;\n\n // Check compatible version\n if (wasJustLoaded) {\n // TODO\n }\n\n return data;\n }\n\n private async restoreLocally(): Promise<Configuration> {\n let data: Configuration;\n\n // Try to load from local storage\n const value: any = await this.storage.get(CONFIGURATION_STORAGE_KEY);\n if (value) {\n console.debug('[config] Restoring configuration from local storage...');\n if (typeof value === 'string') {\n try {\n data = Configuration.fromObject(JSON.parse(value));\n } catch (err) {\n console.error(`Failed to parse config found in local storage: ${err && err.message || err}`, err);\n }\n }\n else if (typeof value === 'object') {\n data = Configuration.fromObject(value);\n }\n\n console.debug('[config] Restoring configuration [OK]');\n }\n\n // Or load default value, from the environment\n if (!data) {\n console.debug('[config] No configuration found. Using environment...');\n data = Configuration.fromObject(this.environment as any);\n }\n\n return data;\n }\n\n private async storeLocally(data?: Configuration) {\n // Nothing to store : reset\n if (!data) {\n await this.storage.remove(CONFIGURATION_STORAGE_KEY);\n }\n // Config exists: store it in the local storage\n else {\n let now = this._debug && Date.now();\n\n // Convert images, for offline usage\n if (this.network.online && isMobile(window)) {\n const jobs = [];\n\n // Download logos\n if (data.largeLogo && data.largeLogo.startsWith('http')) {\n jobs.push(this.file.getImage(data.largeLogo)\n .then(imgUrl => data.largeLogo = imgUrl));\n }\n if (data.smallLogo && data.smallLogo.startsWith('http')) {\n jobs.push(this.file.getImage(data.smallLogo)\n .then(imgUrl => data.smallLogo = imgUrl));\n }\n\n // Background images\n if (isNotEmptyArray(data.backgroundImages)) {\n const options = {\n maxWidth: this.platform.width(),\n maxHeight: this.platform.height()\n };\n\n // Convert the FIRST image found\n // WARN: it's NOT necessary to convert AL image, but only one, for smaller memory footprint\n const index = data.backgroundImages.findIndex((img) => img && img.startsWith('http'));\n if (index !== -1) {\n data.backgroundImages = data.backgroundImages.slice(); // Copy\n jobs.push(\n this.file.getImage(data.backgroundImages[index], options)\n .then(dataUrl => data.backgroundImages[index] = dataUrl));\n }\n }\n\n // Partners\n if (isNotEmptyArray(data.partners)) {\n data.partners.forEach((dep, index) => {\n if (dep && dep.logo && dep.logo.startsWith('http')) {\n jobs.push(this.file.getImage(dep.logo, {\n maxHeight: 50/*see home page CSS */\n })\n .then(img => dep.logo = img)\n .catch(err => {\n console.error(err && err.message || err);\n delete dep.logo;\n }));\n }\n });\n }\n\n if (jobs.length) {\n if (this._debug) console.debug(`[config] Fetching ${jobs.length} images...`);\n try {\n await Promise.all(jobs);\n if (this._debug) console.debug(`[config] Fetching ${jobs.length} images [OK] in ${Date.now() - now}ms`);\n }\n catch (err) {\n console.error(`[config] Failed to fetch image(s): ${err && err.message || err}`, err);\n }\n }\n }\n\n // Saving config to storage\n {\n now = this._debug && Date.now();\n if (this._debug) console.debug('[config] Saving config into local storage...');\n await this.storage.set(CONFIGURATION_STORAGE_KEY, data.asObject());\n if (this._debug) console.debug(`[config] Saving config into local storage [OK] in ${Date.now() - now}ms`);\n }\n }\n }\n\n protected async showToast(opts: ShowToastOptions) {\n await Toasts.show(this.toastController, this.translate, opts);\n }\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, ViewChild, ViewEncapsulation} from '@angular/core';\nimport {PopoverController} from '@ionic/angular';\nimport {UploadFileComponent} from './upload-file.component';\nimport {FileDeleteFn, FileUploadFn, UploadFile} from './upload-file.model';\nimport {isEmptyArray, isNotEmptyArray, isNotNilOrBlank} from '../functions';\nimport {TranslateService} from '@ngx-translate/core';\n\nexport interface UploadFilePopoverOptions<T> {\n title?: string;\n\n uploadFn: FileUploadFn<T>;\n deleteFn?: FileDeleteFn<any>;\n\n instantUpload?: boolean;\n uniqueFile?: boolean;\n fileExtension?: string;\n maxParallelUpload?: number;\n}\n\n@Component({\n selector: 'app-upload-file-popover',\n templateUrl: './upload-file-popover.component.html',\n styleUrls: ['./upload-file-popover.component.scss'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class UploadFilePopover implements UploadFilePopoverOptions<any> {\n\n @ViewChild('uploader', { static: true }) uploader: UploadFileComponent;\n\n @Input() fileExtension: string;\n @Input() title: string;\n @Input() uniqueFile = false;\n @Input() instantUpload = false;\n @Input() uploadFn: FileUploadFn<any>;\n @Input() deleteFn: FileDeleteFn<any>;\n @Input() maxParallelUpload: number;\n\n importing = false;\n error: string;\n\n get files(): UploadFile<any>[] {\n return this.uploader.files;\n }\n\n get disabled() {\n return this.importing || isEmptyArray(this.files);\n }\n\n get valid() {\n return isNotEmptyArray(this.files);\n }\n\n constructor(protected popoverController: PopoverController,\n protected translate: TranslateService,\n protected cd: ChangeDetectorRef) {\n }\n\n async onValidate(event: any): Promise<any> {\n event?.stopPropagation();\n\n // Avoid multiple call\n if (this.importing) return;\n\n console.debug('[upload-file-popover] Validate form: will upload all files...');\n\n try {\n this.importing = true;\n this.resetError();\n\n try {\n // Wait processing files finished\n await this.uploader.waitIdle();\n\n // upload all files\n await this.uploader.uploadFiles();\n\n const files: UploadFile<any>[] = (this.uploader.processedFiles || [])\n .filter(file => !file.deleting); // Remove deleting file (deletion in progress)\n\n // Nothing to upload: close popover\n if (isEmptyArray(files)) return this.cancel();\n\n // check errors\n const errors = files.map(file => file.error).filter(isNotNilOrBlank);\n\n // If error: stop\n if (errors.length) {\n errors.forEach((error) => console.error(error));\n throw {message: 'FILE.UPLOAD.ERROR'};\n }\n\n // return files\n await this.popoverController.dismiss(files);\n }\n catch (err) {\n this.error = (err && err.message) || err;\n }\n } finally {\n this.importing = false;\n this.cd.markForCheck();\n }\n }\n\n cancel() {\n return this.popoverController.dismiss();\n }\n\n protected resetError() {\n if (this.error) {\n this.error = null;\n this.cd.markForCheck();\n }\n }\n}\n","import {FileEvent, FileResponse, UploadFile} from '../upload-file/upload-file.model';\nimport {UploadFilePopover, UploadFilePopoverOptions} from '../upload-file/upload-file-popover.component';\n\nimport {PopoverController} from '@ionic/angular';\nimport {Observable, Subject} from 'rxjs';\nimport {HttpEventType} from '@angular/common/http';\nimport {OverlayEventDetail} from '@ionic/core';\nimport {isNilOrBlank} from '../functions';\n\nexport const MimeTypes = Object.freeze({\n ANDROID_APK: 'application/vnd.android.package-archive'\n});\n\n\nexport class FilesUtils {\n\n static UTF8_BOM_CHAR = new Uint8Array([0xEF, 0xBB, 0xBF]); // UTF-8 BOM\n\n static async showUploadPopover<T>(popoverController: PopoverController,\n event: UIEvent,\n opts: UploadFilePopoverOptions<T>): Promise<OverlayEventDetail<UploadFile<T>[]>> {\n const modal = await popoverController.create({\n component: UploadFilePopover,\n componentProps: opts,\n backdropDismiss: false,\n keyboardClose: false,\n event,\n translucent: true,\n cssClass: 'popover-large',\n });\n\n await modal.present();\n const { data, role } = await modal.onDidDismiss();\n return {\n role,\n data: data ? data as UploadFile<T>[] : undefined\n };\n }\n\n static readAsText(file: File, encoding?: string): Observable<FileEvent<string>> {\n\n const $progress = new Subject<FileEvent<string>>();\n const reader = new FileReader();\n encoding = (encoding || 'UTF-8').toLowerCase();\n\n // Listen progress\n reader.onprogress = (e: ProgressEvent) => {\n const total = e.total || 1;\n const loaded = e.total || 0;\n if (loaded < total) $progress.next({type: HttpEventType.UploadProgress, loaded, total});\n }\n\n // Listen end\n reader.onloadend = (e: ProgressEvent) => {\n const body = reader.result;\n if (typeof body === 'string') {\n $progress.next(new FileResponse({body}));\n $progress.complete();\n }\n else {\n console.error(`Cannot read file '${file.name}' as text`);\n $progress.error(`Cannot read file as text`);\n }\n }\n\n // Listen error\n reader.onerror = (event: ProgressEvent) => {\n console.error('[files] Error while reading file:', event);\n $progress.error(event);\n }\n\n // Start reading the file\n reader.readAsText(file, encoding);\n\n return $progress.asObservable();\n }\n\n static writeTextToFile(content: string,\n opts?: {\n filename?: string;\n encoding?: string;\n type?: string;\n }) {\n if (isNilOrBlank(content)) return; // Skip if empty\n\n const filename = opts?.filename || 'export.txt';\n const charset = (opts?.encoding || 'utf-8').toLowerCase();\n let type = opts?.type || 'text/plain';\n const blob = new Blob((charset === 'utf-8')\n // Add UTF-8 BOM character\n ? [FilesUtils.UTF8_BOM_CHAR, content]\n // Non UTF-8 charset\n : [content],\n { type: `${type};charset=${charset};` });\n if (navigator.msSaveBlob) { // IE 10+\n navigator.msSaveBlob(blob, filename);\n } else {\n const link = document.createElement('a');\n if (link.download !== undefined) {\n // Browsers that support HTML5 download attribute\n const url = URL.createObjectURL(blob);\n link.setAttribute('href', url);\n link.setAttribute('download', filename);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n }\n }\n\n static downloadUri(uri: string,\n filename?: string) {\n if (navigator.msLaunchUri) { // IE 10+\n navigator.msLaunchUri(uri);\n }\n else {\n filename = filename || this.getFilenameFromUri(uri);\n const link = document.createElement('a');\n if (link.download !== undefined) {\n // Browsers that support HTML5 download attribute\n link.setAttribute('href', uri);\n link.setAttribute('download', filename);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n }\n }\n\n static getFilenameFromUri(uri: string): string {\n const lastSlashIndex = uri?.lastIndexOf('/');\n if (lastSlashIndex === -1 || lastSlashIndex === uri.length - 1) throw new Error('Invalid URI format. No slash found');\n return uri.substring(lastSlashIndex + 1);\n }\n}\n\n","export class UriUtils {\n\n /**\n * Extract the filename, from an uri (using the last slash)\n * @param uri\n */\n static getFilename(uri: string): string {\n if (!uri) return uri;\n let filename = uri.trim();\n\n // Get last part (or all string, if no '/')\n const lastSlashIndex = filename.lastIndexOf('/');\n if (lastSlashIndex !== -1 && lastSlashIndex !== uri.length - 1) {\n filename = filename.substring(lastSlashIndex + 1);\n }\n\n // Remove query params\n const queryParamIndex = filename.indexOf('?');\n if (queryParamIndex !== -1) {\n filename = filename.substring(0, queryParamIndex);\n }\n\n return filename;\n }\n}\n","import {Inject, Injectable, Optional} from '@angular/core';\nimport {Platform, ToastController} from '@ionic/angular';\nimport {AuthTokenType, NetworkService} from './network.service';\nimport {Platforms} from '@ionic/core';\nimport {SplashScreen} from '@ionic-native/splash-screen/ngx';\nimport {StatusBar} from '@ionic-native/status-bar/ngx';\nimport {Keyboard} from '@ionic-native/keyboard/ngx';\nimport {LocalSettingsService} from './local-settings.service';\nimport {CacheService} from 'ionic-cache';\nimport {AudioProvider} from '../../shared/audio/audio';\nimport {Platform as CdkPlatform} from '@angular/cdk/platform';\n\nimport {InAppBrowser} from '@ionic-native/in-app-browser/ngx';\nimport {isEmptyArray, isNil, isNilOrBlank, isNotNil, isNotNilOrBlank, toBoolean} from '../../shared/functions';\nimport {Storage} from '@ionic/storage';\nimport {EntitiesStorage} from './storage/entities-storage.service';\nimport {StorageUtils} from '../../shared/services/storage.utils';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {TranslateService} from '@ngx-translate/core';\nimport * as momentImported from 'moment';\nimport {AccountService} from './account.service';\nimport {from, Observable, of, Subscription, timer} from 'rxjs';\nimport {catchError, distinctUntilChanged, filter, map, skip, tap} from 'rxjs/operators';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {ConfigService} from './config.service';\nimport {CORE_CONFIG_OPTIONS} from './config/core.config';\nimport {MomentDateAdapter} from '@angular/material-moment-adapter';\nimport {Downloader, DownloadRequest, NotificationVisibility} from '@ionic-native/downloader/ngx';\nimport {StartableService} from '../../shared/services/startable-service.class';\nimport {isMobile, isWindows} from '../../shared/platforms';\nimport {VersionUtils} from '../../shared/version/versions';\nimport {FilesUtils, MimeTypes} from '../../shared/file/file.utils';\nimport {UriUtils} from '../../shared/file/uri.utils';\n\nconst moment = momentImported;\n\nexport const AndroidOsEnvironment = Object.freeze({\n DIRECTORY_DOWNLOADS: 'Download',\n DIRECTORY_DOWNLOADS_OLD: 'Downloads', // Old name, for older Android version\n // TODO: find value for this. See https://developer.android.com/reference/android/os/Environment#getExternalStorageState(java.io.File)\n // DIRECTORY_MUSIC,\n // DIRECTORY_PODCASTS,\n // DIRECTORY_RINGTONES,\n // DIRECTORY_ALARMS,\n // DIRECTORY_NOTIFICATIONS,\n // DIRECTORY_PICTURES,\n // DIRECTORY_MOVIES,\n // DIRECTORY_DCIM,\n // DIRECTORY_DOCUMENTS,\n // DIRECTORY_AUDIOBOOKS,\n});\n\n@Injectable({providedIn: 'root'})\nexport class PlatformService extends StartableService {\n\n private _mobile: boolean;\n private _cordova: boolean;\n private _android: boolean;\n private _ios: boolean;\n private _downloadingJobs: Map<string, Observable<string>> = new Map();\n private checkAppVersionTimer: Subscription;\n\n constructor(\n private platform: Platform,\n private cdkPlatform: CdkPlatform,\n private toastController: ToastController,\n private translate: TranslateService,\n private dateAdapter: MomentDateAdapter,\n private entitiesStorage: EntitiesStorage,\n private settings: LocalSettingsService,\n private networkService: NetworkService,\n private accountService: AccountService,\n private configService: ConfigService,\n private cache: CacheService,\n private storage: Storage,\n private audioProvider: AudioProvider,\n @Inject(ENVIRONMENT) protected environment,\n @Optional() private statusBar: StatusBar,\n @Optional() private keyboard: Keyboard,\n @Optional() private splashScreen: SplashScreen,\n @Optional() private browser: InAppBrowser,\n @Optional() private downloader: Downloader\n ) {\n super(platform);\n\n this._debug = !environment.production;\n if (this._debug) console.debug('[platform] Creating service');\n }\n\n is(platformName: Platforms): boolean {\n switch (platformName) {\n case 'mobile':\n // Exclude Windows touch screens - see sumaris-app issues #323 and #346\n return isMobile(window);\n case 'mobileweb':\n // Exclude Windows touch screens - see sumaris-app issues #323 and #346\n return this.platform.is(platformName) && !isWindows(window);\n default:\n return this.platform.is(platformName);\n }\n }\n\n get mobile(): boolean {\n return isNotNil(this._mobile) ? this._mobile : this.is('mobile');\n }\n\n /**\n * Say if opened has been opened inside an Android or iOs App.\n * This is used to known if there is cordova features\n */\n isCordova(): boolean {\n return this._cordova;\n }\n\n isAndroidCordova(): boolean {\n return this._android && this._cordova || false;\n }\n\n isIOSCordova(): boolean {\n return this._ios && this._cordova || false;\n }\n\n isApp(): boolean {\n return this.isAndroidCordova() || this.isIOSCordova();\n }\n\n isWeb(): boolean {\n return !this.isApp();\n }\n\n isMobileWeb(): boolean {\n return this.mobile && this.isWeb();\n }\n\n get canDownload(): boolean {\n return this.downloader && this.isAndroidCordova();\n }\n\n get canOpenFile(): boolean {\n return false;\n }\n\n width(): number {\n return this.platform.width();\n }\n\n height(): number {\n return this.platform.height();\n }\n\n protected async ngOnStart(): Promise<any> {\n const now = Date.now();\n this.accountService.tokenType = undefined;\n console.info('[platform] Starting platform...');\n\n try {\n this._mobile = this.is('mobile');\n this._cordova = this.is('cordova');\n this._android = this.is('android');\n this._ios = this.is('ios');\n\n this.configureClassList(this._mobile);\n this.configureCordovaPlugins();\n\n // Force some settings\n this.settings.mobile = this._mobile;\n\n // Configure translation\n await this.configureTranslate();\n\n // Configure storage\n const storage = await this.storageReady();\n await this.migrateStorage(storage);\n\n // Start root services\n await Promise.all([\n this.entitiesStorage.ready(),\n this.cache.ready().then(() => this.configureCache()),\n this.settings.ready(),\n this.networkService.ready(),\n this.audioProvider.ready()\n ]);\n\n // Check if web app has update, and reload page if need\n if (this.isWeb() && this.environment.production) {\n await this.checkAppVersion({canReload: true});\n }\n\n // Update cache configuration when network changed\n this.networkService.onNetworkStatusChanges\n .pipe(\n skip(1) // Olready done once, so we skip the first event\n )\n .subscribe(type => this.configureCache(type !== 'none'));\n\n console.info(`[platform] Starting platform [OK] {mobile: ${this._mobile}, web: ${this.isWeb()}, downloader: ${this.canDownload}, fileOpener: ${this.canOpenFile}} in ${Date.now() - now}ms`);\n\n // Update authentication type\n this.configService.config\n .pipe(\n map(config => config?.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE) as AuthTokenType),\n filter(isNotNilOrBlank),\n distinctUntilChanged()\n )\n .subscribe(tokenType => {\n console.info(`[platform] Using auth token type {${tokenType}}`);\n this.accountService.tokenType = tokenType;\n });\n\n // Hide the splashscreen (if mobile) - after 1s - and play start sound\n if (this._mobile) {\n setTimeout(() => {\n this.splashScreen?.hide();\n\n // Play startup sound\n this.audioProvider.playStartupSound();\n }, 1000);\n }\n\n // Check if new version, every 1 min\n const checkIntervalMs = (this.environment.checkAppVersionIntervalInSeconds || 0) * 1000;\n if (this.isWeb() && this.environment.production && checkIntervalMs > 0) {\n this.checkAppVersionTimer?.unsubscribe();\n this.checkAppVersionTimer = timer(checkIntervalMs, checkIntervalMs)\n .subscribe(_ => this.checkAppVersion({silent: true, canReload: false /*do NOT auto reload, when app is started*/}));\n this.registerSubscription(this.checkAppVersionTimer);\n }\n }\n catch (err) {\n // Manage startup error\n return this.onStartupError(err);\n }\n }\n\n open(url: string, target?: string, features?: string, replace?: boolean) {\n console.info(`[platform] Opening link: ${url}`);\n if (this.browser && this._mobile) {\n this.browser.create(url, target, features).show();\n }\n else {\n window.open(url, target, features, replace);\n }\n }\n\n getDownloadingJob(uri: string): Observable<string> {\n return this._downloadingJobs.get(uri);\n }\n\n download(request: {uri: string; filename?: string } & Partial<DownloadRequest>): Observable<string> {\n if (!request || !request.uri) throw new Error('Missing argument \\'request\\' or \\'request.uri\\'');\n\n if (this._android && this.downloader) {\n\n // Check if not already downloading file\n let job$ = this._downloadingJobs.get(request.uri);\n if (job$) return job$;\n\n // Compute subPath (final filename)\n let subPath = request.destinationInExternalPublicDir?.subPath\n || request.destinationInExternalFilesDir?.subPath\n || request.filename || UriUtils.getFilename(request.uri)\n || request.title || 'download';\n\n subPath = subPath.toLowerCase()\n // Remove spaces\n .replace(/\\s+/g, '-');\n\n // Force APK to finish with '.apk'\n if (request.mimeType === MimeTypes.ANDROID_APK && !subPath.toLowerCase().endsWith('.apk')) {\n subPath += '.apk';\n }\n\n const downloadRequest = <DownloadRequest>{\n visibleInDownloadsUi: true,\n notificationVisibility: NotificationVisibility.VisibleNotifyCompleted,\n ...request,\n filename: undefined, // Force unset\n destinationInExternalPublicDir: !request.destinationInExternalFilesDir\n ? {\n dirType: AndroidOsEnvironment.DIRECTORY_DOWNLOADS,\n ...request.destinationInExternalPublicDir,\n subPath\n }\n : undefined,\n destinationInExternalFilesDir: request.destinationInExternalFilesDir\n ? {\n dirType: AndroidOsEnvironment.DIRECTORY_DOWNLOADS,\n ...request.destinationInExternalFilesDir,\n subPath\n }\n : undefined\n };\n\n // Start download\n console.debug('[platform] Downloading, using request: ' + JSON.stringify(downloadRequest));\n job$ = from(this.downloader.download(downloadRequest));\n\n // Remember this request uri\n this._downloadingJobs.set(downloadRequest.uri, job$);\n return job$\n .pipe(\n tap(location => {\n console.info('[platform] File successfully downloaded at:' + location);\n // Forget job\n this._downloadingJobs.delete(downloadRequest.uri);\n return location;\n }),\n catchError(err => {\n console.error('[platform] Unable to download: ' + (err && err.message || err));\n // Forget the request\n this._downloadingJobs.delete(downloadRequest.uri);\n\n // Retry with another location - issue in older Android version\n if (downloadRequest.destinationInExternalPublicDir?.dirType === AndroidOsEnvironment.DIRECTORY_DOWNLOADS) {\n downloadRequest.destinationInExternalPublicDir.dirType = AndroidOsEnvironment.DIRECTORY_DOWNLOADS_OLD;\n return this.download(downloadRequest);\n }\n throw err;\n })\n );\n }\n\n // Fallback (if not Android and Cordova): opening the URI\n // TODO: find a way to download under iOS (see https://www.c-sharpcorner.com/article/how-to-download-a-file-using-file-transfer-plugin-in-ionic-3/)\n else {\n FilesUtils.downloadUri(request.uri, request.filename);\n //this.open(request.uri, '_system', 'location=no', true);\n return of();\n }\n }\n\n openFile(filePath: string, fileMimeType: string): Promise<any> {\n console.debug(`[platform] Opening file: ${filePath} (${fileMimeType}) ...`);\n\n //if (this.fileOpener) {\n // return this.fileOpener.open(filePath, fileMimeType);\n // }\n //else {\n console.warn('[platform] Cannot use Cordova FileOpener plugin: using browser open()');\n this.open(filePath, '_system', 'location=no', true);\n return Promise.resolve();\n //}\n }\n\n /* -- protected methods -- */\n\n protected configureClassList(mobile: boolean, win: any = window) {\n if (mobile) return; // Nothing to do\n\n // Workaround, for MS Windows touch screen (detected as mobile, but forced as desktop)\n if (!mobile && (win.document.documentElement?.classList.contains('plt-mobile')\n || win.document.documentElement.classList?.contains('plt-mobileweb'))) {\n console.warn('[platform] Force class list to: <html class=\"plt-desktop\">. Workaround for Windows touch screen.');\n win.document.documentElement.classList.remove('plt-mobile','plt-mobileweb');\n win.document.documentElement.classList.add('plt-desktop');\n }\n\n }\n\n protected configureCordovaPlugins() {\n console.info('[platform] Configuring Cordova plugins...');\n\n if (this.statusBar) {\n this.statusBar.styleDefault();\n this.statusBar.overlaysWebView(false);\n }\n if (this.keyboard) {\n this.keyboard.hideFormAccessoryBar(true);\n }\n }\n\n\n protected configureTranslate() {\n console.info('[platform] Configuring i18n ...');\n\n // this language will be used as a fallback when a translation isn't found in the current language\n this.translate.setDefaultLang(this.environment.defaultLocale);\n\n // When locale changes, apply to date adapter\n this.translate.onLangChange.subscribe(event => {\n if (event && event.lang) {\n\n // force 'en' as 'en_GB'\n if (event.lang === 'en') {\n event.lang = 'en_GB';\n }\n\n // config moment lib\n try {\n moment.locale(event.lang);\n console.debug('[platform] Use locale {' + event.lang + '}');\n }\n // If error, fallback to en\n catch (err) {\n moment.locale('en');\n console.warn('[platform] Unknown local for moment lib. Using default [en]');\n }\n\n // Config date adapter\n this.dateAdapter.setLocale(moment.locale());\n }\n });\n\n this.settings.onChange.subscribe(data => {\n if (data && data.locale && data.locale !== this.translate.currentLang) {\n this.translate.use(data.locale);\n }\n });\n\n // Use account's settings, (like locale), when account inheritance enabled\n this.accountService.onLogin.subscribe(account => {\n if (account.settings && this.settings.settings.accountInheritance) {\n const accountSettings = account.settings.asLocalSettings();\n this.settings.apply(accountSettings);\n }\n });\n }\n\n protected configureCache(online?: boolean) {\n online = toBoolean(online, this.cache.isOnline());\n const cacheTTL = online ? 3600 /* 1h */ : 3600 * 24 * 30; /* 1 month */\n console.info(`[platform] Configuring cache [OK] {online: ${online}, timeToLive: ${cacheTTL / 3600}h, offlineInvalidate: false}`);\n this.cache.setDefaultTTL(cacheTTL);\n this.cache.setOfflineInvalidate(false); // Do not invalidate cache when offline\n }\n\n protected async checkAppVersion(opts?: {canReload?: boolean; silent?: boolean}) {\n if (this.networkService.offline || !this.isWeb()) return; // Skip\n\n const silent = opts?.silent === true;\n const production = this.environment.production;\n const canAutoReload = !opts || opts.canReload !== false;\n\n if (!silent) console.info('[platform] Checking remote app version...');\n\n const actualVersion = this.environment.version;\n if (isNilOrBlank(actualVersion)) {\n console.error('[platform] Missing required value for \\'environment.version\\'. Cannot check remote app version.');\n this.checkAppVersionTimer?.unsubscribe(); // Stop timer if exists\n return; // Skip\n }\n\n const remoteVersion = await this.networkService.getAppVersion();\n if (isNilOrBlank(remoteVersion)) {\n if (production && !silent) console.error('[platform] Cannot load remote app version. Skipping version check');\n this.checkAppVersionTimer?.unsubscribe(); // Stop timer if exists\n return;\n }\n\n if (VersionUtils.isCompatible(remoteVersion, actualVersion)) {\n if (!silent) console.info(`[platform] Checking remote app version [OK] {remote: '${remoteVersion}', actual: '${actualVersion}'}`);\n return;\n }\n\n // If newer version exists\n let reloadPath = location.href.replace(/[&]?version=[0-9.]+/gi, ''); // Remove old version in query params\n reloadPath += (reloadPath.indexOf('?') === -1) ? '?' : '&'; // Add query param separator\n reloadPath += 'version=' + remoteVersion; // Add version (to avoid a reload infinite loop)\n\n // Already try to reload, but version still bad\n if (reloadPath === location.href) {\n if (canAutoReload) console.error(`[platform] Reloaded page failed, because version still mismatch! Please check version.appup file (expected app version: ${actualVersion})`);\n // Stop timer, to avoid infinite loop\n this.checkAppVersionTimer?.unsubscribe();\n return;\n }\n\n console.warn(`[platform] More recent version detected (remote: ${remoteVersion}, actual: ${actualVersion}`);\n\n // Auto reload\n if (canAutoReload) {\n console.info('[platform] Will reloading at ' + reloadPath);\n location.href = reloadPath;\n // App stop\n }\n // Ask user to reload\n else {\n await this.showToast({\n message: 'CONFIRM.RELOAD_APP',\n messageParams: {version: remoteVersion, name: this.environment.name},\n type: 'info', duration: -1,\n buttons: [\n // Reload button\n {text: this.translate.instant('COMMON.BTN_RELOAD'),\n side: 'end',\n handler: () => {\n location.href = reloadPath;\n return true;\n }\n }\n ]});\n }\n }\n\n protected async storageReady(): Promise<LocalForage> {\n console.info(`[platform] Starting storage...`);\n const forage = await this.storage.ready();\n const driver = forage.driver();\n\n if (isNil(driver)) {\n console.error('[platform] NO DRIVER DEFINED IN STORAGE. Local storage cannot be used !');\n return Promise.resolve(forage);\n }\n\n console.info(`[platform] Starting storage [OK] {name: '${forage.config().name}', driver: '${forage.driver()}', size: ${forage.config().size}`);\n console.debug(`[platform] Storage supports: {${forage.WEBSQL}: ${forage.supports(forage.WEBSQL)}, ${forage.INDEXEDDB}: ${forage.supports(forage.INDEXEDDB)}, ${forage.LOCALSTORAGE}: ${forage.supports(forage.LOCALSTORAGE)}}`);\n\n return forage;\n }\n\n protected async migrateStorage(storage: LocalForage) {\n const canMigrate = storage &&\n ((storage.driver() === 'cordovaSQLiteDriver' && (storage.supports(storage.INDEXEDDB) || storage.supports(storage.WEBSQL))) ||\n (storage.driver() === storage.WEBSQL && storage.supports(storage.INDEXEDDB)));\n\n if (!canMigrate) return; // Skip\n\n const oldForage = storage.createInstance({\n name: storage.config().name,\n storeName: storage.config().storeName,\n driver: [storage.INDEXEDDB, storage.WEBSQL]\n });\n\n const keys = await oldForage.keys();\n\n // No data in the odl storage: skip migration\n if (isEmptyArray(keys)) {\n // Drop the old instance (not need anymore)\n console.debug(`[platform] Old storage is empty: dropping unused instance {name: '${storage.config().name}', driver: '${oldForage.driver()}'}`);\n await oldForage.dropInstance();\n }\n // IF some data stored in the OLD storage: start migration\n else {\n\n const now = Date.now();\n console.info(`[platform] Starting storage migration...`);\n\n const toast = await this.showToast({message: 'INFO.DATA_MIGRATION_STARTED', type: 'info', duration: 30000});\n try {\n await StorageUtils.copy(oldForage, storage, {keys, deleteAfterCopy: false});\n\n const duration = Date.now() - now;\n setTimeout(() => toast.dismiss(), Math.max(2000 - duration, 0));\n await this.showToast({message: 'INFO.DATA_MIGRATION_SUCCEED',\n type: 'info',\n showCloseButton: true\n });\n console.info('[platform] Starting storage migration [OK]');\n\n // Drop the old instance\n console.info(`[platform] Drop old storage {name: '${storage.config().name}', driver: '${oldForage.driver()}'}`);\n await oldForage.dropInstance();\n }\n catch (err) {\n console.error(err && err.message || err, err);\n await toast.dismiss();\n await this.showToast({message: 'ERROR.DATA_MIGRATION_FAILED',\n type: 'error',\n showCloseButton: true\n });\n }\n }\n }\n\n protected showToast(opts: ShowToastOptions): Promise<HTMLIonToastElement> {\n if (!this.toastController) throw new Error('Missing toastController in component\\'s constructor');\n return new Promise(resolve => Toasts.show(this.toastController, this.translate, {\n ...opts,\n onWillPresent: (t) => resolve(t)\n }));\n }\n\n protected async onStartupError(err) {\n console.error('[platform] Failed starting the platform! ', err);\n let message = err && err.message || err;\n const detailsMessage = err && (err.details && err.details.message || err.details);\n // Set specific error when Firefox is in private mode or history never remembered (see Mantis Ifremer #56441)\n if (err.code === 11 && this.cdkPlatform.FIREFOX) {\n message = 'ERROR.FIREFOX_NO_STORAGE';\n }\n if (this.translate) {\n message = await this.translate.get(message).toPromise();\n if (err && err.code) {\n message += ` {code: ${err.code}}`;\n }\n }\n else {\n message = `Fatal error: Please contact your administrator.\\n\\n{code: ${err && err.code || 'null'}, message: \"${message}\"}`;\n }\n if (this.toastController) {\n if (detailsMessage) {\n message += `<br/><small>${detailsMessage}</small>`;\n }\n await this.showToast({\n type: 'error',\n duration: -1,\n showCloseButton: true,\n message\n });\n }\n else if (window) {\n if (detailsMessage) {\n message += `\\n\\n{cause: \"${detailsMessage}\"}`;\n }\n window.alert(message);\n }\n else {\n console.error(message);\n if (err && err.details) console.error('cause', err.details);\n }\n }\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Injector, Input, OnInit} from '@angular/core';\nimport {ModalController} from '@ionic/angular';\nimport {PlatformService} from '../../core/services/platform.service';\nimport {LocalSettingsService} from '../../core/services/local-settings.service';\nimport {TranslateService} from '@ngx-translate/core';\n\nexport interface AppHelpModalOptions {\n title?: string,\n markdownContent?: string,\n markdownUrl?: string\n showError?: boolean;\n}\n\n@Component({\n selector: 'app-help-modal',\n templateUrl: './help.modal.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppHelpModal implements AppHelpModalOptions {\n\n readonly debug: boolean;\n loading = true;\n error: string = undefined;\n\n @Input() title: string;\n @Input() showError = true;\n @Input() markdownContent: string;\n @Input() markdownUrl: string;\n\n constructor(\n protected injector: Injector,\n protected viewCtrl: ModalController,\n protected platform: PlatformService,\n protected settings: LocalSettingsService,\n protected translate: TranslateService,\n protected cd: ChangeDetectorRef\n ) {\n // TODO: for DEV only\n //this.debug = !environment.production;\n }\n\n close(event?: UIEvent) {\n return this.viewCtrl.dismiss();\n }\n\n markAsLoaded() {\n this.loading = false;\n this.error = null;\n this.cd.markForCheck();\n }\n\n onLoadError(error?: string) {\n console.error(error);\n\n this.error = error;\n this.loading = false;\n this.cd.markForCheck();\n }\n\n\n}\n","import {MatStepperIntl} from '@angular/material/stepper';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Injectable} from '@angular/core';\n\n@Injectable({providedIn: 'root'})\nexport class MatStepperI18n extends MatStepperIntl {\n\n constructor(private translate: TranslateService) {\n super();\n translate.onLangChange.subscribe(() => this.translateLabels());\n\n this.translateLabels();\n }\n\n private translateLabels() {\n this.optionalLabel = this.translate.instant('COMMON.OPTIONAL');\n }\n}\n","import {ChangeDetectorRef, Component, ElementRef, Input, ViewChild} from '@angular/core';\nimport {catchError, debounceTime, filter, first, map, switchMap, tap} from 'rxjs/operators';\nimport {BehaviorSubject, forkJoin, Observable, of, Subject} from 'rxjs';\nimport {TranslateService} from '@ngx-translate/core';\nimport {FileDeleteFn, FileUploadFn, isProgressEvent, isResponseEvent, UploadFile} from './upload-file.model';\nimport {isNil, isNotNil} from '../functions';\nimport {waitFor, WaitForOptions} from '../observables';\n\n@Component({\n selector: 'app-upload-file',\n templateUrl: './upload-file.component.html',\n styleUrls: ['./upload-file.component.scss'],\n})\nexport class UploadFileComponent {\n\n @ViewChild('fileDropRef', { static: false }) fileDropEl: ElementRef;\n\n @Input() fileExtension: string;\n @Input() uniqueFile = false;\n @Input() instantUpload = false;\n @Input() uploadFn: FileUploadFn<any>;\n @Input() deleteFn: FileDeleteFn<any>;\n @Input() maxParallelUpload: number;\n\n files: UploadFile<any>[] = [];\n\n get processingFiles(): UploadFile<any>[] {\n return this.files.filter(f => !f.deleting && isNotNil(f.progress) && f.progress < 1)\n }\n\n get processedFiles(): UploadFile<any>[] {\n return this.files.filter(f => !f.deleting && f.progress === 1);\n }\n\n get processingFilesCount(): number {\n return this.processingFiles.length;\n }\n\n constructor(protected cd: ChangeDetectorRef, protected translate: TranslateService) {}\n\n /**\n * on file drop handler\n */\n onFileDropped(event) {\n this.prepareFilesList(event);\n }\n\n /**\n * handle file from browsing\n */\n fileBrowseHandler(files) {\n this.prepareFilesList(files);\n }\n\n /**\n * Delete file from files list\n *\n * @param index (File index)\n */\n async deleteFile(index: number) {\n const file = this.files[index];\n\n if (file.progress === 1 && this.deleteFn) {\n if (file.deleting) {\n console.warn(`[upload-file] This file already deleting`);\n return;\n }\n try {\n file.deleting = true\n const deleted = await this.deleteFn(file);\n if (!deleted) return;\n }\n catch(err) {\n console.error(err && err.message || err);\n return;\n }\n finally {\n file.deleting = false;\n }\n\n // Make sure index not changed\n index = this.files.indexOf(file);\n if (index === -1) return; // Not found (already removed ?)\n }\n else if (file.progress > 0) {\n console.warn(`[upload-file] Cannot remove this file while uploading`);\n return;\n }\n\n this.files.splice(index, 1);\n this.cd.markForCheck();\n }\n\n /**\n * Convert Files list to normal array list\n *\n * @param files (Files List)\n */\n prepareFilesList(files: FileList | File[]) {\n let items: File[];\n if (files instanceof FileList) {\n items = [];\n for (let i = 0; i < files.length; i++) {\n const item = files.item(i);\n items.push(item);\n }\n }\n else {\n items = files;\n }\n this.files.push(...items);\n\n this.fileDropEl.nativeElement.value = '';\n\n // Start upload\n if (this.instantUpload) {\n this.uploadFiles(items);\n }\n }\n\n /**\n * Execute upload\n */\n async uploadFiles(files?: File[]): Promise<UploadFile<any>[]> {\n\n if (!files) {\n console.info('[upload-file] Uploading all files...');\n files = this.files;\n }\n\n const $processingFileCountChange = new BehaviorSubject(this.processingFilesCount);\n const $changes = new Subject();\n $changes.subscribe(_ => {\n this.cd.markForCheck();\n $processingFileCountChange.next(this.processingFilesCount);\n });\n\n const jobs: Observable<UploadFile<any>>[] = files\n .map(f => f as UploadFile<any>)\n .filter(file => file && isNil(file.progress) && !file.error) // Skip if already started or in error\n .map((file, i) => {\n // Wait if need\n if (isNotNil(this.maxParallelUpload)) {\n return $processingFileCountChange.pipe(\n debounceTime(i), // call of filter() must be different for waiting job\n filter(count => count < this.maxParallelUpload),\n map(_ => {\n // Start uploading\n if (isNil(file.progress)) file.progress = 0;\n $changes.next();\n return file;\n }),\n first()\n );\n }\n // Start uploading\n if (isNil(file.progress)) file.progress = 0;\n return of(file);\n })\n\n .map(file$ => file$.pipe(\n filter(isNotNil),\n // Log\n tap(file => console.debug(`[upload-file] ${file.name}: uploading...`)),\n\n // Start uploading\n switchMap(file => this.uploadFn(file)\n .pipe(\n filter(isNotNil),\n map((event) => {\n\n // Progress event\n if (isProgressEvent(event)) {\n if (isNotNil(event.loaded) && event.loaded >= 0) {\n file.progress = Math.min(1, event.loaded / (event.total || 1));\n }\n else {\n file.progress = -1; // Indeterminate progression\n }\n }\n\n // Response event\n else if (isResponseEvent(event)) {\n file.progress = 1;\n file.response = event;\n console.debug(`[upload-file] ${file.name}: ${event.statusText || 'OK'}`, file.response);\n }\n\n // Other events: ignore\n else {\n // DEBUG\n console.debug('[upload-file] Ignoring a file event: ', event);\n }\n return file;\n }),\n catchError((err) => {\n console.error(err);\n file.error = err && (err.message || err.error?.message) || 'FILE.UPLOAD.ERROR';\n return of(file);\n }),\n tap(() => {\n $changes.next();\n this.cd.markForCheck();\n })\n )\n )\n ));\n\n // Wait jobs to finish\n return forkJoin(jobs)\n .pipe(tap(_ => $changes.complete()))\n .toPromise();\n }\n\n waitIdle(opts?: WaitForOptions): Promise<void> {\n return waitFor(() => this.processingFilesCount === 0, opts);\n }\n}\n","import {Component, Inject, InjectionToken, Optional} from '@angular/core';\nimport {ActivatedRoute, Router} from '@angular/router';\nimport {TranslateService} from '@ngx-translate/core';\n\nexport declare interface TestingPage {\n label: string;\n page?: string;\n divider?: boolean;\n}\n\nexport const APP_TESTING_PAGES = new InjectionToken<TestingPage[]>('testingPages');\n\n@Component({\n selector: 'app-tests-page',\n templateUrl: './tests.page.html'\n})\nexport class SharedTestsPage {\n\n constructor(\n protected route: ActivatedRoute,\n protected router: Router,\n protected translate: TranslateService,\n @Optional() @Inject(APP_TESTING_PAGES) public pages: TestingPage[]\n ) {\n console.info('[testing] Loaded tests pages:', pages);\n }\n\n async openPage(page): Promise<boolean> {\n return this.router.navigate([page], {\n relativeTo: this.route\n });\n }\n}\n\n","import {ModuleWithProviders, NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {SharedMaterialModule} from './material/material.module';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {TranslateModule, TranslateService} from '@ngx-translate/core';\nimport {IonicModule} from '@ionic/angular';\nimport {DateFormatPipe} from './pipes/date-format.pipe';\nimport {DateFromNowPipe} from './pipes/date-from-now.pipe';\nimport {ToolbarComponent} from './toolbar/toolbar';\nimport {TextMaskModule} from 'angular2-text-mask';\nimport {MatPaginatorIntl} from '@angular/material/paginator';\nimport {MatPaginatorI18n} from './material/paginator/material.paginator-i18n';\nimport {ProgressBarService} from './services/progress-bar.service';\nimport {HTTP_INTERCEPTORS} from '@angular/common/http';\nimport {ProgressInterceptor} from './interceptors/progess.interceptor';\nimport {ColorPickerModule} from 'ngx-color-picker';\nimport {AppFormField} from './form/field.component';\nimport {AudioProvider} from './audio/audio';\nimport {CloseScrollStrategy, FullscreenOverlayContainer, Overlay, OverlayContainer} from '@angular/cdk/overlay';\nimport {SharedHotkeysModule} from './hotkeys/shared-hotkeys.module';\nimport {FileService} from './file/file.service';\nimport {ModalToolbarComponent} from './toolbar/modal-toolbar';\nimport {DragDropModule} from '@angular/cdk/drag-drop';\nimport {MAT_AUTOCOMPLETE_DEFAULT_OPTIONS, MAT_AUTOCOMPLETE_SCROLL_STRATEGY} from '@angular/material/autocomplete';\nimport {MAT_SELECT_SCROLL_STRATEGY} from '@angular/material/select';\nimport {SharedDirectivesModule} from './directives/directives.module';\nimport {SharedPipesModule} from './pipes/pipes.module';\nimport {AppLoadingSpinner} from './form/loading-spinner';\nimport {DateDiffDurationPipe} from './pipes/date-diff-duration.pipe';\nimport {LatitudeFormatPipe, LatLongFormatPipe, LongitudeFormatPipe} from './pipes/latlong-format.pipe';\nimport {HighlightPipe} from './pipes/highlight.pipe';\nimport {NumberFormatPipe} from './pipes/number-format.pipe';\nimport {MarkdownModule} from 'ngx-markdown';\nimport {AppHelpModal} from './help/help.modal';\nimport {Environment, ENVIRONMENT} from '../../environments/environment.class';\nimport {TranslateContextService} from './services/translate-context.service';\nimport {MatStepperIntl} from '@angular/material/stepper';\nimport {MatStepperI18n} from './material/stepper/material.stepper-i18n';\nimport {UploadFileComponent} from './upload-file/upload-file.component';\nimport {UploadFilePopover} from './upload-file/upload-file-popover.component';\nimport {SharedTestsPage} from './testing/tests.page';\n\n\nexport function scrollFactory(overlay: Overlay): () => CloseScrollStrategy {\n return () => overlay.scrollStrategies.close();\n}\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n TranslateModule,\n ColorPickerModule,\n TextMaskModule,\n DragDropModule,\n MarkdownModule,\n\n // Sub modules\n SharedMaterialModule,\n SharedDirectivesModule,\n SharedPipesModule,\n SharedHotkeysModule\n ],\n declarations: [\n // Components\n ToolbarComponent,\n ModalToolbarComponent,\n AppFormField,\n AppLoadingSpinner,\n AppHelpModal,\n UploadFileComponent,\n UploadFilePopover,\n SharedTestsPage,\n ],\n exports: [\n CommonModule,\n IonicModule,\n TranslateModule,\n ReactiveFormsModule,\n ColorPickerModule,\n TextMaskModule,\n DragDropModule,\n MarkdownModule,\n\n // Sub-modules\n SharedMaterialModule,\n SharedDirectivesModule,\n SharedPipesModule,\n SharedHotkeysModule,\n\n // Components\n ToolbarComponent,\n ModalToolbarComponent,\n AppFormField,\n AppLoadingSpinner,\n AppHelpModal,\n UploadFileComponent,\n UploadFilePopover,\n SharedTestsPage\n ]\n})\nexport class SharedModule {\n\n static forRoot(environment: Environment): ModuleWithProviders<SharedModule> {\n console.debug('[shared] Creating module (root)');\n\n return {\n ngModule: SharedModule,\n providers: [\n\n { provide: ENVIRONMENT, useValue: environment },\n\n ProgressBarService,\n AudioProvider,\n FileService,\n TranslateContextService,\n\n // Export Pipes as providers\n DateFormatPipe,\n DateFromNowPipe,\n DateDiffDurationPipe,\n LatLongFormatPipe,\n LatitudeFormatPipe,\n LongitudeFormatPipe,\n HighlightPipe,\n NumberFormatPipe,\n\n { provide: OverlayContainer, useClass: FullscreenOverlayContainer },\n { provide: HTTP_INTERCEPTORS, useClass: ProgressInterceptor, multi: true, deps: [ProgressBarService] },\n { provide: MatPaginatorIntl, useClass: MatPaginatorI18n, deps: [TranslateService] },\n { provide: MatStepperIntl, useClass: MatStepperI18n, deps: [TranslateService] },\n\n // FIXME: try to force a custom overlay for autocomplete, because of there is a bug when using inside an ionic modal\n //{ provide: Overlay, useClass: Overlay},\n { provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY, useFactory: scrollFactory, deps: [Overlay] },\n { provide: MAT_AUTOCOMPLETE_DEFAULT_OPTIONS, useValue: {\n autoActiveFirstOption: true\n }\n },\n { provide: MAT_SELECT_SCROLL_STRATEGY, useFactory: scrollFactory, deps: [Overlay] }\n ]\n };\n }\n}\n","import { AlertController } from '@ionic/angular';\nimport { TranslateService } from '@ngx-translate/core';\n\nexport class Alerts {\n\n /**\n * Ask the user to save before leaving. If return undefined: user has cancelled\n *\n * @param alertCtrl\n * @param translate\n * @param event\n * @deprecated prefer ComponentDirtyGuard\n */\n static async askSaveBeforeLeave(\n alertCtrl: AlertController,\n translate: TranslateService,\n event?: UIEvent): Promise<boolean|undefined> {\n let confirm = false;\n let cancel = false;\n const translations = translate.instant(['COMMON.BTN_SAVE', 'COMMON.BTN_CANCEL', 'COMMON.BTN_ABORT_CHANGES', 'CONFIRM.SAVE', 'CONFIRM.ALERT_HEADER']);\n const alert = await alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations['CONFIRM.SAVE'],\n buttons: [\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n cssClass: 'secondary',\n handler: () => {\n cancel = true;\n }\n },\n {\n text: translations['COMMON.BTN_ABORT_CHANGES'],\n cssClass: 'secondary',\n handler: () => {\n }\n },\n {\n text: translations['COMMON.BTN_SAVE'],\n handler: () => {\n confirm = true; // update upper value\n }\n }\n ]\n });\n await alert.present();\n await alert.onDidDismiss();\n\n if (confirm) return true; // = Do save and leave\n\n if (cancel) {\n // Stop the event\n if (event) event.preventDefault();\n\n return undefined; // User cancelled\n }\n\n return false; // Leave without saving\n }\n\n /**\n * Ask the user to conform an action. If return undefined: user has cancelled\n *\n * @param alertCtrl\n * @param translate\n * @param immediate is action has an immediate effect ?\n * @param event\n * @param interpolateParams\n */\n static async askActionConfirmation(\n alertCtrl: AlertController,\n translate: TranslateService,\n immediate?: boolean,\n event?: UIEvent,\n interpolateParams?: any): Promise<boolean|undefined> {\n const messageKey = immediate === true ? 'CONFIRM.ACTION_IMMEDIATE' : 'CONFIRM.ACTION';\n return Alerts.askConfirmation(messageKey, alertCtrl, translate, event, interpolateParams);\n }\n\n\n\n /**\n * Ask the user to confirm. If return undefined: user has cancelled\n *\n * @pram messageKey i18n message key\n * @param messageKey\n * @param alertCtrl\n * @param translate\n * @param event\n * @param interpolateParams\n */\n static async askConfirmation(\n messageKey: string,\n alertCtrl: AlertController,\n translate: TranslateService,\n event?: UIEvent,\n interpolateParams?: any): Promise<boolean|undefined> {\n if (!alertCtrl || !translate) throw new Error('Missing required argument \\'alertCtrl\\' or \\'translate\\'');\n let confirm = false;\n let cancel = false;\n const translations = translate.instant(['COMMON.BTN_YES_CONTINUE', 'COMMON.BTN_CANCEL', messageKey, 'CONFIRM.ALERT_HEADER'], interpolateParams);\n const alert = await alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations[messageKey],\n buttons: [\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n cssClass: 'secondary',\n handler: () => {\n cancel = true;\n }\n },\n {\n text: translations['COMMON.BTN_YES_CONTINUE'],\n handler: () => {\n confirm = true; // update upper value\n }\n }\n ]\n });\n await alert.present();\n await alert.onDidDismiss();\n\n if (confirm) return true; // = Do save and leave\n\n if (cancel) {\n // Stop the event\n if (event) event.preventDefault();\n\n return undefined; // User cancelled\n }\n\n return false; // Leave without saving\n }\n\n\n /**\n * Ask the user to save before leaving. If return undefined: user has cancelled\n *\n * @param alertCtrl\n * @param translate\n * @param event\n * @param interpolateParams\n */\n static async askDeleteConfirmation(\n alertCtrl: AlertController,\n translate: TranslateService,\n event?: UIEvent,\n interpolateParams?: any): Promise<boolean|undefined> {\n let confirm = false;\n let cancel = false;\n const translations = translate.instant(['COMMON.BTN_YES_DELETE', 'COMMON.BTN_CANCEL', 'CONFIRM.DELETE', 'CONFIRM.ALERT_HEADER'], interpolateParams);\n const alert = await alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations['CONFIRM.DELETE'],\n buttons: [\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n cssClass: 'secondary',\n handler: () => {\n cancel = true;\n }\n },\n {\n text: translations['COMMON.BTN_YES_DELETE'],\n handler: () => {\n confirm = true; // update upper value\n }\n }\n ]\n });\n await alert.present();\n await alert.onDidDismiss();\n\n if (confirm) return true; // = Do save and leave\n\n if (cancel) {\n // Stop the event\n if (event) event.preventDefault();\n\n return undefined; // User cancelled\n }\n\n return false; // Leave without saving\n }\n\n\n static async askSaveBeforeAction(alertCtrl: AlertController,\n translate: TranslateService,\n event?: { valid: boolean },\n interpolateParams?: any): Promise<{ confirmed: boolean; save: boolean } | undefined> {\n\n let save = false;\n let confirm = false;\n let alert: HTMLIonAlertElement;\n\n // Ask user before save\n if (event && event.valid) {\n const translations = translate.instant(['COMMON.BTN_CANCEL', 'COMMON.BTN_SAVE', 'COMMON.BTN_ABORT_CHANGES',\n 'CONFIRM.SAVE_BEFORE_CONTINUE', 'CONFIRM.ALERT_HEADER'], interpolateParams);\n alert = await alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations['CONFIRM.SAVE_BEFORE_CONTINUE'],\n buttons: [\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n cssClass: 'secondary',\n handler: () => {\n }\n },\n {\n text: translations['COMMON.BTN_ABORT_CHANGES'],\n cssClass: 'secondary',\n handler: () => {\n confirm = true;\n }\n },\n {\n text: translations['COMMON.BTN_SAVE'],\n handler: () => {\n save = true;\n confirm = true;\n }\n }\n ]\n });\n } else {\n const translations = translate.instant(['COMMON.BTN_ABORT_CHANGES', 'COMMON.BTN_CANCEL', 'CONFIRM.CANCEL_CHANGES', 'CONFIRM.ALERT_HEADER'], interpolateParams);\n\n alert = await alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations['CONFIRM.CANCEL_CHANGES'],\n buttons: [\n {\n text: translations['COMMON.BTN_ABORT_CHANGES'],\n cssClass: 'secondary',\n handler: () => {\n confirm = true;\n }\n },\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n handler: () => {\n }\n }\n ]\n });\n }\n\n await alert.present();\n await alert.onDidDismiss();\n\n return {confirmed: confirm, save};\n }\n\n static async showError(\n messageKey: string,\n alertCtrl: AlertController,\n translate: TranslateService, opts?: {\n titleKey?: string;\n },\n interpolateParams?: any) {\n if (!messageKey || !alertCtrl || !translate) throw new Error('Missing a required argument (\\'messageKey\\', \\'alertCtrl\\' or \\'translate\\')');\n const titleKey = opts && opts.titleKey || 'ERROR.ALERT_HEADER';\n const translations = translate.instant(['COMMON.BTN_OK', messageKey, titleKey], interpolateParams);\n const alert = await alertCtrl.create({\n header: translations[titleKey],\n message: translations[messageKey],\n buttons: [\n {\n text: translations['COMMON.BTN_OK'],\n role: 'cancel'\n }\n ]\n });\n await alert.present();\n await alert.onDidDismiss();\n\n }\n\n\n}\n\n\n\n\n","import {Injectable} from '@angular/core';\nimport {ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree} from '@angular/router';\nimport {TranslateService} from '@ngx-translate/core';\nimport {AlertController} from '@ionic/angular';\nimport {Alerts} from '../alerts';\n\nexport interface CanLeave {\n dirty: boolean;\n valid: boolean;\n save(event?: Event, options?: any): Promise<boolean>;\n cancel(event?: Event): Promise<void>;\n}\n\n@Injectable()\nexport class ComponentDirtyGuard implements CanDeactivate<CanLeave> {\n\n private debug = false;\n\n constructor(\n protected translate: TranslateService,\n protected alertCtrl: AlertController,\n ) {\n }\n\n async canDeactivate(component: CanLeave, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot):\n Promise<boolean | UrlTree> {\n\n const dirty = component?.dirty;\n const valid = component?.valid;\n let can = {\n confirmed: !dirty,\n save: false,\n };\n\n if (this.debug) {\n console.debug(`[dirty-guard] canDeactivate component dirty: ${dirty}, valid: ${valid}`);\n }\n\n if (dirty) {\n // Ask confirmation\n can = await Alerts.askSaveBeforeAction(this.alertCtrl, this.translate, {valid});\n }\n\n if (this.debug) console.debug(`[dirty-guard] confirm: ${can.confirmed}`);\n\n if (can.confirmed) {\n if (can.save) {\n if (this.debug) console.debug(`[dirty-guard] do save`);\n const saved = await component.save();\n if (!saved) {\n if (this.debug) console.debug(`[dirty-guard] save failed, cancel deactivate`);\n return false;\n }\n } else {\n if (this.debug) console.debug(`[dirty-guard] do cancel`);\n if (dirty)\n component.cancel();\n }\n\n // Allow deactivate\n return true;\n }\n\n // Cancel deactivate\n return false;\n\n }\n\n\n}\n","import {Injectable, NgModule} from '@angular/core';\nimport {ActivatedRouteSnapshot, RouteReuseStrategy, RouterModule} from '@angular/router';\nimport {IonicRouteStrategy} from '@ionic/angular';\nimport {ComponentDirtyGuard} from './guard/component-dirty.guard';\n\n\n@Injectable()\nexport class CustomReuseStrategy extends IonicRouteStrategy {\n\n /**\n * Force to reuse the route when:\n * - path change from [/new] -> [/:id]\n * - or path change from [/new] -> [/new?id=:id]\n * @param future\n * @param curr\n */\n shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {\n const result = super.shouldReuseRoute(future, curr);\n\n // Is sam route config\n if (!result && future.routeConfig && future.routeConfig === curr.routeConfig) {\n // Read the parameter name, where id is stored\n const pathIdParam = future.routeConfig.data && future.routeConfig.data.pathIdParam || 'id';\n\n // Read the current route id\n const currId = curr.params[pathIdParam] === 'new'\n ? (curr.queryParams[pathIdParam] || curr.queryParams['id'] || 'new') // e.g. path like '/new/?id=<ID>'\n : curr.params[pathIdParam]; // e.g. path like '/<ID>'\n\n // Read the future route id\n const futureId = future.params[pathIdParam] === 'new'\n ? (future.queryParams[pathIdParam] || future.queryParams['id'] || 'new') // e.g. path like '/new/?id=<ID>'\n : future.params[pathIdParam]; // e.g. path like '/<ID>'\n\n // Reuse if same ID, but never when 'new' expected\n return futureId !== 'new' && currId !== 'new'\n && futureId === currId ;\n }\n\n return result;\n }\n}\n\n@NgModule({\n imports: [\n RouterModule\n ],\n providers: [\n { provide: RouteReuseStrategy, useClass: CustomReuseStrategy },\n { provide: ComponentDirtyGuard, useClass: ComponentDirtyGuard }\n ]\n})\nexport class SharedRoutingModule {\n\n constructor() {\n console.debug('[shared-routing] Creating module...');\n }\n}\n","import {ObjectMap, Property} from '../types';\nimport {isNotNil} from '../functions';\nimport {InjectionToken} from '@angular/core';\nimport {MatAutocompleteFieldAddOptions} from '../material/autocomplete/material.autocomplete';\n\nexport declare type DisplayFn = (obj: any) => string;\n\nexport declare type EqualsFn = (o1: any, o2: any) => boolean;\n\nexport declare type CompareFn = (o1: any, o2: any) => number;\n\nexport declare type FormFieldType = 'integer' | 'double' | 'boolean' | 'string' | 'enum' | 'color' | 'peer' | 'entity' | 'entities' | 'date' | 'dateTime';\n\nexport declare interface FormFieldDefinition<K = string, T = FormFieldType, E = any> {\n key: K;\n type: T;\n label: string;\n minValue?: number;\n maxValue?: number;\n maximumNumberDecimals?: number;\n defaultValue?: any;\n isTransient?: boolean; // Useful only for remote configuration\n values?: (string|Property)[] | InjectionToken<(string|Property)[]>;\n autocomplete?: MatAutocompleteFieldAddOptions<E>;\n disabled?: boolean;\n required?: boolean;\n extra?: {\n [key: string]: {\n disabled?: boolean;\n required: boolean;\n };\n };\n}\nexport declare type FormFieldDefinitionMap = ObjectMap<FormFieldDefinition>;\n\n\nexport abstract class FormFieldValuesHolder {\n getAsBoolean(data: ObjectMap, definition: FormFieldDefinition): boolean {\n const value = this.get(data, definition);\n return isNotNil(value) ? (value && value !== 'false') : undefined;\n }\n\n getAsInt(data: any, definition: FormFieldDefinition): number {\n const value = this.get(data, definition);\n return isNotNil(value) ? parseInt(value) : undefined;\n }\n\n getAsNumbers(data: any, definition: FormFieldDefinition): number[] {\n const value = this.get(data, definition);\n if (typeof value === 'string') return value.split(',').map(parseFloat) || undefined;\n return isNotNil(value) ? [parseFloat(value)] : undefined;\n }\n\n getAsStrings(data: any, definition: FormFieldDefinition): string[] {\n const value = this.get(data, definition);\n return value && value.split(',') || undefined;\n }\n\n get<T = string>(data: any, definition: FormFieldDefinition): T {\n return isNotNil(data[definition.key]) ? data[definition.key] : (definition.defaultValue || undefined);\n }\n}\n","import {Directive, EventEmitter, Injector, Input, OnDestroy, OnInit, Output} from '@angular/core';\nimport {FormGroup} from '@angular/forms';\nimport {BehaviorSubject, Subject, Subscription} from 'rxjs';\nimport {AppFormUtils, IAppForm, OnReady} from './form.utils';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {MatAutocompleteConfigHolder, MatAutocompleteFieldAddOptions, MatAutocompleteFieldConfig} from '../../shared/material/autocomplete/material.autocomplete';\nimport {firstFalsePromise, waitForFalse, WaitForOptions, waitForTrue} from '../../shared/observables';\nimport {FormErrorTranslator, FormErrorTranslatorOptions, IFormControlPathTranslator} from '../../shared/validator/form-error-adapter.class';\nimport {changeCaseToUnderscore} from '../../shared/functions';\nimport {TranslateService} from '@ngx-translate/core';\n\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppForm<T> implements IAppForm, OnInit, OnDestroy, IFormControlPathTranslator {\n\n private _subscription = new Subscription();\n private _form: FormGroup;\n\n protected _enable = false;\n protected errorTranslator: FormErrorTranslator;\n protected i18nFieldPrefix: string = null;\n protected readonly translate: TranslateService;\n protected readonly settings: LocalSettingsService;\n protected readonly destroySubject = new Subject();\n\n readonly autocompleteHelper: MatAutocompleteConfigHolder;\n readonly autocompleteFields: {[key: string]: MatAutocompleteFieldConfig};\n readonly readySubject = new BehaviorSubject<boolean>(false);\n readonly loadingSubject = new BehaviorSubject<boolean>(true);\n readonly errorSubject = new BehaviorSubject<string>(undefined);\n\n /**\n * @deprecated\n */\n protected set _loading(value: boolean) {\n this.loadingSubject.next(value);\n }\n\n /**\n * @deprecated\n */\n protected get _loading(): boolean {\n return this.loadingSubject.value;\n }\n /**\n * @deprecated\n */\n protected get _$ready(): BehaviorSubject<boolean> {\n return this.readySubject;\n }\n /**\n * @deprecated\n */\n protected get _$loading(): BehaviorSubject<boolean> {\n return this.loadingSubject;\n }\n\n get error(): string {\n return this.errorSubject.value;\n }\n\n set error(error: string) {\n this.setError(error);\n }\n\n get loading(): boolean {\n return this.loadingSubject.value;\n }\n\n get loaded(): boolean {\n return !this.loadingSubject.value;\n }\n\n get value(): any {\n return this.form.value;\n }\n\n set value(data: any) {\n this.setValue(data);\n }\n\n get dirty(): boolean {\n return this.form?.dirty || false;\n }\n\n get invalid(): boolean {\n return !this.form || this.form.invalid;\n }\n\n get pending(): boolean {\n return !this.form || (this.form.dirty && this.form.pending);\n }\n\n get valid(): boolean {\n return this.form?.valid || false;\n }\n\n get empty(): boolean {\n return !this.form || (!this.form.dirty && !this.form.touched);\n }\n\n get touched(): boolean {\n return this.form?.touched || false;\n }\n\n get untouched(): boolean {\n return !this.form || this.form.untouched;\n }\n\n get enabled(): boolean {\n return this._enable;\n }\n\n get disabled(): boolean {\n return !this._enable;\n }\n\n disable(opts?: {\n onlySelf?: boolean;\n emitEvent?: boolean;\n }): void {\n this.form?.disable(opts);\n if (this._enable) {\n this._enable = false;\n if (!opts || opts.emitEvent !== true) this.markForCheck();\n }\n }\n\n enable(opts?: {\n onlySelf?: boolean;\n emitEvent?: boolean;\n }): void {\n this.form?.enable(opts);\n if (!this._enable) {\n this._enable = true;\n if (!opts || opts.emitEvent !== true) this.markForCheck();\n }\n }\n\n @Input() debug = false;\n @Input() tabindex: number;\n @Input() errorTranslatorOptions: FormErrorTranslatorOptions;\n\n @Input()\n set form(value: FormGroup) {\n this.setForm(value);\n }\n\n get form(): FormGroup {\n return this._form;\n }\n\n @Output() onCancel = new EventEmitter<any>();\n @Output() onSubmit = new EventEmitter<any>();\n\n protected constructor(\n injector: Injector,\n form?: FormGroup\n ) {\n if (form) this.setForm(form);\n this.translate = injector.get(TranslateService);\n this.settings = injector.get(LocalSettingsService);\n this.errorTranslator = injector.get(FormErrorTranslator);\n this.autocompleteHelper = new MatAutocompleteConfigHolder(this.settings && {\n getUserAttributes: (a, b) => this.settings.getFieldDisplayAttributes(a, b)\n });\n this.autocompleteFields = this.autocompleteHelper.fields;\n }\n\n ngOnInit() {\n this._enable ? this.enable() : this.disable();\n this.errorTranslatorOptions = this.errorTranslatorOptions || {\n controlPathTranslator: this\n };\n\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n\n this.readySubject.unsubscribe();\n this.loadingSubject.unsubscribe();\n this.errorSubject.unsubscribe();\n this.onCancel.unsubscribe();\n this.onSubmit.unsubscribe();\n\n this.destroySubject.next();\n this.destroySubject.unsubscribe();\n }\n\n async cancel() {\n this.onCancel.emit();\n }\n\n /**\n *\n * @param event\n * @param opts allow to skip validation check, using {checkValid: false}\n */\n async doSubmit(event: any, opts?: {checkValid?: boolean;}) {\n if (!this._form) {\n this.markAllAsTouched({emitEvent: true});\n return;\n }\n\n // Check if valid (if not disabled)\n if ((!opts || opts.checkValid !== false) && !this._form.valid) {\n\n // Wait validation end\n await AppFormUtils.waitWhilePending(this._form);\n\n // Form is invalid: exit (+ log if debug)\n if (this._form.invalid) {\n this.markAllAsTouched({emitEvent: true});\n if (this.debug) AppFormUtils.logFormErrors(this._form);\n return;\n }\n }\n\n // Emit event\n this.onSubmit.emit(event);\n }\n\n setForm(form: FormGroup) {\n if (this._form !== form) {\n this._form = form;\n this._subscription.add(\n this._form.statusChanges.subscribe(status => this.markForCheck()));\n }\n }\n\n setValue(data: T, opts?: {emitEvent?: boolean; onlySelf?: boolean }): Promise<void> | void {\n if (!data) {\n console.warn('[form] Trying to set an empty value to form. Skipping');\n return;\n }\n\n // DEBUG\n //if (this.debug) console.debug('[form] Updating form (using entity)', data);\n\n // Convert object to json, then apply it to form (e.g. convert 'undefined' into 'null')\n AppFormUtils.copyEntity2Form(data, this.form, {emitEvent: false, onlySelf: true, ...opts});\n\n if (!opts || opts.emitEvent !== true) {\n this.markForCheck();\n }\n }\n\n reset(data?: T, opts?: {emitEvent?: boolean; onlySelf?: boolean }) {\n if (data) {\n if (this.debug) console.debug('[form] Resetting form (using entity)', data);\n\n // Convert object to json, then apply it to form (e.g. convert 'undefined' into 'null')\n const json = AppFormUtils.getFormValueFromEntity(data, this.form);\n this.form.reset(json, {emitEvent: false, onlySelf: true});\n }\n else {\n this.form.reset(null, {emitEvent: false, onlySelf: true});\n }\n\n if (!opts || opts.emitEvent !== true) this.markForCheck();\n }\n\n markAsPristine(opts?: {onlySelf?: boolean; emitEvent?: boolean;}) {\n this.form.markAsPristine(opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n markAsUntouched(opts?: {onlySelf?: boolean; emitEvent?: boolean;}) {\n this.form.markAsUntouched(opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n /**\n * @deprecated prefer to use markAllAsTouched()\n * @param opts\n */\n markAsTouched(opts?: {onlySelf?: boolean; emitEvent?: boolean;}) {\n // this.form.markAllAsTouched() // This is not working well (e.g. in TripForm)\n console.warn('TODO: Replace this call by markAllAsTouched() - because of changes in ngx-components >= 0.16.0');\n AppFormUtils.markAsTouched(this.form, opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n markAllAsTouched(opts?: { emitEvent?: boolean }) {\n // this.form.markAllAsTouched() // This is not working well (e.g. in TripForm)\n AppFormUtils.markAllAsTouched(this.form, opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n markAsDirty(opts?: {onlySelf?: boolean; emitEvent?: boolean;}) {\n this.form.markAsDirty(opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n markAsLoading(opts?: {emitEvent?: boolean}) {\n this.setLoading(true, opts);\n }\n\n markAsLoaded(opts?: {emitEvent?: boolean}) {\n this.setLoading(false, opts);\n }\n\n markAsReady(opts?: {onlySelf?: boolean; emitEvent?: boolean;}) {\n if (this.readySubject.value !== true) {\n this.readySubject.next(true);\n\n // If subclasses implements OnReady\n if (typeof this['ngOnReady'] === 'function') {\n (this as any as OnReady).ngOnReady();\n }\n }\n }\n\n /**\n * Wait form is ready\n * @param opts\n */\n ready(opts?: WaitForOptions): Promise<void> {\n if (this.readySubject.value) return Promise.resolve();\n return waitForTrue(this.readySubject, opts);\n }\n\n /**\n * Wait form is not busy (=loaded)\n * @param opts\n */\n waitIdle(opts?: WaitForOptions): Promise<void> {\n if (!this.loadingSubject.value) return Promise.resolve();\n return waitForFalse(this.loadingSubject, opts);\n }\n\n updateValueAndValidity(opts?: {\n onlySelf?: boolean;\n emitEvent?: boolean;\n }) {\n AppFormUtils.updateValueAndValidity(this.form, opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n translateControlPath(path: string) {\n const i18nFieldName = this.getI18nFieldName(path);\n return this.translate?.instant(i18nFieldName) || i18nFieldName;\n }\n\n /* -- protected methods -- */\n\n protected getFormError(form: FormGroup, opts?: FormErrorTranslatorOptions): string {\n if (!form || !this.errorTranslator) return undefined;\n return this.errorTranslator.translateFormErrors(this.form, {\n controlPathTranslator: this,\n ...opts\n });\n }\n\n protected getI18nFieldName(path: string) {\n return (this.i18nFieldPrefix || '') + changeCaseToUnderscore(path).toUpperCase();\n }\n\n protected registerSubscription(sub: Subscription): Subscription {\n return this._subscription.add(sub);\n }\n\n protected unregisterSubscription(sub: Subscription): void {\n this._subscription.remove(sub);\n }\n\n protected registerAutocompleteField<E = any, EF = any>(fieldName: string,\n opts?: MatAutocompleteFieldAddOptions<E, EF>): MatAutocompleteFieldConfig<E, EF> {\n return this.autocompleteHelper.add(fieldName, opts);\n }\n\n protected setError(value: string, opts?: {emitEvent?: boolean;}) {\n if (this.errorSubject.value !== value) {\n this.errorSubject.next(value);\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n protected markForCheck() {\n // Should be overwritten by subclasses\n console.warn('markForCheck() has been called, but is not overwritten by component ' + this.constructor.name);\n }\n\n /* -- private function -- */\n\n private setLoading(value: boolean, opts?: {emitEvent?: boolean}) {\n if (this.loadingSubject.value !== value) {\n this.loadingSubject.next(value);\n\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n}\n","import {ChangeDetectorRef, Component, ElementRef, EventEmitter, Injector, Input, OnInit, Output, ViewChild} from '@angular/core';\nimport {FormBuilder, FormControl, Validators} from '@angular/forms';\nimport {CdkTextareaAutosize} from '@angular/cdk/text-field';\nimport {AppForm} from '../form/form.class';\nimport {isNotNil} from '../../shared/functions';\nimport {focusInput} from '../../shared/inputs';\n\n@Component({\n selector: 'app-text-form',\n templateUrl: './text-form.component.html',\n styleUrls: ['./text-form.component.scss'],\n})\nexport class TextForm extends AppForm<{text: string}> implements OnInit {\n @Input() showError = true;\n @Input() placeholder: string;\n @Input() multiline = true;\n @Input() autoHeight = false;\n @Input() maxLength = 2000;\n @Input() autofocus = false;\n\n @Output() textAreaChanges = new EventEmitter<string>();\n\n\n @ViewChild('textArea') textArea: ElementRef;\n @ViewChild('textInput') textInput: ElementRef;\n @ViewChild(CdkTextareaAutosize) autosizeDirective: CdkTextareaAutosize;\n\n control: FormControl;\n\n constructor(protected injector: Injector, protected cd: ChangeDetectorRef, protected formBuilder: FormBuilder) {\n super(injector);\n }\n\n ngOnInit() {\n const form = this.formBuilder.group({\n text: [null, isNotNil(this.maxLength)\n ? Validators.maxLength(this.maxLength)\n : undefined\n ]\n });\n this.control = form.get('text') as FormControl;\n this.setForm(form);\n\n super.ngOnInit()\n }\n\n textAreaChanged(event: KeyboardEvent) {\n this.textAreaChanges.emit(this.control.value);\n }\n\n containerResize() {\n this.autosizeDirective?.resizeToFitContent(true);\n }\n\n focusInput() {\n if (this.textArea) focusInput(this.textArea);\n if (this.textInput) focusInput(this.textInput);\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n","import {AfterViewInit, Component, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';\nimport {PopoverController} from '@ionic/angular';\nimport {Subscription} from 'rxjs';\nimport {TranslateService} from '@ngx-translate/core';\nimport {TextForm} from './text-form.component';\nimport {logFormErrors, waitWhilePending} from '../../shared/forms';\n\nexport interface TextPopoverOptions {\n text?: string;\n placeholder?: string;\n editing?: boolean;\n multiline?: boolean;\n maxLength?: number;\n autofocus?: boolean;\n}\n\n@Component({\n selector: 'app-text-popover',\n templateUrl: './text-popover.component.html',\n})\nexport class TextPopover implements OnInit, AfterViewInit, OnDestroy, TextPopoverOptions {\n\n @ViewChild('form', { static: true }) form: TextForm;\n\n @Input() text: string;\n @Input() placeholder = '';\n @Input() editing = true;\n @Input() multiline = true;\n @Input() maxLength = 2000;\n @Input() autofocus = false;\n\n subscription = new Subscription();\n\n get disabled() {\n return this.form.disabled;\n }\n\n get enabled() {\n return this.form.enabled;\n }\n\n get valid() {\n return this.form?.valid || false;\n }\n\n get value() {\n return this.form?.value.text;\n }\n\n constructor(protected popoverController: PopoverController, protected translate: TranslateService) {}\n\n ngOnInit(): void {\n this.enable();\n }\n\n ngAfterViewInit() {\n setTimeout(() => this.form.setValue({ text: this.text }), 0);\n }\n\n async onValidate(event: any): Promise<any> {\n await waitWhilePending(this.form);\n\n if (!this.valid) {\n logFormErrors(this.form.control);\n return;\n }\n\n try {\n const value = this.value;\n this.disable();\n await this.popoverController.dismiss(value);\n this.form.error = null;\n } catch (err) {\n this.form.error = (err && err.message) || err;\n this.enable();\n }\n }\n\n disable() {\n this.form.disable();\n }\n\n enable() {\n if (this.editing) this.form.enable();\n }\n\n cancel() {\n this.popoverController.dismiss();\n }\n\n ngOnDestroy(): void {\n this.subscription.unsubscribe();\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Directive, ElementRef, Inject, Output } from '@angular/core';\nimport { bufferWhen, distinctUntilChanged, filter, map, switchMap, takeUntil, tap } from 'rxjs/operators';\nimport {fromEvent, interval, Observable} from 'rxjs';\n\n@Directive({\n selector: '[resizable]',\n})\nexport class ResizableDirective {\n\n @Output()\n readonly resizable: Observable<number>;\n\n // fit: doubleclick\n @Output()\n readonly fit: Observable<MouseEvent[]>\n\n constructor(@Inject(DOCUMENT) private readonly document: any,\n @Inject(ElementRef) private readonly elementRef: ElementRef<HTMLElement>) {\n\n // resize: mousedown -> mousemove -> mouseup\n this.resizable = fromEvent<MouseEvent>(this.elementRef.nativeElement, 'mousedown').pipe(\n tap((e) => {\n e.preventDefault();\n e.stopPropagation();\n }),\n switchMap(() => {\n const { width, right } = this.elementRef.nativeElement.closest('th').getBoundingClientRect();\n return fromEvent<MouseEvent>(this.document, 'mousemove').pipe(\n map(({ clientX }) => width + clientX - right),\n distinctUntilChanged(),\n takeUntil(fromEvent(this.document, 'mouseup'))\n );\n })\n );\n\n // fit: doubleclick\n this.fit = fromEvent<MouseEvent>(this.elementRef.nativeElement, 'click').pipe(\n bufferWhen(() => interval(500)),\n filter((ar) => ar.length === 2)\n );\n }\n}\n","import { Component, EventEmitter, HostBinding, Input, Optional, Output } from '@angular/core';\nimport { MatColumnDef } from '@angular/material/table';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'th[resizable]',\n templateUrl: './resizable.template.html',\n styleUrls: ['./resizable.style.scss'],\n})\nexport class ResizableComponent {\n @Input() resizable: boolean;\n @Output() sizeChanged = new EventEmitter<number>();\n\n @HostBinding('style.width')\n width: string | null = null;\n\n @HostBinding('style.min-width')\n minWidth: string | null = null;\n\n @HostBinding('style.max-width')\n maxWidth: string | null = null;\n\n private debug = false;\n\n constructor(@Optional() public readonly columnDef: MatColumnDef) {}\n\n onResize(width: number, opts?: { emitEvent: boolean }) {\n if (!this.resizable) return;\n if (this.debug) console.info(`resize:${width}`);\n this.minWidth = width + 'px';\n this.maxWidth = width + 'px';\n if (!opts || opts.emitEvent) {\n this.sizeChanged.emit(width);\n }\n }\n\n onFit(opts?: { emitEvent: boolean }) {\n if (!this.resizable) return;\n if (this.debug) console.info('fit');\n this.width = 'auto';\n this.minWidth = null;\n this.maxWidth = null;\n if (!opts || opts.emitEvent) {\n this.sizeChanged.emit(undefined);\n }\n }\n}\n","import { NgModule } from '@angular/core';\nimport { ResizableComponent } from './resizable.component';\nimport { ResizableDirective } from './resizable.directive';\n\n@NgModule({\n declarations: [ResizableComponent, ResizableDirective],\n exports: [ResizableComponent, ResizableDirective],\n})\nexport class ResizableModule {}\n","import {isEmptyArray, isNil} from '../../../shared/functions';\nimport {MINIFY_ENTITY_FOR_POD, ReferentialUtils} from './referential.model';\nimport {Entity, EntityAsObjectOptions, IEntity, isInstanceOf} from './entity.model';\nimport {FilterFn} from '../../../shared/services/entity-service.class';\nimport {StoreObject} from '@apollo/client/core';\n\n\n\nexport interface IEntityFilter<F extends IEntityFilter<F, T, ID, AO, FO>,\n T extends IEntity<T, any>,\n ID = number,\n AO extends EntityAsObjectOptions = EntityAsObjectOptions,\n FO = any> extends IEntity<F, ID, AO, FO> {\n\n asPodObject(): any;\n\n asFilterFn(): FilterFn<T>;\n\n isEmpty(): boolean;\n\n countNotEmptyCriteria(): number;\n}\n\nexport abstract class EntityFilter<F extends EntityFilter<F, T, ID, AO, FO>,\n T extends IEntity<T, any>,\n ID = number,\n AO extends EntityAsObjectOptions = EntityAsObjectOptions,\n FO = any>\n extends Entity<F, ID, AO, FO>\n implements IEntityFilter<F, T, ID, AO, FO> {\n\n constructor(__typename?: string) {\n super(__typename);\n }\n\n /**\n * Clean a filter, before sending to the pod (e.g convert dates, remove internal properties, etc.)\n */\n asPodObject(): any {\n return this.asObject(MINIFY_ENTITY_FOR_POD as AO);\n }\n\n isEmpty(): boolean {\n return this.countNotEmptyCriteria() === 0;\n }\n\n countNotEmptyCriteria(): number {\n const json = this.asPodObject();\n return Object.keys(json)\n .filter(key => this.isCriteriaNotEmpty(key, json[key]))\n .length;\n }\n\n asFilterFn(): FilterFn<T> {\n const filterFns = this.buildFilter();\n if (isEmptyArray(filterFns)) return undefined;\n return (entity) => !filterFns.find(fn => !fn(entity));\n }\n\n protected buildFilter(): FilterFn<T>[] {\n // Can be completed by subclasses\n return [];\n }\n\n protected isCriteriaNotEmpty(key: string, value: any): boolean {\n // Can be overridden by subclasses\n return value !== undefined\n && value !== null\n && (\n // not empty string\n (typeof value === 'string' && value.trim() !== '')\n // valid number\n || (typeof value === 'number' && !isNaN(value))\n // valid boolean\n || (typeof value === 'boolean')\n // not empty array\n || (Array.isArray(value) && value.length > 0)\n // entity with an id\n || ReferentialUtils.isNotEmpty(value)\n );\n }\n}\n\nexport abstract class EntityFilterUtils {\n\n static isEntityFilter<F extends EntityFilter<F, any>>(obj: Partial<F>): obj is F {\n return obj && obj.asPodObject && obj.asFilterFn && true || false;\n }\n\n static fromObject<F>(source: any, filterType: new () => F): F {\n if (!source) return source;\n if (isInstanceOf(source, filterType)) return source as F;\n const target = new filterType();\n if (EntityFilterUtils.isEntityFilter(target)) {\n target.fromObject(source);\n } else {\n Object.assign(target, source);\n }\n return target;\n }\n}\n","import {BehaviorSubject, merge, Observable} from 'rxjs';\nimport {filter, map, mergeMap, takeUntil, tap} from 'rxjs/operators';\nimport {isEmptyArray, isNil, isNotEmptyArray, isNotNil} from '../functions';\nimport {EntitiesServiceLoadOptions, EntitiesServiceWatchOptions, FilterFn, FilterFnFactory, IEntitiesService, LoadResult} from './entity-service.class';\nimport {SortDirection} from '@angular/material/sort';\nimport {Directive, OnDestroy} from '@angular/core';\nimport {EntityUtils, IEntity} from '../../core/services/model/entity.model';\nimport {EntityFilter, EntityFilterUtils} from '../../core/services/model/filter.model';\nimport {firstFalsePromise, firstNotNil, WaitForOptions} from '../observables';\nimport {StartableService} from './startable-service.class';\nimport {StartableObservableService} from './startable-observable-service.class';\n\nexport interface InMemoryEntitiesServiceOptions<T, F> {\n onSort?: (data: T[], sortBy?: string, sortDirection?: SortDirection) => T[];\n onLoad?: (data: T[]) => T[] | Promise<T[]>;\n onSave?: (data: T[]) => T[] | Promise<T[]>;\n equals?: (d1: T, d2: T) => boolean;\n\n filterFnFactory?: FilterFnFactory<T, F>;\n filterFn?: FilterFn<T>;\n\n sortByReplacement?: { [key: string]: string };\n}\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport class InMemoryEntitiesService<\n T extends IEntity<T, ID>,\n F = any,\n ID = number,\n O extends EntitiesServiceWatchOptions = EntitiesServiceWatchOptions>\n extends StartableObservableService<T[], T[]>\n implements IEntitiesService<T, F, O>, OnDestroy {\n\n debug = false;\n\n private _hiddenData: T[] = null;\n\n readonly dirtySubject = new BehaviorSubject<boolean>(false);\n\n private readonly savingSubject = new BehaviorSubject<boolean>(false);\n private readonly _sortFn: (data: T[], sortBy?: string, sortDirection?: SortDirection) => T[];\n private readonly _onLoad: (data: T[]) => T[] | Promise<T[]>;\n private readonly _onSaveFn: (data: T[]) => T[] | Promise<T[]>;\n private readonly _equalsFn: (d1: T, d2: T) => boolean;\n private readonly _filterFnFactory: FilterFnFactory<T, F>;\n private readonly _sortByReplacement: { [key: string]: string };\n\n\n set value(data: T[]) {\n this.setValue(data);\n }\n\n get value(): T[] {\n return this.dataSubject.getValue();\n }\n\n get saving(): boolean{\n return this.savingSubject.value;\n }\n\n get dirty(): boolean {\n return this.dirtySubject.value;\n }\n\n constructor(\n protected dataType: new() => T,\n protected filterType: new() => F,\n options?: InMemoryEntitiesServiceOptions<T, F>\n ) {\n super(null);\n options = {\n onSort: this.sort,\n ...options\n };\n\n this._sortFn = options.onSort;\n this._onLoad = options.onLoad;\n this._onSaveFn = options.onSave;\n this._equalsFn = options.equals;\n this._filterFnFactory = options.filterFnFactory || ((f) => {\n const filter = this.asFilter(f) as F;\n if (filter instanceof EntityFilter) {\n return filter.asFilterFn();\n }\n return undefined;\n });\n this._startByReadyFunction = false; // Need setValue() to be called, to start the service\n\n this._sortByReplacement = {\n ...options.sortByReplacement\n };\n }\n\n protected async ngOnStart(data?: T[]): Promise<T[]> {\n if (!data) throw new Error('Missing required data, to start this service');\n if (this.debug) console.debug('[memory-data-service] Starting...');\n this._hiddenData = [];\n this.markAsSaved();\n this.markAsPristine();\n return data;\n }\n\n protected async ngOnStop(): Promise<void> {\n if (this.debug) console.debug('[memory-data-service] Stopping...');\n this.dataSubject.complete();\n this.dataSubject.unsubscribe();\n this._hiddenData = null;\n this.markAsSaved();\n this.markAsPristine();\n }\n\n ngOnDestroy() {\n this.stop();\n }\n\n setValue(data: T[]) {\n // If service already started\n if (this.started) {\n // Update the data, if changed\n if (this.dataSubject.value !== data) {\n this._hiddenData = [];\n this.dataSubject.next(data);\n }\n\n // Reset dirty and saving state\n // (Fix ObsBio issue on samples table : still dirty after setting the same value again)\n this.markAsSaved();\n this.markAsPristine();\n }\n // If service not started yet, then start it, using given data\n else {\n this.start(data);\n }\n }\n\n async loadAll(\n offset: number,\n size: number,\n sortBy?: string,\n sortDirection?: SortDirection,\n filter?: F,\n opts?: EntitiesServiceLoadOptions\n ): Promise<LoadResult<T>> {\n\n offset = offset >= 0 ? offset : 0;\n size = size >= 0 ? size : -1;\n\n const originalData = this.dataSubject.value;\n if (isNil(originalData)) {\n console.warn('[memory-data-service] Cannot load all: no value set. Will return empty result');\n }\n\n try {\n // Wait service is ready\n await this.ready();\n\n // Wait while busy (e.g. when saving, or deleting)\n await this.waitIdle({stopError: false /*avoid error when stopped*/});\n }\n catch (err) {\n // Should be a stop error: log and continue\n if (!this.stopped) console.error('Unexpected error, while waiting :', err);\n }\n\n // Make sure service is not stopped\n if (this.stopped) return undefined;\n\n const excludedDataByFilter: T[] = [];\n let excludedDataByPagination: T[];\n\n try {\n if (isEmptyArray(originalData)) {\n return {data: [], total: 0};\n }\n\n // Apply sort\n let data = this._sortFn(originalData, sortBy, sortDirection) ;\n\n if (this._onLoad) {\n data = await this._onLoad(data);\n }\n\n // Apply filter (will update hiddenData)\n data = this.filter(data, filter, excludedDataByFilter);\n\n // Compute the total length\n const total = data.length;\n\n // If page size=0 (e.g. only need total)\n if (size === 0) {\n excludedDataByPagination = data;\n return {data: [], total};\n }\n\n // Slice in a page (using offset and size)\n if (offset > 0) {\n\n // Offset after the end: no result\n if (offset >= data.length) {\n excludedDataByPagination = data;\n data = [];\n }\n else {\n excludedDataByPagination = (size > 0 && ((offset + size) < data.length))\n // Slice using limit to size\n ? data.slice(0, offset -1).concat(data.slice(offset + size))\n // Slice without limit\n : data.slice(0, offset-1);\n\n data = (size > 0 && ((offset + size) < data.length))\n // Slice using limit to size\n ? data.slice(offset, offset + size)\n // Slice without limit\n : data.slice(offset);\n }\n }\n\n // Apply a limit\n else if (size > 0){\n excludedDataByPagination = data.slice(size);\n data = data.slice(0, size);\n }\n\n // No limit:\n else if (size === -1){\n // Keep all data\n }\n\n // /!\\ If already observed, then always create a copy of the original array\n // Because datasource will only update if the array changed\n if (data === originalData) {\n data = data.slice();\n }\n\n const res: LoadResult<T> = {data, total};\n\n const nextOffset = size > 0 ? (offset || 0) + size : total;\n if (nextOffset < total) {\n res.fetchMore = () => this.loadAll(nextOffset, size, sortBy, sortDirection, filter, opts)\n .then(res => {\n // Update hidden data (remove new fetched item)\n if (res.data?.length) {\n this._hiddenData = this._hiddenData?.filter(item => !res.data.includes(item))\n }\n return res;\n });\n }\n\n return res;\n }\n finally {\n // Remember hidden data\n if (offset === 0) {\n this._hiddenData = !excludedDataByPagination ? excludedDataByFilter : excludedDataByFilter.concat(...excludedDataByPagination);\n }\n }\n }\n\n watchAll(\n offset: number,\n size: number,\n sortBy?: string,\n sortDirection?: SortDirection,\n filterData?: F,\n options?: any\n ): Observable<LoadResult<T>> {\n\n offset = offset >= 0 ? offset : 0;\n size = size >= 0 ? size : -1;\n\n return this.dataSubject\n .pipe(\n takeUntil(this.stopSubject),\n // Warn if waiting value to be set\n tap((data) => this.debug && !data && console.debug('[memory-data-service] Waiting value to be set...')),\n filter(isNotNil),\n mergeMap(_ => this.loadAll(offset, size, sortBy, sortDirection, filterData, options)),\n filter(isNotNil) // Skip no result (e.g. when stopped)\n );\n }\n\n async saveAll(data: T[], options?: any): Promise<T[]> {\n if (!this.dataSubject.value) throw new Error('[memory-service] Could not save, because value not set');\n\n this.markAsSaving();\n\n try {\n\n // Restore hidden data\n if (isNotEmptyArray(this._hiddenData))\n data = data.concat(...this._hiddenData);\n\n if (this._onSaveFn) {\n const res = this._onSaveFn(data);\n data = ((res instanceof Promise)) ? await res : res;\n }\n\n this.dataSubject.next(data);\n this.markAsDirty();\n return data;\n }\n finally {\n this.markAsSaved();\n }\n }\n\n async deleteAll(dataToRemove: T[], options?: any): Promise<any> {\n let data = this.dataSubject.value;\n if (!data) throw new Error('[memory-service] Could not delete, because value not set');\n\n this.markAsSaving();\n\n try {\n // Remove deleted item, from data\n const updatedData = data.filter(entity => {\n const removed = dataToRemove.findIndex(entityToRemove => this.equals(entityToRemove, entity)) !== -1;\n return !removed;\n });\n const deleteCount = data.length - updatedData.length;\n if (deleteCount > 0) {\n data = updatedData;\n this.dataSubject.next(data);\n this.markAsDirty();\n }\n }\n finally {\n this.markAsSaved();\n }\n }\n\n sort(data: T[], sortBy?: string, sortDirection?: SortDirection): T[] {\n // Make sure to fill sortBy BEFORE checking in the replacement map\n sortBy = sortBy || 'id';\n // Replace sortBy, using the replacement map\n sortBy = this._sortByReplacement[sortBy] || sortBy;\n\n // Execute the sort\n return EntityUtils.sort(data, sortBy, sortDirection);\n }\n\n asFilter(source: Partial<F>): F {\n return EntityFilterUtils.fromObject(source, this.filterType);\n }\n\n addSortByReplacement(source: string, target: string) {\n this._sortByReplacement[source] = target;\n }\n\n equals(d1: T, d2: T): boolean {\n if (this._equalsFn) return this._equalsFn(d1, d2);\n return d1 && d1.equals ? d1.equals(d2) : EntityUtils.equals(d1, d2, 'id');\n }\n\n /**\n * Count data stored by the service (without hidden data).\n * @param opts\n */\n get count(): number {\n return (this.dataSubject.value?.length || 0);\n }\n\n get hiddenCount(): number {\n return this._hiddenData?.length || 0;\n }\n\n async waitIdle(opts?: WaitForOptions) {\n await this.waitWhileSaving(opts);\n }\n\n markAsDirty() {\n if (!this.dirtySubject.value) {\n this.dirtySubject.next(true);\n }\n }\n\n markAsPristine() {\n if (this.dirtySubject.value) {\n this.dirtySubject.next(false);\n }\n }\n\n /* -- protected methods -- */\n\n protected filter(data: T[], _filter: F, hiddenData: T[]): T[] {\n\n // if filter is DataFilter instance, use its test function\n const filterFn = this._filterFnFactory && this._filterFnFactory(_filter);\n if (filterFn) {\n const filteredData = [];\n\n data.forEach(value => {\n if (filterFn(value))\n filteredData.push(value);\n else\n hiddenData.push(value);\n });\n\n return filteredData;\n }\n\n // default, no filter\n return data;\n }\n\n protected connect(): Observable<LoadResult<T>> {\n return this.dataSubject.pipe(\n map((data) => {\n data = data || [];\n const total = data.length;\n return {data, total};\n })\n );\n }\n\n protected async waitWhileSaving(opts?: WaitForOptions): Promise<void> {\n if (this.saving) {\n return firstFalsePromise(this.savingSubject, {\n stop: opts?.stop || merge(this.stopSubject, this.dataSubject), // Stop if destroyed or new data Received\n stopError: false, // Avoid error when stopped\n ...opts\n });\n }\n }\n\n protected markAsSaving() {\n if (!this.savingSubject.value) {\n this.savingSubject.next(true);\n }\n }\n\n protected markAsSaved() {\n if (this.savingSubject.value) {\n this.savingSubject.next(false);\n }\n }\n\n\n}\n","import { BehaviorSubject, defer, Observable } from 'rxjs';\nimport { isNil, isNotNil, toNumber } from '../functions';\nimport { LoadResult, LoadResultByPageFn } from './entity-service.class';\n\nexport type CallableWithProgressionFn<O extends CallableWithProgressionOptions> = (opts?: O) => Promise<any>;\nexport interface CallableWithProgressionOptions {\n maxProgression?: number;\n progression?: BehaviorSubject<number>;\n [key: string]: any;\n}\n\n// @dynamic\nexport class JobUtils {\n\n static defers<O extends CallableWithProgressionOptions>(runnableList: CallableWithProgressionFn<O>[], opts?: O): Observable<number>[] {\n return runnableList.map(runnable => JobUtils.defer(runnable, opts));\n }\n\n static defer<O extends CallableWithProgressionOptions>(runnable: CallableWithProgressionFn<O>, opts?: O): Observable<number> {\n return defer<Observable<number>>(() => JobUtils.run(runnable, opts));\n }\n\n static run<O extends CallableWithProgressionOptions>(runnable: CallableWithProgressionFn<O>, opts: O): Observable<number> {\n\n const progression = new BehaviorSubject<number>(0);\n runnable({...opts, progression})\n .then(() => {\n if (opts?.maxProgression) progression.next(opts.maxProgression);\n progression.complete();\n })\n .catch(err => progression.error(err));\n return progression;\n }\n\n static async fetchAllPages<T>(\n loadPageFn: LoadResultByPageFn<T>,\n opts?: {\n progression?: BehaviorSubject<number>;\n maxProgression?: number;\n onPageLoaded?: (pageResult: LoadResult<T>) => any;\n logPrefix?: string;\n fetchSize?: number;\n }): Promise<LoadResult<T>> {\n\n const maxProgression = toNumber(opts?.maxProgression, 100);\n const progression = opts?.progression;\n let total; let pageCount; let progressionStep; let currentPageDataCount: number;\n const fetchSize = toNumber(opts?.fetchSize, 1000);\n if (fetchSize <= 0) throw new Error('Unable to fetch pages: invalid fetchSize: ' + fetchSize);\n let offset = 0;\n let data: T[] = [];\n do {\n\n if (opts && opts.logPrefix) console.debug(`${opts.logPrefix} Fetching page #${offset / fetchSize}...`);\n\n // Fetch a page\n const res = await loadPageFn(offset, fetchSize);\n\n // Concat to previous result\n data = data.concat(res.data);\n\n // Compute variables, for next loop\n currentPageDataCount = res.data && res.data.length || 0;\n offset += currentPageDataCount;\n\n // Set total count (only once)\n if (isNil(total) && isNotNil(res.total)) {\n total = res.total;\n // Compute the number of page\n pageCount = Math.round(res.total / fetchSize + 0.5); // Round to HALF_UP integer\n // Compute step, by dividing maxProgression by number of page\n if (progression) {\n progressionStep = maxProgression / pageCount;\n // DEBUG\n if (opts && opts.logPrefix) console.debug(`${opts.logPrefix} {pageCount: ${pageCount}, progress: ${progression.value?.toFixed(2)}, pageProgressStep: ${progressionStep?.toFixed(1)}}`);\n }\n }\n\n // Increment progression on each iteration (if possible)\n if (isNotNil(progressionStep)) {\n progression.next(progression.value + progressionStep);\n }\n\n if (opts?.onPageLoaded) opts.onPageLoaded(res);\n\n } while (currentPageDataCount > 0 && ((isNil(total) && currentPageDataCount === fetchSize) || (isNotNil(total) && (offset < total))));\n\n // Complete progression to reach progressionStep value (because of round)\n if (isNotNil(progressionStep)) {\n\n // If total return by loadAll was bad !\n if (isNotNil(total) && data.length < total) {\n console.warn(`A function loadAll() returned a bad total (less than all page's data)! Expected ${total} but fetch ${data.length}`);\n total = data.length;\n pageCount = Math.round(data.length / fetchSize + 0.5);\n }\n\n // Compute final increment, using the real page count\n progressionStep = Math.max(0, maxProgression - (progressionStep * pageCount));\n\n }\n\n // Or increment once (e.g. when total is not known, in received LoadResult)\n else if (progression) {\n progressionStep = maxProgression;\n }\n\n // DEBUG\n if (opts && opts.logPrefix) console.debug(`${opts.logPrefix} All pages fetched - {progress: ${progression.value?.toFixed(2)}, lastProgressStep: ${progressionStep?.toFixed(1)}`);\n\n // Final increment\n if (progression && progressionStep > 0) {\n progression.next(progression.value + progressionStep);\n }\n\n return {\n data,\n total\n };\n }\n}\n","import {Observable} from 'rxjs';\nimport {filter, map} from 'rxjs/operators';\nimport {HttpEventType} from '@angular/common/http';\nimport {FileEvent, FileResponse} from '../upload-file/upload-file.model';\nimport {FilesUtils} from './file.utils';\nimport {isNotNil} from '../functions';\n\n//@dynamic\nexport class CsvUtils {\n\n static exportToFile(rows: object[],\n opts?: {\n filename?: string;\n headers?: string[];\n separator?: string;\n encoding?: string;\n type?: string;\n }) {\n if (!rows || !rows.length) return; // Skip if empty\n\n // Create text content\n const separator = opts?.separator || ',';\n const protectCellRegexp = new RegExp(\"/(\\\"|\"+ separator +\"|\\n)/g\");\n const keys = Object.keys(rows[0]);\n const headers = opts?.headers || keys;\n const textContent =\n // Header row\n headers.join(separator) + '\\n' +\n // Data rows\n rows.map(row => {\n return keys.map(k => {\n const cell = row[k] === null || row[k] === undefined ? '' : row[k];\n let cellStr: string = cell instanceof Date\n ? cell.toLocaleString()\n : cell.toString().replace(/\"/g, '\"\"');\n if (protectCellRegexp.test(cellStr)) {\n cellStr = `\"${cellStr}\"`;\n }\n return cellStr;\n }).join(separator);\n }).join('\\n');\n\n // Write to file\n FilesUtils.writeTextToFile(\n textContent, {\n type: 'text/csv',\n filename: 'export.csv',\n ...opts,\n }\n );\n }\n\n static parseFile(file: File, opts?: {separator?: string; encoding?: string;}): Observable<FileEvent<string[][]>> {\n return FilesUtils.readAsText(file, opts?.encoding)\n .pipe(\n map(e => {\n if (e.type === HttpEventType.UploadProgress) {\n const loaded = Math.round(e.loaded * 0.8);\n return {...e, loaded};\n }\n else if (e instanceof FileResponse){\n const body = e.body;\n const data = CsvUtils.parseCSV(body, opts);\n return new FileResponse<string[][]>({body: data});\n }\n }),\n filter(isNotNil)\n );\n }\n\n static parseCSV(body: string, opts?: {separator?: string; skipEmptyLine?: boolean}): string[][] {\n const separator = opts?.separator || ',';\n const skipEmptyLine = !opts || opts.skipEmptyLine !== false;\n\n // Protect special characters (quote and /n)\n body = body.replace('\"\"', '<quote>') // Protect double quote\n .replace(/(\"[^\\n\"]+)\\n\\r?/gm, '\"$1<br>') // Protect \\n inside a quoted expression\n .replace(/\\n\\r/gm, '\\n') // Windows CR\n\n const headerAndRows = body.split('\\n', 2);\n const headers = headerAndRows[0].split(separator);\n\n return body.split('\\n') // split into rows\n .filter(line => !skipEmptyLine || line.trim().length > 0) // Skip empty line\n .map(line => {\n const cells = line.split(separator, headers.length) // split into cells\n .map(cell => cell.replace(/^\"([^\"]*)\"$/, '$1')) // Clean trailing quotes\n .map(cell => cell.replace('<quote>', '\"')) // restore protected quote\n .map(cell => cell.replace('<br>', '\\n')) // restore protected br\n ;\n return cells;\n });\n }\n}\n","import {PredefinedColors} from '@ionic/core';\nimport {isNil, isNotNil} from '../functions';\nimport {hexToRgb, hexToRgbArray, rgbArrayToHex} from './colors.utils';\n\nexport declare type ColorName = PredefinedColors |\n 'white'\n | 'red'\n | 'green'\n | 'blue';\n\n\n/**\n * Define here theme colors\n */\nconst rgbArrayMap = {\n white: [255, 255, 255],\n primary: [20, 67, 145], // ok\n secondary: [117, 196, 253], // ok\n tertiary: [91, 94, 244], // ok\n danger: [245, 61, 61], // ok\n light: [244, 245, 248], // ok\n medium: [152, 154, 162], // ok\n dark: [34, 36, 40], // ok\n red: [255, 0, 0],\n green: [0, 255, 0],\n blue: [0, 0, 255]\n};\n\n// Fill a map of Color objects\nconst colorsMap: { [key: string]: Color } = {};\n\n\n/**\n * Useful class for color conversion\n */\n// @dynamic\nexport class Color {\n\n // Helper method, to retrieve a color\n static get(name: ColorName): Color {\n return colorsMap[name] as Color;\n }\n\n static parseRgba(rgba: string): Color|null{\n if (!rgba || (!rgba.startsWith('rgb(') && !rgba.startsWith('rgba('))) return null;\n\n // Parse parts\n const parts = rgba\n .replace('rgb(', '')\n .replace('rgba(', '')\n .replace(')', '')\n .split(',');\n\n if (parts.length !== 3 && parts.length !== 4) return null;\n\n return new Color([+parts[0], +parts[1], +parts[2]],\n parts.length === 4 && +parts[3] || 1,\n 'custom');\n }\n\n static transparent = function() {\n return new Color([0,0,0], 0, 'translucent');\n };\n\n constructor(\n private _rgbArray: number[],\n private _opacity?: number,\n private _name: string = 'custom'\n ) {\n }\n get name(): string {\n return this._name;\n }\n get opacity(): number{\n return isNotNil(this._opacity) ? this._opacity : 1;\n }\n get rgb(): number[] {\n return this._rgbArray;\n }\n\n get r(): number {\n return this._rgbArray[0];\n }\n\n get g(): number {\n return this._rgbArray[1];\n }\n\n get b(): number {\n return this._rgbArray[2];\n }\n\n rgba(opacity?: number): string {\n opacity = isNotNil(opacity) ? opacity : this._opacity;\n if (isNil(opacity) || opacity < 0 || opacity > 1) {\n return 'rgb(' + this._rgbArray.join(',') + ')';\n }\n return 'rgba(' + this._rgbArray.join(',') + ',' + opacity + ')';\n }\n\n}\n\nexport declare interface ColorGradientOptions {\n startColor?: number[];\n mainColor?: number[];\n mainColorIndex?: number;\n endColor?: number[];\n}\n\nexport declare interface ColorScaleOptions extends ColorGradientOptions {\n opacity?: number;\n min?: number;\n max?: number;\n upperMax?: boolean;\n}\n\nexport declare interface ColorScaleLegendItem {\n label: string|number[];\n color: Color;\n}\n\nexport declare interface ColorScaleLegend {\n items: ColorScaleLegendItem[];\n}\n\n/**\n * Helper class for colors scale\n */\n// @dynamic\nexport class ColorScale {\n\n static custom = (count: number, options?: ColorScaleOptions) => {\n options = options || {};\n return new ColorScale(\n linearColorGradientWithIntermediate(count, {\n startColor: options.startColor || undefined,\n mainColor: options.mainColor || undefined,\n mainColorIndex: isNotNil(options.mainColorIndex) ? options.mainColorIndex : undefined,\n endColor: options.endColor || undefined\n }),\n options\n );\n };\n\n static default() {\n return ColorScale.custom(25);\n }\n\n /**\n * Create a array with the given color\n **/\n static fix(length?: number, colorName?: ColorName): any[] {\n return Array.apply(null, Array(length || 25))\n .map(String.prototype.valueOf, Color.get(colorName || 'primary').rgba(0.5));\n }\n\n private _min: number;\n private _max: number;\n private _rangeSize: number;\n private _legendItems: ColorScaleLegendItem[];\n\n get min(): number {\n return this._min;\n }\n get max(): number {\n return this._max;\n }\n\n constructor(colorArray: number[][], options?: ColorScaleOptions) {\n options = options || {};\n // reserved last colors for value > max\n const nbIntervalBeforeUpper = !options.upperMax ? colorArray.length : (colorArray.length - 1);\n this._min = options.min || 0;\n this._max = options.max || nbIntervalBeforeUpper;\n this._rangeSize = Math.round((this._max - this._min) / nbIntervalBeforeUpper);\n this._legendItems = this.computeLegendItems(colorArray);\n }\n\n get legend(): ColorScaleLegend {\n return {\n items: this._legendItems\n };\n }\n\n getLegendForValue(value: number): ColorScaleLegendItem {\n const index = Math.floor(value * (this._legendItems.length - 1) / this._max);\n return this._legendItems[index];\n }\n\n getLegendAtIndex(index: number): ColorScaleLegendItem {\n return this._legendItems[index];\n }\n\n protected computeLegendItems(colorArray: number[][]): ColorScaleLegendItem[] {\n return colorArray.map((color, index) => {\n const start = index * this._rangeSize;\n const end = start + this._rangeSize;\n return {\n color: new Color(color),\n label: (end < this._max) ? `${start.toLocaleString()} - ${end.toLocaleString()}` : ` >= ${start}`\n };\n });\n }\n}\n\n\n// Fill colorsMap\nObject.getOwnPropertyNames(rgbArrayMap)\n .forEach((key) => {\n colorsMap[key] = new Color(rgbArrayMap[key], 1, key);\n });\n\n\n/**\n * Internal function, that create a colors scale, using iteration\n *\n * @param count\n * @param opacity\n * @param startColor\n * @param startState\n * @returns\n */\nfunction linearColorGradientWithIntermediate(count: number,\n options?: ColorGradientOptions): number[][] {\n options = options || {};\n\n // From [0,1]\n options.startColor = options.startColor || [255, 255, 190]; // default start = creme\n options.mainColorIndex = options.mainColorIndex && options.mainColorIndex < count - 1 ? options.mainColorIndex : count - 1;\n options.endColor = options.endColor || [255, 0, 0]; // default main = red\n\n if (!options.mainColor) {\n return linearColorGradient(count, {\n startColor: options.startColor,\n endColor: options.endColor\n });\n }\n\n else {\n // Step 1: startColor -> mainColor\n const result = linearColorGradient(options.mainColorIndex + 1, {\n startColor: options.startColor,\n endColor: options.mainColor\n });\n\n // Step 2: mainColor -> endColor\n if (options.mainColorIndex < count - 1) {\n return result.concat(\n linearColorGradient(count - options.mainColorIndex, {\n startColor: options.mainColor,\n endColor: options.endColor\n }));\n }\n else {\n return result;\n }\n }\n}\n\nfunction linearColorGradient(count: number,\n options?: ColorGradientOptions): any[] {\n\n options = options || {};\n\n // From [0,1]\n options.startColor = options.startColor || [255, 255, 255]; // default start = white\n options.endColor = options.endColor || [255, 0, 0]; // default end = red\n\n const result: number[][] = [];\n const color = options.startColor.slice(); // copy the start color\n const delta = [\n Math.round((options.endColor[0] - options.startColor[0]) / count),\n Math.round((options.endColor[1] - options.startColor[1]) / count),\n Math.round((options.endColor[2] - options.startColor[2]) / count)\n ];\n\n for (let i = 0; i < count - 1; i++) {\n for (let j = 0; j < 3; j++) {\n color[j] += delta[j];\n }\n result.push(color.slice());\n }\n\n // Force last color = end color\n result.push(options.endColor.slice());\n\n // Output as array\n return result;\n}\n","import {Component, ViewChild} from '@angular/core';\nimport {ModalController} from '@ionic/angular';\nimport {AccountService} from '../../services/account.service';\nimport {RegisterForm} from '../form/form-register';\n\n@Component({\n selector: 'modal-register',\n templateUrl: 'modal-register.html',\n})\nexport class RegisterModal {\n\n sending = false;\n\n @ViewChild('form', { static: true }) private form: RegisterForm;\n\n constructor(private accountService: AccountService,\n public viewCtrl: ModalController) {\n }\n\n cancel() {\n console.debug('[register] cancelled');\n this.viewCtrl.dismiss();\n }\n\n async doSubmit(event?: any) {\n if (this.form.form.disabled || this.sending) return; // Skip\n if (!this.form.valid || !this.form.isEnd()) {\n this.form.markAsTouched();\n return;\n }\n\n this.sending = true;\n const data = this.form.value;\n\n this.form.disable();\n\n try {\n console.debug('[register] Sending registration to server...', data);\n const res = await this.accountService.register(data);\n\n console.debug('[register] Account registered!');\n await this.viewCtrl.dismiss();\n }\n catch (err) {\n this.form.error = err && err.message || err;\n this.form.enable();\n }\n finally {\n this.sending = false;\n }\n }\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, Injector, OnInit, Optional, Output } from '@angular/core';\nimport { FormBuilder, Validators } from '@angular/forms';\nimport { ModalController } from '@ionic/angular';\nimport { RegisterModal } from '../../register/modal/modal-register';\nimport { AuthData } from '../../services/account.service';\nimport { AuthTokenType, NetworkService } from '../../services/network.service';\nimport { LocalSettingsService } from '../../services/local-settings.service';\nimport { slideUpDownAnimation } from '../../../shared/material/material.animations';\nimport { PlatformService } from '../../services/platform.service';\nimport { debounceTime } from 'rxjs/operators';\nimport { AppForm } from '../../form/form.class';\nimport { ENVIRONMENT } from '../../../../environments/environment.class';\nimport { CORE_CONFIG_OPTIONS } from '../../services/config/core.config';\nimport { ConfigService } from '../../services/config.service';\nimport {AppFormUtils} from '../../form/form.utils';\n\n\n@Component({\n selector: 'app-form-auth',\n templateUrl: 'form-auth.html',\n styleUrls: ['./form-auth.scss'],\n animations: [slideUpDownAnimation],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AuthForm extends AppForm<AuthData> implements OnInit {\n\n readonly mobile: boolean;\n canWorkOffline = false;\n showPwd = false;\n canRegister: boolean;\n usernamePlaceholder: string;\n\n @Output() onCancel = new EventEmitter<any>();\n @Output() onSubmit = new EventEmitter<AuthData>();\n\n disable(opts?: { onlySelf?: boolean; emitEvent?: boolean }) {\n super.disable(opts);\n this.showPwd = false; // Hide pwd when disable (e.g. when submitted)\n }\n\n constructor(\n injector: Injector,\n platform: PlatformService,\n formBuilder: FormBuilder,\n settings: LocalSettingsService,\n private configService: ConfigService,\n private modalCtrl: ModalController,\n public network: NetworkService,\n private cd: ChangeDetectorRef,\n @Optional() @Inject(ENVIRONMENT) protected environment\n ) {\n super(injector,\n formBuilder.group({\n username: [null, Validators.required],\n password: [null, Validators.required],\n offline: [network.offline]\n }));\n\n this.mobile = settings.mobile;\n this.canWorkOffline = this.settings.hasOfflineFeature();\n this._enable = true;\n\n }\n\n ngOnInit() {\n super.ngOnInit();\n\n // Load config, to set username's label and validator\n this.registerSubscription(\n this.configService.config.subscribe(config => {\n // Set the username placeholder, with email or username\n const tokenType = config.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE) as AuthTokenType;\n if (tokenType === 'token') {\n this.usernamePlaceholder = 'USER.EMAIL';\n this.form.get('username').setValidators(Validators.compose([Validators.required, Validators.email]));\n }\n else {\n this.usernamePlaceholder = 'USER.USERNAME';\n this.form.get('username').setValidators(Validators.required);\n }\n\n // Enable/disable registration link\n this.canRegister = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.REGISTRATION_ENABLE);\n\n this.markForCheck();\n })\n );\n\n // For DEV only\n if (this.environment && this.environment.production === false && this.environment.defaultAuthValues) {\n // Set the default user, for testing.\n // Override using environment, if any\n this.form.patchValue(this.environment.defaultAuthValues);\n }\n }\n\n async cancel() {\n this.onCancel.emit();\n }\n\n async doSubmit(event?: UIEvent) {\n if (event) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n if (this.loading) return;\n\n if (!this.form.valid) {\n await AppFormUtils.waitWhilePending(this.form);\n if (this.form.invalid) {\n AppFormUtils.logFormErrors(this.form);\n return; // Skip if invalid\n }\n }\n\n this.markAsLoading();\n const data = this.form.value;\n this.showPwd = false; // Hide password\n this.error = null; // Reset error\n\n setTimeout(() => this.onSubmit.emit({\n username: data.username,\n password: data.password,\n offline: data.offline\n }));\n }\n\n register() {\n this.onCancel.emit();\n setTimeout(async () => {\n const modal = await this.modalCtrl.create({\n component: RegisterModal,\n backdropDismiss: false\n });\n return modal.present();\n }, 200);\n }\n\n /* -- protected functions -- */\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewChild, OnInit} from '@angular/core';\nimport {ModalController} from '@ionic/angular';\nimport {AccountService} from '../../services/account.service';\nimport {AuthForm} from '../form/form-auth';\nimport {firstNotNilPromise} from '../../../shared/observables';\nimport {ConfigService} from '../../services/config.service';\nimport {CORE_CONFIG_OPTIONS} from '../../services/config/core.config';\nimport {Configuration} from '../../services/model/config.model';\n\n@Component({\n templateUrl: 'modal-auth.html',\n styleUrls: ['./modal-auth.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AuthModal implements OnInit {\n\n get loading() {\n return this.form?.loading;\n }\n\n @ViewChild('form', { static: true }) private form: AuthForm;\n\n constructor(private accountService: AccountService,\n private viewCtrl: ModalController,\n private cd: ChangeDetectorRef\n ) {\n }\n\n ngOnInit() {\n this.form.markAsReady({emitEvent: false});\n this.form.markAsLoaded();\n }\n\n cancel() {\n this.viewCtrl.dismiss();\n }\n\n async doSubmit(): Promise<any> {\n if (this.form.disabled) return;\n if (!this.form.valid) {\n this.form.markAllAsTouched();\n return;\n }\n this.markAsLoading();\n\n try {\n const data = this.form.value;\n\n // Disable the form\n this.form.disable();\n\n const account = await this.accountService.login(data);\n return this.viewCtrl.dismiss(account);\n }\n catch (err) {\n this.form.error = err && err.message || err;\n this.markAsLoaded();\n\n // Enable the form\n this.form.enable();\n\n // Reset form error on next changes\n firstNotNilPromise(this.form.form.valueChanges).then(() => {\n this.form.error = null;\n this.markForCheck();\n });\n\n return;\n }\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n protected markAsLoading(opts?: {emitEvent?: boolean}) {\n this.form.markAsLoading(opts);\n }\n\n protected markAsLoaded(opts?: {emitEvent?: boolean}) {\n this.form.markAsLoaded(opts);\n }\n}\n","import {Component, Inject, InjectionToken, OnDestroy, Optional} from '@angular/core';\nimport {ModalController} from '@ionic/angular';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {capitalizeFirstLetter} from '../../shared/functions';\nimport {Department} from '../services/model/department.model';\nimport {Person} from '../services/model/person.model';\nimport {TranslateService} from '@ngx-translate/core';\nimport {ConfigService} from '../services/config.service';\nimport {Configuration} from '../services/model/config.model';\nimport {Observable, Subscription} from 'rxjs';\nimport {CORE_CONFIG_OPTIONS} from '../services/config/core.config';\nimport {environment} from '../../../environments/environment';\n\nexport const APP_ABOUT_DEVELOPERS = new InjectionToken<Partial<Department>[]>('aboutDevelopers');\nexport const APP_ABOUT_PARTNERS = new InjectionToken<Partial<Department>[]>('aboutPartners');\n\n@Component({\n selector: 'modal-about',\n styleUrls: ['./modal-about.scss'],\n templateUrl: './modal-about.html'\n})\nexport class AboutModal implements OnDestroy {\n\n readonly name: string;\n readonly version: string;\n readonly sourceUrl: string;\n readonly reportIssueUrl: string;\n readonly config$: Observable<Configuration>;\n forumUrl: string;\n helpUrl: string;\n\n private readonly _subscription = new Subscription();\n\n constructor(\n protected translate: TranslateService,\n protected modalController: ModalController,\n protected configService: ConfigService,\n @Optional() @Inject(ENVIRONMENT) protected environment,\n @Optional() @Inject(APP_ABOUT_DEVELOPERS) public developers: Partial<Department>[],\n @Optional() @Inject(APP_ABOUT_PARTNERS) public partners: Partial<Department>[]\n ) {\n this.name = translate.instant('APP_NAME');\n if (this.name === 'APP_NAME') {\n // Not translated: use name from the environnement\n this.name = environment && environment.name && capitalizeFirstLetter(environment.name) || undefined;\n }\n this.version = environment && environment.version;\n this.sourceUrl = environment && environment.sourceUrl;\n this.reportIssueUrl = environment && environment.reportIssueUrl;\n this.forumUrl = environment && environment.forumUrl;\n this.helpUrl = environment && environment.helpUrl;\n this.config$ = configService.config;\n\n this._subscription.add(\n this.config$.subscribe(config => this.setConfig(config))\n );\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n }\n\n async close() {\n await this.modalController.dismiss();\n }\n\n /* -- protected functions -- */\n\n protected setConfig(config?: Configuration) {\n this.forumUrl = config?.getProperty(CORE_CONFIG_OPTIONS.FORUM_URL) || this.environment.forumUrl;\n this.helpUrl = config?.getProperty(CORE_CONFIG_OPTIONS.HELP_URL) || this.environment.helpUrl;\n }\n}\n","import {UserProfileLabel} from '../services/model/person.model';\nimport {Configuration} from '../services/model/config.model';\nimport {AccountService} from '../services/account.service';\nimport {IconRef} from '../../shared/types';\n\nexport interface MenuItem extends IconRef {\n title: string;\n path?: string;\n action?: string | any;\n profile?: UserProfileLabel;\n exactProfile?: UserProfileLabel;\n color?: string;\n cssClass?: string;\n // A config property, to enable the menu item\n ifProperty?: string;\n // A config property, to override the title\n titleProperty?: string;\n titleArgs?: {[key: string]: string};\n children?: MenuItem[];\n}\n\nexport class MenuItems {\n static checkIfVisible(item: MenuItem,\n accountService: AccountService,\n config: Configuration,\n opts?: {\n isLogin?: boolean;\n debug?: boolean;\n logPrefix?: string;\n }): boolean {\n opts = opts || {};\n if (item.profile) {\n const hasProfile = accountService.isLogin() && accountService.hasMinProfile(item.profile);\n if (!hasProfile) {\n if (opts.debug) console.debug(`${opts && opts.logPrefix || '[menu]'} Hide item '${item.title}': need the min profile '${item.profile}' to access path '${item.path}'`);\n return false;\n }\n }\n\n else if (item.exactProfile) {\n const hasExactProfile = accountService.hasExactProfile(item.exactProfile);\n if (!hasExactProfile) {\n if (opts.debug) console.debug(`${opts && opts.logPrefix || '[menu]'} Hide item '${item.title}': need exact profile '${item.exactProfile}' to access path '${item.path}'`);\n return false;\n }\n }\n\n // If enable by config\n if (item.ifProperty) {\n //console.debug(\"[menu] Checking if property enable ? \" + item.ifProperty, config && config.properties);\n const isEnableByConfig = config && config.properties[item.ifProperty] === 'true';\n if (!isEnableByConfig) {\n if (opts.debug) console.debug('[menu] Config property \\'' + item.ifProperty + '\\' not \\'true\\' for ', item.path);\n return false;\n }\n }\n\n return true;\n }\n}\n\nexport class MenuOptions {\n // TODO add options, when need specific behavior on projects\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, InjectionToken, OnDestroy, Optional } from '@angular/core';\nimport { ModalController, ToastController } from '@ionic/angular';\nimport { RegisterModal } from '../register/modal/modal-register';\nimport { BehaviorSubject, Subscription } from 'rxjs';\nimport { AccountService } from '../services/account.service';\nimport { Account, accountToString } from '../services/model/account.model';\nimport { Configuration } from '../services/model/config.model';\nimport { Department } from '../services/model/department.model';\nimport { APP_LOCALES, LocaleConfig, LocalSettings } from '../services/model/settings.model';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ConfigService } from '../services/config.service';\nimport { PlatformService } from '../services/platform.service';\nimport { LocalSettingsService } from '../services/local-settings.service';\nimport { debounceTime, distinctUntilChanged, map, startWith } from 'rxjs/operators';\nimport { AuthModal } from '../auth/modal/modal-auth';\nimport { NetworkService } from '../services/network.service';\nimport { MenuItem, MenuItems } from '../menu/menu.model';\nimport { ShowToastOptions, Toasts } from '../../shared/toast/toasts';\nimport { fadeInAnimation, slideUpDownAnimation } from '../../shared/material/material.animations';\nimport { isNotNil, isNotNilOrBlank, toBoolean } from '../../shared/functions';\nimport { Environment, ENVIRONMENT } from '../../../environments/environment.class';\nimport { HistoryPageReference } from '../services/model/history.model';\nimport { CORE_CONFIG_OPTIONS } from '../services/config/core.config';\n\nexport function getRandomImage(files: String[]) {\n const imgIndex = Math.floor(Math.random() * files.length);\n return files[imgIndex];\n}\n\nexport const APP_HOME_BUTTONS = new InjectionToken<MenuItem[]>('homeButton');\n\n@Component({\n moduleId: module.id.toString(),\n selector: 'app-page-home',\n templateUrl: 'home.html',\n styleUrls: ['./home.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [fadeInAnimation, slideUpDownAnimation]\n})\nexport class HomePage implements OnDestroy {\n\n private readonly _debug: boolean;\n private _started = false;\n private _subscription = new Subscription();\n private _config: Configuration;\n\n loading = true;\n waitingNetwork = false;\n showSpinner = true;\n accountName: String = '';\n isLogin: boolean;\n $partners = new BehaviorSubject<Department[]>(null);\n loadingBanner = true;\n logo: String;\n description: String;\n appName: string;\n isWeb: boolean;\n canRegister: boolean;\n contentStyle: any;\n pageHistory: HistoryPageReference[] = [];\n offline: boolean;\n $filteredButtons = new BehaviorSubject<MenuItem[]>(undefined);\n readonly showAccountButton: boolean;\n\n get currentLocaleCode(): string {\n return this.loading ? '' :\n (this.translate.currentLang || this.translate.defaultLang).substr(0, 2);\n }\n\n constructor(\n private accountService: AccountService,\n private modalCtrl: ModalController,\n private translate: TranslateService,\n private toastController: ToastController,\n private configService: ConfigService,\n private platform: PlatformService,\n private cd: ChangeDetectorRef,\n public network: NetworkService,\n public settings: LocalSettingsService,\n @Inject(ENVIRONMENT) protected environment: Environment,\n @Inject(APP_LOCALES) public locales: LocaleConfig[],\n @Optional() @Inject(APP_HOME_BUTTONS) public buttons: MenuItem[]\n ) {\n\n this._debug = !environment.production;\n this.showSpinner = !this.platform.started;\n this.platform.ready().then(() => this.start());\n this.showAccountButton = toBoolean(environment.account?.showAccountButton, true);\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n }\n\n async login() {\n const modal = await this.modalCtrl.create({\n component: AuthModal\n });\n return modal.present();\n }\n\n async register() {\n const modal = await this.modalCtrl.create({\n component: RegisterModal,\n backdropDismiss: false\n });\n return modal.present();\n }\n\n async logout(event: any) {\n await this.accountService.logout();\n\n // If was offline, try to reconnect (because can be a forced offline mode)\n if (this.offline) {\n await this.tryOnline();\n }\n }\n\n changeLanguage(locale: string) {\n this.settings.apply({locale})\n .then(() => {\n this.markForCheck();\n });\n }\n\n getPagePath(page: HistoryPageReference) {\n return page && page.path;\n }\n\n\n tryOnline() {\n this.waitingNetwork = true;\n this.markForCheck();\n\n this.network.tryOnline({\n showLoadingToast: false,\n showOnlineToast: true,\n showOfflineToast: false\n })\n .then(() => {\n this.waitingNetwork = false;\n this.markForCheck();\n });\n\n }\n\n /* -- protected method -- */\n\n protected async start() {\n await this.accountService.ready();\n\n this.isLogin = this.accountService.isLogin();\n if (this.isLogin) {\n this.onLogin(this.accountService.account);\n }\n\n this.offline = this.network.offline;\n\n // Listen login/logout events\n this._subscription.add(this.accountService.onLogin.subscribe(account => this.onLogin(account)));\n this._subscription.add(this.accountService.onLogout.subscribe(() => this.onLogout()));\n\n // Listen pod config\n this._subscription.add(this.configService.config.subscribe(config => this.onConfigLoaded(config)));\n\n // Listen settings changes\n this._subscription.add(\n this.settings.onChange\n .pipe(\n // Add a delay, to avoid to apply changes to often\n debounceTime(3000),\n // Start with current settings\n startWith(await this.settings.ready())\n )\n .subscribe(res => this.onSettingsChanged(res)));\n\n // Listen network changes\n this._subscription.add(\n this.network.onNetworkStatusChanges\n .pipe(\n //debounceTime(450),\n //tap(() => this.waitingNetwork = false),\n map(connectionType => connectionType === 'none'),\n distinctUntilChanged()\n )\n .subscribe(offline => {\n this.offline = offline;\n this.markForCheck();\n })\n );\n\n this._started = true;\n }\n\n protected async showToast(opts: ShowToastOptions) {\n await Toasts.show(this.toastController, this.translate, opts);\n }\n\n protected onConfigLoaded(config: Configuration) {\n console.debug('[home] Applying configuration', config);\n this._config = config;\n\n this.appName = config.label || this.environment.defaultAppName || 'SUMARiS';\n this.logo = config.largeLogo || config.smallLogo || undefined;\n this.description = config.name;\n this.isWeb = this.platform.isWeb();\n this.canRegister = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.REGISTRATION_ENABLE);\n\n const partners = (config.partners || []).filter(p => p && p.logo);\n this.$partners.next(partners);\n this.loadingBanner = (partners.length === 0);\n\n // If not already set, compute the background image\n if (!this.contentStyle) {\n const backgroundImages = (config.backgroundImages || [])\n // Filter on not nil, because can occur if detected has not exists (see config-service.js)\n .filter(img => isNotNil(img)\n // If offline, filter on local dataURL image\n && (!this.offline || !img.startsWith('http')));\n\n // Background image found: select one randomly\n if (backgroundImages.length) {\n const bgImage = getRandomImage(backgroundImages);\n this.contentStyle = bgImage && {'background-image': `url(${bgImage})`} || {};\n }\n\n // Use background color\n else {\n const primaryColor = config.properties && config.properties['sumaris.color.primary'] || 'var(--ion-color-primary)';\n this.contentStyle = primaryColor && {'background-color': primaryColor} || {};\n }\n }\n\n this.refreshButtons();\n this.markForCheck();\n\n // If first load, hide the loading indicator\n if (this.loading) {\n setTimeout(() => {\n this.loading = false;\n this.markForCheck();\n }, 500); // Add a delay, for animation\n }\n }\n\n protected onSettingsChanged(settings: LocalSettings) {\n if (settings.pageHistory !== this.pageHistory) {\n console.debug('[home] Page history loaded');\n this.pageHistory = settings.pageHistory || [];\n }\n // Always force a refresh (same history array, but content may have changed)\n this.markForCheck();\n }\n\n protected onLogin(account: Account) {\n if (!account) return; // Skip\n //console.debug('[home] Logged account: ', account);\n this.isLogin = true;\n this.accountName = accountToString(account);\n this.refreshButtons();\n this.markForCheck();\n }\n\n protected onLogout() {\n this.isLogin = false;\n this.accountName = '';\n this.pageHistory = [];\n this.refreshButtons();\n this.markForCheck();\n }\n\n protected refreshButtons() {\n if (!this._config) return; // Skip (waiting config to be loaded)\n if (this._debug) console.debug('[home] Refreshing buttons...');\n\n const filteredButtons = (this.buttons || [])\n .filter((item) => MenuItems.checkIfVisible(item, this.accountService, this._config, {\n isLogin: this.isLogin,\n debug: this._debug,\n logPrefix: '[home]'\n }))\n .map(item => {\n // Replace title using properties\n if (isNotNilOrBlank(item.titleProperty) && this._config) {\n const title = this._config.properties[item.titleProperty];\n if (title) return { ...item, title}; // Create a copy, to keep the original item.title\n }\n return item;\n });\n\n this.$filteredButtons.next(filteredButtons);\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n\n}\n","import {Component, OnDestroy} from '@angular/core';\nimport {Subscription} from 'rxjs';\nimport {ActivatedRoute} from '@angular/router';\nimport {AccountService} from '../../services/account.service';\nimport {getRandomImage} from '../../home/home';\nimport {ConfigService} from '../../services/config.service';\nimport {PlatformService} from '../../services/platform.service';\n\n@Component({\n selector: 'page-register-confirm',\n templateUrl: 'confirm.html',\n styleUrls: ['./confirm.scss']\n})\nexport class RegisterConfirmPage implements OnDestroy {\n\n subscriptions: Subscription[] = [];\n\n isLogin: boolean;\n loading = true;\n error: string;\n email: string;\n contentStyle = {};\n\n constructor(\n private platform: PlatformService,\n private accountService: AccountService,\n private activatedRoute: ActivatedRoute,\n private configService: ConfigService) {\n\n this.platform.ready().then(() => {\n this.isLogin = accountService.isLogin();\n\n // Subscriptions\n this.subscriptions.push(this.accountService.onLogin.subscribe(account => this.isLogin = true));\n this.subscriptions.push(this.accountService.onLogout.subscribe(() => this.isLogin = false));\n this.subscriptions.push(this.activatedRoute.paramMap.subscribe(params =>\n this.doConfirm(params.get('email'), params.get('code'))\n ));\n\n this.configService.config.subscribe(config => {\n\n if (config && config.backgroundImages && config.backgroundImages.length) {\n const bgImage = getRandomImage(config.backgroundImages);\n this.contentStyle = {'background-image': `url(${bgImage})`};\n } else {\n const primaryColor = config.properties && config.properties['sumaris.color.primary'] || '#144391';\n this.contentStyle = {'background-color': primaryColor};\n }\n\n this.loading = false;\n });\n });\n }\n\n ngOnDestroy() {\n this.subscriptions.forEach(s => s.unsubscribe());\n this.subscriptions = [];\n }\n\n async doConfirm(email: string, code: string) {\n this.email = email;\n\n if (!code) {\n this.loading = false;\n this.error = undefined;\n return;\n }\n\n try {\n if (this.accountService.isLogin()) {\n const account = this.accountService.account;\n const emailAccount = account && account.email;\n if (email != emailAccount) {\n // Not same email => logout, then retry\n await this.accountService.logout();\n return this.doConfirm(email, code);\n }\n }\n\n // Send the confirmation code\n const confirmed = await this.accountService.confirmEmail(email, code);\n if (confirmed && this.isLogin) {\n await this.accountService.reload();\n }\n this.loading = false;\n //this.location.replaceState(\"/confirm/\" + email + \"/\");\n }\n catch (err) {\n this.error = err && err.message || err;\n this.loading = false;\n }\n\n }\n}\n","import {ValidatorService} from '@e-is/ngx-material-table';\nimport {AbstractControl, FormBuilder, FormGroup} from '@angular/forms';\nimport {IValidatorService} from '../../../shared/services/validator-service.class';\nimport {Directive} from '@angular/core';\nimport {AppFormUtils} from '../../form/form.utils';\nimport {changeCaseToUnderscore, isEmptyArray} from '../../../shared/functions';\nimport {TranslateService} from '@ngx-translate/core';\nimport {FormErrors} from '../../../shared/forms';\n\n@Directive()\nexport abstract class AppValidatorService<T = any>\n extends ValidatorService\n implements IValidatorService<T> {\n\n protected constructor(\n protected formBuilder: FormBuilder,\n protected translate?: TranslateService\n ) {\n super();\n }\n\n getRowValidator(): FormGroup {\n return this.getFormGroup();\n }\n\n getFormGroup(data?: T): FormGroup {\n return this.formBuilder.group(this.getFormGroupConfig(data));\n }\n\n getFormGroupConfig(data?: T): { [key: string]: any} {\n return {};\n }\n\n getI18nFormErrors(control: AbstractControl): string[] {\n const errors = AppFormUtils.getFormErrors(control);\n return this.getI18nErrors(errors);\n }\n\n getI18nErrors(errors: FormErrors): string[] {\n return Object.keys(errors || {}).map(errorKey => this.getI18nError(errorKey, errors[errorKey]));\n }\n\n protected getI18nError(errorKey: string, errorContent?: any): string {\n const i18nKey = 'ERROR.FIELD_' + changeCaseToUnderscore(errorKey).toUpperCase();\n const i18nMessage = this.translate.instant(i18nKey, errorContent);\n if (i18nKey !== i18nMessage) return i18nMessage;\n if (typeof errorContent === 'string') return errorContent;\n\n // Not translated: show error\n console.error(`[validator] Cannot translate error key '${errorKey}'. Please override translateError() in your validator`);\n\n return changeCaseToUnderscore(errorKey);\n }\n}\n","import {Injectable} from '@angular/core';\nimport {FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {UserSettings} from '../model/settings.model';\nimport {AppValidatorService} from './base.validator.class';\n\n@Injectable({providedIn: 'root'})\nexport class UserSettingsValidatorService extends AppValidatorService<UserSettings> {\n\n constructor(\n formBuilder: FormBuilder\n ) {\n super(formBuilder);\n }\n\n getFormGroup(data?: UserSettings): FormGroup {\n return this.formBuilder.group({\n id: [data && data.id || null],\n updateDate: [data && data.updateDate || null],\n locale: [data && data.locale || null, Validators.required],\n latLongFormat: [data && data.latLongFormat || null, Validators.required],\n content: this.formBuilder.group({\n //usageMode: [data && data.content && data.content.usageMode || 'DESK', Validators.required],\n }),\n nonce: [data && data.nonce || null]\n });\n }\n}\n","import {Injectable} from '@angular/core';\nimport {FormBuilder, ValidatorFn, Validators} from '@angular/forms';\nimport {Account} from '../model/account.model';\nimport {PersonUtils} from '../model/person.model';\nimport {StatusIds} from '../model/model.enum';\nimport {AccountService} from '../account.service';\nimport {SharedValidators} from '../../../shared/validator/validators';\nimport {FormFieldDefinition} from '../../../shared/form/field.model';\nimport {AppValidatorService} from './base.validator.class';\n\n@Injectable({providedIn: 'root'})\nexport class AccountValidatorService extends AppValidatorService<Account> {\n\n constructor(\n protected formBuilder: FormBuilder,\n protected accountService: AccountService\n ) {\n super(formBuilder);\n }\n\n getFormGroupConfig(data?: Account): any {\n const formDef = {\n id: [''],\n updateDate: [''],\n creationDate: [''],\n lastName: [data && data.lastName || null, Validators.compose([Validators.required, Validators.minLength(2)])],\n firstName: [data && data.firstName || null, Validators.compose([Validators.required, Validators.minLength(2)])],\n email: [data && data.email || null, Validators.compose([Validators.required, Validators.email])],\n mainProfile: [data && (data.mainProfile || PersonUtils.getMainProfile(data.profiles)) || 'GUEST', Validators.required],\n statusId: [data && data.statusId || StatusIds.TEMPORARY, Validators.required],\n pubkey: [data && data.pubkey || null, Validators.compose([Validators.required, SharedValidators.pubkey])]\n };\n\n // Add additional fields\n this.accountService.additionalFields.forEach(field => {\n //console.debug(\"[register-form] Add additional field {\" + field.name + \"} to form\", field);\n formDef[field.key] = [data && data[field.key] || null, this.getValidators(field)];\n });\n\n return formDef;\n }\n\n getValidators(field: FormFieldDefinition): ValidatorFn | ValidatorFn[] {\n const validatorFns: ValidatorFn[] = [];\n if (field.extra && field.extra.account && field.extra.account.required) {\n validatorFns.push(Validators.required);\n }\n if (field.type === 'entity') {\n validatorFns.push(SharedValidators.entity);\n }\n\n return validatorFns.length ? Validators.compose(validatorFns) : validatorFns.length === 1 ? validatorFns[0] : undefined;\n }\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Injector, OnDestroy} from '@angular/core';\nimport {Subscription} from 'rxjs';\nimport {AccountService} from '../services/account.service';\nimport {Account} from '../services/model/account.model';\nimport {UserSettingsValidatorService} from '../services/validator/user-settings.validator';\nimport {FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {AccountValidatorService} from '../services/validator/account.validator';\nimport {AppForm} from '../form/form.class';\nimport {AppFormUtils} from '../form/form.utils';\nimport {TranslateService} from '@ngx-translate/core';\nimport {FormFieldDefinition} from '../../shared/form/field.model';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {LAT_LONG_PATTERNS} from '../../shared/material/latlong/latlong.utils';\nimport {StatusIds} from '../services/model/model.enum';\nimport {APP_LOCALES, LocaleConfig} from '../services/model/settings.model';\nimport {Router} from '@angular/router';\nimport {CanLeave} from '../../shared/guard/component-dirty.guard';\nimport {NetworkService} from '../services/network.service';\nimport {map} from 'rxjs/operators';\n\n@Component({\n selector: 'app-page-account',\n templateUrl: 'account.html',\n styleUrls: ['./account.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AccountPage extends AppForm<Account> implements OnDestroy, CanLeave {\n\n isLogin: boolean;\n changesSubscription: Subscription;\n networkSubscription: Subscription;\n account: Account;\n email: any = {\n confirmed: false,\n notConfirmed: false,\n sending: false,\n error: undefined\n };\n additionalFields: FormFieldDefinition[];\n settingsForm: FormGroup;\n settingsContentForm: FormGroup;\n locales: LocaleConfig[];\n latLongFormats = LAT_LONG_PATTERNS;\n saving = false;\n submitted = false;\n\n constructor(\n injector: Injector,\n public formBuilder: FormBuilder,\n public accountService: AccountService,\n public network: NetworkService,\n protected router: Router,\n protected validatorService: AccountValidatorService,\n protected settingsValidatorService: UserSettingsValidatorService,\n protected translate: TranslateService,\n protected settings: LocalSettingsService,\n protected cd: ChangeDetectorRef,\n @Inject(APP_LOCALES) locales\n ) {\n super(injector, validatorService.getFormGroup(accountService.account));\n\n this.locales = locales;\n\n // Add settings fo form\n this.settingsForm = settingsValidatorService.getFormGroup(accountService.account && accountService.account.settings);\n this.settingsContentForm = (this.settingsForm.controls['content'] as FormGroup);\n this.form.addControl('settings', this.settingsForm);\n\n // By default, disable the form\n this.disable();\n\n // Observed some events\n this.registerSubscription(this.accountService.onLogin.subscribe(account => this.onLogin(account)));\n this.registerSubscription(this.accountService.onLogout.subscribe(() => this.onLogout()));\n this.registerSubscription(this.onCancel.subscribe(() => {\n this.setValue(this.accountService.account);\n this.markAsPristine();\n }));\n\n this.registerSubscription(this.accountService.$additionalFields\n .subscribe((additionalFields) => {\n this.additionalFields = additionalFields.slice(); // Copy\n if (accountService.isLogin()) {\n this.onLogin(this.accountService.account);\n }\n else {\n this.markAsLoaded();\n }\n }));\n }\n\n ngOnDestroy() {\n super.ngOnDestroy();\n this.stopListenChanges();\n this.networkSubscription?.unsubscribe();\n }\n\n onLogin(account: Account) {\n console.debug('[account] Logged account: ', account);\n this.isLogin = true;\n\n this.setValue(account);\n\n this.email.confirmed = account && account.email && (account.statusId !== StatusIds.TEMPORARY);\n this.email.notConfirmed = account && account.email && (!account.statusId || account.statusId === StatusIds.TEMPORARY);\n\n this.networkSubscription?.unsubscribe();\n this.networkSubscription = this.network.onNetworkStatusChanges\n .pipe(\n map(connectionType => connectionType !== 'none'),\n )\n .subscribe(online => {\n if (online) {\n this.enable();\n this.markAsPristine();\n this.startListenChanges();\n }\n else {\n this.disable();\n this.markAsPristine();\n this.stopListenChanges();\n }\n this.markAsLoaded();\n });\n }\n\n onLogout() {\n this.isLogin = false;\n this.email.confirmed = false;\n this.email.notConfirmed = false;\n this.email.sending = false;\n this.email.error = undefined;\n this.form.reset();\n this.disable();\n\n this.networkSubscription?.unsubscribe();\n\n this.stopListenChanges();\n\n // Back to home\n this.router.navigateByUrl('/');\n\n }\n\n async refresh(event?: UIEvent) {\n\n this.disable();\n this.markAsLoading();\n\n return this.accountService.reload();\n }\n\n startListenChanges() {\n if (this.changesSubscription) return; // already started\n this.changesSubscription = this.accountService.listenChanges();\n }\n\n stopListenChanges() {\n if (!this.changesSubscription) return;\n this.changesSubscription.unsubscribe();\n this.changesSubscription = undefined;\n }\n\n async sendConfirmationEmail(event: MouseEvent) {\n const json = this.form.value;\n json.email = this.form.controls['email'].value;\n if (!json.email || !this.email.notConfirmed) {\n event.preventDefault();\n return false;\n }\n\n this.email.sending = true;\n console.debug('[account] Sending confirmation email...');\n try {\n await this.accountService.sendConfirmationEmail(\n json.email,\n json.settings && json.settings.locale || this.translate.currentLang\n );\n console.debug('[account] Confirmation email sent.');\n this.email.sending = false;\n }\n catch (err) {\n this.email.sending = false;\n this.email.error = err && err.message || err;\n }\n }\n\n async save(event: MouseEvent): Promise<boolean> {\n if (this.saving) return false;\n\n if (!this.form.valid) {\n await AppFormUtils.waitWhilePending(this.form);\n\n if (this.form.invalid) {\n AppFormUtils.logFormErrors(this.form);\n this.form.markAllAsTouched();\n return false;\n }\n }\n\n this.submitted = true;\n this.saving = true;\n this.error = undefined;\n\n const newAccount = Account.fromObject({\n ...(this.accountService.account.asObject()),\n ...(this.form.value)\n });\n\n console.debug('[account] Saving account...', newAccount);\n try {\n this.disable();\n\n await this.accountService.save(newAccount);\n\n this.markAsPristine();\n return true;\n }\n catch (err) {\n console.error(err);\n this.error = err && err.message || err;\n return false;\n }\n finally {\n this.saving = false;\n this.enable();\n }\n }\n\n enable() {\n super.enable();\n\n // Some fields are always disable\n this.form.controls.email.disable();\n this.form.controls.mainProfile.disable();\n this.form.controls.pubkey.disable();\n\n // Always disable some additional fields\n this.additionalFields\n .forEach(field => {\n const control = this.form.controls[field.key];\n if (!control) return; // Skip\n\n const disabled = field.extra?.account && field.extra.account.disabled || false;\n if (disabled && control.enabled) {\n control.disable();\n }\n const required = field.extra?.account && field.extra.account.required || false;\n if (!field.required && required) {\n control.setValidators(control.validator\n ? Validators.compose([control.validator, Validators.required])\n : Validators.required)\n }\n\n });\n this.markForCheck();\n }\n\n async cancel() {\n await super.cancel();\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n}\n","import {ChangeDetectionStrategy, Component, Input, OnInit} from '@angular/core';\nimport {Entity} from '../services/model/entity.model';\n// import fade in animation\nimport {fadeInAnimation} from '../../shared/material/material.animations';\nimport {Moment} from 'moment';\nimport {toBoolean} from '../../shared/functions';\n\n@Component({\n selector: 'app-entity-metadata',\n templateUrl: './entity-metadata.component.html',\n styleUrls: ['./entity-metadata.component.scss'],\n animations: [fadeInAnimation],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class EntityMetadataComponent {\n\n @Input() value: Entity<any> & {creationDate?: Date | Moment; recorderDepartment?: any; recorderPerson?: any};\n\n @Input() showRecorder = true;\n}\n","import {Injectable} from '@angular/core';\nimport {BehaviorSubject, Observable, Subject} from 'rxjs';\nimport {distinctUntilChanged} from 'rxjs/operators';\n\n\nexport type SplitPaneShowWhen = boolean|'lg';\nexport const DEFAULT_MENU_SHOW_WHEN: SplitPaneShowWhen = 'lg';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MenuService {\n\n private readonly _$toggled = new Subject<void>();\n private readonly _$opened = new Subject<boolean>();\n private readonly _$splitPaneWhen = new BehaviorSubject<SplitPaneShowWhen>(DEFAULT_MENU_SHOW_WHEN);\n private readonly _$enabled = new BehaviorSubject<boolean>(true);\n\n get opened(): Observable<boolean> {\n return this._$opened.asObservable();\n }\n\n get splitPaneWhen(): Observable<SplitPaneShowWhen> {\n return this._$splitPaneWhen.asObservable();\n }\n\n get enabled(): Observable<boolean> {\n return this._$enabled.asObservable();\n }\n\n toggle() {\n this._$toggled.next();\n }\n\n enable(value: boolean) {\n this._$enabled.next(value);\n }\n\n setSplitPaneShowWhen(value: SplitPaneShowWhen) {\n if (this._$splitPaneWhen.value !== value) {\n this._$splitPaneWhen.next(value);\n }\n }\n\n toggleSplitPaneWhen() {\n if (this._$splitPaneWhen.value !== false) {\n this._$splitPaneWhen.next(false);\n }\n else {\n this._$splitPaneWhen.next(DEFAULT_MENU_SHOW_WHEN);\n }\n }\n\n _markAsOpened() {\n this._$opened.next(true);\n }\n\n _markAsClosed() {\n this._$opened.next(false);\n }\n\n}\n","import {Component, EventEmitter, Input, OnDestroy, Output} from '@angular/core';\nimport {Hotkeys} from '../../shared/hotkeys/hotkeys.service';\nimport {Subscription} from 'rxjs';\nimport {filter, tap} from 'rxjs/operators';\nimport {MenuService} from '../menu/menu.service';\n\nexport abstract class FormButtonsBarToken {\n abstract onCancel: EventEmitter<Event>;\n abstract onSave: EventEmitter<Event>;\n abstract onNext: EventEmitter<Event>;\n abstract onBack: EventEmitter<Event>;\n}\n\n@Component({\n selector: 'app-form-buttons-bar',\n templateUrl: './form-buttons-bar.component.html',\n styleUrls: ['./form-buttons-bar.component.scss'],\n providers: [\n {provide: FormButtonsBarToken, useExisting: FormButtonsBarComponent}\n ],\n})\nexport class FormButtonsBarComponent implements FormButtonsBarToken, OnDestroy {\n\n private _subscription = new Subscription();\n\n @Input() disabled = false;\n @Input() disabledCancel = false;\n @Input() classList: string;\n\n @Output() onCancel = new EventEmitter<Event>();\n @Output() onSave = new EventEmitter<Event>();\n @Output() onNext = new EventEmitter<Event>();\n @Output() onBack = new EventEmitter<Event>();\n\n constructor(private hotkeys: Hotkeys,\n public menu: MenuService\n ) {\n\n // Ctrl+S\n this._subscription.add(\n hotkeys.addShortcut({keys: 'control.s', description: 'COMMON.BTN_SAVE'})\n .pipe(filter(e => !this.disabled))\n .subscribe((event) => this.onSave.emit(event)));\n\n // Ctrl+Z\n this._subscription.add(\n hotkeys.addShortcut({keys: 'control.z', description: 'COMMON.BTN_RESET'})\n .pipe(filter(e => !this.disabled && !this.disabledCancel))\n .subscribe((event) => this.onCancel.emit(event))\n );\n\n // Escape\n this._subscription.add(\n hotkeys.addShortcut({keys: 'escape', description: 'COMMON.BTN_CLOSE', preventDefault: false})\n .pipe(\n filter(e => !e.defaultPrevented),\n //tap(() => console.debug('[form-buttons-bar] Emit back event (keydown.escape)'))\n )\n .subscribe((event) => this.onBack.emit(event)));\n }\n\n ngOnDestroy(): void {\n this._subscription.unsubscribe();\n this.onCancel.complete();\n this.onSave.complete();\n this.onNext.complete();\n this.onBack.complete();\n }\n\n}\n","import {Component, Input, OnInit} from '@angular/core';\nimport {ModalController, NavParams} from '@ionic/angular';\nimport {toBoolean} from '../../shared/functions';\n\nexport declare interface ColumnItem {\n name?: string;\n label: string;\n visible: boolean;\n canHide?: boolean;\n}\n\n@Component({\n selector: 'table-select-columns',\n templateUrl: './table-select-columns.component.html'\n})\nexport class TableSelectColumnsComponent implements OnInit {\n\n @Input() columns: ColumnItem[];\n\n @Input() canHideColumns = true;\n\n constructor(\n private navParams: NavParams,\n private viewCtrl: ModalController) {\n }\n\n ngOnInit() {\n this.columns = this.columns || this.navParams.data && this.navParams.data.columns || [];\n\n this.columns.forEach(c => {\n // If cannot hide columns, make sure all columns are set to visible\n c.visible = (this.canHideColumns === false && true/*always visible*/) || c.visible;\n c.canHide = toBoolean(c.canHide, this.canHideColumns);\n });\n }\n\n onRenderItems(event: CustomEvent<{ from: number; to: number; complete: () => {} }>) {\n const element = this.columns.splice(event.detail.from, 1)[0];\n this.columns.splice(event.detail.to, 0, element);\n event.detail.complete();\n }\n\n close() {\n this.viewCtrl.dismiss(this.columns);\n }\n\n cancel() {\n this.viewCtrl.dismiss();\n }\n}\n","import {Component, EventEmitter, Inject, OnInit, Output, ViewChild} from '@angular/core';\nimport {\n AbstractControl,\n AsyncValidatorFn,\n FormBuilder,\n FormControl,\n FormGroup,\n ValidationErrors,\n ValidatorFn,\n Validators\n} from '@angular/forms';\nimport {AccountService, RegisterData} from '../../services/account.service';\nimport {Account} from '../../services/model/account.model';\nimport {referentialToString} from '../../services/model/referential.model';\nimport {MatHorizontalStepper} from '@angular/material/stepper';\nimport {Observable, Subscription, timer} from 'rxjs';\nimport {AccountValidatorService} from '../../services/validator/account.validator';\nimport {FormFieldDefinition} from '../../../shared/form/field.model';\nimport {mergeMap} from 'rxjs/operators';\nimport {LocalSettingsService} from '../../services/local-settings.service';\nimport {MatAutocompleteConfigHolder} from '../../../shared/material/autocomplete/material.autocomplete';\nimport {ENVIRONMENT} from '../../../../environments/environment.class';\n\n\n@Component({\n selector: 'form-register',\n templateUrl: 'form-register.html',\n styleUrls: ['./form-register.scss']\n})\nexport class RegisterForm implements OnInit {\n\n protected debug = false;\n\n autocompleteHelper: MatAutocompleteConfigHolder;\n additionalFields: FormFieldDefinition[];\n form: FormGroup;\n forms: FormGroup[];\n subscriptions: Subscription[] = [];\n error: string;\n sending = false;\n\n showPwd = false;\n showConfirmPwd = false;\n\n @ViewChild('stepper', { static: true }) private stepper: MatHorizontalStepper;\n\n @Output()\n onCancel = new EventEmitter<any>();\n\n @Output()\n onSubmit = new EventEmitter<RegisterData>();\n\n constructor(\n private accountService: AccountService,\n private accountValidatorService: AccountValidatorService,\n public formBuilder: FormBuilder,\n @Inject(ENVIRONMENT) protected environment,\n protected settings?: LocalSettingsService\n ) {\n\n\n this.forms = [];\n // Email form\n this.forms.push(formBuilder.group({\n email: new FormControl(null, Validators.compose([Validators.required, Validators.email]), this.emailAvailability(this.accountService)),\n confirmEmail: new FormControl(null, Validators.compose([Validators.required, this.equalsValidator('email')]))\n }));\n\n // Password form\n this.forms.push(formBuilder.group({\n password: new FormControl(null, Validators.compose([Validators.required, Validators.minLength(8)])),\n confirmPassword: new FormControl(null, Validators.compose([Validators.required, this.equalsValidator('password')]))\n }));\n\n // Detail form\n const formDetailDef = {\n lastName: new FormControl(null, Validators.compose([Validators.required, Validators.minLength(2)])),\n firstName: new FormControl(null, Validators.compose([Validators.required, Validators.minLength(2)]))\n };\n\n // Prepare autocomplete settings\n this.autocompleteHelper = new MatAutocompleteConfigHolder(settings && {\n getUserAttributes: (a, b) => settings.getFieldDisplayAttributes(a, b)\n });\n\n\n // Add additional fields to details form\n this.additionalFields = this.accountService.additionalFields\n // Keep only required fields\n .filter(field => field.extra && field.extra.registration && field.extra.registration.required);\n this.additionalFields.forEach(field => {\n //if (this.debug) console.debug(\"[register-form] Add additional field {\" + field.name + \"} to form\", field);\n formDetailDef[field.key] = new FormControl(null, this.accountValidatorService.getValidators(field));\n\n if (field.type === 'entity') {\n field.autocomplete = this.autocompleteHelper.add(field.key, field.autocomplete);\n }\n\n });\n\n this.forms.push(formBuilder.group(formDetailDef));\n\n this.form = formBuilder.group({\n emailStep: this.forms[0],\n passwordStep: this.forms[1],\n detailsStep: this.forms[2]\n });\n }\n\n ngOnInit() {\n // For DEV only ------------------------\n if (!this.environment.production) {\n this.form.setValue({\n emailStep: {\n email: 'contact@e-is.pro',\n confirmEmail: 'contact@e-is.pro'\n },\n passwordStep: {\n password: 'contactera',\n confirmPassword: 'contactera'\n },\n detailsStep: {\n lastName: 'Lavenier 2',\n firstName: 'Benoit',\n department: null\n }\n });\n }\n }\n\n get value(): RegisterData {\n const result: RegisterData = {\n username: this.form.value.emailStep.email,\n password: this.form.value.passwordStep.password,\n account: new Account()\n };\n result.account.fromObject(this.form.value.detailsStep);\n result.account.email = result.username;\n\n return result;\n }\n\n get valid(): boolean {\n return this.form.valid;\n }\n\n isEnd(): boolean {\n return this.stepper.selectedIndex === 2;\n }\n\n isBeginning(): boolean {\n return this.stepper.selectedIndex === 0;\n }\n\n slidePrev() {\n return this.stepper.previous();\n }\n\n slideNext(event?: UIEvent) {\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n return this.stepper.next();\n }\n\n equalsValidator(otherControlName: string): ValidatorFn {\n return function(c: AbstractControl): ValidationErrors | null {\n if (c.parent && c.value !== c.parent.value[otherControlName]) {\n return {\n equals: true\n };\n }\n return null;\n };\n }\n\n emailAvailability(accountService: AccountService): AsyncValidatorFn {\n return function(control: AbstractControl): Observable<ValidationErrors | null> {\n\n return timer(500).pipe(mergeMap(() => accountService.checkEmailAvailable(control.value)\n .then(res => null)\n .catch(err => {\n console.error(err);\n return { availability: true };\n })));\n };\n }\n\n cancel() {\n this.onCancel.emit();\n }\n\n doSubmit(event?: any) {\n if (this.form.invalid) return;\n this.sending = true;\n this.onSubmit.emit(this.value);\n }\n\n referentialToString = referentialToString;\n\n markAsTouched() {\n this.form.markAsTouched();\n }\n\n disable() {\n this.form.disable();\n }\n\n enable() {\n this.form.enable();\n }\n}\n","import {NgModule} from '@angular/core';\nimport {HttpClientModule} from '@angular/common/http';\n\n@NgModule({\n imports: [\n HttpClientModule\n ],\n exports: [\n HttpClientModule\n ]\n})\nexport class AppGraphQLModule {\n\n constructor() {\n }\n}\n\n","import {Injectable} from '@angular/core';\nimport {AbstractControl, FormBuilder, FormGroup, ValidationErrors, Validators} from '@angular/forms';\nimport {EntityUtils} from '../model/entity.model';\nimport {LocalSettings} from '../model/settings.model';\nimport {SharedValidators} from '../../../shared/validator/validators';\nimport {NetworkService} from '../network.service';\nimport {AppValidatorService} from './base.validator.class';\n\n@Injectable({providedIn: 'root'})\nexport class LocalSettingsValidatorService extends AppValidatorService<LocalSettings> {\n\n constructor(\n formBuilder: FormBuilder,\n private networkService: NetworkService\n ) {\n super(formBuilder);\n }\n\n getFormGroup(data?: LocalSettings): FormGroup {\n return this.formBuilder.group({\n accountInheritance: [data && data.accountInheritance || true, Validators.required],\n locale: [data && data.locale || null, Validators.required],\n latLongFormat: [data && data.latLongFormat || null, Validators.required],\n usageMode: [data && data.usageMode || 'DESK', Validators.required],\n peerUrl: [data && data.peerUrl, Validators.required],\n properties: this.getPropertiesArray(data && data.properties)\n }, {\n asyncValidators: (group: FormGroup) => this.peerAlive(group.get('peerUrl'))\n });\n }\n\n getPropertiesArray(array?: any) {\n const properties = EntityUtils.getMapAsArray(array || {});\n return this.formBuilder.array(\n properties.map(item => this.getPropertyFormGroup(item))\n );\n }\n\n getPropertyFormGroup(data?: {key: string; value?: string}): FormGroup {\n return this.formBuilder.group({\n key: [data && data.key || null, Validators.compose([Validators.required, Validators.max(50)])],\n value: [data && data.value || null, Validators.compose([Validators.required, Validators.max(100)])]\n });\n }\n\n /* -- protected methods -- */\n\n protected async peerAlive(peerUrlControl: AbstractControl): Promise<ValidationErrors | null> {\n\n // Offline mode: no error\n if (this.networkService.offline) {\n SharedValidators.clearError(peerUrlControl, 'peerAlive');\n }\n else {\n const alive = await this.networkService.checkPeerAlive(peerUrlControl.value);\n // KO: add a validation error\n if (!alive) {\n const errors: ValidationErrors = peerUrlControl.errors || {};\n errors['peerAlive'] = true;\n peerUrlControl.setErrors(errors);\n peerUrlControl.markAsTouched({onlySelf: true});\n // Return the error (should be apply to the parent form)\n return { peerAlive: true};\n }\n // OK: remove the existing on control\n else {\n SharedValidators.clearError(peerUrlControl, 'peerAlive');\n }\n }\n }\n\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Injector, OnDestroy, OnInit} from '@angular/core';\nimport {AccountService} from '../services/account.service';\nimport {EntityUtils} from '../services/model/entity.model';\nimport {APP_LOCALES, LocaleConfig, LocalSettings, UsageMode} from '../services/model/settings.model';\nimport {Peer} from '../services/model/peer.model';\nimport {FormArray, FormBuilder, FormControl, FormGroup} from '@angular/forms';\nimport {AppForm} from '../form/form.class';\nimport {AppFormUtils, FormArrayHelper} from '../form/form.utils';\nimport {TranslateService} from '@ngx-translate/core';\nimport {ValidatorService} from '@e-is/ngx-material-table';\nimport {LocalSettingsValidatorService} from '../services/validator/local-settings.validator';\nimport {PlatformService} from '../services/platform.service';\nimport {NetworkService} from '../services/network.service';\nimport {isNil, isNilOrBlank, toBoolean} from '../../shared/functions';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {FormFieldDefinition, FormFieldDefinitionMap} from '../../shared/form/field.model';\nimport {merge} from 'rxjs';\nimport {AlertController} from '@ionic/angular';\nimport {Alerts} from '../../shared/alerts';\nimport {Property} from '../../shared/types';\nimport {Router} from '@angular/router';\nimport {CanLeave} from '../../shared/guard/component-dirty.guard';\n\n@Component({\n selector: 'page-settings',\n templateUrl: 'settings.page.html',\n providers: [\n {provide: ValidatorService, useExisting: LocalSettingsValidatorService},\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SettingsPage extends AppForm<LocalSettings> implements OnInit, OnDestroy, CanLeave {\n\n private data: LocalSettings;\n\n mobile: boolean;\n saving = false;\n usageModes: UsageMode[] = ['FIELD', 'DESK'];\n\n propertyDefinitions: FormFieldDefinition[];\n propertyDefinitionsByKey: FormFieldDefinitionMap = {};\n propertyDefinitionsByIndex: { [index: number]: FormFieldDefinition } = {};\n propertiesFormHelper: FormArrayHelper<Property>;\n\n latLongFormats = ['DDMMSS', 'DDMM', 'DD'];\n\n get accountInheritance(): boolean {\n return this.form.controls['accountInheritance'].value;\n }\n\n get isLogin(): boolean {\n return this.accountService.isLogin();\n }\n\n get propertiesForm(): FormArray {\n return this.form.get('properties') as FormArray;\n }\n\n constructor(\n injector: Injector,\n protected platform: PlatformService,\n protected router: Router,\n protected validatorService: LocalSettingsValidatorService,\n protected alertCtrl: AlertController,\n protected translate: TranslateService,\n protected formBuilder: FormBuilder,\n protected accountService: AccountService,\n protected settings: LocalSettingsService,\n protected cd: ChangeDetectorRef,\n public network: NetworkService,\n @Inject(APP_LOCALES) public locales: LocaleConfig[]\n ) {\n super(injector, validatorService.getFormGroup());\n\n this.propertiesFormHelper = new FormArrayHelper<Property>(\n this.form.get('properties') as FormArray,\n (value) => this.validatorService.getPropertyFormGroup(value),\n (v1, v2) => (!v1 && !v2) || (v1.key === v2.key),\n (value) => isNil(value) || (isNil(value.key) && isNil(value.value)),\n {\n allowEmptyArray: true\n }\n );\n\n this.mobile = this.platform.mobile;\n\n // By default, disable the form\n this._enable = false;\n }\n\n async ngOnInit() {\n super.ngOnInit();\n\n // Make sure platform is ready\n await this.platform.ready();\n\n this.propertyDefinitions = this.settings.optionDefs.slice(); // copy options\n this.propertyDefinitions.forEach(o => this.propertyDefinitionsByKey[o.key] = o); // fill map\n\n // Load settings\n await this.load();\n\n this.registerSubscription(\n merge(\n this.accountService.onLogin,\n this.accountService.onLogout\n )\n .subscribe(() => this.setAccountInheritance(this.accountInheritance)));\n }\n\n getPropertyDefinition(index: number): FormFieldDefinition {\n let definition = this.propertyDefinitionsByIndex[index];\n if (!definition) {\n definition = this.updatePropertyDefinition(index);\n this.propertyDefinitionsByIndex[index] = definition;\n }\n return definition;\n }\n\n updatePropertyDefinition(index: number): FormFieldDefinition {\n const key = (this.propertiesForm.at(index) as FormGroup).controls.key.value;\n const definition = key && this.propertyDefinitionsByKey[key] || null;\n this.propertyDefinitionsByIndex[index] = definition; // update map by index\n this.markForCheck();\n return definition;\n }\n\n removePropertyAt(index: number) {\n this.propertiesFormHelper.removeAt(index);\n this.propertyDefinitionsByIndex = {}; // clear cache by index\n this.markForCheck();\n }\n\n async load() {\n\n this.markAsLoading();\n console.debug('[settings] Loading settings...');\n\n const data = this.settings.settings;\n\n // Set defaults\n data.accountInheritance = toBoolean(data.accountInheritance, true);\n data.locale = data.locale || this.translate.currentLang || this.translate.defaultLang;\n data.latLongFormat = data.latLongFormat || 'DDMMSS';\n data.usageMode = data.usageMode || 'DESK';\n\n // Set peer\n if (isNilOrBlank(data.peerUrl)) {\n await this.network.ready();\n const peer = this.network.peer;\n data.peerUrl = peer && peer.url;\n }\n\n // Remember data\n this.updateView(data);\n }\n\n updateView(data: LocalSettings) {\n if (!data) return; //skip\n this.data = data;\n\n const json: any = {...data};\n\n // Transform properties map into array\n json.properties = EntityUtils.getMapAsArray(data.properties || {});\n this.propertiesFormHelper.resize(json.properties.length);\n\n this.form.patchValue(json, {emitEvent: false});\n this.markAsPristine();\n\n this.enable({emitEvent: false});\n\n // Apply inheritance\n this.setAccountInheritance(data.accountInheritance, {emitEvent: false});\n\n this.markAsLoaded();\n this.error = null;\n this.markForCheck();\n }\n\n async save(event?: Event, options?: any): Promise<boolean> {\n if (this.saving) return; // Skip\n\n if (event) event.preventDefault()\n\n // Remove all empty controls\n this.propertiesFormHelper.removeAllEmpty();\n\n if (!this.form.valid) {\n await AppFormUtils.waitWhilePending(this.form);\n\n if (this.form.invalid) {\n AppFormUtils.logFormErrors(this.form);\n this.form.markAllAsTouched();\n return;\n }\n }\n\n console.debug('[settings] Saving local settings...');\n\n this.saving = true;\n this.error = undefined;\n this.markForCheck();\n\n const data = await this.getValue();\n\n // Check peer alive, before saving\n const peerChanged = this.form.get('peerUrl').dirty;\n\n // Clean page history, when peer changed\n if (peerChanged) data.pageHistory = [];\n\n try {\n this.disable();\n\n await this.settings.apply(data);\n this.data = data;\n this.markAsPristine();\n\n // If peer changed\n if (peerChanged) {\n // Restart the network\n this.network.peer = Peer.parseUrl(data.peerUrl);\n }\n\n return true;\n } catch (err) {\n console.error(err);\n this.error = err && err.message || err;\n return false;\n } finally {\n this.enable({emitEvent: false});\n\n // Apply inheritance\n this.setAccountInheritance(data.accountInheritance, {emitEvent: false});\n\n // Add a delay, because of option menu that is always opened after save!!\n setTimeout(() => {\n this.saving = false;\n this.markForCheck();\n }, 400);\n }\n }\n\n\n setAccountInheritance(enable: boolean, opts?: { emitEvent?: boolean }) {\n // Make sure to update the value in control\n this.form.controls['accountInheritance'].setValue(enable, opts);\n if (this.data.accountInheritance !== enable) {\n this.form.controls['accountInheritance'].markAsDirty({onlySelf: false});\n }\n\n if (enable) {\n if (this.isLogin) {\n // Force using account settings\n const account = this.accountService.account;\n\n // Copy values\n if (account.settings) {\n if (account.settings.locale) this.form.get('locale').setValue(account.settings.locale, opts);\n if (account.settings.latLongFormat) this.form.get('latLongFormat').setValue(account.settings.latLongFormat, opts);\n }\n // Disable fields\n this.form.get('locale').disable(opts);\n this.form.get('latLongFormat').disable(opts);\n } else {\n // Enable fields\n this.form.get('locale').enable(opts);\n this.form.get('latLongFormat').enable(opts);\n }\n } else {\n // Restore previous values\n this.form.get('locale').setValue(this.data.locale, opts);\n this.form.get('latLongFormat').setValue(this.data.latLongFormat, opts);\n\n // Enable fields\n this.form.get('locale').enable(opts);\n this.form.get('latLongFormat').enable(opts);\n }\n\n // Mark for check, if need\n if (!opts || opts.emitEvent) {\n this.markForCheck();\n }\n }\n\n async showSelectPeerModal(opts?: {\n allowSelectDownPeer?: boolean;\n canCancel?: boolean;\n }) {\n const peer = await this.network.showSelectPeerModal(opts);\n if (peer && peer.url) {\n const control = this.form.get('peerUrl') as FormControl;\n control.setValue(peer.url, {emitEvent: true, onlySelf: false});\n control.markAsDirty({onlySelf: false});\n this.markAsDirty();\n }\n }\n\n async cancel(event?: Event) {\n await this.load();\n }\n\n async close(event?: Event) {\n if (this.saving) return;\n\n // Back to home\n return this.router.navigateByUrl('/', { replaceUrl: true }); // back to home\n }\n\n async clearCache(event?: UIEvent) {\n const confirm = await Alerts.askActionConfirmation(this.alertCtrl, this.translate, true, event);\n if (confirm) {\n await this.network.clearCache();\n this.settings.removeOfflineFeatures();\n }\n }\n\n /* -- protected functions -- */\n\n protected async getValue(): Promise<LocalSettings> {\n const json = await this.getJsonValueToSave();\n\n // Override properties from account\n if (json.accountInheritance && this.isLogin) {\n const account = this.accountService.account;\n const userSettings = account && account.settings;\n console.debug(`[settings] Applying account inheritance {locale: '${userSettings.locale}', latLongFormat: '${userSettings.latLongFormat}'}...`);\n json.locale = userSettings.locale || json.locale;\n json.latLongFormat = userSettings.latLongFormat || json.latLongFormat;\n }\n\n return json;\n }\n\n protected getJsonValueToSave(): Promise<any> {\n const json = this.form.value;\n json.properties = EntityUtils.getPropertyArrayAsObject(json.properties);\n\n return Promise.resolve(json);\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Injector, Input, OnInit, Optional} from '@angular/core';\nimport {FormArray, FormBuilder, FormGroup, FormGroupDirective, Validators} from '@angular/forms';\nimport {EntityUtils} from '../services/model/entity.model';\nimport {FormFieldDefinition, FormFieldDefinitionMap} from '../../shared/form/field.model';\nimport {isEmptyArray, isNil} from '../../shared/functions';\nimport {DateAdapter} from '@angular/material/core';\nimport {Moment} from 'moment';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {AppForm} from './form.class';\nimport {FormArrayHelper, FormArrayHelperOptions} from './form.utils';\nimport {Property} from '../../shared/types';\n\n@Component({\n selector: 'app-properties-form',\n templateUrl: 'properties.form.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppPropertiesForm<T = Property> extends AppForm<T[]> implements OnInit {\n\n definitionsMapByKey: FormFieldDefinitionMap = {};\n definitionsByIndex: { [index: number]: FormFieldDefinition } = {};\n helper: FormArrayHelper<Property>;\n\n @Input() formArrayName: string;\n\n @Input() formArray: FormArray;\n\n @Input() options: FormArrayHelperOptions;\n\n @Input() definitions: FormFieldDefinition[];\n\n set value(data: T[]) {\n this.setValue(data);\n }\n\n get value(): T[] {\n return this.formArray.value as T[];\n }\n\n get fieldForms(): FormGroup[] {\n return this.formArray.controls as FormGroup[];\n }\n\n constructor(\n injector: Injector,\n protected formBuilder: FormBuilder,\n protected dateAdapter: DateAdapter<Moment>,\n protected settings: LocalSettingsService,\n protected cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n super(injector,\n null);\n\n //this.debug = !environment.production;\n }\n\n ngOnInit() {\n if (isEmptyArray(this.definitions)) {\n throw new Error('Missing or invalid attribute \\'definitions\\'');\n }\n\n // Fill options map\n this.definitionsMapByKey = {};\n this.definitions.forEach(o => {\n this.definitionsMapByKey[o.key] = o;\n });\n\n // Retrieve the form\n const form = (this.formArray && this.formArray.parent as FormGroup || this.formGroupDir && this.formGroupDir.form || this.formBuilder.group({}));\n this.setForm(form);\n\n this.formArray = this.formArray || this.formArrayName && form.get(this.formArrayName) as FormArray;\n this.formArrayName = this.formArrayName || this.formArray && Object.keys(form.controls).find(key => form.get(key) === this.formArray) || 'properties';\n if (!this.formArray) {\n console.warn(`Missing array control '${this.formArrayName}'. Will create it!`);\n this.formArray = this.formBuilder.array([]);\n this.form.addControl(this.formArrayName, this.formArray);\n }\n\n this.helper = new FormArrayHelper<Property>(\n this.formArray,\n (value) => this.getPropertyFormGroup(value),\n (v1, v2) => (!v1 && !v2) || v1.key === v2.key,\n (value) => isNil(value) || (isNil(value.key) && isNil(value.value)),\n this.options\n );\n\n super.ngOnInit();\n }\n\n getDefinitionAt(index: number): FormFieldDefinition {\n let definition = this.definitionsByIndex[index];\n if (!definition) {\n definition = this.updateDefinitionAt(index);\n this.definitionsByIndex[index] = definition;\n }\n return definition;\n }\n\n updateDefinitionAt(index: number): FormFieldDefinition {\n const key = (this.formArray.at(index) as FormGroup).controls.key.value;\n const definition = key && this.definitionsMapByKey[key] || null;\n this.definitionsByIndex[index] = definition; // update map by index\n this.markForCheck();\n return definition;\n }\n\n removeAt(index: number) {\n this.helper.removeAt(index);\n this.definitionsByIndex = {}; // clear map by index\n this.markForCheck();\n }\n\n isUnknownField(fieldForm: FormGroup) {\n const keyControl = fieldForm.get('key');\n const key = keyControl && keyControl.value;\n return key && isNil(this.definitionsMapByKey[key]);\n }\n\n setValue(data: T[] | any) {\n if (!data) return; // Skip\n\n // Transform properties map into array\n const values = EntityUtils.getMapAsArray<T>(data);\n this.helper.resize(values.length);\n this.helper.formArray.patchValue(values, {emitEvent: false});\n\n this.markAsPristine();\n this.markAsLoaded();\n }\n\n /* -- protected methods -- */\n\n protected getPropertyFormGroup(data?: {key: string; value?: string}): FormGroup {\n return this.formBuilder.group({\n key: [data && data.key || null, Validators.compose([Validators.required, Validators.max(50)])],\n value: [data && data.value || null, Validators.required]\n });\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n}\n\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Injector,\n Input,\n OnInit,\n Optional,\n Output\n} from '@angular/core';\nimport {AbstractControl, FormArray, FormBuilder, FormGroup, FormGroupDirective, Validators} from '@angular/forms';\nimport {referentialToString} from '../services/model/referential.model';\nimport {isNil} from '../../shared/functions';\nimport {DateAdapter} from '@angular/material/core';\nimport {Moment} from 'moment';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {AppForm} from './form.class';\nimport {AppFormUtils, FormArrayHelper, FormArrayHelperOptions} from './form.utils';\nimport {SelectionModel} from '@angular/cdk/collections';\nimport {Observable} from 'rxjs';\nimport {Color} from '@ionic/core';\n\nexport declare interface ItemButton<T = any> {\n title?: string;\n click: (event: UIEvent, item: T, index: number) => void;\n icon: string;\n color?: Color;\n disabled?: Observable<boolean>;\n}\n\nexport declare type AppListFormOptions<T> = FormArrayHelperOptions & {\n allowMultipleSelection?: boolean;\n buttons?: ItemButton<T>[];\n};\n\n@Component({\n selector: 'app-list-form',\n templateUrl: 'list.form.html',\n styleUrls: ['./list.form.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppListForm<T = any> extends AppForm<T[]> implements OnInit {\n helper: FormArrayHelper<T>;\n selection = new SelectionModel<T>(true, []);\n\n @Input() formArrayName: string;\n @Input() formArray: FormArray;\n @Input() options: AppListFormOptions<T>;\n\n @Input('displayWith') displayWithFn: (item: any) => string = referentialToString;\n @Input('equals') equalsFn: (v1: T, v2: T) => boolean;\n\n @Output() onNewItem = new EventEmitter<UIEvent>();\n @Output() selectionChanges = new EventEmitter<T[]>(true);\n\n set value(data: T[]) {\n this.setValue(data);\n }\n\n get value(): T[] {\n return this.formArray.value as T[];\n }\n\n get itemControls(): FormGroup[] {\n return this.formArray && this.formArray.controls as FormGroup[];\n }\n\n get length(): number {\n return this.helper ? this.helper.size() : 0;\n }\n\n get empty(): boolean {\n return this.length === 0;\n }\n\n get touched(): boolean {\n return this.formArray && (this.formArray.touched || (this.formArray.controls || []).findIndex(c => c.touched) !== -1);\n }\n\n get untouched(): boolean {\n return !this.formArray || this.formArray.untouched || (this.formArray.controls || []).findIndex(c => c.touched) === -1;\n }\n\n get dirty(): boolean {\n return this.formArray && this.formArray.dirty;\n }\n\n get invalid(): boolean {\n return !this.formArray || this.formArray.invalid;\n }\n\n get valid(): boolean {\n return this.formArray && this.formArray.valid;\n }\n\n get pending(): boolean {\n return !this.formArray || this.formArray.pending;\n }\n\n markAsTouched(opts?: { onlySelf?: boolean; emitEvent?: boolean }) {\n AppFormUtils.markAsTouched(this.formArray, opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n markAllAsTouched(opts?: { emitEvent?: boolean }) {\n AppFormUtils.markAllAsTouched(this.formArray, opts);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n\n constructor(\n protected injector: Injector,\n protected formBuilder: FormBuilder,\n protected dateAdapter: DateAdapter<Moment>,\n protected settings: LocalSettingsService,\n protected cd: ChangeDetectorRef,\n @Optional() private formGroupDir: FormGroupDirective\n ) {\n super(injector, null);\n\n //this.debug = !environment.production;\n }\n\n ngOnInit() {\n\n this.options = {\n allowEmptyArray: true,\n allowMultipleSelection: true,\n buttons: [],\n ...this.options};\n\n // Retrieve the form\n const form = (this.formArray && this.formArray.parent as FormGroup || this.formGroupDir && this.formGroupDir.form || this.formBuilder.group({}));\n this.setForm(form);\n\n this.formArray = this.formArray || this.formArrayName && form.get(this.formArrayName) as FormArray;\n this.formArrayName = this.formArrayName || this.formArray && Object.keys(form.controls).find(key => form.get(key) === this.formArray) || 'properties';\n if (!this.formArray) {\n console.warn(`Missing array control '${this.formArrayName}'. Will create it!`);\n this.formArray = this.formBuilder.array([]);\n this.form.addControl(this.formArrayName, this.formArray);\n }\n\n this.equalsFn = this.equalsFn || ((v1: any, v2: any) => (isNil(v1) && isNil(v2)) || v1 === v2);\n this.helper = new FormArrayHelper<T>(\n this.formArray,\n (value) => this.createControl(value),\n this.equalsFn,\n (value) => isNil(value),\n this.options\n );\n\n super.ngOnInit();\n }\n\n ngOnDestroy() {\n super.ngOnDestroy();\n\n this.onNewItem.complete();\n this.onNewItem.unsubscribe();\n this.selectionChanges.complete();\n this.selectionChanges.unsubscribe();\n }\n\n setValue(data: T[] | any) {\n data = data || [];\n\n if (this.helper) {\n this.helper.resize(data.length);\n this.helper.formArray.patchValue(data, {emitEvent: false});\n }\n else {\n console.warn('TODO: cannot applyied setValue() on fromArray, because formArrayHelper not exists yet !');\n }\n\n this.selection.clear();\n this.markAsPristine();\n this.markAsLoaded();\n }\n\n /** Whether the number of selected elements matches the total number of rows. */\n isAllSelected() {\n return this.selection.selected.length === this.length;\n }\n\n async masterToggle(opts?: {emitEvent?: boolean}) {\n if (this.loading) return;\n if (this.isAllSelected()) {\n this.selection.clear();\n } else {\n const items = this.value;\n items.forEach(item => this.selection.select(item));\n }\n\n if (!opts || opts.emitEvent !== false) {\n this.selectionChanges.emit(this.selection.selected);\n }\n }\n\n async onItemClick(event: MouseEvent, item: T, opts?: {emitEvent?: boolean}) {\n\n if (!item || event.defaultPrevented || !this.selectionChanges.observers.length) return;\n\n // Multiple selection (if ctrl+click)\n if (event.ctrlKey && this.options.allowMultipleSelection) {\n this.selection.toggle(item);\n }\n else {\n // Unselect all\n\n // Select the item (or reselect)\n if (!this.selection.isSelected(item) || (this.options.allowMultipleSelection && this.selection.selected.length > 1)) {\n this.selection.clear();\n this.selection.select(item);\n }\n // Unselect all\n else {\n this.selection.clear();\n }\n }\n\n if (!opts || opts.emitEvent !== false) {\n this.selectionChanges.emit(this.selection.selected);\n }\n }\n\n async onItemButtonClick(button: ItemButton, event: MouseEvent, item: T, index: number) {\n if (button.click) button.click(event, item, index);\n await this.onItemClick(event, item);\n }\n\n hasSelection(): boolean {\n return this.selection.hasValue();\n }\n\n onNewClick(event: UIEvent) {\n this.onNewItem.emit(event);\n }\n\n add(value: T, opts?: {emitEvent?: boolean}) {\n const done = this.helper.add(value, {emitEvent: true});\n if (done) {\n if (!this.options.allowMultipleSelection) {\n this.selection.clear();\n }\n this.selection.toggle(value);\n this.markForCheck();\n\n if (!opts || opts.emitEvent !== false) {\n this.selectionChanges.emit(this.selection.selected);\n }\n }\n }\n\n removeAt(index: number) {\n const item = this.helper.at(index).value;\n if (this.selection.isSelected(item)) {\n this.selection.deselect(item);\n }\n this.helper.removeAt(index);\n }\n\n displayWith(value: T): string {\n return this.displayWithFn ? this.displayWithFn(value) : (value as any);\n }\n\n /* -- protected methods -- */\n\n protected createControl(data?: any): AbstractControl {\n return this.formBuilder.control(data || null, Validators.required);\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n}\n\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\n\nimport {UsageMode} from '../model/settings.model';\n\n@Pipe({\n name: 'isOnField'\n})\n@Injectable({providedIn: 'root'})\nexport class IsOnFieldModePipe implements PipeTransform {\n\n transform(value: UsageMode): boolean {\n return value === 'FIELD';\n }\n}\n\n\n@Pipe({\n name: 'isNotOnField'\n})\n@Injectable({providedIn: 'root'})\nexport class IsNotOnFieldModePipe implements PipeTransform {\n\n transform(value: UsageMode): boolean {\n return value !== 'FIELD';\n }\n}\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {Person, PersonUtils} from '../model/person.model';\n\n@Pipe({\n name: 'personToString'\n})\n@Injectable({providedIn: 'root'})\nexport class PersonToStringPipe implements PipeTransform {\n\n transform(value: Person | Person[], separator?: string): string {\n if (Array.isArray(value)) return PersonUtils.personsToString(value, separator);\n return PersonUtils.personToString(value as Person);\n }\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, OnDestroy, OnInit} from '@angular/core';\nimport {AlertController, ModalController, ToastController} from '@ionic/angular';\nimport {from, Observable, Subscription} from 'rxjs';\nimport {Configuration} from '../services/model/config.model';\nimport {ConfigService} from '../services/config.service';\nimport {PlatformService} from '../services/platform.service';\nimport {debounceTime, distinctUntilChanged, filter, map, switchMap} from 'rxjs/operators';\nimport {NetworkService} from '../services/network.service';\nimport {CORE_CONFIG_OPTIONS} from '../services/config/core.config';\nimport {VersionUtils} from '../../shared/version/versions';\nimport {slideUpDownAnimation} from '../../shared/material/material.animations';\nimport {isNilOrBlank, isNotEmptyArray, isNotNil, isNotNilOrBlank, sleep} from '../../shared/functions';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Peer} from '../services/model/peer.model';\nimport {MimeTypes} from '../../shared/file/file.utils';\nimport {UriUtils} from '../../shared/file/uri.utils';\n\n\nexport declare interface InstallAppLink {\n name: string;\n url: string;\n platform?: 'android' | 'ios';\n version?: string;\n filename?: string;\n title?: string;\n description?: string;\n mimeType?: string;\n downloading?: boolean;\n location?: string;\n}\n\n\n@Component({\n selector: 'app-install-upgrade-card',\n templateUrl: 'install-upgrade-card.component.html',\n styleUrls: ['./install-upgrade-card.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [slideUpDownAnimation]\n})\nexport class AppInstallUpgradeCard implements OnInit, OnDestroy {\n\n private _subscription = new Subscription();\n\n loading = true;\n hasDownloader = false;\n downloading = false;\n waitingNetwork = false;\n installLinks: InstallAppLink[];\n upgradeLinks: InstallAppLink[];\n offline: boolean;\n upgradeVersion: string;\n\n @Input() isLogin: boolean;\n @Input() showUpgradeWarning = true;\n @Input() showOfflineWarning = true;\n @Input() showInstallButton = false;\n\n constructor(\n private modalCtrl: ModalController,\n private configService: ConfigService,\n private toastController: ToastController,\n private alertController: AlertController,\n private translate: TranslateService,\n private cd: ChangeDetectorRef,\n public platform: PlatformService,\n public network: NetworkService,\n @Inject(ENVIRONMENT) protected environment\n ) {\n\n }\n\n ngOnInit() {\n\n this.offline = this.network.offline;\n\n // Listen pod config\n this._subscription.add(\n from(this.network.ready())\n .pipe(\n debounceTime(1000),\n switchMap(() => this.configService.config),\n filter(isNotNil)\n )\n .subscribe(config => this.checkNeedInstallOrUpdate(config)));\n\n // Listen network changes\n this._subscription.add(\n this.network.onNetworkStatusChanges\n .pipe(\n //debounceTime(450),\n //tap(() => this.waitingNetwork = false),\n map(connectionType => connectionType === 'none'),\n distinctUntilChanged()\n )\n .subscribe(offline => {\n if (this.offline !== offline) {\n this.offline = offline;\n this.markForCheck();\n }\n })\n );\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n this.installLinks = null;\n this.upgradeLinks = null;\n }\n\n async download(event: UIEvent, link: InstallAppLink) {\n if (!link || !link.url) {\n console.error('[install-upgrade-card] Missing required argument \\'link.url\\'');\n return; // Skip\n }\n\n // Mark link as downloading\n link.downloading = true;\n this.markForCheck();\n\n this.listenDownloadJob(link.url, this.platform.download({\n uri: link.url,\n title: link.title,\n filename: link.filename,\n mimeType: link.mimeType\n }))\n .then((location) => {\n if (this.platform.canOpenFile) link.location = location;\n link.downloading = false;\n })\n .catch(() => link.downloading = false)\n .then(() => this.markForCheck());\n }\n\n async openFile(event: UIEvent, link: InstallAppLink) {\n if (!link || !link.location || !link.mimeType) {\n console.error('[install-upgrade-card] Missing required argument \\'link.location\\' or \\'link.mimeType\\'');\n return; // Skip\n }\n try {\n await this.platform.openFile(link.location, link.mimeType);\n }\n catch (err) {\n console.error('[install-upgrade-card] Cannot open file: ' + (err && err.message || err), err);\n }\n }\n\n async tryOnline() {\n this.waitingNetwork = true;\n this.markForCheck();\n\n try {\n await this.network.tryOnline({\n showLoadingToast: false,\n showOnlineToast: true,\n showOfflineToast: false\n });\n }\n finally {\n this.waitingNetwork = false;\n this.markForCheck();\n }\n }\n\n getPlatformName(platform: 'android'|'ios') {\n switch (platform) {\n case 'android':\n return 'Android';\n case 'ios':\n return 'iOS';\n default:\n return '';\n }\n }\n\n asLink(value: any): InstallAppLink {\n return value as InstallAppLink;\n }\n\n /* -- private method -- */\n\n private async checkNeedInstallOrUpdate(config: Configuration) {\n if (!config) return; // Skip\n\n console.info('[install-upgrade-card] Check if need to install or upgrade...');\n\n this.hasDownloader = this.platform.canDownload;\n\n try {\n const links = this.getLinks(config);\n\n // Check for upgrade\n this.upgradeLinks = this.getCompatibleUpgradeLinks(links, config);\n\n if (isNotEmptyArray(this.upgradeLinks)) {\n console.info(`[install-upgrade-card] Find upgrade links: ${this.upgradeLinks.map(l => l.url).join(',')}`);\n this.installLinks = null;\n this.listenDownloadJobs();\n }\n else {\n // Check for install links\n this.installLinks = this.getCompatibleInstallLinks(links);\n if (isNotEmptyArray(this.installLinks)) {\n console.info(`[install-upgrade-card] Find install links ${this.installLinks.map(l => l.url).join(',')}`);\n await sleep(1000); // Add a delay, for animation\n }\n }\n }\n finally {\n this.loading = false;\n this.markForCheck();\n }\n }\n\n private getCompatibleInstallLinks(installLinks: InstallAppLink[]): InstallAppLink[] {\n\n // Cordova already running: not need to install\n if (this.platform.isCordova()) return undefined;\n\n // If mobile web: return all\n if (this.platform.isMobileWeb()) {\n return installLinks;\n }\n\n return undefined;\n }\n\n private getCompatibleUpgradeLinks(installLinks: InstallAppLink[], config: Configuration): InstallAppLink[] {\n const appVersion = this.environment.version;\n const appMinVersionFromPod = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);\n\n if (!appVersion) {\n console.error('Missing value for \\'environment.version\\': cannot check app compatibility!');\n return undefined;\n }\n\n const needUpgrade = appMinVersionFromPod && !VersionUtils.isCompatible(appMinVersionFromPod, appVersion);\n if (!needUpgrade) return undefined;\n\n const upgradeLinks = installLinks\n .filter(link => this.platform.is('mobileweb') || (link.platform && this.platform.is(link.platform)));\n\n // Use min version as default version\n upgradeLinks.forEach(link => {\n link.version = link.version || appMinVersionFromPod;\n });\n\n return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;\n }\n\n private getLinks(config: Configuration): InstallAppLink[] {\n const result: InstallAppLink[] = [];\n\n // Android\n {\n // Get URL (from config, or environment)\n let url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);\n if (isNilOrBlank(url)) url = this.environment.defaultAndroidInstallUrl || null;\n\n // Resolve relative URL\n const peer = this.network.peer;\n if (peer && (url.startsWith('./') || url.startsWith('/'))) {\n url = Peer.path(peer, url);\n }\n\n const minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);\n\n // Compute App name\n const name: string = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';\n\n if (url) {\n let title: string;\n let mimeType: string;\n\n // Get file name\n let filename = UriUtils.getFilename(url);\n let version = minVersion || 'latest';\n\n // OK, this is a downloadable APK file (e.g. NOT a link to a playstore)\n if (filename?.toLowerCase().endsWith('.apk')) {\n // Define mime type\n mimeType = MimeTypes.ANDROID_APK;\n\n // Get the file version (if any)\n const versionMatches = /-v([1-9][0-9]*\\.[0-9]+\\.(:?(:?alpha|beta|rc)?[0-9]*))/i.exec(filename);\n version = versionMatches && versionMatches[1] || version;\n\n // Compute a new file name, with the version\n if (isNotNilOrBlank(name) && version !== 'latest') {\n filename = `${name}-v${version}.apk`.toLowerCase();\n title = `${name} v${version}`;\n }\n\n // Replace 'latest' with the app version, if present in the filename\n else if (filename.indexOf('latest') && version !== 'latest') {\n filename = filename.replace('latest', version);\n }\n }\n\n result.push({ name, url, platform: 'android', version, filename, title, mimeType });\n }\n }\n\n // iOS - TODO\n //{\n // (...)\n //}\n\n return result;\n }\n\n private listenDownloadJobs() {\n // Listening downloading promise, if exists\n (this.upgradeLinks || []).forEach(link => {\n const job = this.platform.getDownloadingJob(link.url);\n if (job) {\n link.downloading = true;\n this.listenDownloadJob(link.url, job)\n .then((location) => {\n link.location = location;\n link.downloading = false;\n })\n .catch(() => link.downloading = false)\n .then(() => this.markForCheck());\n }\n });\n }\n\n private async listenDownloadJob(url: string, job: Observable<string>): Promise<string> {\n if (!url || !job) return; // Skip\n\n try {\n // Mark as downloading\n if (!this.downloading) {\n console.info(`[install-upgrade-card] Asking platform to download '${url}'...`);\n this.downloading = true;\n this.markForCheck();\n }\n else {\n console.info(`[install-upgrade-card] Platform is already downloading!`);\n }\n\n const location = await job.toPromise();\n if (location) {\n console.info('[install-upgrade-card] File downloaded at: ' + location);\n this.showDownloadCompleteDialog();\n }\n return location;\n }\n // Failed: display a toast\n catch (err) {\n console.error('[install-upgrade-card] Download failed: ' + (err && err.message || err));\n this.showDownloadFailedToast(err);\n throw err;\n }\n finally {\n this.downloading = false;\n this.markForCheck();\n }\n }\n\n private showDownloadFailedToast(err) {\n return this.showToast({\n message: 'ERROR.DOWNLOAD_FAILED',\n messageParams: {error: err},\n type: 'error',\n showCloseButton: true\n });\n }\n\n private async showDownloadCompleteDialog() {\n if (!this._subscription) return; // Skip if component has been destroyed\n\n const translations = await this.translate.get([\n 'INFO.ALERT_HEADER',\n 'INFO.UPDATE_APP_DOWNLOADED',\n 'COMMON.BTN_CLOSE'\n ]).toPromise();\n const alert = await this.alertController.create({\n header: translations['INFO.ALERT_HEADER'],\n message: translations['INFO.UPDATE_APP_DOWNLOADED'],\n buttons: [\n {\n text: translations['COMMON.BTN_CLOSE'],\n role: 'cancel',\n cssClass: 'secondary'\n }\n ]\n });\n\n await alert.present();\n await alert.onDidDismiss();\n }\n\n private markForCheck() {\n if (!this._subscription) return; // Skip if destroyed\n this.cd.markForCheck();\n }\n\n private async showToast(opts: ShowToastOptions) {\n if (!this._subscription) return; // Skip if component has been destroyed\n await Toasts.show(this.toastController, this.translate, opts);\n }\n}\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {Account, accountToString} from '../model/account.model';\n\n@Pipe({\n name: 'isLogin'\n})\n@Injectable({providedIn: 'root'})\nexport class IsLoginAccountPipe implements PipeTransform {\n\n transform(value: Account): boolean {\n return value && value.pubkey && true;\n }\n}\n\n@Pipe({\n name: 'accountToString'\n})\n@Injectable({providedIn: 'root'})\nexport class AccountToStringPipe implements PipeTransform {\n\n transform(value: Account): string {\n return accountToString(value);\n }\n}\n\n","import {Injectable, Pipe, PipeTransform} from '@angular/core';\nimport {Department, departmentsToString, departmentToString} from '../model/department.model';\n\n@Pipe({\n name: 'departmentToString'\n})\n@Injectable({providedIn: 'root'})\nexport class DepartmentToStringPipe implements PipeTransform {\n\n transform(value: Department | (Department[]), separator?: string): string {\n if (Array.isArray(value)) return departmentsToString(value, separator);\n return departmentToString(value);\n }\n}\n\n","import {ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild} from '@angular/core';\nimport {MatColumnDef, MatTable} from '@angular/material/table';\nimport {TableElement} from '@e-is/ngx-material-table';\nimport {MatMenuTrigger} from '@angular/material/menu';\nimport {isNil, toBoolean} from '../../shared/functions';\n\n@Component({\n selector: 'app-actions-column',\n templateUrl: './actions-column.component.html',\n})\nexport class ActionsColumnComponent implements OnInit, OnDestroy {\n\n @ViewChild(MatColumnDef) columnDef: MatColumnDef;\n @ViewChild(MatMenuTrigger) matMenuTrigger: MatMenuTrigger;\n\n @Input() stickyEnd = false;\n @Input() canCancel: boolean;\n @Input() canDelete: boolean;\n @Input() canBackward: boolean;\n @Input() canForward: boolean;\n @Input() canConfirmAndAdd: boolean;\n @Input() dirtyIcon: boolean|string;\n @Input() optionsTitle = 'COMMON.BTN_OPTIONS';\n @Input('class') classList: string;\n @Input() cellTemplate: TemplateRef<any>;\n\n @Output() optionsClick = new EventEmitter<UIEvent>();\n @Output() cancelOrDeleteClick = new EventEmitter<{ event: Event; row: TableElement<any> }>();\n @Output() confirmAndAddClick = new EventEmitter<{ event: Event; row: TableElement<any> }>();\n @Output() backward = new EventEmitter<{ event: Event; row: TableElement<any> }>();\n @Output() forward = new EventEmitter<{ event: Event; row: TableElement<any> }>();\n\n constructor(private table: MatTable<any>,\n private cd: ChangeDetectorRef,\n // TODO auto configure using AppTable ? (need a forwardRef() in the table component\n //@Optional() private appTable: AppTable<any>\n ) {\n if (!table) throw new Error(`[actions-column] this column component must be inside a MatTable component`);\n }\n\n ngOnInit(): void {\n this.cd.detectChanges();\n this.table.addColumnDef(this.columnDef);\n this.canCancel = toBoolean(this.canCancel, this.cancelOrDeleteClick.observers.length > 0);\n this.canDelete = toBoolean(this.canDelete, this.cancelOrDeleteClick.observers.length > 0);\n this.canConfirmAndAdd = toBoolean(this.canConfirmAndAdd, this.confirmAndAddClick.observers.length > 0);\n this.canBackward = toBoolean(this.canBackward, this.backward.observers.length > 0);\n this.canForward = toBoolean(this.canForward, this.forward.observers.length > 0);\n if (isNil(this.dirtyIcon)) {\n this.dirtyIcon = 'star';\n }\n }\n\n ngOnDestroy() {\n this.table.removeColumnDef(this.columnDef);\n this.optionsClick.complete();\n this.optionsClick.unsubscribe();\n this.cancelOrDeleteClick.complete();\n this.cancelOrDeleteClick.unsubscribe();\n this.confirmAndAddClick.complete();\n this.confirmAndAddClick.unsubscribe();\n this.backward.complete();\n this.backward.unsubscribe();\n this.forward.complete();\n this.forward.unsubscribe();\n }\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, InjectionToken, Input, OnInit, Optional, ViewChild } from '@angular/core';\nimport { AlertController, IonSplitPane, MenuController, ModalController } from '@ionic/angular';\n\nimport { Router } from '@angular/router';\nimport { Account } from '../services/model/account.model';\nimport { Configuration } from '../services/model/config.model';\nimport { AccountService } from '../services/account.service';\nimport { AboutModal } from '../about/modal-about';\n\nimport { fadeInAnimation } from '../../shared/material/material.animations';\nimport { TranslateService } from '@ngx-translate/core';\nimport { isNotNilOrBlank } from '../../shared/functions';\nimport { BehaviorSubject, merge, Subscription } from 'rxjs';\nimport { ConfigService } from '../services/config.service';\nimport { distinctUntilChanged, map, mergeMap, tap } from 'rxjs/operators';\nimport { HammerSwipeEvent } from '../../shared/gesture/hammer.utils';\nimport { PlatformService } from '../services/platform.service';\nimport { ENVIRONMENT } from '../../../environments/environment.class';\nimport { DEFAULT_MENU_SHOW_WHEN, MenuService, SplitPaneShowWhen } from './menu.service';\nimport {MenuOptions, MenuItem, MenuItems} from './menu.model';\nimport { CORE_CONFIG_OPTIONS } from '../services/config/core.config';\nimport { firstNotNilPromise } from '../../shared/observables';\n\nexport const APP_MENU_ITEMS = new InjectionToken<MenuItem[]>('menuItems');\nexport const APP_MENU_OPTIONS = new InjectionToken<MenuOptions>('menuOptions');\n\n@Component({\n selector: 'app-menu',\n templateUrl: 'menu.component.html',\n styleUrls: ['./menu.component.scss'],\n animations: [fadeInAnimation],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MenuComponent implements OnInit {\n\n private readonly _debug: boolean;\n private _subscription = new Subscription();\n private _config: Configuration;\n\n public loading = true;\n public isLogin = false;\n accountName: string;\n accountAvatar: string;\n accountEmail: string;\n\n $items = new BehaviorSubject<MenuItem[]>(undefined);\n\n @Input() id = 'menu';\n @Input() menuId = 'left';\n @Input() side = 'left';\n @Input() contentId = 'menu-content';\n @Input() logo: string;\n @Input() appName: string;\n @Input() appVersion: string = this.environment.version;\n\n @ViewChild('splitPane', { static: true }) splitPane: IonSplitPane;\n\n constructor(\n protected platformService: PlatformService,\n protected accountService: AccountService,\n protected router: Router,\n protected menu: MenuController,\n protected modalCtrl: ModalController,\n protected alertController: AlertController,\n protected translate: TranslateService,\n protected configService: ConfigService,\n protected cd: ChangeDetectorRef,\n protected menuService: MenuService,\n @Inject(ENVIRONMENT) protected environment,\n @Optional() @Inject(APP_MENU_OPTIONS) protected options: MenuOptions,\n @Optional() @Inject(APP_MENU_ITEMS) protected items: MenuItem[]\n ) {\n\n this._debug = !environment.production;\n }\n\n async ngOnInit() {\n\n this.splitPane.when = await firstNotNilPromise(this.menuService.splitPaneWhen);\n\n // Wait platform started\n await this.platformService.ready();\n\n // Listen to menu service event\n this.menuService.splitPaneWhen\n .subscribe((value) => this.setSplitPaneWhen(value));\n this.menuService.enabled\n .subscribe((value) => this.enable(value));\n this.menuService.opened\n // Avoid duplicated events\n .pipe(distinctUntilChanged())\n .subscribe((value) => value ? this.open() : this.close());\n\n // Update component when refresh is need (=login events or config changed)\n this._subscription.add(\n merge(\n merge(\n this.accountService.onLogin,\n this.accountService.onLogout\n )\n .pipe(\n // Wait account service ready (can be restarted)\n mergeMap(() => this.accountService.ready()),\n map(() => this.accountService.isLogin()),\n distinctUntilChanged()\n ),\n this.configService.config\n .pipe(\n tap(config => this._config = config),\n mergeMap(() => this.accountService.ready()),\n map(() => this.accountService.isLogin())\n )\n )\n .subscribe(login => {\n if (login) {\n this.onLogin(this.accountService.account);\n } else {\n this.onLogout(true);\n }\n }));\n }\n\n async onLogin(account: Account) {\n console.info('[menu] Update (login)');\n this.accountAvatar = account.avatar;\n this.accountName = account.displayName;\n this.accountEmail = account.email;\n this.isLogin = true;\n await this.refreshMenuItems();\n\n setTimeout(() => {\n this.loading = false;\n this.detectChanges();\n }, 500);\n }\n\n async onLogout(skipRedirect?: boolean) {\n if (!skipRedirect) {\n console.debug('[menu] Logout');\n }\n else {\n console.debug('[menu] Update (logout)');\n }\n this.isLogin = false;\n this.accountAvatar = null;\n this.accountEmail = null;\n this.accountName = null;\n await this.refreshMenuItems();\n\n // Wait the end of fadeout, to reset the account\n if (!skipRedirect) {\n await this.router.navigate(['']);\n }\n\n this.loading = false;\n this.detectChanges();\n }\n\n async logout() {\n\n const translations = await this.translate.get([\n 'AUTH.LOGOUT.CONFIRM_TITLE',\n 'AUTH.LOGOUT.CONFIRM_MESSAGE',\n 'COMMON.BTN_CANCEL',\n 'AUTH.LOGOUT.BTN_CONFIRM'\n ]).toPromise();\n const alert = await this.alertController.create({\n header: translations['AUTH.LOGOUT.CONFIRM_TITLE'],\n message: translations['AUTH.LOGOUT.CONFIRM_MESSAGE'],\n buttons: [\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n cssClass: 'secondary'\n },\n {\n text: translations['AUTH.LOGOUT.BTN_CONFIRM'],\n cssClass: 'ion-color-primary',\n handler: () => {\n this.accountService.logout();\n\n setTimeout(() =>\n // Back to home\n this.router.navigateByUrl('/', {replaceUrl: true /* will clear router history */})\n , 100);\n }\n }\n ]\n });\n\n await alert.present();\n }\n\n async enable(value: boolean): Promise<void> {\n const enabled = await this.menu.isEnabled(this.menuId);\n if (enabled !== value) {\n await this.menu.enable(value, this.menuId);\n if (!value) await this.close();\n }\n }\n\n async open(): Promise<boolean> {\n console.debug('[menu] Checking open event...');\n const opened = await this.menu.isOpen(this.menuId);\n if (!opened) {\n console.debug('[menu] Opening menu');\n await this.menu.open(this.menuId);\n // Propage to service\n this.menuService._markAsOpened();\n }\n return true;\n }\n\n async close(): Promise<boolean> {\n console.debug('[menu] Checking close event...');\n const opened = await this.menu.isOpen(this.menuId);\n if (opened) {\n console.debug('[menu] Closing menu');\n await this.menu.close(this.menuId);\n // Propage to service\n this.menuService._markAsClosed();\n }\n return true;\n }\n\n async openAboutModal(event?: UIEvent) {\n const modal = await this.modalCtrl.create({component: AboutModal});\n return modal.present();\n }\n\n async setSplitPaneWhen(value: SplitPaneShowWhen) {\n console.debug('[menu] Checking splitPane when...');\n if (this.splitPane.when !== value) {\n console.debug('[menu] Set splitPane when to ' + value);\n this.splitPane.when = value;\n this.detectChanges();\n\n // Propagate to the menu service\n setTimeout(() => this.menuService.setSplitPaneShowWhen(value), 200);\n }\n }\n\n toggleSplitPaneShow(event?: UIEvent) {\n if (event && event.defaultPrevented) return;\n if (event) event.preventDefault();\n\n if (this.splitPane.when === false) {\n return this.setSplitPaneWhen(DEFAULT_MENU_SHOW_WHEN);\n } else {\n return this.setSplitPaneWhen(false);\n }\n }\n\n async doAction(action: string, event: UIEvent) {\n this.close();\n\n switch (action) {\n case 'logout':\n await this.logout();\n break;\n case 'about':\n await this.openAboutModal(event);\n break;\n default:\n throw new Error('Unknown action: ' + action);\n }\n }\n\n onSwipeRight(event: HammerSwipeEvent) {\n // Skip, if not a valid swipe event\n if (!event || event.pointerType !== 'touch' || event.velocity < 0.4) {\n //event.preventDefault();\n return false;\n }\n\n // Will open the left menu, so cancelled this swipe event\n const startX = event.center.x - event.distance;\n if (startX <= 50) {\n // DEBUG\n //console.debug(\"[menu] Cancel swipe right, because near the left menu {x: \" + startX + \", velocity: \" + event.velocity + \"}\");\n event.preventDefault();\n return false;\n }\n\n // OK: continue\n\n // DEBUG\n //console.debug(\"[menu] Received swipe right {x: \" + startX + \", velocity: \" + event.velocity + \"}\");\n }\n\n /* -- protected methods -- */\n\n protected refreshMenuItems() {\n if (this._debug) console.debug('[menu] Refreshing menu items...');\n\n let items = this.items || [];\n\n // Insert menu items, from the config\n const configValue: string = this._config && this._config.getProperty(CORE_CONFIG_OPTIONS.MENU_ITEMS);\n if (isNotNilOrBlank(configValue)) {\n try {\n const configItems = JSON.parse(configValue);\n items = (configItems || []).reduce((res, item) => {\n if (item.after) {\n const index = res.findIndex(i => i.title === item.after);\n if (index !== -1) {\n return res.slice(0, index+1)\n .concat(item)\n .concat(res.slice(index+1))\n }\n }\n if (item.before) {\n const index = res.findIndex(i => i.title === item.before);\n if (index !== -1) {\n return res.slice(0, index)\n .concat(item)\n .concat(res.slice(index))\n }\n }\n return res.concat(item);\n }, items)\n }\n catch(err) {\n console.error(`[menu] Invalid value for option '${CORE_CONFIG_OPTIONS.MENU_ITEMS.key}'. Expected an array of menu item`, err);\n }\n }\n\n const opts = { isLogin: this.isLogin, debug: this._debug };\n const filteredItems = items\n .filter(item => MenuItems.checkIfVisible(item, this.accountService, this._config, opts))\n .map(item => {\n // Replace title using properties\n if (isNotNilOrBlank(item.titleProperty) && this._config) {\n const title = this._config.properties[item.titleProperty];\n if (title) return { ...item, title}; // Create a copy, to keep the original item.title\n }\n return item;\n });\n\n this.$items.next(filteredItems);\n }\n\n protected detectChanges() {\n this.cd.detectChanges();\n }\n}\n\n","import {NgModule} from '@angular/core';\nimport {SharedModule} from '../../shared/shared.module';\nimport {MenuComponent} from './menu.component';\n// import ngx-translate and the http loader\nimport {TranslateModule} from '@ngx-translate/core';\nimport {RouterModule} from '@angular/router';\n\n@NgModule({\n imports: [\n SharedModule,\n RouterModule,\n TranslateModule\n ],\n\n declarations: [\n // Components\n MenuComponent\n ],\n exports: [\n // Modules\n TranslateModule,\n // Components\n MenuComponent\n ]\n})\nexport class AppMenuModule {\n\n}\n","import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, Output} from '@angular/core';\nimport {slideUpDownAnimation} from '../../shared/material/material.animations';\n\n\n@Component({\n selector: 'app-update-offline-mode-card',\n templateUrl: 'update-offline-mode-card.component.html',\n styleUrls: ['./update-offline-mode-card.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [slideUpDownAnimation]\n})\nexport class AppUpdateOfflineModeCard implements OnDestroy {\n\n @Input() progressionMessage: string;\n @Input() progressionValue: number;\n @Output() onUpdateClick = new EventEmitter<UIEvent>();\n\n constructor(\n ) {\n }\n\n ngOnDestroy() {\n this.onUpdateClick.complete();\n }\n\n /* -- private method -- */\n\n}\n","import { Component, Input } from '@angular/core';\nimport { AppColors, IconRef } from '../../shared/types';\n\n@Component({\n selector: 'app-icon',\n templateUrl: './icon.component.html'\n})\nexport class AppIconComponent {\n\n @Input() icon: string = null;\n @Input() matIcon: string = null;\n @Input() matSvgIcon: string = null;\n @Input() color: AppColors = null;\n @Input() height: number;\n @Input() width: number;\n\n @Input() set ref(value: IconRef) {\n this.icon = value.icon;\n this.matIcon = value.matIcon;\n this.matSvgIcon = value.matSvgIcon;\n this.color = value.color;\n };\n}\n","import {NgModule} from '@angular/core';\nimport {SharedModule} from '../../shared/shared.module';\n// import ngx-translate and the http loader\nimport {TranslateModule} from '@ngx-translate/core';\nimport {RouterModule} from '@angular/router';\nimport {UserEventModule} from '../../social/user-event/user-event.module';\nimport {AppIconComponent} from './icon.component';\n\n@NgModule({\n imports: [\n SharedModule,\n TranslateModule\n ],\n\n declarations: [\n // Components\n AppIconComponent\n ],\n exports: [\n // Modules\n TranslateModule,\n // Components\n AppIconComponent\n ]\n})\nexport class AppIconModule {\n\n}\n","import {ModuleWithProviders, NgModule} from '@angular/core';\nimport {RouterModule} from '@angular/router';\nimport {AuthForm} from './auth/form/form-auth';\nimport {AuthModal} from './auth/modal/modal-auth';\nimport {AboutModal} from './about/modal-about';\nimport {RegisterConfirmPage} from './register/confirm/confirm';\nimport {AccountPage} from './account/account';\nimport {SharedModule} from '../shared/shared.module';\nimport {EntityMetadataComponent} from './form/entity-metadata.component';\nimport {FormButtonsBarComponent} from './form/form-buttons-bar.component';\nimport {TableSelectColumnsComponent} from './table/table-select-columns.component';\nimport {IonicStorageModule} from '@ionic/storage';\nimport {HomePage} from './home/home';\nimport {RegisterForm} from './register/form/form-register';\nimport {RegisterModal} from './register/modal/modal-register';\nimport {AppGraphQLModule} from './graphql/graphql.module';\n// import ngx-translate and the http loader\nimport {HttpClientModule} from '@angular/common/http';\nimport {SelectPeerModal} from './peer/select-peer.modal';\nimport {SettingsPage} from './settings/settings.page';\nimport {CacheModule} from 'ionic-cache';\nimport {AppPropertiesForm} from './form/properties.form';\nimport {AppListForm} from './form/list.form';\nimport {PlatformService} from './services/platform.service';\nimport {IsNotOnFieldModePipe, IsOnFieldModePipe} from './services/pipes/usage-mode.pipes';\nimport {PersonToStringPipe} from './services/pipes/person-to-string.pipe';\nimport {AppInstallUpgradeCard} from './install/install-upgrade-card.component';\nimport {AccountToStringPipe, IsLoginAccountPipe} from './services/pipes/account.pipes';\nimport {DepartmentToStringPipe} from './services/pipes/department-to-string.pipe';\nimport {NgxJdenticonModule} from 'ngx-jdenticon';\nimport {ActionsColumnComponent} from './table/actions-column.component';\nimport {AppMenuModule} from './menu/menu.module';\nimport {TextPopover} from './text-popover/text-popover.component';\nimport {TextForm} from './text-popover/text-form.component';\nimport {AppUpdateOfflineModeCard} from './offline/update-offline-mode-card.component';\nimport {AppIconModule} from './icon/icon.module';\n\n@NgModule({\n imports: [\n SharedModule,\n RouterModule,\n HttpClientModule,\n CacheModule,\n IonicStorageModule,\n NgxJdenticonModule,\n\n // Sub modules\n AppGraphQLModule,\n AppMenuModule,\n AppIconModule\n ],\n\n declarations: [\n // Pipes\n IsOnFieldModePipe,\n IsNotOnFieldModePipe,\n PersonToStringPipe,\n IsLoginAccountPipe,\n AccountToStringPipe,\n DepartmentToStringPipe,\n\n // Home and menu\n HomePage,\n AboutModal,\n\n // Auth & Register\n AuthForm,\n AuthModal,\n RegisterForm,\n RegisterModal,\n RegisterConfirmPage,\n AccountPage,\n SettingsPage,\n\n // Network\n SelectPeerModal,\n AppInstallUpgradeCard,\n AppUpdateOfflineModeCard,\n\n // Other components\n TableSelectColumnsComponent,\n ActionsColumnComponent,\n EntityMetadataComponent,\n FormButtonsBarComponent,\n AppPropertiesForm,\n AppListForm,\n TextPopover,\n TextForm\n ],\n exports: [\n SharedModule,\n RouterModule,\n\n // Sub modules\n AppGraphQLModule,\n AppMenuModule,\n AppIconModule,\n\n // Pipes\n IsOnFieldModePipe,\n IsNotOnFieldModePipe,\n PersonToStringPipe,\n IsLoginAccountPipe,\n AccountToStringPipe,\n\n // Components\n HomePage,\n AuthForm,\n AuthModal,\n TableSelectColumnsComponent,\n ActionsColumnComponent,\n EntityMetadataComponent,\n FormButtonsBarComponent,\n AboutModal,\n AppPropertiesForm,\n AppListForm,\n AppInstallUpgradeCard,\n AppUpdateOfflineModeCard,\n DepartmentToStringPipe,\n TextPopover,\n TextForm\n ]\n})\nexport class CoreModule {\n\n static forRoot(): ModuleWithProviders<CoreModule> {\n console.info('[core] Creating module (root)');\n return {\n ngModule: CoreModule,\n providers: [\n PlatformService\n ]\n };\n }\n}\n","import {Inject, Injectable} from '@angular/core';\nimport {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree} from '@angular/router';\nimport {Observable} from 'rxjs';\nimport {ModalController} from '@ionic/angular';\nimport {AuthModal} from '../auth/modal/modal-auth';\nimport {AccountService} from './account.service';\nimport {ENVIRONMENT} from '../../../environments/environment.class';\n\n@Injectable({providedIn: 'root'})\nexport class AuthGuardService implements CanActivate {\n\n private readonly _debug: boolean;\n\n constructor(private accountService: AccountService,\n private modalCtrl: ModalController,\n private router: Router,\n @Inject(ENVIRONMENT) protected environment\n ) {\n this._debug = !environment.production;\n }\n\n canActivate(\n next: ActivatedRouteSnapshot,\n state: RouterStateSnapshot\n ): Observable<boolean> | Promise<boolean | UrlTree> | boolean | UrlTree {\n\n // If account not started: loop after started\n if (!this.accountService.started) {\n return this.accountService.ready()\n // Iterate\n .then(() => this.canActivate(next, state) as Promise<boolean | UrlTree>);\n }\n\n // Force login\n if (!this.accountService.isLogin()) {\n if (this._debug) console.debug('[auth-gard] Need authentication for page /' + next.url.join('/'));\n return this.login(next)\n .then(res => {\n if (!res) {\n if (this._debug) console.debug('[auth-gard] Authentication cancelled. Could not access to /' + next.url.join('/'));\n return this.router.parseUrl('/home');\n }\n // Iterate\n return this.canActivate(next, state) as Promise<boolean | UrlTree>;\n });\n }\n\n if (next.data && next.data.profile && !this.accountService.hasMinProfile(next.data.profile)) {\n if (this._debug) console.debug('[auth-gard] Not authorized access to /' + next.url.join('/') + '. Missing required profile: ' + next.data.profile);\n return false;\n }\n if (this._debug) console.debug('[auth-gard] Authorized access to /' + next.url.join('/'));\n return true;\n }\n\n login(next?: ActivatedRouteSnapshot): Promise<boolean> {\n return new Promise<boolean>(async (resolve) => {\n const modal = await this.modalCtrl.create({component: AuthModal, componentProps: {next}});\n modal.onDidDismiss()\n .then(() => {\n if (this.accountService.isLogin()) {\n resolve(true);\n return;\n }\n resolve(false);\n });\n return modal.present();\n });\n }\n}\n","import {Observable, of} from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { ErrorCodes } from './errors';\n\nimport { FetchPolicy, InternalRefetchQueriesInclude, MutationUpdaterFn } from '@apollo/client/core';\nimport { SortDirection } from '@angular/material/sort';\n\nimport { BaseGraphqlService } from './base-graphql-service.class';\nimport { EntitiesServiceWatchOptions, EntityServiceLoadOptions, IEntitiesService, IEntityService, LoadResult } from '../../shared/services/entity-service.class';\nimport { GraphqlService } from '../graphql/graphql.service';\nimport { PlatformService } from './platform.service';\nimport { environment } from '../../../environments/environment';\nimport { Entity, EntityAsObjectOptions, EntityUtils } from './model/entity.model';\nimport { chainPromises } from '../../shared/observables';\nimport {isEmptyArray, isNil, isNotNil, removeEnd, toBoolean, toNumber} from '../../shared/functions';\nimport { Directive } from '@angular/core';\nimport { FetchResult } from '@apollo/client/link/core';\nimport { EntityFilter, EntityFilterUtils } from './model/filter.model';\nimport { DocumentNode } from 'graphql';\n\nexport type MutableWatchQueriesUpdatePolicy = 'update-cache' | 'refetch-queries';\n\nexport interface BaseEntityGraphqlQueries {\n load?: any;\n loadAll: any;\n loadAllWithTotal?: any;\n countAll?: any;\n}\nexport interface BaseEntityGraphqlMutations {\n save?: any;\n delete?: any;\n saveAll?: any;\n deleteAll?: any;\n}\n\nexport interface BaseEntityGraphqlSubscriptions {\n listenChanges?: any;\n}\nexport interface BaseEntityServiceOptions<\n T extends Entity<any, ID>,\n ID = number,\n Q extends BaseEntityGraphqlQueries = BaseEntityGraphqlQueries,\n M extends BaseEntityGraphqlMutations = BaseEntityGraphqlMutations,\n S extends BaseEntityGraphqlSubscriptions = BaseEntityGraphqlSubscriptions> {\n queries: Q;\n mutations?: Partial<M>;\n subscriptions?: Partial<S>;\n equalsFn?: (e1: T, e2: T) => boolean;\n isNewFn?: (e: T) => boolean;\n defaultSortBy?: keyof T;\n defaultSortDirection?: SortDirection;\n watchQueriesUpdatePolicy?: MutableWatchQueriesUpdatePolicy;\n}\n\nexport interface EntitySaveOptions {\n refetchQueries?: ((result: FetchResult<{data: any}>) => InternalRefetchQueriesInclude) | InternalRefetchQueriesInclude;\n awaitRefetchQueries?: boolean;\n update?: MutationUpdaterFn<{ data: any; }>;\n}\n\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class BaseEntityService<\n T extends Entity<T, ID>,\n F extends EntityFilter<F, T, ID>,\n ID = number,\n WO extends EntitiesServiceWatchOptions = EntitiesServiceWatchOptions,\n LO extends EntityServiceLoadOptions = EntityServiceLoadOptions,\n Q extends BaseEntityGraphqlQueries = BaseEntityGraphqlQueries,\n M extends BaseEntityGraphqlMutations = BaseEntityGraphqlMutations,\n S extends BaseEntityGraphqlSubscriptions = BaseEntityGraphqlSubscriptions>\n extends BaseGraphqlService<T, F, ID>\n implements\n IEntitiesService<T, F, WO>,\n IEntityService<T, ID, LO> {\n\n protected readonly _typename: string;\n protected readonly _logTypeName: string;\n\n protected readonly queries: Q;\n protected readonly mutations: Partial<M>;\n protected readonly subscriptions: Partial<S>;\n protected readonly equalsFn: (e1: T, e2: T) => boolean;\n protected readonly isNewFn: (e: T) => boolean;\n\n protected readonly defaultSortBy: keyof T;\n protected readonly defaultSortDirection: SortDirection;\n protected readonly watchQueriesUpdatePolicy: MutableWatchQueriesUpdatePolicy;\n\n protected constructor(\n protected graphql: GraphqlService,\n protected platform: PlatformService,\n protected dataType: new() => T,\n protected filterType: new() => F,\n options: BaseEntityServiceOptions<T, ID, Q, M, S>\n ) {\n super(graphql, environment);\n this.queries = options.queries;\n this.mutations = options.mutations || <Partial<M>>{};\n this.subscriptions = options.subscriptions || <Partial<S>>{};\n this.equalsFn = options.equalsFn || ((e1, e2) => EntityUtils.equals(e1, e2, 'id'));\n this.isNewFn = options.isNewFn || ((e) => EntityUtils.isNotEmpty(e, 'id'));\n this.defaultSortBy = options.defaultSortBy || 'id';\n this.defaultSortDirection = options.defaultSortDirection || 'asc';\n this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';\n\n const obj = new dataType();\n this._typename = obj.__typename || 'UnknownVO';\n this._logTypeName = removeEnd(this._typename, 'VO');\n\n // For DEV only\n this._debug = !environment.production;\n }\n\n watch(id: number, opts?: WO & { query?: any }): Observable<T> {\n\n if (this._debug) console.debug(this._logPrefix + `Watching ${this._logTypeName} {${id}}...`);\n\n const query = opts && opts.query || this.queries.load;\n return this.graphql.watchQuery<{data: any}>({\n query,\n variables: { id },\n fetchPolicy: opts && (opts.fetchPolicy as FetchPolicy) || undefined,\n error: {code: ErrorCodes.LOAD_DATA_ERROR, message: 'REFERENTIAL.ERROR.LOAD_DATA_ERROR'}\n })\n .pipe(\n map(({data}) => (!opts || opts.toEntity !== false)\n ? (data && this.fromObject(data))\n : (data as T))\n );\n }\n\n async load(id: ID, opts?: LO & { query?: any }): Promise<T> {\n\n if (this._debug) console.debug(this._logPrefix + `Loading ${this._logTypeName} {${id}}...`);\n const query = opts && opts.query || this.queries.load;\n\n const { data } = await this.graphql.query<{data: any}>({\n query,\n variables: { id },\n fetchPolicy: opts && (opts.fetchPolicy as FetchPolicy) || undefined,\n error: {code: ErrorCodes.LOAD_DATA_ERROR, message: 'REFERENTIAL.ERROR.LOAD_DATA_ERROR'}\n });\n\n // Convert to entity\n return (!opts || opts.toEntity !== false)\n ? (data && this.fromObject(data))\n : (data as T);\n }\n\n watchAll(offset: number,\n size: number,\n sortBy?: string,\n sortDirection?: SortDirection,\n filter?: F,\n opts?: WO & { query?: any }\n ): Observable<LoadResult<T>> {\n\n filter = this.asFilter(filter);\n\n const variables: any = {\n offset: offset || 0,\n size: size || 100,\n sortBy: sortBy || this.defaultSortBy,\n sortDirection: sortDirection || this.defaultSortDirection,\n filter: filter && filter.asPodObject()\n };\n\n let now = this._debug && Date.now();\n if (this._debug) console.debug(this._logPrefix + `Watching ${this._logTypeName}...`, variables);\n\n const withTotal = (!opts || opts.withTotal !== false) && this.queries.loadAllWithTotal && true;\n const query = (opts && opts.query) // use given query\n // Or get loadAll or loadAllWithTotal query\n || (withTotal ? this.queries.loadAllWithTotal : this.queries.loadAll);\n return this.mutableWatchQuery<LoadResult<any>>({\n queryName: withTotal ? 'LoadAllWithTotal' : 'LoadAll',\n query,\n arrayFieldName: 'data',\n totalFieldName: withTotal ? 'total' : undefined,\n insertFilterFn: filter && filter.asFilterFn(),\n variables,\n error: {code: ErrorCodes.LOAD_DATA_ERROR, message: 'REFERENTIAL.ERROR.LOAD_DATA_ERROR'},\n fetchPolicy: opts && opts.fetchPolicy || undefined\n })\n .pipe(\n map(({data, total}) => {\n // Convert to entity (if need)\n const entities = (!opts || opts.toEntity !== false)\n ? (data || []).map(json => this.fromObject(json))\n : (data || []) as T[];\n\n if (now) {\n console.debug(this._logPrefix + `${this._logTypeName} loaded in ${Date.now() - now}ms`, entities);\n now = null;\n }\n return {data: entities, total};\n })\n );\n }\n\n async loadAll(offset: number,\n size: number,\n sortBy?: string,\n sortDirection?: SortDirection,\n filter?: Partial<F>,\n opts?: LO & {\n query?: any;\n debug?: boolean;\n withTotal?: boolean;\n }\n ): Promise<LoadResult<T>> {\n\n const debug = this._debug && (!opts || opts.debug !== false);\n\n filter = this.asFilter(filter);\n\n const variables: any = {\n offset: offset || 0,\n size: size || 100,\n sortBy: sortBy || 'id',\n sortDirection: sortDirection || 'asc',\n filter: filter && filter.asPodObject()\n };\n\n const now = Date.now();\n if (debug) console.debug(this._logPrefix + `Loading ${this._logTypeName}...`, variables);\n\n const withTotal = (!opts || opts.withTotal !== false) && this.queries.loadAllWithTotal && true;\n const query = (opts && opts.query) // use given query\n // Or get loadAll or loadAllWithTotal query\n || (withTotal ? this.queries.loadAllWithTotal : this.queries.loadAll);\n const {data, total} = await this.graphql.query<LoadResult<any>>({\n query,\n variables,\n error: {code: ErrorCodes.LOAD_DATA_ERROR, message: 'ERROR.LOAD_DATA_ERROR'},\n fetchPolicy: opts && opts.fetchPolicy || 'network-only'\n });\n\n const entities = (!opts || opts.toEntity !== false) ?\n (data || []).map(json => this.fromObject(json)) :\n (data || []) as T[];\n if (debug) console.debug(this._logPrefix + `${this._logTypeName} items loaded in ${Date.now() - now}ms`);\n\n const result: LoadResult<T> = {\n data: entities,\n total: total || entities.length\n };\n\n // Add fetch more capability, if total was fetched\n if (withTotal) {\n const nextOffset = (offset || 0) + entities.length;\n if (nextOffset < result.total) {\n result.fetchMore = () => this.loadAll(nextOffset, size, sortBy, sortDirection, filter, opts);\n }\n }\n\n return result;\n }\n\n async countAll(filter?: Partial<F>, opts?: LO) {\n // If no countAll query\n if (!this.queries.countAll) {\n // Fail if no loadAll (cannot count)\n if (!this.queries.loadAllWithTotal) throw new Error('Not implemented');\n\n // Use loadAll query, with size = 0;\n return (await this.loadAll(0, 1, null, null, filter,\n <LO & { withTotal: boolean; }>{withTotal: true}))?.total || 0;\n }\n\n filter = this.asFilter(filter);\n\n const res = await this.graphql.query<{ total: number;}>({\n query: this.queries.countAll,\n variables: {\n filter: filter && filter.asPodObject()\n },\n error: {code: ErrorCodes.LOAD_DATA_ERROR, message: 'ERROR.COUNT_DATA_ERROR'},\n fetchPolicy: opts && opts.fetchPolicy || 'network-only'\n });\n return res.total;\n }\n\n canUserWrite(data: T, opts?: any): boolean {\n return !!data;\n }\n\n async saveAll(entities: T[], opts?: EntitySaveOptions): Promise<T[]> {\n if (isEmptyArray(entities)) return entities; // Nothing to save: skip\n\n if (!this.mutations.saveAll) {\n if (!this.mutations.save) throw new Error('Not implemented');\n // Save one by one\n return chainPromises((entities || [])\n .map(entity => (() => this.save(entity, opts))));\n }\n\n let hasNewEntities = false;\n const json = entities.map(entity => {\n hasNewEntities = hasNewEntities || this.isNewFn(entity);\n this.fillDefaultProperties(entity);\n return this.asObject(entity);\n });\n\n const now = Date.now();\n if (this._debug) console.debug(this._logPrefix + `Saving all ${this._logTypeName}...`, json);\n\n await this.graphql.mutate<LoadResult<any>>({\n mutation: this.mutations.saveAll,\n refetchQueries: this.getRefetchQueriesForMutation(opts),\n awaitRefetchQueries: opts && opts.awaitRefetchQueries,\n variables: {\n data: json\n },\n error: {code: ErrorCodes.SAVE_DATA_ERROR, message: 'ERROR.SAVE_DATA_ERROR'},\n update: (proxy, {data}) => {\n const savedEntities = data && data.data;\n if (savedEntities) {\n // Update entities (id and update date)\n entities.forEach(entity => {\n const savedEntity = savedEntities.find(e => this.equalsFn(e, entity));\n this.copyIdAndUpdateDate(savedEntity, entity);\n });\n\n if (hasNewEntities && this.watchQueriesUpdatePolicy === 'update-cache') {\n // Update the cache\n this.insertIntoMutableCachedQueries(proxy, {\n queries: this.getLoadQueries(),\n data: savedEntities\n });\n }\n }\n\n if (opts && opts.update) {\n opts.update(proxy, {data});\n }\n\n if (this._debug) console.debug(`${this._logTypeName} saved in ${Date.now() - now}ms`, entities);\n\n }\n });\n\n return entities;\n }\n\n /**\n * Save a referential entity\n *\n * @param entity\n * @param opts\n */\n async save(entity: T, opts?: EntitySaveOptions): Promise<T> {\n if (!this.mutations.save) {\n if (!this.mutations.saveAll) throw new Error('Not implemented');\n const data = await this.saveAll([entity], opts);\n return data && data[0];\n }\n\n // Fill default properties\n this.fillDefaultProperties(entity);\n\n // Transform into json\n const json = this.asObject(entity);\n\n const isNew = this.isNewFn(json);\n\n const now = Date.now();\n if (this._debug) console.debug(this._logPrefix + `Saving ${this._logTypeName}...`, json);\n\n await this.graphql.mutate<{data: any}>({\n mutation: this.mutations.save,\n refetchQueries: this.getRefetchQueriesForMutation(opts),\n awaitRefetchQueries: opts && opts.awaitRefetchQueries,\n variables: {\n data: json\n },\n error: {code: ErrorCodes.SAVE_DATA_ERROR, message: 'ERROR.SAVE_DATA_ERROR'},\n update: (cache, {data}) => {\n // Update entity\n const savedEntity = data && data.data;\n this.copyIdAndUpdateDate(savedEntity, entity);\n\n // Insert into the cache\n if (isNew && this.watchQueriesUpdatePolicy === 'update-cache') {\n this.insertIntoMutableCachedQueries(cache, {\n queries: this.getLoadQueries(),\n data: savedEntity\n });\n }\n\n if (opts && opts.update) {\n opts.update(cache, {data});\n }\n\n if (this._debug) console.debug(this._logPrefix + `${entity.__typename} saved in ${Date.now() - now}ms`, entity);\n }\n });\n\n return entity;\n }\n\n /**\n * Delete referential entities\n */\n async deleteAll(entities: T[], opts?: Partial<{\n update: MutationUpdaterFn<any>;\n }> | any): Promise<any> {\n if (!this.mutations.deleteAll) {\n if (!this.mutations.delete) throw new Error('Not implemented');\n // Delete one by one\n return chainPromises((entities || [])\n .map(entity => (() => this.delete(entity, opts))));\n }\n\n // Filter saved entities\n entities = entities && entities.filter(e => isNotNil(e.id));\n\n // Nothing to save: skip\n if (isEmptyArray(entities)) return;\n\n const ids = entities.map(t => t.id);\n const now = Date.now();\n if (this._debug) console.debug(this._logPrefix + `Deleting ${this._logTypeName}...`, ids);\n\n await this.graphql.mutate<any>({\n mutation: this.mutations.deleteAll,\n refetchQueries: this.getRefetchQueriesForMutation(opts),\n awaitRefetchQueries: opts && opts.awaitRefetchQueries,\n variables: { ids },\n error: {code: ErrorCodes.DELETE_DATA_ERROR, message: 'ERROR.DELETE_DATA_ERROR'},\n update: (cache, res) => {\n\n // Remove from cache\n if (this.watchQueriesUpdatePolicy === 'update-cache') {\n this.removeFromMutableCachedQueriesByIds(cache, {\n queries: this.getLoadQueries(),\n ids\n });\n }\n\n if (opts && opts.update) {\n opts.update(cache, res);\n }\n\n if (this._debug) console.debug(this._logPrefix + `${this._logTypeName} deleted in ${Date.now() - now}ms`);\n }\n });\n }\n\n /**\n * Delete a referential entity\n */\n async delete(entity: T, opts?: EntitySaveOptions | any): Promise<any> {\n if (!this.mutations.delete) {\n if (!this.mutations.deleteAll) throw new Error('Not implemented');\n const data = await this.deleteAll([entity], opts);\n return data && data[0];\n }\n\n // Nothing to save: skip\n if (!entity || isNil(entity.id)) return;\n\n const id = entity.id;\n const now = new Date();\n if (this._debug) console.debug(this._logPrefix + `Deleting ${this._logTypeName} {${id}}...`);\n\n await this.graphql.mutate<any>({\n mutation: this.mutations.delete,\n refetchQueries: this.getRefetchQueriesForMutation(opts),\n awaitRefetchQueries: opts && opts.awaitRefetchQueries,\n variables: { id },\n error: {code: ErrorCodes.DELETE_DATA_ERROR, message: 'ERROR.DELETE_DATA_ERROR'},\n update: (proxy, res) => {\n\n // Remove from cache\n if (this.watchQueriesUpdatePolicy === 'update-cache') {\n this.removeFromMutableCachedQueriesByIds(proxy, {\n queries: this.getLoadQueries(),\n ids: [id]\n });\n }\n\n if (opts && opts.update) {\n opts.update(proxy, res);\n }\n\n if (this._debug) console.debug(this._logPrefix + `${this._logTypeName} deleted in ${new Date().getTime() - now.getTime()}ms`);\n }\n });\n }\n\n listenChanges(id: ID, opts?: {\n query?: any;\n variables?: any;\n interval?: number;\n fetchPolicy?: FetchPolicy;\n toEntity?: boolean;\n }): Observable<T> {\n if (isNil(id)) throw Error('Missing argument \\'id\\' ');\n if (!this.subscriptions.listenChanges) {\n console.warn(`${this.constructor.name}.listenChanges() not implemented yet. Will empty observable`);\n return of();\n }\n\n const variables = opts?.variables || {\n id,\n interval: toNumber(opts && opts.interval, 0) // no timer by default\n };\n if (this._debug) console.debug(this._logPrefix + `[WS] Listening for changes on ${this._logTypeName} {${id}}...`);\n\n return this.graphql.subscribe<{data: any}>({\n query: opts?.query || this.subscriptions.listenChanges,\n fetchPolicy: opts?.fetchPolicy || 'no-cache',\n variables,\n error: {\n code: ErrorCodes.SUBSCRIBE_DATA_ERROR,\n message: 'ERROR.SUBSCRIBE_DATA_ERROR'\n }\n })\n .pipe(\n map(({data}) => {\n const entity = (!opts || opts.toEntity !== false) ? data && this.fromObject(data) : data;\n //if (entity && this._debug) console.debug(this._logPrefix + `[WS] Received changes on ${this._logTypeName} {${id}}`, entity);\n\n // TODO: missing = deleted ?\n if (!entity) console.warn(this._logPrefix + `[WS] Received deletion on ${this._logTypeName} {${id}} - TODO check implementation`);\n\n return entity;\n })\n );\n }\n\n copyIdAndUpdateDate(source: T, target: T) {\n if (!source) return;\n\n // Update (id and updateDate)\n EntityUtils.copyIdAndUpdateDate(source, target);\n }\n\n\n fromObject(source: any): T {\n if (!source) return source;\n const target = new this.dataType();\n target.fromObject(source);\n return target;\n }\n\n asFilter(source: any): F {\n return EntityFilterUtils.fromObject(source, this.filterType);\n }\n\n /* -- protected functions -- */\n\n protected async ngOnStart() {\n // No limit for updatable watch queries, if desktop\n if (!this.platform.mobile) {\n this._mutableWatchQueriesMaxCount = -1;\n }\n }\n\n protected fillDefaultProperties(source: T) {\n // Can be override by subclasses\n }\n\n protected asObject(entity: T, opts?: EntityAsObjectOptions): any {\n // Can be override by subclasses\n return entity.asObject(opts);\n }\n\n protected getRefetchQueriesForMutation(opts?: EntitySaveOptions): ((result: FetchResult<{data: any}>) => InternalRefetchQueriesInclude) | InternalRefetchQueriesInclude {\n if (opts && opts.refetchQueries) return opts.refetchQueries;\n\n // Skip if update policy not used refecth queries\n if (this.watchQueriesUpdatePolicy !== 'refetch-queries') return undefined;\n\n const queries = this.getLoadQueries();\n if (!queries.length) return undefined; // Skip if empty\n\n // Find the refetch queries definition\n return this.findRefetchQueries({queries});\n }\n\n protected getLoadQueries(): DocumentNode[] {\n return [this.queries.loadAll, this.queries.loadAllWithTotal].filter(isNotNil);\n }\n\n}\n","import {AppTable} from './table.class';\nimport {debounceTime} from 'rxjs/operators';\nimport {firstFalsePromise} from '../../shared/observables';\nimport {TableElement} from '@e-is/ngx-material-table';\nimport {AppFormUtils} from '../form/form.utils';\n\nexport class AppTableUtils {\n\n static waitIdle(table: AppTable<any, any, any>): Promise<any> {\n if (!table || !table.dataSource) {\n throw new Error('Invalid table. Missing table or table.dataSource');\n }\n return table.dataSource.waitIdle();\n }\n\n static logRowErrors(row: TableElement<any>, logPrefix?: string): void {\n AppFormUtils.logFormErrors(row.validator, logPrefix);\n }\n\n}\n","import {TableDataSource, TableElement, ValidatorService} from '@e-is/ngx-material-table';\nimport {BehaviorSubject, Observable, Subject} from 'rxjs';\nimport {Entity, IEntity} from '../services/model/entity.model';\nimport {ErrorCodes} from '../services/errors';\nimport {catchError, debounceTime, map, takeUntil} from 'rxjs/operators';\nimport {Directive, OnDestroy} from '@angular/core';\nimport {SortDirection} from '@angular/material/sort';\nimport {CollectionViewer} from '@angular/cdk/collections';\nimport {TableDataSourceConfig} from '@e-is/ngx-material-table/src/app/ngx-material-table/table-data-source';\nimport {EntitiesServiceWatchOptions, FetchMoreFn, IEntitiesService, LoadResult} from '../../shared/services/entity-service.class';\nimport {firstFalsePromise} from '../../shared/observables';\nimport {Beans, isEmptyArray, isNotEmptyArray, isNotNil, removeEnd} from '../../shared/functions';\nimport {AppTableUtils} from './table.utils';\nimport {environment} from '../../../environments/environment';\n\n\nexport interface EntitiesTableDataSourceConfig<\n T extends Entity<T, ID>,\n ID = number,\n WO extends EntitiesServiceWatchOptions = EntitiesServiceWatchOptions,\n SO = any\n > extends TableDataSourceConfig {\n\n onRowCreated?: (row: TableElement<T>) => Promise<void> | void;\n saveOnlyDirtyRows?: boolean;\n readOnly?: boolean;\n\n /**\n * @deprecated\n */\n dataServiceOptions?: WO & SO; // Options passed to the dataService.watchAll() and dataService.saveAll()\n\n watchAllOptions?: WO; // Options passed to the dataService.saveAll()\n saveAllOptions?: SO; // Options passed to the dataService.saveAll()\n\n [key: string]: any;\n}\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport class EntitiesTableDataSource<\n T extends IEntity<T, ID>,\n F = any,\n ID = number,\n WO extends EntitiesServiceWatchOptions = EntitiesServiceWatchOptions,\n SO = any,\n V extends ValidatorService = ValidatorService,\n C extends EntitiesTableDataSourceConfig<T, ID, WO, SO> = EntitiesTableDataSourceConfig<T, ID, WO, SO>,\n >\n extends TableDataSource<T, V, C>\n implements OnDestroy {\n\n private readonly _entityName: string;\n\n protected _debug = false;\n protected _creating = false;\n protected _saving = false;\n protected _fetchMoreFn: FetchMoreFn<LoadResult<T>> = null;\n\n protected _stopWatchSubject = new Subject<any>();\n loadingSubject = new BehaviorSubject<boolean>(undefined);\n\n /**\n * @deprecated Use watchAllOptions or saveAllOptions\n */\n get serviceOptions(): WO & SO {\n return this.config.dataServiceOptions\n || {...this.watchAllOptions, ...this.saveAllOptions};\n }\n\n /**\n * @deprecated Use watchAllOptions or saveAllOptions\n */\n set serviceOptions(value: WO & SO) {\n console.warn('dataSource.serviceOptions is deprecated! Please use \\'watchAllOptions\\' or \\'saveAllOptions\\' instead');\n this.config.dataServiceOptions = value;\n }\n\n get watchAllOptions(): WO {\n return this.config.watchAllOptions;\n }\n\n set watchAllOptions(value: WO) {\n this.config.watchAllOptions = value;\n }\n\n get saveAllOptions(): SO {\n return this.config.saveAllOptions;\n }\n\n set saveAllOptions(value: SO) {\n this.config.saveAllOptions = value;\n }\n\n get loaded(): boolean {\n return this.loadingSubject.value === false; // Should be false when undefined (initial state)\n }\n\n get loading(): boolean {\n return this.loadingSubject.value !== false; // Should be true when undefined (initial state)\n }\n\n /**\n * Creates a new TableDataSource instance, that can be used as datasource of `@angular/cdk` data-table.\n *\n * @param dataService A service to load and save data\n * @param dataType Type of data contained by the Table. If not specified, then `data` with at least one element must be specified.\n * @param environment\n * @param validatorService Service that create instances of the FormGroup used to validate row fields.\n * @param config Additional configuration for table.\n */\n constructor(dataType: new() => T,\n public readonly dataService: IEntitiesService<T, F, WO>,\n validatorService?: V,\n options?: C) {\n super([], dataType, validatorService, {\n keepOriginalDataAfterConfirm: false,\n readOnly: false,\n saveOnlyDirtyRows: false,\n ...options\n });\n\n this._entityName = removeEnd((new dataType()).__typename || 'UnknownVO', 'VO');\n this._debug = options?.suppressErrors === false && !environment.production;\n }\n\n /**\n * @deprecated use disconnect\n */\n ngOnDestroy() {\n this.close();\n }\n\n /**\n * @deprecated use disconnect\n */\n close() {\n if (!this._stopWatchSubject.closed) {\n if (this._debug) console.debug('[entities-table-datasource] Closing...');\n this._stopWatchSubject.next();\n this._stopWatchSubject.complete();\n this._stopWatchSubject.unsubscribe();\n this.loadingSubject.complete();\n this.loadingSubject.unsubscribe();\n }\n }\n\n watchAll(offset: number,\n size: number,\n sortBy?: string,\n sortDirection?: SortDirection,\n filter?: Partial<F>): Observable<LoadResult<T>> {\n\n this._stopWatchSubject.next();\n this._fetchMoreFn = null;\n this.markAsLoading();\n\n return this.dataService.watchAll(offset, size, sortBy, sortDirection, filter, this.serviceOptions as WO)\n .pipe(\n catchError(err => this.handleError(err, 'ERROR.LOAD_DATA_ERROR')),\n map((res: LoadResult<T>) => {\n if (this._saving) {\n console.info(`[entities-table-datasource] Received ${this._entityName} data (from service), but still saving: skip`);\n } else if (this.hasSomeEditingRow()) {\n console.warn(`[entities-table-datasource] Received ${this._entityName} data, while some row still editing: skip; Please check save() implementation in the table!`);\n } else {\n this.updateDatasource((res.data || []) as T[]);\n this._fetchMoreFn = res.fetchMore;\n }\n return res;\n }),\n // Stop this pipe next time we call watchAll()\n takeUntil(this._stopWatchSubject)\n // ⚠ Notice: Don't put any operator after takeUntil to avoid potential subscription leaks\n );\n }\n\n protected updateDatasourceFromRows(rows: TableElement<T>[]) {\n // Avoid to update dataSourceSubject, when not need\n if (this.datasourceSubject.observers?.length) {\n if (!this.config.suppressErrors) console.warn('[entities-table-datasource] Update datasource subject. Please prefer using \\'rowsSubject\\' instead of \\'datasourceSubject\\'');\n super.updateDatasourceFromRows(rows);\n }\n else {\n console.debug('[entities-table-datasource] Skipping datasourceSubject update (not used yet).');\n }\n }\n\n async save(): Promise<boolean> {\n if (this.config.readOnly) {\n console.error('[entities-table-datasource] Enable to save, because config.readOnly=true');\n return false;\n }\n // Saving twice (should never occur)\n if (this._saving) {\n console.warn(`[entities-table-datasource] Trying to save ${this._entityName} rows twice. Skip`);\n return false;\n }\n\n this._saving = true;\n this.markAsLoading();\n\n const onlyDirtyRows = this.config.saveOnlyDirtyRows;\n\n try {\n if (this._debug) console.debug(`[entities-table-datasource] Saving ${this._entityName} rows... {onlyDirtyRows: ${onlyDirtyRows}}`);\n\n // Get all rows\n const rows = this.getRows();\n\n // Finish editing all rows\n const invalidRows = rows.filter(row => row.editing && !row.confirmEditCreate());\n\n // Cannot finish some rows: error\n if (invalidRows.length) {\n // log errors\n if (this._debug) invalidRows.forEach(row => AppTableUtils.logRowErrors(row, `[entities-table-datasource] ${this._entityName} row #${row.id}`));\n // Stop with an error\n throw {code: ErrorCodes.TABLE_INVALID_ROW_ERROR, message: 'ERROR.TABLE_INVALID_ROW_ERROR'};\n }\n\n let data: T[];\n let dataToSave: T[];\n\n if (this.validatorService) {\n dataToSave = [];\n data = rows.map(row => {\n const currentData = new this.dataConstructor() as T;\n currentData.fromObject(row.currentData);\n // Filter to keep only dirty row\n if (onlyDirtyRows && row.validator.dirty) dataToSave.push(currentData);\n return currentData;\n });\n if (!onlyDirtyRows) dataToSave = data;\n }\n // Or use the current data without conversion (when no validator service used)\n else {\n data = rows.map(row => row.currentData);\n // save all data, as we don't have any dirty marker\n dataToSave = data;\n }\n\n // If no data to save: exit\n if (onlyDirtyRows && !dataToSave.length) {\n if (this._debug) console.debug(`[entities-table-datasource] No ${this._entityName} data to save. Skip`);\n return false;\n }\n\n if (this._debug) console.debug(`[entities-table-datasource] Asking service to save this ${this._entityName} data:`, dataToSave);\n await this.dataService.saveAll(dataToSave, this.serviceOptions);\n\n if (this._debug) console.debug(`[entities-table-datasource] Saving ${this._entityName} data [OK]`);\n\n // LP 23/03/2021: update datasource is necessary but can be changed to a refetch() on QueryRef (must be created and registered in GraphqlService.watchQuery)\n this.updateDatasource(data, {emitEvent: false});\n\n return true;\n } catch (error) {\n if (this._debug) console.error('[entities-table-datasource] Error while saving: ' + error && error.message || error);\n throw error;\n } finally {\n this._saving = false;\n this.markAsLoaded();\n }\n }\n\n updateDatasource(data: T[], opts?: { emitEvent: boolean }) {\n if (this._debug) console.debug(`[entities-table-datasource] Updating datasource with data:`, data);\n\n super.updateDatasource(data, opts);\n\n if (!opts || opts.emitEvent !== false) {\n this.markAsLoaded();\n }\n }\n\n private viewer: CollectionViewer;\n\n connect(collectionViewer: CollectionViewer): Observable<TableElement<T>[] | ReadonlyArray<TableElement<T>>> {\n // DEBUG console.debug(\"[entities-datasource] connect\");\n this.viewer = collectionViewer;\n return super.connect(collectionViewer);\n }\n\n disconnect(collectionViewer?: CollectionViewer) {\n if (this._debug) console.debug('[entities-table-datasource] Disconnecting...')\n super.disconnect(collectionViewer);\n this.close();\n }\n\n waitIdle(debounceTimeMs?: number): Promise<any> {\n return firstFalsePromise(this.loadingSubject\n .asObservable()\n .pipe(\n debounceTime(debounceTimeMs || 100) // if not started yet, wait\n ));\n }\n\n confirmCreate(row: TableElement<T>) {\n if (!super.confirmCreate(row)) return false;\n if (row.editing && row.validator) {\n console.warn('[entities-table-datasource] Row still has {editing: true} after confirmCreate()! Force editing to false');\n row.validator.disable({onlySelf: true, emitEvent: false});\n }\n return true;\n }\n\n confirmEdit(row: TableElement<T>): boolean {\n if (!super.confirmEdit(row)) return false;\n if (row.editing && row.validator) {\n console.warn('[entities-table-datasource] Row still has {editing: true} after confirmEdit()! Force editing to false');\n row.validator.disable({onlySelf: true, emitEvent: false});\n }\n return true;\n }\n\n startEdit(row: TableElement<T>): boolean {\n if (!super.startEdit(row)) return false;\n if (!row.editing && row.validator) {\n console.warn('[entities-table-datasource] Row still has {editing: false} after startEdit()! Force editing');\n row.validator.enable({onlySelf: true, emitEvent: false});\n }\n }\n\n handleError(error: any, message: string): Observable<LoadResult<T>> {\n const errorMsg = error && error.message || error;\n console.error(`[entities-table-datasource] Service ${this._entityName} sent error: ${errorMsg}`, error);\n this.markAsLoaded();\n throw new Error(message || errorMsg);\n }\n\n handleServiceError(error: any) {\n const errorMsg = error && error.message || error;\n console.error(`[entities-table-datasource] Service ${this._entityName} sent error: ${errorMsg}`, error);\n this.markAsLoaded();\n throw error;\n }\n\n delete(id: number): boolean {\n // If new row: not need to propagate to the dataService\n if (id === -1) {\n return super.delete(id);\n }\n\n const row = this.getRow(id);\n if (!row) {\n console.error(`[entities-table-datasource] Row to delete with id=${id} not found`);\n return;\n }\n\n this.markAsLoading();\n\n this.dataService.deleteAll([row.currentData], this.serviceOptions)\n .catch(err => this.handleServiceError(err))\n .then(() => {\n setTimeout(() => {\n // make sure row has been deleted (because GrapQHl cache remove can failed)\n const present = this.getRow(id) === row;\n if (present) super.delete(id);\n\n this.markAsLoaded();\n }, 300);\n });\n }\n\n async deleteAll(rows: TableElement<T>[]): Promise<any> {\n\n this.markAsLoading();\n\n const data = this.getDataFromRows(rows);\n\n try {\n\n // Call service deletion\n await this.dataService.deleteAll(data, this.serviceOptions);\n\n // Workaround, to be sure all rows have been deleted\n // Sometime, the service miss deletion, or GraphQl cache remove failed.\n // In this case, apply missing deletion using the super.delete() function\n const rowNotDeleted = this.getRows().filter(row => rows.includes(row));\n if (isNotEmptyArray(rowNotDeleted)) {\n console.warn(`[entities-table-datasource] Force deletion of ${rowNotDeleted.length} rows! Please check that data service update the cache, after deletion`);\n rowNotDeleted\n // Start at the end\n .sort((a, b) => a.id > b.id ? -1 : 1)\n .forEach(r => super.delete(r.id));\n }\n }\n catch (err) {\n // Handle service error\n this.handleServiceError(err);\n }\n finally {\n this.markAsLoaded();\n }\n }\n\n getRow(id: number): TableElement<T> {\n return super.getRow(id);\n }\n\n getRows(): TableElement<T>[] {\n return this.rowsSubject.getValue();\n }\n\n hasSomeEditingRow() {\n return (this.rowsSubject.value || []).some(row => row.editing);\n }\n\n async createNew(insertAt?: number, options = {editing: true}): Promise<TableElement<T>|undefined> {\n if (this._creating) return; // Avoid multiple call (should never occur)\n\n this._creating = true;\n\n try {\n const row = await super.createNew(insertAt, options);\n if (!row) return;\n\n if (this.config?.onRowCreated) {\n try {\n await this.config.onRowCreated(row);\n }\n catch (err) {\n // Log, then continue\n console.error(err && err.message || err, err);\n }\n }\n\n return row;\n }\n finally {\n this._creating = false;\n }\n }\n\n getData(): T[] {\n const rows = this.getRows();\n return this.getDataFromRows(rows);\n }\n\n async fetchMore(opts?: { emitEvent: boolean }): Promise<boolean> {\n if (!this._fetchMoreFn) return false; // Avoid multiple call\n if (this.hasSomeEditingRow()) {\n console.warn(`Cannot fetch more ${this._entityName} because some row) still editing`);\n return;\n }\n console.debug(`Will fetching more row(s) still...`);\n\n // Forget the fetchMore function, to avoid multiple call\n const fetchMoreFn = this._fetchMoreFn;\n this._fetchMoreFn = null;\n\n // Fetch next page\n const res: LoadResult<T> = await fetchMoreFn();\n\n // Skip if empty (no more data)\n if (isEmptyArray(res?.data)) return false;\n\n // Update the data source\n super.updateDatasource((this.currentData || []).concat(...res.data), opts);\n\n // Remember fetchMore\n this._fetchMoreFn = res.fetchMore;\n return true;\n }\n\n /* -- protected method -- */\n\n markAsLoading() {\n if (this.loadingSubject.value !== true) {\n this.loadingSubject.next(true);\n }\n }\n\n markAsLoaded() {\n if (this.loadingSubject.value !== false) {\n this.loadingSubject.next(false);\n }\n }\n}\n","import {AfterViewInit, Directive, EventEmitter, Injector, Input, OnDestroy, OnInit, Output, ViewChild} from '@angular/core';\nimport {MatPaginator} from '@angular/material/paginator';\nimport {MatSort, MatSortable, SortDirection} from '@angular/material/sort';\nimport {MatTable} from '@angular/material/table';\nimport {BehaviorSubject, combineLatest, EMPTY, merge, Observable, of, Subject, Subscription} from 'rxjs';\nimport {catchError, debounceTime, distinctUntilChanged, filter, first, map, mergeMap, startWith, switchMap, takeUntil, tap} from 'rxjs/operators';\nimport {TableElement} from '@e-is/ngx-material-table';\nimport {EntitiesTableDataSource} from './entities-table-datasource.class';\nimport {SelectionModel} from '@angular/cdk/collections';\nimport {EntityUtils, IEntity} from '../services/model/entity.model';\nimport {AlertController, ModalController, ToastController} from '@ionic/angular';\nimport {ActivatedRoute, Router} from '@angular/router';\nimport {ColumnItem, TableSelectColumnsComponent} from './table-select-columns.component';\nimport {Location} from '@angular/common';\nimport {ErrorCodes} from '../services/errors';\nimport {AppFormUtils, IAppForm, OnReady} from '../form/form.utils';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {TranslateService} from '@ngx-translate/core';\nimport {MatAutocompleteConfigHolder, MatAutocompleteFieldAddOptions, MatAutocompleteFieldConfig} from '../../shared/material/autocomplete/material.autocomplete';\nimport {CompletableEvent, createPromiseEventEmitter, emitPromiseEvent} from '../../shared/events';\nimport {changeCaseToUnderscore, isEmptyArray, isNil, isNotEmptyArray, isNotNil, toBoolean} from '../../shared/functions';\nimport {waitFor, waitForFalse, WaitForOptions, waitForTrue} from '../../shared/observables';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {Alerts} from '../../shared/alerts';\nimport {CdkColumnDef} from '@angular/cdk/table';\nimport {LoadResult} from '../../shared/services/entity-service.class';\nimport {FormErrorTranslator, FormErrorTranslatorOptions, IFormControlPathTranslator} from '../../shared/validator/form-error-adapter.class';\n\nexport const SETTINGS_DISPLAY_COLUMNS = 'displayColumns';\nexport const SETTINGS_SORTED_COLUMN = 'sortedColumn';\nexport const SETTINGS_FILTER = 'filter';\nexport const SETTINGS_PAGE_SIZE = 'pageSize';\nexport const DEFAULT_PAGE_SIZE = 20;\nexport const DEFAULT_PAGE_SIZE_OPTIONS = [20, 50, 100, 200, 500];\nexport const RESERVED_START_COLUMNS = ['select', 'id'];\nexport const RESERVED_END_COLUMNS = ['actions'];\nexport const DEFAULT_REQUIRED_COLUMNS = ['id'];\n\nexport class CellValueChangeListener {\n subject: Subject<any>;\n subscription: Subscription; // The row start editing subscription\n formPath: string;\n emitInitialValue: boolean;\n}\n\n\nexport interface IModalDetailOptions<T = any> {\n // Data\n isNew: boolean;\n data: T;\n disabled: boolean;\n\n // Callback functions\n onDelete?: (event: UIEvent, data: T) => Promise<boolean>;\n}\n\nexport type SaveActionType = 'delete' | 'sort' | 'filter';\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppTable<\n T extends IEntity<T, ID>,\n F = any,\n ID = number\n >\n implements OnInit, OnDestroy, AfterViewInit, IAppForm, IFormControlPathTranslator {\n\n private _initialized = false;\n private _subscription = new Subscription();\n private _dataSourceLoadingSubscription: Subscription;\n\n private _cellValueChangesDefs: {\n [key: string]: CellValueChangeListener;\n } = {};\n\n protected _enabled = true;\n protected _autocompleteConfigHolder: MatAutocompleteConfigHolder;\n protected allowRowDetail = true;\n protected route: ActivatedRoute;\n protected router: Router;\n protected location: Location;\n protected settings: LocalSettingsService;\n protected translate: TranslateService;\n protected modalCtrl: ModalController;\n protected alertCtrl: AlertController;\n protected toastController: ToastController;\n protected previouslyEditedRowId: number;\n protected formErrorAdapter: FormErrorTranslator;\n protected readonly destroySubject = new Subject();\n\n excludesColumns: string[] = [];\n displayedColumns: string[];\n totalRowCount: number|null = null;\n visibleRowCount: number;\n errorTranslatorOptions: FormErrorTranslatorOptions;\n\n readonly readySubject = new BehaviorSubject<boolean>(false);\n readonly loadingSubject = new BehaviorSubject<boolean>(true);\n readonly savingSubject = new BehaviorSubject<boolean>(false);\n readonly touchedSubject = new BehaviorSubject<boolean>(false);\n readonly dirtySubject = new BehaviorSubject<boolean>(false);\n readonly errorSubject = new BehaviorSubject<string>(undefined);\n\n get error(): string {\n return this.errorSubject.value;\n }\n\n /**\n * @deprecated\n */\n get error$(): Observable<string> {\n return this.errorSubject.asObservable();\n }\n\n\n set error(error: string) {\n this.setError(error);\n }\n\n /**\n * @deprecated\n */\n get loading$(): Observable<boolean> {\n return this.loadingSubject.asObservable();\n }\n\n /**\n * @deprecated\n */\n get saving$(): Observable<boolean> {\n return this.savingSubject.asObservable();\n }\n\n selection = new SelectionModel<TableElement<T>>(true, []);\n editedRow: TableElement<T> = undefined;\n autocompleteFields: {[key: string]: MatAutocompleteFieldConfig};\n readonly mobile: boolean;\n\n // Table options\n @Input() settingsId: string;\n @Input() debug: boolean;\n @Input() i18nColumnPrefix = 'COMMON.';\n @Input() i18nColumnSuffix: string;\n @Input() autoLoad = true;\n @Input() readOnly: boolean;\n @Input() inlineEdition: boolean;\n @Input() focusFirstColumn = false;\n @Input() confirmBeforeDelete = false;\n @Input() confirmBeforeCancel = false;\n @Input() undoableDeletion = false;\n @Input() saveBeforeDelete: boolean;\n @Input() keepEditedRowOnSave: boolean;\n @Input() saveBeforeSort: boolean;\n @Input() saveBeforeFilter: boolean;\n @Input() propagateRowError = false;\n\n @Input() defaultSortBy: string;\n @Input() defaultSortDirection: SortDirection;\n @Input() defaultPageSize = DEFAULT_PAGE_SIZE;\n @Input() defaultPageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS;\n\n // Focus manager\n @Input() focusColumn: string;\n\n get firstUserColumn(): string {\n return this.displayedColumns[RESERVED_START_COLUMNS.length];\n }\n\n get lastUserColumn(): string {\n return this.displayedColumns[this.displayedColumns.length - RESERVED_END_COLUMNS.length - 1];\n }\n\n @Input() set dataSource(value: EntitiesTableDataSource<T, F, ID>) {\n this.setDatasource(value);\n }\n\n get dataSource(): EntitiesTableDataSource<T, F, ID> {\n return this._dataSource;\n }\n\n @Input() set filter(value: F) {\n this.setFilter(value);\n }\n\n get filter(): F {\n return this._filter;\n }\n\n get empty(): boolean {\n return this.loading || this.totalRowCount === 0;\n }\n\n @Output() onRefresh = new EventEmitter<any>();\n @Output() onOpenRow = new EventEmitter<{ id?: ID; row: TableElement<T> }>();\n @Output() onNewRow = new EventEmitter<any>();\n @Output() onStartEditingRow = new EventEmitter<TableElement<T>>();\n @Output() onConfirmEditCreateRow = new EventEmitter<TableElement<T>>();\n @Output() onCancelOrDeleteRow = new EventEmitter<TableElement<T>>();\n @Output() onBeforeDeleteRows = createPromiseEventEmitter<boolean, {rows: TableElement<T>[]}>();\n @Output() onBeforeCancelRows = createPromiseEventEmitter<boolean, {rows: TableElement<T>[]}>();\n @Output() onBeforeSave = createPromiseEventEmitter<{confirmed: boolean; save: boolean}, {action: SaveActionType; valid: boolean}>();\n @Output() onAfterDeletedRows = new EventEmitter<TableElement<T>[]>();\n @Output() onSort = new EventEmitter<any>();\n @Output() onDirty = new EventEmitter<boolean>();\n @Output() onError = new EventEmitter<string>();\n\n get dirty(): boolean {\n return this.dirtySubject.value;\n }\n\n get valid(): boolean {\n return this.editedRow && this.editedRow.editing ? this.editedRow.validator?.valid : true;\n }\n\n get invalid(): boolean {\n return this.editedRow && this.editedRow.editing ? this.editedRow.validator?.invalid : false;\n }\n\n get pending(): boolean {\n return this.editedRow && this.editedRow.editing ? this.editedRow.validator?.pending : false;\n }\n\n get touched(): boolean {\n return this.touchedSubject.value;\n }\n\n get untouched(): boolean {\n return !this.touchedSubject.value;\n }\n\n disable(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.sort) this.sort.disabled = true;\n this._enabled = false;\n }\n\n enable(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.sort) this.sort.disabled = false;\n this._enabled = true;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n // FIXME: need to hidden buttons (in HTML), etc. when disabled\n @Input() set disabled(value: boolean) {\n if (value !== !this._enabled) {\n if (value) this.disable({emitEvent: false});\n else this.enable({emitEvent: false});\n }\n }\n\n get disabled(): boolean {\n return !this._enabled;\n }\n\n markAsDirty(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.dirtySubject.value !== true) {\n this.dirtySubject.next(true);\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n markAsPristine(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.dirtySubject.value !== false) {\n this.dirtySubject.next(false);\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n markAsUntouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n let needEmitEvent = false;\n if (this.touchedSubject.value) {\n this.touchedSubject.next(false);\n needEmitEvent = true;\n }\n if (this.dirty || (this.editedRow && this.editedRow.id !== this.previouslyEditedRowId)) {\n // Cancel the current editing row only if editing and if it was not previously saved\n if (this.editedRow?.editing) {\n this.dataSource.cancelOrDelete(this.editedRow);\n\n // Mark row as pristine\n this.checkIfRowPristine(this.editedRow, {emitEvent: false});\n }\n this.editedRow = null;\n needEmitEvent = true;\n }\n this.previouslyEditedRowId = undefined;\n if (needEmitEvent && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n /**\n * @deprecated prefer to use markAllAsTouched()\n * @param opts\n */\n markAsTouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n console.warn('TODO: Replace this call by markAllAsTouched() - because of changes in ngx-components >= 0.16.0');\n if (this.editedRow?.editing) {\n this.editedRow.validator?.markAllAsTouched();\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n markAllAsTouched(opts?: { emitEvent?: boolean }) {\n if (this.touchedSubject.value !== true) {\n this.touchedSubject.next(true);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n if (this.editedRow?.editing) {\n this.editedRow.validator?.markAllAsTouched();\n }\n }\n\n markAsSaving(opts?: { emitEvent?: boolean }) {\n if (this.savingSubject.value !== true) {\n this.focusColumn = undefined; // unselect focus column\n this.savingSubject.next(true);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n markAsSaved(opts?: { emitEvent?: boolean }) {\n if (this.savingSubject.value !== false) {\n this.savingSubject.next(false);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n markAsLoading(opts?: {emitEvent?: boolean}) {\n this.setLoading(true, opts);\n }\n\n markAsLoaded(opts?: {emitEvent?: boolean}) {\n this.setLoading(false, opts);\n }\n\n markAsReady(opts?: { emitEvent?: boolean }) {\n if (this.readySubject.value !== true) {\n this.readySubject.next(true);\n\n // If subclasses implements OnReady\n if (typeof this['ngOnReady'] === 'function') {\n (this as any as OnReady).ngOnReady();\n }\n }\n }\n\n get loading(): boolean {\n return this.loadingSubject.value;\n }\n\n get loaded(): boolean {\n return !this.loadingSubject.value;\n }\n\n enableSort() {\n if (this.sort) this.sort.disabled = false;\n }\n\n disableSort() {\n if (this.sort) this.sort.disabled = true;\n }\n\n set pageSize(value: number) {\n this.defaultPageSize = value;\n if (this.paginator) {\n this.paginator.pageSize = value;\n }\n }\n\n get pageSize(): number {\n return this.paginator && this.paginator.pageSize || this.defaultPageSize || DEFAULT_PAGE_SIZE;\n }\n\n get pageOffset(): number {\n return this.paginator && this.paginator.pageIndex * this.paginator.pageSize || 0;\n }\n\n get sortActive(): string {\n return this.sort && this.sort.active;\n }\n get sortDirection(): 'asc' | 'desc' {\n return this.sort && this.sort.direction && (this.sort.direction === 'desc' ? 'desc' : 'asc') || undefined;\n }\n\n private _paginator: MatPaginator|null = null;\n\n @Input() set paginator(value: MatPaginator) {\n this._paginator = value;\n }\n\n get paginator(): MatPaginator {\n return this._paginator || this.childPaginator;\n }\n\n @ViewChild(MatTable, {static: false}) table: MatTable<T>;\n @ViewChild(MatPaginator, {static: false}) childPaginator: MatPaginator;\n @ViewChild(MatSort, {static: false}) sort: MatSort;\n\n protected constructor(\n injector: Injector,\n protected columns: string[],\n protected _dataSource?: EntitiesTableDataSource<T, F, ID>,\n private _filter?: F\n ) {\n this.route = injector.get(ActivatedRoute);\n this.router = injector.get(Router);\n this.location = injector.get(Location);\n this.settings = injector.get(LocalSettingsService);\n this.translate = injector.get(TranslateService);\n this.modalCtrl = injector.get(ModalController);\n this.alertCtrl = injector.get(AlertController);\n this.toastController = injector.get(ToastController);\n this.formErrorAdapter = injector.get(FormErrorTranslator);\n this.mobile = this.settings.mobile;\n\n // Autocomplete fields\n this._autocompleteConfigHolder = new MatAutocompleteConfigHolder({\n getUserAttributes: (a, b) => this.settings.getFieldDisplayAttributes(a, b)\n });\n this.autocompleteFields = this._autocompleteConfigHolder.fields;\n }\n\n ngOnInit() {\n if (this._initialized) return; // Init only once\n this._initialized = true;\n\n // Set defaults\n this.readOnly = toBoolean(this.readOnly, this.dataSource?.config.readOnly || false); // read/write by default\n this.inlineEdition = !this.readOnly && toBoolean(this.inlineEdition, false); // force to false when readonly\n this.saveBeforeDelete = toBoolean(this.saveBeforeDelete, !this.readOnly); // force to false when readonly\n this.saveBeforeSort = toBoolean(this.saveBeforeSort, !this.readOnly); // force to false when readonly\n this.saveBeforeFilter = toBoolean(this.saveBeforeFilter, !this.readOnly); // force to false when readonly\n this.keepEditedRowOnSave = toBoolean(this.keepEditedRowOnSave, this.inlineEdition);\n this.errorTranslatorOptions = this.errorTranslatorOptions || { separator: ', ', controlPathTranslator: this}; // Can be override in subclasses constructors\n\n // Check ask user confirmation is possible\n if (this.confirmBeforeDelete && !this.alertCtrl) throw Error('Missing \\'alertCtrl\\' or \\'injector\\' in component\\'s constructor.');\n\n // Defined unique id for settings for the page\n this.settingsId = this.settingsId || this.generateTableId();\n\n this.displayedColumns = this.getDisplayColumns();\n\n // Load the sorted columns, from settings\n {\n const sortedColumn = this.getSortedColumn();\n this.defaultSortBy = sortedColumn.id;\n this.defaultSortDirection = sortedColumn.start;\n }\n\n this.defaultPageSize = this.getPageSize();\n\n // Propagate error to event emitter\n this.registerSubscription(this.errorSubject\n .subscribe(value => this.onError.emit(value)));\n\n // Propagate dirty to event emitter\n this.registerSubscription(this.dirtySubject\n .subscribe(value => this.onDirty.emit(value)));\n\n // Propagate row dirty state to table\n this.registerSubscription(\n this.onStartEditingRow\n .pipe(\n filter(row => row?.validator && true),\n mergeMap(row => row.validator.valueChanges\n .pipe(\n takeUntil(\n // Stop if next another row, or destroying\n combineLatest([\n this.onStartEditingRow,\n this.destroySubject\n ])\n // DEBUG\n //.pipe(\n // tap(() => console.debug('TODO stopping previous row listener'))\n //)\n ),\n map(() => row.validator?.dirty),\n filter(dirty => dirty === true),\n first(),\n // DEBUG\n //tap(() => console.debug(\"Propagate row's dirty to table...\"))\n ))\n )\n .subscribe(() => this.markAsDirty())\n );\n\n // Call datasource refresh, on each refresh events\n this.registerSubscription(\n this.onRefresh\n .pipe(\n startWith<any, any>(this.autoLoad ? {} : 'skip'),\n switchMap(\n (event: any) => {\n this.dirtySubject.next(false);\n this.selection.clear();\n if (event === 'skip') {\n return of(undefined);\n }\n if (!this._dataSource) {\n if (this.debug) console.debug('[table] Skipping data load: no dataSource defined');\n return of(undefined);\n }\n if (this.debug) console.debug('[table] Calling dataSource.watchAll()...');\n return this._dataSource.watchAll(\n this.pageOffset,\n this.pageSize,\n this.sortActive,\n this.sortDirection,\n this._filter\n );\n }),\n catchError(err => {\n if (this.debug) console.error(err);\n this.setError(err && err.message || err);\n return of(undefined); // Continue\n })\n )\n .subscribe(res => this.updateView(res)));\n\n // Listen dataSource loading events\n if (this._dataSource) this.listenDatasourceLoading(this._dataSource);\n }\n\n ngAfterViewInit() {\n // Detect when super.ngOnInit() not call\n if (this.debug && !this.displayedColumns) console.warn(`[table] Missing 'displayedColumns'. Did you call super.ngOnInit() in component ${this.constructor.name} ?`);\n\n // Start listening sort and paginator events\n this.listenSortAndPaginationEvents();\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n\n // Unsubscribe column value changes\n Object.keys(this._cellValueChangesDefs).forEach(col => this.stopCellValueChanges(col, true));\n this._cellValueChangesDefs = {};\n\n this.readySubject.unsubscribe();\n this.loadingSubject.unsubscribe();\n this.savingSubject.unsubscribe();\n this.errorSubject.unsubscribe();\n this.dirtySubject.unsubscribe();\n\n this.onRefresh.unsubscribe();\n this.onOpenRow.unsubscribe();\n this.onNewRow.unsubscribe();\n this.onStartEditingRow.unsubscribe();\n this.onConfirmEditCreateRow.unsubscribe();\n this.onCancelOrDeleteRow.unsubscribe();\n this.onBeforeDeleteRows.unsubscribe();\n this.onBeforeCancelRows.unsubscribe();\n this.onBeforeSave.unsubscribe();\n this.onAfterDeletedRows.unsubscribe();\n this.onSort.unsubscribe();\n this.onDirty.unsubscribe();\n this.onError.unsubscribe();\n\n this.destroySubject.next();\n this.destroySubject.unsubscribe();\n }\n\n async updateView(res: LoadResult<T> | undefined, opts?: {\n emitEvent?: boolean;\n }): Promise<void> {\n if (!res) return; // Skip (e.g error)\n if (res && res.data) {\n this.visibleRowCount = res.data.length;\n this.totalRowCount = isNotNil(res.total) ? res.total : ((this.paginator && this.paginator.pageIndex * (this.paginator.pageSize || DEFAULT_PAGE_SIZE) || 0) + this.visibleRowCount);\n if (this.debug) console.debug(`[table] ${res.data.length} rows loaded`);\n } else {\n //if (this.debug) console.debug('[table] NO rows loaded');\n this.totalRowCount = 0;\n this.visibleRowCount = 0;\n }\n\n if (!opts || opts.emitEvent !== false) {\n this.markAsUntouched({emitEvent: false});\n this.markAsPristine({emitEvent: false});\n this.markAsLoaded({emitEvent: false});\n }\n\n this.markForCheck();\n }\n\n setDatasource(datasource: EntitiesTableDataSource<T, F, ID>) {\n if (this._dataSource) throw new Error('[table] dataSource already set !');\n if (datasource && this._dataSource !== datasource) {\n this._dataSource = datasource;\n if (this._initialized) this.listenDatasourceLoading(datasource);\n }\n }\n\n resetDataSource() {\n if (this._dataSourceLoadingSubscription) {\n this._dataSourceLoadingSubscription.unsubscribe();\n this._subscription.remove(this._dataSourceLoadingSubscription);\n }\n //this._dataSource?.close();\n this._dataSource = null;\n }\n\n addColumnDef(column: CdkColumnDef) {\n this.table.addColumnDef(column);\n }\n\n removeColumnDef(column: CdkColumnDef) {\n this.table.removeColumnDef(column);\n }\n\n setFilter(filter: F, opts?: { emitEvent?: boolean; }) {\n opts = opts || {emitEvent: true};\n\n if (this.saveBeforeFilter) {\n\n // if a dirty table is to be saved before filter\n if (this.dirty) {\n\n // Save\n this.saveBeforeAction('filter').then(saved => {\n // Apply filter only if user didn't cancel the save or the save is ok\n if (saved) {\n this.applyFilter(filter, opts);\n }\n });\n\n } else {\n // apply filter on non dirty table\n this.applyFilter(filter, opts);\n }\n\n } else {\n\n // apply filter directly\n this.applyFilter(filter, opts);\n }\n }\n\n confirmAndAdd(event?: Event, row?: TableElement<T>): boolean {\n if (!this.confirmEditCreate(event, row)) {\n return false;\n }\n // Add row\n return this.addRow(event);\n }\n\n confirmAndBackward(event?: Event, row?: TableElement<T>): boolean {\n\n // Deleting edited row, if empty and not dirty\n const previousRow = this.editedRow;\n if (previousRow && (previousRow.id === -1) && previousRow.validator?.invalid && !(previousRow.validator?.dirty)) {\n this.deleteNewRow(event, previousRow);\n\n // Wait deletion is done, then edit previous row (by id, because of reloading)\n this.waitIdle()\n .then(() => this.editRowById(event, row.id, {focusColumn: this.lastUserColumn}));\n return true;\n }\n\n // Edit previous row\n this.editRow(event, row, {focusColumn: this.lastUserColumn});\n return true;\n }\n\n confirmAndForward(event?: Event, row?: TableElement<T>): boolean | Promise<boolean> {\n row = row || this.editedRow;\n if (!this.confirmEditCreate(event, row)) {\n // If pending: Wait end of validation, then loop\n if (row.validator?.pending) {\n return AppFormUtils.waitWhilePending(row.validator).then(() => this.confirmAndForward(event, row));\n }\n\n return false;\n }\n // Edit next row\n this.editRowById(event, row.id + 1, {focusColumn: this.firstUserColumn});\n return true;\n }\n\n /**\n * Confirm the creation of the given row, or if not specified the currently edited row\n *\n * @param event\n * @param row\n */\n confirmEditCreate(event?: Event, row?: TableElement<T>): boolean {\n row = row || this.editedRow;\n if (!row || !row.editing) return true; // no row to confirm\n\n // Stop event\n event?.stopPropagation();\n\n // Confirmation edition or creation\n // TODO: add await ?\n const confirmed = row.confirmEditCreate();\n\n if (confirmed) {\n // If edit finished, forget edited row\n if (row === this.editedRow) {\n this.editedRow = undefined;\n }\n\n // Mark table as dirty (if row is dirty)\n if (row.validator?.dirty) {\n this.markAsDirty({emitEvent: false /* because of resetError() */});\n }\n\n // Clear error\n this.resetError();\n\n // Emit the confirm event\n this.onConfirmEditCreateRow.next(row);\n\n return true; // Continue\n }\n\n if (row.validator) {\n // If pending: Wait end of validation, then loop\n // TODO: remove when using async isValid() function\n if (row.validator.pending) {\n AppFormUtils.waitWhilePending(row.validator).then(() => this.confirmEditCreate(event, row));\n return false;\n }\n\n // NOT confirmed = row has error\n if (this.debug) {\n console.warn('[table] Cannot confirm row, because invalid');\n AppFormUtils.logFormErrors(row.validator, '[table] ');\n }\n\n // fix: mark all controls as touched to show errors\n row.validator.markAllAsTouched();\n\n // Compute row error, and propagate to table's error\n if (this.propagateRowError) {\n const error = this.getRowError(row);\n this.setError(error);\n }\n }\n\n return false;\n }\n\n cancelOrDelete(event: Event, row: TableElement<T>, opts?: { interactive?: boolean; keepEditing?: boolean; }) {\n // Delete new row\n if (row.id === -1) {\n this.deleteNewRow(event, row);\n }\n // Delete existing (bu not editing) row\n else if (!row.editing) {\n this.deleteExistingRow(event, row, opts);\n }\n // Cancel existing (and editing) row\n else {\n this.cancelExistingRow(event, row, opts);\n }\n }\n\n addRow(event?: Event, insertAt?: number, opts?: {focusColumn?: string; editing?: boolean }): boolean {\n if (this.debug) console.debug('[table] Asking for new row...');\n if (!this._enabled) return false;\n\n // Use modal if inline edition is disabled\n if (!this.inlineEdition) {\n this.openNewRowDetail(event);\n return false;\n }\n\n // Try to finish edited row first\n if (!this.confirmEditCreate()) {\n return false;\n }\n\n // Add new row\n this.addRowToTable(insertAt, opts);\n return true;\n }\n\n async save(opts?: { keepEditing?: boolean }): Promise<boolean> {\n opts = {\n keepEditing: this.keepEditedRowOnSave,\n ...opts\n };\n if (this.readOnly) {\n throw {code: ErrorCodes.TABLE_READ_ONLY, message: 'ERROR.TABLE_READ_ONLY'};\n }\n\n this.resetError();\n\n // Keep edited row id (should be done BEFORE confirmEditCreate() )\n this.previouslyEditedRowId = opts.keepEditing ? ((this.editedRow?.editing ? this.editedRow.id : undefined) || this.singleSelectedRow?.id) : undefined;\n const previouslyEditedData = opts.keepEditing ? (isNotNil(this.previouslyEditedRowId) && this.editedRow?.currentData || this.singleSelectedRow?.currentData) : undefined;\n\n if (!this.confirmEditCreate()) {\n throw {code: ErrorCodes.TABLE_INVALID_ROW_ERROR, message: 'ERROR.TABLE_INVALID_ROW_ERROR'};\n }\n\n // Mark as saving\n this.markAsSaving();\n\n try {\n\n // Calling service save()\n if (this.debug) console.debug('[table] Calling dataSource.save()...');\n const isOK = await this._dataSource.save();\n\n if (isOK) this.markAsPristine();\n\n return isOK;\n } catch (err) {\n this.setError(err && err.message || err);\n throw err;\n }\n finally {\n this.markAsSaved();\n\n // Restore previous row\n if (isNotNil(this.previouslyEditedRowId)) {\n await this.selectRowByIdOrData(this.previouslyEditedRowId, previouslyEditedData);\n }\n }\n }\n\n cancel(event?: Event, opts?: { interactive?: boolean; }) {\n\n // Check confirmation\n if ((!opts || opts.interactive !== false) && this.dirty && (this.confirmBeforeCancel || this.onBeforeCancelRows.observers.length > 0)) {\n event?.stopPropagation();\n this.canCancelRows().then(confirm => {\n // If confirmed, loop\n if (confirm) this.cancel(null, {interactive: false});\n });\n return;\n }\n\n this.onRefresh.emit();\n }\n\n async duplicateRow(event?: Event, row?: TableElement<T>, opts?: {\n skipProperties?: string[];\n }) {\n event?.stopPropagation();\n\n row = row || this.singleSelectedRow;\n if (!row || !this.confirmEditCreate(event, row)) {\n return false;\n }\n\n const newRow = await this.addRowToTable(row.id + 1);\n const json = {...row.currentData, id: null};\n\n // Reset some properties (e.g. rankOrder, etc)\n if (opts && opts.skipProperties) {\n const newData = newRow.currentData;\n opts.skipProperties.forEach(key => json[key] = newData[key]);\n }\n\n if (newRow.validator) {\n newRow.validator.patchValue(json);\n newRow.validator.markAsDirty();\n }\n else {\n if (newRow.currentData?.fromObject) {\n newRow.currentData.fromObject(json);\n }\n else {\n newRow.currentData = json;\n }\n this.markAsDirty();\n }\n\n // select\n this.clickRow(undefined, newRow);\n }\n\n /** Whether the number of selected elements matches the total number of rows. */\n isAllSelected() {\n // DEBUG\n //console.debug('isAllSelected. lengths', this.selection.selected.length, this.totalRowCount);\n\n return this.selection.selected.length === this.totalRowCount ||\n this.selection.selected.length === this.visibleRowCount;\n }\n\n /** Selects all rows if they are not all selected; otherwise clear selection. */\n async masterToggle() {\n\n if (this.loading) return;\n if (this.isAllSelected()) {\n this.selection.clear();\n } else {\n const rows = this._dataSource.getRows();\n rows.forEach(row => this.selection.select(row));\n }\n }\n\n deleteSelection(event: UIEvent): Promise<number> {\n return this.deleteRows(event, this.selection.selected);\n }\n\n /**\n *\n * @param event\n * @param row\n * @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)\n * And to force deletion even if table is busy\n */\n async deleteRow(event: UIEvent|null, row: TableElement<T>, opts?: {interactive?: boolean;}): Promise<boolean> {\n const deleteCount = await this.deleteRows(event, [row], opts);\n return deleteCount === 1;\n }\n\n /**\n *\n * @param event\n * @param rows\n * @param opts Use interactive=false to avoid user interaction (e.g. user confirmation)\n * And to force deletion even if table is busy\n */\n async deleteRows(event: UIEvent|null, rows: TableElement<T>[], opts?: {interactive?: boolean;}): Promise<number> {\n if (this.readOnly) {\n throw {code: ErrorCodes.TABLE_READ_ONLY, message: 'ERROR.TABLE_READ_ONLY'};\n }\n if (event?.defaultPrevented) return 0; // SKip\n event?.preventDefault();\n\n if (!this._enabled || isEmptyArray(rows)) return 0; // Skip is disabled, or no rows to delete\n if (this.loading && (!opts || opts.interactive !== false)) {\n console.warn('[app-table] Skip deleteRows() because table is busy (loading). Use opts.interactive = false to force deletion');\n return 0; // Skip if loading\n }\n\n // Make sure to keep newly created row\n if (this.editedRow?.id === -1 && this.editedRow.editing && !rows.includes(this.editedRow)) {\n const confirmed = this.confirmEditCreate();\n if (!confirmed) return 0; // Cannot delete (e.g. edited row is invalid)\n }\n\n // Check if can delete\n const canDelete = await this.canDeleteRows(rows, opts);\n if (!canDelete) return 0; // Cannot delete\n\n // Reverse row order (on a copy)\n // This is a workaround, need because row.delete() has async execution\n // and index cache is updated with a delay\n let tempRows = rows.slice()\n .sort((a, b) => a.id > b.id ? -1 : 1);\n\n let deletedRows: TableElement<T>[] = [];\n\n // If data need to be saved first\n if (this.saveBeforeDelete) {\n // Exclude invalid rows (because of save() will fail, when exists some invalid rows)\n tempRows = tempRows.filter(row => {\n // Delete the row :\n // - if newly created row (id = -1),\n // - or if invalid and not editing (= not cancellable)\n if (row.id === -1 || (!row.editing && row.invalid /*do not use !valid because if row is disabled, it will be always !valid */)) {\n if (this.debug) console.debug(`[table] Delete row #${row.id}`);\n row.delete();\n this.visibleRowCount--;\n this.totalRowCount--;\n deletedRows.push(row);\n if (this.editedRow === row) this.editedRow = undefined;\n return false; // Exclude from the list to delete using the service\n }\n // Cancel the row (and mark as pristine), when not valid but in edition\n else if (row.editing && !row.valid) {\n row.cancel();\n // Mark row as pristine (if possible)\n this.checkIfRowPristine(row, {emitEvent: false, onlySelf: true /*avoid propagation to table*/});\n return true; // Keep the row. the row will be deleted after the save\n }\n\n return true;\n });\n\n // Apply save, only if there is still some rows to delete\n // WARN: If no more rows (e.g. because all has been cancelled) then continue anyway to clear editedRow and selection (issue IMAGINE-669)\n if (deletedRows.length || tempRows.length) {\n\n // Save data (e.g. when using memory service)\n const saved = await this.saveBeforeAction('delete');\n if (!saved) {\n // Stop if save cancelled or save failed\n return;\n }\n }\n }\n\n try {\n\n // Apply deletion on datasource\n // If no more rows to delete, continue anyway to clear editedRow and selection (issue IMAGINE-669)\n if (tempRows.length) {\n if (this.debug) console.debug(`[table] Delete ${tempRows.length} rows...`);\n await this._dataSource.deleteAll(tempRows);\n }\n\n // DO not update manually, because watchALl().subscribe() will update this count\n //this.totalRowCount -= deleteCount;\n //this.visibleRowCount -= deleteCount;\n\n this.selection.clear();\n this.editedRow = undefined;\n this.markAsDirty({emitEvent: false /*markForCheck() is called just after*/});\n this.markForCheck();\n\n this.onAfterDeletedRows.next(rows);\n\n return rows.length;\n } catch (err) {\n this.setError(err && err.message || err);\n throw err;\n }\n }\n\n async selectRowById(id: number): Promise<boolean> {\n if (id === undefined) return false;\n await this.waitIdle();\n const row = this.dataSource.getRow(id);\n if (!row) return false;\n return this.clickRow(null, row);\n }\n\n /**\n * Try to select row by data. Will use dataEquals() (that call EntityUtils.equals()) to find same row's data\n * @param data\n */\n async selectRowByData(data: T): Promise<boolean> {\n if (data === undefined) return Promise.resolve(false);\n await this.waitIdle();\n const row = this.dataSource.getRows()\n .find(row => this.equals(row.currentData, data));\n if (!row) return false;\n return this.clickRow(null, row);\n }\n\n clickRow(event: UIEvent|undefined, row: TableElement<T>): boolean {\n if (this.loading) {\n // Wait while loading, and loop\n if (this.debug) console.debug(\"[table] Waiting before apply clickRow() (datasource is busy)...\");\n this.waitIdle().then(() => this.clickRow(event, row));\n return false;\n }\n\n // DEBUG\n //console.debug(\"[table] Detect click on row\");\n\n if (row.id === -1 || row.editing) return true; // Already in edition\n if (event?.defaultPrevented) return false; // Cancelled by event\n\n // Open the detail page (if not inline editing)\n if (!this.inlineEdition) {\n\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n this.markAsLoading();\n this.openRow(row.currentData.id, row)\n .then(() => this.markAsLoaded())\n .catch(() => this.markAsLoaded());\n\n return true;\n }\n\n // Start editing row\n return this.editRow(event, row, {focusColumn: undefined /*force to use the click target*/});\n }\n\n moveRow(id: number, direction: number) {\n this.dataSource.move(id, direction);\n }\n\n ready(opts?: WaitForOptions): Promise<void> {\n return waitForTrue(this.readySubject, opts);\n }\n\n waitIdle(opts?: WaitForOptions): Promise<void> {\n return waitForFalse(this.loadingSubject, opts);\n }\n\n async openSelectColumnsModal(event?: Event): Promise<any> {\n\n // Copy current columns (deep copy)\n const columns = this.getCurrentColumns();\n\n const hasTopModal = !!(await this.modalCtrl.getTop());\n const modal = await this.modalCtrl.create({\n component: TableSelectColumnsComponent,\n componentProps: {columns},\n cssClass: hasTopModal && 'stack-modal'\n });\n\n // Open the modal\n await modal.present();\n\n // On dismiss\n const {data} = await modal.onDidDismiss();\n if (!data) return; // CANCELLED\n\n // Apply columns\n const userColumns = (data || []).filter(c => c.canHide === false || c.visible).map(c => c.name) || [];\n this.displayedColumns = RESERVED_START_COLUMNS.concat(userColumns).concat(RESERVED_END_COLUMNS);\n this.markForCheck();\n\n // Update user settings\n await this.settings.savePageSetting(this.settingsId, userColumns, SETTINGS_DISPLAY_COLUMNS);\n }\n\n trackByFn(index: number, row: TableElement<T>) {\n return row.id;\n }\n\n doRefresh(event?: CompletableEvent) {\n this.onRefresh.emit(event);\n\n // When target wait for a complete (e.g. IonRefresher)\n if (event?.target && event.target.complete) {\n setTimeout(async () => {\n await this.waitIdle();\n event.target.complete();\n });\n }\n }\n\n getCurrentColumns(): ColumnItem[] {\n const hiddenColumns = this.columns.slice(RESERVED_START_COLUMNS.length)\n .filter(name => this.displayedColumns.indexOf(name) === -1);\n return this.displayedColumns\n .concat(hiddenColumns)\n .filter(name => !RESERVED_START_COLUMNS.includes(name) && !RESERVED_END_COLUMNS.includes(name)\n && !this.excludesColumns.includes(name))\n .map(name => ({\n name,\n label: this.getI18nColumnName(name),\n visible: this.displayedColumns.indexOf(name) !== -1,\n canHide: this.getRequiredColumns().indexOf(name) === -1\n }));\n }\n\n escapeEditingRow(event?: Event, row?: TableElement<T>) {\n row = row || this.editedRow;\n if (!row || !row.editing) return;\n\n // DEBUG\n //console.debug('[app-table] Cancel the row (keydown.escape)');\n\n if (event) {\n // Avoid to cancel the editor\n event.preventDefault();\n event.stopPropagation();\n }\n\n // If new row (no id)\n if (row.id === -1) {\n if (row.validator) {\n // If pending: Wait end of validation, then loop\n if (row.validator.pending) {\n AppFormUtils.waitWhilePending(row.validator).then(() => this.escapeEditingRow(event, row));\n return;\n }\n\n // Row is invalid: delete the row\n if (row.validator.invalid) {\n this.deleteNewRow(event, row);\n return;\n }\n }\n }\n // If the row exists (has an id)\n else {\n // need to call cancel function (if confirmation will be call before before)\n if (this.confirmBeforeCancel) {\n this.cancelExistingRow(event, row, {keepEditing: false});\n return;\n }\n }\n\n // By default, try to confirm the row\n this.confirmEditCreate(event, row);\n }\n\n translateControlPath(path: string): string {\n // Can be override by subclasses, to resolve all field name\n\n // Use columns key, has default name\n const i18nColumnKey = this.getI18nColumnName(path);\n return this.translate?.instant(i18nColumnKey) || i18nColumnKey;\n }\n\n /* -- protected method -- */\n\n\n protected editRow(event: Event|undefined, row: TableElement<T>, opts?: {focusColumn?: string}): boolean {\n\n if (!this._enabled) return false;\n if (this.editedRow === row) return true; // Already the edited row\n if (event?.defaultPrevented) return false;\n\n if (!this.confirmEditCreate()) {\n return false;\n }\n\n if (!row.editing && !this.loading) {\n this.focusColumn = opts && opts.focusColumn || this.focusColumn;\n this._dataSource.startEdit(row);\n }\n this.editedRow = row;\n this.onStartEditingRow.emit(row);\n return true;\n }\n\n /**\n * Try to select row, by row.id, or by data. WIll use EntityUtils.equals()\n * @param id\n * @param data\n * @protected\n */\n protected async selectRowByIdOrData(id: number, data?: T): Promise<boolean> {\n let done = false;\n try {\n\n // Select by row id (if NOT a new row)\n if (isNotNil(id) || id !== -1) {\n done = await this.selectRowById(id);\n if (done) return true;\n console.warn('[app-table] Save: Cannot reselect row by row.id: ', id);\n }\n\n // Try by data\n if (data) {\n done = await this.selectRowByData(data);\n if (done) return true;\n console.warn('[app-table] Save: Cannot reselect row by data: ', data);\n }\n\n return false;\n }\n catch(err) {\n // Log, but continue\n console.error(err && err.message || err);\n return false;\n }\n }\n\n /**\n * return the selected row if unique in selection\n */\n protected get singleSelectedRow(): TableElement<T> {\n return this.selection.selected?.length === 1 ? this.selection.selected[0] : undefined;\n }\n\n protected async canDeleteRows(rows: TableElement<T>[], opts?: { interactive?: boolean; }): Promise<boolean> {\n\n // Check using emitter\n if (this.onBeforeDeleteRows.observers.length > 0) {\n try {\n const canDelete = await emitPromiseEvent(this.onBeforeDeleteRows, 'canDelete', {\n detail: {rows}\n });\n if (!canDelete) return false;\n }\n catch (err) {\n if (err === 'CANCELLED') return false; // User cancel\n console.error('Error while checking if can delete rows', err);\n throw err;\n }\n }\n\n // Ask user confirmation\n if (this.confirmBeforeDelete && (!opts || opts.interactive !== false)) {\n return this.askDeleteConfirmation(null, rows);\n }\n return true;\n }\n\n protected async canCancelRows(rows?: TableElement<T>[], opts?: { interactive?: boolean; }): Promise<boolean> {\n\n // Get dirty rows\n rows = rows || this.dataSource.getRows().filter(row => row.validator?.dirty);\n\n if (isEmptyArray(rows)) return true; // No dirty: OK\n\n // Check using emitter\n if (this.onBeforeCancelRows.observers.length > 0) {\n try {\n const isCancel = await emitPromiseEvent(this.onBeforeCancelRows, 'canCancel', {\n detail: {rows}\n });\n if (!isCancel) return false;\n }\n catch (err) {\n if (err === 'CANCELLED') return false; // User cancel\n console.error('Error while checking if can cancel rows', err);\n throw err;\n }\n }\n\n // Ask user confirmation\n if (this.confirmBeforeCancel && (!opts || opts.interactive !== false)) {\n return this.askCancelConfirmation(null, rows);\n }\n return true;\n }\n\n protected async saveBeforeAction(saveAction: SaveActionType): Promise<boolean> {\n\n if (!this.dirty) {\n // Continue without save\n return true;\n }\n\n let save: boolean;\n switch (saveAction) {\n case 'delete':\n save = this.saveBeforeDelete;\n break;\n case 'filter':\n save = this.saveBeforeFilter;\n break;\n case 'sort':\n save = this.saveBeforeSort;\n break;\n default:\n save = true;\n }\n\n // Default behavior\n let confirmed = true;\n\n if (save) {\n if (this.onBeforeSave.observers.length > 0) {\n // Ask confirmation\n try {\n const res = await emitPromiseEvent(this.onBeforeSave, 'beforeSave', {\n detail: {action: saveAction, valid: this.valid}\n });\n confirmed = res.confirmed;\n save = res.save;\n }\n catch (err) {\n if (err === 'CANCELLED') return false; // User cancel\n console.error('Error while checking if can delete rows', err);\n throw err;\n }\n\n }\n }\n\n if (confirmed) {\n if (save) {\n // User confirmed save\n const saved = await this.save();\n this.markAsDirty(); // Restore dirty flag\n return saved;\n }\n return true; // No save but continue action\n }\n\n return false; // User cancel the action\n }\n\n /**\n * Open a row. By default, will to open row detail page.\n * Can be override by subclasses, BUT prefer to subscribe on onOpenRow\n * @param id\n * @param row\n * @protected\n */\n protected async openRow(id: ID, row: TableElement<T>): Promise<boolean> {\n if (this.allowRowDetail) {\n if (this.debug && this.dirty) {\n console.warn('[table] Opening row details, but table has unsaved changes!');\n }\n\n if (this.onOpenRow.observers.length) {\n this.onOpenRow.emit({id, row});\n return true;\n }\n\n // No ID defined: unable to open details\n if (isNil(id)) {\n console.warn('[table] Opening row details, but data has no id!');\n return false;\n }\n\n return this.router.navigate(['.', id.toString()], {\n relativeTo: this.route,\n queryParams: {}\n });\n }\n return false;\n }\n\n protected async openNewRowDetail(event?: any): Promise<boolean> {\n if (!this.allowRowDetail) return false;\n\n if (this.onNewRow.observers.length) {\n this.onNewRow.emit(event);\n return true;\n }\n\n return await this.router.navigate(['new'], {\n relativeTo: this.route\n });\n }\n\n // can be overridden to add more required columns\n protected getRequiredColumns() {\n return DEFAULT_REQUIRED_COLUMNS;\n }\n\n protected getUserColumns(): string[] {\n return this.settings.getPageSettings(this.settingsId, SETTINGS_DISPLAY_COLUMNS);\n }\n\n protected getSortedColumn(): MatSortable {\n const data = this.settings.getPageSettings(this.settingsId, SETTINGS_SORTED_COLUMN);\n const parts = data && data.split(':');\n if (parts && parts.length === 2 && this.columns.includes(parts[0])) {\n return {id: parts[0], start: parts[1] === 'desc' ? 'desc' : 'asc', disableClear: false};\n }\n if (this.defaultSortBy) {\n return {id: this.defaultSortBy, start: this.defaultSortDirection || 'asc', disableClear: false};\n }\n return {id: 'id', start: 'asc', disableClear: false};\n }\n\n protected getPageSize(): number {\n const pageSize = this.settings.getPageSettings<number>(this.settingsId, SETTINGS_PAGE_SIZE);\n return pageSize || this.defaultPageSize;\n }\n\n protected getDisplayColumns(): string[] {\n let userColumns = this.getUserColumns();\n\n // No user override\n if (!userColumns) {\n // Return default, without columns to hide\n return this.columns.filter(column => !this.excludesColumns.includes(column));\n }\n\n // Get fixed start columns\n const fixedStartColumns = this.columns.filter(c => RESERVED_START_COLUMNS.includes(c));\n\n // Remove end columns\n const fixedEndColumns = this.columns.filter(c => RESERVED_END_COLUMNS.includes(c));\n\n // Remove fixed columns from user columns\n userColumns = userColumns.filter(c => !fixedStartColumns.includes(c) && !fixedEndColumns.includes(c) && this.columns.includes(c));\n\n // Add required columns if missing\n userColumns.push(...this.getRequiredColumns().filter(c => !fixedStartColumns.includes(c) && !fixedEndColumns.includes(c) && !userColumns.includes(c)));\n\n return fixedStartColumns\n .concat(userColumns)\n .concat(fixedEndColumns)\n // Remove columns to hide\n .filter(column => !this.excludesColumns.includes(column));\n }\n\n /**\n * Recompute display columns\n *\n * @protected\n */\n protected updateColumns() {\n this.displayedColumns = this.getDisplayColumns();\n if (!this.loading) this.markForCheck();\n }\n\n protected registerSubscription(sub: Subscription) {\n this._subscription.add(sub);\n }\n\n protected unregisterSubscription(sub: Subscription) {\n this._subscription.remove(sub);\n }\n\n protected registerAutocompleteField<E = any, EF = any>(fieldName: string, options?: MatAutocompleteFieldAddOptions<E, EF>): MatAutocompleteFieldConfig<E, EF> {\n return this._autocompleteConfigHolder.add(fieldName, options);\n }\n\n protected getI18nColumnName(columnName: string) {\n return (this.i18nColumnPrefix || '') + changeCaseToUnderscore(columnName).toUpperCase();\n }\n\n protected generateTableId() {\n const id = this.location.path(true)\n .replace(/[?].*$/g, '')\n .replace(/\\/[\\d]+/g, '_id')\n + '_'\n // Get a component unique name - See https://stackoverflow.com/questions/60114682/how-to-access-components-unique-encapsulation-id-in-angular-9\n + (this.constructor['ɵcmp']?.id || this.constructor.name);\n //if (this.debug) console.debug(\"[table] id = \" + id);\n return id;\n }\n\n protected async addRowToTable(insertAt?: number, opts?: {focusColumn?: string; editing?: boolean; emitEvent?: boolean; }): Promise<TableElement<T>> {\n\n const row = await this._dataSource.createNew(insertAt, {editing: true, ...opts});\n if (!row) return undefined;\n\n if (row.editing) {\n // Update focused column\n this.focusFirstColumn = true;\n this.focusColumn = opts?.focusColumn || this.firstUserColumn;\n\n // Emit start editing event\n this.editedRow = row;\n this.onStartEditingRow.emit(this.editedRow);\n }\n\n this.totalRowCount++;\n this.visibleRowCount++;\n\n this.markAsDirty({emitEvent: false /*markForCheck() is called just after*/});\n\n // Emit event\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n\n return row;\n }\n\n protected registerCellValueChanges(name: string, formPath?: string, emitInitialValue?: boolean): Observable<any> {\n formPath = formPath || name;\n emitInitialValue = emitInitialValue || false;\n let def = this._cellValueChangesDefs[name];\n if (def && (def.formPath !== formPath || def.emitInitialValue !== emitInitialValue)) {\n throw Error('Already register a cell value change for this name, with different \\'formPath\\' or \\'emitInitialValue\\'. Please use same arguments.');\n }\n\n // Not exists: register new definition\n if (!def) {\n if (this.debug) console.debug(`[table] New listener {${name}} for value changes on path ${formPath}`);\n def = {\n subject: new Subject<any>(),\n subscription: null,\n formPath,\n emitInitialValue\n };\n this._cellValueChangesDefs[name] = def;\n\n // Start the listener, when editing starts\n this.registerSubscription(\n this.onStartEditingRow.subscribe(row => this.startCellValueChanges(name, row)));\n }\n\n return def.subject;\n }\n\n protected setShowColumn(columnName: string, show: boolean, opts?: { emitEvent?: boolean }) {\n if (!this.excludesColumns.includes(columnName) !== show) {\n if (!show) {\n this.excludesColumns.push(columnName);\n } else {\n const index = this.excludesColumns.findIndex(value => value === columnName);\n if (index >= 0) this.excludesColumns.splice(index, 1);\n }\n\n // Recompute display columns\n if (this.displayedColumns && (!opts || opts.emitEvent !== false)) {\n this.updateColumns();\n }\n }\n }\n\n protected getShowColumn(columnName: string): boolean {\n return !this.excludesColumns.includes(columnName);\n }\n\n protected startsWithUpperCase(input: string, search: string): boolean {\n return input && input.toUpperCase().startsWith(search);\n }\n\n protected markForCheck() {\n // Should be override by subclasses, depending on ChangeDetectionStrategy\n }\n\n protected async askDeleteConfirmation(event?: UIEvent, rows?: TableElement<T>[]): Promise<boolean> {\n if (this.undoableDeletion) {\n // Special message, for undoable deletion\n return Alerts.askConfirmation(rows?.length === 1 ? 'CONFIRM.DELETE_ROW' : 'CONFIRM.DELETE_ROWS', this.alertCtrl, this.translate, event);\n }\n // Immediate deletion action\n return Alerts.askActionConfirmation(this.alertCtrl, this.translate, true, event);\n }\n\n protected async askCancelConfirmation(event?: UIEvent, rows?: TableElement<T>[]): Promise<boolean> {\n return Alerts.askConfirmation(rows?.length === 1 ? 'CONFIRM.CANCEL_ROW' : 'CONFIRM.CANCEL_ROWS', this.alertCtrl, this.translate, event);\n }\n\n protected async askRestoreConfirmation(event?: UIEvent): Promise<boolean> {\n return Alerts.askActionConfirmation(this.alertCtrl, this.translate, false, event);\n }\n\n protected async showToast(opts: ShowToastOptions) {\n if (!this.toastController) throw new Error('Missing toastController in component\\'s constructor');\n return Toasts.show(this.toastController, this.translate, opts);\n }\n\n protected resetError(opts?: {emitEvent?: boolean;}) {\n this.setError(undefined, opts);\n }\n\n protected getRowError(row?: TableElement<T>, opts?: FormErrorTranslatorOptions): string {\n row = row || this.editedRow;\n if (!row || !this.formErrorAdapter) return undefined;\n\n return this.formErrorAdapter.translateFormErrors(row.validator, {\n ...this.errorTranslatorOptions,\n ...opts\n });\n }\n\n protected setError(value: string, opts?: {emitEvent?: boolean;}) {\n if (this.errorSubject.value !== value) {\n this.errorSubject.next(value);\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n /**\n * Compare data equality (default by id)\n * Can be overridden to add additional properties to compare\n *\n * @param d1\n * @param d2\n * @protected\n */\n protected equals(d1: T, d2: T): boolean {\n return EntityUtils.equals(d1, d2, 'id');\n }\n\n protected markRowAsDirty(row?: TableElement<T>, opts?: { onlySelf?: boolean; emitEVent?: boolean; }) {\n row = row || this.editedRow;\n if (row) row.validator?.markAsDirty(opts);\n this.markAsDirty(opts);\n }\n\n /* -- private method -- */\n\n private async listenSortAndPaginationEvents() {\n\n if (!this.table) {\n\n // DEBUG only -- alert user that table not found in template\n if (this.debug) {\n setTimeout(() => !this.table && console.warn(`[table] Missing <mat-table> in the HTML template (after waiting 500ms)! Component: ${this.constructor.name}`), 500);\n }\n\n // Make sure to wait the table\n await waitFor(() => !!this.table, {stop: this.destroySubject, stopError: false/*avoid error when destorying the table*/});\n }\n\n this.registerSubscription(\n merge(\n // Listen sort events\n this.sort && this.sort.sortChange\n .pipe(\n filter(() => !this.sort.disabled),\n mergeMap(async () => this.saveBeforeAction('sort')),\n filter(res => res === true),\n // Save sort in settings\n tap(() => {\n const value = [this.sort.active, this.sort.direction || 'asc'].join(':');\n this.settings.savePageSetting(this.settingsId, value, SETTINGS_SORTED_COLUMN);\n })\n )\n || EMPTY,\n\n // Listen paginator events\n this.paginator && this.paginator.page\n .pipe(\n mergeMap(async (event) => this.saveBeforeAction('sort')),\n filter(res => res === true),\n // Save page size in settings\n tap(() => this.settings.savePageSetting(this.settingsId, this.paginator.pageSize, SETTINGS_PAGE_SIZE))\n ) || EMPTY\n )\n // Refresh on any sort or paginator events\n .subscribe(value => {\n this.onSort.emit(value);\n this.onRefresh.emit(value)\n })\n );\n\n // If the user changes the sort order, reset back to the first page.\n if (this.sort && this.paginator) {\n this.registerSubscription(\n this.sort.sortChange\n .pipe(\n filter(() => !this.sort.disabled),\n )\n .subscribe(() => this.paginator.pageIndex = 0)\n );\n }\n }\n\n private async editRowById(event: Event|undefined, id: number, opts?: {focusColumn?: string}) {\n if (id < 0) return;\n if (id >= this.visibleRowCount) {\n this.addRow(event, undefined, {...opts, editing: true});\n }\n else {\n const row = await this.dataSource.getRow(id);\n this.editRow(event, row, opts);\n }\n }\n\n private setLoading(value: boolean, opts?: {emitEvent?: boolean}) {\n if (this.loadingSubject.value !== value) {\n this.loadingSubject.next(value);\n\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n private deleteNewRow(event: Event|undefined, row: TableElement<T>) {// Make sure row will be cancelled, and NOT deleted\n if (row.id !== -1) throw new Error('Row must have id = -1');\n event?.stopPropagation();\n\n this.selection.clear();\n this.editedRow = undefined; // unselect row\n this._dataSource.cancelOrDelete(row);\n this.onCancelOrDeleteRow.next(row);\n this.resetError();\n this.totalRowCount--;\n this.visibleRowCount--;\n }\n\n private deleteExistingRow(event: Event|null, row: TableElement<T>, opts?: {interactive?: boolean;}) {\n // Make sure row will be cancelled, and NOT deleted\n if (row.id === -1) throw new Error('Row must have an id');\n\n if (event?.defaultPrevented) return 0; // SKip\n event?.preventDefault();\n\n this.deleteRow(null, row, opts);\n }\n\n private cancelExistingRow(event: Event|undefined, row: TableElement<T>, opts?: {interactive?: boolean; keepEditing?: boolean;}) {\n // Make sure row will be cancelled, and NOT deleted\n if (row.id === -1 || !row.editing) throw new Error('Row cannot be canceling, but only deleting');\n\n const confirmed = (!opts || opts.interactive !== false);\n\n // Ask user confirmation, if cancel\n if (!confirmed && row.validator?.dirty && (this.confirmBeforeCancel || this.onBeforeCancelRows.observers.length > 0)) {\n event.stopPropagation();\n this.canCancelRows([row], opts)\n .then(confirm => {\n // If confirmed, loop\n if (confirm) this.cancelExistingRow(event, row, {interactive: false});\n });\n return;\n }\n\n const keepEditing = row.editing && (!opts || opts.keepEditing !== false);\n this.editedRow = undefined; // unselect row\n this._dataSource.cancelOrDelete(row);\n this.onCancelOrDeleteRow.next(row);\n\n // Mark row as pristine\n this.checkIfRowPristine(row);\n\n // Restore editing state\n if (keepEditing) {\n this.editRow(undefined, row);\n }\n }\n\n private async checkIfRowPristine(row: TableElement<T>, opts?: {emitEvent?: boolean; onlySelf?: boolean}) {\n // Mark row as pristine\n const markRowAsPristine = this.dataSource?.config.restoreOriginalDataOnCancel === true;\n if (markRowAsPristine) {\n row.validator?.markAsPristine();\n\n // Check if table is now pristine\n if (!opts || opts.onlySelf !== true) {\n await this.checkIfPristine(opts);\n }\n }\n }\n\n private async checkIfPristine(opts?: {emitEvent?: boolean;}) {\n if (!this.dirty) return; // Already pristine\n\n const rows = this._dataSource.getRows();\n const pristine = (rows || []).findIndex(row => row.validator?.dirty) === -1;\n if (pristine) this.markAsPristine(opts);\n }\n\n private applyFilter(filter: F, opts: { emitEvent?: boolean; }) {\n if (this.debug) console.debug('[table] Applying filter', filter);\n this._filter = filter;\n if (opts && opts.emitEvent) {\n if (this.paginator && this.paginator.pageIndex > 0) {\n this.paginator.pageIndex = 0;\n }\n this.onRefresh.emit();\n }\n }\n\n private listenDatasourceLoading(dataSource: EntitiesTableDataSource<T, F, ID>) {\n if (!dataSource) throw new Error('[table] dataSource not set !');\n\n // Cleaning previous subscription on datasource\n if (isNotNil(this._dataSourceLoadingSubscription)) {\n if (this.debug) console.debug('[table] Many call to listenDatasource(): Cleaning previous subscriptions...');\n this._dataSourceLoadingSubscription.unsubscribe();\n this.unregisterSubscription(this._dataSourceLoadingSubscription);\n }\n\n // Propage loading to table\n this._dataSourceLoadingSubscription = this._dataSource.loadingSubject\n .pipe(\n distinctUntilChanged(),\n\n // If changed to True: propagate as soon as possible\n tap((loading) => loading && this.setLoading(true)),\n\n // If changed to False: wait 250ms before propagate (to make sure the spinner has been displayed)\n debounceTime(250),\n tap(loading => !loading && this.setLoading(false))\n )\n .subscribe();\n this.registerSubscription(this._dataSourceLoadingSubscription);\n }\n\n\n private startCellValueChanges(name: string, row: TableElement<T>) {\n const def = this._cellValueChangesDefs[name];\n if (!def) {\n console.warn('[table] Listener with name {' + name + '} not registered! Please call registerCellValueChanges() before;');\n return;\n }\n // Stop previous subscription\n if (def.subscription) {\n def.subscription.unsubscribe();\n def.subscription = null;\n } else {\n if (this.debug) console.debug(`[table] Start values changes on row path {${def.formPath}}`);\n }\n\n // Listen value changes, and redirect to event emitter\n const control = row.validator && AppFormUtils.getControlFromPath(row.validator, def.formPath);\n if (!control) {\n console.warn(`[table] Could not listen cell changes: no validator or invalid form path {${def.formPath}}`);\n } else {\n def.subscription = control.valueChanges\n .pipe(\n // don't emit if control is disabled\n filter(() => control.enabled)\n )\n .subscribe((value) => def.subject.next(value));\n\n // Emit the actual value\n if (def.emitInitialValue !== false) {\n def.subject.next(control.value);\n }\n }\n }\n\n private stopCellValueChanges(name: string, destroy?: boolean) {\n const def = this._cellValueChangesDefs[name];\n if (!def) return;\n if (def.subscription) {\n if (this.debug) console.debug('[table] Stop value changes on row path {' + def.formPath + '}');\n def.subscription.unsubscribe();\n def.subscription = null;\n }\n if (destroy && def.subject) {\n def.subject.complete();\n def.subject.unsubscribe();\n }\n }\n}\n\n","import {AfterViewInit, Directive, EventEmitter, Input, OnDestroy, OnInit, Optional, Output, ViewChild} from '@angular/core';\nimport {ActivatedRoute, Params, Router} from '@angular/router';\nimport {MatTabChangeEvent, MatTabGroup} from '@angular/material/tabs';\nimport {AlertController, IonContent, ToastController} from '@ionic/angular';\nimport {TranslateService} from '@ngx-translate/core';\nimport {BehaviorSubject, Subject, Subscription, TeardownLogic} from 'rxjs';\nimport {AppTable} from '../table/table.class';\nimport {AppForm} from './form.class';\nimport {FormButtonsBarToken} from './form-buttons-bar.component';\nimport {AppFormProvider, AppFormUtils, IAppForm, IAppFormGetter} from './form.utils';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {HammerSwipeEvent} from '../../shared/gesture/hammer.utils';\nimport {ToolbarToken} from '../../shared/toolbar/toolbar';\nimport {isNotNil, toNumber} from '../../shared/functions';\nimport {CanLeave} from '../../shared/guard/component-dirty.guard';\nimport {AbstractControl} from '@angular/forms';\nimport {waitForFalse, WaitForOptions, waitForTrue} from '../../shared/observables';\n\nexport interface IAppEditor extends CanLeave, IAppForm {\n save(event?: Event, options?: any): Promise<boolean>;\n cancel(event?: Event): Promise<void>;\n addChildForm(form: IAppForm | IAppFormGetter): void;\n}\n\nexport interface IAppTabEditor extends IAppEditor {\n selectedTabIndex: number;\n setSelectedTabIndex(value: number, opts?: {emitEvent?: boolean; realignInkBar?: boolean;}): void;\n unload(opts?: {emitEvent?: boolean}): Promise<void>;\n realignInkBar();\n}\n\nexport class AppTabEditorOptions {\n\n /**\n * Number of tab. 1 by default\n */\n tabCount?: number;\n\n /**\n * '200ms' by default\n */\n tabGroupAnimationDuration?: string;\n\n /**\n * Should enable swipe between tab, on touch screen\n */\n enableSwipe?: boolean; // true by default\n}\n\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppEditor<T = any, ID = number, O = any>\n implements IAppEditor, OnInit, OnDestroy, AfterViewInit {\n\n private _children: IAppForm[];\n private _subscription = new Subscription();\n\n protected _enabled = false;\n protected toastController: ToastController;\n protected readonly destroySubject = new Subject();\n\n readonly readySubject = new BehaviorSubject<boolean>(false);\n readonly dirtySubject = new BehaviorSubject<boolean>(false);\n readonly loadingSubject = new BehaviorSubject<boolean>(true);\n readonly errorSubject = new BehaviorSubject<string>(undefined);\n readonly savingSubject = new BehaviorSubject<boolean>(false);\n readonly touchedSubject = new BehaviorSubject<boolean>(false);\n\n debug = false;\n previousDataId: ID;\n submitted = false;\n queryParams: Params;\n i18nContext: {\n prefix: string;\n suffix: string;\n };\n\n /**\n * @deprecated\n */\n protected set _loading(value: boolean) {\n this.loadingSubject.next(value);\n }\n\n /**\n * @deprecated\n */\n protected get _loading(): boolean {\n return this.loadingSubject.value;\n }\n /**\n * @deprecated\n */\n protected get _$ready(): BehaviorSubject<boolean> {\n return this.readySubject;\n }\n /**\n * @deprecated\n */\n protected get _$loading(): BehaviorSubject<boolean> {\n return this.loadingSubject;\n }\n\n get error(): string {\n return this.errorSubject.value;\n }\n\n set error(error: string) {\n this.setError(error);\n }\n\n get saving(): boolean {\n return this.savingSubject.value || this.editors?.some(e => e.saving);\n }\n\n @ViewChild(ToolbarToken) toolbar: ToolbarToken|null = null;\n @ViewChild(FormButtonsBarToken, { static: true }) formButtonsBar: FormButtonsBarToken|null = null;\n @ViewChild(IonContent, {static: true}) content: IonContent;\n\n get tables(): AppTable<any>[] {\n return this._children && (this._children.filter(c => c instanceof AppTable) as AppTable<any>[]);\n }\n get forms(): AppForm<any>[] {\n return this._children && (this._children.filter(c => c instanceof AppForm) as AppForm<any>[]);\n }\n get editors(): AppEditor<any>[] {\n return this._children && (this._children.filter(c => c instanceof AppEditor) as AppEditor[]);\n }\n get dirty(): boolean {\n return this.dirtySubject.value || (this._children && this._children.findIndex(c => c.enabled && c.dirty) !== -1) || false;\n }\n\n /**\n * Is valid (tables and forms)\n */\n get valid(): boolean {\n // Important: Should be not invalid AND not pending, so use '!valid' (DO NOT use 'invalid')\n return !this._children || this._children.findIndex(c => c.enabled && !c.valid) === -1;\n }\n\n get invalid(): boolean {\n return (this._children && this._children.findIndex(c => c.enabled && c.invalid) !== -1) || false;\n }\n\n get pending(): boolean {\n return (this._children && this._children.findIndex(c => c.enabled && c.pending) !== -1) || false;\n }\n\n get loading(): boolean {\n return this.loadingSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.loading) !== -1) || false;\n }\n\n get loaded(): boolean {\n return !this.loadingSubject.value && (!this._children || this._children.findIndex(c => c.enabled && c.loading) === -1) || false;\n }\n\n get touched(): boolean {\n return this.touchedSubject.value || (this._children && this._children.findIndex(c => c.enabled && c.touched) !== -1) || false;\n }\n\n get untouched(): boolean {\n return !this.touchedSubject.value && (!this._children || this._children.findIndex(c => c.enabled && c.touched) === -1) || false;\n }\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n get disabled(): boolean {\n return !this._enabled;\n }\n\n get children(): IAppForm[] {\n return this._children;\n }\n\n get empty(): boolean {\n return !this._enabled;\n }\n\n abstract get isNewData(): boolean;\n\n protected constructor(\n protected route: ActivatedRoute,\n protected router: Router,\n protected alertCtrl: AlertController,\n protected translate: TranslateService\n ) {\n }\n\n ngOnInit() {\n\n if (this.formButtonsBar) {\n this.registerSubscription(this.formButtonsBar.onBack.subscribe(event => this.goBack(event)));\n }\n }\n\n ngAfterViewInit() {\n // Can be overridden by subclasses\n }\n\n ngOnDestroy() {\n this._subscription.unsubscribe();\n\n this.readySubject.unsubscribe();\n this.loadingSubject.unsubscribe();\n this.errorSubject.unsubscribe();\n\n this.destroySubject.next();\n this.destroySubject.unsubscribe();\n }\n\n addChildForm(form: IAppForm | IAppFormGetter) {\n if (!form) throw new Error('Trying to register an undefined child form');\n this._children = this._children || [];\n if (typeof form === 'function') {\n this._children.push(new AppFormProvider(form));\n }\n else {\n this._children.push(form);\n }\n return this;\n }\n\n addChildForms(forms: (IAppForm | IAppFormGetter)[]) {\n (forms || []).forEach(form => this.addChildForm(form));\n }\n\n removeChildForm(form: IAppForm | IAppFormGetter): IAppForm | IAppFormGetter {\n if (!form) throw new Error('Trying to remove an undefined child form');\n const index = (this._children || []).findIndex(c => c === form);\n if (index !== -1) {\n return this._children.splice(index, 1)[0];\n }\n return undefined;\n }\n\n disable(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n this._enabled = false;\n this._children?.forEach(c => c.disable(opts));\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n enable(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n this._enabled = true;\n this._children?.forEach(c => c.enable(opts));\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n markAsPristine(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n this.error = null;\n this.submitted = false;\n if (this.dirtySubject.value !== false) {\n this.dirtySubject.next(false);\n }\n this._children?.forEach(c => c.markAsPristine(opts));\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n markAsUntouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.touchedSubject.value !== false) {\n this.touchedSubject.next(false);\n }\n this._children?.forEach(c => c.markAsUntouched());\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n /**\n * @deprecated prefer to use markAllAsTouched()\n * @param opts\n */\n markAsTouched(opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (!this.touchedSubject.value !== true) {\n this.touchedSubject.next(true);\n }\n this._children?.forEach(c => c.markAsTouched(opts));\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n markAllAsTouched(opts?: {emitEvent?: boolean }) {\n if (this.touchedSubject.value !== true) {\n this.touchedSubject.next(true);\n }\n this._children?.forEach(c => c.markAllAsTouched(opts));\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n\n markAsDirty(opts?: {onlySelf?: boolean; emitEvent?: boolean;}){\n if (!this.dirtySubject.value) {\n this.dirtySubject.next(true);\n if (!this.loading && (!opts || opts.emitEvent !== false)) this.markForCheck();\n }\n }\n\n markAsLoading(opts?: {onlySelf?: boolean; emitEvent?: boolean;}){\n if (!this.loadingSubject.value) {\n this.loadingSubject.next(true);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n markAsLoaded(opts?: {\n onlySelf?: boolean;\n emitEvent?: boolean;\n }){\n if (this.loadingSubject.value) {\n this.loadingSubject.next(false);\n if (!opts || opts.onlySelf !== true) {\n // Emit to children forms and editors\n // note: tables should be changed by parent\n this.forms?.forEach(f => f.markAsLoaded(opts));\n this.editors?.forEach(e => e.markAsLoaded(opts));\n }\n if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n }\n\n markAsReady(opts?: {emitEvent?: boolean }) {\n this._children?.forEach(c => c.markAsReady(opts));\n this.readySubject.next(true);\n }\n\n ready(opts?: WaitForOptions): Promise<void> {\n if (this.readySubject.value) return Promise.resolve();\n return waitForTrue(this.readySubject, opts);\n }\n\n waitIdle(opts?: WaitForOptions): Promise<void> {\n if (!this.loadingSubject.value) return Promise.resolve();\n return waitForFalse(this.loadingSubject, opts);\n }\n\n markAsSaving(opts?: { emitEvent?: boolean }){\n if (this.savingSubject.value !== true) {\n this.savingSubject.next(true);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n markAsSaved(opts?: { emitEvent?: boolean }){\n if (this.savingSubject.value !== false) {\n this.savingSubject.next(false);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n async cancel(event?: Event): Promise<void> {\n if (this.isNewData) {\n await this.unload(); // async reset\n }\n else if (this.dirty){\n await this.reload(); // async reload\n }\n }\n\n /**\n * Unload the page (remove all data). Useful when reusing angular cache a cancelled page\n *\n * @param opts\n */\n async unload(opts?: {emitEvent?: boolean }): Promise<void> {\n console.debug('[editor] Unloading data...');\n this.markAsLoading();\n this._children?.forEach(f => {\n if (f instanceof AppForm) {\n f.reset(null, opts);\n }\n else if (f instanceof AppTable) {\n f.dataSource.disconnect();\n }\n else if (f instanceof AppEditor) {\n f.unload(opts);\n }\n });\n\n this.markAsPristine(opts);\n this.markAsSaved(opts);\n }\n\n async reloadWithConfirmation(confirm?: boolean) {\n const needConfirm = this.dirty;\n // if not confirm yet: ask confirmation\n if (!confirm && needConfirm) {\n const translations = this.translate.instant(['COMMON.BTN_ABORT_CHANGES', 'COMMON.BTN_CANCEL', 'CONFIRM.CANCEL_CHANGES', 'CONFIRM.ALERT_HEADER']);\n const alert = await this.alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations['CONFIRM.CANCEL_CHANGES'],\n buttons: [\n {\n text: translations['COMMON.BTN_ABORT_CHANGES'],\n cssClass: 'secondary',\n handler: () => {\n confirm = true; // update upper value\n }\n },\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n handler: () => {\n }\n }\n ]\n });\n await alert.present();\n await alert.onDidDismiss();\n }\n\n // If confirm: execute the reload\n if (confirm || !needConfirm) {\n this.scrollToTop();\n this.disable();\n return await this.reload();\n }\n }\n\n async goBack(event?: Event): Promise<void | boolean> {\n // Go back\n if (this.toolbar?.canGoBack) {\n return this.toolbar.goBack();\n } else {\n // Back to home\n return this.router.navigateByUrl('/');\n }\n }\n\n\n\n abstract load(id?: ID, options?: O): Promise<void>;\n\n abstract save(event?: Event, options?: any): Promise<boolean>;\n\n abstract reload(): Promise<void>;\n\n logFormErrors(prefix?: string) {\n if (this.debug) console.debug('[editor] Editor not valid. Checking where (forms, tables)...');\n this._children?.forEach(c => this.logChildrenErrors(c, prefix));\n }\n\n /* -- protected methods -- */\n\n protected async scrollToTop(duration?: number) {\n duration = toNumber(duration, 500);\n\n if (!this.content) {\n console.warn(`[tab-editor] Cannot scroll to top. (no 'ion-content' tag found ${this.constructor.name}`);\n\n // TODO: FIXME (not working as the page is not the window)\n const scrollToTop = window.setInterval(() => {\n const pos = window.pageYOffset;\n if (pos > 0) {\n window.scrollTo(0, pos - 20); // how far to scroll on each step\n } else {\n window.clearInterval(scrollToTop);\n }\n }, 16);\n return;\n }\n\n return this.content.scrollToTop(duration);\n }\n\n protected registerSubscription(sub: Subscription|TeardownLogic) {\n this._subscription.add(sub);\n }\n\n protected unregisterSubscription(sub: Subscription) {\n this._subscription.remove(sub);\n }\n\n protected async saveIfDirtyAndConfirm(event?: UIEvent, opts?: {\n emitEvent?: boolean;\n confirmed?: boolean\n }): Promise<boolean> {\n if (!this.dirty) return true;\n\n let confirmed = opts?.confirmed || false;\n if (!confirmed) {\n let cancel = false;\n const translations = this.translate.instant(['COMMON.BTN_SAVE', 'COMMON.BTN_CANCEL', 'COMMON.BTN_ABORT_CHANGES', 'CONFIRM.SAVE', 'CONFIRM.ALERT_HEADER']);\n const alert = await this.alertCtrl.create({\n header: translations['CONFIRM.ALERT_HEADER'],\n message: translations['CONFIRM.SAVE'],\n buttons: [\n {\n text: translations['COMMON.BTN_CANCEL'],\n role: 'cancel',\n cssClass: 'secondary',\n handler: () => {\n cancel = true;\n }\n },\n {\n text: translations['COMMON.BTN_ABORT_CHANGES'],\n cssClass: 'secondary',\n handler: () => {\n }\n },\n {\n text: translations['COMMON.BTN_SAVE'],\n handler: () => {\n confirmed = true; // update upper value\n }\n }\n ]\n });\n await alert.present();\n await alert.onDidDismiss();\n\n if (!confirmed) {\n return !cancel;\n }\n }\n\n return await this.save(event, opts);\n }\n\n protected async showToast(opts: ShowToastOptions) {\n if (!this.toastController) throw new Error('Missing toastController in component\\'s constructor');\n await Toasts.show(this.toastController, this.translate, opts);\n }\n\n protected logChildrenErrors(c: IAppForm | AbstractControl, prefix?: string, path?: string) {\n prefix = prefix || '[app-tab-editor] ';\n // If editor\n if (c instanceof AppEditor) {\n c.logFormErrors();\n }\n // Angular form control\n else if (c instanceof AbstractControl) {\n AppFormUtils.logFormErrors(c, prefix, path);\n }\n // If form provider: get delegate\n else if (c instanceof AppFormProvider) {\n if (!c.empty && !c.valid) {\n c.waitDelegate({timeout: 1000}).then(delegate => this.logChildrenErrors(delegate, prefix, 'provider'));\n }\n }\n // If table\n else if (c instanceof AppTable) {\n if (c.invalid && c.editedRow && c.editedRow.validator) {\n const path = c.constructor.name.toLowerCase();\n AppFormUtils.logFormErrors(c.editedRow.validator, prefix, path);\n }\n }\n // If form\n else if (c instanceof AppForm) {\n if (!c.empty && !c.valid) {\n if (c.pending) {\n const path = c.constructor.name.toLowerCase();\n console.warn( `${prefix} -> ${path}: waiting while pending...`);\n AppFormUtils.waitWhilePending(c, {timeout: 1000})\n .then(() => this.logChildrenErrors(c.form, prefix, path));\n }\n else {\n AppFormUtils.logFormErrors(c.form, prefix);\n }\n }\n }\n // If editor\n else if (c instanceof AppEditor) {\n if (!c.empty && !c.valid) {\n if (c.pending) {\n const path = c.constructor.name.toLowerCase();\n console.warn( `${prefix} -> ${path}: waiting while pending...`);\n AppFormUtils.waitWhilePending(c, {timeout: 1000})\n .then(() => c.logFormErrors(prefix));\n }\n else {\n c.logFormErrors(prefix);\n }\n }\n }\n else {\n console.warn( `${prefix} Unknown children sub-form: `, c);\n }\n }\n\n protected setError(value: string, opts?: {emitEvent?: boolean;}) {\n if (this.errorSubject.value !== value) {\n this.errorSubject.next(value);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n protected resetError(opts?: {emitEvent?: boolean}) {\n this.setError(undefined, opts);\n }\n\n protected markForCheck() {\n // Should be override by subclasses, if change detection is Push\n }\n}\n\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppTabEditor<T = any, ID = number, O = any>\n extends AppEditor<T, ID, O>\n implements IAppTabEditor {\n\n protected _selectedTabIndex = 0;\n\n // Editor options\n tabCount: number;\n enableSwipe: boolean;\n tabGroupAnimationDuration: string;\n\n @Input() queryTabIndexParamName: string;\n\n @Input() set selectedTabIndex(value: number) {\n this.setSelectedTabIndex(value);\n }\n get selectedTabIndex(): number {\n return this._selectedTabIndex;\n }\n\n @Output() readonly selectedTabIndexChange = new EventEmitter<number>();\n\n @ViewChild('tabGroup', { static: true }) tabGroup: MatTabGroup;\n\n protected constructor(\n @Optional() protected route: ActivatedRoute, // Modal editor give 'null'\n protected router: Router,\n protected alertCtrl: AlertController,\n protected translate: TranslateService,\n @Optional() options?: AppTabEditorOptions) {\n super(route, router, alertCtrl, translate);\n options = {\n tabCount: 1,\n enableSwipe: true,\n tabGroupAnimationDuration: '200ms',\n ...options\n }\n this.tabCount = options.tabCount;\n this.enableSwipe = options.enableSwipe;\n this.tabGroupAnimationDuration = options.tabGroupAnimationDuration;\n this.queryTabIndexParamName = 'tab';\n }\n\n ngOnInit() {\n super.ngOnInit();\n\n // Read the selected tab index, from path query params\n if (this.tabGroup && this.route && this.queryTabIndexParamName) {\n this.registerSubscription(this.route.queryParams\n .subscribe(queryParams => {\n this.queryParams = {...queryParams};\n\n // Parse tab param\n if (this.tabCount > 1 && this.queryTabIndexParamName) {\n const tabIndex = queryParams[this.queryTabIndexParamName];\n this.queryParams[this.queryTabIndexParamName] = tabIndex && parseInt(tabIndex) || undefined;\n if (isNotNil(this.queryParams[this.queryTabIndexParamName])) {\n this.selectedTabIndex = this.queryParams[this.queryTabIndexParamName];\n }\n }\n\n // Realign tab, after a delay because the tab can be disabled when component is created\n setTimeout(() => this.tabGroup.realignInkBar(), 500);\n }));\n }\n }\n\n\n ngOnDestroy() {\n super.ngOnDestroy();\n this.selectedTabIndexChange.complete();\n this.loadingSubject.unsubscribe();\n this.errorSubject.unsubscribe();\n }\n\n setSelectedTabIndex(value: number, opts?: {emitEvent?: boolean; realignInkBar?: boolean }) {\n // Fix value\n if (value < 0) {\n value = 0;\n }\n else if (value > this.tabCount - 1) {\n console.warn(`[tab-editor] Invalid tab index ${value}. Max value is ${this.tabCount-1}`)\n value = this._selectedTabIndex;\n }\n\n this._selectedTabIndex = value;\n this.selectedTabIndexChange.next(value);\n\n if (this.tabGroup && (!opts || opts.realignInkBar !== false)) {\n this.tabGroup.selectedIndex = value;\n this.markForCheck();\n // Wait tab change in UI, before realign ink tab\n setTimeout(() => this.tabGroup.realignInkBar(), 200);\n }\n else if (!opts || opts.emitEvent !== false) {\n this.markForCheck();\n }\n }\n\n realignInkBar() {\n this.tabGroup?.realignInkBar();\n }\n\n\n onTabChange(event: MatTabChangeEvent, queryTabIndexParamName?: string): boolean {\n queryTabIndexParamName = queryTabIndexParamName || this.queryTabIndexParamName;\n\n if (!queryTabIndexParamName || !this.route) return true; // Skip if tab query param not set, or no route\n\n if (!this.queryParams || +this.queryParams[queryTabIndexParamName] !== event.index) {\n\n this.queryParams = this.queryParams || {};\n this.queryParams[queryTabIndexParamName] = event.index;\n\n if (queryTabIndexParamName === 'tab' && isNotNil(this.queryParams['subtab'])) {\n delete this.queryParams.subtab; // clean subtab\n }\n this.router.navigate(['.'], {\n relativeTo: this.route,\n queryParams: this.queryParams,\n replaceUrl: true\n });\n return true;\n }\n return false;\n }\n\n /**\n * Action triggered when user swipes\n */\n onSwipeTab(event: HammerSwipeEvent): boolean {\n // DEBUG\n // if (this.debug) console.debug(\"[tab-page] onSwipeTab()\");\n\n // Skip, if not a valid swipe event\n if (!this.enableSwipe || !event\n || event.defaultPrevented || (event.srcEvent && event.srcEvent.defaultPrevented)\n || event.pointerType !== 'touch'\n ) {\n return false;\n }\n\n // DEBUG\n //if (this.debug)\n //console.debug(\"[tab-page] Detected swipe: \" + event.type, event);\n\n let selectTabIndex = this.selectedTabIndex;\n switch (event.type) {\n // Open next tab\n case 'swipeleft':\n const isLast = selectTabIndex >= (this.tabCount - 1);\n selectTabIndex = isLast ? 0 : selectTabIndex + 1;\n break;\n\n\n // Open previous tab\n case 'swiperight':\n const isFirst = selectTabIndex <= 0;\n selectTabIndex = isFirst ? this.tabCount : selectTabIndex - 1;\n break;\n\n // Other case\n default:\n console.error('[tab-page] Unknown swipe action: ' + event.type);\n return false;\n }\n\n setTimeout(() => {\n this.selectedTabIndex = selectTabIndex;\n this.markForCheck();\n });\n\n return true;\n }\n\n onSubTabChange(event: MatTabChangeEvent) {\n this.onTabChange(event, 'subtab');\n }\n\n async unload(opts?: { emitEvent?: boolean }): Promise<void> {\n this.selectedTabIndex = 0;\n await super.unload(opts);\n }\n\n protected abstract getFirstInvalidTabIndex(): number;\n\n protected async saveDirtyChildren(): Promise<boolean> {\n // Save all dirty tables\n const results = await Promise.all([\n ...this.tables,\n ...this.editors\n ]\n .filter(c => c.dirty)\n .map(c => c.save()));\n\n return !results.some(saved => saved !== true);\n }\n}\n","import {AfterViewInit, ChangeDetectorRef, Directive, EventEmitter, Injector, OnDestroy, OnInit, Optional} from '@angular/core';\nimport {ActivatedRoute, Router} from '@angular/router';\nimport {AlertController, ToastController} from '@ionic/angular';\n\nimport {TranslateService} from '@ngx-translate/core';\nimport {BehaviorSubject, Observable, Subject, Subscription} from 'rxjs';\nimport {isMoment} from 'moment';\nimport {AddToPageHistoryOptions, LocalSettingsService} from '../services/local-settings.service';\nimport {filter} from 'rxjs/operators';\nimport {Entity, EntityUtils} from '../services/model/entity.model';\nimport {UsageMode} from '../services/model/settings.model';\nimport {FormGroup} from '@angular/forms';\nimport {AppTabEditor, AppTabEditorOptions, IAppTabEditor} from './editor.class';\nimport {AppFormUtils} from './form.utils';\nimport {Alerts} from '../../shared/alerts';\nimport {ErrorCodes, ServerErrorCodes} from '../services/errors';\nimport {isInt, isNil, isNilOrBlank, isNotEmptyArray, isNotNil, isNotNilOrBlank, toBoolean, toNumber} from '../../shared/functions';\nimport {EntityServiceLoadOptions, IEntityService} from '../../shared/services/entity-service.class';\nimport {DateFormatPipe} from '../../shared/pipes/date-format.pipe';\nimport {Environment, ENVIRONMENT} from '../../../environments/environment.class';\nimport {HistoryPageReference} from '../services/model/history.model';\nimport {waitFor, waitForFalse, WaitForOptions} from '../../shared/observables';\nimport {FormErrorTranslator} from '../../shared/validator/form-error-adapter.class';\nimport {FormErrors} from '../../shared/forms';\n\nexport interface IAppEntityEditor extends IAppTabEditor {\n usageMode: UsageMode;\n isNewData: boolean;\n}\n\nexport class AppEditorOptions extends AppTabEditorOptions {\n autoLoad?: boolean;\n autoLoadDelay?: number;\n pathIdAttribute?: string;\n enableListenChanges?: boolean;\n listenIntervalInSeconds?: number;\n\n /**\n * Change page route (window URL) when saving for the first time\n */\n autoUpdateRoute?: boolean; // Default to true\n\n /**\n * Open the next tab, after saving for the first time\n */\n autoOpenNextTab?: boolean; // Default to true\n\n i18nPrefix?: string;\n}\n\nexport interface AppError {\n code?: number;\n message?: string;\n}\n\n\nexport interface AppErrorWithDetails extends AppError {\n details?: AppError & {errors?: FormErrors};\n}\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppEntityEditor<\n T extends Entity<T, ID>,\n S extends IEntityService<T, ID> = IEntityService<T, any>,\n ID = number\n >\n extends AppTabEditor<T, ID, EntityServiceLoadOptions>\n implements OnInit, OnDestroy, AfterViewInit, IAppEntityEditor {\n\n private _usageMode: UsageMode;\n private readonly _enableListenChanges: boolean;\n private readonly _listenIntervalInSeconds: number;\n private readonly _pathIdAttribute: string;\n private readonly _autoLoad: boolean;\n private readonly _autoLoadDelay: number;\n private readonly _autoUpdateRoute: boolean;\n private _autoOpenNextTab: boolean;\n private _listenChangesSubscription: Subscription;\n\n protected readonly dateFormat: DateFormatPipe;\n protected readonly cd: ChangeDetectorRef;\n protected readonly settings: LocalSettingsService;\n protected readonly environment: Environment;\n protected errorTranslator: FormErrorTranslator;\n\n\n data: T;\n defaultBackHref: string;\n historyIcon: {icon?: string; matIcon?: string };\n\n $title = new Subject<string>();\n onUpdateView = new EventEmitter<T>();\n\n get usageMode(): UsageMode {\n return this._usageMode;\n }\n\n set usageMode(value: UsageMode) {\n if (this._usageMode !== value) {\n this._usageMode = value;\n this.markForCheck();\n }\n }\n\n get isOnFieldMode(): boolean {\n return this.settings.isOnFieldMode(this._usageMode);\n }\n\n get isNewData(): boolean {\n return isNil(this.data?.id);\n }\n\n get service(): S {\n return this.dataService;\n }\n\n protected constructor(\n injector: Injector,\n protected dataType: new() => T,\n protected dataService?: S,\n @Optional() options?: AppEditorOptions\n ) {\n super(injector.get(ActivatedRoute),\n injector.get(Router),\n injector.get(AlertController),\n injector.get(TranslateService),\n options);\n this.environment = injector.get(ENVIRONMENT);\n options = <AppEditorOptions>{\n // Default options\n enableListenChanges: this.environment.entityEditor?.enableListenChanges || false, // False by default\n listenIntervalInSeconds: toNumber(this.environment.entityEditor?.listenIntervalInSeconds, 0), // no timer by default\n pathIdAttribute: 'id',\n autoLoad: true,\n autoUpdateRoute: true,\n i18nPrefix: '',\n\n // Following options are override inside ngOnInit()\n // autoOpenNextTab: ...,\n\n // Override defaults\n ...options\n };\n\n this.settings = injector.get(LocalSettingsService);\n this.errorTranslator = injector.get(FormErrorTranslator);\n this.cd = injector.get(ChangeDetectorRef);\n this.dateFormat = injector.get(DateFormatPipe);\n this.toastController = injector.get(ToastController);\n this._enableListenChanges = options.enableListenChanges;\n this._listenIntervalInSeconds = options.listenIntervalInSeconds;\n this._pathIdAttribute = options.pathIdAttribute;\n this._autoLoad = options.autoLoad;\n this._autoLoadDelay = options.autoLoadDelay;\n this._autoUpdateRoute = options.autoUpdateRoute;\n this._autoOpenNextTab = options.autoOpenNextTab;\n this.i18nContext = {\n prefix: options.i18nPrefix,\n suffix: ''\n };\n\n // FOR DEV ONLY ----\n //this.debug = !environment.production;\n }\n\n ngOnInit() {\n super.ngOnInit();\n\n // Defaults\n this._autoOpenNextTab = toBoolean(this._autoOpenNextTab, !this.isOnFieldMode);\n this.historyIcon = this.historyIcon || {icon: 'list'};\n\n // Register forms\n this.registerForms();\n\n // Disable page, during load\n this.disable();\n }\n\n ngAfterViewInit() {\n super.ngAfterViewInit();\n\n // Load data\n if (this._autoLoad) {\n setTimeout(() => this.loadFromRoute(), this._autoLoadDelay);\n }\n }\n\n ngOnDestroy() {\n super.ngOnDestroy();\n this._listenChangesSubscription = null; // already unsubscribe in the super function\n this.$title.complete();\n this.$title.unsubscribe();\n this.onUpdateView.complete();\n this.onUpdateView.unsubscribe();\n this.savingSubject.unsubscribe();\n }\n\n waitIdle(opts?: WaitForOptions): Promise<void> {\n // Wait end of saving\n if (this.saving) return waitForFalse(this.savingSubject);\n\n return super.waitIdle(opts);\n }\n\n /**\n * Load data from the snapshot route\n *\n * @protected\n */\n protected loadFromRoute(): Promise<void> {\n const route = this.route.snapshot;\n if (!route || isNilOrBlank(this._pathIdAttribute)) {\n throw new Error('Unable to load from route: missing \\'route\\' or \\'options.pathIdAttribute\\'.');\n }\n let id = route.params[this._pathIdAttribute];\n if (isNil(id) || id === 'new') {\n return this.load(undefined, route.params);\n } else {\n // Convert as number, if need\n if (isInt(id)) {\n id = parseInt(id);\n }\n return this.load(id, route.params);\n }\n }\n\n /**\n * Load data from id, using the dataService\n *\n * @param id\n * @param opts\n */\n async load(id?: ID, opts?: EntityServiceLoadOptions & {\n emitEvent?: boolean;\n openTabIndex?: number;\n updateRoute?: boolean;\n [key: string]: any;\n }) {\n if (!this.dataService) throw new Error('Cannot load data: missing \\'dataService\\'!');\n\n this.resetError();\n\n // New data\n if (isNil(id)) {\n try {\n // Create using default values\n const data = new this.dataType();\n this._usageMode = this.computeUsageMode(data);\n await this.onNewEntity(data, opts);\n await this.updateView(data, {\n openTabIndex: 0,\n ...opts\n });\n }\n catch (err) {\n this.setError(err, {emitEvent: false});\n this.selectedTabIndex = 0;\n }\n finally {\n this.markAsLoaded();\n }\n }\n\n // Load existing data\n else {\n try {\n const data = await this.dataService.load(id, opts);\n if (!data) throw {code: ErrorCodes.DATA_NOT_FOUND_ERROR, message: 'ERROR.DATA_NO_FOUND'};\n this._usageMode = this.computeUsageMode(data);\n await this.onEntityLoaded(data, opts);\n await this.updateView(data, opts);\n this.startListenRemoteChanges();\n }\n catch (err) {\n this.setError(err);\n this.selectedTabIndex = 0;\n }\n finally {\n this.markAsLoaded();\n }\n }\n }\n\n canUserWrite(data: T, opts?: any): boolean {\n return this.dataService.canUserWrite(data, opts);\n }\n\n startListenRemoteChanges() {\n // Skip if disable, or already listening\n if (this._listenChangesSubscription || !this._enableListenChanges) return;\n // Skip if new or local data\n if (this.isNewData || EntityUtils.isLocal(this.data)) return;\n\n // Listen for changes on server\n this._listenChangesSubscription = this.listenChanges(this.data.id, {\n interval: this._listenIntervalInSeconds\n })\n .pipe(filter(isNotNil))\n .subscribe((data: T) => {\n const isNewer = isMoment(data.updateDate) && data.updateDate.isAfter(this.data.updateDate);\n if (!isNewer) return; // Skip\n\n // Editor has no changes: reload\n if (!this.dirty) {\n if (this.debug) console.debug(`[data-editor] Changes detected on server, at {${data.updateDate}}: reloading page...`);\n this.reload();\n }\n // Cannot reload: alert the user\n else {\n if (this.debug) console.debug(`[data-editor] Changes detected on server, at {${data.updateDate}}, but page is dirty: skip reloading.`);\n this.showToast({message: 'ERROR.DATA_UPDATE_DATE_CHANGED', type: 'warning', showCloseButton: true});\n }\n });\n this._listenChangesSubscription.add(() => this._listenChangesSubscription = null);\n this.registerSubscription(this._listenChangesSubscription);\n }\n\n stopListenRemoteChanges(){\n if (this._listenChangesSubscription) {\n this.unregisterSubscription(this._listenChangesSubscription);\n this._listenChangesSubscription.unsubscribe();\n this._listenChangesSubscription = null;\n }\n }\n\n async updateView(data: T | null, opts?: {\n emitEvent?: boolean;\n openTabIndex?: number;\n updateRoute?: boolean;\n }): Promise<void> {\n const idChanged = isNotNil(data.id)\n && this.previousDataId !== undefined // Ignore if first loading (=undefined)\n && this.previousDataId !== data.id;\n\n opts = {\n updateRoute: this._autoUpdateRoute && idChanged && !this.loading,\n ...opts\n };\n\n this.data = data;\n this.previousDataId = data.id || null;\n\n await this.ready();\n await this.setValue(data);\n\n if (!opts || opts.emitEvent !== false) {\n this.markAsPristine();\n this.markAsUntouched();\n this.updateViewState(data);\n\n // Need to update route\n if (opts.updateRoute === true) {\n this.updateTabAndRoute(data, opts)\n // Update the title - should be executed AFTER updateRoute because of path change - fix #185\n .then(() => this.updateTitle(data));\n }\n else {\n // Update the next tab\n this.updateTabIndex(opts.openTabIndex);\n\n // Update the title.\n this.updateTitle(data);\n }\n\n this.onUpdateView.emit(data);\n }\n }\n\n /**\n * Enable or disable state\n */\n updateViewState(data: T, opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.isNewData || this.canUserWrite(data)) {\n this.enable(opts);\n }\n else {\n this.disable(opts);\n\n // Allow to sort table\n this.tables?.forEach(t => t.enableSort());\n }\n\n }\n\n /**\n * Update the route location, and open the next tab\n */\n async updateTabAndRoute(data: T, opts?: {\n openTabIndex?: number;\n }): Promise<void> {\n\n this.queryParams = this.queryParams || {};\n\n // Open the next tab\n this.updateTabIndex(opts && opts.openTabIndex);\n\n // Save the opened tab into the queryParams\n this.queryParams.tab = this.selectedTabIndex;\n\n // Update route location\n if (isNotNil(data?.id)) {\n const queryParams = {...this.queryParams};\n queryParams[this._pathIdAttribute] = data.id;\n if (this.debug) console.debug('[entity-editor] Updating route using params: ', queryParams)\n await this.router.navigate(['.'], {\n relativeTo: this.route,\n queryParams\n });\n }\n // Move to ../new\n else {\n const queryParams = {...this.queryParams};\n queryParams[this._pathIdAttribute] = 'new';\n if (this.debug) console.debug('[entity-editor] Updating route to \\'../new\\' using params: ', queryParams)\n await this.router.navigate(['..', 'new'], {\n relativeTo: this.route,\n queryParams\n });\n }\n\n await this.updateRoute(data, this.queryParams);\n }\n\n /**\n * Update the route location, and open the next tab\n */\n updateTabIndex(tabIndex?: number) {\n if (isNotNil(tabIndex) && tabIndex !== this.selectedTabIndex) {\n this.selectedTabIndex = tabIndex;\n this.markForCheck();\n }\n }\n\n async saveAndClose(event: Event, options?: any): Promise<boolean> {\n\n const saved = await this.save(event);\n if (saved) {\n await this.close(event);\n }\n return saved;\n }\n\n async close(event: Event) {\n if (event) {\n if (event.defaultPrevented) return;\n event.preventDefault();\n event.stopPropagation();\n }\n return this.goBack();\n }\n\n /**\n * Save the editor, by calling the dataService.save().\n * Ensure that editor if valid. If not, display an error\n * @param event\n * @param opts\n */\n async save(event?: Event, opts?: any): Promise<boolean> {\n if (this.loading || this.saving) {\n console.debug('[data-editor] Skip save: editor is busy (loading or saving)');\n return false;\n }\n if (!this.dirty) {\n console.debug('[data-editor] Skip save: editor not dirty');\n return true;\n }\n\n // Wait end of async validation\n await this.waitWhilePending();\n\n // If invalid\n if (this.invalid) {\n this.logFormErrors();\n this.openFirstInvalidTab();\n this.scrollToTop();\n this.markAllAsTouched();\n\n this.submitted = true;\n return false;\n }\n\n this.markAsSaving();\n this.resetError();\n\n if (this.debug) console.debug('[data-editor] Saving data...');\n\n try {\n // Compute next tab index (if enable)\n const nextTabIndex = this._autoOpenNextTab && isNil(this.previousDataId) && this.computeNextTabIndex();\n\n // Save all dirty tables\n const saved = await this.saveDirtyChildren();\n if (!saved) return false;\n\n // Get data\n const data = await this.getValue();\n\n this.disable();\n\n // Save form\n const updatedData = await this.dataService.save(data, opts);\n\n await this.onEntitySaved(updatedData);\n\n // Update the view (e.g metadata)\n await this.updateView(updatedData, {\n // Open next tab only if user has not changed it\n openTabIndex: nextTabIndex > this._selectedTabIndex ? nextTabIndex : undefined,\n ...opts\n });\n\n // Subscribe to remote changes\n if (!this._listenChangesSubscription) this.startListenRemoteChanges();\n\n this.submitted = false;\n\n return true;\n } catch (err) {\n this.submitted = true;\n this.setError(err);\n this.selectedTabIndex = 0;\n this.scrollToTop(); // Scroll to top (to show error)\n this.markAsDirty();\n this.enable();\n\n // Concurrent change on pod\n if (err.code === ServerErrorCodes.BAD_UPDATE_DATE && isNotNil(this.data.id)) {\n // Call a data reload (in background), to update the GraphQL cache, and allow to cancel changes\n this.dataService.load(this.data.id, {fetchPolicy: 'network-only'}).then(() => {\n console.debug('[data-editor] Data cache reloaded. User can reload page');\n });\n }\n\n return false;\n } finally {\n this.markAsSaved();\n }\n }\n\n /**\n * Save data (if dirty and valid), and return it. Otherwise, return nil value.\n */\n async saveAndGetDataIfValid(): Promise<T | undefined> {\n // Form is not valid\n if (!this.valid) {\n\n // Make sure validation is finished\n await AppFormUtils.waitWhilePending(this);\n\n // If invalid: Open the first tab in error\n if (this.invalid) {\n this.openFirstInvalidTab();\n return undefined;\n }\n\n // Continue (valid)\n }\n\n // Form is valid, but not saved\n if (this.dirty) {\n const saved = await this.save(new Event('save'));\n if (!saved) return undefined;\n }\n\n // Valid and saved data\n return this.data;\n }\n\n async delete(event?: UIEvent): Promise<boolean> {\n if (this.loading || this.saving) return false;\n\n // Ask user confirmation\n const confirmation = await Alerts.askDeleteConfirmation(this.alertCtrl, this.translate);\n if (!confirmation) return;\n\n console.debug('[data-editor] Asking to delete...');\n\n this.markAsSaving();\n this.resetError();\n\n try {\n // Get data\n const data = await this.getValue();\n const isNew = this.isNewData;\n\n this.disable();\n\n if (!isNew) {\n await this.dataService.delete(data);\n }\n\n await this.onEntityDeleted(data);\n\n // Remove page history\n this.removePageHistory();\n\n\n } catch (err) {\n this.submitted = true;\n this.setError(err);\n this.selectedTabIndex = 0;\n this.markAsSaved();\n this.enable();\n return false;\n }\n\n // Wait, then go back (wait is need in order to update back href is need)\n await setTimeout(() => this.goBack(), 500);\n\n return true;\n }\n\n async reload() {\n this.markAsLoading();\n await this.load(this.data?.id);\n }\n\n async unload(opts?: {emitEvent?: boolean }): Promise<void> {\n await super.unload(opts);\n this.stopListenRemoteChanges();\n this.form.reset();\n this.registerForms();\n this.data = null;\n // TODO: find a way to remove current page from the navigation history\n }\n\n async goBack(event?: Event): Promise<void | boolean> {\n // Go back\n if (this.toolbar?.canGoBack) {\n return this.toolbar.goBack();\n }\n else if (this.defaultBackHref) {\n return this.router.navigateByUrl(this.defaultBackHref);\n } else {\n // Back to home\n return this.router.navigateByUrl('/');\n }\n }\n\n resetError(opts?: {emitEvent?: boolean}) {\n super.resetError(opts);\n }\n\n setError(err: string | AppErrorWithDetails, opts?: {emitEvent?: boolean; detailsCssClass?: string;}) {\n if (!err) {\n super.setError(undefined, opts);\n }\n else if (typeof err === 'string') {\n console.error('[entity-editor] Error: ' + (err || ''));\n super.setError(err as string, opts);\n }\n else {\n console.error('[entity-editor] Error: ' + err.message || '', err);\n let userMessage = err.message && this.translate.instant(err.message) || err;\n\n // Add details error (if any) under the main message\n const detailMessage = (!err.details || typeof err.details === 'string')\n ? err.details as string\n : err.details.message;\n if (isNotNilOrBlank(detailMessage)) {\n const cssClass = opts?.detailsCssClass || 'hidden-xs hidden-sm';\n userMessage += `<br/><small class=\"${cssClass}\" title=\"${detailMessage}\">`;\n userMessage += detailMessage.length < 70 ? detailMessage : detailMessage.substring(0, 67) + '...';\n userMessage += '</small>';\n }\n super.setError(userMessage, opts);\n }\n }\n\n /* -- protected abstract methods (to override) -- */\n\n protected abstract registerForms();\n\n protected abstract computeTitle(data: T): Promise<string>;\n\n protected abstract setValue(data: T): Promise<void> | void;\n\n protected abstract get form(): FormGroup;\n\n protected abstract getFirstInvalidTabIndex(): number;\n\n /* -- protected methods -- */\n\n /**\n * Return undefined to keep same tab\n * @protected\n */\n protected computeNextTabIndex(): number | undefined {\n const nextTabIndex = this.selectedTabIndex + 1;\n return nextTabIndex < this.tabCount ? nextTabIndex : undefined;\n }\n\n protected async onBeforeEntityLoad(): Promise<void> {\n // can be overwritten by subclasses\n }\n\n protected async onNewEntity(data: T, options?: EntityServiceLoadOptions): Promise<void> {\n // can be overwritten by subclasses\n }\n\n protected async onEntityLoaded(data: T, options?: EntityServiceLoadOptions): Promise<void> {\n // can be overwritten by subclasses\n }\n\n protected async onEntitySaved(data: T): Promise<void> {\n // can be overwritten by subclasses\n }\n\n protected async onEntityDeleted(data: T): Promise<void> {\n // can be overwritten by subclasses\n }\n\n protected computeUsageMode(data: T): UsageMode {\n return this.settings.isUsageMode('FIELD') ? 'FIELD' : 'DESK';\n }\n\n protected waitWhilePending(opts?: WaitForOptions): Promise<void> {\n return AppFormUtils.waitWhilePending(this, opts);\n }\n\n protected async getValue(): Promise<T> {\n const json = await this.getJsonValueToSave();\n\n const res = new this.dataType();\n res.fromObject(json);\n\n return res;\n }\n\n protected getJsonValueToSave(): Promise<any> {\n return Promise.resolve(this.form.value);\n }\n\n /**\n * Compute the title\n *\n * @param data\n */\n protected async updateTitle(data?: T) {\n data = data || this.data;\n const title = await this.computeTitle(data);\n this.$title.next(title);\n\n // If NOT data, then add to page history\n if (!this.isNewData) {\n const page = await this.computePageHistory(title);\n if (page) return this.addToPageHistory(page);\n }\n }\n\n protected async addToPageHistory(page: HistoryPageReference, opts?: AddToPageHistoryOptions) {\n if (!page) return; // Skip\n\n return this.settings.addToPageHistory(page, {\n removePathQueryParams: true,\n removeTitleSmallTag: true,\n emitEvent: false,\n ...opts\n });\n }\n\n protected async computePageHistory(title: string): Promise<HistoryPageReference> {\n if (this.debug) console.debug('[entity-editor] Computing page history, using url: ' + this.router.url);\n return {\n title,\n path: this.router.url\n };\n }\n\n protected async removePageHistory(opts?: { emitEvent?: boolean }) {\n return this.settings.removePageHistory(this.router.url, opts);\n }\n\n\n protected computePageUrl(id: ID|'new'): string | any[] {\n const parentUrl = this.getParentPageUrl();\n return parentUrl && `${parentUrl}/${id}`;\n }\n\n protected getParentPageUrl(withQueryParams?: boolean) {\n let parentUrl = this.defaultBackHref;\n\n // Remove query params\n if (withQueryParams !== true && parentUrl && parentUrl.indexOf('?') !== -1) {\n parentUrl = parentUrl.substr(0, parentUrl.indexOf('?'));\n }\n\n return parentUrl;\n }\n\n protected listenChanges(id: ID, opts?: any): Observable<T | undefined> {\n return this.dataService.listenChanges(this.data.id, {\n // Make sure to skip cache, because NOT the full graph will be fetched by subscription\n // When a changes occur, we call reload() to force refetching the full graph\n fetchPolicy: 'no-cache',\n ...opts\n });\n }\n\n protected markForCheck() {\n this.cd?.markForCheck();\n }\n\n /* -- private functions -- */\n\n /**\n * Open the first tab that is invalid\n */\n private openFirstInvalidTab() {\n const invalidTabIndex = this.getFirstInvalidTabIndex();\n if (invalidTabIndex !== -1 && this.selectedTabIndex !== invalidTabIndex) {\n this.selectedTabIndex = invalidTabIndex;\n this.markForCheck();\n }\n }\n\n protected async updateRoute(data: T, queryParams: any): Promise<boolean> {\n const path = this.computePageUrl(isNotNil(data.id) ? data.id : 'new');\n const commands: any[] = (path && typeof path === 'string') ? path.split('/') : path as any[];\n if (isNotEmptyArray(commands)) {\n return await this.router.navigate(commands, {\n replaceUrl: true,\n queryParams: this.queryParams\n });\n }\n else {\n console.warn('Skip page route update. Invalid page path: ', path);\n }\n }\n\n\n}\n","import {AfterViewInit, ChangeDetectorRef, Directive, Injector, Input, OnDestroy, OnInit, Optional} from '@angular/core';\nimport {Router} from '@angular/router';\nimport {AlertController, ModalController} from '@ionic/angular';\n\nimport {TranslateService} from '@ngx-translate/core';\nimport {BehaviorSubject, Subject} from 'rxjs';\nimport {LocalSettingsService} from '../services/local-settings.service';\nimport {Entity} from '../services/model/entity.model';\nimport {UsageMode} from '../services/model/settings.model';\nimport {FormGroup} from '@angular/forms';\nimport {AppTabEditor, AppTabEditorOptions, IAppEditor} from './editor.class';\nimport {AppFormUtils} from './form.utils';\nimport {Alerts} from '../../shared/alerts';\nimport {ErrorCodes} from '../services/errors';\nimport {isNil, isNotNil, isNotNilOrBlank} from '../../shared/functions';\nimport {DateFormatPipe} from '../../shared/pipes/date-format.pipe';\nimport {Environment, ENVIRONMENT} from '../../../environments/environment.class';\nimport {waitFor, waitForFalse, WaitForOptions} from '../../shared/observables';\nimport {FormErrorTranslator} from '../../shared/validator/form-error-adapter.class';\nimport {AppErrorWithDetails} from './entity-editor.class';\nimport {debounceTime} from 'rxjs/operators';\n\n\nexport interface IEntityEditorModalOptions<\n T extends Entity<T, ID> = Entity<any, any>,\n ID = number> {\n\n usageMode: UsageMode;\n data: T;\n disabled: boolean;\n\n onAfterModalInit?: <M extends AppEntityEditorModal<T, ID>>(modal: M) => void | Promise<void>;\n onDelete?: (event: UIEvent, data: T) => Promise<boolean>;\n\n mobile: boolean;\n i18nSuffix?: string;\n}\n\nexport class AppEntityEditorModalOptions extends AppTabEditorOptions {\n i18nPrefix?: string;\n}\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppEntityEditorModal<\n T extends Entity<T, ID>,\n ID = number,\n O extends AppEntityEditorModalOptions = AppEntityEditorModalOptions\n >\n extends AppTabEditor<T, ID>\n implements OnInit, OnDestroy, AfterViewInit, IEntityEditorModalOptions<T, ID> {\n\n private _usageMode: UsageMode;\n protected _logPrefix;\n protected _isNewData: boolean;\n\n protected readonly dateFormat: DateFormatPipe;\n protected readonly cd: ChangeDetectorRef;\n protected readonly settings: LocalSettingsService;\n protected readonly modalCtrl: ModalController;\n protected readonly environement: Environment;\n protected errorTranslator: FormErrorTranslator;\n\n readonly savingSubject = new BehaviorSubject<boolean>(false);\n\n $title = new Subject<string>();\n\n @Input() data: T;\n @Input() mobile: boolean;\n @Input() usageMode: UsageMode;\n @Input() onAfterModalInit: <M extends AppEntityEditorModal<T, ID>>(modal: M) => void | Promise<void>;\n @Input() onDelete: (event: UIEvent, data: T) => Promise<boolean>;\n @Input() i18nSuffix: string = null;\n\n @Input() set isNewData(value: boolean) {\n this._isNewData = value;\n }\n\n get isNewData(): boolean {\n return isNotNil(this._isNewData) ? this._isNewData : isNil(this.data?.id);\n }\n\n @Input() set disabled(value: boolean) {\n this._enabled = !value;\n }\n\n get disabled(): boolean {\n return !this._enabled;\n }\n\n get isOnFieldMode(): boolean {\n return this.settings.isOnFieldMode(this._usageMode);\n }\n\n get saving(): boolean {\n return this.savingSubject.value;\n }\n\n markAsSaving(opts?: { emitEvent?: boolean }){\n if (this.savingSubject.value !== true) {\n this.savingSubject.next(true);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n markAsSaved(opts?: { emitEvent?: boolean }){\n if (this.savingSubject.value !== false) {\n this.savingSubject.next(false);\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n protected constructor(\n injector: Injector,\n protected dataType: new() => T,\n @Optional() options?: O\n ) {\n super(null,\n injector.get(Router),\n injector.get(AlertController),\n injector.get(TranslateService),\n options);\n this.environement = injector.get(ENVIRONMENT);\n options = <O>{\n // Default options\n i18nPrefix: '',\n\n // Override defaults\n ...options\n };\n\n this.queryTabIndexParamName = undefined; // Important: avoid query parameter changed\n this.settings = injector.get(LocalSettingsService);\n this.errorTranslator = injector.get(FormErrorTranslator);\n this.cd = injector.get(ChangeDetectorRef);\n this.dateFormat = injector.get(DateFormatPipe);\n this.modalCtrl = injector.get(ModalController);\n this.i18nContext = {\n prefix: options.i18nPrefix,\n suffix: this.i18nSuffix || ''\n };\n\n // FOR DEV ONLY ----\n //this.debug = !environment.production;\n }\n\n ngOnInit() {\n\n // Default values\n this.mobile = isNotNil(this.mobile) ? this.mobile : this.settings.mobile;\n\n super.ngOnInit();\n\n // Register forms\n this.registerForms();\n\n // Disable\n if (this.disabled) this.disable();\n\n if (this.isNewData) {\n // Update the title.\n this.updateTitle();\n }\n\n else {\n // Update title each time value changes\n this.registerSubscription(\n this.form.valueChanges\n .pipe(debounceTime(250))\n .subscribe(json => this.updateTitle(json))\n );\n }\n }\n\n ngAfterViewInit() {\n super.ngAfterViewInit();\n\n if (this.onAfterModalInit) {\n Promise.resolve(this.onAfterModalInit(this))\n .then(() => this.load());\n }\n else {\n // Use a timeout to avoid error 'NG0100: ExpressionChangedAfterItHasBeenCheckedError'\n setTimeout(() => this.load());\n }\n }\n\n ngOnDestroy() {\n super.ngOnDestroy();\n this.$title.complete();\n this.$title.unsubscribe();\n this.savingSubject.unsubscribe();\n }\n\n waitIdle(opts?: WaitForOptions): Promise<void> {\n // Wait end of saving\n if (this.saving) return waitForFalse(this.savingSubject);\n\n return super.waitIdle(opts);\n }\n\n async load() {\n this.markAsReady();\n this.markAsLoading();\n\n try {\n await this.updateView(this.data);\n }\n catch(err) {\n if (err === 'CANCELLED') return;\n this.setError(err);\n this.selectedTabIndex = 0;\n }\n finally {\n this.markAsLoaded();\n }\n }\n\n reload(): Promise<void> {\n if (this.dirty) {\n return this.load();\n }\n }\n\n unload(opts?: { emitEvent?: boolean }): Promise<void> {\n throw new Error(\"No implemented on modal\");\n }\n\n async updateView(data: T | null, opts?: {\n emitEvent?: boolean;\n openTabIndex?: number;\n }): Promise<void> {\n\n this.resetError();\n\n if (!this.data) throw {code: ErrorCodes.DATA_NOT_FOUND_ERROR, message: 'ERROR.DATA_NO_FOUND'};\n\n await this.setValue(data);\n\n if (!opts || opts.emitEvent !== false) {\n this.markAsPristine();\n this.markAsUntouched();\n this.updateViewState(data);\n\n // Update the title.\n this.updateTitle(data);\n }\n }\n\n /**\n * Enable or disable state\n */\n updateViewState(data: T, opts?: {onlySelf?: boolean; emitEvent?: boolean }) {\n if (this.isNewData || this.enabled) {\n this.enable(opts);\n }\n else {\n this.disable(opts);\n\n // Allow to sort table\n this.tables?.forEach(t => t.enableSort());\n }\n }\n\n async saveAndClose(event?: Event): Promise<boolean> {\n\n const data = await this.saveAndGetDataIfValid();\n if (data) {\n this.modalCtrl.dismiss(data);\n return true;\n }\n return false;\n }\n\n async close(event: UIEvent): Promise<void> {\n if (this.dirty) {\n const saveBeforeLeave = await Alerts.askSaveBeforeLeave(this.alertCtrl, this.translate, event);\n\n // User cancelled\n if (isNil(saveBeforeLeave) || event && event.defaultPrevented) {\n return;\n }\n\n // Is user confirm: close normally\n if (saveBeforeLeave === true) {\n await this.saveAndClose(event);\n return;\n }\n }\n\n await this.modalCtrl.dismiss();\n }\n\n /**\n * Save the editor, by calling the dataService.save().\n * Ensure that editor if valid. If not, display an error\n * @param event\n * @param opts\n */\n async save(event?: Event, opts?: any): Promise<boolean> {\n if (this.loading || this.saving || this.disabled) {\n console.debug(this._logPrefix + 'Skip save: modal is busy (loading or saving)');\n return false;\n }\n if (!this.dirty) {\n console.debug(this._logPrefix + 'Skip save: modal not dirty');\n return true;\n }\n\n // Wait end of async validation\n await this.waitWhilePending();\n\n // If invalid\n if (this.invalid) {\n this.logFormErrors();\n this.setError('COMMON.FORM.HAS_ERROR');\n this.openFirstInvalidTab();\n this.scrollToTop();\n this.markAllAsTouched();\n\n this.submitted = true;\n return false;\n }\n\n this.markAsSaving();\n this.resetError();\n\n if (this.debug) console.debug(this._logPrefix + 'Saving data...');\n\n try {\n // Save all dirty children\n const saved = await this.saveDirtyChildren();\n if (!saved) return false;\n\n // Fill data\n this.data = await this.getValue();\n\n // Mark as submitted\n this.submitted = true;\n\n return true;\n } catch (err) {\n this.submitted = true;\n this.setError(err);\n this.selectedTabIndex = 0;\n this.scrollToTop(); // Scroll to top (to show error)\n this.markAsDirty();\n this.enable();\n\n return false;\n } finally {\n this.markAsSaved();\n }\n }\n\n /**\n * Save data (if dirty and valid), and return it. Otherwise, return nil value.\n */\n async saveAndGetDataIfValid(): Promise<T | undefined> {\n // Form is not valid\n if (!this.valid) {\n\n // Make sure validation is finished\n await AppFormUtils.waitWhilePending(this);\n\n // If invalid: Open the first tab in error\n if (this.invalid) {\n this.openFirstInvalidTab();\n return undefined;\n }\n\n // Continue (valid)\n }\n\n // Form is valid, but not saved\n if (this.dirty) {\n const saved = await this.save(new Event('save'));\n if (!saved) return undefined;\n }\n\n // Valid and saved data\n return this.data;\n }\n\n async delete(event?: UIEvent) {\n if (this.loading || this.saving) return false;\n\n this.markAsSaving();\n this.resetError();\n try {\n\n // Delegate deletion to modal caller\n if (this.onDelete) {\n const result = await this.onDelete(event, this.data);\n\n // User cancelled\n if (isNil(result) || (event && event.defaultPrevented)) return;\n\n if (result) {\n await this.modalCtrl.dismiss(this.data, 'delete');\n }\n }\n\n // Or dismiss, with the role 'delete'\n else {\n if (this.isNewData) {\n console.error(this._logPrefix + \"Trying to delete a new data. Make no sense!\");\n }\n\n await this.modalCtrl.dismiss(this.data, 'delete');\n }\n }\n catch (err) {\n this.submitted = true;\n this.setError(err);\n this.selectedTabIndex = 0;\n this.markAsSaved();\n if (this.enabled) this.enable();\n return false;\n }\n }\n\n resetError(opts?: {emitEvent?: boolean}) {\n if (isNotNilOrBlank(this.error)) {\n this.error = null;\n if (!opts || opts.emitEvent !== false) this.markForCheck();\n }\n }\n\n setError(err: string | AppErrorWithDetails, opts?: {emitEvent?: boolean; detailsCssClass?: string;}) {\n if (!err) {\n super.setError(undefined, opts);\n }\n else if (typeof err === 'string') {\n console.error('[entity-editor] Error: ' + (err || ''));\n super.setError(err as string, opts);\n }\n else {\n console.error('[entity-editor] Error: ' + err.message || '', err);\n let userMessage = err.message && this.translate.instant(err.message) || err;\n\n // Add details error (if any) under the main message\n const detailMessage = (!err.details || typeof err.details === 'string')\n ? err.details as string\n : err.details.message;\n if (isNotNilOrBlank(detailMessage)) {\n const cssClass = opts?.detailsCssClass || 'hidden-xs hidden-sm';\n userMessage += `<br/><small class=\"${cssClass}\" title=\"${detailMessage}\">`;\n userMessage += detailMessage.length < 70 ? detailMessage : detailMessage.substring(0, 67) + '...';\n userMessage += '</small>';\n }\n super.setError(userMessage, opts);\n }\n }\n\n /* -- protected abstract methods (to override) -- */\n\n protected abstract registerForms();\n\n protected abstract computeTitle(data: T): Promise<string>;\n\n protected abstract setValue(data: T): Promise<void> | void;\n\n protected abstract get form(): FormGroup;\n\n protected abstract getFirstInvalidTabIndex(): number;\n\n /* -- protected methods -- */\n\n protected waitWhilePending(opts?: WaitForOptions): Promise<void> {\n return AppFormUtils.waitWhilePending(this, opts);\n }\n\n protected async getValue(): Promise<T> {\n const json = await this.getJsonValueToSave();\n\n const res = new this.dataType();\n res.fromObject(json);\n\n return res;\n }\n\n protected getJsonValueToSave(): Promise<any> {\n return Promise.resolve(this.form.value);\n }\n\n /**\n * Compute the title\n *\n * @param data\n */\n protected async updateTitle(data?: T) {\n data = data || this.data;\n const title = await this.computeTitle(data);\n this.$title.next(title);\n }\n\n protected async scrollToTop(duration?: number) {\n if (this.content) {\n return this.content.scrollToTop(duration);\n }\n }\n\n protected markForCheck() {\n this.cd?.markForCheck();\n }\n\n /* -- private functions -- */\n\n /**\n * Open the first tab that is invalid\n */\n private openFirstInvalidTab() {\n const invalidTabIndex = this.getFirstInvalidTabIndex();\n if (invalidTabIndex !== -1 && this.selectedTabIndex !== invalidTabIndex) {\n this.selectedTabIndex = invalidTabIndex;\n this.markForCheck();\n }\n }\n\n}\n","import {Directive, Injector, Input} from '@angular/core';\nimport {ValidatorService} from '@e-is/ngx-material-table';\nimport {EntitiesTableDataSourceConfig, EntitiesTableDataSource} from './entities-table-datasource.class';\nimport {AppTable} from './table.class';\nimport {IEntity} from '../services/model/entity.model';\nimport {InMemoryEntitiesService} from '../../shared/services/memory-entity-service.class';\n\n// @dynamic\n@Directive()\n// eslint-disable-next-line @angular-eslint/directive-class-suffix\nexport abstract class AppInMemoryTable<\n T extends IEntity<T, ID>,\n F = any,\n ID = number\n > extends AppTable<T, F, ID> {\n\n @Input() canEdit = false;\n @Input() canDelete = false;\n\n set value(data: T[]) {\n this.setValue(data);\n }\n\n get value(): T[] {\n return this.memoryDataService.value;\n }\n\n protected constructor(\n injector: Injector,\n protected columns: string[],\n protected dataType: new () => T,\n protected memoryDataService: InMemoryEntitiesService<T, F, ID>,\n protected validatorService: ValidatorService,\n options?: EntitiesTableDataSourceConfig<T, ID>,\n filter?: F\n ) {\n super(injector,\n columns,\n new EntitiesTableDataSource<T, F, ID>(dataType, memoryDataService, validatorService, options),\n filter);\n\n this.autoLoad = false; // waiting value to be set\n }\n\n ngOnInit() {\n super.ngOnInit();\n }\n\n setValue(value: T[], opts?: { emitEvent?: boolean }) {\n // Reset previous error\n if (this.error) {\n this.setError(null);\n this.markForCheck();\n }\n this.memoryDataService.value = value;\n if (!opts || opts.emitEvent !== false) {\n this.onRefresh.emit();\n }\n }\n\n protected equals(t1: T, t2: T): boolean {\n return this.memoryDataService.equals(t1, t2);\n }\n}\n\n","export const SocialErrorCodes = {\n LOAD_USER_EVENTS_ERROR: 50000,\n SAVE_USER_EVENT_ERROR: 50001,\n COUNT_USER_EVENT_ERROR: 50002,\n SEND_MESSAGE_ERROR: 50003,\n SUBSCRIBE_USER_EVENTS_ERROR: 50005,\n\n SUBSCRIBE_JOB_PROGRESSION_ERROR: 50010\n};\n","import {Directive, InjectionToken, OnDestroy} from '@angular/core';\nimport {FetchPolicy} from '@apollo/client/core';\nimport {SocialErrorCodes} from '../social.errors';\nimport {AccountService} from '../../core/services/account.service';\nimport {GraphqlService} from '../../core/graphql/graphql.service';\nimport {BehaviorSubject, merge, Observable, of, Subject, Subscription} from 'rxjs';\nimport {IUserEvent, IUserEventFilter} from './user-event.model';\nimport {SortDirection} from '@angular/material/sort';\nimport {EntitiesServiceLoadOptions, EntitiesServiceWatchOptions, EntityServiceLoadOptions, IEntitiesService, LoadResult, Page} from '../../shared/services/entity-service.class';\nimport {distinctUntilChanged, map, mergeMap} from 'rxjs/operators';\nimport { isEmptyArray, isNotEmptyArray, isNotNil, toNumber } from '../../shared/functions';\nimport {TranslateService} from '@ngx-translate/core';\nimport {NetworkService} from '../../core/services/network.service';\nimport {BaseGraphqlService, BaseGraphqlServiceOptions} from '../../core/services/base-graphql-service.class';\nimport {EntityUtils} from '../../core/services/model/entity.model';\nimport {DateUtils} from '../../shared/dates';\nimport * as momentImported from 'moment';\nimport {Moment} from 'moment';\nimport {IStartableService} from '../../shared/services/startable-service.class';\n\nconst moment = momentImported;\n\nexport const APP_USER_EVENT_SERVICE = new InjectionToken<IUserEventService<any, any>>('UserEventService');\n\nexport declare interface UserEventLoadOptions extends EntitiesServiceLoadOptions {\n withContent?: boolean; // Default to false\n}\nexport declare interface UserEventWatchOptions extends EntitiesServiceWatchOptions {\n withContent?: boolean; // Default to false\n}\nexport interface IUserEventQueries {\n loadAll: any;\n loadAllWithContent: any;\n count?: any;\n}\n\nexport interface IUserEventMutations {\n save: any;\n markAsRead?: any;\n deleteByIds: any;\n}\n\nexport interface IUserEventSubscriptions {\n listenAllChanges: any;\n listenCountChanges?: any;\n}\n\nexport interface IUserEventListener<E extends IUserEvent<E>> {\n accept: (E) => boolean;\n onReceived?: (E) => Promise<E> | E | undefined;\n onRead?: (E) => Promise<void> | void;\n}\n\nexport interface UserEventServiceOptions<\n Q extends IUserEventQueries = IUserEventQueries,\n M extends IUserEventMutations = IUserEventMutations,\n S extends IUserEventSubscriptions = IUserEventSubscriptions\n > extends BaseGraphqlServiceOptions {\n queries: Q;\n mutations?: Partial<M>;\n subscriptions?: Partial<S>;\n}\n\nexport interface IUserEventService<E extends IUserEvent<E>,\n F extends IUserEventFilter<E>,\n WO extends UserEventWatchOptions = UserEventWatchOptions,\n LO extends UserEventLoadOptions = UserEventLoadOptions\n >\n extends IEntitiesService<E, F, WO>, IStartableService {\n\n countSubject: Observable<number>;\n\n add(entity: E);\n\n count(filter: Partial<F>, options?: { fetchPolicy?: FetchPolicy; }): Promise<number>;\n\n listenCountChanges(filter: Partial<F>, options?: WO & { interval?: number; fetchPolicy?: FetchPolicy; }): Observable<number>;\n\n listenAllChanges(filter: Partial<F>, options?: WO & { interval?: number; fetchPolicy?: FetchPolicy; }): Observable<E[]>;\n\n save(entity: E, options?: EntityServiceLoadOptions): Promise<E>;\n\n delete(entity: E): Promise<any>;\n\n markAllAsRead(entities: E[]);\n\n registerListener(listener: IUserEventListener<E>);\n\n resetCount();\n}\n\n@Directive()\nexport abstract class AbstractUserEventService<E extends IUserEvent<E, any>,\n F extends IUserEventFilter<E, any>,\n WO extends UserEventWatchOptions = UserEventWatchOptions,\n LO extends UserEventLoadOptions = UserEventLoadOptions,\n Q extends IUserEventQueries = IUserEventQueries,\n M extends IUserEventMutations = IUserEventMutations,\n S extends IUserEventSubscriptions = IUserEventSubscriptions\n >\n extends BaseGraphqlService<E, F>\n implements IUserEventService<E, F, WO, LO>, OnDestroy {\n\n protected readonly queries: Q;\n protected readonly mutations: Partial<M>;\n protected readonly subscriptions: Partial<S>;\n protected readonly _countSubject = new BehaviorSubject<number>(0);\n protected resetCountDate: Moment;\n protected listeners: IUserEventListener<E>[] = [];\n private _subscriptions = new Subscription();\n private _listenSubscription: Subscription;\n\n get countSubject(): Subject<number> {\n return this._countSubject;\n }\n\n protected constructor(\n protected graphql: GraphqlService,\n protected accountService: AccountService,\n protected network: NetworkService,\n protected translate: TranslateService,\n protected options: UserEventServiceOptions<Q, M, S>\n ) {\n super(graphql, options);\n this.queries = options.queries;\n this.mutations = options.mutations || <Partial<M>>{};\n this.subscriptions = options.subscriptions || <Partial<S>>{};\n this._logPrefix = '[user-event-service] ';\n }\n\n protected async ngOnStart(): Promise<void> {\n\n // Update component when refresh is need (=login events)\n this._subscriptions.add(\n merge(\n this.accountService.onLogin,\n this.accountService.onLogout,\n of() // Starts with - first attempt if account is ready\n )\n .pipe(\n // Wait account service ready (can be restarted)\n mergeMap(() => this.accountService.ready()),\n map(() => this.accountService.isLogin()),\n distinctUntilChanged()\n )\n .subscribe(login => {\n if (login) {\n this.onLogin();\n } else {\n this.onLogout();\n }\n }));\n }\n\n ngOnDestroy() {\n this._subscriptions.unsubscribe();\n }\n\n abstract asFilter(filter: Partial<F>): F;\n\n abstract fromObject(source: any): E;\n\n watchAll(offset: number, size: number, sortBy?: string, sortDirection?: SortDirection, filter?: Partial<F>, options?: WO): Observable<LoadResult<E>> {\n return this.watchPage(<Page>{ offset, size, sortBy, sortDirection }, filter, options);\n }\n\n watchPage(page: Page,\n filter?: Partial<F>,\n opts?: WO): Observable<LoadResult<E>> {\n\n let now = this._debug && Date.now();\n if (!filter) {\n filter = this.defaultFilter();\n }\n console.debug(`${this._logPrefix}Loading user events...`, filter);\n\n filter = this.asFilter(filter);\n\n // Force recipient to current issuer, if not admin and not specified\n if (isEmptyArray(filter?.recipients) || !this.accountService.isAdmin()) {\n const recipient = this.defaultRecipient();\n if (!filter?.recipients?.includes(recipient)) {\n console.warn('[user-events-service] Force user event filter.recipient=' + recipient);\n filter.recipients = [recipient];\n }\n }\n\n const withContent = opts?.withContent === true;\n\n return this.mutableWatchQuery<LoadResult<E>, { filter: any, page: Page }>({\n queryName: withContent ? 'LoadAllWithContent' : 'LoadAll',\n query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,\n variables: {\n page: {\n sortBy: 'creationDate',\n ...page,\n // @ts-ignore\n sortDirection: (page.sortDirection || 'desc').toUpperCase()\n },\n filter: filter && filter.asPodObject()\n },\n arrayFieldName: 'data',\n error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },\n fetchPolicy: opts?.fetchPolicy || 'cache-first',\n insertFilterFn: filter && filter.asFilterFn()\n })\n .pipe(\n mergeMap(async (res) => {\n let data = await Promise.all((res?.data || []).map(value => this.processUserEvent(value, this)));\n\n if (now) {\n console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);\n now = null;\n }\n\n // Must re-order because of listenAllChanges result will add new event at the end\n data = EntityUtils.sort(data, page.sortBy, page.sortDirection);\n\n const result = <LoadResult<E>>{\n data,\n total: toNumber(res?.total, data.length)\n };\n\n // Add fetch more capability, if total was fetched\n if (isNotNil(res.total)) {\n const nextOffset = (page.offset || 0) + data.length;\n if (nextOffset < result.total) {\n result.fetchMore = (_) => this.loadPage({...page, offset: nextOffset}, filter,\n {...opts, fetchPolicy: <FetchPolicy>'no-cache'} as unknown as LO\n );\n }\n }\n\n return result;\n })\n );\n }\n\n async loadPage(page: Page,\n filter?: Partial<F>,\n opts?: LO): Promise<LoadResult<E>> {\n\n const now = this._debug && Date.now();\n if (!filter) filter = this.defaultFilter();\n\n console.debug(`${this._logPrefix}Loading user events...`, filter);\n\n filter = this.asFilter(filter);\n\n // Force recipient to current issuer, if not admin and not specified\n if (isEmptyArray(filter?.recipients) || !this.accountService.isAdmin()) {\n const recipient = this.defaultRecipient();\n if (!filter?.recipients?.includes(recipient)) {\n console.warn('[user-events-service] Force user event filter.recipient=' + recipient);\n filter.recipients = [recipient];\n }\n }\n\n const withContent = opts?.withContent === true;\n\n const res = await this.graphql.query<LoadResult<E>>({\n query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,\n variables: {\n page: {\n sortBy: 'creationDate',\n ...page,\n // @ts-ignore\n sortDirection: (page.sortDirection || 'desc').toUpperCase()\n },\n filter: filter && filter.asPodObject()\n },\n error: { code: SocialErrorCodes.LOAD_USER_EVENTS_ERROR, message: 'SOCIAL.ERROR.LOAD_USER_EVENTS_ERROR' },\n fetchPolicy: opts?.fetchPolicy\n })\n let data = await Promise.all((res?.data || []).map(value => this.processUserEvent(value, this)));\n\n if (now) console.debug(`${this._logPrefix}${data.length} user events loaded in ${Date.now() - now}ms`);\n\n // Must re-order because of listenAllChanges result will add new event at the end\n data = EntityUtils.sort(data, page.sortBy, page.sortDirection);\n\n const result = <LoadResult<E>>{\n data,\n total: toNumber(res?.total, data.length)\n };\n\n // Add fetch more capability, if total was fetched\n if (isNotNil(res.total)) {\n const nextOffset = (page.offset || 0) + data.length;\n if (nextOffset < result.total) {\n result.fetchMore = (_) => this.loadPage({...page, offset: nextOffset}, filter, opts);\n }\n }\n\n return result;\n }\n\n async add(entity: E) {\n\n // TODO set an id !!!!!!!!!!!!!!!!!!!!!!!!!\n\n entity = await this.processUserEvent(entity);\n\n if (!entity) return; // Rejected\n\n const withContent = !!entity.content;\n\n // Add user event locally\n this.insertIntoMutableCachedQueries(\n this.graphql.cache,\n {\n query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,\n data: entity\n }\n );\n\n // Update count\n this._countSubject.next(this._countSubject.value + 1);\n }\n\n async count(filter: Partial<F>, options?: { fetchPolicy?: FetchPolicy; }): Promise<number> {\n\n if (!this.queries?.count) {\n console.warn(`${this._logPrefix}Query 'count' not provided, skip.`);\n return undefined;\n }\n\n if (!filter) filter = this.defaultFilter();\n // Apply last reset date as start date\n filter.startDate = this.resetCountDate;\n filter = this.asFilter(filter);\n\n if (this._debug) console.debug(`${this._logPrefix}Counting user events with filter:`, filter);\n\n const res = await this.graphql.query<{ total: number; }>({\n query: this.queries.count,\n variables: {\n filter: filter.asPodObject()\n },\n error: { code: SocialErrorCodes.COUNT_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.COUNT_USER_EVENT_ERROR' },\n fetchPolicy: options?.fetchPolicy || 'network-only'\n });\n return res.total;\n }\n\n listenCountChanges(filter: Partial<F>, options?: WO & { interval?: number; fetchPolicy?: FetchPolicy }): Observable<number> {\n\n if (!this.subscriptions?.listenCountChanges) {\n console.warn(`${this._logPrefix}Subscription query 'listenCountChanges' not provided, skip.`);\n return of();\n }\n\n if (!filter) filter = this.defaultFilter();\n // Apply last reset date as start date\n filter.startDate = this.resetCountDate;\n filter.excludeRead = true;\n filter = this.asFilter(filter);\n\n if (this._debug) console.debug(`${this._logPrefix}[WS] Listening count changes for user events with filter:`, filter);\n\n return this.graphql.subscribe<{ total: number }, { filter: any, interval: number }>({\n query: this.subscriptions.listenCountChanges,\n fetchPolicy: options?.fetchPolicy,\n variables: { filter: filter.asPodObject(), interval: toNumber(options?.interval, 10) },\n error: {\n code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,\n message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'\n }\n }).pipe(\n map(({ total }) => {\n if (total && this._debug) console.debug(`${this._logPrefix}Received new user events count:`, total);\n // update count\n this._countSubject.next(total);\n return total;\n }\n )\n );\n\n }\n\n listenAllChanges(filter: Partial<F>, opts?: WO & { interval?: number; fetchPolicy?: FetchPolicy; toEntity?: boolean }): Observable<E[]> {\n\n if (!this.subscriptions?.listenAllChanges) {\n console.warn(`${this._logPrefix}Subscription query 'listenAllChanges' not provided, skip.`);\n return of();\n }\n\n if (!filter) filter = this.defaultFilter();\n filter = this.asFilter(filter);\n\n const withContent = opts?.withContent === true;\n\n if (this._debug) console.debug(`${this._logPrefix}[WS] Listening changes for user events with filter:`, filter);\n\n return this.graphql.subscribe<{ data: any[] }, { filter: any, interval: number }>({\n query: this.subscriptions.listenAllChanges,\n fetchPolicy: opts?.fetchPolicy,\n variables: { filter: filter.asPodObject(), interval: toNumber(opts?.interval, 10) },\n error: {\n code: SocialErrorCodes.SUBSCRIBE_USER_EVENTS_ERROR,\n message: 'SOCIAL.ERROR.SUBSCRIBE_USER_EVENTS_ERROR'\n }\n }).pipe(\n mergeMap(async ({ data }) => {\n if (data && this._debug) console.debug(`${this._logPrefix}Received new user events:`, data);\n\n // Update cache (will update watchAll queries)\n if (isNotEmptyArray(data)) {\n this.insertIntoMutableCachedQueries(\n this.graphql.cache,\n {\n query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,\n data: data\n }\n );\n }\n\n // Convert to entities\n if (!opts || opts.toEntity !== false) {\n return await Promise.all((data || []).map(value => this.processUserEvent(value, this)));\n }\n else {\n return data;\n }\n })\n );\n\n }\n\n async delete(entity: E): Promise<any> {\n if (!entity) return; // skip\n await this.deleteAll([entity]);\n }\n\n async deleteAll(entities: E[], opts?: any): Promise<any> {\n const ids = entities && entities\n .map(t => t.id);\n if (isEmptyArray(ids)) return; // stop, if nothing else to do\n\n const now = Date.now();\n if (this._debug) console.debug(`${this._logPrefix}Deleting events... ids:`, ids);\n\n await this.graphql.mutate<any>({\n mutation: this.mutations.deleteByIds,\n variables: {\n ids\n },\n update: (proxy) => {\n // Remove from caches\n this.removeFromMutableCachedQueriesByIds(proxy, {\n query: this.queries.loadAll,\n ids\n });\n this.removeFromMutableCachedQueriesByIds(proxy, {\n query: this.queries.loadAllWithContent,\n ids\n });\n\n if (this._debug) console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);\n }\n });\n }\n\n async save(entity: E, options?: EntityServiceLoadOptions): Promise<E> {\n this.fillDefaultProperties(entity);\n\n // Transform into json\n const withContent = !!entity.content;\n const json = entity.asObject();\n\n const now = Date.now();\n if (this._debug) console.debug(`${this._logPrefix}Saving user event...`, json);\n\n await this.graphql.mutate<{ data: any }>({\n mutation: this.mutations.save,\n variables: {\n data: json\n },\n error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },\n update: (proxy, { data }) => {\n // Update entity\n const savedEntity = data && data.data;\n if (savedEntity) {\n if (this._debug) console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);\n this.copyIdAndUpdateDate(savedEntity, entity);\n\n // Add to cache\n if (withContent) {\n this.insertIntoMutableCachedQueries(proxy, {\n query: this.queries.loadAllWithContent,\n data: savedEntity\n });\n } else {\n this.insertIntoMutableCachedQueries(proxy, {\n query: this.queries.loadAll,\n data: {\n ...savedEntity,\n content: null\n }\n });\n }\n }\n }\n });\n\n return entity;\n }\n\n async saveAll(entities: E[], opts?: any): Promise<E[]> {\n return Promise.all(entities\n .map(entity => this.save(entity, opts))\n );\n }\n\n async markAllAsRead(entities: E[]) {\n\n const userEventWithoutReadListeners: E[] = [];\n for (const entity of (entities || [])) {\n // Get onRead listeners\n const onReadListeners = (this.listeners || []).filter(listener => !!listener.onRead).filter(listener => listener.accept(entity));\n if (onReadListeners.length) {\n for (const listener of onReadListeners) {\n await listener.onRead(entity);\n }\n } else {\n // Add to this list for default operation\n userEventWithoutReadListeners.push(entity);\n }\n }\n\n // Use default\n await this.defaultMarkAsRead(userEventWithoutReadListeners);\n }\n\n registerListener(listener: IUserEventListener<E>) {\n if (!this.listeners) this.listeners = [];\n this.listeners.push(listener);\n }\n\n resetCount() {\n this._countSubject.next(undefined);\n this.resetCountDate = moment();\n // restart listening count changes\n this.startListenCountChanges();\n }\n\n /* -- protected methods -- */\n\n protected async onLogin() {\n // Get first count\n const count = await this.count(undefined);\n if (this._debug) console.debug(`${this._logPrefix}Receiving user events count`, count);\n // Update count\n this._countSubject.next(count);\n\n // Then listen changes\n this.startListenCountChanges();\n }\n\n protected onLogout() {\n this.stopListenCountChanges();\n }\n\n protected startListenCountChanges() {\n this.stopListenCountChanges();\n this._listenSubscription = this.listenCountChanges(undefined).subscribe();\n }\n\n protected stopListenCountChanges() {\n this._listenSubscription?.unsubscribe();\n this._listenSubscription = undefined;\n }\n\n protected async processUserEvent(source: any, that?: AbstractUserEventService<E, F>): Promise<E> {\n that = that || this;\n\n // Convert json source to IUserEvent\n let target = that.fromObject(source);\n\n // Get listeners\n const listeners = (that.listeners || [])\n .filter(listener => !!listener.onReceived)\n .filter(listener => listener.accept(target));\n for (const listener of listeners) {\n if (target) {\n const res = listener.onReceived(target);\n target = (res instanceof Promise) ? await res : res;\n } else {\n if (that._debug) console.debug(`${that._logPrefix}Event has been rejected by a listener`, source);\n break;\n }\n }\n\n return target;\n }\n\n protected async defaultMarkAsRead(userEvents: E[]) {\n if (!userEvents) throw new Error(`${this._logPrefix}Invalid event to save`);\n if (!userEvents.length) return;\n\n // set read date\n userEvents.forEach(userEvent => userEvent.readDate = moment());\n\n // split local/remote entities\n const localEntities = userEvents.filter(userEvent => !userEvent.id || userEvent.id < 0);\n const remoteEntities = userEvents.filter(userEvent => userEvent.id > 0);\n\n // save local entities\n if (localEntities.length) {\n if (this._debug) console.debug(`${this._logPrefix}Save local user event`);\n // TODO !!!!!!!!!!!!!\n }\n // mark remote entities as read\n if (remoteEntities.length) {\n if (!this.mutations?.markAsRead) {\n console.warn(`${this._logPrefix}Mutation query 'markAsRead' not provided, skip.`);\n return;\n }\n\n // Collect ids\n const ids = remoteEntities.map(value => value.id);\n const now = Date.now();\n if (this._debug) console.debug(`${this._logPrefix}Mark user events as read...`, ids);\n\n await this.graphql.mutate<{ data: any }>({\n mutation: this.mutations.markAsRead,\n variables: {\n ids\n },\n error: { code: SocialErrorCodes.SAVE_USER_EVENT_ERROR, message: 'SOCIAL.ERROR.SAVE_USER_EVENT_ERROR' },\n });\n\n if (this._debug) console.debug(`${this._logPrefix}User events marked as read in ${Date.now() - now}ms`, ids);\n }\n }\n\n protected defaultFilter(): F {\n // By default\n return <F>{\n recipients: [this.defaultRecipient()]\n };\n }\n\n protected defaultRecipient(): any {\n return this.accountService.person.pubkey;\n }\n\n protected fillDefaultProperties(entity: E) {\n }\n\n protected unreadEvents(events: E[]): number {\n // default calculation on unread events from a list\n if (isEmptyArray(events)) return undefined;\n const lastReadDate = events\n .filter(event => isNotNil(event.readDate))\n .reduce((lastDate, event) => DateUtils.max(lastDate, event.readDate), undefined as Moment);\n return events\n .filter(event => event.creationDate.isSameOrAfter(lastReadDate)).length;\n }\n\n protected copyIdAndUpdateDate(source: E, target: E) {\n EntityUtils.copyIdAndUpdateDate(source, target);\n }\n\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnDestroy, OnInit, Optional, Output, QueryList, ViewChild, ViewChildren} from '@angular/core';\nimport {IUserEvent, IUserEventFilter, IUserEventAction} from '../user-event.model';\nimport {BehaviorSubject, Subscription} from 'rxjs';\nimport {IonContent, IonItem, PopoverController} from '@ionic/angular';\nimport {IUserEventService, APP_USER_EVENT_SERVICE} from '../user-event.service';\nimport {LocalSettingsService} from '../../../core/services/local-settings.service';\nimport {FetchMoreFn, LoadResult} from '../../../shared/services/entity-service.class';\nimport {removeDuplicatesFromArray} from '../../../shared/functions';\nimport {fromScrollEndEvent} from '../../../shared/events';\nimport {waitFor} from '../../../shared/observables';\nimport {SortDirection} from '@angular/material/sort';\nimport {debounceTime, distinctUntilChanged, filter, switchMap} from 'rxjs/operators';\n\nexport interface UserEventNotificationListOptions<\n E extends IUserEvent<any> = IUserEvent<any>,\n F extends IUserEventFilter<any> = IUserEventFilter<any>\n > {\n debug?: boolean;\n titleI18n?: string;\n readEvent?: EventEmitter<E>;\n readEvents?: EventEmitter<E[]>;\n filter?: Partial<F>;\n}\n\n@Component({\n selector: 'app-user-event-notification-list',\n templateUrl: './user-event-notification.list.html',\n styleUrls: ['./user-event-notification.list.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UserEventNotificationList<\n E extends IUserEvent<any> = IUserEvent<any>,\n F extends IUserEventFilter<any> = IUserEventFilter<any>\n >\n implements OnInit, OnDestroy, UserEventNotificationListOptions<E, F> {\n\n protected _subscriptions = new Subscription();\n protected _fetchMoreFn: FetchMoreFn<LoadResult<E>>;\n protected _fetchMoreSubscription: Subscription;\n protected _$pageSize = new BehaviorSubject<number>(20);\n\n fetchingMore = false;\n $items = new BehaviorSubject<E[]>(undefined);\n $itemCount = new BehaviorSubject<number>(undefined);\n\n @Input() debug = false;\n @Input() mobile: boolean;\n @Input() titleI18n: string;\n @Input() sortBy = 'creationDate';\n @Input() sortDirection: SortDirection = 'desc';\n @Input() filter: Partial<F>;\n @Input() enableInfiniteScroll = true;\n\n @Input() set pageSize(value: number) {\n if (value > 0 && value !== this._$pageSize.value) this._$pageSize.next(value);\n }\n\n get pageSize(): number {\n return this._$pageSize.value;\n }\n\n @Output() readEvent: EventEmitter<E>;\n @Output() readEvents: EventEmitter<E[]>;\n\n @ViewChild(IonContent) ionContent: IonContent;\n @ViewChildren(IonItem) ionItems: QueryList<IonItem>;\n\n\n get canFetchMore(): boolean {\n return this.enableInfiniteScroll && !!this._fetchMoreFn;\n }\n\n constructor(\n protected cd: ChangeDetectorRef,\n protected popoverController: PopoverController,\n @Optional() protected settings: LocalSettingsService,\n @Optional() @Inject(APP_USER_EVENT_SERVICE) public userEventService: IUserEventService<E, IUserEventFilter<any>>\n ) {\n this.mobile = this.settings?.mobile || false;\n }\n\n ngOnInit(): void {\n\n // Watch all user events\n if (this.userEventService) {\n this._subscriptions.add(\n this._$pageSize.pipe(\n distinctUntilChanged(),\n switchMap(pageSize => this.userEventService.watchAll(0, pageSize, this.sortBy, this.sortDirection, this.filter))\n )\n .subscribe(result => {\n if (this.debug) console.debug(`[user-event-notification-list] Receiving ${result.total} user events`, result.data);\n this.$items.next(result.data);\n this.$itemCount.next(result.total || result.data?.length || 0);\n this._fetchMoreFn = result.fetchMore;\n this.fetchingMore = false; // Allow to refetch more\n this.markForCheck();\n })\n );\n\n // Listen changes\n this._subscriptions.add(\n this.userEventService.listenAllChanges(this.filter)\n .subscribe(data => {\n if (this.debug) console.debug(`[user-event-notification-list] Receiving ${data.length} new user events (by WS)`, data);\n })\n );\n\n if (this.enableInfiniteScroll) this.initInfiniteScroll();\n }\n }\n\n ngOnDestroy() {\n this._subscriptions.unsubscribe();\n this.$items.complete();\n this.$itemCount.complete();\n }\n\n click(event: UIEvent, userEvent: E) {\n if (!userEvent) return // Skip\n\n // MarkAsRead\n this.markAsRead(event, userEvent);\n\n // Get the default action (if any)\n const defaultAction = (userEvent?.actions || []).find(a => a.default);\n\n if (defaultAction) {\n this.executeAction(event, defaultAction, userEvent);\n }\n }\n\n isDefaultAction(action: IUserEventAction): boolean {\n return action && action.default || false;\n }\n\n markAsRead(event: UIEvent, userEvent: E) {\n if (userEvent?.readDate) return;\n this.readEvent?.emit(userEvent);\n }\n\n markAllAsRead(event: UIEvent) {\n const unreadUserEvents = (this.$items.value || []).filter(value => !value.readDate);\n if (!unreadUserEvents.length) return;\n this.readEvents?.emit(unreadUserEvents);\n }\n\n async executeAction(\n event: UIEvent,\n action: IUserEventAction,\n userEvent: IUserEvent<any>) {\n\n if (event?.defaultPrevented) return; // Skip if prevented\n\n // Disable default action (.e.g avoid to call click() function)\n if (event) event.preventDefault();\n\n // Execute then close popover\n try {\n const res = action.executeAction(userEvent);\n this.dismiss();\n if (res instanceof Promise) await res;\n }\n catch(err) {\n console.error(err);\n }\n }\n\n dismiss() {\n this.popoverController.dismiss();\n // Reset counter (need if event has been received while popover if open)\n this.userEventService.resetCount();\n }\n\n async fetchMore(event?: CustomEvent & { target?: EventTarget & { complete?: () => void }}) {\n if (!this._fetchMoreFn || this.fetchingMore) return;\n\n console.debug('[user-event-notification-list] Fetching more notifications...', event);\n this.fetchingMore = true;\n const fetchMoreFn = this._fetchMoreFn;\n\n try {\n const result = await fetchMoreFn();\n let data = [\n ...(this.$items.value || []),\n ...result.data\n ];\n\n // Remove duplication (e.g. when new user event was added by subscription)\n data = removeDuplicatesFromArray(data, 'id');\n\n // fetch more changes (e.g. if watchAll observable as been refreshed)\n if (fetchMoreFn !== this._fetchMoreFn) return; // Skip\n\n this.$items.next(data);\n this.$itemCount.next(result.total || result.data?.length || 0);\n this._fetchMoreFn = result.fetchMore;\n\n // Update the page size, to keep same scroll height, after the next refresh\n this.pageSize = Math.max(this.pageSize, data.length);\n }\n catch(err) {\n console.error(err);\n this._fetchMoreFn = undefined; // Forget the function\n }\n finally {\n this.markForCheck();\n this.fetchingMore = false;\n }\n }\n\n trackByFn(index: number, item: E) {\n return item.id;\n }\n\n protected async initInfiniteScroll(threshold?: string) {\n console.debug('[user-event-notification-list] Init infinite loop');\n if (this._fetchMoreSubscription) this._fetchMoreSubscription.unsubscribe();\n\n threshold = threshold || (this.mobile ? '15%' : '2%');\n await waitFor(() => !!this.ionContent, {dueTime: 250, timeout: 1000});\n const panel = await this.ionContent.getScrollElement();\n\n // Trigger fetch more, end end scroll reached\n this._fetchMoreSubscription = this.$items.pipe(\n debounceTime(250),\n filter(() => this.canFetchMore),\n switchMap(() => fromScrollEndEvent(panel, threshold, 250 /*force to check when no scrollbar - e.g. in large screen*/))\n )\n .subscribe(() => this.fetchMore());\n\n this._subscriptions.add(this._fetchMoreSubscription);\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnDestroy, OnInit, Optional} from '@angular/core';\nimport {Observable, of} from 'rxjs';\nimport { PopoverController } from '@ionic/angular';\nimport { IUserEventService, APP_USER_EVENT_SERVICE } from '../user-event.service';\nimport { UserEventNotificationList, UserEventNotificationListOptions } from './user-event-notification.list';\nimport { IUserEvent, IUserEventFilter } from '../user-event.model';\nimport { AccountService } from '../../../core/services/account.service';\nimport {map, tap} from 'rxjs/operators';\nimport {isNil, toBoolean} from '../../../shared/functions';\n\n@Component({\n selector: 'app-user-event-notification-icon',\n templateUrl: './user-event-notification.icon.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UserEventNotificationIcon implements OnInit, OnDestroy {\n\n @Input() debug = false;\n @Input() titleI18n = 'SOCIAL.USER_EVENT.NOTIFICATION.TITLE';\n @Input() disabled = false;\n @Input() filter: any = null;\n @Input() autoHide: boolean;\n\n visible: boolean;\n\n get countChanges(): Observable<number> {\n if (!this.userEventService) return of();\n return this.userEventService\n .countSubject\n .pipe(\n tap(value => {\n const visible = !this.autoHide || value > 0;\n if (this.visible !== visible) {\n this.visible = visible;\n this.cd.markForCheck();\n }\n }),\n map(value => value === 0 ? undefined : value)\n );\n }\n\n private _logPrefix = '[user-event-notification] ';\n private _readEvent = new EventEmitter<IUserEvent<any>>();\n private _readEvents = new EventEmitter<IUserEvent<any>[]>();\n\n constructor(\n @Optional() @Inject(APP_USER_EVENT_SERVICE) public userEventService: IUserEventService<IUserEvent<any>, IUserEventFilter<any>>,\n protected accountService: AccountService,\n protected popoverController: PopoverController,\n private cd: ChangeDetectorRef\n ) { }\n\n async ngOnInit() {\n\n if (isNil(this.userEventService)) {\n console.warn(`${this._logPrefix}No service injected`);\n this.disabled = true;\n this.visible = false;\n return;\n }\n\n this.visible = toBoolean(this.visible, !this.autoHide);\n\n // Wait service\n await this.userEventService.ready();\n\n // Subscribe to read event\n this._readEvent.subscribe(item => {\n // default: mark event as read\n this.userEventService.markAllAsRead([item]);\n });\n this._readEvents.subscribe(items => {\n this.userEventService.markAllAsRead(items);\n })\n }\n\n async showList(event: UIEvent) {\n // Reset count\n this.userEventService.resetCount();\n\n const popover = await this.popoverController.create({\n component: UserEventNotificationList,\n componentProps: <UserEventNotificationListOptions>{\n debug: this.debug,\n titleI18n: this.titleI18n,\n readEvent: this._readEvent,\n readEvents: this._readEvents,\n filter: this.filter\n },\n backdropDismiss: true,\n keyboardClose: true,\n event,\n translucent: true,\n cssClass: 'popover-large popover-notifications'\n });\n await popover.present();\n }\n\n ngOnDestroy(): void {\n if (this.debug) {\n console.debug(`${this._logPrefix}Destroying`);\n }\n }\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {SharedModule} from '../../shared/shared.module';\nimport {UserEventNotificationIcon} from './notification/user-event-notification.icon';\nimport {UserEventNotificationList} from './notification/user-event-notification.list';\nimport {AppIconModule} from '../../core/icon/icon.module';\nimport {NgxJdenticonModule} from 'ngx-jdenticon';\n\n@NgModule({\n imports: [\n CommonModule,\n SharedModule,\n AppIconModule,\n NgxJdenticonModule\n ],\n declarations: [\n UserEventNotificationIcon,\n UserEventNotificationList\n ],\n exports: [\n UserEventNotificationIcon\n ]\n})\nexport class UserEventModule {\n}\n","import {EntityClass} from '../../core/services/model/entity.decorators';\nimport {Entity, EntityAsObjectOptions} from '../../core/services/model/entity.model';\nimport {StoreObject} from '@apollo/client/core';\nimport {EntityFilter} from '../../core/services/model/filter.model';\nimport {FilterFn} from '../../shared/services/entity-service.class';\nimport {Person} from '../../core/services/model/person.model';\nimport {IReferentialRef, IStatus} from '../../core/services/model/referential.model';\n\nexport const MessageTypes = {\n INBOX_MESSAGE: 'INBOX_MESSAGE',\n EMAIL: 'EMAIL',\n FEED: 'FEED',\n}\nexport const MessageTypeList = Object.freeze([\n {\n id: MessageTypes.INBOX_MESSAGE,\n icon: 'notifications',\n label: 'SOCIAL.MESSAGE.TYPE_ENUM.INBOX_MESSAGE'\n },\n {\n id: MessageTypes.EMAIL,\n icon: 'mail',\n label: 'SOCIAL.MESSAGE.TYPE_ENUM.EMAIL'\n },\n {\n id: MessageTypes.FEED,\n icon: 'paper',\n label: 'SOCIAL.MESSAGE.TYPE_ENUM.FEED'\n }\n]);\n\n// @dynamic\n@EntityClass({typename: 'MessageVO'})\nexport class Message extends Entity<Message>{\n\n static fromObject: (source: any, opts?: any) => Message;\n\n type: string;\n issuer: Person;\n recipients: Person[];\n subject: string;\n body: string;\n\n constructor() {\n super();\n }\n\n fromObject(source: any, opts?: any) {\n super.fromObject(source, opts);\n this.type = source.type;\n this.issuer = source.issuer && Person.fromObject(source.issuer);\n this.recipients = source.recipients && source.recipients.map(Person.fromObject);\n this.subject = source.subject;\n this.body = source.body;\n }\n\n asObject(opts?: EntityAsObjectOptions): StoreObject {\n const target = super.asObject(opts);\n target.recipients = this.recipients && this.recipients.map(p => p.asObject(opts));\n return target;\n }\n}\n\n\n// @dynamic\n@EntityClass({typename: 'MessageFilterVO'})\nexport class MessageFilter extends EntityFilter<MessageFilter, Message> {\n\n static fromObject: (source: any, opts?: any) => MessageFilter;\n\n\n fromObject(source: any, opts?: any) {\n super.fromObject(source, opts);\n }\n\n protected buildFilter(): FilterFn<Message>[] {\n const filterFns = super.buildFilter();\n\n return filterFns;\n }\n}\n","import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewChild} from '@angular/core';\n\nimport {ModalController} from '@ionic/angular';\nimport {Message, MessageTypes} from './message.model';\nimport {Person} from '../../core/services/model/person.model';\nimport {SuggestFn} from '../../shared/services/entity-service.class';\nimport {PersonFilter} from '../../admin/services/filter/person.filter';\nimport {LocalSettingsService} from '../../core/services/local-settings.service';\nimport {MessageForm} from './message.form';\nimport {firstNotNilPromise} from '../../shared/observables';\nimport {AppFormUtils} from '../../core/form/form.utils';\nimport {toBoolean} from '../../shared/functions';\nimport {AccountService} from '../../core/services/account.service';\n\nexport interface MessageModalOptions {\n suggestFn: SuggestFn<Person, PersonFilter>;\n data?: Message;\n canSelectType?: boolean;\n}\n\n@Component({\n selector: 'app-message-modal',\n templateUrl: './message.modal.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MessageModal implements OnInit, AfterViewInit, MessageModalOptions {\n\n readonly mobile: boolean;\n\n @Input() suggestFn: SuggestFn<Person, PersonFilter>;\n\n @Input() data: Message;\n\n @Input() canSelectType: boolean;\n\n @ViewChild('form', { static: true }) private form: MessageForm;\n\n constructor(\n protected settings: LocalSettingsService,\n protected viewCtrl: ModalController,\n protected accountService: AccountService,\n protected cd: ChangeDetectorRef\n ) {\n this.mobile = this.settings.mobile;\n }\n\n ngOnInit() {\n this.canSelectType = toBoolean(this.canSelectType, this.accountService.isAdmin());\n }\n\n ngAfterViewInit() {\n this.form.markAsReady({emitEvent: false});\n if (this.data) {\n this.data.type = this.data.type || MessageTypes.INBOX_MESSAGE;\n this.form.setValue(this.data);\n }\n this.form.markAsLoaded();\n this.form.enable();\n }\n\n cancel(event?: UIEvent) {\n this.viewCtrl.dismiss();\n }\n\n async doSubmit(event?: UIEvent): Promise<any> {\n if (this.form.disabled) return;\n if (!this.form.valid) {\n\n await AppFormUtils.waitWhilePending(this.form);\n\n if (this.form.invalid) {\n AppFormUtils.logFormErrors(this.form.form, '[message-modal] ');\n this.form.markAllAsTouched();\n return;\n }\n }\n this.markAsLoading();\n\n try {\n const data = this.form.value;\n\n // Disable the form\n this.form.disable();\n\n const entity = Message.fromObject(data)\n\n return this.viewCtrl.dismiss(entity);\n }\n catch (err) {\n this.form.error = err && err.message || err;\n this.markAsLoaded();\n\n // Enable the form\n this.form.enable();\n\n // Reset form error on next changes\n firstNotNilPromise(this.form.form.valueChanges).then(() => {\n this.form.error = null;\n this.markForCheck();\n });\n\n return;\n }\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n protected markAsLoading(opts?: {emitEvent?: boolean}) {\n this.form.markAsLoading(opts);\n }\n\n protected markAsLoaded(opts?: {emitEvent?: boolean}) {\n this.form.markAsLoaded(opts);\n }\n}\n\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Injector, Input, OnInit} from '@angular/core';\nimport {FormBuilder, Validators} from '@angular/forms';\nimport {Message, MessageTypeList, MessageTypes} from './message.model';\nimport {AppForm} from '../../core/form/form.class';\nimport {StatusIds} from '../../core/services/model/model.enum';\nimport {Person, PersonUtils} from '../../core/services/model/person.model';\nimport {SuggestFn} from '../../shared/services/entity-service.class';\nimport {PersonFilter} from '../../admin/services/filter/person.filter';\nimport {EntityUtils} from '../../core/services/model/entity.model';\nimport {IStatus} from '../../core/services/model/referential.model';\n\n@Component({\n selector: 'app-message-form',\n templateUrl: './message.form.html',\n styleUrls: ['./message.form.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MessageForm extends AppForm<Message> implements OnInit {\n\n readonly mobile: boolean;\n\n @Input() suggestFn: SuggestFn<Person, PersonFilter>;\n @Input() subjectMinLength = 5;\n @Input() subjectMaxLength = 255;\n @Input() bodyMaxLength = 2000;\n @Input() bodyAutoHeight = true;\n @Input() canSelectType: boolean = false;\n\n types = MessageTypeList;\n\n constructor(\n injector: Injector,\n private formBuilder: FormBuilder,\n private readonly cd: ChangeDetectorRef\n ) {\n super(injector);\n this.mobile = this.settings.mobile;\n }\n\n\n ngOnInit() {\n\n this.setForm(\n this.formBuilder.group({\n type: [MessageTypes.INBOX_MESSAGE, Validators.required],\n recipients: [null, Validators.required],\n subject: [null, this.subjectMaxLength\n ? Validators.compose([Validators.required, Validators.minLength(this.subjectMinLength), Validators.maxLength(this.subjectMaxLength)])\n : Validators.required],\n body: [null, this.bodyMaxLength\n ? Validators.compose([Validators.maxLength(this.bodyMaxLength)])\n : Validators.required]\n })\n );\n\n const personAttributes = this.settings.getFieldDisplayAttributes('person', ['lastName', 'firstName', 'department.name'])\n this.registerAutocompleteField('recipients', {\n showAllOnFocus: false,\n suggestFn: this.suggestFn,\n filter: {\n statusIds: [StatusIds.TEMPORARY, StatusIds.ENABLE]\n },\n attributes: personAttributes,\n displayWith: PersonUtils.personToString,\n multiple: true,\n mobile: this.mobile\n });\n }\n\n\n isSamePerson(o1: Person, o2: Person): boolean {\n return EntityUtils.equals(o1, o2, 'id');\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { CoreModule } from '../../core/core.module';\nimport { SharedModule } from '../../shared/shared.module';\nimport { MessageModal } from './message.modal';\nimport { MessageForm } from './message.form';\n\n@NgModule({\n imports: [\n CommonModule,\n CoreModule,\n SharedModule\n ],\n declarations: [\n MessageModal,\n MessageForm\n ],\n exports: [\n MessageModal\n ]\n})\nexport class MessageModule {}\n","import { Moment } from 'moment';\nimport { EntityClass } from '../../core/services/model/entity.decorators';\nimport { Entity } from '../../core/services/model/entity.model';\n\nexport type JobStatus = 'PENDING' | 'RUNNING' | 'SUCCESS' | 'ERROR' | 'FAILED' | 'WARNING' | 'CANCELLED';\n\nexport interface IJob {\n id: number;\n name: string;\n type: string;\n status: JobStatus;\n startDate: Moment;\n endDate: Moment;\n configuration: string;\n report: string;\n}\n\n// todo use entity\nexport class Job implements IJob {\n id: number;\n name: string;\n type: string;\n status: JobStatus;\n startDate: Moment;\n endDate: Moment;\n configuration: string;\n report: string;\n}\n\n// @dynamic\n@EntityClass({typename: 'JobProgressionVO'})\nexport class JobProgression extends Entity<JobProgression> {\n\n static fromObject: (source: any, opts?: any) => JobProgression;\n\n id: number;\n name: string;\n message: string;\n current: number;\n total: number;\n\n constructor(id?: number) {\n super(JobProgression.TYPENAME);\n this.id = id;\n }\n\n fromObject(source: any) {\n super.fromObject(source);\n this.name = source.name;\n this.message = source.message;\n this.current = source.current;\n this.total = source.total;\n }\n}\n","import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';\nimport { JobProgression } from './job.model';\nimport { BaseGraphqlService } from '../../core/services/base-graphql-service.class';\nimport { GraphqlService } from '../../core/graphql/graphql.service';\nimport { Environment, ENVIRONMENT } from '../../../environments/environment.class';\nimport {Observable, of} from 'rxjs';\nimport {FetchPolicy, gql, WatchQueryFetchPolicy} from '@apollo/client/core';\nimport { isNil, toNumber } from '../../shared/functions';\nimport { map } from 'rxjs/operators';\nimport { SocialErrorCodes } from '../social.errors';\nimport {BaseEntityGraphqlQueries} from '../../core/services/base-entity-service.class';\n\nexport const APP_JOB_PROGRESSION_SERVICE = new InjectionToken<JobProgressionService>('JobProgressionService');\n\nconst QUERIES = {\n listenChanges: gql`subscription UpdateJobProgression($id: Int!, $interval: Int){\n data: updateJobProgression(id: $id, interval: $interval) {\n id\n name\n message\n current\n total\n }\n }`\n}\n\nexport interface IJobProgressionService {\n watchAll(): Observable<JobProgression[]>;\n addJob(id: number, job?: JobProgression);\n removeJob(id: number);\n listenChanges(id: number, options?: { interval?: number; fetchPolicy?: FetchPolicy }): Observable<JobProgression>;\n}\n\n@Injectable()\nexport class JobProgressionService\n extends BaseGraphqlService<JobProgression>\n implements IJobProgressionService {\n\n constructor(\n protected graphql: GraphqlService,\n @Optional() @Inject(ENVIRONMENT) protected environment: Environment\n ) {\n super(graphql, environment);\n this._logPrefix = '[job-progression-service] ';\n // For DEV only\n this._debug = !environment?.production;\n }\n\n watchAll(options?: {\n fetchPolicy?: WatchQueryFetchPolicy\n }): Observable<JobProgression[]> {\n return of([]); // TODO\n }\n\n addJob(id: number, job?: JobProgression) {\n throw new Error('no implemented');\n }\n\n removeJob(id: number) {\n throw new Error('no implemented');\n }\n\n listenChanges(id: number, options?: {\n interval?: number;\n fetchPolicy?: FetchPolicy\n }): Observable<JobProgression> {\n\n if (isNil(id)) throw new Error(`${this._logPrefix}Missing argument 'id'`);\n if (this._debug) console.debug(`${this._logPrefix}[WS] Listening changes for job progression {${id}}...`);\n\n return this.graphql.subscribe<{ data: any }>({\n query: QUERIES.listenChanges,\n fetchPolicy: options?.fetchPolicy,\n variables: { id, interval: toNumber(options?.interval, 10)},\n error: {code: SocialErrorCodes.SUBSCRIBE_JOB_PROGRESSION_ERROR, message: 'SOCIAL.ERROR.SUBSCRIBE_JOB_PROGRESSION_ERROR'}\n }).pipe(\n map(({data}) => {\n const progression = data && JobProgression.fromObject(data);\n if (progression && this._debug) console.debug(`${this._logPrefix}Job progression ${id} updated on server`, progression);\n return progression;\n })\n );\n\n }\n}\n","import { Component, Input, OnInit } from '@angular/core';\nimport { JobProgression } from '../job.model';\n\nexport interface JobProgressionListOptions {\n titleI18n?: string;\n jobProgressions?: JobProgression[];\n}\n\n@Component({\n selector: 'app-job-progression-list',\n templateUrl: './job-progression.list.html',\n styleUrls: ['./job-progression.list.scss'],\n})\nexport class JobProgressionList implements OnInit, JobProgressionListOptions {\n\n @Input() titleI18n: string;\n @Input() jobProgressions: JobProgression[];\n\n constructor() {\n }\n\n ngOnInit(): void {\n }\n\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnDestroy, OnInit, Optional, Output } from '@angular/core';\nimport { ThemePalette } from '@angular/material/core';\nimport { ProgressSpinnerMode } from '@angular/material/progress-spinner';\nimport { IJobProgressionService, APP_JOB_PROGRESSION_SERVICE } from '../job.service';\nimport { JobProgression } from '../job.model';\nimport { Subscription } from 'rxjs';\nimport { ObjectMap } from '../../../shared/types';\nimport { arraySize, isNil, toBoolean, toNumber } from '../../../shared/functions';\nimport { filter, map } from 'rxjs/operators';\nimport { PopoverController } from '@ionic/angular';\nimport { JobProgressionList, JobProgressionListOptions } from './job-progression.list';\nimport {UserEventNotificationIcon} from '../../user-event/notification/user-event-notification.icon';\n\nexport interface JobProgressionOptions {\n autoHide: boolean;\n autoHideDelay: number;\n autoRemove: boolean;\n autoRemoveDelay: number;\n}\n\n@Component({\n selector: 'app-job-progression-icon',\n templateUrl: './job-progression.icon.html',\n styleUrls: ['./job-progression.icon.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class JobProgressionIcon implements OnInit, OnDestroy {\n\n @Input() debug = false;\n @Input() titleI18n = 'SOCIAL.JOB.PROGRESSION.TITLE';\n @Input() options: JobProgressionOptions;\n @Input() autoHide: boolean;\n @Output() jobFinished = new EventEmitter<number>();\n\n visible: boolean;\n disabled = true;\n color: ThemePalette = 'accent';\n mode: ProgressSpinnerMode = 'determinate';\n value = 0;\n jobProgressions: JobProgression[] = [];\n\n protected autoHideDelay: number;\n protected autoRemove: boolean;\n protected autoRemoveDelay: number;\n\n private _listPopover: HTMLIonPopoverElement;\n private _subscriptions = new Subscription();\n private _subscriptionsById: ObjectMap<Subscription> = {};\n private _logPrefix = '[job-progression] ';\n\n constructor(\n @Optional() @Inject(APP_JOB_PROGRESSION_SERVICE) protected jobProgressionService: IJobProgressionService,\n protected popoverController: PopoverController,\n protected cd: ChangeDetectorRef\n ) {\n\n }\n\n ngOnInit() {\n if (isNil(this.jobProgressionService)) {\n console.warn(`${this._logPrefix}No service injected`);\n }\n // parse options\n this.autoHide = toBoolean(this.autoHide, this.options?.autoHide || false);\n this.visible = !this.autoHide;\n this.autoHideDelay = toNumber(this.options?.autoHideDelay, 1000);\n this.autoRemove = toBoolean(this.options?.autoRemove, true);\n this.autoRemoveDelay = toNumber(this.options?.autoRemoveDelay, 1000);\n\n this._subscriptions.add(\n this.jobProgressionService.watchAll()\n .subscribe(items => {\n (items || []).forEach(item => this.addJob(item.id, item));\n })\n );\n }\n\n addJob(id: number, job?: JobProgression) {\n if (isNil(this.jobProgressionService)) {\n console.warn(`${this._logPrefix}No service injected. Can't add a job`);\n return;\n }\n\n if (!!this.getProgression(id)) {\n console.warn(`${this._logPrefix}Job (id=${id}) already present`);\n return;\n }\n if (this.debug) {\n console.debug(`${this._logPrefix}Add job id=${id}`);\n }\n // Adding empty job progression\n let progression = this.getProgression(id);\n if (!progression) {\n progression = job || new JobProgression(id);\n this.jobProgressions.push(progression);\n }\n\n this.disabled = false;\n\n const sub = this.jobProgressionService.listenChanges(id)\n .pipe(\n filter(progression => {\n if (id !== progression.id) {\n console.error(`${this._logPrefix}Job progression (id=${progression.id}) doesn't match expected job (id=${id})`);\n return false;\n }\n return true;\n }),\n map(progression => {\n // Ensure visible\n this.visible = true;\n // Get current progression object\n const currentProgression = this.getProgression(id);\n if (!currentProgression) {\n // add it if absent\n this.jobProgressions.push(progression);\n if (this.debug) {\n console.debug(`${this._logPrefix}Progression added id=${id}`, progression);\n }\n } else {\n // update current\n Object.assign(currentProgression, progression);\n if (this.debug) {\n console.debug(`${this._logPrefix}Progression updated id=${id}`, progression);\n }\n }\n return progression;\n })\n )\n .subscribe(progression => {\n // update value\n this.updateValue();\n\n // job finished\n if (progression.total > 0 && progression.current == progression.total) {\n if (this.debug) {\n console.debug(`${this._logPrefix}Finished job id=${progression.id}`);\n }\n // emit event\n this.jobFinished.emit(progression.id);\n if (this.autoRemove) {\n setTimeout(() => {\n this.removeJob(progression.id);\n // If last job\n if (this.autoHide && !this.jobProgressions?.length) {\n setTimeout(async () => {\n this._listPopover?.dismiss();\n this.visible = false;\n this.markForCheck();\n }, this.autoHideDelay);\n }\n }, this.autoRemoveDelay);\n }\n }\n });\n\n this._subscriptionsById[id] = sub;\n this._subscriptions.add(sub);\n }\n\n removeJob(id: number) {\n if (this.debug) {\n console.debug(`${this._logPrefix}Remove job id=${id}`);\n }\n const sub = this._subscriptionsById[id];\n if (sub) {\n this._subscriptions.remove(sub);\n sub.unsubscribe();\n }\n const progression = this.getProgression(id);\n if (progression) {\n this.jobProgressions.splice(this.jobProgressions.indexOf(progression), 1);\n }\n this.updateValue();\n }\n\n getProgression(id: number): JobProgression | undefined {\n return this.jobProgressions.find(progression => progression.id === id);\n }\n\n updateValue() {\n if (this.debug) {\n console.debug(`${this._logPrefix}Updating value`);\n }\n let value = 0;\n const nbProgression = arraySize(this.jobProgressions);\n let allIndeterminate = nbProgression > 0;\n\n this.jobProgressions.forEach(progression => {\n const indeterminate = progression.total === 0;\n allIndeterminate = allIndeterminate && indeterminate;\n if (!indeterminate) {\n value = value + progression.current * 100 / progression.total;\n }\n });\n\n this.value = nbProgression > 0 ? value / nbProgression : 0;\n this.mode = allIndeterminate ? 'indeterminate' : 'determinate';\n if (this.debug) {\n console.debug(`${this._logPrefix}Setting value=${this.value}, mode=${this.mode}`);\n }\n\n this.markForCheck();\n }\n\n async showList(event: UIEvent) {\n this._listPopover = await this.popoverController.create({\n component: JobProgressionList,\n componentProps: <JobProgressionListOptions>{\n titleI18n: this.titleI18n,\n jobProgressions: this.jobProgressions\n },\n backdropDismiss: true,\n keyboardClose: true,\n event,\n translucent: true,\n cssClass: 'popover-large'\n });\n await this._listPopover.present();\n await this._listPopover.onDidDismiss();\n this._listPopover = undefined;\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n ngOnDestroy(): void {\n if (this.debug) {\n console.debug(`${this._logPrefix}Destroying`);\n }\n this._subscriptions.unsubscribe();\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { SharedModule } from '../../shared/shared.module';\nimport { JobProgressionIcon } from './progression/job-progression.icon';\nimport { JobProgressionList } from './progression/job-progression.list';\n\n@NgModule({\n imports: [\n CommonModule,\n SharedModule,\n TranslateModule.forChild(),\n ],\n declarations: [\n JobProgressionIcon,\n JobProgressionList\n ],\n exports: [\n JobProgressionIcon\n ]\n})\nexport class JobModule {}\n","import {InjectionToken, NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {CoreModule} from '../core/core.module';\nimport {SharedModule} from '../shared/shared.module';\nimport {UserEventModule} from './user-event/user-event.module';\nimport {MessageModule} from './message/message.module';\nimport {JobModule} from './job/job.module';\nimport {JobProgressionOptions} from './job/progression/job-progression.icon';\n\nexport interface SocialModuleOptions {\n showUserEventNotification: boolean;\n // todo : userEventNotificationOptions\n showJobProgression: boolean;\n jobProgressionOptions: JobProgressionOptions;\n}\n\nexport const SocialModuleOptionsToken = new InjectionToken<SocialModuleOptions>(\"SocialModuleOptions\");\n\n@NgModule({\n imports: [\n CommonModule,\n CoreModule,\n SharedModule,\n\n UserEventModule,\n JobModule,\n MessageModule\n ],\n exports: [\n UserEventModule,\n JobModule,\n MessageModule\n ]\n})\nexport class SocialModule {\n}\n","import {Inject, Injectable, Optional} from '@angular/core';\nimport {gql} from '@apollo/client/core';\nimport {SocialErrorCodes} from '../social.errors';\nimport {GraphqlService} from '../../core/graphql/graphql.service';\nimport {EntityServiceLoadOptions} from '../../shared/services/entity-service.class';\nimport {ToastController} from '@ionic/angular';\nimport {TranslateService} from '@ngx-translate/core';\nimport {BaseGraphqlService} from '../../core/services/base-graphql-service.class';\nimport {Environment, ENVIRONMENT} from '../../../environments/environment.class';\nimport {Message, MessageFilter} from './message.model';\nimport {MINIFY_ENTITY_FOR_POD} from '../../core/services/model/referential.model';\nimport {ShowToastOptions, Toasts} from '../../shared/toast/toasts';\nimport {isNotNilOrBlank} from '../../shared/functions';\n\n\nconst Mutations = {\n send: gql`mutation SendMessage($data: MessageVOInput){\n done: sendMessage(message: $data)\n }`\n};\n\n@Injectable({providedIn: 'root'})\nexport class MessageService\n extends BaseGraphqlService<Message, MessageFilter> {\n\n constructor(\n protected graphql: GraphqlService,\n protected translate: TranslateService,\n protected toastController: ToastController,\n @Optional() @Inject(ENVIRONMENT) protected environment: Environment\n ) {\n super(graphql, environment);\n\n // For DEV only\n this._debug = !environment.production;\n }\n\n /**\n * Send a message to recipient(s)\n *\n * @param entity\n * @param opts\n */\n async send(entity: Message, opts?: {showToast?: boolean}): Promise<boolean> {\n\n // Transform into json\n const data = entity.asObject(MINIFY_ENTITY_FOR_POD);\n\n const now = Date.now();\n if (this._debug) console.debug(`[message-service] Send message...`, data);\n\n try {\n const {done} = await this.graphql.mutate<{done: boolean}>({\n mutation: Mutations.send,\n variables: { data },\n error: { code: SocialErrorCodes.SEND_MESSAGE_ERROR, message: 'SOCIAL.ERROR.SEND_MESSAGE_ERROR' }\n });\n\n if (this._debug) console.debug(`[message-service] Send message [OK] in ${Date.now() - now}ms`);\n\n if (done && (!opts || opts.showToast !== false)) {\n await this.showToast({type: 'info', message: 'SOCIAL.INFO.MESSAGE_SENT'});\n }\n return done;\n }\n catch (err) {\n const error = err && err.message || err;\n console.error(error);\n\n // Show error\n if (!opts || opts.showToast !== false) {\n let message = error || 'SOCIAL.ERROR.SEND_MESSAGE_ERROR';\n await this.showToast({type: 'error', message});\n }\n return false;\n }\n }\n\n /* -- protected methods -- */\n\n protected async showToast(opts: ShowToastOptions) {\n return Toasts.show(this.toastController, this.translate, {\n type: 'info',\n message: 'SOCIAL.INFO.MESSAGE_SENT',\n ...opts\n });\n }\n}\n","import { EntityClass } from '../../../core/services/model/entity.decorators';\nimport { EntityFilter } from '../../../core/services/model/filter.model';\nimport { Person } from '../../../core/services/model/person.model';\nimport { FilterFn } from '../../../shared/services/entity-service.class';\nimport { EntityAsObjectOptions, EntityUtils } from '../../../core/services/model/entity.model';\nimport { StoreObject } from '@apollo/client/core';\nimport { isNil, isNotEmptyArray, isNotNil } from '../../../shared/functions';\n\n// @dynamic\n@EntityClass({ typename: 'PersonFilterVO' })\nexport class PersonFilter extends EntityFilter<PersonFilter, Person> {\n\n static fromObject: (source, opts?: any) => PersonFilter;\n\n static searchFilter(source: any): FilterFn<Person> {\n return source && PersonFilter.fromObject(source).asFilterFn();\n }\n\n email: string;\n pubkey: string;\n searchText: string;\n statusIds: number[];\n userProfiles: string[];\n excludedIds: number[];\n searchAttribute: string;\n searchAttributes: string[];\n\n constructor() {\n super(PersonFilter.TYPENAME);\n }\n\n fromObject(source: any, opts?: EntityAsObjectOptions) {\n super.fromObject(source, opts);\n this.email = source.email;\n this.pubkey = source.pubkey;\n this.searchText = source.searchText;\n this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);\n this.userProfiles = source.userProfiles;\n this.excludedIds = source.excludedIds;\n this.searchAttribute = source.searchAttribute;\n this.searchAttributes = source.searchAttributes;\n }\n\n asObject(opts?: EntityAsObjectOptions): StoreObject {\n const target = super.asObject(opts);\n target.email = this.email;\n target.pubkey = this.pubkey;\n target.searchText = this.searchText;\n target.statusIds = this.statusIds;\n target.userProfiles = this.userProfiles;\n target.excludedIds = this.excludedIds;\n target.searchAttribute = this.searchAttribute;\n target.searchAttributes = this.searchAttributes;\n return target;\n }\n\n protected buildFilter(): FilterFn<Person>[] {\n\n const filterFns = super.buildFilter();\n\n // Filter by status\n if (isNotEmptyArray(this.statusIds)) {\n filterFns.push(e => this.statusIds.includes(e.statusId));\n }\n\n // Filter excluded ids\n if (isNotEmptyArray(this.excludedIds)) {\n filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));\n }\n\n // Search text\n const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);\n if (searchTextFilter) filterFns.push(searchTextFilter);\n\n return filterFns;\n }\n}\n","import {Injectable} from '@angular/core';\nimport {FetchPolicy, gql} from '@apollo/client/core';\nimport {BehaviorSubject} from 'rxjs';\nimport {GraphqlService} from '../../core/graphql/graphql.service';\nimport {NetworkService} from '../../core/services/network.service';\nimport {EntitiesStorage} from '../../core/services/storage/entities-storage.service';\nimport {Person, UserProfileLabel} from '../../core/services/model/person.model';\nimport {StatusIds} from '../../core/services/model/model.enum';\nimport {SortDirection} from '@angular/material/sort';\nimport {JobUtils} from '../../shared/services/job.utils';\nimport {LoadResult, SuggestService} from '../../shared/services/entity-service.class';\nimport {PlatformService} from '../../core/services/platform.service';\nimport {PersonFilter} from './filter/person.filter';\nimport {EntityUtils} from '../../core/services/model/entity.model';\nimport {BaseEntityGraphqlMutations, BaseEntityService} from '../../core/services/base-entity-service.class';\nimport {environment} from '../../../environments/environment';\n\nexport const PersonFragments = {\n person: gql`fragment PersonFragment on PersonVO {\n id\n firstName\n lastName\n email\n pubkey\n avatar\n statusId\n updateDate\n creationDate\n profiles\n username\n usernameExtranet\n department {\n id\n label\n name\n logo\n __typename\n }\n __typename\n }`\n};\n\n// Load persons query\nconst PersonQueries = {\n loadAll: gql`\n query Persons($offset: Int, $size: Int, $sortBy: String, $sortDirection: String, $filter: PersonFilterVOInput){\n data: persons(filter: $filter, offset: $offset, size: $size, sortBy: $sortBy, sortDirection: $sortDirection){\n ...PersonFragment\n }\n }\n ${PersonFragments.person}`,\n\n loadAllWithTotal: gql`\n query PersonsWithTotal($offset: Int, $size: Int, $sortBy: String, $sortDirection: String, $filter: PersonFilterVOInput){\n data: persons(filter: $filter, offset: $offset, size: $size, sortBy: $sortBy, sortDirection: $sortDirection){\n ...PersonFragment\n }\n total: personsCount(filter: $filter)\n }\n ${PersonFragments.person}`\n};\n\n\nconst PersonMutations: BaseEntityGraphqlMutations = {\n saveAll: gql`\n mutation savePersons($data:[PersonVOInput]){\n data: savePersons(persons: $data){\n ...PersonFragment\n }\n }\n ${PersonFragments.person}`,\n deleteAll: gql`\n mutation deletePersons($ids:[Int]){\n deletePersons(ids: $ids)\n }`\n};\n\n@Injectable({providedIn: 'root'})\nexport class PersonService extends BaseEntityService<Person, PersonFilter>\n implements SuggestService<Person, PersonFilter> {\n\n constructor(\n protected graphql: GraphqlService,\n protected platform: PlatformService,\n protected network: NetworkService,\n protected entities: EntitiesStorage\n ) {\n super(graphql, platform, Person, PersonFilter, {\n queries: PersonQueries,\n mutations: PersonMutations,\n defaultSortBy: 'lastName',\n defaultSortDirection: 'asc'\n });\n\n // for DEV only -----\n this._debug = !environment.production;\n }\n\n async loadAll(offset: number, size: number, sortBy?: string,\n sortDirection?: SortDirection,\n filter?: Partial<PersonFilter>, opts?: {\n [key: string]: any;\n fetchPolicy?: FetchPolicy;\n debug?: boolean;\n withTotal?: boolean;\n toEntity?: boolean;\n }): Promise<LoadResult<Person>> {\n\n const offline = this.network.offline && (!opts || opts.fetchPolicy !== 'network-only');\n if (offline) {\n return this.loadAllLocally(offset, size, sortBy, sortDirection, filter, opts);\n }\n\n return super.loadAll(offset, size, sortBy, sortDirection, filter, opts);\n }\n\n async loadAllLocally(offset: number, size: number, sortBy?: string, sortDirection?: SortDirection,\n filter?: Partial<PersonFilter>,\n opts?: {\n [key: string]: any;\n fetchPolicy?: FetchPolicy;\n debug?: boolean;\n withTotal?: boolean;\n toEntity?: boolean;\n }): Promise<LoadResult<Person>> {\n\n filter = this.asFilter(filter);\n\n const variables = {\n offset: offset || 0,\n size: size || 100,\n sortBy: sortBy || this.defaultSortBy,\n sortDirection: sortDirection || this.defaultSortDirection,\n filter: filter && filter.asFilterFn()\n };\n\n const {data, total} = await this.entities.loadAll<Person>('PersonVO', variables);\n\n const entities = (!opts || opts.toEntity !== false) ?\n (data || []).map(Person.fromObject) :\n (data || []) as Person[];\n return {\n data: entities,\n total\n };\n }\n\n async suggest(value: any, filter?: PersonFilter, sortBy?: string, sortDirection?: SortDirection): Promise<LoadResult<Person>> {\n if (EntityUtils.isNotEmpty(value, 'id')) return {data: [value]};\n value = (typeof value === 'string' && value !== '*') && value || undefined;\n sortBy = sortBy || filter.searchAttribute || (filter.searchAttributes && filter.searchAttributes[0]);\n return this.loadAll(0, !value ? 30 : 10, sortBy, sortDirection,\n {\n ...filter,\n searchText: value as string,\n statusIds: filter && filter.statusIds || [StatusIds.ENABLE],\n userProfiles: filter && filter.userProfiles\n },\n { withTotal: true /* need by autocomplete */ }\n );\n }\n\n async executeImport(filter: Partial<PersonFilter>,\n opts: {\n progression?: BehaviorSubject<number>;\n maxProgression?: number;\n }): Promise<void> {\n\n const maxProgression = opts && opts.maxProgression || 100;\n filter = {\n ...filter,\n statusIds: [StatusIds.ENABLE, StatusIds.TEMPORARY],\n userProfiles: <UserProfileLabel[]>['SUPERVISOR', 'USER', 'GUEST']\n };\n\n console.info('[person-service] Importing persons...');\n\n const res = await JobUtils.fetchAllPages((offset, size) =>\n super.loadAll(offset, size, 'id', null, filter, {\n debug: false,\n fetchPolicy: 'network-only',\n withTotal: (offset === 0), // Compute total only once\n toEntity: false\n }),\n {progression: opts?.progression, maxProgression: maxProgression * 0.9}\n );\n\n // Save result locally\n await this.entities.saveAll(res.data, {entityName: 'PersonVO', reset: true});\n }\n\n /* -- protected methods -- */\n\n protected asObject(source: Person | any): any {\n if (!source) return undefined;\n\n console.debug('TODO check isInstanceOf');\n if (!(source instanceof Person)) {\n source = Person.fromObject(source);\n }\n const target = source.asObject();\n\n // Not known in server GraphQL schema\n delete target.mainProfile;\n\n // Minify the department object\n target.department = source.department && source.department.asObject(true);\n\n return target;\n }\n\n}\n","import { Injectable } from '@angular/core';\nimport { ValidatorService } from '@e-is/ngx-material-table';\nimport {FormGroup, FormBuilder, Validators} from '@angular/forms';\nimport { Person } from '../../../core/services/model/person.model';\nimport { Account } from '../../../core/services/model/account.model';\nimport { SharedValidators } from '../../../shared/validator/validators';\nimport {AccountValidatorService} from '../../../core/services/validator/account.validator';\n\n@Injectable({providedIn: 'root'})\nexport class PersonValidatorService implements ValidatorService {\n\n constructor(\n protected formBuilder: FormBuilder,\n protected accountValidatorService: AccountValidatorService\n ) {\n }\n\n getRowValidator(): FormGroup {\n return this.getFormGroup();\n }\n\n getFormGroup(data?: Person): FormGroup {\n\n // Use account validator as base form group definition\n // BUT add more flexibility (e.g. 'pubkey' become optional)\n // This is need to be able to store person that are not using SUMARiS tools (e.g. onboard observers)\n const formConfig = this.accountValidatorService.getFormGroupConfig(data && Account.fromObject(data.asObject()));\n formConfig.pubkey = [data && data.pubkey || null, SharedValidators.pubkey];\n formConfig.username = [data && data.username || null, Validators.minLength(2)];\n formConfig.usernameExtranet = [data && data.usernameExtranet || null, Validators.minLength(2)];\n formConfig.avatar = [data && data.avatar || null];\n\n return this.formBuilder.group(formConfig);\n }\n\n\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Injector, Input, OnInit, ViewChild} from '@angular/core';\nimport {Person, PRIORITIZED_AUTHORITIES} from '../../../core/services/model/person.model';\nimport {StatusById, StatusList} from '../../../core/services/model/referential.model';\nimport {PersonService} from '../../services/person.service';\nimport {PersonValidatorService} from '../../services/validator/person.validator';\nimport {AccountService} from '../../../core/services/account.service';\nimport {AbstractControl, FormBuilder, FormGroup} from '@angular/forms';\nimport {AppTable, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, SETTINGS_FILTER} from '../../../core/table/table.class';\nimport {ValidatorService} from '@e-is/ngx-material-table';\nimport {FormFieldDefinition} from '../../../shared/form/field.model';\nimport {debounceTime, filter, tap} from 'rxjs/operators';\nimport {EntitiesTableDataSource} from '../../../core/table/entities-table-datasource.class';\nimport {isNotNil} from '../../../shared/functions';\nimport {ENVIRONMENT} from '../../../../environments/environment.class';\nimport {PersonFilter} from '../../services/filter/person.filter';\nimport {ConfigService} from '../../../core/services/config.service';\nimport {CORE_CONFIG_OPTIONS} from '../../../core/services/config/core.config';\nimport {AuthTokenType} from '../../../core/services/network.service';\nimport {MatExpansionPanel} from '@angular/material/expansion';\nimport {slideUpDownAnimation} from '../../../shared/material/material.animations';\nimport {MessageModal, MessageModalOptions} from '../../../social/message/message.modal';\nimport {Message} from '../../../social/message/message.model';\nimport {MessageService} from '../../../social/message/message.service';\n\n@Component({\n selector: 'app-users-table',\n templateUrl: 'users.html',\n styleUrls: ['./users.scss'],\n providers: [\n {provide: ValidatorService, useExisting: PersonValidatorService}\n ],\n animations: [slideUpDownAnimation],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UsersPage extends AppTable<Person, PersonFilter> implements OnInit {\n\n readonly canEdit: boolean;\n readonly canSendMessage: boolean;\n readonly filterForm: FormGroup;\n readonly profiles = [...PRIORITIZED_AUTHORITIES].reverse();\n readonly statusList = StatusList;\n readonly statusById = StatusById;\n\n additionalFields: FormFieldDefinition[];\n filterCriteriaCount = 0;\n\n set showUsernameColumn(value: boolean) {\n this.setShowColumn('username', value);\n }\n\n set showUsernameExtranetColumn(value: boolean) {\n this.setShowColumn('usernameExtranet', value);\n }\n\n @Input() useSticky = false;\n\n constructor(\n injector: Injector,\n formBuilder: FormBuilder,\n protected accountService: AccountService,\n protected validatorService: ValidatorService,\n protected configService: ConfigService,\n protected dataService: PersonService,\n protected messageService: MessageService,\n protected cd: ChangeDetectorRef,\n @Inject(ENVIRONMENT) environment\n ) {\n super(injector,\n RESERVED_START_COLUMNS\n .concat([\n 'avatar',\n 'lastName',\n 'firstName',\n 'email',\n 'profile',\n 'status',\n 'username',\n 'usernameExtranet',\n 'pubkey'\n ])\n .concat(accountService.additionalFields.map(field => field.key))\n .concat(RESERVED_END_COLUMNS),\n new EntitiesTableDataSource(Person, dataService, validatorService, {\n prependNewElements: false,\n suppressErrors: environment.production,\n dataServiceOptions: {\n saveOnlyDirtyRows: true\n }\n }),\n null\n );\n\n\n this.canEdit = accountService.isAdmin();\n this.canSendMessage = this.canEdit;\n this.inlineEdition = this.canEdit;\n this.confirmBeforeDelete = true;\n this.autoLoad = false; // Wait config loading\n this.i18nColumnPrefix = 'USER.';\n this.defaultSortBy = 'lastName';\n this.defaultSortDirection = 'asc';\n\n this.filterForm = formBuilder.group({\n searchText: [null],\n statusId: [null]\n });\n\n this.additionalFields = (this.accountService.additionalFields || [])\n .filter(field => isNotNil(field.autocomplete))\n .map(field => {\n // Make sure to get the final autocomplete config (e.g. with a suggestFn function)\n field.autocomplete = this.registerAutocompleteField(field.key, {\n ...field.autocomplete // Copy, to be sure the original config is unchanged\n });\n return field;\n });\n\n // For DEV only --\n this.debug = !environment.production;\n }\n\n @ViewChild(MatExpansionPanel, {static: true}) filterExpansionPanel: MatExpansionPanel;\n\n ngOnInit() {\n super.ngOnInit();\n\n this.registerSubscription(\n this.configService.config.subscribe(config => {\n const authTokenType = config.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE) as AuthTokenType;\n console.debug('[users] AuthTokenType=' + authTokenType)\n switch (authTokenType) {\n case \"basic\":\n this.setShowColumn('pubkey', false, {emitEvent: false});\n case \"basic-and-token\":\n this.setShowColumn('username', true, {emitEvent: false});\n this.setShowColumn('usernameExtranet', true, {emitEvent: false});\n break;\n case \"token\":\n this.setShowColumn('pubkey', true, {emitEvent: false});\n this.setShowColumn('username', false, {emitEvent: false});\n this.setShowColumn('usernameExtranet', false, {emitEvent: false});\n }\n this.updateColumns();\n this.onRefresh.emit();\n })\n )\n\n this.registerSubscription(\n this.onRefresh.subscribe(() => {\n this.filterForm.markAsUntouched();\n this.filterForm.markAsPristine();\n }));\n\n // Update filter when changes\n this.registerSubscription(\n this.filterForm.valueChanges\n .pipe(\n debounceTime(250),\n filter(() => this.filterForm.valid),\n tap(json => {\n const filter = PersonFilter.fromObject(json);\n this.filterCriteriaCount = filter.countNotEmptyCriteria();\n this.markForCheck();\n // Update the filter, without reloading the content\n this.setFilter(filter, {emitEvent: false});\n }),\n // Save filter in settings (after a debounce time)\n debounceTime(500),\n tap(json => this.settings.savePageSetting(this.settingsId, json, SETTINGS_FILTER))\n )\n .subscribe());\n\n // Restore filter from settings, or load all\n this.restoreFilterOrLoad();\n }\n\n applyFilterAndClosePanel(event?: UIEvent) {\n this.onRefresh.emit(event);\n this.filterExpansionPanel.close();\n }\n\n resetFilter(event?: UIEvent) {\n this.totalRowCount = undefined;\n this.filterCriteriaCount = 0;\n this.markAsLoading();\n this.filterForm.reset();\n this.setFilter(null);\n }\n\n protected async restoreFilterOrLoad() {\n this.markAsLoading();\n\n console.debug(\"[users] Restoring filter from settings...\");\n\n const json = this.settings.getPageSettings(this.settingsId, SETTINGS_FILTER) || {};\n const filter = PersonFilter.fromObject(json);\n\n this.filterForm.patchValue(json);\n this.setFilter(filter, {emitEvent: true});\n }\n\n clearControlValue(event: UIEvent, formControl: AbstractControl): boolean {\n if (event) event.stopPropagation(); // Avoid to enter input the field\n formControl.setValue(null);\n return false;\n }\n\n async openComposeMessageModal(event?: Event): Promise<any> {\n\n // Get recipients\n const recipients = (this.selection.selected || [])\n .map(row => row.currentData)\n .map(Person.fromObject)\n .map(p => {\n const target = p.asObject({minify: true});\n target.department = p.department?.asObject();\n return target;\n });\n\n const hasTopModal = !!(await this.modalCtrl.getTop());\n const modal = await this.modalCtrl.create({\n component: MessageModal,\n componentProps: <MessageModalOptions>{\n suggestFn: (value, filter, sortBy, sortDirection) => this.dataService.suggest(value, filter, sortBy, sortDirection),\n data: <Message>{\n recipients\n }\n },\n cssClass: hasTopModal && 'stack-modal'\n });\n\n // Open the modal\n await modal.present();\n\n // On dismiss\n const {data} = await modal.onDidDismiss();\n if (!data || !(data instanceof Message)) return; // CANCELLED\n\n console.info('[users] received message to send: ', data);\n await this.messageService.send(data);\n }\n\n /* -- protected methods -- */\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n\n}\n\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {CoreModule} from '../core/core.module';\nimport {UsersPage} from './users/list/users';\nimport {SocialModule} from '../social/social.module';\nimport {NgxJdenticonModule} from 'ngx-jdenticon';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {SharedMaterialModule} from '../shared/material/material.module';\n\n@NgModule({\n imports: [\n CommonModule,\n CoreModule,\n SocialModule,\n SharedMaterialModule,\n NgxJdenticonModule,\n TranslateModule.forChild()\n ],\n declarations: [\n UsersPage\n ],\n exports: [\n SocialModule,\n UsersPage\n ]\n})\nexport class AdminModule {\n\n constructor() {\n console.debug('[admin] Creating module');\n }\n}\n","import {RouterModule, Routes} from '@angular/router';\nimport {UsersPage} from './users/list/users';\nimport {AuthGuardService} from '../core/services/auth-guard.service';\nimport {NgModule} from '@angular/core';\nimport {SharedRoutingModule} from '../shared/shared-routing.module';\nimport {AdminModule} from './admin.module';\nimport {ComponentDirtyGuard} from '../shared/guard/component-dirty.guard';\nimport {SocialModule} from '../social/social.module';\n\nconst routes: Routes = [\n {\n path: 'users',\n pathMatch: 'full',\n component: UsersPage,\n canActivate: [AuthGuardService],\n canDeactivate: [ComponentDirtyGuard],\n data: {\n profile: 'ADMIN'\n }\n }\n];\n\n@NgModule({\n imports: [\n SharedRoutingModule,\n AdminModule,\n RouterModule.forChild(routes)\n ],\n exports: [RouterModule]\n})\nexport class AdminRoutingModule { }\n","import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';\nimport {FormArray, FormBuilder, FormGroup} from '@angular/forms';\nimport {SharedFormArrayValidators, SharedValidators} from '../../../validator/validators';\nimport {MatAutocompleteConfigHolder, MatAutocompleteField} from '../material.autocomplete';\nimport {isNil, isNotNil, sleep} from '../../../functions';\nimport {BehaviorSubject} from 'rxjs';\nimport {LoadResult} from '../../../services/entity-service.class';\nimport {suggestFromArray} from '../../../services';\nimport Timer = NodeJS.Timer;\n\nclass EntityTestClass {\n id: number;\n label: string;\n name: string;\n}\n\nconst FAKE_ENTITIES = [\n {id: 1, label: 'AAA', name: 'Item A', description: 'Very long description A', comments: 'Very very long comments... again for A'},\n {id: 2, label: 'BBB', name: 'Item B', description: 'Very long description B', comments: 'Very very long comments... again for B'},\n {id: 3, label: 'CCC', name: 'Item C', description: 'Very long description C', comments: 'Very very long comments... again for C'}\n];\n\nfunction deepCopy(values?: EntityTestClass[], size?: number): EntityTestClass[] {\n if (isNil(size)) {\n return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));\n }\n\n let result = [];\n let i = 1;\n while (result.length < size) {\n result = result.concat((values || FAKE_ENTITIES).map(entity => {\n const name = entity.name + ' #' + i;\n return {...entity, id: i++, name};\n }));\n }\n return result.slice(0, size);\n}\n\n@Component({\n selector: 'app-autocomplete-test',\n templateUrl: './autocomplete.test.html'\n})\nexport class AutocompleteTestPage implements OnInit, AfterViewInit {\n\n private _items = deepCopy(FAKE_ENTITIES, 100);\n private _$items = new BehaviorSubject<EntityTestClass[]>(undefined);\n\n form: FormGroup;\n autocompleteFields = new MatAutocompleteConfigHolder();\n memoryHide = false;\n memoryMobile = true;\n memoryAutocompleteFieldName = 'entity-$items';\n memoryTimer: Timer;\n\n mode: 'mobile'|'desktop'|'memory'|'temp' = 'mobile';\n\n @ViewChild('farEntityField') farEntityField: MatAutocompleteField;\n\n constructor(\n protected formBuilder: FormBuilder\n ) {\n this.form = formBuilder.group({\n entity: [null, SharedValidators.entity],\n missingEntity: [null, SharedValidators.entity],\n disableEntity: [null, SharedValidators.entity],\n entities: [null, SharedFormArrayValidators.requiredArrayMinLength(1)],\n farEntity: [null, SharedValidators.entity]\n });\n\n this.form.get('disableEntity').disable();\n }\n\n ngOnInit() {\n\n // From suggest\n this.autocompleteFields.add('entity-suggestFn', {\n suggestFn: (value, filter) => this.suggest(value, filter),\n attributes: ['label', 'name'],\n displayWith: this.entityToString\n });\n\n // From items array\n this.autocompleteFields.add('entity-items', {\n items: this._items.slice(),\n attributes: ['label', 'name'],\n displayWith: this.entityToString\n });\n\n // From $items observable\n this.autocompleteFields.add('entity-$items', {\n items: this._$items,\n attributes: ['label', 'name'],\n displayWith: this.entityToString\n });\n\n // From $items with filter\n this.autocompleteFields.add('entity-items-filter', {\n service: {\n suggest: (value, filter) => this.suggest(value, filter)\n },\n attributes: ['label', 'name'],\n displayWith: this.entityToString\n });\n\n // From items\n this.autocompleteFields.add('entity-items-large', {\n items: FAKE_ENTITIES.slice(),\n attributes: ['label', 'name', 'description', 'comments'],\n displayWith: this.entityToString\n });\n\n // Far entity, in the list\n this.autocompleteFields.add('entity-far', {\n suggestFn: (value, filter) => this.suggest(value, filter),\n attributes: ['label', 'name'],\n displayWith: this.entityToString\n });\n\n // For multiple value\n this.autocompleteFields.add('entities-items-filter', {\n service: {\n suggest: (value, filter) => this.suggest(value, filter)\n },\n attributes: ['label', 'name'],\n multiple: true\n });\n\n }\n\n ngAfterViewInit() {\n\n if (this.farEntityField) {\n setTimeout(() => {\n this.farEntityField.suggestLengthThreshold=2;\n this.farEntityField.reloadItems();\n }, 2000);\n }\n\n setTimeout(()=> this.loadData(), 1000);\n }\n\n // Load the form with data\n async loadData() {\n const data = {\n entity: deepCopy(FAKE_ENTITIES)[0], // First\n\n farEntity: deepCopy(FAKE_ENTITIES)[2],\n\n // This item is NOT in the items list => i should be displayed anyway\n missingEntity: {\n id: -1, label: '??', name: 'Missing item'\n },\n\n disableEntity: deepCopy(FAKE_ENTITIES)[2],\n\n entities: deepCopy(FAKE_ENTITIES)\n };\n\n this.form.setValue(data);\n\n // Load observables\n setTimeout(() => this.loadItems(), 1000);\n }\n\n async loadItems() {\n this._$items.next(this._items.slice());\n }\n\n entityToString(item: any) {\n return [item && item.label || undefined, item && item.name || undefined].filter(isNotNil).join(' - ');\n }\n\n entitiesToString(items: any[]) {\n return (items||[]).map(this.entityToString).join(', ');\n }\n\n async suggest(value: any, filter?: any): Promise<LoadResult<EntityTestClass>> {\n filter = {offset: 0, size: 30, ...filter};\n const res = suggestFromArray(this._items, value, {\n ...filter,\n searchAttributes: ['label', 'name']\n });\n\n // Simulate a size = 30\n const total = res.total || res.data.length;\n\n const nextOffset = filter.offset + res.data.length;\n if (nextOffset < total) {\n filter = {...filter, offset: nextOffset};\n return {\n total,\n data: res.data,\n fetchMore: async (variables) => {\n await sleep(1000); // Simulate access to server\n return this.suggest(value, {...filter, ...variables});\n }\n };\n }\n\n return res;\n }\n\n doSubmit(event) {\n\n console.debug('Validate form: ', this.form.value);\n }\n\n equals(o1: EntityTestClass, o2: EntityTestClass): boolean {\n return o1 && o2 && o1.id === o2.id;\n }\n\n toggleMode(value) {\n if (this.mode !== value) {\n this.mode = value;\n this.stopMemoryTimer();\n }\n }\n\n startMemoryTimer() {\n this.memoryTimer = setInterval(() => {\n this.memoryHide = !this.memoryHide;\n }, 50);\n }\n\n stopMemoryTimer() {\n clearInterval(this.memoryTimer);\n this.memoryTimer = null;\n this.memoryHide = false;\n }\n\n updateFilter(autocompleteField: MatAutocompleteField, fieldName: string) {\n const filter: { searchAttribute?: string } = this.autocompleteFields.get(fieldName).filter || {};\n filter.searchAttribute = (!filter || filter.searchAttribute !== 'name') ? 'name' : 'label';\n autocompleteField.reloadItems();\n }\n\n /* -- protected methods -- */\n\n stringify(value: any) {\n return JSON.stringify(value);\n }\n}\n\n","import {Component, OnInit} from '@angular/core';\nimport {FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {SharedValidators} from '../../../validator/validators';\n\n\n@Component({\n selector: 'app-latlong-test',\n templateUrl: './latlong.test.html'\n})\nexport class LatLongTestPage implements OnInit {\n\n\n form: FormGroup;\n\n constructor(\n protected formBuilder: FormBuilder\n ) {\n this.form = formBuilder.group({\n empty: formBuilder.group({\n latitude: [null, Validators.compose([Validators.required, SharedValidators.latitude])],\n longitude: [null, Validators.compose([Validators.required, SharedValidators.longitude])]\n }),\n enable: formBuilder.group({\n latitude: [null, SharedValidators.latitude],\n longitude: [null, SharedValidators.longitude]\n }),\n disable: formBuilder.group({\n latitude: [null, SharedValidators.latitude],\n longitude: [null, SharedValidators.longitude]\n })\n });\n\n const disableFormGroup = this.form.get('disable');\n disableFormGroup.disable();\n\n // Copy enable value to disable form\n this.form.get('enable').valueChanges.subscribe(value => disableFormGroup.setValue(value));\n\n }\n\n ngOnInit() {\n\n\n setTimeout(() => this.loadData(), 250);\n }\n\n // Load the form with data\n async loadData() {\n const data = {\n empty: {\n latitude: null,\n longitude: null\n },\n enable: {\n latitude: 50.1,\n longitude: -2\n },\n disable: {\n latitude: 50.1,\n longitude: -2\n },\n };\n\n this.form.setValue(data);\n }\n\n doSubmit(event) {\n console.debug('Validate form: ', this.form.value);\n }\n\n geoPosition(event: UIEvent): boolean {\n console.debug('Click on geoLocation button', event);\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n\n stringify = JSON.stringify;\n\n /* -- protected methods -- */\n\n\n}\n\n","import {Component, OnInit} from '@angular/core';\nimport {FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {SharedValidators} from '../../../validator/validators';\nimport * as momentImported from 'moment';\nconst moment = momentImported;\nimport {BehaviorSubject} from 'rxjs';\nimport {Moment} from 'moment';\nimport {DateFormatPipe} from '../../../pipes/date-format.pipe';\nimport {DisplayFn} from '../../../form/field.model';\nimport {distinctUntilChanged} from 'rxjs/operators';\n\n@Component({\n selector: 'app-swipe-test',\n templateUrl: './swipe.test.html'\n})\nexport class SwipeTestPage implements OnInit {\n\n form: FormGroup;\n\n $dates = new BehaviorSubject<Moment[]>(undefined);\n private _today = moment().startOf('day');\n\n constructor(\n protected formBuilder: FormBuilder,\n protected dateFormatPipe: DateFormatPipe\n ) {\n this.form = formBuilder.group({\n empty: [null, Validators.required],\n date: [null, Validators.compose([Validators.required, SharedValidators.validDate])],\n disabledEmpty: [null, Validators.required],\n disabledDate: [null, Validators.required]\n });\n\n this.form.get('disabledEmpty').disable();\n this.form.get('disabledDate').disable();\n\n }\n\n ngOnInit() {\n\n const dates: Moment[] = [];\n for (let d = 0; d < 7; d++) {\n dates[d] = moment(this._today).add(d-3, 'day');\n }\n this.$dates.next(dates);\n\n\n this.loadData();\n //setTimeout(() => this.loadData(), 1500);\n\n this.form.valueChanges.pipe(\n distinctUntilChanged()\n ).subscribe(() => console.debug(this.form.value));\n }\n\n // Load the form with data\n async loadData() {\n const data = {\n empty: null,\n date: this._today,\n disabledEmpty: null,\n disabledDate: this._today\n };\n\n this.form.patchValue(data);\n }\n\n doSubmit(event) {\n console.debug('Validate form: ', this.form.value);\n }\n\n /* -- protected methods -- */\n\n displayDate(): DisplayFn {\n return (obj: any) => this.dateFormatPipe.transform(obj, {pattern: 'dddd L'}).toString();\n }\n\n compareDate() {\n return (d1: Moment, d2: Moment) => d1 && d2 && d1.isSame(d2) || false;\n }\n}\n\n","import { ChangeDetectorRef, Component, OnInit } from '@angular/core';\nimport { FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Platform } from '@ionic/angular';\nimport { debounceTime } from 'rxjs/operators';\nimport { SharedFormGroupValidators } from '../../../validator/validators';\nimport { AppFormUtils } from '../../../../core/form/form.utils';\nimport { DateUtils, MOMENT_NO_TIME_PROPERTY, toDateISOString } from '../../../dates';\nimport * as momentImported from 'moment';\nimport { isMobile } from '../../../platforms';\nimport Timer = NodeJS.Timer;\n\nconst moment = momentImported;\n\n@Component({\n selector: 'app-data-time-test',\n templateUrl: './mat-date-time.test.html'\n})\nexport class DateTimeTestPage implements OnInit {\n\n\n showLogPanel = true;\n logContent = '';\n\n memoryHide = false;\n memoryMobile = true;\n memoryTimer: Timer;\n\n form: FormGroup;\n\n noTimeProperty = MOMENT_NO_TIME_PROPERTY;\n\n constructor(\n protected platform: Platform,\n protected formBuilder: FormBuilder,\n protected cd: ChangeDetectorRef\n ) {\n this.form = formBuilder.group({\n empty: [null],\n emptyRequired: [null, Validators.required],\n enable: [null, Validators.required],\n disable: [null, Validators.required],\n noTime: [null, Validators.required],\n readonly: [null]\n }, {\n validators: SharedFormGroupValidators.dateRange('empty', 'enable')\n });\n\n const disableControl = this.form.get('disable');\n disableControl.disable();\n\n // Copy the 'enable' value, into the disable control\n this.form.get('enable').valueChanges.subscribe(value => disableControl.setValue(value));\n\n this.showLogPanel = this.showLogPanel || isMobile(window);\n }\n\n ngOnInit() {\n\n setTimeout(() => this.loadData(), 250);\n\n\n }\n\n // Load the form with data\n async loadData() {\n const now = moment();\n const data = {\n empty: null, // toDateISOString(now.clone().add(2, 'hours'))\n emptyRequired: null,\n enable: toDateISOString(now),\n disable: now,\n noTime: DateUtils.markNoTime(DateUtils.resetTime(now)),\n readonly: now\n };\n\n this.form.setValue(data);\n\n this.log('[test-page] Data loaded: ' + JSON.stringify(data));\n\n this.form.get('empty').valueChanges\n .pipe(debounceTime(300))\n .subscribe(value => this.log('[test-page] Value n°1: ' + JSON.stringify(value)));\n\n this.form.get('enable').valueChanges\n .pipe(debounceTime(300))\n .subscribe(value => this.log('[test-page] Value n°2: ' + JSON.stringify(value)));\n\n this.form.get('noTime').valueChanges\n .pipe(debounceTime(300))\n .subscribe(value => this.log('[test-page] Value n°3: ' + JSON.stringify(value)));\n }\n\n doSubmit(event) {\n this.form.markAllAsTouched();\n this.log('[test-page] Form content: ' + JSON.stringify(this.form.value));\n this.log('[test-page] Form status: ' + this.form.status);\n if (this.form.invalid) {\n this.log('[test-page] Form errors: ' + JSON.stringify(this.form.errors));\n\n // DEBUG\n AppFormUtils.logFormErrors(this.form);\n }\n }\n\n log(message: string) {\n console.debug(message);\n\n if (this.showLogPanel) {\n this.logContent += message + '<br/>';\n this.cd.markForCheck();\n }\n }\n\n clearLogPanel() {\n this.logContent = '';\n this.cd.markForCheck();\n }\n\n startMemoryTimer() {\n this.memoryTimer = setInterval(() => {\n this.memoryHide = !this.memoryHide;\n }, 50);\n }\n\n stopMemoryTimer() {\n clearInterval(this.memoryTimer);\n this.memoryTimer = null;\n this.memoryHide = false;\n }\n\n stringify = JSON.stringify;\n\n /* -- protected methods -- */\n\n\n}\n\n","import {Component, OnInit} from '@angular/core';\nimport {FormBuilder, FormGroup} from '@angular/forms';\nimport {BehaviorSubject} from 'rxjs';\nimport {SharedValidators} from '../../../validator/validators';\nimport {MatAutocompleteConfigHolder} from '../../autocomplete/material.autocomplete';\nimport {isNil, isNotNil, sleep} from '../../../functions';\nimport {LoadResult} from '../../../services/entity-service.class';\nimport {EntityUtils} from '../../../../core/services/model/entity.model';\nimport {MatFormFieldAppearance} from '@angular/material/form-field';\nimport {suggestFromArray} from \"../../../services\";\n\nclass EntityTestClass {\n id: number;\n label: string;\n name: string;\n}\n\nconst FAKE_ENTITIES: EntityTestClass[] = [\n {id: 1, label: 'AAA', name: 'Item A'},\n {id: 2, label: 'BBB', name: 'Item B'},\n {id: 3, label: 'CCC', name: 'Item C'},\n {id: 4, label: 'DDD', name: 'Item D'},\n {id: 5, label: 'EEE', name: 'Item E'},\n {id: 6, label: 'FFF', name: 'Item F'},\n {id: 7, label: 'GGG', name: 'Item G'}\n];\n\nfunction deepCopy(values?: EntityTestClass[], size?: number): EntityTestClass[] {\n if (isNil(size)) {\n return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));\n }\n\n let result = [];\n let i = 1;\n while (result.length < size) {\n result = result.concat((values || FAKE_ENTITIES).map(entity => {\n const name = entity.name + ' #' + i;\n return {...entity, id: i++, name};\n }));\n }\n return result.slice(0, size);\n}\n\n@Component({\n selector: 'app-chips-test',\n templateUrl: './chips.test.html'\n})\nexport class ChipsTestPage implements OnInit {\n\n private _items = deepCopy(FAKE_ENTITIES, 100);\n private _$items = new BehaviorSubject<EntityTestClass[]>(undefined);\n\n form: FormGroup;\n autocompleteFields = new MatAutocompleteConfigHolder();\n appearance: MatFormFieldAppearance = 'legacy';\n\n constructor(\n protected formBuilder: FormBuilder\n ) {\n this.form = formBuilder.group({\n entity: [null, SharedValidators.entity],\n entityInitial: [null, SharedValidators.entity],\n disableEntity: [null, SharedValidators.entity],\n });\n\n this.form.get('disableEntity').disable();\n }\n\n ngOnInit() {\n\n // From suggest\n this.autocompleteFields.add('entity-suggestFn', {\n suggestFn: (value, filter) => this.suggest(value, filter),\n attributes: ['label', 'name'],\n displayWith: this.entityToString,\n equals: (o1, o2) => EntityUtils.compare(o1, o2, 1, 'id') === 0\n });\n\n // From items\n this.autocompleteFields.add('entity-items', {\n items: this._items.slice(),\n attributes: ['label', 'name'],\n displayWith: this.entityToString,\n equals: (o1, o2) => EntityUtils.compare(o1, o2, 1, 'id') === 0\n });\n\n // From $items observable\n this.autocompleteFields.add('entity-$items', {\n items: this._$items,\n attributes: ['label', 'name'],\n displayWith: this.entityToString\n });\n\n this.loadData();\n //setTimeout(() => this.loadData(), 1500);\n\n //\n setTimeout(() => this.loadItems(), 1000);\n }\n\n // Load the form with data\n async loadData() {\n const items = deepCopy(FAKE_ENTITIES);\n const data = {\n entity: items.slice(0, 1), // Select the first\n\n entityInitial: items.slice(1, 2),\n\n disableEntity: items.slice(1, 2)\n };\n\n this.form.setValue(data);\n\n // Load observables\n setTimeout(() => this.loadItems(), 1000);\n }\n\n async loadItems() {\n this._$items.next(this._items.slice());\n }\n\n entityToString(item: any) {\n return [item && item.label || undefined, item && item.name || undefined].filter(isNotNil).join(' - ');\n }\n\n async suggest(value: any, filter?: any): Promise<LoadResult<EntityTestClass>> {\n filter = {offset: 0, size: 30, ...filter};\n const res = suggestFromArray(this._items, value, {\n ...filter,\n searchAttributes: ['label', 'name']\n });\n\n // Simulate a size = 30\n const total = res.total || res.data.length;\n\n const nextOffset = filter.offset + res.data.length;\n if (nextOffset < total) {\n filter = {...filter, offset: nextOffset};\n return {\n total,\n data: res.data,\n fetchMore: async (variables) => {\n await sleep(1000);\n return this.suggest(value, {...filter, ...variables});\n }\n };\n }\n\n return res;\n }\n\n doSubmit(event) {\n\n console.debug('Validate form: ', this.form.value);\n }\n\n equals(o1: EntityTestClass, o2: EntityTestClass): boolean {\n return o1 && o2 && o1.id === o2.id;\n }\n\n /* -- protected methods -- */\n\n stringify(value: any) {\n return JSON.stringify(value);\n }\n}\n\n","import {Component} from '@angular/core';\nimport {BehaviorSubject} from 'rxjs';\nimport {MatBadgeFill} from './badge-icon.directive';\nimport {ThemePalette} from '@angular/material/core';\nimport {PredefinedColors} from '@ionic/core';\nimport {MatBadgeSize} from '@angular/material/badge';\n\n@Component({\n selector: 'mat-badge-icon-test',\n templateUrl: './badge-icon.test.html'\n})\nexport class MatBadgeIconTestPage {\n\n $icon = new BehaviorSubject<string>('alert');\n $size = new BehaviorSubject<MatBadgeSize>('small');\n $fill = new BehaviorSubject<MatBadgeFill>('solid');\n $color = new BehaviorSubject<PredefinedColors | ThemePalette>('danger');\n}\n","import {Component, OnInit} from '@angular/core';\nimport {FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {SharedValidators} from '../../../validator/validators';\n\n\n@Component({\n selector: 'app-numpad-test',\n templateUrl: './numpad.test.html'\n})\nexport class NumpadTestPage implements OnInit {\n\n\n form: FormGroup;\n\n constructor(\n protected formBuilder: FormBuilder\n ) {\n this.form = formBuilder.group({\n empty: [null, Validators.required],\n integer: [null, Validators.compose([Validators.required, SharedValidators.integer])],\n disable: [null, Validators.required],\n datetime: [null]\n });\n\n this.form.get('disable').disable();\n }\n\n ngOnInit() {\n\n\n this.loadData();\n //setTimeout(() => this.loadData(), 1500);\n\n }\n\n // Load the form with data\n async loadData() {\n const data = {\n empty: null,\n integer: 99,\n disable: -111.11\n };\n\n this.form.patchValue(data);\n }\n\n doSubmit(event) {\n console.debug('Validate form: ', this.form.value);\n }\n\n /* -- protected methods -- */\n\n\n}\n\n","import {ChangeDetectorRef, Component, OnInit} from '@angular/core';\nimport {FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {debounceTime} from 'rxjs/operators';\nimport {SharedFormGroupValidators, SharedValidators} from '../../../validator/validators';\nimport {AppFormUtils} from '../../../../core/form/form.utils';\nimport {toDateISOString} from '../../../dates';\nimport * as momentImported from 'moment';\nimport {isMobile} from '../../../platforms';\nimport Timer = NodeJS.Timer;\n\nconst moment = momentImported;\n\n@Component({\n selector: 'app-data-test',\n templateUrl: './mat-date.test.html'\n})\nexport class DateTestPage implements OnInit {\n\n showLogPanel = true;\n logContent = '';\n\n memoryHide = false;\n memoryMobile = true;\n memoryTimer: Timer;\n timezone = 'Indian/Mahe';\n\n form: FormGroup;\n\n constructor(\n protected formBuilder: FormBuilder,\n protected cd: ChangeDetectorRef\n ) {\n this.form = formBuilder.group({\n empty: [null, SharedValidators.validDate],\n emptyRequired: [null, Validators.compose([Validators.required, SharedValidators.validDate])],\n enable: [null, Validators.required],\n disable: [null, Validators.required],\n readonly: [null],\n timezone: [null]\n }, {\n validators: SharedFormGroupValidators.dateRange('empty', 'enable')\n });\n\n const disableControl = this.form.get('disable');\n disableControl.disable();\n\n // Copy the 'enable' value, into the disable control\n this.form.get('enable').valueChanges.subscribe(value => disableControl.setValue(value));\n\n this.showLogPanel = this.showLogPanel || isMobile(window);\n }\n\n ngOnInit() {\n\n setTimeout(() => this.loadData(), 250);\n\n\n }\n\n // Load the form with data\n async loadData() {\n const now = moment();\n\n const nowAtMahe = now.clone().tz(this.timezone).startOf('day');\n\n const data = {\n empty: null, // toDateISOString(now.clone().add(2, 'hours')),\n emptyRequired: null,\n enable: toDateISOString(now),\n disable: now.clone(),\n readonly: now.clone(),\n timezone: nowAtMahe\n };\n\n this.form.setValue(data);\n\n this.log('[test-page] Data loaded: ' + JSON.stringify(data));\n\n this.form.get('empty').valueChanges\n .pipe(debounceTime(300))\n .subscribe(value => this.log('[test-page] Value n°1: ' + JSON.stringify(value)));\n\n this.form.get('enable').valueChanges\n .pipe(debounceTime(300))\n .subscribe(value => this.log('[test-page] Value n°2: ' + JSON.stringify(value)));\n\n this.form.get('timezone').valueChanges\n .pipe(debounceTime(300))\n .subscribe(value => this.log('[test-page] Value with timezone: ' + JSON.stringify(value)));\n }\n\n doSubmit(event) {\n this.form.markAllAsTouched();\n this.log('[test-page] Form content: ' + JSON.stringify(this.form.value));\n this.log('[test-page] Form status: ' + this.form.status);\n if (this.form.invalid) {\n this.log('[test-page] Form errors: ' + JSON.stringify(this.form.errors));\n\n // DEBUG\n AppFormUtils.logFormErrors(this.form);\n }\n }\n\n log(message: string) {\n console.debug(message);\n\n if (this.showLogPanel) {\n this.logContent += message + '<br/>';\n this.cd.markForCheck();\n }\n }\n\n clearLogPanel() {\n this.logContent = '';\n this.cd.markForCheck();\n }\n\n startMemoryTimer() {\n this.memoryTimer = setInterval(() => {\n this.memoryHide = !this.memoryHide;\n }, 50);\n }\n\n stopMemoryTimer() {\n clearInterval(this.memoryTimer);\n this.memoryTimer = null;\n this.memoryHide = false;\n }\n\n stringify = JSON.stringify;\n\n /* -- protected methods -- */\n\n\n}\n\n","import {NgModule} from '@angular/core';\nimport {RouterModule, Routes} from '@angular/router';\nimport {AutocompleteTestPage} from './autocomplete/testing/autocomplete.test';\nimport {LatLongTestPage} from './latlong/testing/latlong.test';\nimport {SharedTestsPage, TestingPage} from '../testing/tests.page';\nimport {SharedMaterialModule} from './material.module';\nimport {IonicModule} from '@ionic/angular';\nimport {CommonModule} from '@angular/common';\nimport {ReactiveFormsModule} from '@angular/forms';\nimport {SwipeTestPage} from './swipe/testing/swipe.test';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {DateTimeTestPage} from './datetime/testing/mat-date-time.test';\nimport {ChipsTestPage} from './chips/testing/chips.test';\nimport {MatBadgeIconTestPage} from './badge/badge-icon.test';\nimport {NumpadTestPage} from './numpad/testing/numpad.test';\nimport {DateTestPage} from './datetime/testing/mat-date.test';\n\nexport const SHARED_MATERIAL_TESTING_PAGES: TestingPage[] = [\n {label: 'Shared Material components', divider: true},\n {label: 'Date/Time field', page: '/testing/shared/datetime'},\n {label: 'Date field', page: '/testing/shared/date'},\n {label: 'Autocomplete field', page: '/testing/shared/autocomplete'},\n {label: 'Lat/Long field', page: '/testing/shared/latlong'},\n {label: 'Numeric pad component', page: '/testing/shared/numpad'},\n\n {label: 'Swipe component', page: '/testing/shared/swipe'},\n {label: 'Chips component', page: '/testing/shared/chips'},\n\n\n {label: 'Shared directives', divider: true},\n {label: 'Badge icon directive', page: '/testing/shared/badge-icon'}\n];\n\nconst routes: Routes = [\n {\n path: '',\n pathMatch: 'full',\n component: SharedTestsPage\n },\n {\n path: 'autocomplete',\n pathMatch: 'full',\n component: AutocompleteTestPage\n },\n {\n path: 'datetime',\n pathMatch: 'full',\n component: DateTimeTestPage\n },\n {\n path: 'date',\n pathMatch: 'full',\n component: DateTestPage\n },\n {\n path: 'latlong',\n pathMatch: 'full',\n component: LatLongTestPage\n },\n {\n path: 'numpad',\n pathMatch: 'full',\n component: NumpadTestPage\n },\n {\n path: 'swipe',\n pathMatch: 'full',\n component: SwipeTestPage\n },\n {\n path: 'chips',\n pathMatch: 'full',\n component: ChipsTestPage\n },\n {\n path: 'badge-icon',\n pathMatch: 'full',\n component: MatBadgeIconTestPage\n }\n];\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n ReactiveFormsModule,\n SharedMaterialModule,\n TranslateModule.forChild(),\n RouterModule.forChild(routes)\n ],\n declarations: [\n DateTimeTestPage,\n DateTestPage,\n AutocompleteTestPage,\n LatLongTestPage,\n NumpadTestPage,\n SwipeTestPage,\n ChipsTestPage,\n MatBadgeIconTestPage\n ],\n exports: [\n SharedMaterialModule,\n RouterModule,\n DateTimeTestPage,\n DateTestPage,\n AutocompleteTestPage,\n LatLongTestPage,\n NumpadTestPage,\n SwipeTestPage,\n ChipsTestPage\n ]\n})\nexport class MaterialTestingModule {\n}\n","import {Component} from '@angular/core';\nimport {ToastController} from '@ionic/angular';\nimport {ShowToastOptions, Toasts} from './toasts';\nimport {TranslateService} from '@ngx-translate/core';\n\n@Component({\n selector: 'toast-testing',\n templateUrl: 'toast.testing.html'\n})\nexport class ToastTestingPage {\n\n readonly defaultOptions: ShowToastOptions = {\n showCloseButton: false\n };\n\n constructor(\n private toastController: ToastController,\n private translate: TranslateService\n ) {\n }\n\n showToast(opts?: ShowToastOptions) {\n return Toasts.show(this.toastController, this.translate, {\n ...this.defaultOptions,\n message: 'This is a message',\n ...opts\n });\n }\n\n showInfo(opts?: ShowToastOptions) {\n return this.showToast({\n type: 'info',\n message: 'This is a info text !',\n ...opts\n });\n }\n\n showWarning(opts?: ShowToastOptions) {\n return this.showToast({\n type: 'warning',\n message: 'This is a warning text !',\n ...opts\n });\n }\n\n showError(opts?: ShowToastOptions) {\n return this.showToast({\n type: 'error',\n message: 'This is a error text !',\n ...opts\n });\n }\n\n toggleCloseButton() {\n this.defaultOptions.showCloseButton = !this.defaultOptions.showCloseButton;\n }\n}\n","import {NgModule} from '@angular/core';\nimport {RouterModule, Routes} from '@angular/router';\nimport {IonicModule} from '@ionic/angular';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {ToastTestingPage} from './toast.testing';\n\nconst routes: Routes = [\n {\n path: 'toast',\n pathMatch: 'full',\n component: ToastTestingPage\n }\n];\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n TranslateModule.forChild(),\n RouterModule.forChild(routes)\n ],\n declarations: [\n ToastTestingPage\n ],\n exports: [\n RouterModule,\n ToastTestingPage\n ]\n})\nexport class ToastTestingModule {\n}\n","import {Component} from '@angular/core';\nimport {PopoverController} from '@ionic/angular';\nimport {UploadFilePopoverOptions} from '../upload-file-popover.component';\nimport {Observable, Subject, timer} from 'rxjs';\nimport {HttpEventType, HttpResponse} from '@angular/common/http';\nimport {map, takeUntil} from 'rxjs/operators';\nimport {sleep} from '../../functions';\nimport {FileEvent} from '../upload-file.model';\nimport {FilesUtils} from '../../file/file.utils';\n\n@Component({\n selector: 'upload-file-testing',\n templateUrl: 'upload-file.testing.html'\n})\nexport class UploadFileTestingPage {\n\n constructor(\n private popoverController: PopoverController\n ) {\n }\n\n async showPopover(event: UIEvent, opts?: Partial<UploadFilePopoverOptions<any>>) {\n const {data} = await FilesUtils.showUploadPopover(this.popoverController, event, {\n uploadFn: (file) => this.uploadFile(file),\n deleteFn: (file) => this.deleteFile(file),\n ...opts\n });\n\n const filenames = (data || []).map(file => file.response?.body?.finalName);\n console.info('Popover result: ', filenames);\n }\n\n /**\n * Simulate a upload function, with progression\n * @param file\n */\n uploadFile(file: File): Observable<FileEvent<{ finalName: string; }>> {\n const $stop = new Subject();\n const loadStep = file.size / 10;\n let loaded = 0;\n return timer(0, 250)\n .pipe(\n takeUntil($stop),\n map(() => {\n loaded += loadStep;\n\n // Return progression\n if (loaded < file.size) {\n //return {type: HttpEventType.UploadProgress, total: file.size, loaded };\n return {type: HttpEventType.UploadProgress, loaded: -1 };\n }\n\n // Stop the timer\n setTimeout(() => $stop.next(), 100);\n\n // Return final response\n return new HttpResponse({body: {finalName : file.name}});\n })\n )\n\n }\n\n async deleteFile(file: File): Promise<boolean> {\n console.info('[testing] Simulate remote deletion... (waiting 2s)');\n await sleep(2000);\n return true;\n }\n}\n","import {NgModule} from '@angular/core';\nimport {RouterModule, Routes} from '@angular/router';\nimport {IonicModule} from '@ionic/angular';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {UploadFileTestingPage} from './upload-file.testing';\n\nconst routes: Routes = [\n {\n path: 'upload-file',\n pathMatch: 'full',\n component: UploadFileTestingPage\n }\n];\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n TranslateModule.forChild(),\n RouterModule.forChild(routes)\n ],\n declarations: [\n UploadFileTestingPage\n ],\n exports: [\n RouterModule,\n UploadFileTestingPage\n ]\n})\nexport class UploadFileTestingModule {\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {MaterialTestingModule, SHARED_MATERIAL_TESTING_PAGES} from './material/material.testing.module';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {ToastTestingModule} from './toast/toast.testing.module';\nimport {UploadFileTestingModule} from './upload-file/testing/upload-file.testing.module';\nimport {TestingPage} from './testing/tests.page';\n\nexport const SHARED_TESTING_PAGES: TestingPage[] = [\n ...SHARED_MATERIAL_TESTING_PAGES,\n\n {label: 'Shared other components', divider: true},\n {label: 'Toast', page: '/testing/shared/toast'},\n {label: 'File upload', page: '/testing/shared/upload-file'}\n];\n\n@NgModule({\n imports: [\n CommonModule,\n TranslateModule.forChild(),\n\n // Testing sub-modules\n MaterialTestingModule,\n ToastTestingModule,\n UploadFileTestingModule\n ],\n exports: [\n // Testing sub-modules\n MaterialTestingModule,\n ToastTestingModule,\n UploadFileTestingModule\n ]\n})\nexport class SharedTestingModule {\n}\n","import {EntityClass} from '../model/entity.decorators';\nimport {EntityFilter} from '../model/filter.model';\nimport {Referential} from '../model/referential.model';\nimport {EntityUtils} from '../model/entity.model';\nimport {FilterFn} from '../../../shared/services/entity-service.class';\n\n// @dynamic\n@EntityClass({typename: 'ReferentialFilterVO'})\nexport class ReferentialFilter extends EntityFilter<ReferentialFilter, Referential> {\n\n static fromObject: (source: any, opts?: any) => ReferentialFilter;\n\n searchText: string;\n\n fromObject(source: any, opts?: any) {\n super.fromObject(source, opts);\n this.searchText = source.searchText;\n }\n\n protected buildFilter(): FilterFn<Referential>[] {\n const target = super.buildFilter();\n\n const searchTextFn = EntityUtils.searchTextFilter(['label', 'name'], this.searchText);\n if (searchTextFn) target.push(searchTextFn);\n\n return target;\n }\n}\n","import {Injectable} from '@angular/core';\nimport {AbstractControlOptions, FormBuilder, FormGroup, Validators} from '@angular/forms';\nimport {Referential} from '../model/referential.model';\nimport {AppValidatorService} from '../validator/base.validator.class';\nimport {StatusIds} from '../model/model.enum';\n\n@Injectable()\nexport class ReferentialValidatorService<T extends Referential = Referential>\n extends AppValidatorService<T> {\n\n constructor(protected formBuilder: FormBuilder) {\n super(formBuilder);\n }\n\n getRowValidator(): FormGroup {\n return this.getFormGroup();\n }\n\n getFormGroup(data?: T, opts?: {\n withDescription?: boolean;\n withComments?: boolean;\n }): FormGroup {\n return this.formBuilder.group(\n this.getFormGroupConfig(data, opts),\n this.getFormGroupOptions(data, opts)\n );\n }\n\n getFormGroupConfig(data?: T, opts?: {\n withDescription?: boolean;\n withComments?: boolean;\n }): {[key: string]: any} {\n const controlsConfig: {[key: string]: any} = {\n id: [data && data.id || null],\n updateDate: [data && data.updateDate || null],\n creationDate: [data && data.creationDate || null],\n statusId: [data && data.statusId || null, Validators.required],\n levelId: [data && data.levelId || null],\n label: [data && data.label || null, Validators.required],\n name: [data && data.name || null, Validators.required],\n entityName: [data && data.entityName || null, Validators.required]\n };\n\n if (!opts || opts.withDescription !== false) {\n controlsConfig.description = [data && data.description || null, Validators.maxLength(255)];\n }\n if (!opts || opts.withComments !== false) {\n controlsConfig.comments = [data && data.comments || null, Validators.maxLength(2000)];\n }\n\n return controlsConfig;\n }\n\n getFormGroupOptions(data?: T, opts?: any): AbstractControlOptions | null {\n return null;\n }\n}\n","import {ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Injector, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';\nimport {AppTable, DEFAULT_PAGE_SIZE, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS} from '../table.class';\nimport {Referential, StatusById, StatusList} from '../../services/model/referential.model';\nimport {IonInfiniteScroll} from '@ionic/angular';\nimport {EntitiesTableDataSource} from '../entities-table-datasource.class';\nimport {InMemoryEntitiesService} from '../../../shared/services/memory-entity-service.class';\nimport {AppValidatorService} from '../../services/validator/base.validator.class';\nimport {AbstractControl, FormBuilder, FormGroup} from '@angular/forms';\nimport {isNil, isNotNil} from '../../../shared/functions';\nimport {fromUnixMsTimestamp} from '../../../shared/dates';\nimport {ReferentialFilter} from '../../services/testing/referential-filter.model';\nimport {debounceTime, filter, tap} from 'rxjs/operators';\nimport {MatExpansionPanel} from '@angular/material/expansion';\nimport {ReferentialValidatorService} from '../../services/testing/referential.validator';\nimport {StatusIds} from '../../services/model/model.enum';\nimport Timeout = NodeJS.Timeout;\n\n@Component({\n selector: 'app-table-testing',\n styleUrls: ['table.testing.scss'],\n templateUrl: 'table.testing.html',\n providers: [\n {\n provide: AppValidatorService,\n useClass: ReferentialValidatorService\n },\n {\n provide: AppTable, useExisting: forwardRef(() => TableTestPage),\n }\n ],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class TableTestPage extends AppTable<Referential, ReferentialFilter>\n implements OnInit, OnDestroy {\n\n static maxRowCount = 100;\n\n timer: Timeout;\n canEdit = true;\n data: Referential[];\n filterForm: FormGroup;\n filterCriteriaCount = 0;\n groupColumns = ['top-start', 'group-1', 'group-2', 'top-end'];\n\n readonly statusList = StatusList;\n readonly statusById = StatusById;\n\n @Input() enableInfiniteScroll: boolean;\n @Input() useSticky = true;\n\n get hasMoreData(): boolean {\n return this.data.length < 100;\n }\n\n @ViewChild(MatExpansionPanel, {static: true}) filterExpansionPanel: MatExpansionPanel;\n @ViewChild(IonInfiniteScroll) infiniteScroll: IonInfiniteScroll;\n\n get dataService(): InMemoryEntitiesService<Referential>{\n return this._dataSource.dataService as InMemoryEntitiesService<Referential>\n }\n\n constructor(injector: Injector,\n protected validatorService: AppValidatorService,\n protected formBuilder: FormBuilder,\n protected cd: ChangeDetectorRef\n ) {\n super(injector, [\n ...RESERVED_START_COLUMNS,\n 'label',\n 'name',\n 'levelId',\n 'statusId',\n 'updateDate',\n 'comments',\n ...RESERVED_END_COLUMNS\n ],\n new EntitiesTableDataSource(Referential, new InMemoryEntitiesService(Referential, ReferentialFilter, {\n sortByReplacement: {id: 'id'}\n }), validatorService, {\n suppressErrors: false\n }),\n null);\n\n // Works with true and false\n this.enableInfiniteScroll = this.mobile;\n\n this.autoLoad = false;\n this.inlineEdition = true;\n this.i18nColumnPrefix = 'TABLE.TESTING.';\n\n this.confirmBeforeDelete = true;\n this.confirmBeforeCancel = false;\n this.undoableDeletion = false;\n this.saveBeforeDelete = false;\n\n this.saveBeforeSort = true;\n this.saveBeforeFilter = true;\n this.propagateRowError = true;\n\n this.filterForm = formBuilder.group({\n searchText: [null]\n });\n\n this.onStartEditingRow.subscribe(row => {\n row.validator.patchValue({entityName: 'TestVO'}, {emitEvent: false});\n });\n }\n\n ngOnInit() {\n super.ngOnInit();\n\n // Update filter when changes\n this.registerSubscription(\n this.filterForm.valueChanges\n .pipe(\n debounceTime(250),\n filter(() => this.filterForm.valid),\n tap(value => {\n const filter = ReferentialFilter.fromObject(value);\n this.filterCriteriaCount = filter.countNotEmptyCriteria();\n this.markForCheck();\n // Applying the filter\n this.setFilter(filter, {emitEvent: false});\n }),\n // Save filter in settings (after a debounce time)\n debounceTime(500),\n tap(json => this.settings.savePageSetting(this.settingsId, json, 'filter'))\n )\n .subscribe()\n );\n\n this.registerAutocompleteField('level', {\n items: [\n {id: 1, label: 'A', name: 'item A'},\n {id: 1, label: 'B', name: 'item B'}\n ],\n mobile: this.mobile\n });\n\n this.registerSubscription(\n this.onRefresh.subscribe(() => {\n this.filterForm.markAsUntouched();\n this.filterForm.markAsPristine();\n }));\n\n this.markAsReady();\n }\n\n ngAfterViewInit() {\n super.ngAfterViewInit();\n\n // Restore filter from settings\n this.restoreFilter();\n\n // Load data\n this.load();\n }\n\n ngOnDestroy() {\n console.debug('[test-table] Destroying table...');\n super.ngOnDestroy();\n this.stopTimer();\n //this.dataService.stop();\n }\n\n protected restoreFilter() {\n const json = this.settings.getPageSettings(this.settingsId, 'filter');\n console.debug('[table-test] Restoring filter from settings...', json);\n\n if (json) {\n const filter = ReferentialFilter.fromObject(json);\n this.filterForm.patchValue(json, {emitEvent: false});\n this.filterCriteriaCount = filter.countNotEmptyCriteria();\n this.setFilter(filter, {emitEvent: false});\n this.markForCheck();\n }\n }\n\n toggleTimer() {\n if (isNotNil(this.timer)) this.stopTimer();\n else this.startTimer();\n }\n\n load() {\n console.debug('[test-table] Updating data...');\n this.markAsLoading();\n\n if (isNil(this.data)) {\n this.data = this.generateData(0, TableTestPage.maxRowCount);\n }\n this.dataService.value = this.data;\n\n this.onRefresh.emit();\n }\n\n async fetchMore(event?: CustomEvent & { target?: EventTarget & { complete?: () => void }}) {\n console.debug('[table-test] Loading more...', event);\n const fetched = await this._dataSource.fetchMore();\n\n if (fetched && event?.target && event.target.complete) {\n // Wait end of load\n await this.waitIdle();\n // Mark target event as completed (e.g. IonRefresher)\n event.target.complete();\n }\n }\n\n async save(opts?: { keepEditing?: boolean }): Promise<boolean> {\n const saved = await super.save(opts);\n if (saved) {\n // Update source data\n this.data = this.dataService.value;\n }\n return saved;\n }\n\n clearControlValue(event: UIEvent, formControl: AbstractControl): boolean {\n if (event) event.stopPropagation(); // Avoid to enter input the field\n formControl.setValue(null);\n return false;\n }\n\n applyFilterAndClosePanel(event?: UIEvent) {\n this.defaultPageSize = DEFAULT_PAGE_SIZE;\n this.onRefresh.emit(event);\n this.filterExpansionPanel.close();\n }\n\n resetFilter(event?: UIEvent) {\n this.filterForm.reset({}, {emitEvent: true});\n this.setFilter(ReferentialFilter.fromObject({}), {emitEvent: true});\n this.filterExpansionPanel.close();\n }\n\n startTimer() {\n this.stopTimer();\n this.timer = setInterval(() => {\n this.data = null; // Reset\n this.load();\n }, 500);\n }\n\n stopTimer() {\n if (isNotNil(this.timer)) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n protected generateData(offset?: number, size?: number, ): Referential[] {\n offset = offset || 0;\n size = size || 100;\n\n const result = new Array<Referential>();\n for (let i = 0; i < size; i++) {\n const id = i + 1 + offset;\n const item = Referential.fromObject({\n id,\n label: 'CODE-' + id,\n name: 'Name #' + id,\n levelId: {id: 1, label: 'A', name: 'Item A'},\n statusId: StatusIds.ENABLE,\n comments: 'My comment #' + id,\n creationDate: fromUnixMsTimestamp(Date.now() - i * 60 * 1000),\n updateDate: fromUnixMsTimestamp(Date.now() - i * 60 * 1000),\n entityName: 'TestVO'\n });\n result.push(item);\n }\n\n return result;\n }\n\n protected markForCheck() {\n this.cd.markForCheck();\n }\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {CoreModule} from '../../core.module';\nimport {TableTestPage} from './table.testing';\nimport {SharedModule} from '../../../shared/shared.module';\n\n\n@NgModule({\n imports: [\n CommonModule,\n SharedModule,\n CoreModule,\n TranslateModule.forChild()\n ],\n declarations: [\n TableTestPage\n ],\n exports: [\n TableTestPage,\n TranslateModule\n ]\n})\nexport class TableTestingModule {\n}\n","import {Component} from '@angular/core';\nimport {PopoverController} from '@ionic/angular';\nimport {TextPopover, TextPopoverOptions} from '../text-popover.component';\n\n@Component({\n selector: 'text-popover-testing',\n templateUrl: 'text-popover.testing.html'\n})\nexport class TextPopoverTestingPage {\n\n constructor(\n private popoverController: PopoverController\n ) {\n }\n\n async showPopover(event: UIEvent, opts?: Partial<TextPopoverOptions>) {\n const modal = await this.popoverController.create({\n component: TextPopover,\n componentProps: <TextPopoverOptions>{\n title: 'modalTitle',\n placeholder: 'your text',\n ...opts\n },\n backdropDismiss: false,\n keyboardClose: false,\n event,\n translucent: true,\n cssClass: 'popover-large',\n });\n\n await modal.present();\n const { data } = await modal.onDidDismiss();\n\n if (data) {\n console.info('Popover result: ', data);\n }\n }\n}\n","import {NgModule} from '@angular/core';\nimport {RouterModule, Routes} from '@angular/router';\nimport {IonicModule} from '@ionic/angular';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {TextPopoverTestingPage} from './text-popover.testing';\n\nconst routes: Routes = [\n {\n path: 'text-popover',\n pathMatch: 'full',\n component: TextPopoverTestingPage\n }\n];\n\n@NgModule({\n imports: [\n CommonModule,\n IonicModule,\n TranslateModule.forChild(),\n RouterModule.forChild(routes)\n ],\n declarations: [\n TextPopoverTestingPage\n ],\n exports: [\n RouterModule,\n TextPopoverTestingPage\n ]\n})\nexport class TextPopoverTestingModule {\n}\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {TranslateModule} from '@ngx-translate/core';\nimport {RouterModule, Routes} from '@angular/router';\nimport {TableTestingModule} from './table/testing/table.testing.module';\nimport {TableTestPage} from './table/testing/table.testing';\nimport {TextPopoverTestingModule} from './text-popover/testing/text-popover.testing.module';\nimport {TextPopoverTestingPage} from './text-popover/testing/text-popover.testing';\nimport {TestingPage} from '../shared/testing/tests.page';\n\nexport const CORE_TESTING_PAGES: TestingPage[] = [\n {label: 'Core components', divider: true},\n {label: 'Table', page: '/testing/core/table'},\n {label: 'Text popover', page: '/testing/core/text-popover'}\n];\n\nconst routes: Routes = [\n {\n path: '',\n pathMatch: 'full',\n redirectTo: 'table'\n },\n {\n path: 'table',\n pathMatch: 'full',\n component: TableTestPage\n },\n {\n path: 'text-popover',\n pathMatch: 'full',\n component: TextPopoverTestingPage\n }\n];\n\n@NgModule({\n imports: [\n CommonModule,\n TranslateModule.forChild(),\n RouterModule.forChild(routes),\n\n // Sub modules\n TableTestingModule,\n TextPopoverTestingModule\n ],\n exports: [\n RouterModule,\n\n // Sub modules\n TableTestingModule,\n TextPopoverTestingModule\n ]\n})\nexport class CoreTestingModule {\n}\n","import {Component, Inject, ViewChild} from '@angular/core';\nimport {JobProgressionIcon, JobProgressionOptions} from '../progression/job-progression.icon';\nimport {JobProgression} from '../job.model';\nimport {APP_JOB_PROGRESSION_SERVICE, JobProgressionService} from '../job.service';\n\n@Component({\n selector: 'job-progression-testing',\n templateUrl: 'job-progression.testing.html'\n})\nexport class JobProgressionTestingPage {\n\n @ViewChild('icon') jobProgressionIcon: JobProgressionIcon;\n\n jobId = 0;\n job: JobProgression = null;\n options = <JobProgressionOptions>{\n autoHide: true\n };\n\n constructor(\n @Inject(APP_JOB_PROGRESSION_SERVICE) protected jobProgressionService: JobProgressionService) {\n }\n\n incrementJob(value: number) {\n this.job = this.job || this.createJob();\n this.job.current += value || 0;\n this.job.message = `Fake progression (very long message very long message very long message very long message) ${this.job.current}/100`\n\n if (this.job.current > this.job.total) {\n this.jobProgressionService.removeJob(this.job.id);\n this.job.current = 0;\n this.job = null; // Forget the job\n }\n this.jobProgressionIcon.updateValue();\n }\n\n addJob() {\n this.job = this.createJob();\n }\n\n private createJob(): JobProgression {\n const job = new JobProgression();\n job.id = ++this.jobId;\n job.name = 'test';\n job.current = 0;\n job.total = 100;\n this.jobProgressionService.addJob(job.id, job);\n return job;\n }\n}\n\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { JobProgressionTestingPage } from './job-progression.testing';\nimport { SharedModule } from '../../../shared/shared.module';\nimport { JobModule } from '../job.module';\n\n@NgModule({\n imports: [\n CommonModule,\n TranslateModule.forChild(),\n SharedModule,\n JobModule\n ],\n declarations: [\n JobProgressionTestingPage\n ],\n exports: [\n JobProgressionTestingPage\n ]\n})\nexport class JobTestingModule {}\n","// @dynamic\nimport {EntityClass} from '../../../core/services/model/entity.decorators';\nimport {Entity, EntityAsObjectOptions} from '../../../core/services/model/entity.model';\nimport {Moment} from 'moment';\nimport {IconRef} from '../../../shared/types';\nimport {fromDateISOString, toDateISOString} from '../../../shared/dates';\nimport {EventLevel, IUserEvent, IUserEventFilter, IUserEventAction} from '../user-event.model';\nimport {EntityFilter} from '../../../core/services/model/filter.model';\nimport {FilterFn} from '../../../shared/services/entity-service.class';\nimport {isNil, isNotEmptyArray, isNotNil} from '../../../shared/functions';\nimport {StoreObject} from '@apollo/client/core';\n\n// @dynamic\n@EntityClass({typename: 'UserEventTestVO'})\nexport class UserEventTest extends Entity<UserEventTest> implements IUserEvent<UserEventTest> {\n\n static fromObject: (source: any, opts?: any) => UserEventTest;\n\n type: string;\n level: EventLevel;\n issuer: string;\n recipient: string;\n updateDate: Moment;\n creationDate: Moment;\n readDate: Moment;\n\n message: string | undefined;\n content: string | any;\n hash: string;\n signature: string;\n readSignature: string;\n\n avatar?: string;\n avatarIcon?: IconRef;\n icon?: IconRef;\n\n actions?: IUserEventAction[];\n\n constructor() {\n super(UserEventTest.TYPENAME);\n }\n\n asObject(opts?: EntityAsObjectOptions): any {\n const target = super.asObject(opts);\n target.creationDate = toDateISOString(this.creationDate);\n target.readDate = toDateISOString(this.readDate);\n\n // Serialize content\n if (typeof target.content === 'object') {\n target.content = JSON.stringify(target.content);\n }\n\n delete target.avatar;\n delete target.avatarIcon;\n delete target.icon;\n delete target.actions;\n\n return target;\n }\n\n fromObject(source: any) {\n Object.assign(this, source); // Copy all properties\n super.fromObject(source);\n this.creationDate = fromDateISOString(source.creationDate);\n this.readDate = fromDateISOString(source.readDate);\n\n try {\n // Deserialize content\n if (typeof source.content === 'string' && source.content.startsWith('{')) {\n this.content = JSON.parse(source.content);\n }\n\n // Deserialize content.context\n if (this.content && typeof this.content.context === 'string' && this.content.context.startsWith('{')) {\n this.content.context = JSON.parse(this.content.context);\n }\n } catch (err) {\n console.error('Error during UserEvent deserialization', err);\n }\n }\n}\n\n// @dynamic\n@EntityClass({typename: 'UserEventTestFilterVO'})\nexport class UserEventTestFilter extends EntityFilter<UserEventTestFilter, UserEventTest> implements IUserEventFilter<UserEventTest> {\n\n static fromObject: (source: any, opts?: any) => UserEventTestFilter;\n\n types: string[] = [];\n levels: EventLevel[] = [];\n issuers: string[] = [];\n recipients: string[] = [];\n startDate: Moment = null;\n excludeRead: boolean = false;\n\n fromObject(source: any, opts?: any) {\n super.fromObject(source, opts);\n this.types = source.types || [];\n this.levels = source.levels || [];\n this.issuers = source.issuers || [];\n this.recipients = source.recipients || [];\n this.startDate = fromDateISOString(source.startDate);\n this.excludeRead = source.excludeRead || false;\n }\n\n protected buildFilter(): FilterFn<UserEventTest>[] {\n const filterFns = super.buildFilter();\n\n if (isNotEmptyArray(this.types)) {\n filterFns.push(t => this.types.includes(t.type));\n }\n if (isNotEmptyArray(this.levels)) {\n filterFns.push(t => this.levels.includes(t.level));\n }\n if (isNotEmptyArray(this.issuers)) {\n filterFns.push(t => this.issuers.includes(t.issuer));\n }\n if (isNotEmptyArray(this.recipients)) {\n filterFns.push(t => this.recipients.includes(t.recipient));\n }\n\n if (isNotNil(this.startDate)) {\n filterFns.push(t => this.startDate.isSameOrBefore(t.creationDate))\n }\n if (this.excludeRead === true) {\n filterFns.push(t => isNil(t.readSignature)); // todo or t.signature ?\n }\n\n return filterFns;\n }\n\n asObject(opts?: EntityAsObjectOptions): StoreObject {\n const target = super.asObject(opts);\n return target;\n }\n}\n","import {Inject, Injectable, Optional} from '@angular/core';\nimport {AbstractUserEventService, UserEventLoadOptions, UserEventWatchOptions} from '../user-event.service';\nimport {BehaviorSubject, Observable, Subject} from 'rxjs';\nimport {GraphqlService} from '../../../core/graphql/graphql.service';\nimport {AccountService} from '../../../core/services/account.service';\nimport {NetworkService} from '../../../core/services/network.service';\nimport {TranslateService} from '@ngx-translate/core';\nimport {Environment, ENVIRONMENT} from '../../../../environments/environment.class';\nimport {FetchPolicy} from '@apollo/client/core';\nimport {EntityServiceLoadOptions, LoadResult} from '../../../shared/services/entity-service.class';\nimport {SortDirection} from '@angular/material/sort';\nimport {EntityUtils} from '../../../core/services/model/entity.model';\nimport {map} from 'rxjs/operators';\nimport {UserEventTest, UserEventTestFilter} from './user-event.testing.model';\n\n@Injectable()\nexport class UserEventTestService extends AbstractUserEventService<UserEventTest, UserEventTestFilter> {\n\n private $userEvents = new BehaviorSubject<UserEventTest[]>([]);\n private $newUserEvents = new Subject<UserEventTest[]>();\n\n constructor(\n protected graphql: GraphqlService,\n protected accountService: AccountService,\n protected network: NetworkService,\n protected translate: TranslateService,\n @Optional() @Inject(ENVIRONMENT) protected environment: Environment\n ) {\n super(graphql, accountService, network, translate, {\n queries: {\n loadAll: null,\n loadAllWithContent: null\n },\n production: environment?.production\n });\n }\n\n\n fromObject(source: any): UserEventTest {\n return UserEventTest.fromObject(source);\n }\n\n async add(entity: UserEventTest) {\n entity = await this.processUserEvent(entity);\n entity.id = (this.$userEvents.value?.length || 0) + 1;\n this.$userEvents.next([\n entity,\n ...this.$userEvents.value\n ]);\n this._countSubject.next((this._countSubject.value || 0) + 1);\n this.$newUserEvents.next([entity]);\n }\n\n asFilter(filter: Partial<any>): any {\n return filter;\n }\n\n count(filter: any, options?: { fetchPolicy?: FetchPolicy }): Promise<number> {\n return Promise.resolve(this.$userEvents.value?.length || 0);\n }\n\n delete(entity: any): Promise<any> {\n return Promise.resolve(undefined);\n }\n\n deleteAll(data: any[], opts?: any): Promise<any> {\n return Promise.resolve(undefined);\n }\n\n listenAllChanges(filter: any, options?: UserEventWatchOptions & { interval?: number; fetchPolicy?: FetchPolicy }): Observable<any[]> {\n return this.$newUserEvents.asObservable();\n }\n\n save(entity: any, options?: EntityServiceLoadOptions): Promise<any> {\n\n const toSave = this.$userEvents.value?.find(value => value.id == entity?.id);\n Object.assign(toSave, entity);\n\n return entity;\n }\n\n async saveAll(data: any[], opts?: any): Promise<any[]> {\n\n for (const entity of (data || [])) {\n await this.save(entity);\n }\n\n return this.$userEvents.toPromise();\n }\n\n watchAll(offset: number, size: number, sortBy?: string, sortDirection?: SortDirection, filter?: Partial<any>, opts?: UserEventWatchOptions): Observable<LoadResult<any>> {\n return this.$userEvents.pipe(\n map(userEvents => {\n let data = (userEvents || []).slice(offset||0, offset + size);\n const total = this.$userEvents.value?.length || 0;\n\n const res = <LoadResult<UserEventTest>>{ data, total };\n\n // Must re-order because of listenChanges result will add new event at the end\n data = EntityUtils.sort(data, sortBy, sortDirection);\n\n // Add fetch more\n const nextOffset = offset + data.length;\n if (nextOffset < res.total) {\n res.fetchMore = (_) => this.loadAll(nextOffset, size, sortBy, sortDirection, filter,\n {...opts, fetchPolicy: <FetchPolicy>'no-cache'} as unknown as UserEventLoadOptions\n );\n }\n\n return res;\n })\n )\n\n }\n\n loadAll(offset: number, size: number, sortBy?: string, sortDirection?: SortDirection, filter?: Partial<any>,\n opts?: UserEventLoadOptions): Promise<LoadResult<any>> {\n let data = (this.$userEvents.value || []).slice(offset||0, offset + size);\n const total = this.$userEvents.value?.length || 0;\n\n const res = <LoadResult<UserEventTest>>{ data, total };\n\n // Must re-order because of listenChanges result will add new event at the end\n data = EntityUtils.sort(data, sortBy, sortDirection);\n\n // Add fetch more\n const nextOffset = offset + data.length;\n if (nextOffset < res.total) {\n res.fetchMore = (_) => this.loadAll(nextOffset, size, sortBy, sortDirection, filter,\n {...opts, fetchPolicy: <FetchPolicy>'no-cache'} as unknown as UserEventLoadOptions\n );\n }\n\n return Promise.resolve(res);\n }\n}\n","import {Component, Inject, OnDestroy, ViewChild} from '@angular/core';\nimport {APP_USER_EVENT_SERVICE} from '../user-event.service';\nimport {IUserEventAction} from '../user-event.model';\nimport {Router} from '@angular/router';\nimport {Alerts} from '../../../shared/alerts';\nimport {AlertController} from '@ionic/angular';\nimport {TranslateService} from '@ngx-translate/core';\nimport * as momentImported from 'moment';\nimport {UserEventTestService} from './user-event.testing.service';\nimport {UserEventNotificationIcon} from '../notification/user-event-notification.icon';\nimport {Subscription, timer} from 'rxjs';\nimport {UserEventTest} from './user-event.testing.model';\n\nconst moment = momentImported;\n\n@Component({\n selector: 'job-progression-testing',\n templateUrl: 'user-event.testing.html'\n})\nexport class UserEventTestingPage implements OnDestroy{\n\n private _timerSubscription: Subscription;\n\n @ViewChild('notification') notification: UserEventNotificationIcon;\n\n get timerStarted(): boolean {\n return !!this._timerSubscription;\n }\n\n constructor(\n @Inject(APP_USER_EVENT_SERVICE) protected userEventService: UserEventTestService,\n protected router: Router,\n protected alertController: AlertController,\n protected translateService: TranslateService\n ) {\n\n userEventService.registerListener({\n accept: (userEvent: UserEventTest) => { return true },\n onReceived: (userEvent: UserEventTest) => {\n this.customize(userEvent);\n return userEvent\n }\n })\n userEventService.registerListener({\n accept: (userEvent: UserEventTest) => { return userEvent.level == \"DEBUG\" },\n onRead: (userEvent: UserEventTest) => { this.showMessage(\"debug message read \")}\n })\n }\n\n ngOnDestroy() {\n this.stopTimer();\n }\n\n protected customize(userEvent: UserEventTest) {\n\n // Choose avatarIcon\n switch (userEvent.level) {\n case 'ERROR':\n userEvent.avatarIcon = { icon: 'close-outline', color: 'danger' };\n break;\n case 'WARNING':\n userEvent.avatarIcon = { icon: 'warning-outline', color: 'warning' };\n break;\n case 'INFO':\n userEvent.avatarIcon = { icon: 'information-circle-outline' };\n break;\n case 'DEBUG':\n userEvent.avatarIcon = { icon: 'cog', color: \"medium\" };\n break;\n }\n\n // Choose icon\n switch (userEvent.type) {\n case 'message':\n userEvent.icon = { matIcon: 'inbox', color: 'accent' };\n break;\n case 'upload':\n userEvent.icon = { matIcon: 'file_upload' };\n break;\n case 'download':\n userEvent.icon = { matIcon: 'file_download' };\n break;\n }\n\n }\n\n addNotification() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'message',\n level: 'INFO',\n message: 'message test message test message test message test message test message test message test message test',\n creationDate: moment(),\n }\n ));\n }\n\n addError() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'upload',\n level: 'ERROR',\n message: 'message error',\n creationDate: moment(),\n }\n ));\n }\n\n addWarning() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'download',\n level: 'WARNING',\n message: 'message warning',\n creationDate: moment(),\n }\n ));\n }\n\n addDebug() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'debug',\n level: 'DEBUG',\n message: 'message DEBUG',\n creationDate: moment(),\n }\n ));\n }\n\n addNotificationWithLink() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'message',\n level: 'INFO',\n message: 'message with link',\n creationDate: moment(),\n actions: [<IUserEventAction>{\n name: 'click here',\n iconRef: {\n icon: 'arrow-forward-outline'\n },\n executeAction: event => { this.router.navigateByUrl('/') }\n }]\n }\n ));\n }\n\n addNotificationWithAction() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'message',\n level: 'INFO',\n message: 'message with action',\n creationDate: moment(),\n actions: [\n <IUserEventAction>{\n name: 'click here',\n iconRef: {\n icon: 'arrow-forward-outline',\n color: 'warning'\n },\n executeAction: event => { this.showMessage('action 1') }\n },\n <IUserEventAction>{\n name: 'click here 2',\n iconRef: {\n matIcon: 'settings_applications',\n color: 'secondary'\n },\n executeAction: event => { this.showMessage('action 2') }\n }\n ]\n }\n ));\n }\n\n addMany(count?: number) {\n count = count || 20;\n for (let i=0; i < count; i++) {\n this.addRandom(i);\n }\n }\n\n startTimer(period?: number) {\n this._timerSubscription?.unsubscribe();\n\n period = period || 1000;\n let counter = 0;\n\n this._timerSubscription = timer(period, period)\n .subscribe(() => {\n this.addRandom(counter);\n counter++;\n });\n }\n\n stopTimer() {\n this._timerSubscription?.unsubscribe();\n this._timerSubscription = null;\n }\n\n addRandom(value: number) {\n switch (value % 6) {\n case 0:\n this.addNotification();\n break;\n case 1:\n this.addError()\n break;\n case 2:\n this.addDebug()\n break;\n case 3:\n this.addNotificationWithLink()\n break;\n case 4:\n this.addNotificationWithAction()\n break;\n case 5:\n this.addNotificationWithDefaultAction()\n break;\n }\n }\n\n addNotificationWithDefaultAction() {\n this.userEventService.add(UserEventTest.fromObject({\n issuer: 'system',\n recipient: 'me',\n type: 'message',\n level: 'INFO',\n message: 'message with action',\n creationDate: moment(),\n actions: [\n <IUserEventAction>{\n default: true,\n name: 'default',\n executeAction: event => { this.showMessage('default action') }\n }\n ]\n }\n ));\n }\n\n protected showMessage(text: string): Promise<void> {\n return Alerts.showError(text, this.alertController, this.translateService);\n }\n}\n\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { SharedModule } from '../../../shared/shared.module';\nimport { UserEventModule } from '../user-event.module';\nimport { UserEventTestingPage } from './user-event.testing';\n\n@NgModule({\n imports: [\n CommonModule,\n TranslateModule.forChild(),\n SharedModule,\n UserEventModule\n ],\n declarations: [\n UserEventTestingPage\n ],\n exports: [\n UserEventTestingPage\n ]\n})\nexport class UserEventTestingModule {}\n","import { TestingPage } from '../shared/testing/tests.page';\nimport { RouterModule, Routes } from '@angular/router';\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { JobTestingModule } from './job/testing/job.testing.module';\nimport { JobProgressionTestingPage } from './job/testing/job-progression.testing';\nimport { UserEventTestingModule } from './user-event/testing/user-event.testing.module';\nimport { UserEventTestingPage } from './user-event/testing/user-event.testing';\n\nexport const SOCIAL_TESTING_PAGES: TestingPage[] = [\n {label: 'Social components', divider: true},\n {label: 'User event', page: '/testing/social/user-event'},\n {label: 'Job progression', page: '/testing/social/job-progression'}\n];\n\nconst routes: Routes = [\n {\n path: 'job-progression',\n pathMatch: 'full',\n component: JobProgressionTestingPage\n },\n {\n path: 'user-event',\n pathMatch: 'full',\n component: UserEventTestingPage\n },\n];\n\n@NgModule({\n imports: [\n CommonModule,\n TranslateModule.forChild(),\n RouterModule.forChild(routes),\n\n JobTestingModule,\n UserEventTestingModule\n ],\n})\nexport class SocialTestingModule {}\n","import {Injectable} from '@angular/core';\nimport {IJobProgressionService} from '../job.service';\nimport {FetchPolicy} from '@apollo/client/core';\nimport {BehaviorSubject, interval, Observable, of} from 'rxjs';\nimport {JobProgression} from '../job.model';\nimport {map, take} from 'rxjs/operators';\n\n@Injectable()\nexport class JobProgressionTestService implements IJobProgressionService {\n\n private jobsSubject = new BehaviorSubject<JobProgression[]>([]);\n\n addJob(id: number, job?: JobProgression) {\n const exists = this.jobsSubject.value.some(j => j.id === id);\n if (!exists) {\n job = job || new JobProgression(id);\n this.jobsSubject.next([...this.jobsSubject.value, job]);\n }\n }\n\n removeJob(id: number) {\n const jobs = this.jobsSubject.value;\n const index = jobs.findIndex(j => j.id === id);\n if (index !== -1) {\n jobs.splice(index, 1);\n this.jobsSubject.next(jobs);\n }\n }\n\n watchAll(): Observable<JobProgression[]> {\n return this.jobsSubject.asObservable();\n }\n\n listenChanges(id: number, options?: { interval?: number; fetchPolicy?: FetchPolicy }): Observable<JobProgression> {\n\n return interval(100).pipe(\n take(111),\n map(value => {\n if (value <= 10) {\n return <JobProgression>{\n id: id,\n name: `Job #${id}`,\n current: 0,\n total: 0,\n message: `Progression pending`\n };\n }\n value = value - 10;\n return <JobProgression>{\n id: id,\n name: `Job #${id}`,\n current: value,\n total: 100,\n message: `Progression ${value}/100`\n };\n })\n );\n }\n\n}\n","import {Observable} from 'rxjs';\nimport {FetchPolicy, WatchQueryFetchPolicy} from '@apollo/client/core';\nimport {SortDirection} from '@angular/material/sort';\nimport {EmptyObject} from 'apollo-angular/types';\n\nexport declare interface Page {\n offset: number;\n size: number;\n sortBy?: string;\n sortDirection?: SortDirection;\n}\n\nexport declare type FetchMoreFn<R, V = EmptyObject> = (variables?: V) => Promise<R>;\n\nexport declare interface LoadResult<T> {\n data: T[];\n total?: number;\n errors?: any[];\n fetchMore?: FetchMoreFn<LoadResult<T>>;\n}\n\nexport declare type SuggestFn<T, F> = (value: any, filter?: F,\n sortBy?: string|keyof T,\n sortDirection?: SortDirection,\n opts?: {\n fetchPolicy: FetchPolicy;\n [key: string]: any;\n }) => Promise<T[] | LoadResult<T>>;\n\nexport declare interface SuggestService<T, F> {\n suggest: SuggestFn<T, F>;\n}\n\nexport declare type FilterFn<T> = (data: T) => boolean;\nexport declare type FilterFnFactory<T, F> = (filter: F) => FilterFn<T>;\n\nexport declare interface EntityServiceLoadOptions {\n fetchPolicy?: FetchPolicy;\n trash?: boolean;\n toEntity?: boolean;\n [key: string]: any;\n}\n\nexport declare interface IEntityService<\n T,\n ID = any,\n LO = EntityServiceLoadOptions> {\n\n load(\n id: ID,\n opts?: LO\n ): Promise<T>;\n\n canUserWrite(data: T, opts?: any): boolean;\n\n save(data: T, opts?: any): Promise<T>;\n\n delete(data: T, opts?: any): Promise<any>;\n\n listenChanges(id: ID, opts?: any): Observable<T | undefined>;\n}\n\nexport declare interface EntitiesServiceLoadOptions {\n fetchPolicy?: FetchPolicy;\n trash?: boolean;\n withTotal?: boolean;\n toEntity?: boolean;\n [key: string]: any;\n}\n\nexport declare interface EntitiesServiceWatchOptions {\n fetchPolicy?: WatchQueryFetchPolicy;\n trash?: boolean;\n withTotal?: boolean;\n toEntity?: boolean;\n [key: string]: any;\n}\n\nexport declare interface IEntitiesService<T, F, O extends EntitiesServiceWatchOptions = EntitiesServiceWatchOptions> {\n\n watchAll(\n offset: number,\n size: number,\n sortBy?: string,\n sortDirection?: SortDirection,\n filter?: Partial<F>,\n options?: O\n ): Observable<LoadResult<T>>;\n\n // TODO\n /*watchPage(\n page: Page<T>,\n filter?: F,\n options?: O\n ): Observable<LoadResult<T>>;*/\n\n saveAll(data: T[], opts?: any): Promise<T[]>;\n\n deleteAll(data: T[], opts?: any): Promise<any>;\n\n asFilter(filter: Partial<F>): F;\n}\n\nexport declare type LoadResultByPageFn<T> = (offset: number, size: number) => Promise<LoadResult<T>>;\n\nexport interface IEntityFullService<T, ID, F, O extends EntitiesServiceWatchOptions & EntityServiceLoadOptions>\n extends IEntityService<T, ID, O>, IEntitiesService<T, F, O> {\n}\n\nexport function mergeLoadResult<T>(res1: LoadResult<T>, res2: LoadResult<T>): LoadResult<T> {\n return {\n data : (res1.data || []).concat(...res2.data),\n total: ((res1.total || res1.data?.length || 0) + (res2.total || res2.data?.length || 0))\n };\n}\n"]}
|