@c8y/tutorial 1019.0.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/.browserslistrc +16 -0
- package/NOTICES +41743 -0
- package/cumulocity.config.ts +643 -0
- package/package.json +22 -0
- package/src/__mocks/README.md +73 -0
- package/src/__mocks/global-mocks/inventory.interceptor.ts +145 -0
- package/src/__mocks/global-mocks/measurements.interceptor.ts +58 -0
- package/src/__mocks/index.ts +5 -0
- package/src/__mocks/mock.model.ts +76 -0
- package/src/__mocks/mock.module.ts +121 -0
- package/src/__mocks/mock.realtime-subject.ts +68 -0
- package/src/__mocks/mock.realtime.ts +31 -0
- package/src/__mocks/mock.service.ts +113 -0
- package/src/__mocks/scoped-mocks/boilerplate.ts +54 -0
- package/src/__mocks/scoped-mocks/context-dashboard.ts +47 -0
- package/src/__mocks/scoped-mocks/device-data-grid.ts +44 -0
- package/src/__mocks/scoped-mocks/named-context-dashboard.ts +42 -0
- package/src/__mocks/scoped-mocks/server-side-data-grid.ts +47 -0
- package/src/__mocks/scoped-mocks/service-dashboard.ts +42 -0
- package/src/__mocks/utils/clean.realtime.ts +23 -0
- package/src/__mocks/utils/common.ts +114 -0
- package/src/__mocks/utils/generators/alarms.ts +30 -0
- package/src/__mocks/utils/generators/events.ts +14 -0
- package/src/__mocks/utils/generators/managedObjects.ts +208 -0
- package/src/__mocks/utils/generators/measurement.ts +22 -0
- package/src/__mocks/utils/generators/operations.ts +67 -0
- package/src/__mocks/utils/grid.ts +87 -0
- package/src/__mocks/utils/realtime.ts +59 -0
- package/src/alert/alert-example.components.html +110 -0
- package/src/alert/alert-example.components.ts +77 -0
- package/src/alert/alert-example.module.ts +21 -0
- package/src/app/app.module.ts +72 -0
- package/src/bootstrap.ts +19 -0
- package/src/branding/branding.less +78 -0
- package/src/client-interceptor/client-interceptor.module.ts +12 -0
- package/src/client-interceptor/client-interceptor.service.ts +61 -0
- package/src/client-interceptor/index.ts +1 -0
- package/src/component-styles/cascading-style-sheets-example/cascading-style-sheets-example.component.css +17 -0
- package/src/component-styles/cascading-style-sheets-example/cascading-style-sheets-example.component.ts +11 -0
- package/src/component-styles/cascading-style-sheets-example/cascading-style-sheets-example.module.ts +26 -0
- package/src/component-styles/leaner-style-sheets-example/leaner-style-sheets-example.component.less +14 -0
- package/src/component-styles/leaner-style-sheets-example/leaner-style-sheets-example.component.ts +11 -0
- package/src/component-styles/leaner-style-sheets-example/leaner-style-sheets-example.module.ts +26 -0
- package/src/component-styles/syntactically-awesome-style-sheets-example/syntactically-awesome-style-sheets-example.component.scss +13 -0
- package/src/component-styles/syntactically-awesome-style-sheets-example/syntactically-awesome-style-sheets-example.component.ts +11 -0
- package/src/component-styles/syntactically-awesome-style-sheets-example/syntactically-awesome-style-sheets-example.module.ts +26 -0
- package/src/dashboard/context-dashboard/context-dashboard.component.ts +32 -0
- package/src/dashboard/context-dashboard/context-dashboard.module.ts +22 -0
- package/src/dashboard/custom-dashboard/custom-dashboard.component.html +180 -0
- package/src/dashboard/custom-dashboard/custom-dashboard.component.ts +52 -0
- package/src/dashboard/custom-dashboard/custom-dashboard.module.ts +22 -0
- package/src/dashboard/index.ts +4 -0
- package/src/dashboard/named-context-dashboard/named-context-dashboard.component.ts +51 -0
- package/src/dashboard/named-context-dashboard/named-context-dashboard.module.ts +37 -0
- package/src/dashboard/service-dashboard/service-dashboard.component.ts +51 -0
- package/src/dashboard/service-dashboard/service-dashboard.module.ts +35 -0
- package/src/dashboard/widget-dashboard/widget-dashboard.component.ts +65 -0
- package/src/dashboard/widget-dashboard/widget-dashboard.module.ts +22 -0
- package/src/date-time-range/date-time-range-example.component.ts +109 -0
- package/src/date-time-range/date-time-range-example.module.ts +21 -0
- package/src/dynamic-forms/custom-element-example/custom-element-example.component.ts +70 -0
- package/src/dynamic-forms/custom-element-example/custom-element-example.module.ts +38 -0
- package/src/dynamic-forms/custom-element-example/types/checkbox/checkbox.type.component.html +26 -0
- package/src/dynamic-forms/custom-element-example/types/checkbox/checkbox.type.component.ts +21 -0
- package/src/dynamic-forms/dynamic-forms.module.ts +16 -0
- package/src/dynamic-forms/index.ts +2 -0
- package/src/dynamic-forms/introduction-example/introduction-example.component.ts +116 -0
- package/src/dynamic-forms/introduction-example/introduction-example.module.ts +24 -0
- package/src/dynamic-forms/json-schema-example/json-schema-example.component.html +33 -0
- package/src/dynamic-forms/json-schema-example/json-schema-example.component.ts +102 -0
- package/src/dynamic-forms/json-schema-example/json-schema-example.module.ts +24 -0
- package/src/for-of-directive/for-of-example.component.html +19 -0
- package/src/for-of-directive/for-of-example.component.ts +39 -0
- package/src/for-of-directive/for-of.module.ts +18 -0
- package/src/forms/form-validation/forms-validation.component.html +105 -0
- package/src/forms/form-validation/forms-validation.component.ts +52 -0
- package/src/forms/form-validation/forms.module.ts +22 -0
- package/src/forms/index.ts +1 -0
- package/src/grids/client-grid-example/client-grid-example.component.html +16 -0
- package/src/grids/client-grid-example/client-grid-example.component.ts +166 -0
- package/src/grids/client-grid-example/client-grid-example.module.ts +24 -0
- package/src/grids/client-grid-example/data.ts +427 -0
- package/src/grids/device-grid-example/device-grid-example.component.html +58 -0
- package/src/grids/device-grid-example/device-grid-example.component.ts +134 -0
- package/src/grids/device-grid-example/device-grid-example.module.ts +24 -0
- package/src/grids/grids-tabs.ts +37 -0
- package/src/grids/grids.module.ts +17 -0
- package/src/grids/index.ts +1 -0
- package/src/grids/server-grid-example/server-grid-example.component.html +26 -0
- package/src/grids/server-grid-example/server-grid-example.component.ts +121 -0
- package/src/grids/server-grid-example/server-grid-example.module.ts +24 -0
- package/src/grids/server-grid-example/server-grid-example.service.ts +266 -0
- package/src/grids/server-grid-example/type-data-grid-column/type.cell-renderer.component.ts +31 -0
- package/src/grids/server-grid-example/type-data-grid-column/type.data-grid-column.ts +47 -0
- package/src/grids/server-grid-example/type-data-grid-column/type.filtering-form-renderer.component.ts +107 -0
- package/src/grids/server-grid-example/type-data-grid-column/type.header-cell-renderer.component.ts +20 -0
- package/src/hello/hello.component.ts +55 -0
- package/src/hello/hello.module.ts +20 -0
- package/src/hello/index.ts +1 -0
- package/src/help/help-example.component.ts +23 -0
- package/src/help/help-example.module.ts +20 -0
- package/src/hooks/action/action.module.ts +34 -0
- package/src/hooks/action/action.ts +41 -0
- package/src/hooks/action/basic-view/basic-view.component.html +8 -0
- package/src/hooks/action/basic-view/basic-view.component.ts +18 -0
- package/src/hooks/action/index.ts +1 -0
- package/src/hooks/action/logout-action/logout-action.component.ts +18 -0
- package/src/hooks/action-bar/action-bar.module.ts +34 -0
- package/src/hooks/action-bar/action-bar.ts +28 -0
- package/src/hooks/action-bar/basic-view/basic-view.component.html +8 -0
- package/src/hooks/action-bar/basic-view/basic-view.component.ts +18 -0
- package/src/hooks/action-bar/index.ts +1 -0
- package/src/hooks/action-bar/refresh-element/refresh-element.component.html +15 -0
- package/src/hooks/action-bar/refresh-element/refresh-element.component.ts +21 -0
- package/src/hooks/breadcrumbs/basic-view/basic-view.component.html +7 -0
- package/src/hooks/breadcrumbs/basic-view/basic-view.component.ts +18 -0
- package/src/hooks/breadcrumbs/breadcrumbs.module.ts +34 -0
- package/src/hooks/breadcrumbs/breadcrumbs.ts +93 -0
- package/src/hooks/breadcrumbs/index.ts +1 -0
- package/src/hooks/component/basic-view/basic-view.component.html +11 -0
- package/src/hooks/component/basic-view/basic-view.component.ts +16 -0
- package/src/hooks/component/basic-view/simple.component.ts +8 -0
- package/src/hooks/component/component.module.ts +38 -0
- package/src/hooks/component/index.ts +1 -0
- package/src/hooks/drawer/index.ts +2 -0
- package/src/hooks/drawer/left-drawer-tutorial/left-drawer-tutorial.component.ts +8 -0
- package/src/hooks/drawer/left-drawer-tutorial/left-drawer.module.ts +10 -0
- package/src/hooks/drawer/right-drawer-tutorial/right-drawer-tutorial.component.ts +8 -0
- package/src/hooks/drawer/right-drawer-tutorial/right-drawer.module.ts +10 -0
- package/src/hooks/generic-wizard/index.ts +1 -0
- package/src/hooks/generic-wizard/minimal-setup/minimal-setup.component.ts +12 -0
- package/src/hooks/generic-wizard/minimal-setup/multiple-entries-one.component.ts +25 -0
- package/src/hooks/generic-wizard/minimal-setup/multiple-entries-two.component.ts +25 -0
- package/src/hooks/generic-wizard/minimal-setup/stepper-example.component.html +38 -0
- package/src/hooks/generic-wizard/minimal-setup/stepper-example.component.ts +33 -0
- package/src/hooks/generic-wizard/wizard-tabs.ts +22 -0
- package/src/hooks/generic-wizard/wizard.component.html +51 -0
- package/src/hooks/generic-wizard/wizard.component.ts +86 -0
- package/src/hooks/generic-wizard/wizard.module.ts +79 -0
- package/src/hooks/hooks.module.ts +19 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/navigator/index.ts +1 -0
- package/src/hooks/navigator/navigator.module.ts +21 -0
- package/src/hooks/navigator/navigator.ts +35 -0
- package/src/hooks/navigator/time-navigator-node/time-navigator-node.component.ts +19 -0
- package/src/hooks/navigator-route/basic-view/basic-view.component.html +7 -0
- package/src/hooks/navigator-route/basic-view/basic-view.component.ts +18 -0
- package/src/hooks/navigator-route/index.ts +1 -0
- package/src/hooks/navigator-route/navigator-route.module.ts +27 -0
- package/src/hooks/route/device/device-info.component.html +2 -0
- package/src/hooks/route/device/device-info.component.ts +13 -0
- package/src/hooks/route/device/device-tab-context.component.html +15 -0
- package/src/hooks/route/device/device-tab-context.component.ts +13 -0
- package/src/hooks/route/index.ts +1 -0
- package/src/hooks/route/random.guard.ts +12 -0
- package/src/hooks/route/route.module.ts +51 -0
- package/src/hooks/state/hook-state.module.ts +25 -0
- package/src/hooks/state/hook-with-service-example.component.html +29 -0
- package/src/hooks/state/hook-with-service-example.component.ts +36 -0
- package/src/hooks/stepper/basic-view/basic-view.component.html +17 -0
- package/src/hooks/stepper/basic-view/basic-view.component.ts +31 -0
- package/src/hooks/stepper/index.ts +4 -0
- package/src/hooks/stepper/stepper-hook.module.ts +53 -0
- package/src/hooks/stepper/steps/step1.component.html +24 -0
- package/src/hooks/stepper/steps/step1.component.ts +18 -0
- package/src/hooks/stepper/steps/step2.component.html +7 -0
- package/src/hooks/stepper/steps/step2.component.ts +11 -0
- package/src/hooks/tabs/awesome/awesome.component.html +7 -0
- package/src/hooks/tabs/awesome/awesome.component.ts +21 -0
- package/src/hooks/tabs/index.ts +1 -0
- package/src/hooks/tabs/outstanding/outstanding.component.html +22 -0
- package/src/hooks/tabs/outstanding/outstanding.component.ts +27 -0
- package/src/hooks/tabs/tab.ts +44 -0
- package/src/hooks/tabs/tabs.module.ts +37 -0
- package/src/hooks/version/custom-version-factory.service.ts +49 -0
- package/src/hooks/version/index.ts +1 -0
- package/src/hooks/version/version.module.ts +11 -0
- package/src/i18n.ts +18 -0
- package/src/input/range-input-example.component.ts +29 -0
- package/src/input/range-input-example.module.ts +19 -0
- package/src/lazy/component-one.component.ts +28 -0
- package/src/lazy/component-two.component.ts +17 -0
- package/src/lazy/index.ts +1 -0
- package/src/lazy/lazy-loaded.module.ts +21 -0
- package/src/lazy/lazy-routing.module.ts +21 -0
- package/src/lazy/lazy.hooks.ts +24 -0
- package/src/lazy-widget/index.ts +1 -0
- package/src/lazy-widget/lazy-widget-config/index.ts +1 -0
- package/src/lazy-widget/lazy-widget-config/lazy-widget-config.component.ts +10 -0
- package/src/lazy-widget/lazy-widget-view/index.ts +1 -0
- package/src/lazy-widget/lazy-widget-view/lazy-widget-view.component.ts +10 -0
- package/src/lazy-widget/lazy-widget.module.ts +27 -0
- package/src/list/index.ts +1 -0
- package/src/list/list/list-check/list-check.component.html +35 -0
- package/src/list/list/list-check/list-check.component.ts +47 -0
- package/src/list/list/list-check/list-check.module.ts +21 -0
- package/src/list/list/list-timeline/list-timeline.component.html +30 -0
- package/src/list/list/list-timeline/list-timeline.component.ts +46 -0
- package/src/list/list/list-timeline/list-timeline.module.ts +21 -0
- package/src/list/list-virtual-scroll/list-virtual-scroll-check/list-virtual-scroll-check.component.html +105 -0
- package/src/list/list-virtual-scroll/list-virtual-scroll-check/list-virtual-scroll-check.component.ts +70 -0
- package/src/list/list-virtual-scroll/list-virtual-scroll-check/list-virtual-scroll-check.module.ts +22 -0
- package/src/list/list-virtual-scroll/list-virtual-scroll-timeline/list-virtual-scroll-timeline.component.html +37 -0
- package/src/list/list-virtual-scroll/list-virtual-scroll-timeline/list-virtual-scroll-timeline.component.ts +69 -0
- package/src/list/list-virtual-scroll/list-virtual-scroll-timeline/list-virtual-scroll-timeline.module.ts +24 -0
- package/src/list/lists.module.ts +17 -0
- package/src/main.ts +23 -0
- package/src/maps/cluster-map/cluster-map-example.component.html +60 -0
- package/src/maps/cluster-map/cluster-map-example.component.ts +39 -0
- package/src/maps/cluster-map/cluster-map-example.module.ts +24 -0
- package/src/maps/cluster-map-root-node/cluster-map-root-node-example.component.html +54 -0
- package/src/maps/cluster-map-root-node/cluster-map-root-node-example.component.ts +54 -0
- package/src/maps/cluster-map-root-node/cluster-map-root-node-example.module.ts +26 -0
- package/src/maps/map-examples.module.ts +18 -0
- package/src/maps/map-popup/map-popup-example.component.html +34 -0
- package/src/maps/map-popup/map-popup-example.component.ts +43 -0
- package/src/maps/map-popup/map-popup-example.module.ts +24 -0
- package/src/maps/simple-map/simple-map-example.component.html +59 -0
- package/src/maps/simple-map/simple-map-example.component.ts +70 -0
- package/src/maps/simple-map/simple-map-example.module.ts +24 -0
- package/src/modal/confirm-modal/confirm-modal-example.component.ts +69 -0
- package/src/modal/confirm-modal/confirm-modal-example.module.ts +22 -0
- package/src/modal/ngx-modal/ngx-modal-example.component.ts +34 -0
- package/src/modal/ngx-modal/ngx-modal-example.module.ts +22 -0
- package/src/modal/simple-modal/modal-example.component.ts +34 -0
- package/src/modal/simple-modal/modal.example.module.ts +21 -0
- package/src/polyfills.ts +33 -0
- package/src/popconfirm/pop-confirm-example.component.ts +61 -0
- package/src/popconfirm/pop-confirm-example.module.ts +23 -0
- package/src/properties-list/properties-list-example.component.ts +49 -0
- package/src/properties-list/properties-list-example.module.ts +21 -0
- package/src/provider-configuration/index.ts +3 -0
- package/src/provider-configuration/introduction-example/introduction.component.ts +69 -0
- package/src/provider-configuration/introduction-example/introduction.module.ts +21 -0
- package/src/provider-configuration/provider-configuration-example/demo-provider.guard.ts +9 -0
- package/src/provider-configuration/provider-configuration-example/provider-configuration.module.ts +48 -0
- package/src/quick-link/quick-link-example.component.ts +39 -0
- package/src/quick-link/quick-link-example.module.ts +23 -0
- package/src/realtime/index.ts +1 -0
- package/src/realtime/realtime-tutorial.component.html +52 -0
- package/src/realtime/realtime-tutorial.component.ts +91 -0
- package/src/realtime/realtime-tutorial.module.ts +21 -0
- package/src/redirect-to-last-route/index.ts +1 -0
- package/src/redirect-to-last-route/redirect-to-last-route-guard.service.ts +16 -0
- package/src/redirect-to-last-route/redirect-to-last-route.module.ts +20 -0
- package/src/redirect-to-last-route/view-context-redirect.service.ts +53 -0
- package/src/selector/asset-selector-example/child-devices/asset-selector-child-devices.component.ts +49 -0
- package/src/selector/asset-selector-example/child-devices/asset-selector-child-devices.module.ts +24 -0
- package/src/selector/asset-selector-example/column-header/asset-selector-column-header.component.ts +46 -0
- package/src/selector/asset-selector-example/column-header/asset-selector-column-header.module.ts +24 -0
- package/src/selector/asset-selector-example/different-root/asset-selector-different-root.component.ts +87 -0
- package/src/selector/asset-selector-example/different-root/asset-selector-different-root.module.ts +24 -0
- package/src/selector/asset-selector-example/general-example/asset-selector-example.component.html +342 -0
- package/src/selector/asset-selector-example/general-example/asset-selector-example.component.ts +34 -0
- package/src/selector/asset-selector-example/general-example/asset-selector-example.module.ts +22 -0
- package/src/selector/asset-selector-example/global-search/asset-selector-global-search.component.ts +50 -0
- package/src/selector/asset-selector-example/global-search/asset-selector-global-search.module.ts +24 -0
- package/src/selector/asset-selector-example/miller-columns-options/asset-selector-miller-example.component.ts +85 -0
- package/src/selector/asset-selector-example/miller-columns-options/asset-selector-miller-example.module.ts +26 -0
- package/src/selector/asset-selector-example/multi-select/asset-selector-multi-select.component.ts +50 -0
- package/src/selector/asset-selector-example/multi-select/asset-selector-multi-select.module.ts +24 -0
- package/src/selector/asset-selector-example/only-devices/asset-selector-only-devices.component.ts +44 -0
- package/src/selector/asset-selector-example/only-devices/asset-selector-only-devices.module.ts +24 -0
- package/src/selector/asset-selector-example/single-search/asset-selector-single-search.component.ts +71 -0
- package/src/selector/asset-selector-example/single-search/asset-selector-single-search.module.ts +24 -0
- package/src/selector/asset-selector-example/single-select/asset-selector-single-select.component.ts +47 -0
- package/src/selector/asset-selector-example/single-select/asset-single-select.module.ts +24 -0
- package/src/selector/asset-selector-example/tree-devices/asset-selector-tree-devices.component.ts +62 -0
- package/src/selector/asset-selector-example/tree-devices/asset-selector-tree-devices.module.ts +24 -0
- package/src/selector/asset-selector-example/tree-options/asset-selector-tree-example.component.ts +83 -0
- package/src/selector/asset-selector-example/tree-options/asset-selector-tree-example.module.ts +26 -0
- package/src/selector/asset-selector-example/tree-search/asset-selector-tree-search.component.ts +75 -0
- package/src/selector/asset-selector-example/tree-search/asset-selector-tree-search.module.ts +24 -0
- package/src/selector/asset-selector-example/tree-single/asset-selector-tree-single.component.ts +66 -0
- package/src/selector/asset-selector-example/tree-single/asset-selector-tree-single.module.ts +24 -0
- package/src/selector/datapoint-selection-example/context-example/datapoint-selection-context-example.component.ts +54 -0
- package/src/selector/datapoint-selection-example/context-example/datapoint-selection-context-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/dragdrop-example/datapoint-selection-dragdrop-example.component.ts +43 -0
- package/src/selector/datapoint-selection-example/dragdrop-example/datapoint-selection-dragdrop-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/general-example/datapoint-selection-example.component.html +202 -0
- package/src/selector/datapoint-selection-example/general-example/datapoint-selection-example.component.ts +51 -0
- package/src/selector/datapoint-selection-example/general-example/datapoint-selection-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/list-example/datapoint-selection-list-example.component.ts +42 -0
- package/src/selector/datapoint-selection-example/list-example/datapoint-selection-list-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/modal-example/datapoint-selection-modal-example.component.ts +51 -0
- package/src/selector/datapoint-selection-example/modal-example/datapoint-selection-modal-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/no-templates-example/datapoint-selection-notemplates-example.component.ts +43 -0
- package/src/selector/datapoint-selection-example/no-templates-example/datapoint-selection-notemplates-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/selector/datapoint-selection-selector-example.component.ts +43 -0
- package/src/selector/datapoint-selection-example/selector/datapoint-selection-selector-example.module.ts +24 -0
- package/src/selector/datapoint-selection-example/validation-example/datapoint-selection-validation-example.component.ts +46 -0
- package/src/selector/datapoint-selection-example/validation-example/datapoint-selection-validation-example.module.ts +24 -0
- package/src/standalone-demo/index.ts +1 -0
- package/src/standalone-demo/standalone-component/standalone-component.component.html +4 -0
- package/src/standalone-demo/standalone-component/standalone-component.component.ts +11 -0
- package/src/standalone-demo/standalone-demo.module.ts +23 -0
- package/src/stepper/device-stepper.component.html +70 -0
- package/src/stepper/device-stepper.component.ts +98 -0
- package/src/stepper/device.model.ts +5 -0
- package/src/stepper/index.ts +1 -0
- package/src/stepper/stepper.component.ts +19 -0
- package/src/stepper/stepper.module.ts +24 -0
- package/src/stepper/stepper.service.ts +32 -0
- package/src/time/time-picker-example.component.ts +19 -0
- package/src/time/time-picker-example.module.ts +21 -0
- package/src/translations/date-translation/c8y-translation/c8y-date-translation.component.ts +23 -0
- package/src/translations/date-translation/c8y-translation/c8y-date-translation.module.ts +22 -0
- package/src/translations/date-translation/ng-translation/date-translation.component.ts +17 -0
- package/src/translations/date-translation/ng-translation/date-translation.module.ts +22 -0
- package/src/translations/dynamic-form-translation/dynamic-form-translation.component.ts +58 -0
- package/src/translations/dynamic-form-translation/dynamic-form-translation.module.ts +22 -0
- package/src/translations/index.ts +1 -0
- package/src/translations/locales/it.po +18 -0
- package/src/translations/locales/pt_BR.po +33 -0
- package/src/translations/new-language/new-language.component.html +45 -0
- package/src/translations/new-language/new-language.component.ts +19 -0
- package/src/translations/new-language/new-language.module.ts +21 -0
- package/src/translations/new-translate/new-translation.component.html +92 -0
- package/src/translations/new-translate/new-translation.component.ts +9 -0
- package/src/translations/new-translate/new-translation.module.ts +22 -0
- package/src/translations/text-translation/gettext-translation/text-translation-gettext.component.ts +18 -0
- package/src/translations/text-translation/gettext-translation/text-translation-gettext.module.ts +22 -0
- package/src/translations/text-translation/ngNonBindable-translation/text-translation-ngnonbindable.component.ts +22 -0
- package/src/translations/text-translation/ngNonBindable-translation/text-translation-ngnonbindable.module.ts +24 -0
- package/src/translations/text-translation/service-translation/text-translation-by-service.component.ts +38 -0
- package/src/translations/text-translation/service-translation/text-translation-by-service.module.ts +24 -0
- package/src/translations/translation-tabs.ts +50 -0
- package/src/translations/translations.module.ts +18 -0
- package/src/user-menu/index.ts +1 -0
- package/src/user-menu/user-menu.module.ts +13 -0
- package/src/user-menu/user-menu.ts +26 -0
- package/src/widget/demo-widget-config.component.ts +81 -0
- package/src/widget/demo-widget.component.ts +35 -0
- package/src/widget/demo-widget.module.ts +47 -0
- package/src/widget/index.ts +1 -0
- package/src/widget-resolvers/alternative-event.resolver.ts +21 -0
- package/src/widget-resolvers/event-property.resolver.ts +52 -0
- package/src/widget-resolvers/event.resolver.ts +100 -0
- package/src/widget-resolvers/index.ts +1 -0
- package/src/widget-resolvers/widget-resolvers-config/widget-resolvers-config.component.html +31 -0
- package/src/widget-resolvers/widget-resolvers-config/widget-resolvers-config.component.ts +67 -0
- package/src/widget-resolvers/widget-resolvers.component.html +13 -0
- package/src/widget-resolvers/widget-resolvers.component.ts +37 -0
- package/src/widget-resolvers/widget-resolvers.module.ts +50 -0
- package/tsconfig.app.json +18 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Creating and Registering Interceptors
|
|
2
|
+
## Introduction
|
|
3
|
+
|
|
4
|
+
Interceptors are a feature used in HTTP communication to intercept and possibly alter HTTP requests or responses. They are powerful tools in managing communication with backend services and can be used to manipulate requests or simulate server responses.
|
|
5
|
+
|
|
6
|
+
## Why Use Interceptors
|
|
7
|
+
|
|
8
|
+
In our context, we aim to mock backend requests, particularly for unauthenticated users. This allows developers to simulate a variety of server responses without needing to communicate with the actual backend service, facilitating development and testing.
|
|
9
|
+
|
|
10
|
+
## Precaution
|
|
11
|
+
|
|
12
|
+
All files and logic within the __mocks folder are intended solely to enable Codex operation for unauthenticated users. This code should not be copied and should not be used as the basis for your own implementations.
|
|
13
|
+
|
|
14
|
+
## Adding an Interceptor
|
|
15
|
+
|
|
16
|
+
In this section, you will learn how to add your own interceptor in the tutorial application. The first decision you have to make is whether you want to create a global interceptor, which will act on all paths, or a scoped interceptor, which will act only on a selected path. They differ by the path parameter: global interceptors do not have a path specified.
|
|
17
|
+
|
|
18
|
+
Here's an example of how to register interceptors in the module's providers section:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
{
|
|
22
|
+
provide: API_MOCK_CONFIG,
|
|
23
|
+
useValue: {
|
|
24
|
+
path: 'path-on-which-this-interceptor-is-tiggered',
|
|
25
|
+
// The interceptors are sorted by their ID, so the scoped interceptors should be before the global ones.
|
|
26
|
+
id: 'your-scoped-interceptor-name',
|
|
27
|
+
mockService: ScopedInterceptor
|
|
28
|
+
} as ApiMockConfig,
|
|
29
|
+
multi: true
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
provide: API_MOCK_CONFIG,
|
|
33
|
+
useValue: {
|
|
34
|
+
// The interceptors are sorted by their ID, so the scoped interceptors should be before the global ones.
|
|
35
|
+
id: 'z-your-global-interceptor-name',
|
|
36
|
+
mockService: GlobalInterceptor
|
|
37
|
+
} as ApiMockConfig,
|
|
38
|
+
multi: true
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Implementing the Interceptor
|
|
44
|
+
|
|
45
|
+
After deciding the type of interceptor, you should add it to the corresponding folder: scoped-mocks for scoped interceptors and global-mocks for global ones.
|
|
46
|
+
|
|
47
|
+
Here's a template for an interceptor that intercepts all requests sent to "inventory/managedObjects":
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
export class BoilerplateInterceptor implements HttpInterceptor {
|
|
51
|
+
intercept(req: ApiCall, next: HttpHandler): Observable<IFetchResponse> {
|
|
52
|
+
return handleRequest(req, next, 'inventory/managedObjects', {
|
|
53
|
+
POST: this.mockPOST.bind(this),
|
|
54
|
+
PUT: this.mockPUT.bind(this),
|
|
55
|
+
GET: this.mockGET.bind(this)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
mockPOST(_requestDescriptor: string) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
mockPUT(_requestDescriptor: string) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
mockGET(_requestDescriptor: string) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This interceptor will capture all POST, PUT and GET requests to "inventory/managedObjects". In this template, all mock functions simply return null — you should replace them with your own logic.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { IFetchResponse } from '@c8y/client';
|
|
2
|
+
import { ApiCall, HttpHandler, HttpInterceptor } from '@c8y/ngx-components/api';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { generateResponse, handleRequest } from '../utils/common';
|
|
5
|
+
import {
|
|
6
|
+
generateUserPreferences,
|
|
7
|
+
generateRealtimeDeviceMO,
|
|
8
|
+
generateRandomMo,
|
|
9
|
+
generateDevice,
|
|
10
|
+
generateSubGroup,
|
|
11
|
+
generateAsset,
|
|
12
|
+
generateGroup,
|
|
13
|
+
generateAssetType
|
|
14
|
+
} from '../../__mocks/utils/generators/managedObjects';
|
|
15
|
+
|
|
16
|
+
export class InventoryInterceptor implements HttpInterceptor {
|
|
17
|
+
intercept(req: ApiCall, next: HttpHandler): Observable<IFetchResponse> {
|
|
18
|
+
return handleRequest(req, next, 'inventory/managedObjects', {
|
|
19
|
+
POST: this.mockPOST.bind(this),
|
|
20
|
+
PUT: this.mockPUT.bind(this),
|
|
21
|
+
GET: this.mockGET.bind(this)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private mockPOST(_requestDescriptor: string) {
|
|
26
|
+
if (_requestDescriptor.includes('c8y_UserPreference')) {
|
|
27
|
+
return generateResponse(() => generateUserPreferences());
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private mockPUT(_requestDescriptor: string) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private async mockGET(_requestDescriptor: string) {
|
|
37
|
+
/**
|
|
38
|
+
* Workaround. Leaflet is lazy loaded. Adding mocked assets too fast leads to not loaded markers.
|
|
39
|
+
*/
|
|
40
|
+
await new Promise(r => setTimeout(r, 300));
|
|
41
|
+
|
|
42
|
+
const responseGenerators = this.getResponseGenerators(_requestDescriptor);
|
|
43
|
+
for (const urlPart in responseGenerators) {
|
|
44
|
+
if (_requestDescriptor.includes(urlPart)) {
|
|
45
|
+
const generatorResult = responseGenerators[urlPart]();
|
|
46
|
+
if (generatorResult) {
|
|
47
|
+
return generateResponse(() => generatorResult);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Intercept request to /inventory/managedObjects/<moId>
|
|
54
|
+
*/
|
|
55
|
+
if (/\/\d+/.test(_requestDescriptor)) {
|
|
56
|
+
return generateResponse(() => generateDevice());
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private getResponseGenerators(_requestDescriptor: string) {
|
|
62
|
+
return {
|
|
63
|
+
c8y_DeviceGroup: () => ({
|
|
64
|
+
managedObjects: [...[...Array(10)].map(() => generateSubGroup())]
|
|
65
|
+
}),
|
|
66
|
+
c8y_DeviceSubgroup: () => ({
|
|
67
|
+
managedObjects: [generateSubGroup()]
|
|
68
|
+
}),
|
|
69
|
+
'has(c8y_IsDeviceGroup)': () => ({
|
|
70
|
+
managedObjects: [...[...Array(5)].map(() => generateGroup())]
|
|
71
|
+
}),
|
|
72
|
+
'has(c8y_Position)': () => ({
|
|
73
|
+
managedObjects: [generateRealtimeDeviceMO()]
|
|
74
|
+
}),
|
|
75
|
+
'has(c8y_IsDevice)': () => ({
|
|
76
|
+
managedObjects: [...[...Array(5)].map(() => generateDevice())]
|
|
77
|
+
}),
|
|
78
|
+
childAssets: () => ({
|
|
79
|
+
references: [
|
|
80
|
+
...[...Array(3)].map(() => ({
|
|
81
|
+
managedObject: generateRandomMo()
|
|
82
|
+
}))
|
|
83
|
+
]
|
|
84
|
+
}),
|
|
85
|
+
childDevices: () => ({
|
|
86
|
+
references: []
|
|
87
|
+
}),
|
|
88
|
+
childAdditions: () => ({
|
|
89
|
+
references: []
|
|
90
|
+
}),
|
|
91
|
+
c8y_Dashboard: () => ({
|
|
92
|
+
managedObjects: []
|
|
93
|
+
}),
|
|
94
|
+
c8y_IsAssetType: () => ({
|
|
95
|
+
managedObjects: [generateAssetType()]
|
|
96
|
+
}),
|
|
97
|
+
c8y_IsDeviceGroup: () => ({
|
|
98
|
+
managedObjects: [
|
|
99
|
+
...[...Array(5)].map(() => (Math.random() < 0.5 ? generateSubGroup() : generateAsset()))
|
|
100
|
+
]
|
|
101
|
+
}),
|
|
102
|
+
c8y_IsDevice: () =>
|
|
103
|
+
_requestDescriptor.includes('"onlyRoots":true') &&
|
|
104
|
+
!_requestDescriptor.includes('c8y_IsDeviceGroup')
|
|
105
|
+
? {
|
|
106
|
+
managedObjects: [...[...Array(2)].map(() => generateDevice())]
|
|
107
|
+
}
|
|
108
|
+
: null,
|
|
109
|
+
supportedMeasurements: () => ({
|
|
110
|
+
c8y_SupportedMeasurements: ['c8y_Battery']
|
|
111
|
+
}),
|
|
112
|
+
supportedSeries: () => ({
|
|
113
|
+
c8y_SupportedSeries: ['c8y_Battery.Battery']
|
|
114
|
+
}),
|
|
115
|
+
c8y_Kpi: () => ({
|
|
116
|
+
managedObjects: []
|
|
117
|
+
}),
|
|
118
|
+
kpis: () => ({
|
|
119
|
+
managedObjects: []
|
|
120
|
+
}),
|
|
121
|
+
c8y_Battery: () => ({
|
|
122
|
+
id: '100000',
|
|
123
|
+
type: 'c8y_Battery',
|
|
124
|
+
source: {
|
|
125
|
+
id: '200000'
|
|
126
|
+
},
|
|
127
|
+
c8y_Battery: {
|
|
128
|
+
Battery: {
|
|
129
|
+
unit: '%',
|
|
130
|
+
value: 67
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}),
|
|
134
|
+
c8y_Service: () => ({
|
|
135
|
+
managedObjects: [generateDevice()]
|
|
136
|
+
}),
|
|
137
|
+
gainsightBotEnabled: () => ({
|
|
138
|
+
managedObjects: []
|
|
139
|
+
}),
|
|
140
|
+
language: () => ({
|
|
141
|
+
managedObjects: [generateUserPreferences()]
|
|
142
|
+
})
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { IFetchResponse } from '@c8y/client';
|
|
2
|
+
import { ApiCall, HttpHandler, HttpInterceptor } from '@c8y/ngx-components/api';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { generateResponse, handleRequest } from '../utils/common';
|
|
5
|
+
|
|
6
|
+
export class MeasurementsInterceptor implements HttpInterceptor {
|
|
7
|
+
intercept(req: ApiCall, next: HttpHandler): Observable<IFetchResponse> {
|
|
8
|
+
return handleRequest(req, next, 'measurement/measurements', {
|
|
9
|
+
POST: this.mockPOST.bind(this),
|
|
10
|
+
PUT: this.mockPUT.bind(this),
|
|
11
|
+
GET: this.mockGET.bind(this)
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
private mockPOST(_requestDescriptor) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private mockPUT(_requestDescriptor) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private mockGET(_requestDescriptor: string) {
|
|
24
|
+
const responseGenerators = this.getResponseGenerators();
|
|
25
|
+
|
|
26
|
+
for (const urlPart in responseGenerators) {
|
|
27
|
+
if (_requestDescriptor.includes(urlPart)) {
|
|
28
|
+
const generatorResult = responseGenerators[urlPart]();
|
|
29
|
+
if (generatorResult) {
|
|
30
|
+
return generateResponse(() => generatorResult);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private getResponseGenerators() {
|
|
38
|
+
return {
|
|
39
|
+
c8y_Battery: () => ({
|
|
40
|
+
measurements: [
|
|
41
|
+
{
|
|
42
|
+
id: '10000',
|
|
43
|
+
type: 'c8y_Battery',
|
|
44
|
+
source: {
|
|
45
|
+
id: '20000'
|
|
46
|
+
},
|
|
47
|
+
c8y_Battery: {
|
|
48
|
+
Battery: {
|
|
49
|
+
unit: '%',
|
|
50
|
+
value: 67
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import {
|
|
3
|
+
IAlarm,
|
|
4
|
+
IEvent,
|
|
5
|
+
IManagedObject,
|
|
6
|
+
IMeasurement,
|
|
7
|
+
IOperation,
|
|
8
|
+
IOperationBulk
|
|
9
|
+
} from '@c8y/client';
|
|
10
|
+
import { HttpInterceptor } from '@c8y/ngx-components/api';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A string literal type that represents the HTTP methods that can be used for making requests.
|
|
14
|
+
*/
|
|
15
|
+
export type HttpMethods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'PATCH';
|
|
16
|
+
/**
|
|
17
|
+
* A type that extends the built-in Response object to include a json method, which returns a Promise of a generic type T.
|
|
18
|
+
*/
|
|
19
|
+
export type ResponseWithType<T = unknown> = Response & {
|
|
20
|
+
json: () => T;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* A union type representing any of the possible data types.
|
|
24
|
+
*/
|
|
25
|
+
export type IAnyData =
|
|
26
|
+
| IAlarm
|
|
27
|
+
| IEvent
|
|
28
|
+
| IManagedObject
|
|
29
|
+
| IMeasurement
|
|
30
|
+
| IOperation
|
|
31
|
+
| IOperationBulk;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Enumeration of the possible channel paths.
|
|
35
|
+
*/
|
|
36
|
+
export enum Channels {
|
|
37
|
+
ManagedObjects = '/managedobjects/*',
|
|
38
|
+
Operations = '/operations/*',
|
|
39
|
+
BulkOperations = '/bulkOperations/*',
|
|
40
|
+
Measurements = '/measurements/*',
|
|
41
|
+
Alarms = '/alarms/*',
|
|
42
|
+
Events = '/events/*',
|
|
43
|
+
MangedObjectsMap = '/managedobjects/1'
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* path and mockService
|
|
47
|
+
*/
|
|
48
|
+
export const API_MOCK_CONFIG = new InjectionToken<ApiMockConfig>('ApiMockConfig');
|
|
49
|
+
/**
|
|
50
|
+
* Interface for configuring API mocking.
|
|
51
|
+
*/
|
|
52
|
+
export interface ApiMockConfig {
|
|
53
|
+
/**
|
|
54
|
+
* Route path under which all interceptors are registered.
|
|
55
|
+
* By default all routes are affected.
|
|
56
|
+
*/
|
|
57
|
+
path?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Mock service that should implement the HttpInterceptor interface.
|
|
60
|
+
* This service will be used to intercept http requests and return mock responses.
|
|
61
|
+
*/
|
|
62
|
+
mockService: new (...args: unknown[]) => HttpInterceptor;
|
|
63
|
+
/**
|
|
64
|
+
* Unique identifier for the interceptor.
|
|
65
|
+
*/
|
|
66
|
+
id: string;
|
|
67
|
+
debug?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* An object representing default values for pagination statistics.
|
|
71
|
+
*/
|
|
72
|
+
export const DEFAULT_STATISTICS = {
|
|
73
|
+
totalPages: 1,
|
|
74
|
+
pageSize: 2000,
|
|
75
|
+
currentPage: 1
|
|
76
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Inject, NgModule } from '@angular/core';
|
|
3
|
+
import { IUser } from '@c8y/client';
|
|
4
|
+
import {
|
|
5
|
+
AppStateService,
|
|
6
|
+
CoreModule,
|
|
7
|
+
OptionsService,
|
|
8
|
+
RealtimeSubjectService
|
|
9
|
+
} from '@c8y/ngx-components';
|
|
10
|
+
import { InventoryInterceptor } from './global-mocks/inventory.interceptor';
|
|
11
|
+
import { MeasurementsInterceptor } from './global-mocks/measurements.interceptor';
|
|
12
|
+
import { API_MOCK_CONFIG, ApiMockConfig } from './mock.model';
|
|
13
|
+
import { MockService } from './mock.service';
|
|
14
|
+
import { NamedContextDashboardInterceptor } from './scoped-mocks/named-context-dashboard';
|
|
15
|
+
import { ContextDashboardInterceptor } from './scoped-mocks/context-dashboard';
|
|
16
|
+
import { ServerSideDataGridInterceptor } from './scoped-mocks/server-side-data-grid';
|
|
17
|
+
import { DeviceDataGridInterceptor } from './scoped-mocks/device-data-grid';
|
|
18
|
+
import { ServiceDashboardInterceptor } from './scoped-mocks/service-dashboard';
|
|
19
|
+
import { RealtimeSubjectServiceWithMocking } from './mock.realtime';
|
|
20
|
+
// import { BoilerplateInterceptor } from './scoped-mocks/boilerplate';
|
|
21
|
+
@NgModule({
|
|
22
|
+
imports: [CoreModule, CommonModule],
|
|
23
|
+
providers: [
|
|
24
|
+
// TODO: ask Jan about mocking clusters maps/cluster
|
|
25
|
+
// {
|
|
26
|
+
// provide: API_MOCK_CONFIG,
|
|
27
|
+
// useValue: {
|
|
28
|
+
// id: 'a-cluster-map-interceptor',
|
|
29
|
+
// path: 'maps/cluster',
|
|
30
|
+
// mockService: BoilerplateInterceptor,
|
|
31
|
+
// debug: true
|
|
32
|
+
// } as ApiMockConfig,
|
|
33
|
+
// multi: true
|
|
34
|
+
// },
|
|
35
|
+
{
|
|
36
|
+
provide: API_MOCK_CONFIG,
|
|
37
|
+
useValue: {
|
|
38
|
+
id: 'a-service-dashboard-interceptor',
|
|
39
|
+
path: 'service-dashboard',
|
|
40
|
+
mockService: ServiceDashboardInterceptor,
|
|
41
|
+
debug: true
|
|
42
|
+
} as ApiMockConfig,
|
|
43
|
+
multi: true
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
provide: API_MOCK_CONFIG,
|
|
47
|
+
useValue: {
|
|
48
|
+
id: 'server-side-data-grid-interceptor',
|
|
49
|
+
path: 'server-grid-example',
|
|
50
|
+
mockService: ServerSideDataGridInterceptor
|
|
51
|
+
} as ApiMockConfig,
|
|
52
|
+
multi: true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
provide: API_MOCK_CONFIG,
|
|
56
|
+
useValue: {
|
|
57
|
+
id: 'device-data-grid-interceptor',
|
|
58
|
+
path: 'device-grid-example',
|
|
59
|
+
mockService: DeviceDataGridInterceptor
|
|
60
|
+
} as ApiMockConfig,
|
|
61
|
+
multi: true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
provide: API_MOCK_CONFIG,
|
|
65
|
+
useValue: {
|
|
66
|
+
id: 'scoped-dashboard-context-interceptor',
|
|
67
|
+
path: 'dashboards/context',
|
|
68
|
+
mockService: ContextDashboardInterceptor
|
|
69
|
+
} as ApiMockConfig,
|
|
70
|
+
multi: true
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
provide: API_MOCK_CONFIG,
|
|
74
|
+
useValue: {
|
|
75
|
+
path: 'named-context',
|
|
76
|
+
// The interceptors are sorted by their ID, so the scoped interceptors should be before the global ones.
|
|
77
|
+
id: 'named-context-interceptor-example',
|
|
78
|
+
mockService: NamedContextDashboardInterceptor
|
|
79
|
+
} as ApiMockConfig,
|
|
80
|
+
multi: true
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
provide: API_MOCK_CONFIG,
|
|
84
|
+
useValue: {
|
|
85
|
+
// The interceptors are sorted by their ID, so the scoped interceptors should be before the global ones.
|
|
86
|
+
id: 'z-global-inventory-interceptor',
|
|
87
|
+
mockService: InventoryInterceptor
|
|
88
|
+
} as ApiMockConfig,
|
|
89
|
+
multi: true
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
provide: API_MOCK_CONFIG,
|
|
93
|
+
useValue: {
|
|
94
|
+
// The interceptors are sorted by their ID, so the scoped interceptors should be before the global ones.
|
|
95
|
+
id: 'z-global-measurementsInterceptor-interceptor',
|
|
96
|
+
mockService: MeasurementsInterceptor
|
|
97
|
+
} as ApiMockConfig,
|
|
98
|
+
multi: true
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
provide: RealtimeSubjectService,
|
|
102
|
+
useExisting: RealtimeSubjectServiceWithMocking
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
})
|
|
106
|
+
export class MockModule {
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
108
|
+
constructor(
|
|
109
|
+
@Inject(MockService) service,
|
|
110
|
+
appStateService: AppStateService,
|
|
111
|
+
private options: OptionsService
|
|
112
|
+
) {
|
|
113
|
+
if (this.options.get<boolean>('noLogin', false)) {
|
|
114
|
+
appStateService.currentUser.next({
|
|
115
|
+
id: 'NO_LOGIN',
|
|
116
|
+
userName: 'noLogin',
|
|
117
|
+
displayName: 'noLogin'
|
|
118
|
+
} as IUser);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { RealtimeMessage } from '@c8y/ngx-components';
|
|
3
|
+
import { Observable, Subject, Subscription, interval } from 'rxjs';
|
|
4
|
+
import { map, take, takeUntil } from 'rxjs/operators';
|
|
5
|
+
import { CleanRealtime } from './utils/clean.realtime';
|
|
6
|
+
import { Channels } from './mock.model';
|
|
7
|
+
import { getFakeData } from './utils/realtime';
|
|
8
|
+
import { IManagedObject } from '@c8y/client';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Mock service for creating a stream of realtime data for a given channel.
|
|
12
|
+
*/
|
|
13
|
+
@Injectable({ providedIn: 'root' })
|
|
14
|
+
export class MockRealtimeSubject {
|
|
15
|
+
/**
|
|
16
|
+
* The channel for which the realtime data will be mocked.
|
|
17
|
+
*/
|
|
18
|
+
private readonly REALTIME_CHANNEL = Channels.ManagedObjects;
|
|
19
|
+
/**
|
|
20
|
+
* The subscription for the interval generating the mocked data.
|
|
21
|
+
*/
|
|
22
|
+
private intervalSubscription: Subscription;
|
|
23
|
+
/**
|
|
24
|
+
* The subject emitting the mocked realtime data.
|
|
25
|
+
*/
|
|
26
|
+
private realtimeMockedData$: Subject<RealtimeMessage<IManagedObject>>;
|
|
27
|
+
|
|
28
|
+
constructor(cleanRealtime: CleanRealtime) {
|
|
29
|
+
cleanRealtime.stop$.pipe(takeUntil(cleanRealtime.onDestroy$)).subscribe(() => this.cleanUp());
|
|
30
|
+
cleanRealtime.onDestroy$.pipe(take(1)).subscribe(() => this.cleanUp());
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns an observable emitting realtime data for the given channel.
|
|
34
|
+
*
|
|
35
|
+
* @returns The observable of the mocked realtime data.
|
|
36
|
+
*/
|
|
37
|
+
getObservableForChannel(): Observable<RealtimeMessage<IManagedObject>> {
|
|
38
|
+
this.realtimeMockedData$ = new Subject<RealtimeMessage<IManagedObject>>();
|
|
39
|
+
this.setInterval(this.realtimeMockedData$);
|
|
40
|
+
return this.realtimeMockedData$;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Sets up an interval for generating and emitting the mocked data.
|
|
44
|
+
*
|
|
45
|
+
* @param realtimeMessageSubject$ - The subject to emit the mocked data.
|
|
46
|
+
*/
|
|
47
|
+
private setInterval(realtimeMessageSubject$: Subject<RealtimeMessage<IManagedObject>>) {
|
|
48
|
+
this.intervalSubscription = interval(5000)
|
|
49
|
+
.pipe(map(() => getFakeData<IManagedObject>(this.REALTIME_CHANNEL)))
|
|
50
|
+
.subscribe(data => {
|
|
51
|
+
if (!realtimeMessageSubject$.isStopped) {
|
|
52
|
+
realtimeMessageSubject$.next(data);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Cleans up by completing and unsubscribing the subject and the interval subscription.
|
|
58
|
+
*/
|
|
59
|
+
private cleanUp() {
|
|
60
|
+
if (this.realtimeMockedData$) {
|
|
61
|
+
this.realtimeMockedData$.complete();
|
|
62
|
+
this.realtimeMockedData$.unsubscribe();
|
|
63
|
+
}
|
|
64
|
+
if (this.intervalSubscription) {
|
|
65
|
+
this.intervalSubscription.unsubscribe();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { OptionsService, RealtimeMessage, RealtimeSubjectService } from '@c8y/ngx-components';
|
|
3
|
+
import { Observable, interval } from 'rxjs';
|
|
4
|
+
import { map } from 'rxjs/operators';
|
|
5
|
+
import { getFakeData } from './utils/realtime';
|
|
6
|
+
import { Realtime } from '@c8y/client';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A mocked implementation of `RealtimeSubjectService` provides observables with emitting fake data every 5 seconds in case the noLogin option is set.
|
|
10
|
+
* In case it is not set, we will use the default functionality of `RealtimeSubjectService`.
|
|
11
|
+
*/
|
|
12
|
+
@Injectable({ providedIn: 'root' })
|
|
13
|
+
export class RealtimeSubjectServiceWithMocking extends RealtimeSubjectService {
|
|
14
|
+
mockingEnabled = false;
|
|
15
|
+
constructor(options: OptionsService, realtime: Realtime) {
|
|
16
|
+
super(realtime);
|
|
17
|
+
this.mockingEnabled = options.get<boolean>('noLogin', false);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getObservableForChannel<T>(channel: string): Observable<RealtimeMessage<T>> {
|
|
21
|
+
if (!this.mockingEnabled) {
|
|
22
|
+
return super.getObservableForChannel(channel);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return this.getMockedData$<T>(channel);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private getMockedData$<T>(channel: string): Observable<RealtimeMessage<T>> {
|
|
29
|
+
return interval(5000).pipe(map(() => getFakeData<T>(channel)));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Inject, Injectable } from '@angular/core';
|
|
2
|
+
import { NavigationEnd, Router } from '@angular/router';
|
|
3
|
+
import { OptionsService } from '@c8y/ngx-components';
|
|
4
|
+
import { ApiService } from '@c8y/ngx-components/api';
|
|
5
|
+
import { filter } from 'rxjs/operators';
|
|
6
|
+
import { API_MOCK_CONFIG, ApiMockConfig } from './mock.model';
|
|
7
|
+
interface DebugData {
|
|
8
|
+
text: string;
|
|
9
|
+
content?: any;
|
|
10
|
+
}
|
|
11
|
+
@Injectable({ providedIn: 'root' })
|
|
12
|
+
export class MockService {
|
|
13
|
+
constructor(
|
|
14
|
+
@Inject(API_MOCK_CONFIG) private apiMocks,
|
|
15
|
+
private apiService: ApiService,
|
|
16
|
+
private router: Router,
|
|
17
|
+
private options: OptionsService
|
|
18
|
+
) {
|
|
19
|
+
if (this.options.get<boolean>('noLogin', false)) {
|
|
20
|
+
this.setupMocks();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Method responsible for setting up API mock behaviors.
|
|
25
|
+
* It adds global interceptors and handles scoped interceptors for the current router URL.
|
|
26
|
+
* If 'noLogin' option is true, it sets up scoped interceptors based on router navigation events and returns.
|
|
27
|
+
* If 'noLogin' option is false, it sets up reactions for changes in the Mock API enabled state and
|
|
28
|
+
* sets up scoped interceptors with filter based on router navigation events.
|
|
29
|
+
*/
|
|
30
|
+
private setupMocks() {
|
|
31
|
+
this.addGlobalInterceptors();
|
|
32
|
+
this.handleScopedInterceptors(this.router.url);
|
|
33
|
+
|
|
34
|
+
this.setupScopedInterceptorsOnNavigationEnd();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Method responsible for handling scoped interceptors based on router navigation events.
|
|
38
|
+
* It listens for NavigationEnd events, and calls handleScopedInterceptors method with current URL.
|
|
39
|
+
*/
|
|
40
|
+
private setupScopedInterceptorsOnNavigationEnd() {
|
|
41
|
+
this.router.events
|
|
42
|
+
.pipe(filter(event => event instanceof NavigationEnd))
|
|
43
|
+
.subscribe((event: NavigationEnd) => {
|
|
44
|
+
this.handleScopedInterceptors(event.url);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Registers global interceptors from the apiMocks configuration.
|
|
49
|
+
*
|
|
50
|
+
* This method filters apiMocks for entries with undefined path, considering them as global.
|
|
51
|
+
* For each such entry, it creates an instance of the corresponding mock service and adds it as an interceptor.
|
|
52
|
+
*
|
|
53
|
+
* Note: The method is private and is likely to be used within the class internally.
|
|
54
|
+
*/
|
|
55
|
+
private addGlobalInterceptors() {
|
|
56
|
+
const mocksToRegister = this.apiMocks.filter((mock: ApiMockConfig) => mock.path === undefined);
|
|
57
|
+
mocksToRegister.forEach((mock: ApiMockConfig) => {
|
|
58
|
+
if (this.apiService.hasInterceptor(mock.id)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.apiService.addInterceptor(new mock.mockService() as any, mock.id);
|
|
62
|
+
this.logDebugInfo({ text: `Added global interceptor with id: ${mock.id}` }, mock.debug);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Handles registration and unregistration of scoped interceptors based on the provided URL.
|
|
67
|
+
*
|
|
68
|
+
* This method filters the apiMocks configuration for entries where the path is defined and included in the URL.
|
|
69
|
+
* It registers these as scoped interceptors. It then filters for entries where the path is defined but not included in the URL,
|
|
70
|
+
* and unregisters these interceptors.
|
|
71
|
+
*
|
|
72
|
+
* @param url The URL used to determine which interceptors to register and unregister.
|
|
73
|
+
*/
|
|
74
|
+
private handleScopedInterceptors(url: string) {
|
|
75
|
+
const mocksToRegister = [];
|
|
76
|
+
const mocksToUnregister = [];
|
|
77
|
+
|
|
78
|
+
this.apiMocks.forEach((mock: ApiMockConfig) => {
|
|
79
|
+
if (!mock.path) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (url.includes(mock.path)) {
|
|
84
|
+
mocksToRegister.push(mock);
|
|
85
|
+
} else {
|
|
86
|
+
mocksToUnregister.push(mock);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
this.applyMockConfig(mocksToRegister, mock => {
|
|
91
|
+
this.logDebugInfo({ text: `Added scoped interceptor with id: ${mock.id}` }, mock.debug);
|
|
92
|
+
this.apiService.addInterceptor(new mock.mockService() as any, mock.id);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
this.applyMockConfig(mocksToUnregister, mock => {
|
|
96
|
+
if (this.apiService.hasInterceptor(mock.id)) {
|
|
97
|
+
this.logDebugInfo({ text: `Removed scoped interceptor with id: ${mock.id}` }, mock.debug);
|
|
98
|
+
this.apiService.removeInterceptor(mock.id);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private applyMockConfig(mockConfigs: ApiMockConfig[], action: (mock: ApiMockConfig) => void) {
|
|
104
|
+
mockConfigs.forEach(mock => action(mock));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private logDebugInfo(data: DebugData, show: boolean) {
|
|
108
|
+
if (show) {
|
|
109
|
+
// eslint-disable-next-line no-console
|
|
110
|
+
data.content ? console.info(data.text, data.content) : console.info(data.text);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|