@sapui5/sap.fe.core 1.99.0 → 1.101.1
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/package.json +6 -4
- package/src/sap/fe/core/.library +2 -3
- package/src/sap/fe/core/AnnotationHelper.js +43 -92
- package/src/sap/fe/core/AnnotationHelper.ts +43 -107
- package/src/sap/fe/core/AppComponent.js +381 -399
- package/src/sap/fe/core/AppComponent.ts +397 -0
- package/src/sap/fe/core/AppStateHandler.js +131 -162
- package/src/sap/fe/core/AppStateHandler.ts +2 -2
- package/src/sap/fe/core/BaseController.js +82 -58
- package/src/sap/fe/core/BaseController.ts +67 -0
- package/src/sap/fe/core/CommonUtils.js +179 -31
- package/src/sap/fe/core/CommonUtils.ts +295 -125
- package/src/sap/fe/core/ExtensionAPI.js +279 -274
- package/src/sap/fe/core/ExtensionAPI.ts +242 -0
- package/src/sap/fe/core/PageController.js +158 -29
- package/src/sap/fe/core/PageController.ts +65 -37
- package/src/sap/fe/core/RouterProxy.js +700 -750
- package/src/sap/fe/core/RouterProxy.ts +47 -31
- package/src/sap/fe/core/Synchronization.js +21 -31
- package/src/sap/fe/core/TemplateComponent.js +193 -118
- package/src/sap/fe/core/TemplateComponent.ts +104 -109
- package/src/sap/fe/core/TemplateModel.js +24 -44
- package/src/sap/fe/core/TemplateModel.ts +3 -3
- package/src/sap/fe/core/TransactionHelper.js +1368 -1369
- package/src/sap/fe/core/TransactionHelper.ts +201 -171
- package/src/sap/fe/core/actions/collaboration/ActivitySync.js +406 -0
- package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +362 -0
- package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +146 -0
- package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +129 -0
- package/src/sap/fe/core/actions/collaboration/Manage.js +264 -0
- package/src/sap/fe/core/actions/collaboration/Manage.ts +246 -0
- package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +100 -0
- package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
- package/src/sap/fe/core/actions/draft.js +324 -220
- package/src/sap/fe/core/actions/draft.ts +209 -133
- package/src/sap/fe/core/actions/messageHandling.js +79 -48
- package/src/sap/fe/core/actions/messageHandling.ts +113 -83
- package/src/sap/fe/core/actions/operations.js +37 -18
- package/src/sap/fe/core/actions/operations.ts +51 -20
- package/src/sap/fe/core/actions/sticky.js +17 -4
- package/src/sap/fe/core/actions/sticky.ts +21 -4
- package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
- package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +707 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +628 -0
- package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
- package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
- package/src/sap/fe/core/controllerextensions/EditFlow.js +1854 -1669
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +1792 -0
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +60 -0
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +716 -779
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +785 -0
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +810 -0
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +1056 -1005
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +1001 -0
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +498 -532
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +13 -12
- package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
- package/src/sap/fe/core/controllerextensions/MassEdit.ts +155 -0
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +221 -244
- package/src/sap/fe/core/controllerextensions/MessageHandler.ts +215 -0
- package/src/sap/fe/core/controllerextensions/PageReady.js +312 -345
- package/src/sap/fe/core/controllerextensions/PageReady.ts +57 -53
- package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
- package/src/sap/fe/core/controllerextensions/Paginator.ts +169 -0
- package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
- package/src/sap/fe/core/controllerextensions/Placeholder.ts +149 -0
- package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
- package/src/sap/fe/core/controllerextensions/Routing.ts +131 -0
- package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
- package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
- package/src/sap/fe/core/controllerextensions/Share.js +230 -268
- package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
- package/src/sap/fe/core/controllerextensions/SideEffects.js +603 -644
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +68 -68
- package/src/sap/fe/core/controllerextensions/ViewState.js +774 -806
- package/src/sap/fe/core/controllerextensions/ViewState.ts +796 -0
- package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
- package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
- package/src/sap/fe/core/controls/Any.js +28 -0
- package/src/sap/fe/core/controls/Any.ts +30 -0
- package/src/sap/fe/core/controls/CommandExecution.js +92 -68
- package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
- package/src/sap/fe/core/controls/ConditionalWrapper.js +165 -79
- package/src/sap/fe/core/controls/ConditionalWrapper.ts +74 -0
- package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +366 -0
- package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +278 -0
- package/src/sap/fe/core/controls/CustomQuickViewPage.js +167 -125
- package/src/sap/fe/core/controls/CustomQuickViewPage.ts +116 -0
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +44 -5
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +163 -122
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +155 -0
- package/src/sap/fe/core/controls/FieldWrapper.js +212 -141
- package/src/sap/fe/core/controls/FieldWrapper.ts +104 -0
- package/src/sap/fe/core/controls/FileWrapper.js +313 -0
- package/src/sap/fe/core/controls/FileWrapper.ts +169 -0
- package/src/sap/fe/core/controls/FilterBar.js +197 -159
- package/src/sap/fe/core/controls/FilterBar.ts +148 -0
- package/src/sap/fe/core/controls/FormElementWrapper.js +100 -39
- package/src/sap/fe/core/controls/FormElementWrapper.ts +37 -0
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
- package/src/sap/fe/core/controls/filterbar/FilterContainer.js +147 -115
- package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +102 -0
- package/src/sap/fe/core/controls/filterbar/VisualFilter.js +300 -265
- package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +252 -0
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +185 -140
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
- package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +37 -42
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +75 -74
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +71 -0
- package/src/sap/fe/core/converters/ConverterContext.js +348 -379
- package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
- package/src/sap/fe/core/converters/ManifestSettings.js +13 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +17 -2
- package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
- package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
- package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
- package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
- package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
- package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
- package/src/sap/fe/core/converters/annotations/DataField.js +26 -13
- package/src/sap/fe/core/converters/annotations/DataField.ts +40 -17
- package/src/sap/fe/core/converters/controls/Common/Action.js +10 -10
- package/src/sap/fe/core/converters/controls/Common/Action.ts +20 -19
- package/src/sap/fe/core/converters/controls/Common/Chart.js +8 -8
- package/src/sap/fe/core/converters/controls/Common/Chart.ts +12 -11
- package/src/sap/fe/core/converters/controls/Common/Form.js +6 -6
- package/src/sap/fe/core/converters/controls/Common/Form.ts +7 -3
- package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -2
- package/src/sap/fe/core/converters/controls/Common/Table.js +326 -86
- package/src/sap/fe/core/converters/controls/Common/Table.ts +384 -167
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +120 -55
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +158 -98
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +206 -223
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +263 -287
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +5 -2
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +4 -1
- package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
- package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
- package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
- package/src/sap/fe/core/converters/helpers/Key.js +42 -57
- package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +51 -27
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +69 -43
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +42 -25
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +91 -65
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +11 -9
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +8 -8
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
- package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
- package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
- package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
- package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
- package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
- package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
- package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
- package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
- package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
- package/src/sap/fe/core/fpm/Component.js +80 -55
- package/src/sap/fe/core/fpm/Component.ts +43 -0
- package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
- package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
- package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
- package/src/sap/fe/core/helpers/ClassSupport.js +307 -166
- package/src/sap/fe/core/helpers/ClassSupport.ts +348 -155
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
- package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
- package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
- package/src/sap/fe/core/helpers/MassEditHelper.js +735 -684
- package/src/sap/fe/core/helpers/MassEditHelper.ts +803 -0
- package/src/sap/fe/core/helpers/ModelHelper.js +53 -1
- package/src/sap/fe/core/helpers/ModelHelper.ts +46 -0
- package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
- package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
- package/src/sap/fe/core/helpers/SemanticDateOperators.js +7 -3
- package/src/sap/fe/core/helpers/SemanticDateOperators.ts +7 -1
- package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
- package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
- package/src/sap/fe/core/helpers/StableIdHelper.js +1 -7
- package/src/sap/fe/core/helpers/StableIdHelper.ts +0 -4
- package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
- package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
- package/src/sap/fe/core/library.js +425 -451
- package/src/sap/fe/core/library.support.js +22 -33
- package/src/sap/fe/core/library.support.ts +23 -0
- package/src/sap/fe/core/library.ts +420 -0
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -4
- package/src/sap/fe/core/messagebundle.properties +45 -13
- package/src/sap/fe/core/messagebundle_ar.properties +29 -7
- package/src/sap/fe/core/messagebundle_bg.properties +29 -7
- package/src/sap/fe/core/messagebundle_ca.properties +29 -7
- package/src/sap/fe/core/messagebundle_cs.properties +29 -7
- package/src/sap/fe/core/messagebundle_cy.properties +29 -7
- package/src/sap/fe/core/messagebundle_da.properties +29 -7
- package/src/sap/fe/core/messagebundle_de.properties +29 -7
- package/src/sap/fe/core/messagebundle_el.properties +29 -7
- package/src/sap/fe/core/messagebundle_en.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_GB.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +29 -7
- package/src/sap/fe/core/messagebundle_es.properties +29 -7
- package/src/sap/fe/core/messagebundle_es_MX.properties +29 -7
- package/src/sap/fe/core/messagebundle_et.properties +29 -7
- package/src/sap/fe/core/messagebundle_fi.properties +30 -8
- package/src/sap/fe/core/messagebundle_fr.properties +31 -9
- package/src/sap/fe/core/messagebundle_fr_CA.properties +31 -9
- package/src/sap/fe/core/messagebundle_hi.properties +29 -7
- package/src/sap/fe/core/messagebundle_hr.properties +29 -7
- package/src/sap/fe/core/messagebundle_hu.properties +29 -7
- package/src/sap/fe/core/messagebundle_id.properties +29 -7
- package/src/sap/fe/core/messagebundle_it.properties +29 -7
- package/src/sap/fe/core/messagebundle_iw.properties +29 -7
- package/src/sap/fe/core/messagebundle_ja.properties +28 -6
- package/src/sap/fe/core/messagebundle_kk.properties +29 -7
- package/src/sap/fe/core/messagebundle_ko.properties +29 -7
- package/src/sap/fe/core/messagebundle_lt.properties +29 -7
- package/src/sap/fe/core/messagebundle_lv.properties +30 -8
- package/src/sap/fe/core/messagebundle_ms.properties +29 -7
- package/src/sap/fe/core/messagebundle_nl.properties +29 -7
- package/src/sap/fe/core/messagebundle_no.properties +29 -7
- package/src/sap/fe/core/messagebundle_pl.properties +29 -7
- package/src/sap/fe/core/messagebundle_pt.properties +30 -8
- package/src/sap/fe/core/messagebundle_pt_PT.properties +29 -7
- package/src/sap/fe/core/messagebundle_ro.properties +29 -7
- package/src/sap/fe/core/messagebundle_ru.properties +29 -7
- package/src/sap/fe/core/messagebundle_sh.properties +29 -7
- package/src/sap/fe/core/messagebundle_sk.properties +29 -7
- package/src/sap/fe/core/messagebundle_sl.properties +29 -7
- package/src/sap/fe/core/messagebundle_sv.properties +30 -8
- package/src/sap/fe/core/messagebundle_th.properties +28 -6
- package/src/sap/fe/core/messagebundle_tr.properties +32 -10
- package/src/sap/fe/core/messagebundle_uk.properties +29 -7
- package/src/sap/fe/core/messagebundle_vi.properties +29 -7
- package/src/sap/fe/core/messagebundle_zh_CN.properties +29 -7
- package/src/sap/fe/core/messagebundle_zh_TW.properties +29 -7
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +47 -73
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +158 -196
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +5 -6
- package/src/sap/fe/core/services/EnvironmentServiceFactory.js +70 -96
- package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +7 -6
- package/src/sap/fe/core/services/NavigationServiceFactory.js +287 -342
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +11 -14
- package/src/sap/fe/core/services/ResourceModelServiceFactory.js +70 -105
- package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +6 -3
- package/src/sap/fe/core/services/RoutingServiceFactory.js +796 -820
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +62 -53
- package/src/sap/fe/core/services/ShellServicesFactory.js +694 -741
- package/src/sap/fe/core/services/ShellServicesFactory.ts +33 -33
- package/src/sap/fe/core/services/SideEffectsServiceFactory.js +570 -595
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +23 -4
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +357 -389
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +25 -29
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +7 -4
- package/src/sap/fe/core/support/CommonHelper.js +1 -1
- package/src/sap/fe/core/support/CommonHelper.ts +1 -4
- package/src/sap/fe/core/support/Diagnostics.js +36 -48
- package/src/sap/fe/core/templating/DataModelPathHelper.js +91 -90
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +126 -123
- package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
- package/src/sap/fe/core/templating/DisplayModeFormatter.ts +26 -5
- package/src/sap/fe/core/templating/FilterHelper.js +25 -32
- package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
- package/src/sap/fe/core/templating/PropertyHelper.js +16 -2
- package/src/sap/fe/core/templating/PropertyHelper.ts +31 -24
- package/src/sap/fe/core/templating/UIFormatters.js +150 -44
- package/src/sap/fe/core/templating/UIFormatters.ts +165 -67
- package/src/sap/fe/core/type/Email.js +26 -8
- package/src/sap/fe/core/type/Email.ts +8 -7
- package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -75
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import Log from "sap/base/Log";
|
|
2
|
+
import UriParameters from "sap/base/util/UriParameters";
|
|
3
|
+
import { Activity, CollaborationUtils, Message, User, UserActivity } from "sap/fe/core/actions/collaboration/CollaborationCommon";
|
|
4
|
+
import MessageBox from "sap/m/MessageBox";
|
|
5
|
+
import Event from "sap/ui/base/Event";
|
|
6
|
+
import Control from "sap/ui/core/Control";
|
|
7
|
+
import View from "sap/ui/core/mvc/View";
|
|
8
|
+
import SapPcpWebSocket from "sap/ui/core/ws/SapPcpWebSocket";
|
|
9
|
+
import Context from "sap/ui/model/odata/v4/Context";
|
|
10
|
+
import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
|
|
11
|
+
|
|
12
|
+
const CONNECTED = "/collaboration/connected";
|
|
13
|
+
const CONNECTION = "/collaboration/connection";
|
|
14
|
+
const MYACTIVITY = "/collaboration/myActivity";
|
|
15
|
+
const ACTIVEUSERS = "/collaboration/activeUsers";
|
|
16
|
+
const ACTIVITIES = "/collaboration/activities";
|
|
17
|
+
|
|
18
|
+
export const isConnected = function (control: Control): boolean {
|
|
19
|
+
return !!control.getModel("internal").getProperty(CONNECTED);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const send = function (control: Control, action: Activity, content: string | string[] | Context | Context[] | undefined) {
|
|
23
|
+
if (isConnected(control)) {
|
|
24
|
+
const contentArray = Array.isArray(content) ? content : [content];
|
|
25
|
+
let clientContent: string = "";
|
|
26
|
+
contentArray.forEach(function (c) {
|
|
27
|
+
if (c) {
|
|
28
|
+
clientContent += clientContent ? "|" : "";
|
|
29
|
+
clientContent += typeof c === "string" ? c : c.getPath();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const internalModel = control.getModel("internal") as any;
|
|
34
|
+
const webSocket = internalModel.getProperty(CONNECTION) as SapPcpWebSocket;
|
|
35
|
+
|
|
36
|
+
if (action === Activity.LiveChange) {
|
|
37
|
+
// To avoid unnecessary traffic we keep track of live changes and send it only once
|
|
38
|
+
const myActivity = internalModel.getProperty(MYACTIVITY);
|
|
39
|
+
if (myActivity === clientContent) {
|
|
40
|
+
return;
|
|
41
|
+
} else {
|
|
42
|
+
internalModel.setProperty(MYACTIVITY, clientContent);
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
// user finished the activity
|
|
46
|
+
internalModel.setProperty(MYACTIVITY, null);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
webSocket.send("", {
|
|
50
|
+
clientAction: action,
|
|
51
|
+
clientContent: clientContent
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (action === Activity.Activate || action === Activity.Discard) {
|
|
55
|
+
disconnect(control);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const getWebSocketBaseURL = function (bindingContext: Context): string {
|
|
61
|
+
return bindingContext.getModel().getMetaModel().getObject("/@com.sap.vocabularies.Common.v1.WebSocketBaseURL");
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const isCollaborationEnabled = function (view: View): boolean {
|
|
65
|
+
const bindingContext = view?.getBindingContext && (view.getBindingContext() as Context);
|
|
66
|
+
return !!(bindingContext && getWebSocketBaseURL(bindingContext));
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const connect = async function (view: View) {
|
|
70
|
+
const internalModel: any = view.getModel("internal");
|
|
71
|
+
const me = CollaborationUtils.getMe(view);
|
|
72
|
+
if (internalModel.getProperty(CONNECTION)) {
|
|
73
|
+
// connection already established
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Retrieving ME from shell service
|
|
78
|
+
if (!me) {
|
|
79
|
+
// no me = no shell = not sure what to do
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const activeUsers: any[] = [me];
|
|
84
|
+
internalModel.setProperty("/collaboration", { activeUsers: activeUsers, activities: {} });
|
|
85
|
+
const bindingContext = view.getBindingContext() as Context;
|
|
86
|
+
const webSocketBaseURL = getWebSocketBaseURL(bindingContext);
|
|
87
|
+
|
|
88
|
+
if (!webSocketBaseURL) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const sDraftUUID = await bindingContext.requestProperty("DraftAdministrativeData/DraftUUID");
|
|
93
|
+
if (!sDraftUUID) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const webSocket = establishWebSocketConnection(webSocketBaseURL, sDraftUUID, view);
|
|
98
|
+
|
|
99
|
+
webSocket.attachMessage(function (event: Event) {
|
|
100
|
+
const message: Message = event.getParameter("pcpFields");
|
|
101
|
+
messageReceive(message, view, webSocket);
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const disconnect = function (control: Control) {
|
|
106
|
+
const internalModel = control.getModel("internal") as any;
|
|
107
|
+
const webSocket = internalModel.getProperty(CONNECTION) as SapPcpWebSocket;
|
|
108
|
+
webSocket.close();
|
|
109
|
+
internalModel.setProperty(CONNECTION, null);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
function establishWebSocketConnection(socketBaseURL: string, draftUUID: string, view: View) {
|
|
113
|
+
const internalModel: any = view.getModel("internal");
|
|
114
|
+
const hostLocation = window.location;
|
|
115
|
+
let socketURI;
|
|
116
|
+
|
|
117
|
+
// Support useBackendUrl for local testing
|
|
118
|
+
const useBackendUrl = UriParameters.fromQuery(window.location.search).get("useBackendUrl");
|
|
119
|
+
if (useBackendUrl) {
|
|
120
|
+
socketURI = useBackendUrl.replace("https", "wss");
|
|
121
|
+
} else {
|
|
122
|
+
socketURI = hostLocation.protocol === "https:" ? "wss:" : "ws:";
|
|
123
|
+
socketURI += "//" + hostLocation.host;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
socketURI += (socketBaseURL.startsWith("/") ? "" : "/") + socketBaseURL + "?draft=" + draftUUID;
|
|
127
|
+
|
|
128
|
+
const useFLPUser = UriParameters.fromQuery(window.location.search).get("useFLPUser");
|
|
129
|
+
if (useFLPUser === "true") {
|
|
130
|
+
const me = CollaborationUtils.getMe(view);
|
|
131
|
+
socketURI += "&userID=" + encodeURI(me.id) + "&userName=" + encodeURI(me.initialName || "");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const webSocket = new SapPcpWebSocket(socketURI, ["v10.pcp.sap.com"]); // TODO: use enum
|
|
135
|
+
internalModel.setProperty(CONNECTION, webSocket);
|
|
136
|
+
|
|
137
|
+
webSocket.attachOpen(function () {
|
|
138
|
+
internalModel.setProperty(CONNECTED, true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
webSocket.attachError(function () {
|
|
142
|
+
Log.error("The connection to the websocket channel " + socketBaseURL + " could not be established");
|
|
143
|
+
internalModel.setProperty(CONNECTED, false);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
webSocket.attachClose(function () {
|
|
147
|
+
internalModel.setProperty(CONNECTED, false);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return webSocket;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function messageReceive(message: Message, view: View, webSocket: any) {
|
|
154
|
+
const internalModel: any = view.getModel("internal");
|
|
155
|
+
let activeUsers: User[] = internalModel.getProperty(ACTIVEUSERS);
|
|
156
|
+
let activities: UserActivity[];
|
|
157
|
+
let activityKey: string;
|
|
158
|
+
const metaPath: string = message.clientContent && (view.getModel().getMetaModel() as ODataMetaModel).getMetaPath(message.clientContent);
|
|
159
|
+
message.userAction = message.userAction || message.clientAction;
|
|
160
|
+
|
|
161
|
+
const sender: User = {
|
|
162
|
+
id: message.userID,
|
|
163
|
+
name: message.userDescription,
|
|
164
|
+
initials: CollaborationUtils.formatInitials(message.userDescription),
|
|
165
|
+
color: CollaborationUtils.getUserColor(message.userID, activeUsers, [])
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
switch (message.userAction) {
|
|
169
|
+
case Activity.Join:
|
|
170
|
+
case Activity.JoinEcho:
|
|
171
|
+
if (activeUsers.findIndex((user) => user.id === sender.id) === -1) {
|
|
172
|
+
activeUsers.push(sender);
|
|
173
|
+
internalModel.setProperty(ACTIVEUSERS, activeUsers);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (message.userAction === Activity.Join) {
|
|
177
|
+
// we echo our existence to the newly entered user and also send the current activity if there is any
|
|
178
|
+
webSocket.send("", {
|
|
179
|
+
clientAction: Activity.JoinEcho,
|
|
180
|
+
clientContent: internalModel.getProperty(MYACTIVITY)
|
|
181
|
+
});
|
|
182
|
+
// TODO: echo current activity
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (message.userAction === Activity.JoinEcho) {
|
|
186
|
+
if (message.clientContent) {
|
|
187
|
+
// another user was already typing therefore I want to see his activity immediately. Calling me again as a live change
|
|
188
|
+
message.userAction = Activity.LiveChange;
|
|
189
|
+
messageReceive(message, view, webSocket);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
break;
|
|
194
|
+
case Activity.Leave:
|
|
195
|
+
// Removing the active user. Not removing "me" if I had the screen open in another session
|
|
196
|
+
activeUsers = activeUsers.filter((user) => user.id !== sender.id || user.me);
|
|
197
|
+
internalModel.setProperty(ACTIVEUSERS, activeUsers);
|
|
198
|
+
const allActivities = internalModel.getProperty(ACTIVITIES) || {};
|
|
199
|
+
const removeUserActivities = function (bag: any) {
|
|
200
|
+
if (Array.isArray(bag)) {
|
|
201
|
+
return bag.filter((activity) => activity.id !== sender.id);
|
|
202
|
+
} else {
|
|
203
|
+
for (const p in bag) {
|
|
204
|
+
bag[p] = removeUserActivities(bag[p]);
|
|
205
|
+
}
|
|
206
|
+
return bag;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
removeUserActivities(allActivities);
|
|
210
|
+
internalModel.setProperty(ACTIVITIES, allActivities);
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
case Activity.Change:
|
|
214
|
+
let currentActivities: any[] = internalModel.getProperty(ACTIVITIES + metaPath) || [];
|
|
215
|
+
activityKey = getActivityKey(message.clientContent);
|
|
216
|
+
currentActivities = currentActivities.filter((activity) => activity.key !== activityKey);
|
|
217
|
+
internalModel.setProperty(ACTIVITIES + metaPath, currentActivities);
|
|
218
|
+
|
|
219
|
+
update(view, message, metaPath, Activity.Change);
|
|
220
|
+
break;
|
|
221
|
+
case Activity.Create:
|
|
222
|
+
// For create we actually just need to refresh the table
|
|
223
|
+
update(view, message, metaPath, Activity.Create);
|
|
224
|
+
break;
|
|
225
|
+
case Activity.Delete:
|
|
226
|
+
// For now also refresh the page but in case of deletion we need to inform the user
|
|
227
|
+
update(view, message, metaPath, Activity.Delete);
|
|
228
|
+
break;
|
|
229
|
+
case Activity.Activate:
|
|
230
|
+
disconnect(view);
|
|
231
|
+
MessageBox.information(CollaborationUtils.getText("C_COLLABORATIONDRAFT_ACTIVATE", sender.name));
|
|
232
|
+
navigate(message.clientContent, view);
|
|
233
|
+
break;
|
|
234
|
+
case Activity.Discard:
|
|
235
|
+
disconnect(view);
|
|
236
|
+
MessageBox.information(CollaborationUtils.getText("C_COLLABORATIONDRAFT_DISCARD", sender.name));
|
|
237
|
+
navigate(message.clientContent, view);
|
|
238
|
+
break;
|
|
239
|
+
/*
|
|
240
|
+
// TODO: Action to be implemented
|
|
241
|
+
case Activity.Action:
|
|
242
|
+
// Just for test reasons show a toast - to be checked with UX
|
|
243
|
+
MessageToast.show("User " + sender.name + " has executed action " + metaPath.split("|")[0]);
|
|
244
|
+
//update(view, message, metaPath, Activity.Delete);
|
|
245
|
+
break;
|
|
246
|
+
*/
|
|
247
|
+
case Activity.LiveChange:
|
|
248
|
+
const activity: UserActivity = sender;
|
|
249
|
+
activity.key = getActivityKey(message.clientContent);
|
|
250
|
+
|
|
251
|
+
// stupid JSON model...
|
|
252
|
+
let initJSONModel: string = "";
|
|
253
|
+
const parts = metaPath.split("/");
|
|
254
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
255
|
+
initJSONModel += "/" + parts[i];
|
|
256
|
+
if (!internalModel.getProperty(ACTIVITIES + initJSONModel)) {
|
|
257
|
+
internalModel.setProperty(ACTIVITIES + initJSONModel, {});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
activities = internalModel.getProperty(ACTIVITIES + metaPath);
|
|
262
|
+
activities = activities ? activities.slice() : [];
|
|
263
|
+
activities.push(activity);
|
|
264
|
+
internalModel.setProperty(ACTIVITIES + metaPath, activities);
|
|
265
|
+
break;
|
|
266
|
+
case Activity.Undo:
|
|
267
|
+
// The user did a change but reverted it, therefore unblock the control
|
|
268
|
+
activities = internalModel.getProperty(ACTIVITIES + metaPath);
|
|
269
|
+
activityKey = getActivityKey(message.clientContent);
|
|
270
|
+
internalModel.setProperty(
|
|
271
|
+
ACTIVITIES + metaPath,
|
|
272
|
+
activities.filter((a) => a.key !== activityKey)
|
|
273
|
+
);
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function update(view: View, message: Message, metaPath: string, action: Activity) {
|
|
279
|
+
const appComponent = CollaborationUtils.getAppComponent(view);
|
|
280
|
+
const metaModel = view.getModel().getMetaModel() as ODataMetaModel;
|
|
281
|
+
const currentPage = getCurrentPage(view);
|
|
282
|
+
const sideEffectsService = (appComponent as any).getSideEffectsService(); // TODO: add to appcomponent
|
|
283
|
+
const currentContext = currentPage.getBindingContext();
|
|
284
|
+
const currentPath = currentContext.getPath();
|
|
285
|
+
const currentMetaPath = metaModel.getMetaPath(currentPath);
|
|
286
|
+
let changedDocument = message.clientContent;
|
|
287
|
+
|
|
288
|
+
if (action === Activity.Delete) {
|
|
289
|
+
// check if user currently displays one deleted object
|
|
290
|
+
const deletedObjects = message.clientContent.split("|");
|
|
291
|
+
if (deletedObjects.findIndex((deletedObject) => currentPath.startsWith(deletedObject)) > -1) {
|
|
292
|
+
// any other user deleted the object I'm currently looking at. Inform the user we will navigate to root now
|
|
293
|
+
MessageBox.information(CollaborationUtils.getText("C_COLLABORATIONDRAFT_DELETE", message.userDescription), {
|
|
294
|
+
onClose: function () {
|
|
295
|
+
// TODO: Navigate to root? To be implemented
|
|
296
|
+
history.back();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
// TODO: For now just take the first object to get the meta path and do a full refresh of the table
|
|
301
|
+
changedDocument = deletedObjects[0];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (changedDocument.startsWith(currentPath)) {
|
|
305
|
+
// Execute SideEffects (TODO for Meet there should be one central method)
|
|
306
|
+
const activityPath = metaPath.replace(currentMetaPath, "").slice(1);
|
|
307
|
+
if (activityPath) {
|
|
308
|
+
// Request also the property itself
|
|
309
|
+
const sideEffects: any[] = [
|
|
310
|
+
{
|
|
311
|
+
$PropertyPath: activityPath
|
|
312
|
+
}
|
|
313
|
+
];
|
|
314
|
+
const entityType = sideEffectsService.getEntityTypeFromContext(currentContext);
|
|
315
|
+
const entityTypeSideEffects = sideEffectsService.getODataEntitySideEffects(entityType);
|
|
316
|
+
// Poor man solution without checking source targets, just for POC, this is throw-way coding only
|
|
317
|
+
const object: any = Object; // just to overcome TS issues, will be anyway replaced
|
|
318
|
+
const relevantSideEffects = object.fromEntries(
|
|
319
|
+
object
|
|
320
|
+
.entries(entityTypeSideEffects)
|
|
321
|
+
.filter((x: any[]) => x[1].SourceProperties?.findIndex((source: any) => source.value === activityPath) > -1)
|
|
322
|
+
);
|
|
323
|
+
for (const p in relevantSideEffects) {
|
|
324
|
+
relevantSideEffects[p].TargetProperties.forEach(function (targetProperty: any) {
|
|
325
|
+
sideEffects.push({
|
|
326
|
+
$PropertyPath: targetProperty
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
sideEffectsService.requestSideEffects(sideEffects, currentContext, "$auto");
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Simulate any change so the edit flow shows the draft indicator and sets the page to dirty
|
|
335
|
+
currentPage.getController().editFlow.updateDocument(currentContext, Promise.resolve());
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function navigate(path: string, view: View) {
|
|
339
|
+
// TODO: routing.navigate doesn't consider semantic bookmarking
|
|
340
|
+
const currentPage = getCurrentPage(view);
|
|
341
|
+
const targetContext = view.getModel().bindContext(path).getBoundContext();
|
|
342
|
+
currentPage.getController().routing.navigate(targetContext);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function getCurrentPage(view: View) {
|
|
346
|
+
const appComponent = CollaborationUtils.getAppComponent(view);
|
|
347
|
+
// TODO: isn't there an easier way to get the current page?
|
|
348
|
+
// TODO: What about FCL?
|
|
349
|
+
return (appComponent.getRootControl() as any).getContent()[0].getCurrentPage().getComponentInstance().getRootControl();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function getActivityKey(x: string): string {
|
|
353
|
+
return x.substring(x.lastIndexOf("(") + 1, x.lastIndexOf(")"));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export default {
|
|
357
|
+
connect: connect,
|
|
358
|
+
disconnect: disconnect,
|
|
359
|
+
isConnected: isConnected,
|
|
360
|
+
isCollaborationEnabled: isCollaborationEnabled,
|
|
361
|
+
send: send
|
|
362
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
+
* (c) Copyright 2009-2021 SAP SE. All rights reserved
|
|
4
|
+
*/
|
|
5
|
+
sap.ui.define(["sap/ui/core/Component", "sap/ui/core/Core"], function (Component, Core) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
var _exports = {};
|
|
9
|
+
|
|
10
|
+
var Role;
|
|
11
|
+
|
|
12
|
+
(function (Role) {
|
|
13
|
+
Role["Owner"] = "O";
|
|
14
|
+
Role["Edit"] = "E";
|
|
15
|
+
})(Role || (Role = {}));
|
|
16
|
+
|
|
17
|
+
_exports.Role = Role;
|
|
18
|
+
var Activity;
|
|
19
|
+
|
|
20
|
+
(function (Activity) {
|
|
21
|
+
Activity["Join"] = "JOIN";
|
|
22
|
+
Activity["JoinEcho"] = "JOINECHO";
|
|
23
|
+
Activity["Leave"] = "LEAVE";
|
|
24
|
+
Activity["Change"] = "CHANGE";
|
|
25
|
+
Activity["Create"] = "CREATE";
|
|
26
|
+
Activity["Delete"] = "DELETE";
|
|
27
|
+
Activity["Action"] = "ACTION";
|
|
28
|
+
Activity["LiveChange"] = "LIVECHANGE";
|
|
29
|
+
Activity["Activate"] = "ACTIVATE";
|
|
30
|
+
Activity["Discard"] = "DISCARD";
|
|
31
|
+
Activity["Undo"] = "UNDO";
|
|
32
|
+
})(Activity || (Activity = {}));
|
|
33
|
+
|
|
34
|
+
_exports.Activity = Activity;
|
|
35
|
+
|
|
36
|
+
function formatInitials(fullName) {
|
|
37
|
+
// remove titles - those are the ones from S/4 to be checked if there are others
|
|
38
|
+
var academicTitles = ["Dr.", "Prof.", "Prof. Dr.", "B.A.", "MBA", "Ph.D."];
|
|
39
|
+
academicTitles.forEach(function (academicTitle) {
|
|
40
|
+
fullName = fullName.replace(academicTitle, "");
|
|
41
|
+
});
|
|
42
|
+
var initials;
|
|
43
|
+
var parts = fullName.trimStart().split(" ");
|
|
44
|
+
|
|
45
|
+
if (parts.length > 1) {
|
|
46
|
+
var _parts$shift, _parts$pop;
|
|
47
|
+
|
|
48
|
+
initials = ((parts === null || parts === void 0 ? void 0 : (_parts$shift = parts.shift()) === null || _parts$shift === void 0 ? void 0 : _parts$shift.charAt(0)) || "") + ((_parts$pop = parts.pop()) === null || _parts$pop === void 0 ? void 0 : _parts$pop.charAt(0));
|
|
49
|
+
} else {
|
|
50
|
+
initials = fullName.substring(0, 2);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return initials.toUpperCase();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getUserColor(UserID, activeUsers, invitedUsers) {
|
|
57
|
+
// search if user is known
|
|
58
|
+
var user = activeUsers.find(function (u) {
|
|
59
|
+
return u.id === UserID;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (user) {
|
|
63
|
+
return user.color;
|
|
64
|
+
} else {
|
|
65
|
+
var _loop = function (i) {
|
|
66
|
+
if (activeUsers.findIndex(function (u) {
|
|
67
|
+
return u.color === i;
|
|
68
|
+
}) === -1 && invitedUsers.findIndex(function (u) {
|
|
69
|
+
return u.color === i;
|
|
70
|
+
}) === -1) {
|
|
71
|
+
return {
|
|
72
|
+
v: i
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// search for next free color
|
|
78
|
+
for (var i = 1; i <= 10; i++) {
|
|
79
|
+
var _ret = _loop(i);
|
|
80
|
+
|
|
81
|
+
if (typeof _ret === "object") return _ret.v;
|
|
82
|
+
} // this seems to be a popular object :) for now just return 10 for all.
|
|
83
|
+
// for invited we should start from 1 again so the colors are different
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
return 10;
|
|
87
|
+
}
|
|
88
|
+
} // copied from CommonUtils. Due to a cycle dependency I can't use CommonUtils here.
|
|
89
|
+
// That's to be fixed. the discard popover thingy shouldn't be in the common utils at all
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
function getAppComponent(oControl) {
|
|
93
|
+
if (oControl.isA("sap.fe.core.AppComponent")) {
|
|
94
|
+
return oControl;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var oOwner = Component.getOwnerComponentFor(oControl);
|
|
98
|
+
|
|
99
|
+
if (!oOwner) {
|
|
100
|
+
return oControl;
|
|
101
|
+
} else {
|
|
102
|
+
return getAppComponent(oOwner);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getMe(view) {
|
|
107
|
+
var shellServiceHelper = getAppComponent(view).getShellServices();
|
|
108
|
+
|
|
109
|
+
if (!shellServiceHelper || !shellServiceHelper.hasUShell()) {
|
|
110
|
+
throw "No Shell... No User";
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
var me = {
|
|
114
|
+
initials: shellServiceHelper.getUser().getInitials(),
|
|
115
|
+
id: shellServiceHelper.getUser().getId(),
|
|
116
|
+
name: shellServiceHelper.getUser().getFullName() + " (" + getText("C_COLLABORATIONDRAFT_YOU") + ")",
|
|
117
|
+
initialName: shellServiceHelper.getUser().getFullName(),
|
|
118
|
+
color: 6,
|
|
119
|
+
// same color as FLP...
|
|
120
|
+
role: Role.Owner,
|
|
121
|
+
me: true
|
|
122
|
+
};
|
|
123
|
+
return me;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getText(textId) {
|
|
127
|
+
var oResourceModel = Core.getLibraryResourceBundle("sap.fe.core");
|
|
128
|
+
|
|
129
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
130
|
+
args[_key - 1] = arguments[_key];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return oResourceModel.getText(textId, args);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var CollaborationUtils = {
|
|
137
|
+
formatInitials: formatInitials,
|
|
138
|
+
getUserColor: getUserColor,
|
|
139
|
+
getMe: getMe,
|
|
140
|
+
getAppComponent: getAppComponent,
|
|
141
|
+
getText: getText
|
|
142
|
+
};
|
|
143
|
+
_exports.CollaborationUtils = CollaborationUtils;
|
|
144
|
+
return _exports;
|
|
145
|
+
}, false);
|
|
146
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbGxhYm9yYXRpb25Db21tb24udHMiXSwibmFtZXMiOlsiUm9sZSIsIkFjdGl2aXR5IiwiZm9ybWF0SW5pdGlhbHMiLCJmdWxsTmFtZSIsImFjYWRlbWljVGl0bGVzIiwiZm9yRWFjaCIsImFjYWRlbWljVGl0bGUiLCJyZXBsYWNlIiwiaW5pdGlhbHMiLCJwYXJ0cyIsInRyaW1TdGFydCIsInNwbGl0IiwibGVuZ3RoIiwic2hpZnQiLCJjaGFyQXQiLCJwb3AiLCJzdWJzdHJpbmciLCJ0b1VwcGVyQ2FzZSIsImdldFVzZXJDb2xvciIsIlVzZXJJRCIsImFjdGl2ZVVzZXJzIiwiaW52aXRlZFVzZXJzIiwidXNlciIsImZpbmQiLCJ1IiwiaWQiLCJjb2xvciIsImkiLCJmaW5kSW5kZXgiLCJnZXRBcHBDb21wb25lbnQiLCJvQ29udHJvbCIsImlzQSIsIm9Pd25lciIsIkNvbXBvbmVudCIsImdldE93bmVyQ29tcG9uZW50Rm9yIiwiZ2V0TWUiLCJ2aWV3Iiwic2hlbGxTZXJ2aWNlSGVscGVyIiwiZ2V0U2hlbGxTZXJ2aWNlcyIsImhhc1VTaGVsbCIsIm1lIiwiZ2V0VXNlciIsImdldEluaXRpYWxzIiwiZ2V0SWQiLCJuYW1lIiwiZ2V0RnVsbE5hbWUiLCJnZXRUZXh0IiwiaW5pdGlhbE5hbWUiLCJyb2xlIiwiT3duZXIiLCJ0ZXh0SWQiLCJvUmVzb3VyY2VNb2RlbCIsIkNvcmUiLCJnZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUiLCJhcmdzIiwiQ29sbGFib3JhdGlvblV0aWxzIl0sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBOzs7Ozs7TUFtQllBLEk7O2FBQUFBLEk7QUFBQUEsSUFBQUEsSTtBQUFBQSxJQUFBQSxJO0tBQUFBLEksS0FBQUEsSTs7O01BS0FDLFE7O2FBQUFBLFE7QUFBQUEsSUFBQUEsUTtBQUFBQSxJQUFBQSxRO0FBQUFBLElBQUFBLFE7QUFBQUEsSUFBQUEsUTtBQUFBQSxJQUFBQSxRO0FBQUFBLElBQUFBLFE7QUFBQUEsSUFBQUEsUTtB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LEtBSDBCO0FBSWpDTixJQUFBQSxlQUFlLEVBQUVBLGVBSmdCO0FBS2pDaUIsSUFBQUEsT0FBTyxFQUFFQTtBQUx3QixHQUEzQiIsInNvdXJjZVJvb3QiOiIuIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFZpZXcgZnJvbSBcInNhcC91aS9jb3JlL212Yy9WaWV3XCI7XG5pbXBvcnQgQ29tcG9uZW50IGZyb20gXCJzYXAvdWkvY29yZS9Db21wb25lbnRcIjtcbmltcG9ydCBBcHBDb21wb25lbnQgZnJvbSBcInNhcC9mZS9jb3JlL0FwcENvbXBvbmVudFwiO1xuaW1wb3J0IHsgQ29yZUV4IH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3R5cGVzL2V4dGVuc2lvbl90eXBlc1wiO1xuaW1wb3J0IENvcmUgZnJvbSBcInNhcC91aS9jb3JlL0NvcmVcIjtcblxuZXhwb3J0IHR5cGUgVXNlciA9IHtcblx0aWQ6IHN0cmluZztcblx0aW5pdGlhbHM/OiBzdHJpbmc7XG5cdG5hbWU6IHN0cmluZztcblx0cm9sZT86IFJvbGU7XG5cdGNvbG9yPzogbnVtYmVyO1xuXHR0cmFuc2llbnQ/OiBib29sZWFuO1xuXHRtZT86IGJvb2xlYW47XG5cdGluaXRpYWxOYW1lPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgVXNlckFjdGl2aXR5ID0gVXNlciAmIHtcblx0a2V5Pzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGVudW0gUm9sZSB7XG5cdE93bmVyID0gXCJPXCIsXG5cdEVkaXQgPSBcIkVcIlxufVxuXG5leHBvcnQgZW51bSBBY3Rpdml0eSB7XG5cdEpvaW4gPSBcIkpPSU5cIixcblx0Sm9pbkVjaG8gPSBcIkpPSU5FQ0hPXCIsXG5cdExlYXZlID0gXCJMRUFWRVwiLFxuXHRDaGFuZ2UgPSBcIkNIQU5HRVwiLFxuXHRDcmVhdGUgPSBcIkNSRUFURVwiLFxuXHREZWxldGUgPSBcIkRFTEVURVwiLFxuXHRBY3Rpb24gPSBcIkFDVElPTlwiLFxuXHRMaXZlQ2hhbmdlID0gXCJMSVZFQ0hBTkdFXCIsXG5cdEFjdGl2YXRlID0gXCJBQ1RJVkFURVwiLFxuXHREaXNjYXJkID0gXCJESVNDQVJEXCIsXG5cdFVuZG8gPSBcIlVORE9cIlxufVxuXG5leHBvcnQgdHlwZSBNZXNzYWdlID0ge1xuXHR1c2VyRGVzY3JpcHRpb246IHN0cmluZztcblx0dXNlcklEOiBzdHJpbmc7XG5cdHVzZXJBY3Rpb246IHN0cmluZztcblx0Y2xpZW50QWN0aW9uOiBzdHJpbmc7XG5cdGNsaWVudENvbnRlbnQ6IHN0cmluZztcbn07XG5cbmZ1bmN0aW9uIGZvcm1hdEluaXRpYWxzKGZ1bGxOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuXHQvLyByZW1vdmUgdGl0bGVzIC0gdGhvc2UgYXJlIHRoZSBvbmVzIGZyb20gUy80IHRvIGJlIGNoZWNrZWQgaWYgdGhlcmUgYXJlIG90aGVyc1xuXHRjb25zdCBhY2FkZW1pY1RpdGxlcyA9IFtcIkRyLlwiLCBcIlByb2YuXCIsIFwiUHJvZi4gRHIuXCIsIFwiQi5BLlwiLCBcIk1CQVwiLCBcIlBoLkQuXCJdO1xuXHRhY2FkZW1pY1RpdGxlcy5mb3JFYWNoKGZ1bmN0aW9uKGFjYWRlbWljVGl0bGUpIHtcblx0XHRmdWxsTmFtZSA9IGZ1bGxOYW1lLnJlcGxhY2UoYWNhZGVtaWNUaXRsZSwgXCJcIik7XG5cdH0pO1xuXG5cdGxldCBpbml0aWFsczogc3RyaW5nO1xuXHRjb25zdCBwYXJ0cyA9IGZ1bGxOYW1lLnRyaW1TdGFydCgpLnNwbGl0KFwiIFwiKTtcblxuXHRpZiAocGFydHMubGVuZ3RoID4gMSkge1xuXHRcdGluaXRpYWxzID0gKHBhcnRzPy5zaGlmdCgpPy5jaGFyQXQoMCkgfHwgXCJcIikgKyBwYXJ0cy5wb3AoKT8uY2hhckF0KDApO1xuXHR9IGVsc2Uge1xuXHRcdGluaXRpYWxzID0gZnVsbE5hbWUuc3Vic3RyaW5nKDAsIDIpO1xuXHR9XG5cblx0cmV0dXJuIGluaXRpYWxzLnRvVXBwZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIGdldFVzZXJDb2xvcihVc2VySUQ6IHN0cmluZywgYWN0aXZlVXNlcnM6IFVzZXJbXSwgaW52aXRlZFVzZXJzOiBVc2VyW10pIHtcblx0Ly8gc2VhcmNoIGlmIHVzZXIgaXMga25vd25cblx0Y29uc3QgdXNlciA9IGFjdGl2ZVVzZXJzLmZpbmQodSA9PiB1LmlkID09PSBVc2VySUQpO1xuXHRpZiAodXNlcikge1xuXHRcdHJldHVybiB1c2VyLmNvbG9yO1xuXHR9IGVsc2Uge1xuXHRcdC8vIHNlYXJjaCBmb3IgbmV4dCBmcmVlIGNvbG9yXG5cdFx0Zm9yIChsZXQgaSA9IDE7IGkgPD0gMTA7IGkrKykge1xuXHRcdFx0aWYgKGFjdGl2ZVVzZXJzLmZpbmRJbmRleCh1ID0+IHUuY29sb3IgPT09IGkpID09PSAtMSAmJiBpbnZpdGVkVXNlcnMuZmluZEluZGV4KHUgPT4gdS5jb2xvciA9PT0gaSkgPT09IC0xKSB7XG5cdFx0XHRcdHJldHVybiBpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHQvLyB0aGlzIHNlZW1zIHRvIGJlIGEgcG9wdWxhciBvYmplY3QgOikgZm9yIG5vdyBqdXN0IHJldHVybiAxMCBmb3IgYWxsLlxuXHRcdC8vIGZvciBpbnZpdGVkIHdlIHNob3VsZCBzdGFydCBmcm9tIDEgYWdhaW4gc28gdGhlIGNvbG9ycyBhcmUgZGlmZmVyZW50XG5cdFx0cmV0dXJuIDEwO1xuXHR9XG59XG5cbi8vIGNvcGllZCBmcm9tIENvbW1vblV0aWxzLiBEdWUgdG8gYSBjeWNsZSBkZXBlbmRlbmN5IEkgY2FuJ3QgdXNlIENvbW1vblV0aWxzIGhlcmUuXG4vLyBUaGF0J3MgdG8gYmUgZml4ZWQuIHRoZSBkaXNjYXJkIHBvcG92ZXIgdGhpbmd5IHNob3VsZG4ndCBiZSBpbiB0aGUgY29tbW9uIHV0aWxzIGF0IGFsbFxuZnVuY3Rpb24gZ2V0QXBwQ29tcG9uZW50KG9Db250cm9sOiBhbnkpOiBBcHBDb21wb25lbnQge1xuXHRpZiAob0NvbnRyb2wuaXNBKFwic2FwLmZlLmNvcmUuQXBwQ29tcG9uZW50XCIpKSB7XG5cdFx0cmV0dXJuIG9Db250cm9sO1xuXHR9XG5cdGNvbnN0IG9Pd25lciA9IENvbXBvbmVudC5nZXRPd25lckNvbXBvbmVudEZvcihvQ29udHJvbCk7XG5cdGlmICghb093bmVyKSB7XG5cdFx0cmV0dXJuIG9Db250cm9sO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBnZXRBcHBDb21wb25lbnQob093bmVyKTtcblx0fVxufVxuXG5mdW5jdGlvbiBnZXRNZSh2aWV3OiBWaWV3KTogVXNlciB7XG5cdGNvbnN0IHNoZWxsU2VydmljZUhlbHBlciA9IGdldEFwcENvbXBvbmVudCh2aWV3KS5nZXRTaGVsbFNlcnZpY2VzKCk7XG5cdGlmICghc2hlbGxTZXJ2aWNlSGVscGVyIHx8ICFzaGVsbFNlcnZpY2VIZWxwZXIuaGFzVVNoZWxsKCkpIHtcblx0XHR0aHJvdyBcIk5vIFNoZWxsLi4uIE5vIFVzZXJcIjtcblx0fVxuXHRjb25zdCBtZTogVXNlciA9IHtcblx0XHRpbml0aWFsczogc2hlbGxTZXJ2aWNlSGVscGVyLmdldFVzZXIoKS5nZXRJbml0aWFscygpLFxuXHRcdGlkOiBzaGVsbFNlcnZpY2VIZWxwZXIuZ2V0VXNlcigpLmdldElkKCksXG5cdFx0bmFtZTogc2hlbGxTZXJ2aWNlSGVscGVyLmdldFVzZXIoKS5nZXRGdWxsTmFtZSgpICsgXCIgKFwiICsgZ2V0VGV4dChcIkNfQ09MTEFCT1JBVElPTkRSQUZUX1lPVVwiKSArIFwiKVwiLFxuXHRcdGluaXRpYWxOYW1lOiBzaGVsbFNlcnZpY2VIZWxwZXIuZ2V0VXNlcigpLmdldEZ1bGxOYW1lKCksXG5cdFx0Y29sb3I6IDYsIC8vICBzYW1lIGNvbG9yIGFzIEZMUC4uLlxuXHRcdHJvbGU6IFJvbGUuT3duZXIsXG5cdFx0bWU6IHRydWVcblx0fTtcblxuXHRyZXR1cm4gbWU7XG59XG5cbmZ1bmN0aW9uIGdldFRleHQodGV4dElkOiBzdHJpbmcsIC4uLmFyZ3M6IHN0cmluZ1tdKTogc3RyaW5nIHtcblx0Y29uc3Qgb1Jlc291cmNlTW9kZWwgPSAoQ29yZSBhcyBDb3JlRXgpLmdldExpYnJhcnlSZXNvdXJjZUJ1bmRsZShcInNhcC5mZS5jb3JlXCIpO1xuXHRyZXR1cm4gb1Jlc291cmNlTW9kZWwuZ2V0VGV4dCh0ZXh0SWQsIGFyZ3MpO1xufVxuXG5leHBvcnQgY29uc3QgQ29sbGFib3JhdGlvblV0aWxzID0ge1xuXHRmb3JtYXRJbml0aWFsczogZm9ybWF0SW5pdGlhbHMsXG5cdGdldFVzZXJDb2xvcjogZ2V0VXNlckNvbG9yLFxuXHRnZXRNZTogZ2V0TWUsXG5cdGdldEFwcENvbXBvbmVudDogZ2V0QXBwQ29tcG9uZW50LFxuXHRnZXRUZXh0OiBnZXRUZXh0XG59O1xuIl19
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import View from "sap/ui/core/mvc/View";
|
|
2
|
+
import Component from "sap/ui/core/Component";
|
|
3
|
+
import AppComponent from "sap/fe/core/AppComponent";
|
|
4
|
+
import { CoreEx } from "../../../../../../../../types/extension_types";
|
|
5
|
+
import Core from "sap/ui/core/Core";
|
|
6
|
+
|
|
7
|
+
export type User = {
|
|
8
|
+
id: string;
|
|
9
|
+
initials?: string;
|
|
10
|
+
name: string;
|
|
11
|
+
role?: Role;
|
|
12
|
+
color?: number;
|
|
13
|
+
transient?: boolean;
|
|
14
|
+
me?: boolean;
|
|
15
|
+
initialName?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type UserActivity = User & {
|
|
19
|
+
key?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export enum Role {
|
|
23
|
+
Owner = "O",
|
|
24
|
+
Edit = "E"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export enum Activity {
|
|
28
|
+
Join = "JOIN",
|
|
29
|
+
JoinEcho = "JOINECHO",
|
|
30
|
+
Leave = "LEAVE",
|
|
31
|
+
Change = "CHANGE",
|
|
32
|
+
Create = "CREATE",
|
|
33
|
+
Delete = "DELETE",
|
|
34
|
+
Action = "ACTION",
|
|
35
|
+
LiveChange = "LIVECHANGE",
|
|
36
|
+
Activate = "ACTIVATE",
|
|
37
|
+
Discard = "DISCARD",
|
|
38
|
+
Undo = "UNDO"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type Message = {
|
|
42
|
+
userDescription: string;
|
|
43
|
+
userID: string;
|
|
44
|
+
userAction: string;
|
|
45
|
+
clientAction: string;
|
|
46
|
+
clientContent: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function formatInitials(fullName: string): string {
|
|
50
|
+
// remove titles - those are the ones from S/4 to be checked if there are others
|
|
51
|
+
const academicTitles = ["Dr.", "Prof.", "Prof. Dr.", "B.A.", "MBA", "Ph.D."];
|
|
52
|
+
academicTitles.forEach(function(academicTitle) {
|
|
53
|
+
fullName = fullName.replace(academicTitle, "");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
let initials: string;
|
|
57
|
+
const parts = fullName.trimStart().split(" ");
|
|
58
|
+
|
|
59
|
+
if (parts.length > 1) {
|
|
60
|
+
initials = (parts?.shift()?.charAt(0) || "") + parts.pop()?.charAt(0);
|
|
61
|
+
} else {
|
|
62
|
+
initials = fullName.substring(0, 2);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return initials.toUpperCase();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getUserColor(UserID: string, activeUsers: User[], invitedUsers: User[]) {
|
|
69
|
+
// search if user is known
|
|
70
|
+
const user = activeUsers.find(u => u.id === UserID);
|
|
71
|
+
if (user) {
|
|
72
|
+
return user.color;
|
|
73
|
+
} else {
|
|
74
|
+
// search for next free color
|
|
75
|
+
for (let i = 1; i <= 10; i++) {
|
|
76
|
+
if (activeUsers.findIndex(u => u.color === i) === -1 && invitedUsers.findIndex(u => u.color === i) === -1) {
|
|
77
|
+
return i;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// this seems to be a popular object :) for now just return 10 for all.
|
|
81
|
+
// for invited we should start from 1 again so the colors are different
|
|
82
|
+
return 10;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// copied from CommonUtils. Due to a cycle dependency I can't use CommonUtils here.
|
|
87
|
+
// That's to be fixed. the discard popover thingy shouldn't be in the common utils at all
|
|
88
|
+
function getAppComponent(oControl: any): AppComponent {
|
|
89
|
+
if (oControl.isA("sap.fe.core.AppComponent")) {
|
|
90
|
+
return oControl;
|
|
91
|
+
}
|
|
92
|
+
const oOwner = Component.getOwnerComponentFor(oControl);
|
|
93
|
+
if (!oOwner) {
|
|
94
|
+
return oControl;
|
|
95
|
+
} else {
|
|
96
|
+
return getAppComponent(oOwner);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getMe(view: View): User {
|
|
101
|
+
const shellServiceHelper = getAppComponent(view).getShellServices();
|
|
102
|
+
if (!shellServiceHelper || !shellServiceHelper.hasUShell()) {
|
|
103
|
+
throw "No Shell... No User";
|
|
104
|
+
}
|
|
105
|
+
const me: User = {
|
|
106
|
+
initials: shellServiceHelper.getUser().getInitials(),
|
|
107
|
+
id: shellServiceHelper.getUser().getId(),
|
|
108
|
+
name: shellServiceHelper.getUser().getFullName() + " (" + getText("C_COLLABORATIONDRAFT_YOU") + ")",
|
|
109
|
+
initialName: shellServiceHelper.getUser().getFullName(),
|
|
110
|
+
color: 6, // same color as FLP...
|
|
111
|
+
role: Role.Owner,
|
|
112
|
+
me: true
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return me;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function getText(textId: string, ...args: string[]): string {
|
|
119
|
+
const oResourceModel = (Core as CoreEx).getLibraryResourceBundle("sap.fe.core");
|
|
120
|
+
return oResourceModel.getText(textId, args);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const CollaborationUtils = {
|
|
124
|
+
formatInitials: formatInitials,
|
|
125
|
+
getUserColor: getUserColor,
|
|
126
|
+
getMe: getMe,
|
|
127
|
+
getAppComponent: getAppComponent,
|
|
128
|
+
getText: getText
|
|
129
|
+
};
|