@c8y/ngx-components 1022.13.0 → 1022.21.3
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/alarms/alarms.helper.d.ts.map +1 -1
- package/auth-configuration/sso-configuration/templates/template.component.d.ts +1 -1
- package/core/asset-property/asset-property.model.d.ts +0 -6
- package/core/asset-property/asset-property.model.d.ts.map +1 -1
- package/core/authentication/authentication.module.d.ts.map +1 -1
- package/core/authentication/new-password.component.d.ts +3 -2
- package/core/authentication/new-password.component.d.ts.map +1 -1
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts.map +1 -1
- package/core/drop-area/drop-area.component.d.ts +2 -0
- package/core/drop-area/drop-area.component.d.ts.map +1 -1
- package/core/dynamic-forms/file/file.type.component.d.ts.map +1 -1
- package/core/modal/modal.module.d.ts.map +1 -1
- package/core/modal/modal.service.d.ts +1 -0
- package/core/modal/modal.service.d.ts.map +1 -1
- package/core/plugins/plugins.module.d.ts.map +1 -1
- package/core/plugins/plugins.service.d.ts +1 -2
- package/core/plugins/plugins.service.d.ts.map +1 -1
- package/core/select/select.component.d.ts.map +1 -1
- package/core/user/user-edit-modal.component.d.ts +1 -0
- package/core/user/user-edit-modal.component.d.ts.map +1 -1
- package/core/user/user-edit.component.d.ts +4 -1
- package/core/user/user-edit.component.d.ts.map +1 -1
- package/datapoint-explorer/datapoint-explorer.module.d.ts +2 -0
- package/datapoint-explorer/datapoint-explorer.module.d.ts.map +1 -1
- package/datapoint-explorer/devicemanagement/c8y-ngx-components-datapoint-explorer-devicemanagement.d.ts.map +1 -0
- package/datapoint-explorer/devicemanagement/index.d.ts +2 -0
- package/datapoint-explorer/devicemanagement/index.d.ts.map +1 -0
- package/datapoint-explorer/view/datapoint-explorer.component.d.ts +6 -3
- package/datapoint-explorer/view/datapoint-explorer.component.d.ts.map +1 -1
- package/datapoint-explorer/view/datapoint-explorer.model.d.ts +8 -0
- package/datapoint-explorer/view/datapoint-explorer.model.d.ts.map +1 -0
- package/datapoint-explorer/view/index.d.ts +1 -0
- package/datapoint-explorer/view/index.d.ts.map +1 -1
- package/device-list/devices.breadcrumb-factory.d.ts +1 -0
- package/device-list/devices.breadcrumb-factory.d.ts.map +1 -1
- package/device-profile/add-device-profile.component.d.ts +1 -1
- package/device-profile/add-device-profile.component.d.ts.map +1 -1
- package/device-profile/device-profile-list.component.d.ts +1 -1
- package/device-profile/device-profile-list.component.d.ts.map +1 -1
- package/device-profile/device-profile.component.d.ts +1 -1
- package/device-profile/device-profile.component.d.ts.map +1 -1
- package/device-profile/device-profile.module.d.ts +17 -17
- package/device-profile/device-profile.module.d.ts.map +1 -1
- package/device-profile/device-tab-profile/device-profile-item-list.component.d.ts +1 -1
- package/device-profile/device-tab-profile/device-profile-item-list.component.d.ts.map +1 -1
- package/device-profile/device-tab-profile/device-tab-profile-detail.component.d.ts +1 -1
- package/device-profile/device-tab-profile/device-tab-profile-detail.component.d.ts.map +1 -1
- package/device-profile/device-tab-profile/device-tab-profile.component.d.ts +1 -1
- package/device-profile/device-tab-profile/device-tab-profile.component.d.ts.map +1 -1
- package/device-profile/select-configuration-modal.component.d.ts +1 -1
- package/device-profile/select-configuration-modal.component.d.ts.map +1 -1
- package/device-provisioned-certificates/device-tab-provisioned-certificates.component.d.ts +4 -2
- package/device-provisioned-certificates/device-tab-provisioned-certificates.component.d.ts.map +1 -1
- package/device-shell/command-templates/command-templates.component.d.ts +1 -1
- package/device-shell/command-templates/command-templates.component.d.ts.map +1 -1
- package/device-shell/command-templates/command-templates.directive.d.ts +1 -1
- package/device-shell/command-templates/command-templates.directive.d.ts.map +1 -1
- package/device-shell/command-templates/command-templates.module.d.ts +1 -1
- package/device-shell/shell/shell.component.d.ts +1 -1
- package/device-shell/shell/shell.component.d.ts.map +1 -1
- package/device-shell/shell/shell.module.d.ts +7 -7
- package/diagnostics/diagnostics.component.d.ts +1 -1
- package/diagnostics/diagnostics.component.d.ts.map +1 -1
- package/diagnostics/diagnostics.module.d.ts +8 -8
- package/diagnostics/diagnostics.module.d.ts.map +1 -1
- package/echart/services/chart-realtime.service.d.ts +2 -0
- package/echart/services/chart-realtime.service.d.ts.map +1 -1
- package/echart/services/echarts-options.service.d.ts +4 -4
- package/echart/services/echarts-options.service.d.ts.map +1 -1
- package/events/c8y-ngx-components-events.d.ts.map +1 -0
- package/events/events-timeline/c8y-ngx-components-events-events-timeline.d.ts.map +1 -0
- package/events/events-timeline/events-timeline.component.d.ts +19 -0
- package/events/events-timeline/events-timeline.component.d.ts.map +1 -0
- package/events/events-timeline/index.d.ts +2 -0
- package/events/events-timeline/index.d.ts.map +1 -0
- package/events/events.model.d.ts +6 -0
- package/events/events.model.d.ts.map +1 -0
- package/events/events.service.d.ts +10 -0
- package/events/events.service.d.ts.map +1 -0
- package/events/index.d.ts +3 -0
- package/events/index.d.ts.map +1 -0
- package/fesm2022/c8y-ngx-components-alarms.mjs +2 -1
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-auth-configuration.mjs +2 -2
- package/fesm2022/c8y-ngx-components-auth-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-devicemanagement.mjs +38 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer-devicemanagement.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +143 -142
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-list.mjs +10 -3
- package/fesm2022/c8y-ngx-components-device-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-profile.mjs +126 -49
- package/fesm2022/c8y-ngx-components-device-profile.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-provisioned-certificates.mjs +44 -12
- package/fesm2022/c8y-ngx-components-device-provisioned-certificates.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-shell.mjs +31 -22
- package/fesm2022/c8y-ngx-components-device-shell.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-diagnostics.mjs +36 -19
- package/fesm2022/c8y-ngx-components-diagnostics.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +53 -17
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-events-events-timeline.mjs +45 -0
- package/fesm2022/c8y-ngx-components-events-events-timeline.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-events.mjs +44 -0
- package/fesm2022/c8y-ngx-components-events.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-from-single.mjs +8 -14
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-from-single.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-list-item.mjs +49 -49
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-list-item.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-scheduler.mjs +27 -14
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-scheduler.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-stepper.mjs +27 -33
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-stepper.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operations-list.mjs +51 -39
- package/fesm2022/c8y-ngx-components-operations-bulk-operations-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operations-stepper-container.mjs +10 -8
- package/fesm2022/c8y-ngx-components-operations-bulk-operations-stepper-container.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-create-bulk-operation-details.mjs +16 -11
- package/fesm2022/c8y-ngx-components-operations-create-bulk-operation-details.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-device-selector.mjs +8 -11
- package/fesm2022/c8y-ngx-components-operations-device-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operation-details.mjs +25 -21
- package/fesm2022/c8y-ngx-components-operations-operation-details.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operation-summary.mjs +7 -9
- package/fesm2022/c8y-ngx-components-operations-operation-summary.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-list-item-details.mjs +31 -31
- package/fesm2022/c8y-ngx-components-operations-operations-list-item-details.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-list.mjs +3 -3
- package/fesm2022/c8y-ngx-components-operations-operations-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-timeline.mjs +33 -13
- package/fesm2022/c8y-ngx-components-operations-operations-timeline.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-status-filter.mjs +19 -13
- package/fesm2022/c8y-ngx-components-operations-status-filter.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-configuration.mjs +40 -36
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-device-profile.mjs +60 -41
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-device-profile.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-firmware.mjs +122 -109
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-firmware.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-software.mjs +66 -41
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-software.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-frames.mjs +11 -16
- package/fesm2022/c8y-ngx-components-operations-stepper-frames.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-protocol-opcua.mjs +212 -83
- package/fesm2022/c8y-ngx-components-protocol-opcua.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs +113 -54
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-firmware.mjs +130 -62
- package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-shared.mjs +37 -28
- package/fesm2022/c8y-ngx-components-repository-shared.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-software.mjs +156 -83
- package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-services.mjs +32 -19
- package/fesm2022/c8y-ngx-components-services.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-time-context.mjs +12 -5
- package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +68 -31
- package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-upgrade-upgraded-services.mjs +16 -3
- package/fesm2022/c8y-ngx-components-upgrade-upgraded-services.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-upgrade.mjs +1 -14
- package/fesm2022/c8y-ngx-components-upgrade.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-user-roles.mjs +8 -3
- package/fesm2022/c8y-ngx-components-user-roles.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +4 -4
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +1219 -1190
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +53 -35
- package/locales/es.po +26 -5
- package/locales/fr.po +51 -30
- package/locales/ja_JP.po +90 -67
- package/locales/ko.po +26 -5
- package/locales/locales.pot +22 -13
- package/locales/nl.po +26 -5
- package/locales/pl.po +26 -5
- package/locales/pt_BR.po +26 -5
- package/locales/zh_CN.po +27 -6
- package/locales/zh_TW.po +26 -5
- package/operations/bulk-operation-from-single/bulk-operation-from-single.component.d.ts +1 -1
- package/operations/bulk-operation-from-single/bulk-operation-from-single.component.d.ts.map +1 -1
- package/operations/bulk-operation-from-single/bulk-operation-from-single.module.d.ts +3 -5
- package/operations/bulk-operation-from-single/bulk-operation-from-single.module.d.ts.map +1 -1
- package/operations/bulk-operation-list-item/bulk-operation-list-item.component.d.ts +1 -1
- package/operations/bulk-operation-list-item/bulk-operation-list-item.component.d.ts.map +1 -1
- package/operations/bulk-operation-list-item/bulk-operation-list-item.module.d.ts +1 -7
- package/operations/bulk-operation-list-item/bulk-operation-list-item.module.d.ts.map +1 -1
- package/operations/bulk-operation-list-item/bulk-operation-wrapper.component.d.ts +1 -1
- package/operations/bulk-operation-list-item/bulk-operation-wrapper.component.d.ts.map +1 -1
- package/operations/bulk-operation-list-item/modal-body-host.directive.d.ts +1 -1
- package/operations/bulk-operation-list-item/modal-body-host.directive.d.ts.map +1 -1
- package/operations/bulk-operation-list-item/modals/bulk-operations-reschedule-modal.component.d.ts +1 -1
- package/operations/bulk-operation-list-item/modals/bulk-operations-reschedule-modal.component.d.ts.map +1 -1
- package/operations/bulk-operation-scheduler/bulk-operation-scheduler.module.d.ts +6 -6
- package/operations/bulk-operation-scheduler/operation-scheduler.component.d.ts +1 -1
- package/operations/bulk-operation-scheduler/operation-scheduler.component.d.ts.map +1 -1
- package/operations/bulk-operation-stepper/base-stepper.component.d.ts +1 -1
- package/operations/bulk-operation-stepper/bulk-operation-stepper.component.d.ts +1 -1
- package/operations/bulk-operation-stepper/bulk-operation-stepper.component.d.ts.map +1 -1
- package/operations/bulk-operation-stepper/bulk-operation-stepper.module.d.ts +1 -5
- package/operations/bulk-operation-stepper/bulk-operation-stepper.module.d.ts.map +1 -1
- package/operations/bulk-operation-stepper/custom-step.directive.d.ts +1 -1
- package/operations/bulk-operation-stepper/custom-step.directive.d.ts.map +1 -1
- package/operations/bulk-operations-list/bulk-operations-list.component.d.ts +1 -1
- package/operations/bulk-operations-list/bulk-operations-list.component.d.ts.map +1 -1
- package/operations/bulk-operations-list/bulk-operations-list.module.d.ts +4 -10
- package/operations/bulk-operations-list/bulk-operations-list.module.d.ts.map +1 -1
- package/operations/bulk-operations-list/modals/bulk-operations-modal.component.d.ts +1 -1
- package/operations/bulk-operations-list/modals/bulk-operations-modal.component.d.ts.map +1 -1
- package/operations/bulk-operations-stepper-container/bulk-operations-stepper-container.component.d.ts +1 -1
- package/operations/bulk-operations-stepper-container/bulk-operations-stepper-container.component.d.ts.map +1 -1
- package/operations/bulk-operations-stepper-container/bulk-operations-stepper-container.module.d.ts +3 -4
- package/operations/bulk-operations-stepper-container/bulk-operations-stepper-container.module.d.ts.map +1 -1
- package/operations/create-bulk-operation-details/create-bulk-operation-details.component.d.ts +1 -1
- package/operations/create-bulk-operation-details/create-bulk-operation-details.component.d.ts.map +1 -1
- package/operations/create-bulk-operation-details/create-bulk-operation-details.module.d.ts +1 -4
- package/operations/create-bulk-operation-details/create-bulk-operation-details.module.d.ts.map +1 -1
- package/operations/device-selector/device-selector.component.d.ts +1 -1
- package/operations/device-selector/device-selector.component.d.ts.map +1 -1
- package/operations/device-selector/device-selector.module.d.ts +1 -3
- package/operations/device-selector/device-selector.module.d.ts.map +1 -1
- package/operations/operation-details/operation-details-modal.component.d.ts +1 -1
- package/operations/operation-details/operation-details-modal.component.d.ts.map +1 -1
- package/operations/operation-details/operation-details.component.d.ts +1 -1
- package/operations/operation-details/operation-details.component.d.ts.map +1 -1
- package/operations/operation-details/operation-details.module.d.ts +1 -7
- package/operations/operation-details/operation-details.module.d.ts.map +1 -1
- package/operations/operation-details/operation-details.service.d.ts.map +1 -1
- package/operations/operation-summary/operation-summary.component.d.ts +1 -1
- package/operations/operation-summary/operation-summary.component.d.ts.map +1 -1
- package/operations/operation-summary/operation-summary.module.d.ts +1 -2
- package/operations/operation-summary/operation-summary.module.d.ts.map +1 -1
- package/operations/operations-list/operations-list-item.component.d.ts.map +1 -1
- package/operations/operations-list/operations-list.component.d.ts.map +1 -1
- package/operations/operations-list/operations-list.service.d.ts +1 -1
- package/operations/operations-list/operations-list.service.d.ts.map +1 -1
- package/operations/operations-list-item-details/operation-details-tabs.component.d.ts +1 -1
- package/operations/operations-list-item-details/operation-details-tabs.component.d.ts.map +1 -1
- package/operations/operations-list-item-details/operation-details.component.d.ts +1 -1
- package/operations/operations-list-item-details/operation-details.component.d.ts.map +1 -1
- package/operations/operations-list-item-details/operations-list-item-details.module.d.ts +1 -6
- package/operations/operations-list-item-details/operations-list-item-details.module.d.ts.map +1 -1
- package/operations/operations-timeline/operations-timeline.component.d.ts +5 -5
- package/operations/operations-timeline/operations-timeline.component.d.ts.map +1 -1
- package/operations/operations-timeline/operations-timeline.module.d.ts +4 -6
- package/operations/operations-timeline/operations-timeline.module.d.ts.map +1 -1
- package/operations/status-filter/status-filter.component.d.ts +1 -1
- package/operations/status-filter/status-filter.component.d.ts.map +1 -1
- package/operations/status-filter/status-filter.module.d.ts +1 -4
- package/operations/status-filter/status-filter.module.d.ts.map +1 -1
- package/operations/stepper-bulk-type-configuration/stepper-bulk-type-configuration.component.d.ts +1 -1
- package/operations/stepper-bulk-type-configuration/stepper-bulk-type-configuration.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-configuration/stepper-bulk-type-configuration.module.d.ts +1 -6
- package/operations/stepper-bulk-type-configuration/stepper-bulk-type-configuration.module.d.ts.map +1 -1
- package/operations/stepper-bulk-type-device-profile/confirm-device-profile-selection-step.component.d.ts +1 -1
- package/operations/stepper-bulk-type-device-profile/confirm-device-profile-selection-step.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-device-profile/select-device-profile-step.component.d.ts +1 -1
- package/operations/stepper-bulk-type-device-profile/select-device-profile-step.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-device-profile/stepper-bulk-type-device-profile.component.d.ts +1 -1
- package/operations/stepper-bulk-type-device-profile/stepper-bulk-type-device-profile.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-device-profile/stepper-bulk-type-device-profile.module.d.ts +1 -6
- package/operations/stepper-bulk-type-device-profile/stepper-bulk-type-device-profile.module.d.ts.map +1 -1
- package/operations/stepper-bulk-type-firmware/select-firmware.component.d.ts +1 -1
- package/operations/stepper-bulk-type-firmware/select-firmware.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-firmware/stepper-bulk-type-firmware.component.d.ts +1 -1
- package/operations/stepper-bulk-type-firmware/stepper-bulk-type-firmware.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-firmware/stepper-bulk-type-firmware.module.d.ts +1 -6
- package/operations/stepper-bulk-type-firmware/stepper-bulk-type-firmware.module.d.ts.map +1 -1
- package/operations/stepper-bulk-type-firmware/version-or-patch.component.d.ts +1 -1
- package/operations/stepper-bulk-type-firmware/version-or-patch.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-software/confirm-software-selection-step.component.d.ts +1 -1
- package/operations/stepper-bulk-type-software/confirm-software-selection-step.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-software/select-software-step.component.d.ts +1 -1
- package/operations/stepper-bulk-type-software/select-software-step.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-software/stepper-bulk-type-software.component.d.ts +1 -1
- package/operations/stepper-bulk-type-software/stepper-bulk-type-software.component.d.ts.map +1 -1
- package/operations/stepper-bulk-type-software/stepper-bulk-type-software.module.d.ts +1 -6
- package/operations/stepper-bulk-type-software/stepper-bulk-type-software.module.d.ts.map +1 -1
- package/operations/stepper-frames/preview-block.directive.d.ts +1 -1
- package/operations/stepper-frames/preview-block.directive.d.ts.map +1 -1
- package/operations/stepper-frames/preview-selection-frame.component.d.ts +1 -1
- package/operations/stepper-frames/preview-selection-frame.component.d.ts.map +1 -1
- package/operations/stepper-frames/select-step-frame.component.d.ts +1 -1
- package/operations/stepper-frames/select-step-frame.component.d.ts.map +1 -1
- package/operations/stepper-frames/stepper-frames.modules.d.ts +1 -2
- package/operations/stepper-frames/stepper-frames.modules.d.ts.map +1 -1
- package/package.json +1 -1
- package/protocol-opcua/opcua-address-space-detail.component.d.ts +1 -1
- package/protocol-opcua/opcua-address-space-detail.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-address-space-tree.component.d.ts +1 -1
- package/protocol-opcua/opcua-address-space-tree.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-address-space.component.d.ts +1 -1
- package/protocol-opcua/opcua-address-space.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-auto-apply-settings.component.d.ts +1 -1
- package/protocol-opcua/opcua-auto-apply-settings.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-device-protocol-browse-path-validation.directive.d.ts +1 -1
- package/protocol-opcua/opcua-device-protocol-browse-path-validation.directive.d.ts.map +1 -1
- package/protocol-opcua/opcua-device-protocol-data-reporting.component.d.ts +1 -1
- package/protocol-opcua/opcua-device-protocol-data-reporting.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-device-protocol-description.component.d.ts +1 -1
- package/protocol-opcua/opcua-device-protocol-description.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-device-protocol-detail.component.d.ts +1 -1
- package/protocol-opcua/opcua-device-protocol-detail.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-device-protocol-mapping.component.d.ts +1 -1
- package/protocol-opcua/opcua-device-protocol-mapping.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-device-protocol-object-mapping-status-icon.component.d.ts +1 -1
- package/protocol-opcua/opcua-device-protocol-object-mapping-status-icon.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-protocol.module.d.ts +26 -26
- package/protocol-opcua/opcua-protocol.module.d.ts.map +1 -1
- package/protocol-opcua/opcua-server-config.component.d.ts +1 -1
- package/protocol-opcua/opcua-server-config.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-server-list.component.d.ts +1 -1
- package/protocol-opcua/opcua-server-list.component.d.ts.map +1 -1
- package/protocol-opcua/opcua-servers.component.d.ts +1 -1
- package/protocol-opcua/opcua-servers.component.d.ts.map +1 -1
- package/repository/configuration/device-tab/configuration-filter.pipe.d.ts +1 -1
- package/repository/configuration/device-tab/configuration-filter.pipe.d.ts.map +1 -1
- package/repository/configuration/device-tab/configuration-preview.component.d.ts +1 -1
- package/repository/configuration/device-tab/configuration-preview.component.d.ts.map +1 -1
- package/repository/configuration/device-tab/configuration-repository-device-tab.module.d.ts +11 -13
- package/repository/configuration/device-tab/configuration-repository-device-tab.module.d.ts.map +1 -1
- package/repository/configuration/device-tab/device-configuration-list.component.d.ts +1 -1
- package/repository/configuration/device-tab/device-configuration-list.component.d.ts.map +1 -1
- package/repository/configuration/device-tab/device-configuration.component.d.ts +1 -1
- package/repository/configuration/device-tab/device-configuration.component.d.ts.map +1 -1
- package/repository/configuration/device-tab/save-to-repository.component.d.ts +1 -1
- package/repository/configuration/device-tab/save-to-repository.component.d.ts.map +1 -1
- package/repository/configuration/device-tab/source-code-preview.component.d.ts +1 -1
- package/repository/configuration/device-tab/source-code-preview.component.d.ts.map +1 -1
- package/repository/configuration/device-tab/text-based-configuration.component.d.ts +1 -1
- package/repository/configuration/device-tab/text-based-configuration.component.d.ts.map +1 -1
- package/repository/configuration/list/configuration-detail.component.d.ts +1 -1
- package/repository/configuration/list/configuration-detail.component.d.ts.map +1 -1
- package/repository/configuration/list/configuration-list.component.d.ts +1 -1
- package/repository/configuration/list/configuration-list.component.d.ts.map +1 -1
- package/repository/configuration/list/configuration-repository-list.module.d.ts +4 -7
- package/repository/configuration/list/configuration-repository-list.module.d.ts.map +1 -1
- package/repository/firmware/device-tab/firmware-device-tab.component.d.ts +1 -1
- package/repository/firmware/device-tab/firmware-device-tab.component.d.ts.map +1 -1
- package/repository/firmware/device-tab/firmware-repository-device-tab.module.d.ts +4 -6
- package/repository/firmware/device-tab/firmware-repository-device-tab.module.d.ts.map +1 -1
- package/repository/firmware/list/add-firmware-modal.component.d.ts +1 -1
- package/repository/firmware/list/add-firmware-modal.component.d.ts.map +1 -1
- package/repository/firmware/list/add-firmware-patch-modal.component.d.ts +1 -1
- package/repository/firmware/list/add-firmware-patch-modal.component.d.ts.map +1 -1
- package/repository/firmware/list/firmware-details.component.d.ts +1 -1
- package/repository/firmware/list/firmware-details.component.d.ts.map +1 -1
- package/repository/firmware/list/firmware-list.component.d.ts +1 -1
- package/repository/firmware/list/firmware-list.component.d.ts.map +1 -1
- package/repository/firmware/list/firmware-repository-list.module.d.ts +6 -11
- package/repository/firmware/list/firmware-repository-list.module.d.ts.map +1 -1
- package/repository/shared/file-download/file-download.component.d.ts +1 -1
- package/repository/shared/file-download/file-download.component.d.ts.map +1 -1
- package/repository/shared/select-modal/repository-select-modal.component.d.ts +1 -1
- package/repository/shared/select-modal/repository-select-modal.component.d.ts.map +1 -1
- package/repository/shared/shared-repository.module.d.ts +1 -4
- package/repository/shared/shared-repository.module.d.ts.map +1 -1
- package/repository/shared/software-type/software-type.component.d.ts +1 -1
- package/repository/shared/software-type/software-type.component.d.ts.map +1 -1
- package/repository/software/device-tab/device-software-changes.component.d.ts +1 -1
- package/repository/software/device-tab/device-software-changes.component.d.ts.map +1 -1
- package/repository/software/device-tab/device-software-list.component.d.ts +1 -1
- package/repository/software/device-tab/device-software-list.component.d.ts.map +1 -1
- package/repository/software/device-tab/installed-software.component.d.ts +1 -1
- package/repository/software/device-tab/installed-software.component.d.ts.map +1 -1
- package/repository/software/device-tab/software-device-tab.component.d.ts +1 -1
- package/repository/software/device-tab/software-device-tab.component.d.ts.map +1 -1
- package/repository/software/device-tab/software-repository-device-tab.module.d.ts +7 -11
- package/repository/software/device-tab/software-repository-device-tab.module.d.ts.map +1 -1
- package/repository/software/list/add-software-modal.component.d.ts +1 -1
- package/repository/software/list/add-software-modal.component.d.ts.map +1 -1
- package/repository/software/list/software-details.component.d.ts +1 -1
- package/repository/software/list/software-details.component.d.ts.map +1 -1
- package/repository/software/list/software-list.component.d.ts +1 -1
- package/repository/software/list/software-list.component.d.ts.map +1 -1
- package/repository/software/list/software-repository-list.module.d.ts +5 -11
- package/repository/software/list/software-repository-list.module.d.ts.map +1 -1
- package/services/services-device-tab/columns/last-updated-date.cell-renderer.component.d.ts +1 -1
- package/services/services-device-tab/columns/last-updated-date.cell-renderer.component.d.ts.map +1 -1
- package/services/services-device-tab/columns/name.cell-renderer.component.d.ts +1 -1
- package/services/services-device-tab/columns/name.cell-renderer.component.d.ts.map +1 -1
- package/services/services-device-tab/columns/status.cell-renderer.component.d.ts +1 -1
- package/services/services-device-tab/columns/status.cell-renderer.component.d.ts.map +1 -1
- package/services/services-device-tab/services-device-tab.component.d.ts +1 -1
- package/services/services-device-tab/services-device-tab.component.d.ts.map +1 -1
- package/services/services-device-tab/services-device-tab.module.d.ts +1 -4
- package/services/services-device-tab/services-device-tab.module.d.ts.map +1 -1
- package/time-context/index.d.ts +1 -0
- package/time-context/index.d.ts.map +1 -1
- package/time-context/time-context.component.d.ts +6 -3
- package/time-context/time-context.component.d.ts.map +1 -1
- package/time-context/time-context.model.d.ts +10 -0
- package/time-context/time-context.model.d.ts.map +1 -0
- package/time-context/time-context.service.d.ts +2 -6
- package/time-context/time-context.service.d.ts.map +1 -1
- package/trusted-certificates/crl/crl-settings.component.d.ts +5 -1
- package/trusted-certificates/crl/crl-settings.component.d.ts.map +1 -1
- package/trusted-certificates/factories/tabs.factory.d.ts +3 -2
- package/trusted-certificates/factories/tabs.factory.d.ts.map +1 -1
- package/trusted-certificates/factories/trusted-certificates-navigation.factory.d.ts +2 -0
- package/trusted-certificates/factories/trusted-certificates-navigation.factory.d.ts.map +1 -1
- package/trusted-certificates/list/trusted-certificate-list.component.d.ts +5 -1
- package/trusted-certificates/list/trusted-certificate-list.component.d.ts.map +1 -1
- package/trusted-certificates/trusted-certificates.guard.d.ts +11 -0
- package/trusted-certificates/trusted-certificates.guard.d.ts.map +1 -0
- package/upgrade/index.d.ts +0 -1
- package/upgrade/index.d.ts.map +1 -1
- package/upgrade/upgrade.module.d.ts.map +1 -1
- package/upgrade/upgraded-services/index.d.ts +1 -0
- package/upgrade/upgraded-services/index.d.ts.map +1 -1
- package/upgrade/upgraded-services/smart-rules.service.d.ts.map +1 -0
- package/upgrade/upgraded-services/upgraded-services.module.d.ts.map +1 -1
- package/user-roles/inventory-role-selector/inventory-role-selector.component.d.ts +2 -1
- package/user-roles/inventory-role-selector/inventory-role-selector.component.d.ts.map +1 -1
- package/user-roles/roles-asset-tree/roles-asset-tree.component.d.ts +2 -1
- package/user-roles/roles-asset-tree/roles-asset-tree.component.d.ts.map +1 -1
- package/device-parameters/c8y-ngx-components-device-parameters.d.ts.map +0 -1
- package/device-parameters/device-parameters-list.component.d.ts +0 -22
- package/device-parameters/device-parameters-list.component.d.ts.map +0 -1
- package/device-parameters/device-parameters-tab.guard.d.ts +0 -11
- package/device-parameters/device-parameters-tab.guard.d.ts.map +0 -1
- package/device-parameters/index.d.ts +0 -2
- package/device-parameters/index.d.ts.map +0 -1
- package/fesm2022/c8y-ngx-components-device-parameters.mjs +0 -118
- package/fesm2022/c8y-ngx-components-device-parameters.mjs.map +0 -1
- package/upgrade/smart-rules.service.d.ts.map +0 -1
- /package/upgrade/{smart-rules.service.d.ts → upgraded-services/smart-rules.service.d.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Input, Directive, Injectable, Injector, InjectionToken, NgModuleRef, createNgModule, Optional, Inject, isDevMode, inject, Pipe, EventEmitter, NgModule, LOCALE_ID, EnvironmentInjector, createEnvironmentInjector, HostListener, Component, HostBinding, Output, forwardRef, DestroyRef, ViewChild, SecurityContext, TemplateRef, provideAppInitializer, Self, SkipSelf, Attribute, ContentChild, ViewContainerRef, ElementRef, ContentChildren, ViewChildren, createComponent, runInInjectionContext, importProvidersFrom, ChangeDetectionStrategy, SimpleChange, reflectComponentType, signal,
|
|
2
|
+
import { Input, Directive, Injectable, Injector, InjectionToken, NgModuleRef, createNgModule, Optional, Inject, isDevMode, inject, Pipe, EventEmitter, NgModule, LOCALE_ID, EnvironmentInjector, createEnvironmentInjector, HostListener, Component, HostBinding, Output, forwardRef, DestroyRef, ViewChild, SecurityContext, TemplateRef, provideAppInitializer, Self, SkipSelf, Attribute, ContentChild, ViewContainerRef, ElementRef, ContentChildren, ViewChildren, viewChild, effect, createComponent, runInInjectionContext, importProvidersFrom, ChangeDetectionStrategy, SimpleChange, reflectComponentType, signal, Type, computed, input, output } from '@angular/core';
|
|
3
3
|
import * as i1$3 from 'ngx-bootstrap/dropdown';
|
|
4
4
|
import { BsDropdownModule, BsDropdownDirective } from 'ngx-bootstrap/dropdown';
|
|
5
5
|
import { CdkTrapFocus, A11yModule } from '@angular/cdk/a11y';
|
|
@@ -15122,102 +15122,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
15122
15122
|
args: ['document:keydown.enter', ['$event']]
|
|
15123
15123
|
}] } });
|
|
15124
15124
|
|
|
15125
|
-
/**
|
|
15126
|
-
* Service to show a modal.
|
|
15127
|
-
*/
|
|
15128
|
-
class ModalService {
|
|
15129
|
-
constructor(modalService, gainsightService) {
|
|
15130
|
-
this.modalService = modalService;
|
|
15131
|
-
this.gainsightService = gainsightService;
|
|
15132
|
-
}
|
|
15133
|
-
/**
|
|
15134
|
-
* Shows a quick confirm message modal.
|
|
15135
|
-
* @param title The title of that modal.
|
|
15136
|
-
* @param body The text body to display.
|
|
15137
|
-
* @param status The status.
|
|
15138
|
-
* @param labels The labels to use. Default: { ok: 'Confirm', cancel: 'Cancel'}
|
|
15139
|
-
* @param confirmOptions Selection options to display as checkbox list.
|
|
15140
|
-
* @param productExperienceEvent Additional data to attach to custom product experience events.
|
|
15141
|
-
*/
|
|
15142
|
-
async confirm(title, body, status = Status.INFO, labels = {}, confirmOptions = {}, productExperienceEvent = { eventName: 'confirmModal' }) {
|
|
15143
|
-
const modalLabels = {
|
|
15144
|
-
ok: labels.ok || gettext$1('Confirm'),
|
|
15145
|
-
cancel: labels.cancel || gettext$1('Cancel')
|
|
15146
|
-
};
|
|
15147
|
-
const modalRef = this.modalService.show(ConfirmModalComponent, {
|
|
15148
|
-
initialState: { title, body, labels: modalLabels, status, confirmOptions },
|
|
15149
|
-
ariaDescribedby: 'modal-body',
|
|
15150
|
-
ariaLabelledBy: 'modal-title',
|
|
15151
|
-
ignoreBackdropClick: true
|
|
15152
|
-
});
|
|
15153
|
-
if (productExperienceEvent) {
|
|
15154
|
-
productExperienceEvent.data = { ...productExperienceEvent.data, title };
|
|
15155
|
-
}
|
|
15156
|
-
this.triggerEvent(modalRef.content.result, modalLabels, productExperienceEvent);
|
|
15157
|
-
return await modalRef.content.result;
|
|
15158
|
-
}
|
|
15159
|
-
/**
|
|
15160
|
-
* Shows a quick acknowledge message modal.
|
|
15161
|
-
* @param title The title of that modal.
|
|
15162
|
-
* @param body The text body to display.
|
|
15163
|
-
* @param status The status.
|
|
15164
|
-
* @param acknowledgeLabel The label to use.
|
|
15165
|
-
* @param productExperienceEvent Additional data to attach to custom product experience events.
|
|
15166
|
-
*/
|
|
15167
|
-
async acknowledge(title, body, status = Status.INFO, acknowledgeLabel = gettext$1('Confirm'), productExperienceEvent = { eventName: 'confirmModal' }) {
|
|
15168
|
-
const labels = { ok: acknowledgeLabel, cancel: null };
|
|
15169
|
-
const modalRef = this.modalService.show(ConfirmModalComponent, {
|
|
15170
|
-
initialState: { title, body, labels, status },
|
|
15171
|
-
ariaDescribedby: 'modal-body',
|
|
15172
|
-
ariaLabelledBy: 'modal-title',
|
|
15173
|
-
ignoreBackdropClick: true
|
|
15174
|
-
});
|
|
15175
|
-
if (productExperienceEvent) {
|
|
15176
|
-
productExperienceEvent.data = { ...productExperienceEvent.data, title };
|
|
15177
|
-
}
|
|
15178
|
-
this.triggerEvent(modalRef.content.result, labels, productExperienceEvent);
|
|
15179
|
-
return await modalRef.content.result;
|
|
15180
|
-
}
|
|
15181
|
-
/**
|
|
15182
|
-
* Shows a quick logout confirmation modal.
|
|
15183
|
-
* @param body The text body to display. Default: 'You will be logged out to apply your changes. Do you want to proceed?'
|
|
15184
|
-
* @param status The status.
|
|
15185
|
-
* @param labels The labels to use. Default: { ok: 'Confirm and log out', cancel: 'Cancel' }
|
|
15186
|
-
*/
|
|
15187
|
-
async confirmLogout(body, status = Status.WARNING, labels = {}) {
|
|
15188
|
-
const modalLabels = {
|
|
15189
|
-
ok: labels.ok || gettext$1('Confirm and log out'),
|
|
15190
|
-
cancel: labels.cancel || gettext$1('Cancel')
|
|
15191
|
-
};
|
|
15192
|
-
const modalBody = body || gettext$1('You must log out to apply your changes. Do you want to proceed?');
|
|
15193
|
-
return await this.confirm(gettext$1('Logout required'), modalBody, status, modalLabels);
|
|
15194
|
-
}
|
|
15195
|
-
triggerEvent(result, labels, productExperienceEvent) {
|
|
15196
|
-
const data = { ...productExperienceEvent.data, url: window.location.href };
|
|
15197
|
-
result
|
|
15198
|
-
.then(() => {
|
|
15199
|
-
this.gainsightService.triggerEvent(productExperienceEvent.eventName, {
|
|
15200
|
-
...data,
|
|
15201
|
-
result: labels.ok
|
|
15202
|
-
});
|
|
15203
|
-
})
|
|
15204
|
-
.catch(() => {
|
|
15205
|
-
this.gainsightService.triggerEvent(productExperienceEvent.eventName, {
|
|
15206
|
-
...data,
|
|
15207
|
-
result: labels.cancel
|
|
15208
|
-
});
|
|
15209
|
-
});
|
|
15210
|
-
}
|
|
15211
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalService, deps: [{ token: i1$7.BsModalService }, { token: GainsightService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
15212
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalService, providedIn: 'root' }); }
|
|
15213
|
-
}
|
|
15214
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalService, decorators: [{
|
|
15215
|
-
type: Injectable,
|
|
15216
|
-
args: [{
|
|
15217
|
-
providedIn: 'root'
|
|
15218
|
-
}]
|
|
15219
|
-
}], ctorParameters: () => [{ type: i1$7.BsModalService }, { type: GainsightService }] });
|
|
15220
|
-
|
|
15221
15125
|
/**
|
|
15222
15126
|
* The angular module definition for modal.
|
|
15223
15127
|
* @exports ConfirmModalComponent
|
|
@@ -15229,7 +15133,7 @@ class ModalModule {
|
|
|
15229
15133
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: ModalModule, imports: [i1$7.ModalModule, CommonModule, i1$9.PopoverModule, ConfirmModalComponent,
|
|
15230
15134
|
ModalComponent,
|
|
15231
15135
|
PopoverConfirmComponent], exports: [ConfirmModalComponent, ModalComponent, PopoverConfirmComponent] }); }
|
|
15232
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalModule,
|
|
15136
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalModule, imports: [ModalModule$1.forRoot(),
|
|
15233
15137
|
CommonModule,
|
|
15234
15138
|
PopoverModule.forRoot(),
|
|
15235
15139
|
PopoverConfirmComponent] }); }
|
|
@@ -15245,8 +15149,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
15245
15149
|
ModalComponent,
|
|
15246
15150
|
PopoverConfirmComponent
|
|
15247
15151
|
],
|
|
15248
|
-
exports: [ConfirmModalComponent, ModalComponent, PopoverConfirmComponent]
|
|
15249
|
-
providers: [ModalService]
|
|
15152
|
+
exports: [ConfirmModalComponent, ModalComponent, PopoverConfirmComponent]
|
|
15250
15153
|
}]
|
|
15251
15154
|
}] });
|
|
15252
15155
|
|
|
@@ -19203,299 +19106,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
19203
19106
|
}]
|
|
19204
19107
|
}] });
|
|
19205
19108
|
|
|
19206
|
-
class
|
|
19207
|
-
constructor(
|
|
19208
|
-
this.
|
|
19209
|
-
this.
|
|
19210
|
-
this.
|
|
19211
|
-
|
|
19212
|
-
|
|
19213
|
-
|
|
19214
|
-
|
|
19215
|
-
|
|
19216
|
-
|
|
19217
|
-
|
|
19218
|
-
|
|
19219
|
-
|
|
19220
|
-
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19109
|
+
class PasswordConfirmModalComponent {
|
|
19110
|
+
constructor(user, ui, client, alert) {
|
|
19111
|
+
this.user = user;
|
|
19112
|
+
this.ui = ui;
|
|
19113
|
+
this.client = client;
|
|
19114
|
+
this.alert = alert;
|
|
19115
|
+
this.passwordConfirmedEmitter = new EventEmitter();
|
|
19116
|
+
this.loading = false;
|
|
19117
|
+
}
|
|
19118
|
+
async passwordConfirm() {
|
|
19119
|
+
if (this.password) {
|
|
19120
|
+
const supportUserName = this.ui.currentSupportUserName.value;
|
|
19121
|
+
const userId = this.ui.currentUser.value.id;
|
|
19122
|
+
const credentials = {
|
|
19123
|
+
password: this.password,
|
|
19124
|
+
user: `${supportUserName ? `${supportUserName}$` : ''}${userId}`,
|
|
19125
|
+
tenant: this.client.tenant
|
|
19126
|
+
};
|
|
19127
|
+
try {
|
|
19128
|
+
this.loading = true;
|
|
19129
|
+
const auth = new BasicAuth(credentials);
|
|
19130
|
+
const newClient = this.createNewClient(auth, this.client.baseUrl);
|
|
19131
|
+
await newClient.user.current();
|
|
19132
|
+
this.emitSuccessAndClose();
|
|
19225
19133
|
}
|
|
19226
|
-
|
|
19227
|
-
|
|
19228
|
-
|
|
19229
|
-
|
|
19230
|
-
|
|
19231
|
-
|
|
19232
|
-
|
|
19134
|
+
catch (e) {
|
|
19135
|
+
if (e.res && e.res.status === 401 && e.data && /pin|totp/i.test(e.data.message)) {
|
|
19136
|
+
this.emitSuccessAndClose();
|
|
19137
|
+
}
|
|
19138
|
+
else {
|
|
19139
|
+
this.alert.danger(gettext$1("Provided password doesn't match your current one."));
|
|
19140
|
+
}
|
|
19233
19141
|
}
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
this.disableThemeSelection$ = this._temporaryThemePreference$.pipe(map(preference => preference !== 'none'));
|
|
19237
|
-
this.currentlyAppliedTheme$ = this._temporaryThemePreference$.pipe(switchMap(temporaryPreference => {
|
|
19238
|
-
if (temporaryPreference !== 'none') {
|
|
19239
|
-
return of(temporaryPreference);
|
|
19142
|
+
finally {
|
|
19143
|
+
this.loading = false;
|
|
19240
19144
|
}
|
|
19241
|
-
return userSelectedTheme$;
|
|
19242
|
-
}));
|
|
19243
|
-
this.darkThemeAvailable$ = this.options.get$('darkThemeAvailable').pipe(map(value => !!value));
|
|
19244
|
-
}
|
|
19245
|
-
getCurrentThemePreference() {
|
|
19246
|
-
const value = getThemePreference();
|
|
19247
|
-
if (value === 'system' || value === 'dark') {
|
|
19248
|
-
return value;
|
|
19249
19145
|
}
|
|
19250
|
-
return 'light';
|
|
19251
|
-
}
|
|
19252
|
-
getUsersSystemPreferenceForTheme$() {
|
|
19253
|
-
return fromEvent(window.matchMedia('(prefers-color-scheme: dark)'), 'change').pipe(startWith(window.matchMedia('(prefers-color-scheme: dark)')), map((e) => (e.matches ? 'dark' : 'light')));
|
|
19254
|
-
}
|
|
19255
|
-
changeUserPreference(preference) {
|
|
19256
|
-
setThemePreference(preference);
|
|
19257
|
-
this._userSelectedThemePreference$.next(preference);
|
|
19258
|
-
this.applyTheme(preference);
|
|
19259
19146
|
}
|
|
19260
|
-
|
|
19261
|
-
this.
|
|
19262
|
-
this.
|
|
19147
|
+
cancel() {
|
|
19148
|
+
this.passwordConfirmedEmitter.emit(false);
|
|
19149
|
+
this.modal._dismiss();
|
|
19263
19150
|
}
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
this.applyTheme(this.getCurrentThemePreference());
|
|
19151
|
+
createNewClient(auth, baseUrl) {
|
|
19152
|
+
return new Client(auth, baseUrl);
|
|
19267
19153
|
}
|
|
19268
|
-
|
|
19269
|
-
|
|
19154
|
+
emitSuccessAndClose() {
|
|
19155
|
+
this.passwordConfirmedEmitter.emit(true);
|
|
19156
|
+
this.modal._dismiss();
|
|
19270
19157
|
}
|
|
19271
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type:
|
|
19272
|
-
static { this.ɵ
|
|
19158
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordConfirmModalComponent, deps: [{ token: i1.UserService }, { token: AppStateService }, { token: i1.FetchClient }, { token: AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19159
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PasswordConfirmModalComponent, isStandalone: true, selector: "c8y-password-confirm-modal", outputs: { passwordConfirmedEmitter: "passwordConfirmedEmitter" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], ngImport: i0, template: "<c8y-modal [customFooter]=\"true\" [title]=\"'Confirm your current password' | translate\" #modal>\r\n <form #confirmForm=\"ngForm\" (ngSubmit)=\"confirmForm.form.valid && passwordConfirm()\">\r\n <div class=\"d-block p-24 p-b-0\">\r\n <c8y-form-group [hasWarning]=\"true\">\r\n <label translate for=\"currentPassword\">Enter your password</label>\r\n <input\r\n id=\"currentPassword\"\r\n [(ngModel)]=\"password\"\r\n type=\"password\"\r\n name=\"password\"\r\n class=\"form-control\"\r\n placeholder=\"{{ 'Enter your password' | translate }}\"\r\n required\r\n />\r\n <c8y-messages>\r\n <c8y-message translate>\r\n Enter the password of the user that you are currently logged in with.\r\n </c8y-message>\r\n </c8y-messages>\r\n </c8y-form-group>\r\n </div>\r\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\r\n <button\r\n title=\"{{ 'Cancel' | translate }}\"\r\n class=\"btn btn-default\"\r\n type=\"button\"\r\n (click)=\"cancel()\"\r\n >\r\n {{ 'Cancel' | translate }}\r\n </button>\r\n <button\r\n title=\"{{ 'Confirm' | translate }}\"\r\n class=\"btn btn-primary\"\r\n type=\"submit\"\r\n [disabled]=\"!confirmForm.form.valid || loading\"\r\n >\r\n {{ 'Confirm' | translate }}\r\n </button>\r\n </div>\r\n </form>\r\n</c8y-modal>\r\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
19273
19160
|
}
|
|
19274
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type:
|
|
19275
|
-
type:
|
|
19276
|
-
args: [{
|
|
19277
|
-
|
|
19278
|
-
|
|
19279
|
-
|
|
19161
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordConfirmModalComponent, decorators: [{
|
|
19162
|
+
type: Component,
|
|
19163
|
+
args: [{ selector: 'c8y-password-confirm-modal', standalone: true, imports: [
|
|
19164
|
+
ModalComponent,
|
|
19165
|
+
FormsModule$1,
|
|
19166
|
+
FormGroupComponent,
|
|
19167
|
+
C8yTranslateDirective,
|
|
19168
|
+
RequiredInputPlaceholderDirective,
|
|
19169
|
+
MessagesComponent,
|
|
19170
|
+
MessageDirective,
|
|
19171
|
+
C8yTranslatePipe
|
|
19172
|
+
], template: "<c8y-modal [customFooter]=\"true\" [title]=\"'Confirm your current password' | translate\" #modal>\r\n <form #confirmForm=\"ngForm\" (ngSubmit)=\"confirmForm.form.valid && passwordConfirm()\">\r\n <div class=\"d-block p-24 p-b-0\">\r\n <c8y-form-group [hasWarning]=\"true\">\r\n <label translate for=\"currentPassword\">Enter your password</label>\r\n <input\r\n id=\"currentPassword\"\r\n [(ngModel)]=\"password\"\r\n type=\"password\"\r\n name=\"password\"\r\n class=\"form-control\"\r\n placeholder=\"{{ 'Enter your password' | translate }}\"\r\n required\r\n />\r\n <c8y-messages>\r\n <c8y-message translate>\r\n Enter the password of the user that you are currently logged in with.\r\n </c8y-message>\r\n </c8y-messages>\r\n </c8y-form-group>\r\n </div>\r\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\r\n <button\r\n title=\"{{ 'Cancel' | translate }}\"\r\n class=\"btn btn-default\"\r\n type=\"button\"\r\n (click)=\"cancel()\"\r\n >\r\n {{ 'Cancel' | translate }}\r\n </button>\r\n <button\r\n title=\"{{ 'Confirm' | translate }}\"\r\n class=\"btn btn-primary\"\r\n type=\"submit\"\r\n [disabled]=\"!confirmForm.form.valid || loading\"\r\n >\r\n {{ 'Confirm' | translate }}\r\n </button>\r\n </div>\r\n </form>\r\n</c8y-modal>\r\n" }]
|
|
19173
|
+
}], ctorParameters: () => [{ type: i1.UserService }, { type: AppStateService }, { type: i1.FetchClient }, { type: AlertService }], propDecorators: { passwordConfirmedEmitter: [{
|
|
19174
|
+
type: Output
|
|
19175
|
+
}], modal: [{
|
|
19176
|
+
type: ViewChild,
|
|
19177
|
+
args: ['modal', { static: false }]
|
|
19178
|
+
}] } });
|
|
19280
19179
|
|
|
19281
|
-
class
|
|
19282
|
-
constructor(
|
|
19283
|
-
this.
|
|
19284
|
-
this.
|
|
19285
|
-
this.ui = ui;
|
|
19286
|
-
this.userPreferences = userPreferences;
|
|
19287
|
-
this.c8yModalService = c8yModalService;
|
|
19288
|
-
this.headerService = headerService;
|
|
19289
|
-
this.themeSwitcher = themeSwitcher;
|
|
19290
|
-
this.destroyed$ = new Subject();
|
|
19291
|
-
this.currentLang = this.ui.state.lang;
|
|
19292
|
-
this.ui.state$
|
|
19293
|
-
.pipe(filter(({ lang }) => lang !== this.currentLang), takeUntil(this.destroyed$), first$1())
|
|
19294
|
-
.subscribe(({ lang }) => (this.currentLang = lang));
|
|
19295
|
-
this.open$ = this.headerService.rightDrawerOpen$;
|
|
19180
|
+
class CurrentPasswordModalComponent {
|
|
19181
|
+
constructor(modal) {
|
|
19182
|
+
this.modal = modal;
|
|
19183
|
+
this.currentPasswordEmitter = new EventEmitter();
|
|
19296
19184
|
}
|
|
19297
|
-
|
|
19298
|
-
this.
|
|
19299
|
-
|
|
19300
|
-
nativeLanguage: this.translate.getNativeLanguage(l)
|
|
19301
|
-
}));
|
|
19185
|
+
passwordConfirm() {
|
|
19186
|
+
this.currentPasswordEmitter.emit(this.password);
|
|
19187
|
+
this.modal.hide();
|
|
19302
19188
|
}
|
|
19303
|
-
|
|
19304
|
-
this.
|
|
19305
|
-
this.
|
|
19306
|
-
}
|
|
19307
|
-
async onLanguageChange(changedLang) {
|
|
19308
|
-
if (!changedLang) {
|
|
19309
|
-
return;
|
|
19310
|
-
}
|
|
19311
|
-
await this.translate.switchToLanguage(changedLang);
|
|
19312
|
-
if (await this.persistLanguage(changedLang)) {
|
|
19313
|
-
location.reload();
|
|
19314
|
-
}
|
|
19315
|
-
}
|
|
19316
|
-
async persistLanguage(lang) {
|
|
19317
|
-
let shouldReload = true;
|
|
19318
|
-
try {
|
|
19319
|
-
await this.c8yModalService.confirm(gettext$1('Reload recommended'), gettext$1('To change the language in the entire application, we recommend you to reload the page. If you have any unsaved changes, you can reload later. How would you like to proceed?'), Status.WARNING, {
|
|
19320
|
-
ok: gettext$1('Reload now'),
|
|
19321
|
-
cancel: gettext$1('Reload later')
|
|
19322
|
-
});
|
|
19323
|
-
}
|
|
19324
|
-
catch (ex) {
|
|
19325
|
-
shouldReload = false;
|
|
19326
|
-
}
|
|
19327
|
-
finally {
|
|
19328
|
-
this.translate.saveInLocalStorage(lang);
|
|
19329
|
-
await this.userPreferences.set('language', lang);
|
|
19330
|
-
this.currentLang = lang;
|
|
19331
|
-
}
|
|
19332
|
-
return shouldReload;
|
|
19333
|
-
}
|
|
19334
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsComponent, deps: [{ token: TranslateService }, { token: AppStateService }, { token: AppStateService }, { token: UserPreferencesService }, { token: ModalService }, { token: HeaderService }, { token: ThemeSwitcherService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19335
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UiSettingsComponent, isStandalone: true, selector: "c8y-ui-settings", ngImport: i0, template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"eyedropper\"></i>\n <span class=\"text-bold\">{{ 'UI settings' | translate }}</span>\n </div>\n\n <div\n class=\"p-l-16 p-r-16 p-b-16\"\n *ngIf=\"themeSwitcher.darkThemeAvailable$ | async\"\n >\n <p translate>Theme</p>\n <div\n class=\"c8y-switch-multistate\"\n *ngIf=\"themeSwitcher.userSelectedThemePreference$ | async as themePreference\"\n >\n <ng-container *ngFor=\"let themeOption of themeSwitcher.themeOptions; index as i\">\n <input\n [attr.aria-label]=\"themeOption.label\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n name=\"theme-switcher\"\n type=\"radio\"\n [id]=\"'theme-option-' + i\"\n [disabled]=\"themeSwitcher.disableThemeSelection$ | async\"\n [checked]=\"themePreference === themeOption.value\"\n (click)=\"themeSwitcher.changeUserPreference(themeOption.value)\"\n />\n <label\n title=\"{{ themeOption.label | translate }}\"\n [for]=\"'theme-option-' + i\"\n >\n <i [c8yIcon]=\"themeOption.icon\"></i>\n </label>\n </ng-container>\n <div class=\"c8y-switch-multistate__handle\"></div>\n </div>\n </div>\n\n <div class=\"form-group p-l-16 p-r-16\">\n <label\n for=\"userLang\"\n translate\n >\n Language\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n #selectLang\n [ngModel]=\"currentLang\"\n (change)=\"onLanguageChange(selectLang.value)\"\n >\n <option\n *ngFor=\"let language of languages\"\n [value]=\"language.lang\"\n >\n {{ language.nativeLanguage }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
19336
|
-
}
|
|
19337
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsComponent, decorators: [{
|
|
19338
|
-
type: Component,
|
|
19339
|
-
args: [{ selector: 'c8y-ui-settings', standalone: true, imports: [
|
|
19340
|
-
IconDirective,
|
|
19341
|
-
NgIf,
|
|
19342
|
-
C8yTranslateDirective,
|
|
19343
|
-
NgFor,
|
|
19344
|
-
FormsModule$1,
|
|
19345
|
-
C8yTranslatePipe,
|
|
19346
|
-
AsyncPipe
|
|
19347
|
-
], template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"eyedropper\"></i>\n <span class=\"text-bold\">{{ 'UI settings' | translate }}</span>\n </div>\n\n <div\n class=\"p-l-16 p-r-16 p-b-16\"\n *ngIf=\"themeSwitcher.darkThemeAvailable$ | async\"\n >\n <p translate>Theme</p>\n <div\n class=\"c8y-switch-multistate\"\n *ngIf=\"themeSwitcher.userSelectedThemePreference$ | async as themePreference\"\n >\n <ng-container *ngFor=\"let themeOption of themeSwitcher.themeOptions; index as i\">\n <input\n [attr.aria-label]=\"themeOption.label\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n name=\"theme-switcher\"\n type=\"radio\"\n [id]=\"'theme-option-' + i\"\n [disabled]=\"themeSwitcher.disableThemeSelection$ | async\"\n [checked]=\"themePreference === themeOption.value\"\n (click)=\"themeSwitcher.changeUserPreference(themeOption.value)\"\n />\n <label\n title=\"{{ themeOption.label | translate }}\"\n [for]=\"'theme-option-' + i\"\n >\n <i [c8yIcon]=\"themeOption.icon\"></i>\n </label>\n </ng-container>\n <div class=\"c8y-switch-multistate__handle\"></div>\n </div>\n </div>\n\n <div class=\"form-group p-l-16 p-r-16\">\n <label\n for=\"userLang\"\n translate\n >\n Language\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n #selectLang\n [ngModel]=\"currentLang\"\n (change)=\"onLanguageChange(selectLang.value)\"\n >\n <option\n *ngFor=\"let language of languages\"\n [value]=\"language.lang\"\n >\n {{ language.nativeLanguage }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n</div>\n" }]
|
|
19348
|
-
}], ctorParameters: () => [{ type: TranslateService }, { type: AppStateService }, { type: AppStateService }, { type: UserPreferencesService }, { type: ModalService }, { type: HeaderService }, { type: ThemeSwitcherService }] });
|
|
19349
|
-
|
|
19350
|
-
class UiSettingsModule {
|
|
19351
|
-
static providers() {
|
|
19352
|
-
return [
|
|
19353
|
-
hookDrawer({
|
|
19354
|
-
component: UiSettingsComponent,
|
|
19355
|
-
position: 'right',
|
|
19356
|
-
priority: 90,
|
|
19357
|
-
id: 'uiSettings'
|
|
19358
|
-
})
|
|
19359
|
-
];
|
|
19360
|
-
}
|
|
19361
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
19362
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, imports: [CommonModule, FormsModule$1, UiSettingsComponent], exports: [UiSettingsComponent] }); }
|
|
19363
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, imports: [CommonModule, FormsModule$1, UiSettingsComponent] }); }
|
|
19364
|
-
}
|
|
19365
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, decorators: [{
|
|
19366
|
-
type: NgModule,
|
|
19367
|
-
args: [{
|
|
19368
|
-
imports: [CommonModule, FormsModule$1, UiSettingsComponent],
|
|
19369
|
-
exports: [UiSettingsComponent]
|
|
19370
|
-
}]
|
|
19371
|
-
}] });
|
|
19372
|
-
|
|
19373
|
-
class UserMenuItemComponent {
|
|
19374
|
-
constructor(userService, headerService) {
|
|
19375
|
-
this.userService = userService;
|
|
19376
|
-
this.headerService = headerService;
|
|
19377
|
-
this.priority = 0;
|
|
19378
|
-
this.click = new EventEmitter();
|
|
19379
|
-
this.open$ = this.headerService.rightDrawerOpen$;
|
|
19380
|
-
}
|
|
19381
|
-
ngAfterViewInit() {
|
|
19382
|
-
this.viewInitTimeout = setTimeout(() => this.userService.add(this));
|
|
19383
|
-
}
|
|
19384
|
-
ngOnDestroy() {
|
|
19385
|
-
clearTimeout(this.viewInitTimeout);
|
|
19386
|
-
this.userService.remove(this);
|
|
19387
|
-
}
|
|
19388
|
-
onClick() {
|
|
19389
|
-
this.click.emit(this);
|
|
19390
|
-
}
|
|
19391
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserMenuItemComponent, deps: [{ token: UserMenuService }, { token: HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19392
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UserMenuItemComponent, isStandalone: true, selector: "c8y-user-menu-item", inputs: { icon: "icon", label: "label", link: "link", target: "target", priority: "priority", dataCy: "dataCy" }, outputs: { click: "click" }, viewQueries: [{ propertyName: "template", first: true, predicate: ["template"], descendants: true }], ngImport: i0, template: "<ng-template #template>\n <li>\n <a\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n *ngIf=\"link\"\n [attr.href]=\"link\"\n [attr.target]=\"target\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </a>\n <button\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n *ngIf=\"!link\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </button>\n </li>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
19393
|
-
}
|
|
19394
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserMenuItemComponent, decorators: [{
|
|
19395
|
-
type: Component,
|
|
19396
|
-
args: [{ selector: 'c8y-user-menu-item', standalone: true, imports: [NgIf, C8yTranslatePipe, AsyncPipe], template: "<ng-template #template>\n <li>\n <a\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n *ngIf=\"link\"\n [attr.href]=\"link\"\n [attr.target]=\"target\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </a>\n <button\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n *ngIf=\"!link\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </button>\n </li>\n</ng-template>\n" }]
|
|
19397
|
-
}], ctorParameters: () => [{ type: UserMenuService }, { type: HeaderService }], propDecorators: { icon: [{
|
|
19398
|
-
type: Input
|
|
19399
|
-
}], label: [{
|
|
19400
|
-
type: Input
|
|
19401
|
-
}], link: [{
|
|
19402
|
-
type: Input
|
|
19403
|
-
}], target: [{
|
|
19404
|
-
type: Input
|
|
19405
|
-
}], priority: [{
|
|
19406
|
-
type: Input
|
|
19407
|
-
}], dataCy: [{
|
|
19408
|
-
type: Input
|
|
19409
|
-
}], template: [{
|
|
19410
|
-
type: ViewChild,
|
|
19411
|
-
args: ['template', { static: false }]
|
|
19412
|
-
}], click: [{
|
|
19413
|
-
type: Output
|
|
19414
|
-
}] } });
|
|
19415
|
-
|
|
19416
|
-
class PasswordConfirmModalComponent {
|
|
19417
|
-
constructor(user, ui, client, alert) {
|
|
19418
|
-
this.user = user;
|
|
19419
|
-
this.ui = ui;
|
|
19420
|
-
this.client = client;
|
|
19421
|
-
this.alert = alert;
|
|
19422
|
-
this.passwordConfirmedEmitter = new EventEmitter();
|
|
19423
|
-
this.loading = false;
|
|
19424
|
-
}
|
|
19425
|
-
async passwordConfirm() {
|
|
19426
|
-
if (this.password) {
|
|
19427
|
-
const supportUserName = this.ui.currentSupportUserName.value;
|
|
19428
|
-
const userId = this.ui.currentUser.value.id;
|
|
19429
|
-
const credentials = {
|
|
19430
|
-
password: this.password,
|
|
19431
|
-
user: `${supportUserName ? `${supportUserName}$` : ''}${userId}`,
|
|
19432
|
-
tenant: this.client.tenant
|
|
19433
|
-
};
|
|
19434
|
-
try {
|
|
19435
|
-
this.loading = true;
|
|
19436
|
-
const auth = new BasicAuth(credentials);
|
|
19437
|
-
const newClient = this.createNewClient(auth, this.client.baseUrl);
|
|
19438
|
-
await newClient.user.current();
|
|
19439
|
-
this.emitSuccessAndClose();
|
|
19440
|
-
}
|
|
19441
|
-
catch (e) {
|
|
19442
|
-
if (e.res && e.res.status === 401 && e.data && /pin|totp/i.test(e.data.message)) {
|
|
19443
|
-
this.emitSuccessAndClose();
|
|
19444
|
-
}
|
|
19445
|
-
else {
|
|
19446
|
-
this.alert.danger(gettext$1("Provided password doesn't match your current one."));
|
|
19447
|
-
}
|
|
19448
|
-
}
|
|
19449
|
-
finally {
|
|
19450
|
-
this.loading = false;
|
|
19451
|
-
}
|
|
19452
|
-
}
|
|
19453
|
-
}
|
|
19454
|
-
cancel() {
|
|
19455
|
-
this.passwordConfirmedEmitter.emit(false);
|
|
19456
|
-
this.modal._dismiss();
|
|
19457
|
-
}
|
|
19458
|
-
createNewClient(auth, baseUrl) {
|
|
19459
|
-
return new Client(auth, baseUrl);
|
|
19460
|
-
}
|
|
19461
|
-
emitSuccessAndClose() {
|
|
19462
|
-
this.passwordConfirmedEmitter.emit(true);
|
|
19463
|
-
this.modal._dismiss();
|
|
19464
|
-
}
|
|
19465
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordConfirmModalComponent, deps: [{ token: i1.UserService }, { token: AppStateService }, { token: i1.FetchClient }, { token: AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19466
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PasswordConfirmModalComponent, isStandalone: true, selector: "c8y-password-confirm-modal", outputs: { passwordConfirmedEmitter: "passwordConfirmedEmitter" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], ngImport: i0, template: "<c8y-modal [customFooter]=\"true\" [title]=\"'Confirm your current password' | translate\" #modal>\r\n <form #confirmForm=\"ngForm\" (ngSubmit)=\"confirmForm.form.valid && passwordConfirm()\">\r\n <div class=\"d-block p-24 p-b-0\">\r\n <c8y-form-group [hasWarning]=\"true\">\r\n <label translate for=\"currentPassword\">Enter your password</label>\r\n <input\r\n id=\"currentPassword\"\r\n [(ngModel)]=\"password\"\r\n type=\"password\"\r\n name=\"password\"\r\n class=\"form-control\"\r\n placeholder=\"{{ 'Enter your password' | translate }}\"\r\n required\r\n />\r\n <c8y-messages>\r\n <c8y-message translate>\r\n Enter the password of the user that you are currently logged in with.\r\n </c8y-message>\r\n </c8y-messages>\r\n </c8y-form-group>\r\n </div>\r\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\r\n <button\r\n title=\"{{ 'Cancel' | translate }}\"\r\n class=\"btn btn-default\"\r\n type=\"button\"\r\n (click)=\"cancel()\"\r\n >\r\n {{ 'Cancel' | translate }}\r\n </button>\r\n <button\r\n title=\"{{ 'Confirm' | translate }}\"\r\n class=\"btn btn-primary\"\r\n type=\"submit\"\r\n [disabled]=\"!confirmForm.form.valid || loading\"\r\n >\r\n {{ 'Confirm' | translate }}\r\n </button>\r\n </div>\r\n </form>\r\n</c8y-modal>\r\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
19467
|
-
}
|
|
19468
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordConfirmModalComponent, decorators: [{
|
|
19469
|
-
type: Component,
|
|
19470
|
-
args: [{ selector: 'c8y-password-confirm-modal', standalone: true, imports: [
|
|
19471
|
-
ModalComponent,
|
|
19472
|
-
FormsModule$1,
|
|
19473
|
-
FormGroupComponent,
|
|
19474
|
-
C8yTranslateDirective,
|
|
19475
|
-
RequiredInputPlaceholderDirective,
|
|
19476
|
-
MessagesComponent,
|
|
19477
|
-
MessageDirective,
|
|
19478
|
-
C8yTranslatePipe
|
|
19479
|
-
], template: "<c8y-modal [customFooter]=\"true\" [title]=\"'Confirm your current password' | translate\" #modal>\r\n <form #confirmForm=\"ngForm\" (ngSubmit)=\"confirmForm.form.valid && passwordConfirm()\">\r\n <div class=\"d-block p-24 p-b-0\">\r\n <c8y-form-group [hasWarning]=\"true\">\r\n <label translate for=\"currentPassword\">Enter your password</label>\r\n <input\r\n id=\"currentPassword\"\r\n [(ngModel)]=\"password\"\r\n type=\"password\"\r\n name=\"password\"\r\n class=\"form-control\"\r\n placeholder=\"{{ 'Enter your password' | translate }}\"\r\n required\r\n />\r\n <c8y-messages>\r\n <c8y-message translate>\r\n Enter the password of the user that you are currently logged in with.\r\n </c8y-message>\r\n </c8y-messages>\r\n </c8y-form-group>\r\n </div>\r\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\r\n <button\r\n title=\"{{ 'Cancel' | translate }}\"\r\n class=\"btn btn-default\"\r\n type=\"button\"\r\n (click)=\"cancel()\"\r\n >\r\n {{ 'Cancel' | translate }}\r\n </button>\r\n <button\r\n title=\"{{ 'Confirm' | translate }}\"\r\n class=\"btn btn-primary\"\r\n type=\"submit\"\r\n [disabled]=\"!confirmForm.form.valid || loading\"\r\n >\r\n {{ 'Confirm' | translate }}\r\n </button>\r\n </div>\r\n </form>\r\n</c8y-modal>\r\n" }]
|
|
19480
|
-
}], ctorParameters: () => [{ type: i1.UserService }, { type: AppStateService }, { type: i1.FetchClient }, { type: AlertService }], propDecorators: { passwordConfirmedEmitter: [{
|
|
19481
|
-
type: Output
|
|
19482
|
-
}], modal: [{
|
|
19483
|
-
type: ViewChild,
|
|
19484
|
-
args: ['modal', { static: false }]
|
|
19485
|
-
}] } });
|
|
19486
|
-
|
|
19487
|
-
class CurrentPasswordModalComponent {
|
|
19488
|
-
constructor(modal) {
|
|
19489
|
-
this.modal = modal;
|
|
19490
|
-
this.currentPasswordEmitter = new EventEmitter();
|
|
19491
|
-
}
|
|
19492
|
-
passwordConfirm() {
|
|
19493
|
-
this.currentPasswordEmitter.emit(this.password);
|
|
19494
|
-
this.modal.hide();
|
|
19495
|
-
}
|
|
19496
|
-
cancel() {
|
|
19497
|
-
this.currentPasswordEmitter.emit(null);
|
|
19498
|
-
this.modal.hide();
|
|
19189
|
+
cancel() {
|
|
19190
|
+
this.currentPasswordEmitter.emit(null);
|
|
19191
|
+
this.modal.hide();
|
|
19499
19192
|
}
|
|
19500
19193
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CurrentPasswordModalComponent, deps: [{ token: i1$7.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19501
19194
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: CurrentPasswordModalComponent, isStandalone: true, selector: "c8y-current-password-modal", outputs: { currentPasswordEmitter: "currentPasswordEmitter" }, ngImport: i0, template: "<c8y-modal [customFooter]=\"true\" [title]=\"'Confirm your current password' | translate\" #modal>\n <form #confirmForm=\"ngForm\" (ngSubmit)=\"confirmForm.form.valid && passwordConfirm()\">\n <div class=\"d-block p-24\">\n <c8y-form-group [hasWarning]=\"true\">\n <label translate for=\"currentPassword\">Enter your password</label>\n <input\n id=\"currentPassword\"\n [(ngModel)]=\"password\"\n type=\"password\"\n name=\"password\"\n class=\"form-control\"\n required\n />\n <c8y-messages>\n <c8y-message translate>\n The password of the user that you are currently logged in with.\n </c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\n <button\n title=\"{{ 'Cancel' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n title=\"{{ 'Confirm' | translate }}\"\n class=\"btn btn-primary\"\n [attr.data-cy]=\"'confirm-current-password-confirm-button'\"\n type=\"submit\"\n [disabled]=\"!confirmForm.form.valid\"\n >\n {{ 'Confirm' | translate }}\n </button>\n </div>\n </form>\n</c8y-modal>\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
@@ -19594,10 +19287,11 @@ class PasswordService {
|
|
|
19594
19287
|
return this.DEFAULT_PASSWORD_MIN_LENGTH;
|
|
19595
19288
|
}
|
|
19596
19289
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordService, deps: [{ token: i1$7.BsModalService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
19597
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordService }); }
|
|
19290
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordService, providedIn: 'root' }); }
|
|
19598
19291
|
}
|
|
19599
19292
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordService, decorators: [{
|
|
19600
|
-
type: Injectable
|
|
19293
|
+
type: Injectable,
|
|
19294
|
+
args: [{ providedIn: 'root' }]
|
|
19601
19295
|
}], ctorParameters: () => [{ type: i1$7.BsModalService }] });
|
|
19602
19296
|
|
|
19603
19297
|
class TotpSetupComponent {
|
|
@@ -20049,9 +19743,10 @@ class NewPasswordComponent {
|
|
|
20049
19743
|
ngModel.control.addValidators(this.passwordChecklistValidator);
|
|
20050
19744
|
}
|
|
20051
19745
|
}
|
|
20052
|
-
constructor(passwordStrength, cdRef) {
|
|
19746
|
+
constructor(passwordStrength, cdRef, elementRef) {
|
|
20053
19747
|
this.passwordStrength = passwordStrength;
|
|
20054
19748
|
this.cdRef = cdRef;
|
|
19749
|
+
this.elementRef = elementRef;
|
|
20055
19750
|
this.password = new EventEmitter();
|
|
20056
19751
|
this.showChangePasswordButton = true;
|
|
20057
19752
|
this.model = {};
|
|
@@ -20107,7 +19802,7 @@ class NewPasswordComponent {
|
|
|
20107
19802
|
this.model = {};
|
|
20108
19803
|
}
|
|
20109
19804
|
}
|
|
20110
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NewPasswordComponent, deps: [{ token: PasswordStrengthService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19805
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NewPasswordComponent, deps: [{ token: PasswordStrengthService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20111
19806
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: NewPasswordComponent, isStandalone: true, selector: "c8y-new-password", inputs: { showChangePasswordButton: "showChangePasswordButton", requireStrongPassword: "requireStrongPassword" }, outputs: { password: "password" }, viewQueries: [{ propertyName: "_newPasswordModel", first: true, predicate: ["newPassword"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"showChangePasswordButton\" class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n <ng-container *ngIf=\"!changePassword\">\n {{ 'Change password' | translate }}\n </ng-container>\n <ng-container *ngIf=\"changePassword\">\n {{ 'Cancel password change' | translate }}\n </ng-container>\n </button>\n</div>\n\n<div\n class=\"row content-flex-50\"\n *ngIf=\"changePassword\"\n>\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yDefaultValidation=\"password\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: PasswordInputComponent, selector: "c8y-password-input", inputs: ["id", "autocomplete"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: DefaultValidationDirective, selector: "[c8yDefaultValidation]", inputs: ["c8yDefaultValidation"] }, { kind: "directive", type: PasswordConfirm, selector: "[passwordConfirm]" }, { kind: "component", type: PasswordCheckListComponent, selector: "c8y-password-check-list", inputs: ["strengthEnforced", "password"], outputs: ["onRequirementsFulfilled"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
|
|
20112
19807
|
}
|
|
20113
19808
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NewPasswordComponent, decorators: [{
|
|
@@ -20123,7 +19818,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
20123
19818
|
PasswordCheckListComponent,
|
|
20124
19819
|
C8yTranslatePipe
|
|
20125
19820
|
], template: "<div *ngIf=\"showChangePasswordButton\" class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n <ng-container *ngIf=\"!changePassword\">\n {{ 'Change password' | translate }}\n </ng-container>\n <ng-container *ngIf=\"changePassword\">\n {{ 'Cancel password change' | translate }}\n </ng-container>\n </button>\n</div>\n\n<div\n class=\"row content-flex-50\"\n *ngIf=\"changePassword\"\n>\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yDefaultValidation=\"password\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n</div>\n" }]
|
|
20126
|
-
}], ctorParameters: () => [{ type: PasswordStrengthService }, { type: i0.ChangeDetectorRef }], propDecorators: { password: [{
|
|
19821
|
+
}], ctorParameters: () => [{ type: PasswordStrengthService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { password: [{
|
|
20127
19822
|
type: Output
|
|
20128
19823
|
}], showChangePasswordButton: [{
|
|
20129
19824
|
type: Input
|
|
@@ -20157,13 +19852,26 @@ class UserEditComponent {
|
|
|
20157
19852
|
this.showProductExperienceOptions = false;
|
|
20158
19853
|
this.isUsageTrackingEnabled = true;
|
|
20159
19854
|
this.isUserEngagementPreferenceEnabled = true;
|
|
19855
|
+
this.focusOnNewPassword = false;
|
|
20160
19856
|
this.onUser = new EventEmitter();
|
|
20161
19857
|
this.onUsageTrackingChange = new EventEmitter();
|
|
20162
19858
|
this.onUserEngagementPreferenceChange = new EventEmitter();
|
|
20163
19859
|
this.onCancel = new EventEmitter();
|
|
19860
|
+
this.newPasswordComponent = viewChild(NewPasswordComponent);
|
|
20164
19861
|
this.userHasActiveTotp = false;
|
|
20165
19862
|
this.userCanSetupTotp = false;
|
|
20166
19863
|
this.isPhoneRequired = false;
|
|
19864
|
+
effect(() => {
|
|
19865
|
+
if (this.focusOnNewPassword && this.newPasswordComponent()) {
|
|
19866
|
+
this.newPasswordComponent().toggleChangePassword();
|
|
19867
|
+
setTimeout(() => {
|
|
19868
|
+
this.newPasswordComponent().elementRef.nativeElement.scrollIntoView({
|
|
19869
|
+
behavior: 'smooth',
|
|
19870
|
+
block: 'center'
|
|
19871
|
+
});
|
|
19872
|
+
}, 100);
|
|
19873
|
+
}
|
|
19874
|
+
});
|
|
20167
19875
|
}
|
|
20168
19876
|
async ngOnInit() {
|
|
20169
19877
|
const currentTenant = (await this.tenantService.current()).data;
|
|
@@ -20220,7 +19928,7 @@ class UserEditComponent {
|
|
|
20220
19928
|
return loginOptions.some(({ tfaStrategy = '' }) => tfaStrategy.toLowerCase() === 'totp');
|
|
20221
19929
|
}
|
|
20222
19930
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserEditComponent, deps: [{ token: AppStateService }, { token: TranslateService }, { token: i1$7.BsModalService }, { token: AlertService }, { token: i1.UserService }, { token: i1.TenantLoginOptionsService }, { token: i1.TenantService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20223
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
19931
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.14", type: UserEditComponent, isStandalone: true, selector: "c8y-user-edit", inputs: { loading: "loading", user: "user", showProductExperienceOptions: "showProductExperienceOptions", isUsageTrackingEnabled: "isUsageTrackingEnabled", isUserEngagementPreferenceEnabled: "isUserEngagementPreferenceEnabled", focusOnNewPassword: "focusOnNewPassword" }, outputs: { onUser: "onUser", onUsageTrackingChange: "onUsageTrackingChange", onUserEngagementPreferenceChange: "onUserEngagementPreferenceChange", onCancel: "onCancel" }, viewQueries: [{ propertyName: "newPasswordComponent", first: true, predicate: NewPasswordComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<form #userForm=\"ngForm\" (ngSubmit)=\"userForm.form.valid && save()\">\n <div class=\"d-block p-24 p-b-0\">\n <div class=\"alert alert-warning\" role=\"alert\" *ngIf=\"userIsExternal\" translate>\n Some of the user settings are not editable here because they are managed via your\n authorization server.\n </div>\n <c8y-form-group>\n <label translate for=\"userName\">Username</label>\n <input\n id=\"userName\"\n class=\"form-control\"\n [(ngModel)]=\"user.userName\"\n name=\"userName\"\n autocomplete=\"off\"\n required\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [disabled]=\"user.id\"\n c8yDefaultValidation=\"user\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"displayName\">Login alias</label>\n <input\n id=\"displayName\"\n class=\"form-control\"\n [(ngModel)]=\"user.displayName\"\n name=\"displayName\"\n autocomplete=\"off\"\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe`LOCALIZE`' | translate }}\"\n [disabled]=\"userIsExternal\"\n c8yDefaultValidation=\"loginAlias\"\n />\n </c8y-form-group>\n\n <c8y-form-group [hasWarning]=\"!user.email\">\n <label translate for=\"userEmail\">Email</label>\n <input\n id=\"userEmail\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n [maxlength]=\"254\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"user.email\"\n email\n [required]=\"true\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userFirstName\">First name</label>\n <input\n id=\"userFirstName\"\n class=\"form-control\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. Joe`LOCALIZE`' | translate }}\"\n maxlength=\"50\"\n name=\"firstName\"\n [(ngModel)]=\"user.firstName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userLastName\">Last name</label>\n <input\n id=\"userLastName\"\n class=\"form-control\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. Doe`LOCALIZE`' | translate }}\"\n maxlength=\"50\"\n name=\"lastName\"\n [(ngModel)]=\"user.lastName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n </div>\n\n <c8y-form-group>\n <label translate for=\"userTelephone\">Telephone</label>\n <input\n id=\"userTelephone\"\n class=\"form-control\"\n autocomplete=\"off\"\n name=\"phone\"\n maxlength=\"254\"\n [(ngModel)]=\"user.phone\"\n placeholder=\"{{ 'e.g. +49 9 876 543 210`LOCALIZE`' | translate }}\"\n c8yPhoneValidation\n [required]=\"isPhoneRequired\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"p-t-16 separator-top\" *ngIf=\"showProductExperienceOptions\">\n <label translate>Product experience</label>\n <label class=\"c8y-switch\" for=\"productUsageTracking\">\n <input\n id=\"productUsageTracking\"\n name=\"productUsageTracking\"\n type=\"checkbox\"\n [(ngModel)]=\"isUsageTrackingEnabled\"\n />\n <span></span>\n {{ 'Enable personalized product experience tracking' | translate }}\n </label>\n <ng-container *ngIf=\"isUsageTrackingEnabled\">\n <label class=\"c8y-switch m-l-0\" for=\"userEngagementPreference\">\n <input\n id=\"userEngagementPreference\"\n name=\"userEngagementPreference\"\n type=\"checkbox\"\n [(ngModel)]=\"isUserEngagementPreferenceEnabled\"\n />\n <span></span>\n {{ 'Enable in-product information & communication' | translate }}\n </label>\n </ng-container>\n </c8y-form-group>\n\n <div class=\"form-group p-t-16 separator-top\" *ngIf=\"!userIsExternal\">\n <label class=\"control-label\">{{ 'Login options' | translate }}</label>\n <c8y-new-password (password)=\"onNewPasswordChanged($event)\"></c8y-new-password>\n <button\n class=\"btn btn-default\"\n type=\"button\"\n title=\"{{ 'Set up two-factor authentication' | translate }}\"\n (click)=\"setupTotp()\"\n *ngIf=\"userCanSetupTotp && !userHasActiveTotp && isTfaEnabled\"\n >\n {{ 'Set up two-factor authentication' | translate }}\n </button>\n </div>\n\n <c8y-form-group *ngIf=\"!!(state.state$ | async).newsletter\">\n <label translate>Newsletter</label>\n <label\n title=\"{{ 'Send me information about outages, maintenance or updates.' | translate }}\"\n class=\"c8y-checkbox\"\n >\n <input\n type=\"checkbox\"\n name=\"newsletter\"\n [(ngModel)]=\"user.newsletter\"\n [disabled]=\"userIsExternal\"\n />\n <span></span>\n <span>\n {{ 'Send me information about outages, maintenance or updates.' | translate }}\n </span>\n </label>\n </c8y-form-group>\n </div>\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n title=\"{{ 'Cancel' | translate }}\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n type=\"submit\"\n title=\"{{ 'Save' | translate }}\"\n [disabled]=\"!userForm.form.valid || userForm.form.pristine || loading\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$8.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: DefaultValidationDirective, selector: "[c8yDefaultValidation]", inputs: ["c8yDefaultValidation"] }, { kind: "directive", type: PhoneValidationDirective, selector: "[c8yPhoneValidation]" }, { kind: "component", type: NewPasswordComponent, selector: "c8y-new-password", inputs: ["showChangePasswordButton", "requireStrongPassword"], outputs: ["password"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
20224
19932
|
}
|
|
20225
19933
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserEditComponent, decorators: [{
|
|
20226
19934
|
type: Component,
|
|
@@ -20246,6 +19954,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
20246
19954
|
type: Input
|
|
20247
19955
|
}], isUserEngagementPreferenceEnabled: [{
|
|
20248
19956
|
type: Input
|
|
19957
|
+
}], focusOnNewPassword: [{
|
|
19958
|
+
type: Input
|
|
20249
19959
|
}], onUser: [{
|
|
20250
19960
|
type: Output
|
|
20251
19961
|
}], onUsageTrackingChange: [{
|
|
@@ -20272,6 +19982,7 @@ class UserEditModalComponent {
|
|
|
20272
19982
|
this.userEngagementsService = userEngagementsService;
|
|
20273
19983
|
this.loading = false;
|
|
20274
19984
|
this.showProductExperienceOptions = false;
|
|
19985
|
+
this.passwordChange = false;
|
|
20275
19986
|
}
|
|
20276
19987
|
async ngOnInit() {
|
|
20277
19988
|
this.updateUserInAppState();
|
|
@@ -20390,127 +20101,383 @@ class UserEditModalComponent {
|
|
|
20390
20101
|
this.auth.updateCredentials(newCredentials);
|
|
20391
20102
|
}
|
|
20392
20103
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserEditModalComponent, deps: [{ token: i1$7.BsModalRef }, { token: i1.UserService }, { token: AppStateService }, { token: i1.BasicAuth }, { token: i1.FetchClient }, { token: AlertService }, { token: UserPreferencesService }, { token: ModalService }, { token: GainsightService }, { token: CookieBannerService }, { token: PasswordService }, { token: UserEngagementsService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20393
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UserEditModalComponent, isStandalone: true, selector: "c8y-user-edit-modal", ngImport: i0, template: "<c8y-modal\n [title]=\"'Edit user' | translate\"\n [customFooter]=\"true\"\n (onDismiss)=\"onDismiss()\"\n>\n <c8y-user-edit\n [user]=\"ui.currentUser | async\"\n [loading]=\"loading\"\n [isUsageTrackingEnabled]=\"currentUsageTrackingState\"\n [isUserEngagementPreferenceEnabled]=\"currentUserEngagementPreferenceInitialState\"\n [showProductExperienceOptions]=\"showProductExperienceOptions\"\n (onUsageTrackingChange)=\"onUsageTrackingChange($event)\"\n (onUserEngagementPreferenceChange)=\"onUserEngagementPreferenceChange($event)\"\n (onUser)=\"updateAndClose($event)\"\n (onCancel)=\"onDismiss()\"\n ></c8y-user-edit>\n</c8y-modal>\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "component", type: UserEditComponent, selector: "c8y-user-edit", inputs: ["loading", "user", "showProductExperienceOptions", "isUsageTrackingEnabled", "isUserEngagementPreferenceEnabled"], outputs: ["onUser", "onUsageTrackingChange", "onUserEngagementPreferenceChange", "onCancel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
20104
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UserEditModalComponent, isStandalone: true, selector: "c8y-user-edit-modal", ngImport: i0, template: "<c8y-modal\n [title]=\"'Edit user' | translate\"\n [customFooter]=\"true\"\n (onDismiss)=\"onDismiss()\"\n>\n <c8y-user-edit\n [user]=\"ui.currentUser | async\"\n [loading]=\"loading\"\n [isUsageTrackingEnabled]=\"currentUsageTrackingState\"\n [isUserEngagementPreferenceEnabled]=\"currentUserEngagementPreferenceInitialState\"\n [showProductExperienceOptions]=\"showProductExperienceOptions\"\n [focusOnNewPassword]=\"passwordChange\"\n (onUsageTrackingChange)=\"onUsageTrackingChange($event)\"\n (onUserEngagementPreferenceChange)=\"onUserEngagementPreferenceChange($event)\"\n (onUser)=\"updateAndClose($event)\"\n (onCancel)=\"onDismiss()\"\n ></c8y-user-edit>\n</c8y-modal>\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "component", type: UserEditComponent, selector: "c8y-user-edit", inputs: ["loading", "user", "showProductExperienceOptions", "isUsageTrackingEnabled", "isUserEngagementPreferenceEnabled", "focusOnNewPassword"], outputs: ["onUser", "onUsageTrackingChange", "onUserEngagementPreferenceChange", "onCancel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
20394
20105
|
}
|
|
20395
20106
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserEditModalComponent, decorators: [{
|
|
20396
20107
|
type: Component,
|
|
20397
|
-
args: [{ selector: 'c8y-user-edit-modal', standalone: true, imports: [ModalComponent, UserEditComponent, C8yTranslatePipe, AsyncPipe], template: "<c8y-modal\n [title]=\"'Edit user' | translate\"\n [customFooter]=\"true\"\n (onDismiss)=\"onDismiss()\"\n>\n <c8y-user-edit\n [user]=\"ui.currentUser | async\"\n [loading]=\"loading\"\n [isUsageTrackingEnabled]=\"currentUsageTrackingState\"\n [isUserEngagementPreferenceEnabled]=\"currentUserEngagementPreferenceInitialState\"\n [showProductExperienceOptions]=\"showProductExperienceOptions\"\n (onUsageTrackingChange)=\"onUsageTrackingChange($event)\"\n (onUserEngagementPreferenceChange)=\"onUserEngagementPreferenceChange($event)\"\n (onUser)=\"updateAndClose($event)\"\n (onCancel)=\"onDismiss()\"\n ></c8y-user-edit>\n</c8y-modal>\n" }]
|
|
20108
|
+
args: [{ selector: 'c8y-user-edit-modal', standalone: true, imports: [ModalComponent, UserEditComponent, C8yTranslatePipe, AsyncPipe], template: "<c8y-modal\n [title]=\"'Edit user' | translate\"\n [customFooter]=\"true\"\n (onDismiss)=\"onDismiss()\"\n>\n <c8y-user-edit\n [user]=\"ui.currentUser | async\"\n [loading]=\"loading\"\n [isUsageTrackingEnabled]=\"currentUsageTrackingState\"\n [isUserEngagementPreferenceEnabled]=\"currentUserEngagementPreferenceInitialState\"\n [showProductExperienceOptions]=\"showProductExperienceOptions\"\n [focusOnNewPassword]=\"passwordChange\"\n (onUsageTrackingChange)=\"onUsageTrackingChange($event)\"\n (onUserEngagementPreferenceChange)=\"onUserEngagementPreferenceChange($event)\"\n (onUser)=\"updateAndClose($event)\"\n (onCancel)=\"onDismiss()\"\n ></c8y-user-edit>\n</c8y-modal>\n" }]
|
|
20398
20109
|
}], ctorParameters: () => [{ type: i1$7.BsModalRef }, { type: i1.UserService }, { type: AppStateService }, { type: i1.BasicAuth }, { type: i1.FetchClient }, { type: AlertService }, { type: UserPreferencesService }, { type: ModalService }, { type: GainsightService }, { type: CookieBannerService }, { type: PasswordService }, { type: UserEngagementsService }] });
|
|
20399
20110
|
|
|
20400
|
-
|
|
20401
|
-
|
|
20402
|
-
|
|
20403
|
-
|
|
20404
|
-
|
|
20405
|
-
this.
|
|
20406
|
-
this.
|
|
20407
|
-
this.items$ = this.userMenu.items$;
|
|
20408
|
-
this.open$ = this.headerService.rightDrawerOpen$;
|
|
20111
|
+
/**
|
|
20112
|
+
* Service to show a modal.
|
|
20113
|
+
*/
|
|
20114
|
+
class ModalService {
|
|
20115
|
+
constructor(modalService, gainsightService) {
|
|
20116
|
+
this.modalService = modalService;
|
|
20117
|
+
this.gainsightService = gainsightService;
|
|
20409
20118
|
}
|
|
20410
|
-
|
|
20411
|
-
|
|
20119
|
+
/**
|
|
20120
|
+
* Shows a quick confirm message modal.
|
|
20121
|
+
* @param title The title of that modal.
|
|
20122
|
+
* @param body The text body to display.
|
|
20123
|
+
* @param status The status.
|
|
20124
|
+
* @param labels The labels to use. Default: { ok: 'Confirm', cancel: 'Cancel'}
|
|
20125
|
+
* @param confirmOptions Selection options to display as checkbox list.
|
|
20126
|
+
* @param productExperienceEvent Additional data to attach to custom product experience events.
|
|
20127
|
+
*/
|
|
20128
|
+
async confirm(title, body, status = Status.INFO, labels = {}, confirmOptions = {}, productExperienceEvent = { eventName: 'confirmModal' }) {
|
|
20129
|
+
const modalLabels = {
|
|
20130
|
+
ok: labels.ok || gettext$1('Confirm'),
|
|
20131
|
+
cancel: labels.cancel || gettext$1('Cancel')
|
|
20132
|
+
};
|
|
20133
|
+
const modalRef = this.modalService.show(ConfirmModalComponent, {
|
|
20134
|
+
initialState: { title, body, labels: modalLabels, status, confirmOptions },
|
|
20412
20135
|
ariaDescribedby: 'modal-body',
|
|
20413
|
-
ariaLabelledBy: 'modal-title'
|
|
20136
|
+
ariaLabelledBy: 'modal-title',
|
|
20137
|
+
ignoreBackdropClick: true
|
|
20414
20138
|
});
|
|
20139
|
+
if (productExperienceEvent) {
|
|
20140
|
+
productExperienceEvent.data = { ...productExperienceEvent.data, title };
|
|
20141
|
+
}
|
|
20142
|
+
this.triggerEvent(modalRef.content.result, modalLabels, productExperienceEvent);
|
|
20143
|
+
return await modalRef.content.result;
|
|
20415
20144
|
}
|
|
20416
|
-
|
|
20417
|
-
|
|
20418
|
-
|
|
20419
|
-
|
|
20420
|
-
|
|
20421
|
-
|
|
20422
|
-
|
|
20423
|
-
|
|
20424
|
-
|
|
20425
|
-
|
|
20426
|
-
|
|
20427
|
-
|
|
20428
|
-
|
|
20429
|
-
|
|
20430
|
-
|
|
20431
|
-
|
|
20432
|
-
|
|
20433
|
-
|
|
20434
|
-
}
|
|
20435
|
-
this.
|
|
20436
|
-
|
|
20437
|
-
color: 'rgb(255, 204, 51)',
|
|
20438
|
-
description: gettext$1('medium'),
|
|
20439
|
-
passwordStrength: PasswordStrength.YELLOW
|
|
20440
|
-
};
|
|
20441
|
-
this.RED = {
|
|
20442
|
-
colorName: 'red',
|
|
20443
|
-
color: 'rgb(170, 0, 51)',
|
|
20444
|
-
description: gettext$1('weak'),
|
|
20445
|
-
passwordStrength: PasswordStrength.RED
|
|
20446
|
-
};
|
|
20145
|
+
/**
|
|
20146
|
+
* Shows a quick acknowledge message modal.
|
|
20147
|
+
* @param title The title of that modal.
|
|
20148
|
+
* @param body The text body to display.
|
|
20149
|
+
* @param status The status.
|
|
20150
|
+
* @param acknowledgeLabel The label to use.
|
|
20151
|
+
* @param productExperienceEvent Additional data to attach to custom product experience events.
|
|
20152
|
+
*/
|
|
20153
|
+
async acknowledge(title, body, status = Status.INFO, acknowledgeLabel = gettext$1('Confirm'), productExperienceEvent = { eventName: 'confirmModal' }) {
|
|
20154
|
+
const labels = { ok: acknowledgeLabel, cancel: null };
|
|
20155
|
+
const modalRef = this.modalService.show(ConfirmModalComponent, {
|
|
20156
|
+
initialState: { title, body, labels, status },
|
|
20157
|
+
ariaDescribedby: 'modal-body',
|
|
20158
|
+
ariaLabelledBy: 'modal-title',
|
|
20159
|
+
ignoreBackdropClick: true
|
|
20160
|
+
});
|
|
20161
|
+
if (productExperienceEvent) {
|
|
20162
|
+
productExperienceEvent.data = { ...productExperienceEvent.data, title };
|
|
20163
|
+
}
|
|
20164
|
+
this.triggerEvent(modalRef.content.result, labels, productExperienceEvent);
|
|
20165
|
+
return await modalRef.content.result;
|
|
20447
20166
|
}
|
|
20448
|
-
|
|
20449
|
-
|
|
20167
|
+
/**
|
|
20168
|
+
* Shows a quick logout confirmation modal.
|
|
20169
|
+
* @param body The text body to display. Default: 'You will be logged out to apply your changes. Do you want to proceed?'
|
|
20170
|
+
* @param status The status.
|
|
20171
|
+
* @param labels The labels to use. Default: { ok: 'Confirm and log out', cancel: 'Cancel' }
|
|
20172
|
+
*/
|
|
20173
|
+
async confirmLogout(body, status = Status.WARNING, labels = {}) {
|
|
20174
|
+
const modalLabels = {
|
|
20175
|
+
ok: labels.ok || gettext$1('Confirm and log out'),
|
|
20176
|
+
cancel: labels.cancel || gettext$1('Cancel')
|
|
20177
|
+
};
|
|
20178
|
+
const modalBody = body || gettext$1('You must log out to apply your changes. Do you want to proceed?');
|
|
20179
|
+
return await this.confirm(gettext$1('Logout required'), modalBody, status, modalLabels);
|
|
20450
20180
|
}
|
|
20451
|
-
|
|
20452
|
-
|
|
20181
|
+
async changeCurrentUserPassword() {
|
|
20182
|
+
this.modalService.show(UserEditModalComponent, {
|
|
20183
|
+
initialState: { passwordChange: true },
|
|
20184
|
+
ariaDescribedby: 'modal-body',
|
|
20185
|
+
ariaLabelledBy: 'modal-title'
|
|
20186
|
+
});
|
|
20453
20187
|
}
|
|
20454
|
-
|
|
20455
|
-
|
|
20188
|
+
triggerEvent(result, labels, productExperienceEvent) {
|
|
20189
|
+
const data = { ...productExperienceEvent.data, url: window.location.href };
|
|
20190
|
+
result
|
|
20191
|
+
.then(() => {
|
|
20192
|
+
this.gainsightService.triggerEvent(productExperienceEvent.eventName, {
|
|
20193
|
+
...data,
|
|
20194
|
+
result: labels.ok
|
|
20195
|
+
});
|
|
20196
|
+
})
|
|
20197
|
+
.catch(() => {
|
|
20198
|
+
this.gainsightService.triggerEvent(productExperienceEvent.eventName, {
|
|
20199
|
+
...data,
|
|
20200
|
+
result: labels.cancel
|
|
20201
|
+
});
|
|
20202
|
+
});
|
|
20456
20203
|
}
|
|
20457
|
-
|
|
20458
|
-
|
|
20204
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalService, deps: [{ token: i1$7.BsModalService }, { token: GainsightService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
20205
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalService, providedIn: 'root' }); }
|
|
20206
|
+
}
|
|
20207
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ModalService, decorators: [{
|
|
20208
|
+
type: Injectable,
|
|
20209
|
+
args: [{
|
|
20210
|
+
providedIn: 'root'
|
|
20211
|
+
}]
|
|
20212
|
+
}], ctorParameters: () => [{ type: i1$7.BsModalService }, { type: GainsightService }] });
|
|
20213
|
+
|
|
20214
|
+
class ThemeSwitcherService {
|
|
20215
|
+
constructor(options) {
|
|
20216
|
+
this.options = options;
|
|
20217
|
+
this.darkThemeClass = `c8y-dark-theme`;
|
|
20218
|
+
this.themeOptions = [
|
|
20219
|
+
{
|
|
20220
|
+
label: gettext$1('Light'),
|
|
20221
|
+
value: 'light',
|
|
20222
|
+
icon: 'sun'
|
|
20223
|
+
},
|
|
20224
|
+
{
|
|
20225
|
+
label: gettext$1('Dark'),
|
|
20226
|
+
value: 'dark',
|
|
20227
|
+
icon: 'moon'
|
|
20228
|
+
},
|
|
20229
|
+
{
|
|
20230
|
+
label: gettext$1('System'),
|
|
20231
|
+
value: 'system',
|
|
20232
|
+
icon: 'imac-settings'
|
|
20233
|
+
}
|
|
20234
|
+
];
|
|
20235
|
+
this._userSelectedThemePreference$ = new BehaviorSubject(this.getCurrentThemePreference());
|
|
20236
|
+
this._temporaryThemePreference$ = new BehaviorSubject('none');
|
|
20237
|
+
this.userSelectedThemePreference$ = this._userSelectedThemePreference$.asObservable();
|
|
20238
|
+
const userSelectedTheme$ = this.userSelectedThemePreference$.pipe(switchMap(preference => {
|
|
20239
|
+
if (preference === 'system') {
|
|
20240
|
+
return this.getUsersSystemPreferenceForTheme$();
|
|
20241
|
+
}
|
|
20242
|
+
return of(preference);
|
|
20243
|
+
}));
|
|
20244
|
+
this.disableThemeSelection$ = this._temporaryThemePreference$.pipe(map(preference => preference !== 'none'));
|
|
20245
|
+
this.currentlyAppliedTheme$ = this._temporaryThemePreference$.pipe(switchMap(temporaryPreference => {
|
|
20246
|
+
if (temporaryPreference !== 'none') {
|
|
20247
|
+
return of(temporaryPreference);
|
|
20248
|
+
}
|
|
20249
|
+
return userSelectedTheme$;
|
|
20250
|
+
}));
|
|
20251
|
+
this.darkThemeAvailable$ = this.options.get$('darkThemeAvailable').pipe(map(value => !!value));
|
|
20459
20252
|
}
|
|
20460
|
-
|
|
20461
|
-
const
|
|
20462
|
-
|
|
20463
|
-
|
|
20464
|
-
this.hasNumbers(password),
|
|
20465
|
-
this.hasSpecialChars(password)
|
|
20466
|
-
]).length;
|
|
20467
|
-
if (passwordStrength > 3) {
|
|
20468
|
-
return this.GREEN;
|
|
20469
|
-
}
|
|
20470
|
-
else if (passwordStrength >= 3) {
|
|
20471
|
-
return this.YELLOW;
|
|
20472
|
-
}
|
|
20473
|
-
else {
|
|
20474
|
-
return this.RED;
|
|
20253
|
+
getCurrentThemePreference() {
|
|
20254
|
+
const value = getThemePreference();
|
|
20255
|
+
if (value === 'system' || value === 'dark') {
|
|
20256
|
+
return value;
|
|
20475
20257
|
}
|
|
20258
|
+
return 'light';
|
|
20476
20259
|
}
|
|
20477
|
-
|
|
20478
|
-
|
|
20260
|
+
getUsersSystemPreferenceForTheme$() {
|
|
20261
|
+
return fromEvent(window.matchMedia('(prefers-color-scheme: dark)'), 'change').pipe(startWith(window.matchMedia('(prefers-color-scheme: dark)')), map((e) => (e.matches ? 'dark' : 'light')));
|
|
20262
|
+
}
|
|
20263
|
+
changeUserPreference(preference) {
|
|
20264
|
+
setThemePreference(preference);
|
|
20265
|
+
this._userSelectedThemePreference$.next(preference);
|
|
20266
|
+
this.applyTheme(preference);
|
|
20267
|
+
}
|
|
20268
|
+
temporaryChangeTheme(preference) {
|
|
20269
|
+
this._temporaryThemePreference$.next(preference);
|
|
20270
|
+
this.applyTheme(preference);
|
|
20271
|
+
}
|
|
20272
|
+
resetTemporaryTheme() {
|
|
20273
|
+
this._temporaryThemePreference$.next('none');
|
|
20274
|
+
this.applyTheme(this.getCurrentThemePreference());
|
|
20275
|
+
}
|
|
20276
|
+
applyTheme(preference) {
|
|
20277
|
+
applyTheme(preference);
|
|
20278
|
+
}
|
|
20279
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ThemeSwitcherService, deps: [{ token: OptionsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
20280
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ThemeSwitcherService, providedIn: 'root' }); }
|
|
20479
20281
|
}
|
|
20480
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type:
|
|
20481
|
-
type: Injectable
|
|
20482
|
-
|
|
20282
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ThemeSwitcherService, decorators: [{
|
|
20283
|
+
type: Injectable,
|
|
20284
|
+
args: [{
|
|
20285
|
+
providedIn: 'root'
|
|
20286
|
+
}]
|
|
20287
|
+
}], ctorParameters: () => [{ type: OptionsService }] });
|
|
20483
20288
|
|
|
20484
|
-
|
|
20485
|
-
|
|
20486
|
-
|
|
20487
|
-
|
|
20488
|
-
|
|
20489
|
-
|
|
20490
|
-
|
|
20491
|
-
|
|
20289
|
+
class UiSettingsComponent {
|
|
20290
|
+
constructor(translate, state, ui, userPreferences, c8yModalService, headerService, themeSwitcher) {
|
|
20291
|
+
this.translate = translate;
|
|
20292
|
+
this.state = state;
|
|
20293
|
+
this.ui = ui;
|
|
20294
|
+
this.userPreferences = userPreferences;
|
|
20295
|
+
this.c8yModalService = c8yModalService;
|
|
20296
|
+
this.headerService = headerService;
|
|
20297
|
+
this.themeSwitcher = themeSwitcher;
|
|
20298
|
+
this.destroyed$ = new Subject();
|
|
20299
|
+
this.currentLang = this.ui.state.lang;
|
|
20300
|
+
this.ui.state$
|
|
20301
|
+
.pipe(filter(({ lang }) => lang !== this.currentLang), takeUntil(this.destroyed$), first$1())
|
|
20302
|
+
.subscribe(({ lang }) => (this.currentLang = lang));
|
|
20303
|
+
this.open$ = this.headerService.rightDrawerOpen$;
|
|
20304
|
+
}
|
|
20305
|
+
ngOnInit() {
|
|
20306
|
+
this.languages = this.state.state.langs.map(l => ({
|
|
20307
|
+
lang: l,
|
|
20308
|
+
nativeLanguage: this.translate.getNativeLanguage(l)
|
|
20309
|
+
}));
|
|
20310
|
+
}
|
|
20311
|
+
ngOnDestroy() {
|
|
20312
|
+
this.destroyed$.next();
|
|
20313
|
+
this.destroyed$.complete();
|
|
20314
|
+
}
|
|
20315
|
+
async onLanguageChange(changedLang) {
|
|
20316
|
+
if (!changedLang) {
|
|
20317
|
+
return;
|
|
20318
|
+
}
|
|
20319
|
+
await this.translate.switchToLanguage(changedLang);
|
|
20320
|
+
if (await this.persistLanguage(changedLang)) {
|
|
20321
|
+
location.reload();
|
|
20492
20322
|
}
|
|
20493
20323
|
}
|
|
20494
|
-
|
|
20495
|
-
|
|
20496
|
-
|
|
20497
|
-
|
|
20324
|
+
async persistLanguage(lang) {
|
|
20325
|
+
let shouldReload = true;
|
|
20326
|
+
try {
|
|
20327
|
+
await this.c8yModalService.confirm(gettext$1('Reload recommended'), gettext$1('To change the language in the entire application, we recommend you to reload the page. If you have any unsaved changes, you can reload later. How would you like to proceed?'), Status.WARNING, {
|
|
20328
|
+
ok: gettext$1('Reload now'),
|
|
20329
|
+
cancel: gettext$1('Reload later')
|
|
20330
|
+
});
|
|
20331
|
+
}
|
|
20332
|
+
catch (ex) {
|
|
20333
|
+
shouldReload = false;
|
|
20334
|
+
}
|
|
20335
|
+
finally {
|
|
20336
|
+
this.translate.saveInLocalStorage(lang);
|
|
20337
|
+
await this.userPreferences.set('language', lang);
|
|
20338
|
+
this.currentLang = lang;
|
|
20339
|
+
}
|
|
20340
|
+
return shouldReload;
|
|
20498
20341
|
}
|
|
20499
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type:
|
|
20500
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type:
|
|
20342
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsComponent, deps: [{ token: TranslateService }, { token: AppStateService }, { token: AppStateService }, { token: UserPreferencesService }, { token: ModalService }, { token: HeaderService }, { token: ThemeSwitcherService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20343
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UiSettingsComponent, isStandalone: true, selector: "c8y-ui-settings", ngImport: i0, template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"eyedropper\"></i>\n <span class=\"text-bold\">{{ 'UI settings' | translate }}</span>\n </div>\n\n <div\n class=\"p-l-16 p-r-16 p-b-16\"\n *ngIf=\"themeSwitcher.darkThemeAvailable$ | async\"\n >\n <p translate>Theme</p>\n <div\n class=\"c8y-switch-multistate\"\n *ngIf=\"themeSwitcher.userSelectedThemePreference$ | async as themePreference\"\n >\n <ng-container *ngFor=\"let themeOption of themeSwitcher.themeOptions; index as i\">\n <input\n [attr.aria-label]=\"themeOption.label\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n name=\"theme-switcher\"\n type=\"radio\"\n [id]=\"'theme-option-' + i\"\n [disabled]=\"themeSwitcher.disableThemeSelection$ | async\"\n [checked]=\"themePreference === themeOption.value\"\n (click)=\"themeSwitcher.changeUserPreference(themeOption.value)\"\n />\n <label\n title=\"{{ themeOption.label | translate }}\"\n [for]=\"'theme-option-' + i\"\n >\n <i [c8yIcon]=\"themeOption.icon\"></i>\n </label>\n </ng-container>\n <div class=\"c8y-switch-multistate__handle\"></div>\n </div>\n </div>\n\n <div class=\"form-group p-l-16 p-r-16\">\n <label\n for=\"userLang\"\n translate\n >\n Language\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n #selectLang\n [ngModel]=\"currentLang\"\n (change)=\"onLanguageChange(selectLang.value)\"\n >\n <option\n *ngFor=\"let language of languages\"\n [value]=\"language.lang\"\n >\n {{ language.nativeLanguage }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
20501
20344
|
}
|
|
20502
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type:
|
|
20345
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsComponent, decorators: [{
|
|
20503
20346
|
type: Component,
|
|
20504
|
-
args: [{ selector: 'c8y-
|
|
20505
|
-
|
|
20506
|
-
|
|
20507
|
-
|
|
20508
|
-
|
|
20509
|
-
|
|
20510
|
-
|
|
20511
|
-
|
|
20512
|
-
|
|
20513
|
-
|
|
20347
|
+
args: [{ selector: 'c8y-ui-settings', standalone: true, imports: [
|
|
20348
|
+
IconDirective,
|
|
20349
|
+
NgIf,
|
|
20350
|
+
C8yTranslateDirective,
|
|
20351
|
+
NgFor,
|
|
20352
|
+
FormsModule$1,
|
|
20353
|
+
C8yTranslatePipe,
|
|
20354
|
+
AsyncPipe
|
|
20355
|
+
], template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"eyedropper\"></i>\n <span class=\"text-bold\">{{ 'UI settings' | translate }}</span>\n </div>\n\n <div\n class=\"p-l-16 p-r-16 p-b-16\"\n *ngIf=\"themeSwitcher.darkThemeAvailable$ | async\"\n >\n <p translate>Theme</p>\n <div\n class=\"c8y-switch-multistate\"\n *ngIf=\"themeSwitcher.userSelectedThemePreference$ | async as themePreference\"\n >\n <ng-container *ngFor=\"let themeOption of themeSwitcher.themeOptions; index as i\">\n <input\n [attr.aria-label]=\"themeOption.label\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n name=\"theme-switcher\"\n type=\"radio\"\n [id]=\"'theme-option-' + i\"\n [disabled]=\"themeSwitcher.disableThemeSelection$ | async\"\n [checked]=\"themePreference === themeOption.value\"\n (click)=\"themeSwitcher.changeUserPreference(themeOption.value)\"\n />\n <label\n title=\"{{ themeOption.label | translate }}\"\n [for]=\"'theme-option-' + i\"\n >\n <i [c8yIcon]=\"themeOption.icon\"></i>\n </label>\n </ng-container>\n <div class=\"c8y-switch-multistate__handle\"></div>\n </div>\n </div>\n\n <div class=\"form-group p-l-16 p-r-16\">\n <label\n for=\"userLang\"\n translate\n >\n Language\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n tabindex=\"{{ (open$ | async) ? '0' : '-1' }}\"\n #selectLang\n [ngModel]=\"currentLang\"\n (change)=\"onLanguageChange(selectLang.value)\"\n >\n <option\n *ngFor=\"let language of languages\"\n [value]=\"language.lang\"\n >\n {{ language.nativeLanguage }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n</div>\n" }]
|
|
20356
|
+
}], ctorParameters: () => [{ type: TranslateService }, { type: AppStateService }, { type: AppStateService }, { type: UserPreferencesService }, { type: ModalService }, { type: HeaderService }, { type: ThemeSwitcherService }] });
|
|
20357
|
+
|
|
20358
|
+
class UiSettingsModule {
|
|
20359
|
+
static providers() {
|
|
20360
|
+
return [
|
|
20361
|
+
hookDrawer({
|
|
20362
|
+
component: UiSettingsComponent,
|
|
20363
|
+
position: 'right',
|
|
20364
|
+
priority: 90,
|
|
20365
|
+
id: 'uiSettings'
|
|
20366
|
+
})
|
|
20367
|
+
];
|
|
20368
|
+
}
|
|
20369
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
20370
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, imports: [CommonModule, FormsModule$1, UiSettingsComponent], exports: [UiSettingsComponent] }); }
|
|
20371
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, imports: [CommonModule, FormsModule$1, UiSettingsComponent] }); }
|
|
20372
|
+
}
|
|
20373
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UiSettingsModule, decorators: [{
|
|
20374
|
+
type: NgModule,
|
|
20375
|
+
args: [{
|
|
20376
|
+
imports: [CommonModule, FormsModule$1, UiSettingsComponent],
|
|
20377
|
+
exports: [UiSettingsComponent]
|
|
20378
|
+
}]
|
|
20379
|
+
}] });
|
|
20380
|
+
|
|
20381
|
+
class UserMenuItemComponent {
|
|
20382
|
+
constructor(userService, headerService) {
|
|
20383
|
+
this.userService = userService;
|
|
20384
|
+
this.headerService = headerService;
|
|
20385
|
+
this.priority = 0;
|
|
20386
|
+
this.click = new EventEmitter();
|
|
20387
|
+
this.open$ = this.headerService.rightDrawerOpen$;
|
|
20388
|
+
}
|
|
20389
|
+
ngAfterViewInit() {
|
|
20390
|
+
this.viewInitTimeout = setTimeout(() => this.userService.add(this));
|
|
20391
|
+
}
|
|
20392
|
+
ngOnDestroy() {
|
|
20393
|
+
clearTimeout(this.viewInitTimeout);
|
|
20394
|
+
this.userService.remove(this);
|
|
20395
|
+
}
|
|
20396
|
+
onClick() {
|
|
20397
|
+
this.click.emit(this);
|
|
20398
|
+
}
|
|
20399
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserMenuItemComponent, deps: [{ token: UserMenuService }, { token: HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20400
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UserMenuItemComponent, isStandalone: true, selector: "c8y-user-menu-item", inputs: { icon: "icon", label: "label", link: "link", target: "target", priority: "priority", dataCy: "dataCy" }, outputs: { click: "click" }, viewQueries: [{ propertyName: "template", first: true, predicate: ["template"], descendants: true }], ngImport: i0, template: "<ng-template #template>\n <li>\n <a\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n *ngIf=\"link\"\n [attr.href]=\"link\"\n [attr.target]=\"target\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </a>\n <button\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n *ngIf=\"!link\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </button>\n </li>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
20401
|
+
}
|
|
20402
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserMenuItemComponent, decorators: [{
|
|
20403
|
+
type: Component,
|
|
20404
|
+
args: [{ selector: 'c8y-user-menu-item', standalone: true, imports: [NgIf, C8yTranslatePipe, AsyncPipe], template: "<ng-template #template>\n <li>\n <a\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n *ngIf=\"link\"\n [attr.href]=\"link\"\n [attr.target]=\"target\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </a>\n <button\n class=\"c8y-right-drawer__link\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n *ngIf=\"!link\"\n (click)=\"onClick()\"\n [attr.data-cy]=\"dataCy\"\n >\n {{ label | translate }}\n <ng-content></ng-content>\n </button>\n </li>\n</ng-template>\n" }]
|
|
20405
|
+
}], ctorParameters: () => [{ type: UserMenuService }, { type: HeaderService }], propDecorators: { icon: [{
|
|
20406
|
+
type: Input
|
|
20407
|
+
}], label: [{
|
|
20408
|
+
type: Input
|
|
20409
|
+
}], link: [{
|
|
20410
|
+
type: Input
|
|
20411
|
+
}], target: [{
|
|
20412
|
+
type: Input
|
|
20413
|
+
}], priority: [{
|
|
20414
|
+
type: Input
|
|
20415
|
+
}], dataCy: [{
|
|
20416
|
+
type: Input
|
|
20417
|
+
}], template: [{
|
|
20418
|
+
type: ViewChild,
|
|
20419
|
+
args: ['template', { static: false }]
|
|
20420
|
+
}], click: [{
|
|
20421
|
+
type: Output
|
|
20422
|
+
}] } });
|
|
20423
|
+
|
|
20424
|
+
class UserMenuOutletComponent {
|
|
20425
|
+
constructor(ui, bsModalService, authService, userMenu, headerService) {
|
|
20426
|
+
this.ui = ui;
|
|
20427
|
+
this.bsModalService = bsModalService;
|
|
20428
|
+
this.authService = authService;
|
|
20429
|
+
this.userMenu = userMenu;
|
|
20430
|
+
this.headerService = headerService;
|
|
20431
|
+
this.items$ = this.userMenu.items$;
|
|
20432
|
+
this.open$ = this.headerService.rightDrawerOpen$;
|
|
20433
|
+
}
|
|
20434
|
+
async editUser() {
|
|
20435
|
+
this.bsModalService.show(UserEditModalComponent, {
|
|
20436
|
+
ariaDescribedby: 'modal-body',
|
|
20437
|
+
ariaLabelledBy: 'modal-title'
|
|
20438
|
+
});
|
|
20439
|
+
}
|
|
20440
|
+
async logout() {
|
|
20441
|
+
await this.authService.logout();
|
|
20442
|
+
}
|
|
20443
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserMenuOutletComponent, deps: [{ token: AppStateService }, { token: i1$7.BsModalService }, { token: SimplifiedAuthService }, { token: UserMenuService }, { token: HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20444
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UserMenuOutletComponent, isStandalone: true, selector: "c8y-user-menu-outlet", ngImport: i0, template: "<ng-container *ngIf=\"items$ | async as items\">\n <div\n class=\"p-t-8 p-b-8\"\n *ngIf=\"items.length\"\n >\n <ul class=\"list-unstyled m-b-0\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container *ngIf=\"item.template\">\n <ng-container *c8yOutlet=\"item.template\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"!item.template\">\n <li>\n <button\n class=\"c8y-right-drawer__link\"\n [attr.aria-label]=\"item.label | translate\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"item.click()\"\n [attr.href]=\"item.link\"\n [attr.target]=\"item.target\"\n >\n {{ item.label | translate }}\n </button>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n</ng-container>\n\n<!-- the default items -->\n<c8y-user-menu-item\n [icon]=\"'user-menu-male'\"\n *ngIf=\"(ui.currentUser | async) && (ui.currentUser | async).id !== 'NO_LOGIN'\"\n [label]=\"'User settings' | translate\"\n [priority]=\"20\"\n [dataCy]=\"'user-menu-user-settings-button'\"\n (click)=\"editUser()\"\n></c8y-user-menu-item>\n<c8y-user-menu-item\n [icon]=\"'sign-out'\"\n *ngIf=\"(ui.currentUser | async) && (ui.currentUser | async).id !== 'NO_LOGIN'\"\n [label]=\"'Logout' | translate\"\n [dataCy]=\"'user-menu-logout-button'\"\n (click)=\"logout()\"\n></c8y-user-menu-item>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: OutletDirective, selector: "[c8yOutlet]", inputs: ["c8yOutlet", "c8yOutletProperties", "c8yOutletInjector"] }, { kind: "component", type: UserMenuItemComponent, selector: "c8y-user-menu-item", inputs: ["icon", "label", "link", "target", "priority", "dataCy"], outputs: ["click"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
20445
|
+
}
|
|
20446
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserMenuOutletComponent, decorators: [{
|
|
20447
|
+
type: Component,
|
|
20448
|
+
args: [{ selector: 'c8y-user-menu-outlet', standalone: true, imports: [NgIf, NgFor, OutletDirective, UserMenuItemComponent, C8yTranslatePipe, AsyncPipe], template: "<ng-container *ngIf=\"items$ | async as items\">\n <div\n class=\"p-t-8 p-b-8\"\n *ngIf=\"items.length\"\n >\n <ul class=\"list-unstyled m-b-0\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container *ngIf=\"item.template\">\n <ng-container *c8yOutlet=\"item.template\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"!item.template\">\n <li>\n <button\n class=\"c8y-right-drawer__link\"\n [attr.aria-label]=\"item.label | translate\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"item.click()\"\n [attr.href]=\"item.link\"\n [attr.target]=\"item.target\"\n >\n {{ item.label | translate }}\n </button>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n</ng-container>\n\n<!-- the default items -->\n<c8y-user-menu-item\n [icon]=\"'user-menu-male'\"\n *ngIf=\"(ui.currentUser | async) && (ui.currentUser | async).id !== 'NO_LOGIN'\"\n [label]=\"'User settings' | translate\"\n [priority]=\"20\"\n [dataCy]=\"'user-menu-user-settings-button'\"\n (click)=\"editUser()\"\n></c8y-user-menu-item>\n<c8y-user-menu-item\n [icon]=\"'sign-out'\"\n *ngIf=\"(ui.currentUser | async) && (ui.currentUser | async).id !== 'NO_LOGIN'\"\n [label]=\"'Logout' | translate\"\n [dataCy]=\"'user-menu-logout-button'\"\n (click)=\"logout()\"\n></c8y-user-menu-item>\n" }]
|
|
20449
|
+
}], ctorParameters: () => [{ type: AppStateService }, { type: i1$7.BsModalService }, { type: SimplifiedAuthService }, { type: UserMenuService }, { type: HeaderService }] });
|
|
20450
|
+
|
|
20451
|
+
/**
|
|
20452
|
+
* @deprecated: [MTM-56403] Password strength indicator removed from UI in favor of the enhanced password strength check list.
|
|
20453
|
+
*/
|
|
20454
|
+
class PasswordStrengthComponent {
|
|
20455
|
+
set password(password) {
|
|
20456
|
+
if (typeof password === 'string') {
|
|
20457
|
+
this.model = this.passwordStrengthCheckerService.getStrengthColor(password);
|
|
20458
|
+
this.strength.emit(this.model);
|
|
20459
|
+
}
|
|
20460
|
+
}
|
|
20461
|
+
constructor(passwordStrengthCheckerService) {
|
|
20462
|
+
this.passwordStrengthCheckerService = passwordStrengthCheckerService;
|
|
20463
|
+
this.strength = new EventEmitter();
|
|
20464
|
+
this.password = '';
|
|
20465
|
+
}
|
|
20466
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordStrengthComponent, deps: [{ token: PasswordService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20467
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PasswordStrengthComponent, isStandalone: true, selector: "c8y-password-strength", inputs: { password: "password" }, outputs: { strength: "strength" }, ngImport: i0, template: "<div class=\"password-strength password-{{ model.colorName }}\">\r\n <label class=\"password-strength-label small\" translate>\r\n Password strength\r\n </label>\r\n <div>\r\n <div class=\"password-bar\"></div>\r\n </div>\r\n <span class=\"small\">\r\n {{ model.description | translate }}\r\n </span>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
20468
|
+
}
|
|
20469
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordStrengthComponent, decorators: [{
|
|
20470
|
+
type: Component,
|
|
20471
|
+
args: [{ selector: 'c8y-password-strength', standalone: true, imports: [C8yTranslateDirective, C8yTranslatePipe], template: "<div class=\"password-strength password-{{ model.colorName }}\">\r\n <label class=\"password-strength-label small\" translate>\r\n Password strength\r\n </label>\r\n <div>\r\n <div class=\"password-bar\"></div>\r\n </div>\r\n <span class=\"small\">\r\n {{ model.description | translate }}\r\n </span>\r\n</div>\r\n" }]
|
|
20472
|
+
}], ctorParameters: () => [{ type: PasswordService }], propDecorators: { password: [{
|
|
20473
|
+
type: Input,
|
|
20474
|
+
args: ['password']
|
|
20475
|
+
}], strength: [{
|
|
20476
|
+
type: Output
|
|
20477
|
+
}] } });
|
|
20478
|
+
|
|
20479
|
+
/**
|
|
20480
|
+
* The angular module definition for new password.
|
|
20514
20481
|
* @exports PasswordStrengthComponent
|
|
20515
20482
|
* @exports PasswordCheckListComponent
|
|
20516
20483
|
* @exports PasswordConfirm
|
|
@@ -20541,7 +20508,7 @@ class AuthenticationModule {
|
|
|
20541
20508
|
CurrentPasswordModalComponent,
|
|
20542
20509
|
TotpSetupComponent,
|
|
20543
20510
|
PasswordInputComponent] }); }
|
|
20544
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AuthenticationModule,
|
|
20511
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AuthenticationModule, imports: [FormsModule,
|
|
20545
20512
|
TooltipModule,
|
|
20546
20513
|
CommonModule,
|
|
20547
20514
|
ModalModule,
|
|
@@ -20581,8 +20548,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
20581
20548
|
CurrentPasswordModalComponent,
|
|
20582
20549
|
TotpSetupComponent,
|
|
20583
20550
|
PasswordInputComponent
|
|
20584
|
-
]
|
|
20585
|
-
providers: [PasswordStrengthCheckerService, PasswordService]
|
|
20551
|
+
]
|
|
20586
20552
|
}]
|
|
20587
20553
|
}] });
|
|
20588
20554
|
|
|
@@ -20827,769 +20793,770 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
20827
20793
|
}]
|
|
20828
20794
|
}] });
|
|
20829
20795
|
|
|
20830
|
-
|
|
20831
|
-
(
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
20835
|
-
|
|
20836
|
-
|
|
20837
|
-
|
|
20838
|
-
|
|
20839
|
-
|
|
20840
|
-
|
|
20841
|
-
* A package coming from the official Cumulocity github enterprise.
|
|
20842
|
-
*/
|
|
20843
|
-
PackageType["OFFICIAL"] = "OFFICIAL";
|
|
20844
|
-
/**
|
|
20845
|
-
* A package coming from any connected partner repository.
|
|
20846
|
-
*/
|
|
20847
|
-
PackageType["COMMUNITY"] = "COMMUNITY";
|
|
20848
|
-
/**
|
|
20849
|
-
* A package where the origin is unknown (e.g. uploaded to management with an unknown label)
|
|
20850
|
-
*/
|
|
20851
|
-
PackageType["UNKNOWN"] = "UNKNOWN";
|
|
20852
|
-
/**
|
|
20853
|
-
* A custom package e.g. uploaded to the tenant by a user
|
|
20854
|
-
*/
|
|
20855
|
-
PackageType["CUSTOM"] = "CUSTOM";
|
|
20856
|
-
/**
|
|
20857
|
-
* A package that was archived by the user
|
|
20858
|
-
*/
|
|
20859
|
-
PackageType["ARCHIVED"] = "ARCHIVED";
|
|
20860
|
-
})(PackageType || (PackageType = {}));
|
|
20796
|
+
class PluginsModule {
|
|
20797
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PluginsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
20798
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: PluginsModule }); }
|
|
20799
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PluginsModule }); }
|
|
20800
|
+
}
|
|
20801
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PluginsModule, decorators: [{
|
|
20802
|
+
type: NgModule,
|
|
20803
|
+
args: [{
|
|
20804
|
+
providers: []
|
|
20805
|
+
}]
|
|
20806
|
+
}] });
|
|
20861
20807
|
|
|
20862
|
-
|
|
20863
|
-
|
|
20864
|
-
|
|
20808
|
+
/**
|
|
20809
|
+
* An extension HOOK can use either a pure value:
|
|
20810
|
+
* ```typescript
|
|
20811
|
+
* { provide: HOOK_X, useValue: { ...hookValue }, multi: true }
|
|
20812
|
+
* ```
|
|
20813
|
+
*
|
|
20814
|
+
* Or an array to directly register multiple:
|
|
20815
|
+
* ```typescript
|
|
20816
|
+
* { provide: HOOK_X, useValue: [{ ...hookValues }], multi: true }
|
|
20817
|
+
* ```
|
|
20818
|
+
*
|
|
20819
|
+
* Or an ExtensionFactory which allows to define a get() function. This function
|
|
20820
|
+
* gets called on each navigation with the current route and can return values
|
|
20821
|
+
* async (observable or promise).
|
|
20822
|
+
* ```typescript
|
|
20823
|
+
* { provide: HOOK_X, useFactory: { get: (route) => doSomethingAsync(route) }, multi: true }
|
|
20824
|
+
* ```
|
|
20825
|
+
* @deprecated Consider using the `hookVersion` function instead.
|
|
20826
|
+
*/
|
|
20827
|
+
const HOOK_VERSION = new InjectionToken('HOOK_VERSION');
|
|
20828
|
+
const VERSION_MODULE_CONFIG = new InjectionToken('VERSION_MODULE_CONFIG');
|
|
20829
|
+
/**
|
|
20830
|
+
* You can either provide a single `Version` as parameter:
|
|
20831
|
+
* ```typescript
|
|
20832
|
+
* hookVersion(...)
|
|
20833
|
+
* ```
|
|
20834
|
+
*
|
|
20835
|
+
* Or an array to directly register multiple:
|
|
20836
|
+
* ```typescript
|
|
20837
|
+
* hookVersion([...])
|
|
20838
|
+
* ```
|
|
20839
|
+
*
|
|
20840
|
+
* Or you provide an Service that implements `ExtensionFactory<Version>`
|
|
20841
|
+
* ```typescript
|
|
20842
|
+
* export class MyVersionFactory implements ExtensionFactory<Version> {...}
|
|
20843
|
+
* ...
|
|
20844
|
+
* hookVersion(MyVersionFactory)
|
|
20845
|
+
* ```
|
|
20846
|
+
* A typed alternative to `HOOK_VERSION`.
|
|
20847
|
+
* @param versions The `Version`'s or `ExtensionFactory` to be provided.
|
|
20848
|
+
* @returns An `Provider` to be provided in your module.
|
|
20849
|
+
*/
|
|
20850
|
+
function hookVersion(versions, options) {
|
|
20851
|
+
return hookGeneric(versions, HOOK_VERSION, options);
|
|
20852
|
+
}
|
|
20853
|
+
|
|
20854
|
+
/**
|
|
20855
|
+
* Will provide the backend versions of the tenant.
|
|
20856
|
+
* The system option 'system' -> 'version' is used for this.
|
|
20857
|
+
*/
|
|
20858
|
+
class BackendVersionFactory {
|
|
20859
|
+
constructor(config, appState) {
|
|
20860
|
+
this.config = config;
|
|
20861
|
+
this.appState = appState;
|
|
20862
|
+
this.backendVersion$ = of([]);
|
|
20863
|
+
if (this.config?.disableBackendVersionFactory) {
|
|
20865
20864
|
return;
|
|
20866
20865
|
}
|
|
20867
|
-
|
|
20868
|
-
const plugins = [];
|
|
20869
|
-
importContextPaths.forEach(contextPath => {
|
|
20870
|
-
const moduleNames = remotes[contextPath] || [];
|
|
20871
|
-
plugins.push(...moduleNames.map(module => PluginsService.createPluginId(contextPath, module, '', true)));
|
|
20872
|
-
});
|
|
20873
|
-
return plugins;
|
|
20866
|
+
this.backendVersion$ = this.appState.state$.pipe(map(state => state?.versions?.backend), filter(backendVersion => !!backendVersion), distinctUntilChanged(), map(backendVersion => this.buildBackendVersion(backendVersion)), shareReplay(1));
|
|
20874
20867
|
}
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
if (useLatest) {
|
|
20878
|
-
return `${contextPath}/${moduleName}`;
|
|
20879
|
-
}
|
|
20880
|
-
return `${contextPath}@${version}/${moduleName}`;
|
|
20868
|
+
get() {
|
|
20869
|
+
return this.backendVersion$;
|
|
20881
20870
|
}
|
|
20882
|
-
|
|
20883
|
-
|
|
20884
|
-
|
|
20885
|
-
|
|
20871
|
+
buildBackendVersion(backendVersion) {
|
|
20872
|
+
return {
|
|
20873
|
+
label: gettext$1('Backend'),
|
|
20874
|
+
version: backendVersion,
|
|
20875
|
+
priority: 20,
|
|
20876
|
+
type: 'SYSTEM',
|
|
20877
|
+
hidden: true
|
|
20878
|
+
};
|
|
20886
20879
|
}
|
|
20887
|
-
|
|
20888
|
-
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20880
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BackendVersionFactory, deps: [{ token: VERSION_MODULE_CONFIG, optional: true }, { token: AppStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
20881
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BackendVersionFactory, providedIn: 'root' }); }
|
|
20882
|
+
}
|
|
20883
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BackendVersionFactory, decorators: [{
|
|
20884
|
+
type: Injectable,
|
|
20885
|
+
args: [{
|
|
20886
|
+
providedIn: 'root'
|
|
20887
|
+
}]
|
|
20888
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
20889
|
+
type: Optional
|
|
20890
|
+
}, {
|
|
20891
|
+
type: Inject,
|
|
20892
|
+
args: [VERSION_MODULE_CONFIG]
|
|
20893
|
+
}] }, { type: AppStateService }] });
|
|
20894
|
+
|
|
20895
|
+
class VersionService extends ExtensionPointForPlugins {
|
|
20896
|
+
constructor(rootInjector, pluginService) {
|
|
20897
|
+
super(rootInjector, pluginService);
|
|
20898
|
+
this.items$ = this.setupItemsObservable();
|
|
20899
|
+
this.nonHiddenItems$ = this.items$.pipe(map(versions => versions.filter(version => !version.hidden)));
|
|
20897
20900
|
}
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
* @param application Application managed object.
|
|
20901
|
-
* @returns Returns true if the application is a package.
|
|
20902
|
-
*/
|
|
20903
|
-
isPackage(application) {
|
|
20904
|
-
return application.manifest?.isPackage === true;
|
|
20901
|
+
get state() {
|
|
20902
|
+
return this.state$.value;
|
|
20905
20903
|
}
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
* remotes will not be added. Make sure that this object exists in the application configuration.
|
|
20910
|
-
* @param application Application managed object.
|
|
20911
|
-
* @param plugins List of remotes to be added.
|
|
20912
|
-
* @returns Returns updated application remotes.
|
|
20913
|
-
*/
|
|
20914
|
-
async addRemotes(application, plugins) {
|
|
20915
|
-
const pluginsArray = Array.isArray(plugins) ? plugins : [plugins];
|
|
20916
|
-
const manifestRemotes = application.manifest?.remotes || {};
|
|
20917
|
-
const appConfig = application?.config;
|
|
20918
|
-
const appConfigRemotes = appConfig?.remotes || manifestRemotes;
|
|
20919
|
-
const appConfigExcludedRemotes = appConfig?.excludedRemotes || {};
|
|
20920
|
-
// only normal and self optional scoped plugins should be added to remotes
|
|
20921
|
-
// self scoped plugins will be automatically added
|
|
20922
|
-
const allPluginsExceptSelfScoped = this.getAllPluginsExceptSelfScoped(pluginsArray, application.contextPath);
|
|
20923
|
-
const newRemotes = this.addPluginToRemotesConfig(appConfigRemotes, allPluginsExceptSelfScoped);
|
|
20924
|
-
// should be unproblematic to remove all categories of plugins from excluded remotes
|
|
20925
|
-
const newExcludedRemotes = this.removePluginsFromRemotesConfig(appConfigExcludedRemotes, plugins);
|
|
20926
|
-
return await this.updateRemotesInAppConfig(application, newRemotes, newExcludedRemotes);
|
|
20904
|
+
add(version) {
|
|
20905
|
+
this.state.add(version);
|
|
20906
|
+
this.emitNewState();
|
|
20927
20907
|
}
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
20931
|
-
* @param plugins List of remotes to be removed.
|
|
20932
|
-
* @returns Returns updated application remotes.
|
|
20933
|
-
*/
|
|
20934
|
-
async removeRemotes(application, plugins) {
|
|
20935
|
-
const pluginsArray = Array.isArray(plugins) ? plugins : [plugins];
|
|
20936
|
-
const manifestRemotes = application.manifest?.remotes || {};
|
|
20937
|
-
const appConfig = application?.config;
|
|
20938
|
-
const appConfigRemotes = appConfig?.remotes || manifestRemotes;
|
|
20939
|
-
const appConfigExcludedRemotes = appConfig?.excludedRemotes || {};
|
|
20940
|
-
// app plugins need to be removed from remotes
|
|
20941
|
-
const newRemotes = this.removePluginsFromRemotesConfig(appConfigRemotes, plugins);
|
|
20942
|
-
// self scoped plugins need to be added to excluded remotes
|
|
20943
|
-
// as they would be otherwise automatically added to remotes
|
|
20944
|
-
const selfScopedPlugins = this.getSelfScopedPlugins(pluginsArray, application.contextPath);
|
|
20945
|
-
const newExcludedRemotes = this.addPluginToRemotesConfig(appConfigExcludedRemotes, selfScopedPlugins);
|
|
20946
|
-
return await this.updateRemotesInAppConfig(application, newRemotes, newExcludedRemotes);
|
|
20908
|
+
remove(version) {
|
|
20909
|
+
this.state.delete(version);
|
|
20910
|
+
this.emitNewState();
|
|
20947
20911
|
}
|
|
20948
|
-
|
|
20949
|
-
|
|
20950
|
-
* @param application Application managed object.
|
|
20951
|
-
* @param plugins List of remotes to be added.
|
|
20952
|
-
* @returns Returns updated application remotes.
|
|
20953
|
-
*/
|
|
20954
|
-
async updateRemotesInAppConfig(application, plugins, excludedRemotes) {
|
|
20955
|
-
const updatedAppWithConfig = await this.applicationService.updateApplicationConfig(application, {
|
|
20956
|
-
remotes: plugins,
|
|
20957
|
-
excludedRemotes: excludedRemotes || {}
|
|
20958
|
-
});
|
|
20959
|
-
return updatedAppWithConfig?.config || { remotes: {} };
|
|
20912
|
+
cleanUpVersions(versions) {
|
|
20913
|
+
return versions.map(version => pick(version, 'label', 'version', 'type', 'custom'));
|
|
20960
20914
|
}
|
|
20961
|
-
|
|
20962
|
-
|
|
20963
|
-
|
|
20964
|
-
|
|
20965
|
-
|
|
20966
|
-
|
|
20967
|
-
const c8yJson = await this.applicationService.getAppManifest(application);
|
|
20968
|
-
if (!c8yJson.remotes) {
|
|
20969
|
-
c8yJson.remotes = {};
|
|
20970
|
-
}
|
|
20971
|
-
return c8yJson;
|
|
20915
|
+
setupItemsObservable() {
|
|
20916
|
+
return fromTriggerOnce(undefined, this.refresh$, [
|
|
20917
|
+
getInjectedHooks(HOOK_VERSION, this.injectors),
|
|
20918
|
+
() => this.factories,
|
|
20919
|
+
stateToFactory(this.state$)
|
|
20920
|
+
]).pipe(distinctUntilChanged(), map(versions => sortByPriority(versions)), shareReplay(1));
|
|
20972
20921
|
}
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
|
|
20976
|
-
|
|
20977
|
-
|
|
20978
|
-
|
|
20979
|
-
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
|
|
20983
|
-
|
|
20984
|
-
|
|
20985
|
-
|
|
20986
|
-
|
|
20922
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionService, deps: [{ token: i0.Injector }, { token: PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
20923
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionService, providedIn: 'root' }); }
|
|
20924
|
+
}
|
|
20925
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionService, decorators: [{
|
|
20926
|
+
type: Injectable,
|
|
20927
|
+
args: [{
|
|
20928
|
+
providedIn: 'root'
|
|
20929
|
+
}]
|
|
20930
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: PluginsResolveService }] });
|
|
20931
|
+
|
|
20932
|
+
class PlatformDetailsService {
|
|
20933
|
+
constructor(version, appState, apps) {
|
|
20934
|
+
this.version = version;
|
|
20935
|
+
this.appState = appState;
|
|
20936
|
+
this.apps = apps;
|
|
20987
20937
|
}
|
|
20988
|
-
async
|
|
20989
|
-
|
|
20990
|
-
|
|
20991
|
-
|
|
20992
|
-
|
|
20938
|
+
async getPlatformDetailsObject() {
|
|
20939
|
+
const currentUser = this.appState.currentUser.value;
|
|
20940
|
+
const userId = currentUser?.id;
|
|
20941
|
+
const userPermissions = this.getUserPermissions(currentUser);
|
|
20942
|
+
const [hookedVersions, microserviceVersions] = await Promise.all([
|
|
20943
|
+
this.getVersions(),
|
|
20944
|
+
this.getMicroserviceVersions(userId)
|
|
20945
|
+
]);
|
|
20946
|
+
const versions = [...hookedVersions, ...microserviceVersions];
|
|
20947
|
+
const groupedVersions = groupBy(versions, 'type');
|
|
20948
|
+
const tenantId = this.appState.currentTenant.value?.name;
|
|
20949
|
+
// useful as `domainName` might be pointing to a custom domain
|
|
20950
|
+
// self link should still allow to identify the actual environment of the tenant
|
|
20951
|
+
const tenantSelfLink = this.appState.currentTenant.value?.self;
|
|
20952
|
+
const tenantDomainName = this.appState.currentTenant.value?.domainName;
|
|
20953
|
+
const applicationKey = this.appState.currentApplication.value?.key;
|
|
20954
|
+
const applicationId = this.appState.currentApplication.value?.id;
|
|
20955
|
+
const time = new Date().toISOString();
|
|
20956
|
+
const url = document.URL;
|
|
20957
|
+
const obj = {
|
|
20958
|
+
time,
|
|
20959
|
+
tenantId,
|
|
20960
|
+
tenantSelfLink,
|
|
20961
|
+
tenantDomainName,
|
|
20962
|
+
url,
|
|
20963
|
+
userId,
|
|
20964
|
+
userPermissions,
|
|
20965
|
+
applicationId,
|
|
20966
|
+
applicationKey,
|
|
20967
|
+
versions: groupedVersions
|
|
20968
|
+
};
|
|
20969
|
+
return obj;
|
|
20993
20970
|
}
|
|
20994
|
-
|
|
20995
|
-
const
|
|
20996
|
-
|
|
20997
|
-
|
|
20998
|
-
|
|
20971
|
+
async getVersions() {
|
|
20972
|
+
const versions = await this.version.items$
|
|
20973
|
+
.pipe(take(1), map(versions => this.version.cleanUpVersions(versions)))
|
|
20974
|
+
.toPromise();
|
|
20975
|
+
return versions;
|
|
20976
|
+
}
|
|
20977
|
+
async getMicroserviceVersions(userId) {
|
|
20978
|
+
try {
|
|
20979
|
+
const { data: apps } = await this.apps.listByUser(userId, {
|
|
20980
|
+
pageSize: 2000,
|
|
20981
|
+
dropOverwrittenApps: true,
|
|
20982
|
+
noPaging: true
|
|
20983
|
+
});
|
|
20984
|
+
return apps
|
|
20985
|
+
.filter(app => !!app.manifest?.version && app.type === ApplicationType.MICROSERVICE)
|
|
20986
|
+
.map(app => {
|
|
20987
|
+
return {
|
|
20988
|
+
label: app.name,
|
|
20989
|
+
version: app.manifest.version,
|
|
20990
|
+
type: app.type,
|
|
20991
|
+
custom: {
|
|
20992
|
+
owner: app.owner?.tenant?.id,
|
|
20993
|
+
provider: app.manifest?.provider
|
|
20994
|
+
}
|
|
20995
|
+
};
|
|
20996
|
+
});
|
|
20999
20997
|
}
|
|
21000
|
-
|
|
21001
|
-
|
|
20998
|
+
catch (e) {
|
|
20999
|
+
console.warn(e);
|
|
21000
|
+
return [];
|
|
21002
21001
|
}
|
|
21003
21002
|
}
|
|
21004
|
-
|
|
21005
|
-
|
|
21006
|
-
|
|
21007
|
-
* @param useLatest Set this to true, to not bind the plugin to any version.
|
|
21008
|
-
* @returns Returns a list of exported plugins.
|
|
21009
|
-
*/
|
|
21010
|
-
getMFExports(application, excludedScopes = [
|
|
21011
|
-
PluginsExportScopes.SELF,
|
|
21012
|
-
PluginsExportScopes.SELF_OPTIONAL,
|
|
21013
|
-
PluginsExportScopes.GLOBAL
|
|
21014
|
-
], useLatest = false) {
|
|
21015
|
-
const manifest = application.manifest;
|
|
21016
|
-
if (!manifest || !manifest.exports) {
|
|
21017
|
-
return [];
|
|
21003
|
+
getUserPermissions(user) {
|
|
21004
|
+
if (!user) {
|
|
21005
|
+
return null;
|
|
21018
21006
|
}
|
|
21019
|
-
|
|
21020
|
-
|
|
21021
|
-
|
|
21022
|
-
}, useLatest).filter(plugin => !excludedScopes.includes(plugin.scope));
|
|
21007
|
+
const userPermissions = this.getDirectPermissionsOfUser(user);
|
|
21008
|
+
const groupPermissions = this.getPermissionsOfAssignedGroups(user);
|
|
21009
|
+
return { user: userPermissions, groups: groupPermissions };
|
|
21023
21010
|
}
|
|
21024
|
-
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
|
|
21029
|
-
|
|
21030
|
-
|
|
21031
|
-
|
|
21032
|
-
|
|
21033
|
-
|
|
21034
|
-
|
|
21035
|
-
|
|
21036
|
-
|
|
21037
|
-
|
|
21038
|
-
|
|
21039
|
-
|
|
21040
|
-
|
|
21041
|
-
|
|
21042
|
-
|
|
21043
|
-
|
|
21044
|
-
|
|
21011
|
+
getDirectPermissionsOfUser(user) {
|
|
21012
|
+
const userChangedType = user;
|
|
21013
|
+
const userRoleReferences = userChangedType.roles?.references || [];
|
|
21014
|
+
return userRoleReferences.map(ref => ref.role.id);
|
|
21015
|
+
}
|
|
21016
|
+
getPermissionsOfAssignedGroups(user) {
|
|
21017
|
+
const groups = user.groups?.references || [];
|
|
21018
|
+
return groups.map(ref => {
|
|
21019
|
+
const roleReferences = ref.group?.roles?.references || [];
|
|
21020
|
+
const permissions = roleReferences.map(ref => ref.role.id);
|
|
21021
|
+
return {
|
|
21022
|
+
id: ref.group.id,
|
|
21023
|
+
name: ref.group.name,
|
|
21024
|
+
permissions
|
|
21025
|
+
};
|
|
21026
|
+
});
|
|
21027
|
+
}
|
|
21028
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PlatformDetailsService, deps: [{ token: VersionService }, { token: AppStateService }, { token: i1.ApplicationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21029
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PlatformDetailsService, providedIn: 'root' }); }
|
|
21030
|
+
}
|
|
21031
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PlatformDetailsService, decorators: [{
|
|
21032
|
+
type: Injectable,
|
|
21033
|
+
args: [{ providedIn: 'root' }]
|
|
21034
|
+
}], ctorParameters: () => [{ type: VersionService }, { type: AppStateService }, { type: i1.ApplicationService }] });
|
|
21035
|
+
|
|
21036
|
+
class VersionListComponent {
|
|
21037
|
+
constructor(version, appState, clipboardService, modalService, platformDetails, headerService) {
|
|
21038
|
+
this.version = version;
|
|
21039
|
+
this.appState = appState;
|
|
21040
|
+
this.clipboardService = clipboardService;
|
|
21041
|
+
this.modalService = modalService;
|
|
21042
|
+
this.platformDetails = platformDetails;
|
|
21043
|
+
this.headerService = headerService;
|
|
21044
|
+
this.versionsToDirectlyDisplay$ = this.version.nonHiddenItems$;
|
|
21045
|
+
this.currentTenantId$ = this.appState.currentTenant.pipe(map(tenant => tenant?.name), filter(tenantId => !!tenantId), distinctUntilChanged());
|
|
21046
|
+
this.open$ = this.headerService.rightDrawerOpen$;
|
|
21047
|
+
}
|
|
21048
|
+
async downloadPlatformDetails() {
|
|
21049
|
+
const obj = await this.platformDetails.getPlatformDetailsObject();
|
|
21050
|
+
const json = JSON.stringify(obj, undefined, 2);
|
|
21051
|
+
const blob = new Blob([json]);
|
|
21052
|
+
saveAs$1(blob, 'platform-details.json');
|
|
21053
|
+
}
|
|
21054
|
+
copyIt(text) {
|
|
21055
|
+
this.clipboardService.writeText(text);
|
|
21056
|
+
}
|
|
21057
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionListComponent, deps: [{ token: VersionService }, { token: AppStateService }, { token: ClipboardService }, { token: i1$7.BsModalService }, { token: PlatformDetailsService }, { token: HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
21058
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: VersionListComponent, isStandalone: true, selector: "c8y-version-list", ngImport: i0, template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"c8y-c8y-c\"></i>\n <span class=\"text-bold\">{{ 'Platform info' | translate }}</span>\n </div>\n\n <ul class=\"list-unstyled\">\n <li\n class=\"c8y-right-drawer__item\"\n *ngIf=\"currentTenantId$ | async as tenantId\"\n >\n <span\n class=\"flex-grow text-muted m-0 text-12 text-truncate\"\n translate\n >\n Tenant ID\n </span>\n <button\n class=\"m-l-auto flex-no-shrink btn-clean p-0 btn-link\"\n title=\"{{ 'Copy tenant ID to the clipboard' | translate }}\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"$event.stopPropagation(); copyIt(tenantId)\"\n >\n {{ tenantId }}\n <i\n class=\"text-14 m-0\"\n [c8yIcon]=\"'clipboard'\"\n ></i>\n </button>\n </li>\n <li\n class=\"c8y-right-drawer__item\"\n *ngFor=\"let versionEntry of versionsToDirectlyDisplay$ | async\"\n >\n <span\n class=\"flex-no-shrink text-muted text-12 text-truncate m-r-8\"\n [title]=\"versionEntry.label | translate\"\n >\n {{ versionEntry.label | translate }}\n </span>\n <span\n class=\"flex-grow text-right text-truncate\"\n [title]=\"versionEntry.version | translate\"\n >\n {{ versionEntry.version }}\n </span>\n </li>\n <li class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n title=\"{{ 'Download platform details' | translate }}\"\n (click)=\"downloadPlatformDetails()\"\n >\n <i c8yIcon=\"download\" class=\"m-t-0 m-b-0 text-14\"></i>\n <span translate>Download platform details</span>\n </button>\n </li>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
21059
|
+
}
|
|
21060
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionListComponent, decorators: [{
|
|
21061
|
+
type: Component,
|
|
21062
|
+
args: [{ selector: 'c8y-version-list', standalone: true, imports: [IconDirective, NgIf, C8yTranslateDirective, NgFor, C8yTranslatePipe, AsyncPipe], template: "<div class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"c8y-c8y-c\"></i>\n <span class=\"text-bold\">{{ 'Platform info' | translate }}</span>\n </div>\n\n <ul class=\"list-unstyled\">\n <li\n class=\"c8y-right-drawer__item\"\n *ngIf=\"currentTenantId$ | async as tenantId\"\n >\n <span\n class=\"flex-grow text-muted m-0 text-12 text-truncate\"\n translate\n >\n Tenant ID\n </span>\n <button\n class=\"m-l-auto flex-no-shrink btn-clean p-0 btn-link\"\n title=\"{{ 'Copy tenant ID to the clipboard' | translate }}\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"$event.stopPropagation(); copyIt(tenantId)\"\n >\n {{ tenantId }}\n <i\n class=\"text-14 m-0\"\n [c8yIcon]=\"'clipboard'\"\n ></i>\n </button>\n </li>\n <li\n class=\"c8y-right-drawer__item\"\n *ngFor=\"let versionEntry of versionsToDirectlyDisplay$ | async\"\n >\n <span\n class=\"flex-no-shrink text-muted text-12 text-truncate m-r-8\"\n [title]=\"versionEntry.label | translate\"\n >\n {{ versionEntry.label | translate }}\n </span>\n <span\n class=\"flex-grow text-right text-truncate\"\n [title]=\"versionEntry.version | translate\"\n >\n {{ versionEntry.version }}\n </span>\n </li>\n <li class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.tabindex]=\"(open$ | async) ? '0' : '-1'\"\n title=\"{{ 'Download platform details' | translate }}\"\n (click)=\"downloadPlatformDetails()\"\n >\n <i c8yIcon=\"download\" class=\"m-t-0 m-b-0 text-14\"></i>\n <span translate>Download platform details</span>\n </button>\n </li>\n </ul>\n</div>\n" }]
|
|
21063
|
+
}], ctorParameters: () => [{ type: VersionService }, { type: AppStateService }, { type: ClipboardService }, { type: i1$7.BsModalService }, { type: PlatformDetailsService }, { type: HeaderService }] });
|
|
21064
|
+
|
|
21065
|
+
class VersionDrawerFactory {
|
|
21066
|
+
constructor(options) {
|
|
21067
|
+
this.options = options;
|
|
21068
|
+
this.drawerItem = {
|
|
21069
|
+
component: VersionListComponent,
|
|
21070
|
+
position: 'right',
|
|
21071
|
+
priority: 80,
|
|
21072
|
+
id: 'platformInformation'
|
|
21073
|
+
};
|
|
21074
|
+
}
|
|
21075
|
+
get() {
|
|
21076
|
+
return this.shouldShowPlatformInformation$().pipe(distinctUntilChanged(), map(shouldShowPlatformInformation => {
|
|
21077
|
+
if (shouldShowPlatformInformation) {
|
|
21078
|
+
return this.drawerItem;
|
|
21045
21079
|
}
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21049
|
-
|
|
21050
|
-
|
|
21080
|
+
return [];
|
|
21081
|
+
}));
|
|
21082
|
+
}
|
|
21083
|
+
shouldShowPlatformInformation$() {
|
|
21084
|
+
return combineLatest([
|
|
21085
|
+
this.options.get$('hidePowered'),
|
|
21086
|
+
this.options.get$('hidePlatformInformation')
|
|
21087
|
+
]).pipe(map(([hidePowered, hidePlatformInformation]) => {
|
|
21088
|
+
if (hidePlatformInformation === undefined) {
|
|
21089
|
+
return !hidePowered;
|
|
21051
21090
|
}
|
|
21052
|
-
|
|
21053
|
-
|
|
21091
|
+
return !hidePlatformInformation;
|
|
21092
|
+
}));
|
|
21054
21093
|
}
|
|
21094
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionDrawerFactory, deps: [{ token: OptionsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21095
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionDrawerFactory }); }
|
|
21096
|
+
}
|
|
21097
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionDrawerFactory, decorators: [{
|
|
21098
|
+
type: Injectable
|
|
21099
|
+
}], ctorParameters: () => [{ type: OptionsService }] });
|
|
21100
|
+
|
|
21101
|
+
var ApplicationPluginStatus;
|
|
21102
|
+
(function (ApplicationPluginStatus) {
|
|
21103
|
+
ApplicationPluginStatus["ORPHANED"] = "ORPHANED";
|
|
21104
|
+
ApplicationPluginStatus["LATEST"] = "LATEST";
|
|
21105
|
+
ApplicationPluginStatus["OUTDATED"] = "OUTDATED";
|
|
21106
|
+
ApplicationPluginStatus["REVOKED"] = "REVOKED";
|
|
21107
|
+
ApplicationPluginStatus["AUTO"] = "AUTO";
|
|
21108
|
+
})(ApplicationPluginStatus || (ApplicationPluginStatus = {}));
|
|
21109
|
+
var PackageType;
|
|
21110
|
+
(function (PackageType) {
|
|
21055
21111
|
/**
|
|
21056
|
-
*
|
|
21057
|
-
* @param application Application managed object.
|
|
21058
|
-
* @returns Returns list of remotes.
|
|
21112
|
+
* A package coming from the official Cumulocity github enterprise.
|
|
21059
21113
|
*/
|
|
21060
|
-
|
|
21061
|
-
const manifest = application.manifest || {};
|
|
21062
|
-
const config = application?.config;
|
|
21063
|
-
let remotes = config?.remotes || manifest.remotes || {};
|
|
21064
|
-
const manifestExports = manifest.exports || manifest.manifest?.exports || [];
|
|
21065
|
-
const selfRemotes = manifestExports
|
|
21066
|
-
.filter(plugin => plugin.scope === PluginsExportScopes.SELF)
|
|
21067
|
-
.map(plugin => plugin.module || plugin.name);
|
|
21068
|
-
if (selfRemotes.length) {
|
|
21069
|
-
remotes = mergeRemotes([{ [application.contextPath]: selfRemotes }, remotes]);
|
|
21070
|
-
}
|
|
21071
|
-
remotes = removeRemotes(remotes, config?.excludedRemotes);
|
|
21072
|
-
return remotes;
|
|
21073
|
-
}
|
|
21114
|
+
PackageType["OFFICIAL"] = "OFFICIAL";
|
|
21074
21115
|
/**
|
|
21075
|
-
*
|
|
21076
|
-
* A package is OFFICIAL if it comes from management tenant and has a label attached called OFFICIAL.
|
|
21077
|
-
* A package is COMMUNITY if it has a label called COMMUNITY.
|
|
21078
|
-
* A package is CUSTOM if it does not have any label attached.
|
|
21079
|
-
* A package is UNKNOWN if it has a label attached but it does not match COMMUNITY or OFFICIAL.
|
|
21080
|
-
*
|
|
21081
|
-
* Labels can be used to identify the status of a package. Community packages always need
|
|
21082
|
-
* a license validation. The label will be shown on the application card to tell a user
|
|
21083
|
-
* whether they are looking into an official or community package.
|
|
21084
|
-
*
|
|
21085
|
-
* @param packageApplication The package application object to check.
|
|
21086
|
-
* @returns The package type.
|
|
21116
|
+
* A package coming from any connected partner repository.
|
|
21087
21117
|
*/
|
|
21088
|
-
|
|
21089
|
-
const label = packageApplication.label || packageApplication.manifest?.label;
|
|
21090
|
-
if (label === PackageType.ARCHIVED) {
|
|
21091
|
-
return PackageType.ARCHIVED;
|
|
21092
|
-
}
|
|
21093
|
-
if (!label) {
|
|
21094
|
-
return PackageType.CUSTOM;
|
|
21095
|
-
}
|
|
21096
|
-
if (label === PackageType.OFFICIAL && this.isOwnedByManagement(packageApplication)) {
|
|
21097
|
-
return PackageType.OFFICIAL;
|
|
21098
|
-
}
|
|
21099
|
-
if (label === PackageType.COMMUNITY) {
|
|
21100
|
-
return PackageType.COMMUNITY;
|
|
21101
|
-
}
|
|
21102
|
-
return PackageType.UNKNOWN;
|
|
21103
|
-
}
|
|
21118
|
+
PackageType["COMMUNITY"] = "COMMUNITY";
|
|
21104
21119
|
/**
|
|
21105
|
-
*
|
|
21106
|
-
*
|
|
21107
|
-
* @param app The application to verify.
|
|
21108
|
-
* @returns True if owned by management tenant.
|
|
21120
|
+
* A package where the origin is unknown (e.g. uploaded to management with an unknown label)
|
|
21109
21121
|
*/
|
|
21110
|
-
|
|
21111
|
-
|
|
21112
|
-
|
|
21113
|
-
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21117
|
-
|
|
21118
|
-
|
|
21119
|
-
|
|
21120
|
-
|
|
21121
|
-
|
|
21122
|
-
|
|
21123
|
-
|
|
21124
|
-
|
|
21125
|
-
type: PackageType.CUSTOM
|
|
21126
|
-
}));
|
|
21127
|
-
return extendedPlugins;
|
|
21128
|
-
}
|
|
21129
|
-
async getReadmeFileContent(baseUrl) {
|
|
21130
|
-
return this.getFileContent(baseUrl, 'readme');
|
|
21131
|
-
}
|
|
21132
|
-
async getChangelogFileContent(baseUrl) {
|
|
21133
|
-
return this.getFileContent(baseUrl, 'changelog');
|
|
21134
|
-
}
|
|
21135
|
-
async getFileContent(baseUrl, fileType) {
|
|
21136
|
-
const file = await this.getFile(baseUrl, fileType);
|
|
21137
|
-
if (file.status === 200) {
|
|
21138
|
-
return await file.text();
|
|
21122
|
+
PackageType["UNKNOWN"] = "UNKNOWN";
|
|
21123
|
+
/**
|
|
21124
|
+
* A custom package e.g. uploaded to the tenant by a user
|
|
21125
|
+
*/
|
|
21126
|
+
PackageType["CUSTOM"] = "CUSTOM";
|
|
21127
|
+
/**
|
|
21128
|
+
* A package that was archived by the user
|
|
21129
|
+
*/
|
|
21130
|
+
PackageType["ARCHIVED"] = "ARCHIVED";
|
|
21131
|
+
})(PackageType || (PackageType = {}));
|
|
21132
|
+
|
|
21133
|
+
class PluginsService {
|
|
21134
|
+
static convertInstalledRemotesToIds(remotes) {
|
|
21135
|
+
if (!remotes) {
|
|
21136
|
+
return;
|
|
21139
21137
|
}
|
|
21140
|
-
|
|
21138
|
+
const importContextPaths = Object.keys(remotes);
|
|
21139
|
+
const plugins = [];
|
|
21140
|
+
importContextPaths.forEach(contextPath => {
|
|
21141
|
+
const moduleNames = remotes[contextPath] || [];
|
|
21142
|
+
plugins.push(...moduleNames.map(module => PluginsService.createPluginId(contextPath, module, '', true)));
|
|
21143
|
+
});
|
|
21144
|
+
return plugins;
|
|
21141
21145
|
}
|
|
21142
|
-
|
|
21143
|
-
const
|
|
21144
|
-
|
|
21145
|
-
|
|
21146
|
-
};
|
|
21147
|
-
const uppercaseFilename = fileType === 'readme' ? 'README.md' : 'CHANGELOG.md';
|
|
21148
|
-
let result = await this.client.fetch(`${baseUrl}${uppercaseFilename}`, options);
|
|
21149
|
-
if (result && result.status === 404) {
|
|
21150
|
-
result = await this.client.fetch(`${baseUrl}${uppercaseFilename.toLowerCase()}`, options);
|
|
21146
|
+
static createPluginId(contextPath, plugin, version, useLatest = false) {
|
|
21147
|
+
const moduleName = typeof plugin === 'string' ? plugin : plugin.module;
|
|
21148
|
+
if (useLatest) {
|
|
21149
|
+
return `${contextPath}/${moduleName}`;
|
|
21151
21150
|
}
|
|
21152
|
-
return
|
|
21153
|
-
}
|
|
21154
|
-
isSelfScopedPlugin(plugin, contextPath) {
|
|
21155
|
-
return (plugin.scope === PluginsExportScopes.SELF &&
|
|
21156
|
-
(!contextPath || plugin.contextPath === contextPath));
|
|
21157
|
-
}
|
|
21158
|
-
getSelfScopedPlugins(plugins, contextPath) {
|
|
21159
|
-
return plugins.filter(plugin => this.isSelfScopedPlugin(plugin, contextPath));
|
|
21151
|
+
return `${contextPath}@${version}/${moduleName}`;
|
|
21160
21152
|
}
|
|
21161
|
-
|
|
21162
|
-
|
|
21153
|
+
constructor(applicationService, appStateService, client) {
|
|
21154
|
+
this.applicationService = applicationService;
|
|
21155
|
+
this.appStateService = appStateService;
|
|
21156
|
+
this.client = client;
|
|
21163
21157
|
}
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21172
|
-
|
|
21173
|
-
|
|
21174
|
-
if (appFromCurrentTenant) {
|
|
21175
|
-
uniqueList.push(appFromCurrentTenant);
|
|
21176
|
-
continue;
|
|
21177
|
-
}
|
|
21178
|
-
const appNotOwnedByManagement = appsGroup.find(app => !this.isOwnedByManagement(app));
|
|
21179
|
-
uniqueList.push(appNotOwnedByManagement);
|
|
21180
|
-
}
|
|
21181
|
-
}
|
|
21182
|
-
return uniqueList;
|
|
21158
|
+
/**
|
|
21159
|
+
* Fetches a list of available packages.
|
|
21160
|
+
* @param params Additional query parameters.
|
|
21161
|
+
* @returns Returns a list of packages.
|
|
21162
|
+
*/
|
|
21163
|
+
async listPackages(params = {}) {
|
|
21164
|
+
const apps = await this.listApplicationsByCurrentTenant(params);
|
|
21165
|
+
const webApps = apps.filter(app => this.isPackage(app));
|
|
21166
|
+
const uniqueWebApps = this.removeDuplicates(webApps, 'contextPath');
|
|
21167
|
+
return uniqueWebApps.sort((a, b) => a.name.localeCompare(b.name));
|
|
21183
21168
|
}
|
|
21184
|
-
|
|
21185
|
-
|
|
21169
|
+
/**
|
|
21170
|
+
* Checks if an application is a package.
|
|
21171
|
+
* @param application Application managed object.
|
|
21172
|
+
* @returns Returns true if the application is a package.
|
|
21173
|
+
*/
|
|
21174
|
+
isPackage(application) {
|
|
21175
|
+
return application.manifest?.isPackage === true;
|
|
21186
21176
|
}
|
|
21187
21177
|
/**
|
|
21188
|
-
*
|
|
21189
|
-
*
|
|
21178
|
+
* Updates the remotes field in the application configuration by adding new plugins.
|
|
21179
|
+
* Important: if the remotes object is not set on the configuration object,
|
|
21180
|
+
* remotes will not be added. Make sure that this object exists in the application configuration.
|
|
21181
|
+
* @param application Application managed object.
|
|
21182
|
+
* @param plugins List of remotes to be added.
|
|
21183
|
+
* @returns Returns updated application remotes.
|
|
21190
21184
|
*/
|
|
21191
|
-
|
|
21192
|
-
const
|
|
21193
|
-
const
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
|
|
21199
|
-
|
|
21200
|
-
|
|
21201
|
-
|
|
21202
|
-
|
|
21203
|
-
|
|
21204
|
-
}));
|
|
21205
|
-
return extendedPlugins;
|
|
21185
|
+
async addRemotes(application, plugins) {
|
|
21186
|
+
const pluginsArray = Array.isArray(plugins) ? plugins : [plugins];
|
|
21187
|
+
const manifestRemotes = application.manifest?.remotes || {};
|
|
21188
|
+
const appConfig = application?.config;
|
|
21189
|
+
const appConfigRemotes = appConfig?.remotes || manifestRemotes;
|
|
21190
|
+
const appConfigExcludedRemotes = appConfig?.excludedRemotes || {};
|
|
21191
|
+
// only normal and self optional scoped plugins should be added to remotes
|
|
21192
|
+
// self scoped plugins will be automatically added
|
|
21193
|
+
const allPluginsExceptSelfScoped = this.getAllPluginsExceptSelfScoped(pluginsArray, application.contextPath);
|
|
21194
|
+
const newRemotes = this.addPluginToRemotesConfig(appConfigRemotes, allPluginsExceptSelfScoped);
|
|
21195
|
+
// should be unproblematic to remove all categories of plugins from excluded remotes
|
|
21196
|
+
const newExcludedRemotes = this.removePluginsFromRemotesConfig(appConfigExcludedRemotes, plugins);
|
|
21197
|
+
return await this.updateRemotesInAppConfig(application, newRemotes, newExcludedRemotes);
|
|
21206
21198
|
}
|
|
21207
|
-
|
|
21208
|
-
|
|
21209
|
-
|
|
21210
|
-
|
|
21211
|
-
|
|
21212
|
-
|
|
21213
|
-
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
}
|
|
21219
|
-
|
|
21220
|
-
const
|
|
21221
|
-
|
|
21222
|
-
|
|
21223
|
-
|
|
21224
|
-
const
|
|
21225
|
-
|
|
21226
|
-
const webApps = [...appsOwnedByTenant, ...sharedApps];
|
|
21227
|
-
return uniqBy(webApps, (app) => app.id);
|
|
21199
|
+
/**
|
|
21200
|
+
* Updates the remotes field in the application configuration by removing plugins.
|
|
21201
|
+
* @param application Application managed object.
|
|
21202
|
+
* @param plugins List of remotes to be removed.
|
|
21203
|
+
* @returns Returns updated application remotes.
|
|
21204
|
+
*/
|
|
21205
|
+
async removeRemotes(application, plugins) {
|
|
21206
|
+
const pluginsArray = Array.isArray(plugins) ? plugins : [plugins];
|
|
21207
|
+
const manifestRemotes = application.manifest?.remotes || {};
|
|
21208
|
+
const appConfig = application?.config;
|
|
21209
|
+
const appConfigRemotes = appConfig?.remotes || manifestRemotes;
|
|
21210
|
+
const appConfigExcludedRemotes = appConfig?.excludedRemotes || {};
|
|
21211
|
+
// app plugins need to be removed from remotes
|
|
21212
|
+
const newRemotes = this.removePluginsFromRemotesConfig(appConfigRemotes, plugins);
|
|
21213
|
+
// self scoped plugins need to be added to excluded remotes
|
|
21214
|
+
// as they would be otherwise automatically added to remotes
|
|
21215
|
+
const selfScopedPlugins = this.getSelfScopedPlugins(pluginsArray, application.contextPath);
|
|
21216
|
+
const newExcludedRemotes = this.addPluginToRemotesConfig(appConfigExcludedRemotes, selfScopedPlugins);
|
|
21217
|
+
return await this.updateRemotesInAppConfig(application, newRemotes, newExcludedRemotes);
|
|
21228
21218
|
}
|
|
21229
|
-
|
|
21230
|
-
|
|
21231
|
-
|
|
21232
|
-
|
|
21233
|
-
|
|
21234
|
-
|
|
21235
|
-
|
|
21236
|
-
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
}
|
|
21240
|
-
remotesCopy[contextPath]?.length >= 0
|
|
21241
|
-
? remotesCopy[contextPath].push(moduleName)
|
|
21242
|
-
: (remotesCopy[contextPath] = []).push(moduleName);
|
|
21243
|
-
remotesCopy[contextPath] = [...new Set(remotesCopy[contextPath])];
|
|
21219
|
+
/**
|
|
21220
|
+
* Updates the remotes field in the application configuration.
|
|
21221
|
+
* @param application Application managed object.
|
|
21222
|
+
* @param plugins List of remotes to be added.
|
|
21223
|
+
* @returns Returns updated application remotes.
|
|
21224
|
+
*/
|
|
21225
|
+
async updateRemotesInAppConfig(application, plugins, excludedRemotes) {
|
|
21226
|
+
const updatedAppWithConfig = await this.applicationService.updateApplicationConfig(application, {
|
|
21227
|
+
remotes: plugins,
|
|
21228
|
+
excludedRemotes: excludedRemotes || {}
|
|
21244
21229
|
});
|
|
21245
|
-
return
|
|
21230
|
+
return updatedAppWithConfig?.config || { remotes: {} };
|
|
21246
21231
|
}
|
|
21247
|
-
|
|
21248
|
-
|
|
21249
|
-
|
|
21250
|
-
|
|
21251
|
-
|
|
21252
|
-
|
|
21253
|
-
|
|
21254
|
-
|
|
21255
|
-
|
|
21256
|
-
|
|
21257
|
-
|
|
21258
|
-
|
|
21259
|
-
|
|
21260
|
-
|
|
21261
|
-
|
|
21262
|
-
|
|
21263
|
-
|
|
21264
|
-
|
|
21232
|
+
/**
|
|
21233
|
+
* Fetches the application manifest.
|
|
21234
|
+
* @param application Application managed object.
|
|
21235
|
+
* @returns Returns the application manifest.
|
|
21236
|
+
*/
|
|
21237
|
+
async getCumulocityJsonFile(application) {
|
|
21238
|
+
const c8yJson = await this.applicationService.getAppManifest(application);
|
|
21239
|
+
if (!c8yJson.remotes) {
|
|
21240
|
+
c8yJson.remotes = {};
|
|
21241
|
+
}
|
|
21242
|
+
return c8yJson;
|
|
21243
|
+
}
|
|
21244
|
+
/**
|
|
21245
|
+
* Sets the initial state of remotes in the configuration (when it's missing), based on the list of remotes being in the application manifest.
|
|
21246
|
+
* @param application Application managed object.
|
|
21247
|
+
* @returns Returns a list of remotes that has been assigned to the configuration object.
|
|
21248
|
+
*/
|
|
21249
|
+
async setInitialRemotes(application) {
|
|
21250
|
+
try {
|
|
21251
|
+
const manifest = await this.getCumulocityJsonFile(application);
|
|
21252
|
+
const manifestRemotes = manifest.remotes;
|
|
21253
|
+
return await this.updateRemotesInAppConfig(application, manifestRemotes || {}, {});
|
|
21254
|
+
}
|
|
21255
|
+
catch (er) {
|
|
21256
|
+
return undefined;
|
|
21257
|
+
}
|
|
21258
|
+
}
|
|
21259
|
+
async resetRemotes(application) {
|
|
21260
|
+
return await this.applicationService.updateApplicationConfig(application, {
|
|
21261
|
+
remotes: undefined,
|
|
21262
|
+
excludedRemotes: undefined
|
|
21265
21263
|
});
|
|
21266
|
-
|
|
21264
|
+
}
|
|
21265
|
+
sortVersions(source, order) {
|
|
21266
|
+
const sourceCopy = cloneDeep(source);
|
|
21267
|
+
if (source.list && source.path) {
|
|
21268
|
+
const path = sourceCopy.path.join('.');
|
|
21269
|
+
return sourceCopy.list.sort((a, b) => compare(coerce(get(a, path)), coerce(get(b, path))) * (order === 'asc' ? 1 : -1));
|
|
21270
|
+
}
|
|
21271
|
+
else {
|
|
21272
|
+
return sourceCopy.sort((a, b) => compare(coerce(a), coerce(b)) * (order === 'asc' ? 1 : -1));
|
|
21273
|
+
}
|
|
21267
21274
|
}
|
|
21268
21275
|
/**
|
|
21269
|
-
*
|
|
21270
|
-
*
|
|
21271
|
-
*
|
|
21272
|
-
*
|
|
21273
|
-
* const parsed = parsePluginId(id); // { contextPath: 'widget-plugin@1021.0.1', moduleName: 'WidgetPluginModule', rawContextPath: 'widget-plugin' }
|
|
21274
|
-
* @param id Plugin id in the format of `<contextPath>@<version>/<moduleName>`
|
|
21275
|
-
* @returns Object with context path, module name and raw context path (without version).
|
|
21276
|
+
* Extracts a list of exported plugins from the application object.
|
|
21277
|
+
* @param application Application managed object.
|
|
21278
|
+
* @param useLatest Set this to true, to not bind the plugin to any version.
|
|
21279
|
+
* @returns Returns a list of exported plugins.
|
|
21276
21280
|
*/
|
|
21277
|
-
|
|
21278
|
-
|
|
21279
|
-
|
|
21280
|
-
|
|
21281
|
+
getMFExports(application, excludedScopes = [
|
|
21282
|
+
PluginsExportScopes.SELF,
|
|
21283
|
+
PluginsExportScopes.SELF_OPTIONAL,
|
|
21284
|
+
PluginsExportScopes.GLOBAL
|
|
21285
|
+
], useLatest = false) {
|
|
21286
|
+
const manifest = application.manifest;
|
|
21287
|
+
if (!manifest || !manifest.exports) {
|
|
21288
|
+
return [];
|
|
21289
|
+
}
|
|
21290
|
+
return this.extendPluginsDetails(application, {
|
|
21291
|
+
version: manifest.version,
|
|
21292
|
+
binaryId: undefined
|
|
21293
|
+
}, useLatest).filter(plugin => !excludedScopes.includes(plugin.scope));
|
|
21281
21294
|
}
|
|
21282
|
-
|
|
21283
|
-
|
|
21284
|
-
|
|
21285
|
-
|
|
21286
|
-
|
|
21287
|
-
|
|
21288
|
-
|
|
21289
|
-
|
|
21290
|
-
|
|
21291
|
-
|
|
21292
|
-
|
|
21293
|
-
|
|
21294
|
-
|
|
21295
|
-
|
|
21296
|
-
|
|
21297
|
-
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
|
|
21302
|
-
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
21306
|
-
|
|
21307
|
-
|
|
21308
|
-
|
|
21309
|
-
|
|
21310
|
-
* ```
|
|
21311
|
-
*
|
|
21312
|
-
* Or an ExtensionFactory which allows to define a get() function. This function
|
|
21313
|
-
* gets called on each navigation with the current route and can return values
|
|
21314
|
-
* async (observable or promise).
|
|
21315
|
-
* ```typescript
|
|
21316
|
-
* { provide: HOOK_X, useFactory: { get: (route) => doSomethingAsync(route) }, multi: true }
|
|
21317
|
-
* ```
|
|
21318
|
-
* @deprecated Consider using the `hookVersion` function instead.
|
|
21319
|
-
*/
|
|
21320
|
-
const HOOK_VERSION = new InjectionToken('HOOK_VERSION');
|
|
21321
|
-
const VERSION_MODULE_CONFIG = new InjectionToken('VERSION_MODULE_CONFIG');
|
|
21322
|
-
/**
|
|
21323
|
-
* You can either provide a single `Version` as parameter:
|
|
21324
|
-
* ```typescript
|
|
21325
|
-
* hookVersion(...)
|
|
21326
|
-
* ```
|
|
21327
|
-
*
|
|
21328
|
-
* Or an array to directly register multiple:
|
|
21329
|
-
* ```typescript
|
|
21330
|
-
* hookVersion([...])
|
|
21331
|
-
* ```
|
|
21332
|
-
*
|
|
21333
|
-
* Or you provide an Service that implements `ExtensionFactory<Version>`
|
|
21334
|
-
* ```typescript
|
|
21335
|
-
* export class MyVersionFactory implements ExtensionFactory<Version> {...}
|
|
21336
|
-
* ...
|
|
21337
|
-
* hookVersion(MyVersionFactory)
|
|
21338
|
-
* ```
|
|
21339
|
-
* A typed alternative to `HOOK_VERSION`.
|
|
21340
|
-
* @param versions The `Version`'s or `ExtensionFactory` to be provided.
|
|
21341
|
-
* @returns An `Provider` to be provided in your module.
|
|
21342
|
-
*/
|
|
21343
|
-
function hookVersion(versions, options) {
|
|
21344
|
-
return hookGeneric(versions, HOOK_VERSION, options);
|
|
21345
|
-
}
|
|
21346
|
-
|
|
21347
|
-
/**
|
|
21348
|
-
* Will provide the backend versions of the tenant.
|
|
21349
|
-
* The system option 'system' -> 'version' is used for this.
|
|
21350
|
-
*/
|
|
21351
|
-
class BackendVersionFactory {
|
|
21352
|
-
constructor(config, appState) {
|
|
21353
|
-
this.config = config;
|
|
21354
|
-
this.appState = appState;
|
|
21355
|
-
this.backendVersion$ = of([]);
|
|
21356
|
-
if (this.config?.disableBackendVersionFactory) {
|
|
21357
|
-
return;
|
|
21295
|
+
/**
|
|
21296
|
+
* Extracts a list of exports from each available package.
|
|
21297
|
+
* @param allVersions If set to true, all and not only latest versions are included.
|
|
21298
|
+
* @param excludedScopes Defines which scopes should not be loaded.
|
|
21299
|
+
* @returns Returns a list of all exported plugins.
|
|
21300
|
+
*/
|
|
21301
|
+
async getAllMFExports(allVersions = false, excludedScopes = [
|
|
21302
|
+
PluginsExportScopes.SELF,
|
|
21303
|
+
PluginsExportScopes.SELF_OPTIONAL,
|
|
21304
|
+
PluginsExportScopes.GLOBAL
|
|
21305
|
+
]) {
|
|
21306
|
+
const plugins = new Array();
|
|
21307
|
+
const packages = await this.listPackages();
|
|
21308
|
+
for (const pkg of packages) {
|
|
21309
|
+
if (!pkg?.manifest?.exports) {
|
|
21310
|
+
continue;
|
|
21311
|
+
}
|
|
21312
|
+
if (allVersions && Array.isArray(pkg.applicationVersions)) {
|
|
21313
|
+
pkg.applicationVersions.forEach(version => {
|
|
21314
|
+
plugins.push(...this.extendPluginsDetails(pkg, version));
|
|
21315
|
+
});
|
|
21316
|
+
}
|
|
21317
|
+
else {
|
|
21318
|
+
plugins.push(...this.extendPluginsDetails(pkg, {
|
|
21319
|
+
version: pkg.manifest.version,
|
|
21320
|
+
binaryId: undefined
|
|
21321
|
+
}));
|
|
21322
|
+
}
|
|
21358
21323
|
}
|
|
21359
|
-
|
|
21360
|
-
}
|
|
21361
|
-
get() {
|
|
21362
|
-
return this.backendVersion$;
|
|
21363
|
-
}
|
|
21364
|
-
buildBackendVersion(backendVersion) {
|
|
21365
|
-
return {
|
|
21366
|
-
label: gettext$1('Backend'),
|
|
21367
|
-
version: backendVersion,
|
|
21368
|
-
priority: 20,
|
|
21369
|
-
type: 'SYSTEM',
|
|
21370
|
-
hidden: true
|
|
21371
|
-
};
|
|
21372
|
-
}
|
|
21373
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BackendVersionFactory, deps: [{ token: VERSION_MODULE_CONFIG, optional: true }, { token: AppStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21374
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BackendVersionFactory, providedIn: 'root' }); }
|
|
21375
|
-
}
|
|
21376
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BackendVersionFactory, decorators: [{
|
|
21377
|
-
type: Injectable,
|
|
21378
|
-
args: [{
|
|
21379
|
-
providedIn: 'root'
|
|
21380
|
-
}]
|
|
21381
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
21382
|
-
type: Optional
|
|
21383
|
-
}, {
|
|
21384
|
-
type: Inject,
|
|
21385
|
-
args: [VERSION_MODULE_CONFIG]
|
|
21386
|
-
}] }, { type: AppStateService }] });
|
|
21387
|
-
|
|
21388
|
-
class VersionService extends ExtensionPointForPlugins {
|
|
21389
|
-
constructor(rootInjector, pluginService) {
|
|
21390
|
-
super(rootInjector, pluginService);
|
|
21391
|
-
this.items$ = this.setupItemsObservable();
|
|
21392
|
-
this.nonHiddenItems$ = this.items$.pipe(map(versions => versions.filter(version => !version.hidden)));
|
|
21393
|
-
}
|
|
21394
|
-
get state() {
|
|
21395
|
-
return this.state$.value;
|
|
21396
|
-
}
|
|
21397
|
-
add(version) {
|
|
21398
|
-
this.state.add(version);
|
|
21399
|
-
this.emitNewState();
|
|
21400
|
-
}
|
|
21401
|
-
remove(version) {
|
|
21402
|
-
this.state.delete(version);
|
|
21403
|
-
this.emitNewState();
|
|
21404
|
-
}
|
|
21405
|
-
cleanUpVersions(versions) {
|
|
21406
|
-
return versions.map(version => pick(version, 'label', 'version', 'type', 'custom'));
|
|
21407
|
-
}
|
|
21408
|
-
setupItemsObservable() {
|
|
21409
|
-
return fromTriggerOnce(undefined, this.refresh$, [
|
|
21410
|
-
getInjectedHooks(HOOK_VERSION, this.injectors),
|
|
21411
|
-
() => this.factories,
|
|
21412
|
-
stateToFactory(this.state$)
|
|
21413
|
-
]).pipe(distinctUntilChanged(), map(versions => sortByPriority(versions)), shareReplay(1));
|
|
21414
|
-
}
|
|
21415
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionService, deps: [{ token: i0.Injector }, { token: PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21416
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionService, providedIn: 'root' }); }
|
|
21417
|
-
}
|
|
21418
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VersionService, decorators: [{
|
|
21419
|
-
type: Injectable,
|
|
21420
|
-
args: [{
|
|
21421
|
-
providedIn: 'root'
|
|
21422
|
-
}]
|
|
21423
|
-
}], ctorParameters: () => [{ type: i0.Injector }, { type: PluginsResolveService }] });
|
|
21424
|
-
|
|
21425
|
-
class PlatformDetailsService {
|
|
21426
|
-
constructor(version, appState, apps) {
|
|
21427
|
-
this.version = version;
|
|
21428
|
-
this.appState = appState;
|
|
21429
|
-
this.apps = apps;
|
|
21430
|
-
}
|
|
21431
|
-
async getPlatformDetailsObject() {
|
|
21432
|
-
const currentUser = this.appState.currentUser.value;
|
|
21433
|
-
const userId = currentUser?.id;
|
|
21434
|
-
const userPermissions = this.getUserPermissions(currentUser);
|
|
21435
|
-
const [hookedVersions, microserviceVersions] = await Promise.all([
|
|
21436
|
-
this.getVersions(),
|
|
21437
|
-
this.getMicroserviceVersions(userId)
|
|
21438
|
-
]);
|
|
21439
|
-
const versions = [...hookedVersions, ...microserviceVersions];
|
|
21440
|
-
const groupedVersions = groupBy(versions, 'type');
|
|
21441
|
-
const tenantId = this.appState.currentTenant.value?.name;
|
|
21442
|
-
// useful as `domainName` might be pointing to a custom domain
|
|
21443
|
-
// self link should still allow to identify the actual environment of the tenant
|
|
21444
|
-
const tenantSelfLink = this.appState.currentTenant.value?.self;
|
|
21445
|
-
const tenantDomainName = this.appState.currentTenant.value?.domainName;
|
|
21446
|
-
const applicationKey = this.appState.currentApplication.value?.key;
|
|
21447
|
-
const applicationId = this.appState.currentApplication.value?.id;
|
|
21448
|
-
const time = new Date().toISOString();
|
|
21449
|
-
const url = document.URL;
|
|
21450
|
-
const obj = {
|
|
21451
|
-
time,
|
|
21452
|
-
tenantId,
|
|
21453
|
-
tenantSelfLink,
|
|
21454
|
-
tenantDomainName,
|
|
21455
|
-
url,
|
|
21456
|
-
userId,
|
|
21457
|
-
userPermissions,
|
|
21458
|
-
applicationId,
|
|
21459
|
-
applicationKey,
|
|
21460
|
-
versions: groupedVersions
|
|
21461
|
-
};
|
|
21462
|
-
return obj;
|
|
21324
|
+
return plugins.filter(plugin => !excludedScopes.includes(plugin.scope));
|
|
21463
21325
|
}
|
|
21464
|
-
|
|
21465
|
-
|
|
21466
|
-
|
|
21467
|
-
|
|
21468
|
-
|
|
21326
|
+
/**
|
|
21327
|
+
* Extracts a list of remotes from the application object.
|
|
21328
|
+
* @param application Application managed object.
|
|
21329
|
+
* @returns Returns list of remotes.
|
|
21330
|
+
*/
|
|
21331
|
+
getMFRemotes(application) {
|
|
21332
|
+
const manifest = application.manifest || {};
|
|
21333
|
+
const config = application?.config;
|
|
21334
|
+
let remotes = config?.remotes || manifest.remotes || {};
|
|
21335
|
+
const manifestExports = manifest.exports || manifest.manifest?.exports || [];
|
|
21336
|
+
const selfRemotes = manifestExports
|
|
21337
|
+
.filter(plugin => plugin.scope === PluginsExportScopes.SELF)
|
|
21338
|
+
.map(plugin => plugin.module || plugin.name);
|
|
21339
|
+
if (selfRemotes.length) {
|
|
21340
|
+
remotes = mergeRemotes([{ [application.contextPath]: selfRemotes }, remotes]);
|
|
21341
|
+
}
|
|
21342
|
+
remotes = removeRemotes(remotes, config?.excludedRemotes);
|
|
21343
|
+
return remotes;
|
|
21469
21344
|
}
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
|
|
21473
|
-
|
|
21474
|
-
|
|
21475
|
-
|
|
21476
|
-
|
|
21477
|
-
|
|
21478
|
-
|
|
21479
|
-
|
|
21480
|
-
|
|
21481
|
-
|
|
21482
|
-
|
|
21483
|
-
|
|
21484
|
-
|
|
21485
|
-
|
|
21486
|
-
|
|
21487
|
-
|
|
21488
|
-
};
|
|
21489
|
-
});
|
|
21345
|
+
/**
|
|
21346
|
+
* Determines the type of a package.
|
|
21347
|
+
* A package is OFFICIAL if it comes from management tenant and has a label attached called OFFICIAL.
|
|
21348
|
+
* A package is COMMUNITY if it has a label called COMMUNITY.
|
|
21349
|
+
* A package is CUSTOM if it does not have any label attached.
|
|
21350
|
+
* A package is UNKNOWN if it has a label attached but it does not match COMMUNITY or OFFICIAL.
|
|
21351
|
+
*
|
|
21352
|
+
* Labels can be used to identify the status of a package. Community packages always need
|
|
21353
|
+
* a license validation. The label will be shown on the application card to tell a user
|
|
21354
|
+
* whether they are looking into an official or community package.
|
|
21355
|
+
*
|
|
21356
|
+
* @param packageApplication The package application object to check.
|
|
21357
|
+
* @returns The package type.
|
|
21358
|
+
*/
|
|
21359
|
+
getPackageType(packageApplication) {
|
|
21360
|
+
const label = packageApplication.label || packageApplication.manifest?.label;
|
|
21361
|
+
if (label === PackageType.ARCHIVED) {
|
|
21362
|
+
return PackageType.ARCHIVED;
|
|
21490
21363
|
}
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
return [];
|
|
21364
|
+
if (!label) {
|
|
21365
|
+
return PackageType.CUSTOM;
|
|
21494
21366
|
}
|
|
21495
|
-
|
|
21496
|
-
|
|
21497
|
-
if (!user) {
|
|
21498
|
-
return null;
|
|
21367
|
+
if (label === PackageType.OFFICIAL && this.isOwnedByManagement(packageApplication)) {
|
|
21368
|
+
return PackageType.OFFICIAL;
|
|
21499
21369
|
}
|
|
21500
|
-
|
|
21501
|
-
|
|
21502
|
-
|
|
21503
|
-
|
|
21504
|
-
getDirectPermissionsOfUser(user) {
|
|
21505
|
-
const userChangedType = user;
|
|
21506
|
-
const userRoleReferences = userChangedType.roles?.references || [];
|
|
21507
|
-
return userRoleReferences.map(ref => ref.role.id);
|
|
21370
|
+
if (label === PackageType.COMMUNITY) {
|
|
21371
|
+
return PackageType.COMMUNITY;
|
|
21372
|
+
}
|
|
21373
|
+
return PackageType.UNKNOWN;
|
|
21508
21374
|
}
|
|
21509
|
-
|
|
21510
|
-
|
|
21511
|
-
|
|
21512
|
-
|
|
21513
|
-
|
|
21514
|
-
|
|
21515
|
-
|
|
21516
|
-
|
|
21517
|
-
|
|
21518
|
-
};
|
|
21519
|
-
});
|
|
21375
|
+
/**
|
|
21376
|
+
* Verifies if an application is owned by management tenant.
|
|
21377
|
+
*
|
|
21378
|
+
* @param app The application to verify.
|
|
21379
|
+
* @returns True if owned by management tenant.
|
|
21380
|
+
*/
|
|
21381
|
+
isOwnedByManagement(app) {
|
|
21382
|
+
const appOwner = get(app, 'owner.tenant.id');
|
|
21383
|
+
return appOwner === 'management';
|
|
21520
21384
|
}
|
|
21521
|
-
|
|
21522
|
-
|
|
21523
|
-
|
|
21524
|
-
|
|
21525
|
-
|
|
21526
|
-
|
|
21527
|
-
|
|
21528
|
-
|
|
21529
|
-
|
|
21530
|
-
|
|
21531
|
-
|
|
21532
|
-
|
|
21533
|
-
|
|
21534
|
-
|
|
21535
|
-
this.platformDetails = platformDetails;
|
|
21536
|
-
this.headerService = headerService;
|
|
21537
|
-
this.versionsToDirectlyDisplay$ = this.version.nonHiddenItems$;
|
|
21538
|
-
this.currentTenantId$ = this.appState.currentTenant.pipe(map(tenant => tenant?.name), filter(tenantId => !!tenantId), distinctUntilChanged());
|
|
21539
|
-
this.open$ = this.headerService.rightDrawerOpen$;
|
|
21385
|
+
pluginsFromManifest(manifest) {
|
|
21386
|
+
const plugins = manifest.exports;
|
|
21387
|
+
const extendedPlugins = plugins
|
|
21388
|
+
.filter(p => p.scope === PluginsExportScopes.SELF)
|
|
21389
|
+
.map(p => ({
|
|
21390
|
+
...p,
|
|
21391
|
+
id: PluginsService.createPluginId(manifest.contextPath, p, manifest.version),
|
|
21392
|
+
contextPath: manifest.contextPath,
|
|
21393
|
+
version: manifest.version,
|
|
21394
|
+
versioningMatrix: manifest.versioningMatrix,
|
|
21395
|
+
license: manifest.license,
|
|
21396
|
+
type: PackageType.CUSTOM
|
|
21397
|
+
}));
|
|
21398
|
+
return extendedPlugins;
|
|
21540
21399
|
}
|
|
21541
|
-
async
|
|
21542
|
-
|
|
21543
|
-
const json = JSON.stringify(obj, undefined, 2);
|
|
21544
|
-
const blob = new Blob([json]);
|
|
21545
|
-
saveAs$1(blob, 'platform-details.json');
|
|
21400
|
+
async getReadmeFileContent(baseUrl) {
|
|
21401
|
+
return this.getFileContent(baseUrl, 'readme');
|
|
21546
21402
|
}
|
|
21547
|
-
|
|
21548
|
-
this.
|
|
21403
|
+
async getChangelogFileContent(baseUrl) {
|
|
21404
|
+
return this.getFileContent(baseUrl, 'changelog');
|
|
21549
21405
|
}
|
|
21550
|
-
|
|
21551
|
-
|
|
21552
|
-
|
|
21553
|
-
|
|
21554
|
-
|
|
21555
|
-
|
|
21556
|
-
|
|
21557
|
-
|
|
21558
|
-
|
|
21559
|
-
|
|
21560
|
-
|
|
21561
|
-
this.drawerItem = {
|
|
21562
|
-
component: VersionListComponent,
|
|
21563
|
-
position: 'right',
|
|
21564
|
-
priority: 80,
|
|
21565
|
-
id: 'platformInformation'
|
|
21406
|
+
async getFileContent(baseUrl, fileType) {
|
|
21407
|
+
const file = await this.getFile(baseUrl, fileType);
|
|
21408
|
+
if (file.status === 200) {
|
|
21409
|
+
return await file.text();
|
|
21410
|
+
}
|
|
21411
|
+
return '';
|
|
21412
|
+
}
|
|
21413
|
+
async getFile(baseUrl, fileType) {
|
|
21414
|
+
const options = {
|
|
21415
|
+
method: 'GET',
|
|
21416
|
+
headers: { 'Content-Type': 'text/markdown' }
|
|
21566
21417
|
};
|
|
21418
|
+
const uppercaseFilename = fileType === 'readme' ? 'README.md' : 'CHANGELOG.md';
|
|
21419
|
+
let result = await this.client.fetch(`${baseUrl}${uppercaseFilename}`, options);
|
|
21420
|
+
if (result && result.status === 404) {
|
|
21421
|
+
result = await this.client.fetch(`${baseUrl}${uppercaseFilename.toLowerCase()}`, options);
|
|
21422
|
+
}
|
|
21423
|
+
return result;
|
|
21567
21424
|
}
|
|
21568
|
-
|
|
21569
|
-
return
|
|
21570
|
-
|
|
21571
|
-
|
|
21425
|
+
isSelfScopedPlugin(plugin, contextPath) {
|
|
21426
|
+
return (plugin.scope === PluginsExportScopes.SELF &&
|
|
21427
|
+
(!contextPath || plugin.contextPath === contextPath));
|
|
21428
|
+
}
|
|
21429
|
+
getSelfScopedPlugins(plugins, contextPath) {
|
|
21430
|
+
return plugins.filter(plugin => this.isSelfScopedPlugin(plugin, contextPath));
|
|
21431
|
+
}
|
|
21432
|
+
getAllPluginsExceptSelfScoped(plugins, contextPath) {
|
|
21433
|
+
return plugins.filter(plugin => !this.isSelfScopedPlugin(plugin, contextPath));
|
|
21434
|
+
}
|
|
21435
|
+
removeDuplicates(apps, key) {
|
|
21436
|
+
const uniqueList = [];
|
|
21437
|
+
const groupedAppsByKey = groupBy(apps, key);
|
|
21438
|
+
const groupedApps = Object.keys(groupedAppsByKey).map(key => groupedAppsByKey[key]);
|
|
21439
|
+
for (const appsGroup of groupedApps) {
|
|
21440
|
+
if (appsGroup.length < 2) {
|
|
21441
|
+
uniqueList.push(...appsGroup);
|
|
21572
21442
|
}
|
|
21573
|
-
|
|
21443
|
+
else {
|
|
21444
|
+
const appFromCurrentTenant = appsGroup.find(app => this.isFromCurrentTenant(app));
|
|
21445
|
+
if (appFromCurrentTenant) {
|
|
21446
|
+
uniqueList.push(appFromCurrentTenant);
|
|
21447
|
+
continue;
|
|
21448
|
+
}
|
|
21449
|
+
const appNotOwnedByManagement = appsGroup.find(app => !this.isOwnedByManagement(app));
|
|
21450
|
+
uniqueList.push(appNotOwnedByManagement);
|
|
21451
|
+
}
|
|
21452
|
+
}
|
|
21453
|
+
return uniqueList;
|
|
21454
|
+
}
|
|
21455
|
+
isFromCurrentTenant(app) {
|
|
21456
|
+
return app.owner.tenant.id === this.appStateService.currentTenant.value.name;
|
|
21457
|
+
}
|
|
21458
|
+
/**
|
|
21459
|
+
* Modifies the list of plugins to have additional information such as id.
|
|
21460
|
+
* @ignore
|
|
21461
|
+
*/
|
|
21462
|
+
extendPluginsDetails(application, version, useLatest = false) {
|
|
21463
|
+
const plugins = application.manifest.exports;
|
|
21464
|
+
const extendedPlugins = plugins.map(p => ({
|
|
21465
|
+
...p,
|
|
21466
|
+
id: PluginsService.createPluginId(application.contextPath, p, version.version, useLatest),
|
|
21467
|
+
idLatest: PluginsService.createPluginId(application.contextPath, p, version.version, true),
|
|
21468
|
+
contextPath: application.contextPath,
|
|
21469
|
+
version: version.version,
|
|
21470
|
+
versioningMatrix: application.manifest.versioningMatrix,
|
|
21471
|
+
tags: useLatest ? ['latest'] : version.tags || [],
|
|
21472
|
+
license: application.manifest.license,
|
|
21473
|
+
type: this.getPackageType(application),
|
|
21474
|
+
originApp: application
|
|
21574
21475
|
}));
|
|
21476
|
+
return extendedPlugins;
|
|
21575
21477
|
}
|
|
21576
|
-
|
|
21577
|
-
|
|
21578
|
-
|
|
21579
|
-
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
21478
|
+
async listApplicationsByCurrentTenant(params = {}) {
|
|
21479
|
+
const filter = Object.assign({
|
|
21480
|
+
type: 'HOSTED',
|
|
21481
|
+
pageSize: 2000,
|
|
21482
|
+
withTotalPages: true
|
|
21483
|
+
}, params);
|
|
21484
|
+
const sharedFilter = Object.assign({
|
|
21485
|
+
availability: ApplicationAvailability.SHARED,
|
|
21486
|
+
type: 'HOSTED',
|
|
21487
|
+
pageSize: 2000,
|
|
21488
|
+
withTotalPages: true
|
|
21489
|
+
}, params);
|
|
21490
|
+
const tenantName = this.appStateService.currentTenant.value.name;
|
|
21491
|
+
const [resultAppsOwnedByTenant, resultSharedApps] = await Promise.all([
|
|
21492
|
+
this.applicationService.listByTenant(tenantName, filter),
|
|
21493
|
+
this.applicationService.list(sharedFilter)
|
|
21494
|
+
]);
|
|
21495
|
+
const { data: appsOwnedByTenant } = resultAppsOwnedByTenant;
|
|
21496
|
+
const { data: sharedApps } = resultSharedApps;
|
|
21497
|
+
const webApps = [...appsOwnedByTenant, ...sharedApps];
|
|
21498
|
+
return uniqBy(webApps, (app) => app.id);
|
|
21499
|
+
}
|
|
21500
|
+
addPluginToRemotesConfig(remotesConfig, plugins) {
|
|
21501
|
+
if (!plugins) {
|
|
21502
|
+
return;
|
|
21503
|
+
}
|
|
21504
|
+
const remotesCopy = cloneDeep(remotesConfig);
|
|
21505
|
+
const temp = Array.isArray(plugins) ? plugins : [plugins];
|
|
21506
|
+
temp.forEach(plugin => {
|
|
21507
|
+
const { contextPath, moduleName } = this.parsePluginId(plugin.id);
|
|
21508
|
+
if (!contextPath || !moduleName) {
|
|
21509
|
+
return;
|
|
21583
21510
|
}
|
|
21584
|
-
|
|
21585
|
-
|
|
21511
|
+
remotesCopy[contextPath]?.length >= 0
|
|
21512
|
+
? remotesCopy[contextPath].push(moduleName)
|
|
21513
|
+
: (remotesCopy[contextPath] = []).push(moduleName);
|
|
21514
|
+
remotesCopy[contextPath] = [...new Set(remotesCopy[contextPath])];
|
|
21515
|
+
});
|
|
21516
|
+
return remotesCopy;
|
|
21586
21517
|
}
|
|
21587
|
-
|
|
21588
|
-
|
|
21518
|
+
removePluginsFromRemotesConfig(remotesConfig, plugins) {
|
|
21519
|
+
const remotesCopy = cloneDeep(remotesConfig);
|
|
21520
|
+
const temp = Array.isArray(plugins) ? plugins : [plugins];
|
|
21521
|
+
temp.forEach(plugin => {
|
|
21522
|
+
const { rawContextPath, moduleName } = this.parsePluginId(plugin.id);
|
|
21523
|
+
if (!rawContextPath || !moduleName) {
|
|
21524
|
+
return;
|
|
21525
|
+
}
|
|
21526
|
+
// Find all keys in remotesConfig that match the plugin context (regardless of version)
|
|
21527
|
+
Object.keys(remotesCopy).forEach(key => {
|
|
21528
|
+
if (key === rawContextPath || key.startsWith(`${rawContextPath}@`)) {
|
|
21529
|
+
remotesCopy[key] = remotesCopy[key].filter(p => p !== moduleName);
|
|
21530
|
+
remotesCopy[key] = [...new Set(remotesCopy[key])];
|
|
21531
|
+
if (remotesCopy[key].length === 0) {
|
|
21532
|
+
delete remotesCopy[key];
|
|
21533
|
+
}
|
|
21534
|
+
}
|
|
21535
|
+
});
|
|
21536
|
+
});
|
|
21537
|
+
return remotesCopy;
|
|
21538
|
+
}
|
|
21539
|
+
/**
|
|
21540
|
+
* Parses id of the plugin and returns object with context path, raw context path (without version) and module name.
|
|
21541
|
+
* For example:
|
|
21542
|
+
* ```ts
|
|
21543
|
+
* const id = 'widget-plugin@1021.0.1/WidgetPluginModule'
|
|
21544
|
+
* const parsed = parsePluginId(id); // { contextPath: 'widget-plugin@1021.0.1', moduleName: 'WidgetPluginModule', rawContextPath: 'widget-plugin' }
|
|
21545
|
+
* @param id Plugin id in the format of `<contextPath>@<version>/<moduleName>`
|
|
21546
|
+
* @returns Object with context path, module name and raw context path (without version).
|
|
21547
|
+
*/
|
|
21548
|
+
parsePluginId(id) {
|
|
21549
|
+
const [contextPath, moduleName] = id.split('/');
|
|
21550
|
+
const [rawContextPath] = contextPath.split('@');
|
|
21551
|
+
return { rawContextPath, contextPath, moduleName };
|
|
21552
|
+
}
|
|
21553
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PluginsService, deps: [{ token: i1.ApplicationService }, { token: AppStateService }, { token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21554
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PluginsService, providedIn: 'root' }); }
|
|
21589
21555
|
}
|
|
21590
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type:
|
|
21591
|
-
type: Injectable
|
|
21592
|
-
|
|
21556
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PluginsService, decorators: [{
|
|
21557
|
+
type: Injectable,
|
|
21558
|
+
args: [{ providedIn: 'root' }]
|
|
21559
|
+
}], ctorParameters: () => [{ type: i1.ApplicationService }, { type: AppStateService }, { type: i1.FetchClient }] });
|
|
21593
21560
|
|
|
21594
21561
|
/**
|
|
21595
21562
|
* Will provide the version of plugins installed to the current application.
|
|
@@ -22557,6 +22524,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
22557
22524
|
args: [{}]
|
|
22558
22525
|
}] });
|
|
22559
22526
|
|
|
22527
|
+
class PasswordStrengthCheckerService {
|
|
22528
|
+
constructor() {
|
|
22529
|
+
this.GREEN = {
|
|
22530
|
+
colorName: 'green',
|
|
22531
|
+
color: 'rgb(0, 128, 0)',
|
|
22532
|
+
description: gettext$1('strong'),
|
|
22533
|
+
passwordStrength: PasswordStrength.GREEN
|
|
22534
|
+
};
|
|
22535
|
+
this.YELLOW = {
|
|
22536
|
+
colorName: 'yellow',
|
|
22537
|
+
color: 'rgb(255, 204, 51)',
|
|
22538
|
+
description: gettext$1('medium'),
|
|
22539
|
+
passwordStrength: PasswordStrength.YELLOW
|
|
22540
|
+
};
|
|
22541
|
+
this.RED = {
|
|
22542
|
+
colorName: 'red',
|
|
22543
|
+
color: 'rgb(170, 0, 51)',
|
|
22544
|
+
description: gettext$1('weak'),
|
|
22545
|
+
passwordStrength: PasswordStrength.RED
|
|
22546
|
+
};
|
|
22547
|
+
}
|
|
22548
|
+
hasLowerCase(password) {
|
|
22549
|
+
return password.search(/[a-z]/) !== -1;
|
|
22550
|
+
}
|
|
22551
|
+
hasUpperCase(password) {
|
|
22552
|
+
return password.search(/[A-Z]/) !== -1;
|
|
22553
|
+
}
|
|
22554
|
+
hasNumbers(password) {
|
|
22555
|
+
return password.search(/[0-9]/) !== -1;
|
|
22556
|
+
}
|
|
22557
|
+
hasSpecialChars(password) {
|
|
22558
|
+
return password.search(/[^0-9a-zA-Z]+/) !== -1;
|
|
22559
|
+
}
|
|
22560
|
+
getStrengthColor(password) {
|
|
22561
|
+
const passwordStrength = filter$2([
|
|
22562
|
+
this.hasLowerCase(password),
|
|
22563
|
+
this.hasUpperCase(password),
|
|
22564
|
+
this.hasNumbers(password),
|
|
22565
|
+
this.hasSpecialChars(password)
|
|
22566
|
+
]).length;
|
|
22567
|
+
if (passwordStrength > 3) {
|
|
22568
|
+
return this.GREEN;
|
|
22569
|
+
}
|
|
22570
|
+
else if (passwordStrength >= 3) {
|
|
22571
|
+
return this.YELLOW;
|
|
22572
|
+
}
|
|
22573
|
+
else {
|
|
22574
|
+
return this.RED;
|
|
22575
|
+
}
|
|
22576
|
+
}
|
|
22577
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordStrengthCheckerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
22578
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordStrengthCheckerService, providedIn: 'root' }); }
|
|
22579
|
+
}
|
|
22580
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PasswordStrengthCheckerService, decorators: [{
|
|
22581
|
+
type: Injectable,
|
|
22582
|
+
args: [{ providedIn: 'root' }]
|
|
22583
|
+
}] });
|
|
22584
|
+
|
|
22560
22585
|
/**
|
|
22561
22586
|
* A drop-zone which is a file selector allowing users to select file(s) from their file system, either natively or by drag and drop.
|
|
22562
22587
|
*
|
|
@@ -22594,6 +22619,7 @@ class DropAreaComponent {
|
|
|
22594
22619
|
this.maxAllowedFiles = Infinity;
|
|
22595
22620
|
this.isOver = false;
|
|
22596
22621
|
this.errors = false;
|
|
22622
|
+
this.disabled = false;
|
|
22597
22623
|
this.onChange = _ => undefined;
|
|
22598
22624
|
this.onTouched = () => undefined;
|
|
22599
22625
|
}
|
|
@@ -22700,6 +22726,9 @@ class DropAreaComponent {
|
|
|
22700
22726
|
registerOnTouched(fn) {
|
|
22701
22727
|
this.onTouched = fn;
|
|
22702
22728
|
}
|
|
22729
|
+
setDisabledState(isDisabled) {
|
|
22730
|
+
this.disabled = isDisabled;
|
|
22731
|
+
}
|
|
22703
22732
|
async onFilesSelected(files) {
|
|
22704
22733
|
this.onTouched();
|
|
22705
22734
|
const hasValidNameLength = this.filesService.checkMaxLength(files);
|
|
@@ -22839,11 +22868,11 @@ class DropAreaComponent {
|
|
|
22839
22868
|
resolve(reader.result);
|
|
22840
22869
|
}
|
|
22841
22870
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DropAreaComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: FilesService }, { token: i1$1.TranslateService }, { token: BytesPipe }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
22842
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DropAreaComponent, isStandalone: true, selector: "c8y-drop-area", inputs: { formControl: "formControl", title: "title", message: "message", icon: "icon", loadingMessage: "loadingMessage", forceHideList: "forceHideList", alwaysShow: "alwaysShow", clickToOpen: "clickToOpen", loading: "loading", progress: "progress", maxAllowedFiles: "maxAllowedFiles", files: "files", maxFileSizeInMegaBytes: "maxFileSizeInMegaBytes", accept: "accept" }, outputs: { dropped: "dropped" }, host: { listeners: { "keyup": "onkeyup($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DropAreaComponent, multi: true }], viewQueries: [{ propertyName: "area", first: true, predicate: ["area"], descendants: true, static: true }, { propertyName: "zone", first: true, predicate: ["zone"], descendants: true }, { propertyName: "picker", first: true, predicate: ["picker"], descendants: true }], ngImport: i0, template: "<div\n class=\"drop-zone\"\n [style.pointerEvents]=\"loading ? 'none' : 'auto'\"\n [style.display]=\"isOver || alwaysShow || loading ? 'block' : 'none'\"\n tabindex=\"0\"\n *ngIf=\"!shouldShowFilesList()\"\n [ngClass]=\"{ 'has-errors': errors, disabled: formControl?.disabled }\"\n #zone\n (dragleave)=\"stopDragging()\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onOver()\"\n (click)=\"showPicker($event)\"\n>\n <div\n class=\"file-placeholder\"\n data-cy=\"c8y-file-placeholder--drop-zone\"\n [ngClass]=\"{ 'drag-over': isOver }\"\n >\n <div\n class=\"d-flex d-col p-4 flex-center\"\n *ngIf=\"loading\"\n >\n <div\n class=\"progress progress-striped active m-0\"\n style=\"min-width: 50%\"\n *ngIf=\"progress !== -1\"\n >\n <div\n class=\"progress-bar\"\n [style.width]=\"progress + '%'\"\n [attr.aria-label]=\"progress + '%'\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n role=\"progressbar\"\n ></div>\n </div>\n <div\n class=\"spinner-snake\"\n *ngIf=\"progress === -1\"\n ></div>\n <p\n class=\"m-t-auto m-b-auto m-r-8\"\n *ngIf=\"!hasDropAreaSmallClass\"\n >\n {{ loadingMessage | translate }}\n </p>\n </div>\n <div\n class=\"hint-placeholder pointer\"\n *ngIf=\"!loading\"\n data-cy=\"drop-zone--hint-placeholder\"\n >\n <i class=\"dlt-c8y-icon-{{ icon }}\"></i>\n <p
|
|
22871
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DropAreaComponent, isStandalone: true, selector: "c8y-drop-area", inputs: { formControl: "formControl", title: "title", message: "message", icon: "icon", loadingMessage: "loadingMessage", forceHideList: "forceHideList", alwaysShow: "alwaysShow", clickToOpen: "clickToOpen", loading: "loading", progress: "progress", maxAllowedFiles: "maxAllowedFiles", files: "files", maxFileSizeInMegaBytes: "maxFileSizeInMegaBytes", accept: "accept" }, outputs: { dropped: "dropped" }, host: { listeners: { "keyup": "onkeyup($event)" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DropAreaComponent, multi: true }], viewQueries: [{ propertyName: "area", first: true, predicate: ["area"], descendants: true, static: true }, { propertyName: "zone", first: true, predicate: ["zone"], descendants: true }, { propertyName: "picker", first: true, predicate: ["picker"], descendants: true }], ngImport: i0, template: "<div\n class=\"drop-zone\"\n [style.pointerEvents]=\"loading ? 'none' : 'auto'\"\n [style.display]=\"isOver || alwaysShow || loading ? 'block' : 'none'\"\n tabindex=\"0\"\n *ngIf=\"!shouldShowFilesList()\"\n [ngClass]=\"{ 'has-errors': errors, disabled: formControl?.disabled || disabled }\"\n #zone\n (dragleave)=\"stopDragging()\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onOver()\"\n (click)=\"showPicker($event)\"\n>\n <div\n class=\"file-placeholder\"\n data-cy=\"c8y-file-placeholder--drop-zone\"\n [ngClass]=\"{ 'drag-over': isOver }\"\n >\n <div\n class=\"d-flex d-col p-4 flex-center\"\n *ngIf=\"loading\"\n >\n <div\n class=\"progress progress-striped active m-0\"\n style=\"min-width: 50%\"\n *ngIf=\"progress !== -1\"\n >\n <div\n class=\"progress-bar\"\n [style.width]=\"progress + '%'\"\n [attr.aria-label]=\"progress + '%'\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n role=\"progressbar\"\n ></div>\n </div>\n <div\n class=\"spinner-snake\"\n *ngIf=\"progress === -1\"\n ></div>\n <p\n class=\"m-t-auto m-b-auto m-r-8\"\n *ngIf=\"!hasDropAreaSmallClass\"\n >\n {{ loadingMessage | translate }}\n </p>\n </div>\n <div\n class=\"hint-placeholder pointer\"\n *ngIf=\"!loading\"\n data-cy=\"drop-zone--hint-placeholder\"\n >\n <i class=\"dlt-c8y-icon-{{ icon }}\"></i>\n <p\n class=\"text-truncate\"\n title=\"{{ message | translate }}\"\n *ngIf=\"!errors\"\n >\n <b>{{ message | translate }}</b>\n <br />\n <span\n *ngIf=\"alwaysShow && clickToOpen\"\n translate\n ></span>\n </p>\n <div\n class=\"has-errors\"\n *ngIf=\"errors\"\n >\n <p class=\"form-control-feedback-message\">\n {{ errorMessage | translate }}\n </p>\n </div>\n </div>\n </div>\n</div>\n\n<div\n class=\"drop-zone\"\n [style.display]=\"isOver || alwaysShow || loading ? 'block' : 'none'\"\n tabindex=\"0\"\n *ngIf=\"shouldShowFilesList()\"\n>\n <div\n class=\"p-absolute p-4 fit-w fit-h d-flex d-col j-c-center a-i-center\"\n *ngIf=\"loading\"\n >\n <div\n class=\"progress progress-striped active m-0\"\n style=\"min-width: 80%\"\n *ngIf=\"progress !== -1\"\n >\n <div\n class=\"progress-bar\"\n [style.width]=\"progress + '%'\"\n [attr.aria-label]=\"progress + '%'\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n role=\"progressbar\"\n ></div>\n </div>\n <div *ngIf=\"progress === -1\">\n <c8y-loading></c8y-loading>\n </div>\n <p\n class=\"m-b-8\"\n *ngIf=\"!hasDropAreaSmallClass\"\n >\n <strong>\n {{ loadingMessage | translate }}\n </strong>\n </p>\n </div>\n <div\n class=\"file-placeholder p-4\"\n *ngIf=\"!loading\"\n >\n <div class=\"d-flex p-4 a-i-center\">\n <i\n class=\"icon-20 m-r-8\"\n c8yIcon=\"file-o\"\n ></i>\n <span\n class=\"text-truncate\"\n title=\"{{ filesNameString }}\"\n >\n {{ filesNameString }}\n </span>\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover m-l-auto\"\n title=\"{{ 'Remove' | translate }}\"\n [attr.aria-label]=\"'Remove' | translate\"\n type=\"button\"\n >\n <i\n c8yIcon=\"minus-circle\"\n (click)=\"onDelete()\"\n ></i>\n </button>\n </div>\n </div>\n</div>\n<label\n class=\"sr-only\"\n for=\"file\"\n>\n {{ 'Select file' | translate }}\n</label>\n<input\n class=\"hidden\"\n id=\"file\"\n type=\"file\"\n #picker\n *ngIf=\"clickToOpen\"\n (change)=\"onPick($event)\"\n (click)=\"picker.focus()\"\n (blur)=\"onTouched()\"\n [accept]=\"acceptedExts\"\n [multiple]=\"maxAllowedFiles > 1\"\n [disabled]=\"formControl?.disabled || disabled\"\n/>\n<div\n #area\n [hidden]=\"isOver || loading\"\n (dragover)=\"toggle()\"\n>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i1$a.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$a.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
22843
22872
|
}
|
|
22844
22873
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DropAreaComponent, decorators: [{
|
|
22845
22874
|
type: Component,
|
|
22846
|
-
args: [{ selector: 'c8y-drop-area', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DropAreaComponent, multi: true }], standalone: true, imports: [CommonModule, C8yTranslatePipe, NgIf, NgClass, IconDirective], template: "<div\n class=\"drop-zone\"\n [style.pointerEvents]=\"loading ? 'none' : 'auto'\"\n [style.display]=\"isOver || alwaysShow || loading ? 'block' : 'none'\"\n tabindex=\"0\"\n *ngIf=\"!shouldShowFilesList()\"\n [ngClass]=\"{ 'has-errors': errors, disabled: formControl?.disabled }\"\n #zone\n (dragleave)=\"stopDragging()\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onOver()\"\n (click)=\"showPicker($event)\"\n>\n <div\n class=\"file-placeholder\"\n data-cy=\"c8y-file-placeholder--drop-zone\"\n [ngClass]=\"{ 'drag-over': isOver }\"\n >\n <div\n class=\"d-flex d-col p-4 flex-center\"\n *ngIf=\"loading\"\n >\n <div\n class=\"progress progress-striped active m-0\"\n style=\"min-width: 50%\"\n *ngIf=\"progress !== -1\"\n >\n <div\n class=\"progress-bar\"\n [style.width]=\"progress + '%'\"\n [attr.aria-label]=\"progress + '%'\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n role=\"progressbar\"\n ></div>\n </div>\n <div\n class=\"spinner-snake\"\n *ngIf=\"progress === -1\"\n ></div>\n <p\n class=\"m-t-auto m-b-auto m-r-8\"\n *ngIf=\"!hasDropAreaSmallClass\"\n >\n {{ loadingMessage | translate }}\n </p>\n </div>\n <div\n class=\"hint-placeholder pointer\"\n *ngIf=\"!loading\"\n data-cy=\"drop-zone--hint-placeholder\"\n >\n <i class=\"dlt-c8y-icon-{{ icon }}\"></i>\n <p
|
|
22875
|
+
args: [{ selector: 'c8y-drop-area', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DropAreaComponent, multi: true }], standalone: true, imports: [CommonModule, C8yTranslatePipe, NgIf, NgClass, IconDirective], template: "<div\n class=\"drop-zone\"\n [style.pointerEvents]=\"loading ? 'none' : 'auto'\"\n [style.display]=\"isOver || alwaysShow || loading ? 'block' : 'none'\"\n tabindex=\"0\"\n *ngIf=\"!shouldShowFilesList()\"\n [ngClass]=\"{ 'has-errors': errors, disabled: formControl?.disabled || disabled }\"\n #zone\n (dragleave)=\"stopDragging()\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onOver()\"\n (click)=\"showPicker($event)\"\n>\n <div\n class=\"file-placeholder\"\n data-cy=\"c8y-file-placeholder--drop-zone\"\n [ngClass]=\"{ 'drag-over': isOver }\"\n >\n <div\n class=\"d-flex d-col p-4 flex-center\"\n *ngIf=\"loading\"\n >\n <div\n class=\"progress progress-striped active m-0\"\n style=\"min-width: 50%\"\n *ngIf=\"progress !== -1\"\n >\n <div\n class=\"progress-bar\"\n [style.width]=\"progress + '%'\"\n [attr.aria-label]=\"progress + '%'\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n role=\"progressbar\"\n ></div>\n </div>\n <div\n class=\"spinner-snake\"\n *ngIf=\"progress === -1\"\n ></div>\n <p\n class=\"m-t-auto m-b-auto m-r-8\"\n *ngIf=\"!hasDropAreaSmallClass\"\n >\n {{ loadingMessage | translate }}\n </p>\n </div>\n <div\n class=\"hint-placeholder pointer\"\n *ngIf=\"!loading\"\n data-cy=\"drop-zone--hint-placeholder\"\n >\n <i class=\"dlt-c8y-icon-{{ icon }}\"></i>\n <p\n class=\"text-truncate\"\n title=\"{{ message | translate }}\"\n *ngIf=\"!errors\"\n >\n <b>{{ message | translate }}</b>\n <br />\n <span\n *ngIf=\"alwaysShow && clickToOpen\"\n translate\n ></span>\n </p>\n <div\n class=\"has-errors\"\n *ngIf=\"errors\"\n >\n <p class=\"form-control-feedback-message\">\n {{ errorMessage | translate }}\n </p>\n </div>\n </div>\n </div>\n</div>\n\n<div\n class=\"drop-zone\"\n [style.display]=\"isOver || alwaysShow || loading ? 'block' : 'none'\"\n tabindex=\"0\"\n *ngIf=\"shouldShowFilesList()\"\n>\n <div\n class=\"p-absolute p-4 fit-w fit-h d-flex d-col j-c-center a-i-center\"\n *ngIf=\"loading\"\n >\n <div\n class=\"progress progress-striped active m-0\"\n style=\"min-width: 80%\"\n *ngIf=\"progress !== -1\"\n >\n <div\n class=\"progress-bar\"\n [style.width]=\"progress + '%'\"\n [attr.aria-label]=\"progress + '%'\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n role=\"progressbar\"\n ></div>\n </div>\n <div *ngIf=\"progress === -1\">\n <c8y-loading></c8y-loading>\n </div>\n <p\n class=\"m-b-8\"\n *ngIf=\"!hasDropAreaSmallClass\"\n >\n <strong>\n {{ loadingMessage | translate }}\n </strong>\n </p>\n </div>\n <div\n class=\"file-placeholder p-4\"\n *ngIf=\"!loading\"\n >\n <div class=\"d-flex p-4 a-i-center\">\n <i\n class=\"icon-20 m-r-8\"\n c8yIcon=\"file-o\"\n ></i>\n <span\n class=\"text-truncate\"\n title=\"{{ filesNameString }}\"\n >\n {{ filesNameString }}\n </span>\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover m-l-auto\"\n title=\"{{ 'Remove' | translate }}\"\n [attr.aria-label]=\"'Remove' | translate\"\n type=\"button\"\n >\n <i\n c8yIcon=\"minus-circle\"\n (click)=\"onDelete()\"\n ></i>\n </button>\n </div>\n </div>\n</div>\n<label\n class=\"sr-only\"\n for=\"file\"\n>\n {{ 'Select file' | translate }}\n</label>\n<input\n class=\"hidden\"\n id=\"file\"\n type=\"file\"\n #picker\n *ngIf=\"clickToOpen\"\n (change)=\"onPick($event)\"\n (click)=\"picker.focus()\"\n (blur)=\"onTouched()\"\n [accept]=\"acceptedExts\"\n [multiple]=\"maxAllowedFiles > 1\"\n [disabled]=\"formControl?.disabled || disabled\"\n/>\n<div\n #area\n [hidden]=\"isOver || loading\"\n (dragover)=\"toggle()\"\n>\n <ng-content></ng-content>\n</div>\n" }]
|
|
22847
22876
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: FilesService }, { type: i1$1.TranslateService }, { type: BytesPipe }, { type: i0.ElementRef }], propDecorators: { formControl: [{
|
|
22848
22877
|
type: Input
|
|
22849
22878
|
}], title: [{
|
|
@@ -22994,7 +23023,7 @@ class FilePickerComponent {
|
|
|
22994
23023
|
this.onFilesPicked.emit(this.fileToSave);
|
|
22995
23024
|
}
|
|
22996
23025
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FilePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
22997
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FilePickerComponent, isStandalone: true, selector: "c8y-file-picker", inputs: { maxAllowedFiles: "maxAllowedFiles", uploadChoice: "uploadChoice", allowedUploadChoices: "allowedUploadChoices", fileUrl: "fileUrl", fileBinary: "fileBinary", config: "config", filePickerIndex: "filePickerIndex", fileUrlPopover: "fileUrlPopover" }, outputs: { onFilesPicked: "onFilesPicked" }, viewQueries: [{ propertyName: "dropArea", first: true, predicate: DropAreaComponent, descendants: true, static: true }], ngImport: i0, template: "<div class=\"form-group\">\n <label\n class=\"c8y-radio\"\n title=\"{{ 'Upload a binary' | translate }}\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadBinary\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearInputFromUrl()\"\n />\n <span></span>\n <span>{{ 'Upload a binary' | translate }}</span>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Provide a file path' | translate }}\"\n data-cy=\"file-picker--file-path-input\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadUrl\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearSelectedFiles()\"\n />\n <span></span>\n <span>\n {{ 'Provide a file path' | translate }}\n </span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ fileUrlPopover | translate }}\"\n placement=\"top\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n *ngIf=\"isPopoverUsed()\"\n ></button>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Mark as provided' | translate }}\"\n *ngIf=\"allowedUploadChoices.includes('provided')\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"provided\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"setProvidedOption()\"\n />\n <span></span>\n <span>{{ 'Provided' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ providedPopover | translate }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadBinary'\">\n <c8y-form-group class=\"m-0\">\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop file or click to browse' | translate\"\n [attr.aria-label]=\"'Drop file or click to browse' | translate\"\n (dropped)=\"onFileDropped($event)\"\n [maxAllowedFiles]=\"maxAllowedFiles\"\n [files]=\"droppedFiles\"\n ></c8y-drop-area>\n </c8y-form-group>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadUrl'\">\n <c8y-form-group class=\"m-0\">\n <div class=\"m-b-4 p-b-8\">\n <div class=\"input-group\">\n <span class=\"input-group-addon\">\n <i c8yIcon=\"globe\"></i>\n </span>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} http://example.com/binary.zip\"\n name=\"fileUrl\"\n type=\"text\"\n required\n data-cy=\"file-picker--fileUrl\"\n [(ngModel)]=\"fileUrl\"\n (ngModelChange)=\"onFileUrlChange($event)\"\n maxlength=\"{{ config.maxlength }}\"\n [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n />\n </div>\n </div>\n </c8y-form-group>\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i1$9.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
23026
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FilePickerComponent, isStandalone: true, selector: "c8y-file-picker", inputs: { maxAllowedFiles: "maxAllowedFiles", uploadChoice: "uploadChoice", allowedUploadChoices: "allowedUploadChoices", fileUrl: "fileUrl", fileBinary: "fileBinary", config: "config", filePickerIndex: "filePickerIndex", fileUrlPopover: "fileUrlPopover" }, outputs: { onFilesPicked: "onFilesPicked" }, viewQueries: [{ propertyName: "dropArea", first: true, predicate: DropAreaComponent, descendants: true, static: true }], ngImport: i0, template: "<div class=\"form-group\">\n <label\n class=\"c8y-radio\"\n [class.m-l-8]=\"allowedUploadChoices.includes('provided')\"\n title=\"{{ 'Upload a binary' | translate }}\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadBinary\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearInputFromUrl()\"\n />\n <span></span>\n <span>{{ 'Upload a binary' | translate }}</span>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Provide a file path' | translate }}\"\n data-cy=\"file-picker--file-path-input\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadUrl\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearSelectedFiles()\"\n />\n <span></span>\n <span>\n {{ 'Provide a file path' | translate }}\n </span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ fileUrlPopover | translate }}\"\n placement=\"top\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n *ngIf=\"isPopoverUsed()\"\n ></button>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Mark as provided' | translate }}\"\n *ngIf=\"allowedUploadChoices.includes('provided')\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"provided\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"setProvidedOption()\"\n />\n <span></span>\n <span>{{ 'Provided' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ providedPopover | translate }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadBinary'\">\n <c8y-form-group class=\"m-0\">\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop file or click to browse' | translate\"\n [attr.aria-label]=\"'Drop file or click to browse' | translate\"\n (dropped)=\"onFileDropped($event)\"\n [maxAllowedFiles]=\"maxAllowedFiles\"\n [files]=\"droppedFiles\"\n ></c8y-drop-area>\n </c8y-form-group>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadUrl'\">\n <c8y-form-group class=\"m-0\">\n <div class=\"m-b-4 p-b-8\">\n <div class=\"input-group\">\n <span class=\"input-group-addon\">\n <i c8yIcon=\"globe\"></i>\n </span>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} http://example.com/binary.zip\"\n name=\"fileUrl\"\n type=\"text\"\n required\n data-cy=\"file-picker--fileUrl\"\n [(ngModel)]=\"fileUrl\"\n (ngModelChange)=\"onFileUrlChange($event)\"\n maxlength=\"{{ config.maxlength }}\"\n [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n />\n </div>\n </div>\n </c8y-form-group>\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i1$9.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
22998
23027
|
}
|
|
22999
23028
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FilePickerComponent, decorators: [{
|
|
23000
23029
|
type: Component,
|
|
@@ -23007,7 +23036,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
23007
23036
|
IconDirective,
|
|
23008
23037
|
RequiredInputPlaceholderDirective,
|
|
23009
23038
|
C8yTranslatePipe
|
|
23010
|
-
], template: "<div class=\"form-group\">\n <label\n class=\"c8y-radio\"\n title=\"{{ 'Upload a binary' | translate }}\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadBinary\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearInputFromUrl()\"\n />\n <span></span>\n <span>{{ 'Upload a binary' | translate }}</span>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Provide a file path' | translate }}\"\n data-cy=\"file-picker--file-path-input\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadUrl\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearSelectedFiles()\"\n />\n <span></span>\n <span>\n {{ 'Provide a file path' | translate }}\n </span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ fileUrlPopover | translate }}\"\n placement=\"top\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n *ngIf=\"isPopoverUsed()\"\n ></button>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Mark as provided' | translate }}\"\n *ngIf=\"allowedUploadChoices.includes('provided')\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"provided\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"setProvidedOption()\"\n />\n <span></span>\n <span>{{ 'Provided' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ providedPopover | translate }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadBinary'\">\n <c8y-form-group class=\"m-0\">\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop file or click to browse' | translate\"\n [attr.aria-label]=\"'Drop file or click to browse' | translate\"\n (dropped)=\"onFileDropped($event)\"\n [maxAllowedFiles]=\"maxAllowedFiles\"\n [files]=\"droppedFiles\"\n ></c8y-drop-area>\n </c8y-form-group>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadUrl'\">\n <c8y-form-group class=\"m-0\">\n <div class=\"m-b-4 p-b-8\">\n <div class=\"input-group\">\n <span class=\"input-group-addon\">\n <i c8yIcon=\"globe\"></i>\n </span>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} http://example.com/binary.zip\"\n name=\"fileUrl\"\n type=\"text\"\n required\n data-cy=\"file-picker--fileUrl\"\n [(ngModel)]=\"fileUrl\"\n (ngModelChange)=\"onFileUrlChange($event)\"\n maxlength=\"{{ config.maxlength }}\"\n [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n />\n </div>\n </div>\n </c8y-form-group>\n</div>\n" }]
|
|
23039
|
+
], template: "<div class=\"form-group\">\n <label\n class=\"c8y-radio\"\n [class.m-l-8]=\"allowedUploadChoices.includes('provided')\"\n title=\"{{ 'Upload a binary' | translate }}\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadBinary\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearInputFromUrl()\"\n />\n <span></span>\n <span>{{ 'Upload a binary' | translate }}</span>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Provide a file path' | translate }}\"\n data-cy=\"file-picker--file-path-input\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"uploadUrl\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"clearSelectedFiles()\"\n />\n <span></span>\n <span>\n {{ 'Provide a file path' | translate }}\n </span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ fileUrlPopover | translate }}\"\n placement=\"top\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n *ngIf=\"isPopoverUsed()\"\n ></button>\n </label>\n <label\n class=\"c8y-radio m-l-8\"\n title=\"{{ 'Mark as provided' | translate }}\"\n *ngIf=\"allowedUploadChoices.includes('provided')\"\n >\n <input\n name=\"uploadChoice-{{ filePickerIndex }}\"\n type=\"radio\"\n value=\"provided\"\n #radio\n [(ngModel)]=\"uploadChoice\"\n (click)=\"setProvidedOption()\"\n />\n <span></span>\n <span>{{ 'Provided' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ providedPopover | translate }}\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadBinary'\">\n <c8y-form-group class=\"m-0\">\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop file or click to browse' | translate\"\n [attr.aria-label]=\"'Drop file or click to browse' | translate\"\n (dropped)=\"onFileDropped($event)\"\n [maxAllowedFiles]=\"maxAllowedFiles\"\n [files]=\"droppedFiles\"\n ></c8y-drop-area>\n </c8y-form-group>\n</div>\n\n<div [hidden]=\"uploadChoice !== 'uploadUrl'\">\n <c8y-form-group class=\"m-0\">\n <div class=\"m-b-4 p-b-8\">\n <div class=\"input-group\">\n <span class=\"input-group-addon\">\n <i c8yIcon=\"globe\"></i>\n </span>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} http://example.com/binary.zip\"\n name=\"fileUrl\"\n type=\"text\"\n required\n data-cy=\"file-picker--fileUrl\"\n [(ngModel)]=\"fileUrl\"\n (ngModelChange)=\"onFileUrlChange($event)\"\n maxlength=\"{{ config.maxlength }}\"\n [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n />\n </div>\n </div>\n </c8y-form-group>\n</div>\n" }]
|
|
23011
23040
|
}], propDecorators: { dropArea: [{
|
|
23012
23041
|
type: ViewChild,
|
|
23013
23042
|
args: [DropAreaComponent, { static: true }]
|