@sapui5/sap.fe.macros 1.139.0 → 1.141.0
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 +1 -1
- package/src/sap/fe/macros/.library +1 -1
- package/src/sap/fe/macros/Chart.js +53 -2
- package/src/sap/fe/macros/Chart.tsx +55 -0
- package/src/sap/fe/macros/CollaborativeDraftHandler.js +230 -0
- package/src/sap/fe/macros/CollaborativeDraftHandler.tsx +218 -0
- package/src/sap/fe/macros/CommonHelper.js +59 -15
- package/src/sap/fe/macros/CommonHelper.ts +65 -14
- package/src/sap/fe/macros/ConditionalSwitch.js +174 -0
- package/src/sap/fe/macros/ConditionalSwitch.tsx +141 -0
- package/src/sap/fe/macros/ConditionalSwitchProperty.js +78 -0
- package/src/sap/fe/macros/ConditionalSwitchProperty.tsx +62 -0
- package/src/sap/fe/macros/Field.js +78 -64
- package/src/sap/fe/macros/Field.ts +97 -68
- package/src/sap/fe/macros/FooterContent.js +5 -2
- package/src/sap/fe/macros/FooterContent.tsx +4 -1
- package/src/sap/fe/macros/MacroAPI.js +9 -4
- package/src/sap/fe/macros/MacroAPI.ts +9 -4
- package/src/sap/fe/macros/MessageButton.js +1 -2
- package/src/sap/fe/macros/MessageButton.tsx +0 -1
- package/src/sap/fe/macros/MultiValueField.js +10 -7
- package/src/sap/fe/macros/MultiValueField.tsx +7 -3
- package/src/sap/fe/macros/Page.js +5 -7
- package/src/sap/fe/macros/Page.tsx +4 -6
- package/src/sap/fe/macros/Paginator.js +9 -4
- package/src/sap/fe/macros/Paginator.tsx +12 -3
- package/src/sap/fe/macros/RichTextEditor.js +3 -2
- package/src/sap/fe/macros/RichTextEditor.tsx +2 -1
- package/src/sap/fe/macros/Share.js +14 -2
- package/src/sap/fe/macros/Share.tsx +13 -0
- package/src/sap/fe/macros/Status.js +251 -0
- package/src/sap/fe/macros/Status.tsx +212 -0
- package/src/sap/fe/macros/ValueHelp.js +4 -28
- package/src/sap/fe/macros/ValueHelp.tsx +2 -42
- package/src/sap/fe/macros/ai/EasyFillDialog.js +11 -17
- package/src/sap/fe/macros/ai/EasyFillDialog.tsx +11 -16
- package/src/sap/fe/macros/ai/EasyFilterBar.js +246 -97
- package/src/sap/fe/macros/ai/EasyFilterBar.tsx +302 -106
- package/src/sap/fe/macros/ai/EasyFilterDataFetcher.js +76 -33
- package/src/sap/fe/macros/ai/EasyFilterDataFetcher.ts +89 -40
- package/src/sap/fe/macros/ai/SummarizationButton.js +2 -2
- package/src/sap/fe/macros/ai/SummarizationButton.tsx +1 -1
- package/src/sap/fe/macros/chart/Chart.js +2 -2
- package/src/sap/fe/macros/chart/Chart.tsx +1 -1
- package/src/sap/fe/macros/chart/ChartHelper.js +1 -2
- package/src/sap/fe/macros/chart/ChartHelper.ts +0 -1
- package/src/sap/fe/macros/chart/ChartRuntime.js +1 -2
- package/src/sap/fe/macros/chart/ChartRuntime.ts +0 -1
- package/src/sap/fe/macros/chart/MdcChartTemplate.js +5 -5
- package/src/sap/fe/macros/chart/MdcChartTemplate.tsx +5 -5
- package/src/sap/fe/macros/contentSwitcher/ContentSwitcher.js +9 -2
- package/src/sap/fe/macros/contentSwitcher/ContentSwitcher.tsx +8 -0
- package/src/sap/fe/macros/controls/BuildingBlockObjectProperty.js +5 -1
- package/src/sap/fe/macros/controls/BuildingBlockObjectProperty.ts +4 -0
- package/src/sap/fe/macros/controls/BuildingBlockWithTemplating.js +4 -2
- package/src/sap/fe/macros/controls/BuildingBlockWithTemplating.ts +3 -1
- package/src/sap/fe/macros/controls/FilterBar.js +14 -5
- package/src/sap/fe/macros/controls/FilterBar.ts +3 -0
- package/src/sap/fe/macros/controls/NumberWithUnitOrCurrency.js +2 -2
- package/src/sap/fe/macros/controls/NumberWithUnitOrCurrency.tsx +2 -2
- package/src/sap/fe/macros/controls/RadioButtons.js +61 -38
- package/src/sap/fe/macros/controls/RadioButtons.tsx +39 -18
- package/src/sap/fe/macros/controls/Section.js +4 -3
- package/src/sap/fe/macros/controls/Section.ts +3 -2
- package/src/sap/fe/macros/controls/section/SubSection.js +63 -8
- package/src/sap/fe/macros/controls/section/SubSection.ts +67 -1
- package/src/sap/fe/macros/coreUI/OperationParameterDialog.js +43 -4
- package/src/sap/fe/macros/coreUI/OperationParameterDialog.tsx +48 -1
- package/src/sap/fe/macros/designtime/Designtime.helper.js +28 -1
- package/src/sap/fe/macros/designtime/Designtime.helper.ts +27 -0
- package/src/sap/fe/macros/field/Field.js +2 -2
- package/src/sap/fe/macros/field/Field.tsx +1 -1
- package/src/sap/fe/macros/field/FieldBaseDelegate.js +13 -7
- package/src/sap/fe/macros/field/FieldBaseDelegate.ts +12 -8
- package/src/sap/fe/macros/field/FieldFormatOptions.js +25 -2
- package/src/sap/fe/macros/field/FieldFormatOptions.ts +13 -0
- package/src/sap/fe/macros/field/FieldHelper.js +2 -2
- package/src/sap/fe/macros/field/FieldHelper.ts +1 -4
- package/src/sap/fe/macros/field/FieldRuntime.js +1 -2
- package/src/sap/fe/macros/field/FieldRuntime.ts +0 -1
- package/src/sap/fe/macros/field/FieldTemplating.js +3 -3
- package/src/sap/fe/macros/field/FieldTemplating.ts +4 -2
- package/src/sap/fe/macros/filter/FilterUtils.js +233 -5
- package/src/sap/fe/macros/filter/FilterUtils.ts +291 -7
- package/src/sap/fe/macros/filterBar/FilterBar.block.js +5 -3
- package/src/sap/fe/macros/filterBar/FilterBar.block.tsx +4 -2
- package/src/sap/fe/macros/filterBar/FilterBar.js +2 -2
- package/src/sap/fe/macros/filterBar/FilterBar.tsx +1 -1
- package/src/sap/fe/macros/filterBar/FilterBarAPI.js +63 -27
- package/src/sap/fe/macros/filterBar/FilterBarAPI.ts +49 -3
- package/src/sap/fe/macros/filterBar/FilterBarDelegate.js +5 -3
- package/src/sap/fe/macros/filterBar/FilterBarDelegate.ts +5 -2
- package/src/sap/fe/macros/filterBar/mixin/FilterBarAPIStateHandler.js +7 -2
- package/src/sap/fe/macros/filterBar/mixin/FilterBarAPIStateHandler.ts +6 -1
- package/src/sap/fe/macros/form/Form.block.js +7 -8
- package/src/sap/fe/macros/form/Form.block.ts +4 -6
- package/src/sap/fe/macros/form/Form.js +1 -4
- package/src/sap/fe/macros/form/Form.tsx +0 -3
- package/src/sap/fe/macros/form/FormContainer.block.js +555 -5
- package/src/sap/fe/macros/form/FormContainer.block.ts +665 -7
- package/src/sap/fe/macros/form/FormContainer.fragment.xml +1 -0
- package/src/sap/fe/macros/form/FormDelegate.js +24 -8
- package/src/sap/fe/macros/form/FormDelegate.ts +29 -7
- package/src/sap/fe/macros/form/FormHelper.js +1 -2
- package/src/sap/fe/macros/form/FormHelper.ts +0 -1
- package/src/sap/fe/macros/fpm/CustomFragment.block.js +1 -2
- package/src/sap/fe/macros/fpm/CustomFragment.block.ts +0 -1
- package/src/sap/fe/macros/internal/ActionCommand.block.js +1 -2
- package/src/sap/fe/macros/internal/ActionCommand.block.ts +0 -1
- package/src/sap/fe/macros/internal/DataPoint.js +3 -2
- package/src/sap/fe/macros/internal/DataPoint.tsx +10 -1
- package/src/sap/fe/macros/internal/FilterField.block.js +19 -5
- package/src/sap/fe/macros/internal/FilterField.block.ts +16 -4
- package/src/sap/fe/macros/internal/field/DisplayStyle.js +9 -3
- package/src/sap/fe/macros/internal/field/DisplayStyle.tsx +10 -2
- package/src/sap/fe/macros/internal/field/EditStyle.js +21 -4
- package/src/sap/fe/macros/internal/field/EditStyle.tsx +18 -4
- package/src/sap/fe/macros/internal/field/FieldStructureHelper.js +3 -2
- package/src/sap/fe/macros/internal/field/FieldStructureHelper.ts +5 -1
- package/src/sap/fe/macros/internal/filterField/FilterFieldTemplate.fragment.xml +1 -0
- package/src/sap/fe/macros/internal/helpers/ActionHelper.js +36 -5
- package/src/sap/fe/macros/internal/helpers/ActionHelper.ts +34 -4
- package/src/sap/fe/macros/internal/valuehelp/AdditionalValueHelper.js +46 -8
- package/src/sap/fe/macros/internal/valuehelp/AdditionalValueHelper.ts +60 -6
- package/src/sap/fe/macros/internal/valuehelp/TableDelegate.js +38 -2
- package/src/sap/fe/macros/internal/valuehelp/TableDelegate.ts +37 -2
- package/src/sap/fe/macros/internal/valuehelp/ValueListDialogTable.fragment.xml +1 -1
- package/src/sap/fe/macros/internal/valuehelp/ValueListHelper.js +10 -3
- package/src/sap/fe/macros/internal/valuehelp/ValueListHelper.ts +13 -2
- package/src/sap/fe/macros/library.js +1 -1
- package/src/sap/fe/macros/mdc/adapter/StateFilterToSelectionVariant.js +2 -1
- package/src/sap/fe/macros/mdc/adapter/StateFilterToSelectionVariant.ts +1 -0
- package/src/sap/fe/macros/messagebundle.properties +24 -4
- package/src/sap/fe/macros/messagebundle_ar.properties +8 -2
- package/src/sap/fe/macros/messagebundle_bg.properties +8 -2
- package/src/sap/fe/macros/messagebundle_ca.properties +11 -5
- package/src/sap/fe/macros/messagebundle_cnr.properties +8 -2
- package/src/sap/fe/macros/messagebundle_cs.properties +7 -1
- package/src/sap/fe/macros/messagebundle_cy.properties +9 -3
- package/src/sap/fe/macros/messagebundle_da.properties +8 -2
- package/src/sap/fe/macros/messagebundle_de.properties +13 -7
- package/src/sap/fe/macros/messagebundle_el.properties +7 -1
- package/src/sap/fe/macros/messagebundle_en.properties +11 -5
- package/src/sap/fe/macros/messagebundle_en_GB.properties +9 -3
- package/src/sap/fe/macros/messagebundle_en_US_saprigi.properties +11 -5
- package/src/sap/fe/macros/messagebundle_es.properties +10 -4
- package/src/sap/fe/macros/messagebundle_es_MX.properties +11 -5
- package/src/sap/fe/macros/messagebundle_et.properties +9 -3
- package/src/sap/fe/macros/messagebundle_fi.properties +7 -1
- package/src/sap/fe/macros/messagebundle_fr.properties +9 -3
- package/src/sap/fe/macros/messagebundle_fr_CA.properties +8 -2
- package/src/sap/fe/macros/messagebundle_hi.properties +8 -2
- package/src/sap/fe/macros/messagebundle_hr.properties +8 -2
- package/src/sap/fe/macros/messagebundle_hu.properties +7 -1
- package/src/sap/fe/macros/messagebundle_id.properties +15 -9
- package/src/sap/fe/macros/messagebundle_it.properties +7 -1
- package/src/sap/fe/macros/messagebundle_iw.properties +8 -2
- package/src/sap/fe/macros/messagebundle_ja.properties +13 -7
- package/src/sap/fe/macros/messagebundle_kk.properties +11 -5
- package/src/sap/fe/macros/messagebundle_ko.properties +8 -2
- package/src/sap/fe/macros/messagebundle_lt.properties +9 -3
- package/src/sap/fe/macros/messagebundle_lv.properties +8 -2
- package/src/sap/fe/macros/messagebundle_mk.properties +8 -2
- package/src/sap/fe/macros/messagebundle_ms.properties +7 -1
- package/src/sap/fe/macros/messagebundle_nl.properties +7 -1
- package/src/sap/fe/macros/messagebundle_no.properties +7 -1
- package/src/sap/fe/macros/messagebundle_pl.properties +8 -2
- package/src/sap/fe/macros/messagebundle_pt.properties +7 -1
- package/src/sap/fe/macros/messagebundle_pt_PT.properties +7 -1
- package/src/sap/fe/macros/messagebundle_ro.properties +8 -2
- package/src/sap/fe/macros/messagebundle_ru.properties +10 -4
- package/src/sap/fe/macros/messagebundle_sh.properties +8 -2
- package/src/sap/fe/macros/messagebundle_sk.properties +7 -1
- package/src/sap/fe/macros/messagebundle_sl.properties +7 -1
- package/src/sap/fe/macros/messagebundle_sr.properties +8 -2
- package/src/sap/fe/macros/messagebundle_sv.properties +7 -1
- package/src/sap/fe/macros/messagebundle_th.properties +8 -2
- package/src/sap/fe/macros/messagebundle_tr.properties +7 -1
- package/src/sap/fe/macros/messagebundle_uk.properties +10 -4
- package/src/sap/fe/macros/messagebundle_vi.properties +10 -4
- package/src/sap/fe/macros/messagebundle_zh_CN.properties +7 -1
- package/src/sap/fe/macros/messagebundle_zh_TW.properties +8 -2
- package/src/sap/fe/macros/messages/MessageButton.js +39 -18
- package/src/sap/fe/macros/messages/MessageButton.ts +42 -19
- package/src/sap/fe/macros/messages/MessagePopover.js +4 -2
- package/src/sap/fe/macros/messages/MessagePopover.ts +6 -4
- package/src/sap/fe/macros/microchart/MicroChart.js +2 -2
- package/src/sap/fe/macros/microchart/MicroChart.tsx +1 -1
- package/src/sap/fe/macros/microchart/MicroChartContainer.js +1 -2
- package/src/sap/fe/macros/microchart/MicroChartContainer.ts +1 -2
- package/src/sap/fe/macros/microchart/MicroChartHelper.js +2 -3
- package/src/sap/fe/macros/microchart/MicroChartHelper.tsx +1 -2
- package/src/sap/fe/macros/share/ShareAPI.js +4 -29
- package/src/sap/fe/macros/share/ShareAPI.ts +1 -32
- package/src/sap/fe/macros/situations/SituationsPopover.js +3 -1
- package/src/sap/fe/macros/situations/SituationsPopover.ts +2 -0
- package/src/sap/fe/macros/table/ActionsTemplating.js +4 -8
- package/src/sap/fe/macros/table/ActionsTemplating.tsx +5 -8
- package/src/sap/fe/macros/table/BasicSearch.js +1 -1
- package/src/sap/fe/macros/table/BasicSearch.ts +2 -1
- package/src/sap/fe/macros/table/Column.js +14 -2
- package/src/sap/fe/macros/table/Column.ts +7 -0
- package/src/sap/fe/macros/table/ColumnExportSettings.js +83 -15
- package/src/sap/fe/macros/table/ColumnExportSettings.ts +44 -0
- package/src/sap/fe/macros/table/ColumnOverride.js +14 -2
- package/src/sap/fe/macros/table/ColumnOverride.ts +7 -0
- package/src/sap/fe/macros/table/MdcTableTemplate.js +7 -5
- package/src/sap/fe/macros/table/MdcTableTemplate.tsx +21 -11
- package/src/sap/fe/macros/table/QuickFilterSelector.js +12 -3
- package/src/sap/fe/macros/table/QuickFilterSelector.tsx +15 -2
- package/src/sap/fe/macros/table/Table.block.js +188 -147
- package/src/sap/fe/macros/table/Table.block.tsx +41 -11
- package/src/sap/fe/macros/table/Table.js +16 -10
- package/src/sap/fe/macros/table/Table.tsx +16 -10
- package/src/sap/fe/macros/table/TableAPI.js +224 -184
- package/src/sap/fe/macros/table/TableAPI.ts +63 -19
- package/src/sap/fe/macros/table/TableEventHandlerProvider.js +6 -6
- package/src/sap/fe/macros/table/TableEventHandlerProvider.ts +5 -4
- package/src/sap/fe/macros/table/TableHelper.js +2 -3
- package/src/sap/fe/macros/table/TableHelper.ts +1 -2
- package/src/sap/fe/macros/table/TableRuntime.js +24 -5
- package/src/sap/fe/macros/table/TableRuntime.ts +31 -3
- package/src/sap/fe/macros/table/TreeTable.js +16 -10
- package/src/sap/fe/macros/table/TreeTable.tsx +16 -10
- package/src/sap/fe/macros/table/Utils.js +8 -3
- package/src/sap/fe/macros/table/Utils.ts +12 -3
- package/src/sap/fe/macros/table/delegates/ALPTableDelegate.js +1 -2
- package/src/sap/fe/macros/table/delegates/ALPTableDelegate.ts +0 -1
- package/src/sap/fe/macros/table/delegates/TableDelegate.js +69 -34
- package/src/sap/fe/macros/table/delegates/TableDelegate.ts +75 -33
- package/src/sap/fe/macros/table/delegates/TreeTableDelegate.js +1 -2
- package/src/sap/fe/macros/table/delegates/TreeTableDelegate.ts +0 -1
- package/src/sap/fe/macros/table/massEdit/MassEditDialog.js +10 -10
- package/src/sap/fe/macros/table/massEdit/MassEditDialog.tsx +11 -9
- package/src/sap/fe/macros/table/massEdit/MassEditDialogHelper.js +14 -12
- package/src/sap/fe/macros/table/massEdit/MassEditDialogHelper.tsx +11 -10
- package/src/sap/fe/macros/table/mixin/ContextMenuHandler.js +34 -4
- package/src/sap/fe/macros/table/mixin/ContextMenuHandler.ts +45 -2
- package/src/sap/fe/macros/table/mixin/EmptyRowsHandler.js +55 -12
- package/src/sap/fe/macros/table/mixin/EmptyRowsHandler.ts +71 -9
- package/src/sap/fe/macros/table/mixin/TableAPIStateHandler.js +53 -2
- package/src/sap/fe/macros/table/mixin/TableAPIStateHandler.ts +55 -0
- package/src/sap/fe/macros/table/mixin/TableExport.js +22 -3
- package/src/sap/fe/macros/table/mixin/TableExport.ts +25 -4
- package/src/sap/fe/macros/table/mixin/TableHierarchy.js +5 -1
- package/src/sap/fe/macros/table/mixin/TableHierarchy.ts +7 -0
- package/src/sap/fe/macros/table/mixin/TableSharing.js +4 -2
- package/src/sap/fe/macros/table/mixin/TableSharing.ts +10 -1
- package/src/sap/fe/macros/valuehelp/ValueHelpDelegate.js +36 -10
- package/src/sap/fe/macros/valuehelp/ValueHelpDelegate.ts +44 -9
- package/src/sap/fe/macros/visualfilters/VisualFilter.js +5 -4
- package/src/sap/fe/macros/visualfilters/VisualFilter.tsx +3 -2
- package/src/sap/fe/macros/visualfilters/VisualFilterRuntime.js +2 -3
- package/src/sap/fe/macros/visualfilters/VisualFilterRuntime.ts +1 -2
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import type { ComplexType, EntitySet, EntityType, NavigationProperty, Property, TypeDefinition } from "@sap-ux/vocabularies-types";
|
|
1
2
|
import Log from "sap/base/Log";
|
|
3
|
+
import Localization from "sap/base/i18n/Localization";
|
|
4
|
+
import { isConstant } from "sap/fe/base/BindingToolkit";
|
|
2
5
|
import type { EnhanceWithUI5 } from "sap/fe/base/ClassSupport";
|
|
3
6
|
import { aggregation, association, defineUI5Class, implementInterface, property, type PropertiesOf } from "sap/fe/base/ClassSupport";
|
|
4
7
|
import type {
|
|
8
|
+
CodeListType,
|
|
5
9
|
EasyFilterBarContainer$ShowValueHelpEvent,
|
|
6
10
|
EasyFilterPropertyMetadata,
|
|
7
11
|
TokenDefinition,
|
|
@@ -14,10 +18,11 @@ import BuildingBlock from "sap/fe/core/buildingBlocks/BuildingBlock";
|
|
|
14
18
|
import BusyLocker from "sap/fe/core/controllerextensions/BusyLocker";
|
|
15
19
|
import type { ControlState, NavigationParameter } from "sap/fe/core/controllerextensions/ViewState";
|
|
16
20
|
import type IViewStateContributor from "sap/fe/core/controllerextensions/viewState/IViewStateContributor";
|
|
17
|
-
import type
|
|
21
|
+
import { type FilterField } from "sap/fe/core/definition/FEDefinition";
|
|
18
22
|
import type MetaPath from "sap/fe/core/helpers/MetaPath";
|
|
19
23
|
import ModelHelper from "sap/fe/core/helpers/ModelHelper";
|
|
20
|
-
import { isPathAnnotationExpression } from "sap/fe/core/helpers/TypeGuards";
|
|
24
|
+
import { isComplexType, isEntityType, isNavigationProperty, isPathAnnotationExpression, isProperty } from "sap/fe/core/helpers/TypeGuards";
|
|
25
|
+
import { isPathFilterable } from "sap/fe/core/templating/DataModelPathHelper";
|
|
21
26
|
import { hasValueHelpWithFixedValues } from "sap/fe/core/templating/PropertyHelper";
|
|
22
27
|
import {
|
|
23
28
|
generateSelectParameter,
|
|
@@ -42,14 +47,13 @@ import DateTimeOffset from "sap/ui/model/odata/type/DateTimeOffset";
|
|
|
42
47
|
import type ODataType from "sap/ui/model/odata/type/ODataType";
|
|
43
48
|
import TimeOfDay from "sap/ui/model/odata/type/TimeOfDay";
|
|
44
49
|
import type ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
|
|
45
|
-
import type { CodeList
|
|
50
|
+
import type { CodeList } from "ux/eng/fioriai/reuse/easyfilter/EasyFilter";
|
|
46
51
|
|
|
47
52
|
type EasyFilterBarState = {};
|
|
48
|
-
type FieldMetadata = EasyFilterPropertyMetadata & {
|
|
53
|
+
type FieldMetadata = EasyFilterPropertyMetadata & { maxLength?: number };
|
|
49
54
|
|
|
50
55
|
/**
|
|
51
56
|
* Delivery for beta release for the easy filter feature.
|
|
52
|
-
* @experimental
|
|
53
57
|
*/
|
|
54
58
|
@defineUI5Class("sap.fe.macros.EasyFilterBar")
|
|
55
59
|
export default class EasyFilterBar extends BuildingBlock implements IViewStateContributor<EasyFilterBarState> {
|
|
@@ -71,8 +75,6 @@ export default class EasyFilterBar extends BuildingBlock implements IViewStateCo
|
|
|
71
75
|
@aggregation({ type: "sap.fe.controls.easyFilter.EasyFilterBarContainer" })
|
|
72
76
|
content?: EnhanceWithUI5<EasyFilterBarContainer>;
|
|
73
77
|
|
|
74
|
-
_fetchedCodeList!: Record<string, CodeList | undefined>;
|
|
75
|
-
|
|
76
78
|
private filterBarMetadata!: FieldMetadata[];
|
|
77
79
|
|
|
78
80
|
private easyFilterPath?: string;
|
|
@@ -142,116 +144,272 @@ export default class EasyFilterBar extends BuildingBlock implements IViewStateCo
|
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
onMetadataAvailable(): void {
|
|
145
|
-
this._fetchedCodeList ??= {};
|
|
146
147
|
this.filterBarMetadata = this.prepareFilterBarMetadata();
|
|
147
148
|
this.recommendedQueries = this.getAppComponent()?.getManifestEntry("sap.fe")?.macros?.easyFilter?.recommendedQueries ?? [];
|
|
148
149
|
this.content = this.createContent() as EnhanceWithUI5<EasyFilterBarContainer>;
|
|
149
150
|
this.content.filterBarMetadata = this.filterBarMetadata;
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
private getUnitForProperty(prop: Property, basePath: string): string | undefined {
|
|
154
|
+
const unitAnnotation = prop.annotations.Measures?.ISOCurrency ?? prop.annotations.Measures?.Unit;
|
|
155
|
+
return isPathAnnotationExpression(unitAnnotation) ? `${basePath}/${unitAnnotation.path}` : undefined;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private getDefaultValueForFilterField(
|
|
159
|
+
field: FilterField,
|
|
160
|
+
startupParameters: Record<string, unknown>
|
|
161
|
+
): TokenSelectedValuesDefinition[] | undefined {
|
|
162
|
+
let defaultValue: TokenSelectedValuesDefinition[] | undefined;
|
|
163
|
+
if (startupParameters.hasOwnProperty(field.name)) {
|
|
164
|
+
defaultValue = [
|
|
165
|
+
{
|
|
166
|
+
operator: FilterOperator.EQ,
|
|
167
|
+
selectedValues: startupParameters[field.name] as TokenSelectedValuesDefinition["selectedValues"]
|
|
168
|
+
}
|
|
169
|
+
];
|
|
170
|
+
} else if (field.isParameter && startupParameters.hasOwnProperty(field.name.substring(2))) {
|
|
171
|
+
defaultValue = [
|
|
172
|
+
{
|
|
173
|
+
operator: FilterOperator.EQ,
|
|
174
|
+
selectedValues: startupParameters[field.name.substring(2)] as TokenSelectedValuesDefinition["selectedValues"]
|
|
175
|
+
}
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
return defaultValue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private getEditStateFilterMetadata(metaModel: ODataMetaModel): FieldMetadata {
|
|
182
|
+
// Assemble the code list for the editing status filter values:
|
|
183
|
+
const props = new JSONModel({
|
|
184
|
+
isDraftCollaborative: ModelHelper.isCollaborationDraftSupported(metaModel)
|
|
185
|
+
}).createBindingContext("/");
|
|
186
|
+
|
|
187
|
+
const editingStatusCodeList = DraftEditState.getEditStatesContext(props)
|
|
188
|
+
.getObject("/")
|
|
189
|
+
.map((state: { id: string; display: string }) => ({ value: state.id, description: state.display }));
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
name: "$editState",
|
|
193
|
+
label: this.getTranslatedText("FILTERBAR_EDITING_STATUS"),
|
|
194
|
+
dataType: "Edm.String",
|
|
195
|
+
filterable: true,
|
|
196
|
+
codeList: editingStatusCodeList,
|
|
197
|
+
type: "MenuWithSingleSelect"
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private getTokenType(prop: Property, filterRestriction: string): TokenType {
|
|
202
|
+
if (hasValueHelpWithFixedValues(prop)) {
|
|
203
|
+
return filterRestriction === "SingleValue" ? "MenuWithSingleSelect" : "MenuWithCheckBox";
|
|
204
|
+
}
|
|
205
|
+
switch (prop.type) {
|
|
206
|
+
case "Edm.Date":
|
|
207
|
+
return "Calendar";
|
|
208
|
+
case "Edm.TimeOfDay":
|
|
209
|
+
return "Time";
|
|
210
|
+
default:
|
|
211
|
+
return "ValueHelp";
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private getLabel(element: Property | NavigationProperty | EntityType | ComplexType): string | undefined {
|
|
216
|
+
const label = element.annotations.Common?.Label?.toString();
|
|
217
|
+
const headerInfoTypeName = isEntityType(element) ? (element.annotations.UI?.HeaderInfo?.TypeName?.valueOf() as string) : undefined;
|
|
218
|
+
const result = headerInfoTypeName || label;
|
|
219
|
+
|
|
220
|
+
if (this.isComplexProperty(element) || isNavigationProperty(element)) {
|
|
221
|
+
return result || this.getLabel(element.targetType);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private isScalarProperty(element: unknown): element is Property & { targetType?: TypeDefinition } {
|
|
228
|
+
return isProperty(element) && !isComplexType(element.targetType);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private isComplexProperty(element: unknown): element is Property & { targetType: ComplexType } {
|
|
232
|
+
return isProperty(element) && isComplexType(element.targetType);
|
|
233
|
+
}
|
|
234
|
+
|
|
152
235
|
prepareFilterBarMetadata(): FieldMetadata[] {
|
|
236
|
+
/*
|
|
237
|
+
* 1. INITIALIZATION:
|
|
238
|
+
* - Queue all root entity properties and navigation properties for traversal
|
|
239
|
+
* - Initialize result array and elimination set for Common.Text targets
|
|
240
|
+
*
|
|
241
|
+
* 2. BREADTH-FIRST TRAVERSAL:
|
|
242
|
+
* For each path in queue:
|
|
243
|
+
* - Skip UI.Hidden properties
|
|
244
|
+
* - Scalar properties: Generate metadata, track Common.Text targets for elimination
|
|
245
|
+
* - Complex properties: Add child properties to queue
|
|
246
|
+
* - Navigation properties: Add target EntityType properties to queue
|
|
247
|
+
* (Collections only if explicit filter fields exist, respect depth limits)
|
|
248
|
+
*
|
|
249
|
+
* 3. POST-PROCESSING:
|
|
250
|
+
* - Add $editState filter for draft-enabled entities
|
|
251
|
+
* - Remove properties marked for elimination (except explicit filter fields)
|
|
252
|
+
*/
|
|
153
253
|
const owner = this._getOwner()!;
|
|
154
254
|
const definitionForPage = owner.preprocessorContext?.getDefinitionForPage();
|
|
155
|
-
let filterBarDef;
|
|
156
|
-
if (definitionForPage) {
|
|
157
|
-
filterBarDef = definitionForPage.getFilterBarDefinition({});
|
|
158
255
|
|
|
159
|
-
|
|
256
|
+
if (!definitionForPage) {
|
|
257
|
+
return [];
|
|
258
|
+
}
|
|
160
259
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
260
|
+
const filterBarDef = definitionForPage.getFilterBarDefinition({});
|
|
261
|
+
const metaPath = definitionForPage.getMetaPath();
|
|
262
|
+
const entitySet = metaPath.getClosestEntitySet() as EntitySet;
|
|
263
|
+
|
|
264
|
+
let filterExpressionRestrictions = entitySet.annotations.Capabilities?.FilterRestrictions?.FilterExpressionRestrictions ?? [];
|
|
265
|
+
|
|
266
|
+
// TODO: Maybe we can simplify this by using restrictions on the main entity set only
|
|
267
|
+
for (const navigationProperty in entitySet.navigationPropertyBinding) {
|
|
268
|
+
if (entitySet.navigationPropertyBinding[navigationProperty]?._type === "EntitySet") {
|
|
269
|
+
// FIXME: optional chaining should not be needed here -> root cause fix pending
|
|
270
|
+
const navigationPropertyEntitySet = entitySet.navigationPropertyBinding[navigationProperty] as EntitySet;
|
|
271
|
+
const navPropertyFilterExpressionRestrictions =
|
|
272
|
+
navigationPropertyEntitySet.annotations.Capabilities?.FilterRestrictions?.FilterExpressionRestrictions ?? [];
|
|
273
|
+
|
|
274
|
+
const currentFilterRestrictions = [...filterExpressionRestrictions];
|
|
275
|
+
filterExpressionRestrictions = [
|
|
276
|
+
...filterExpressionRestrictions,
|
|
277
|
+
...navPropertyFilterExpressionRestrictions.filter((restriction) => !currentFilterRestrictions.includes(restriction))
|
|
278
|
+
];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
175
281
|
|
|
176
|
-
|
|
177
|
-
const nonHiddenFilterFields = filterFields.filter((field: FilterField) => {
|
|
178
|
-
return !field.getTarget()?.annotations?.UI?.HiddenFilter?.valueOf();
|
|
179
|
-
});
|
|
180
|
-
const result = nonHiddenFilterFields.map((field: FilterField): FieldMetadata => {
|
|
181
|
-
const propertyObject = field.getTarget();
|
|
182
|
-
let codeList: MayBeLazy<CodeList> | undefined;
|
|
183
|
-
const hasCodeList = hasValueHelpWithFixedValues(propertyObject);
|
|
184
|
-
if (hasCodeList) {
|
|
185
|
-
codeList = this._fetchedCodeList[field.name];
|
|
186
|
-
if (!codeList) {
|
|
187
|
-
codeList = async (): Promise<CodeList> => this.getCodeListForProperty(field.name, field.annotationPath!);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
282
|
+
const metaModel = owner.preprocessorContext?.models.metaModel as ODataMetaModel;
|
|
190
283
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
284
|
+
const getCodeList = (lastPathSegment: Property, propertyPath: string): CodeList | (() => Promise<CodeList>) | undefined =>
|
|
285
|
+
hasValueHelpWithFixedValues(lastPathSegment)
|
|
286
|
+
? async (): Promise<CodeList> => this.getCodeListForProperty(propertyPath)
|
|
287
|
+
: undefined;
|
|
288
|
+
|
|
289
|
+
const filterFields = filterBarDef
|
|
290
|
+
.getFilterFields()
|
|
291
|
+
.filter((field: FilterField) => !field.getTarget()?.annotations?.UI?.HiddenFilter?.valueOf());
|
|
292
|
+
|
|
293
|
+
const startupParameters = owner.getAppComponent().getComponentData()?.startupParameters ?? {};
|
|
294
|
+
|
|
295
|
+
const maxDepth = 1; // Maximum depth for navigation properties
|
|
296
|
+
|
|
297
|
+
// Initialize traversal queue with all entity properties and navigation properties.
|
|
298
|
+
// Each path to traverse is a list of segments (e.g. [navProp1, complexProp1, complexProp2, scalarProp])
|
|
299
|
+
const pathsToExplore: (Property | NavigationProperty)[][] = [
|
|
300
|
+
...entitySet.entityType.entityProperties,
|
|
301
|
+
...entitySet.entityType.navigationProperties
|
|
302
|
+
].map((element) => [element]);
|
|
303
|
+
|
|
304
|
+
// Resulting metadata array
|
|
305
|
+
const result: EasyFilterPropertyMetadata[] = [];
|
|
306
|
+
|
|
307
|
+
// Set of property paths to be eliminated from the filter bar metadata
|
|
308
|
+
const pathsToEliminate = new Set<string>();
|
|
309
|
+
|
|
310
|
+
const getPathLabel = (path: (Property | NavigationProperty)[]): string => {
|
|
311
|
+
const pathLabels = path.map((e) => this.getLabel(e) || `[${e.name}]`);
|
|
312
|
+
return Localization.getRTL() ? pathLabels.slice().reverse().join(" - ") : pathLabels.join(" - ");
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
while (pathsToExplore.length > 0) {
|
|
316
|
+
const currentPath = pathsToExplore.shift()!;
|
|
317
|
+
|
|
318
|
+
const navigationDepth = currentPath.filter(isNavigationProperty).length;
|
|
319
|
+
|
|
320
|
+
const lastPathSegment = currentPath[currentPath.length - 1];
|
|
321
|
+
|
|
322
|
+
if (lastPathSegment.annotations.UI?.Hidden?.valueOf() === true) {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const pathString = [`/${entitySet.name}`, ...currentPath.slice(0, -1).map((e) => e.name)].reduce(
|
|
327
|
+
(acc, curr) => `${acc}/${curr}`
|
|
328
|
+
);
|
|
329
|
+
const propertyPath = `${pathString}/${lastPathSegment.name}`;
|
|
330
|
+
|
|
331
|
+
if (this.isScalarProperty(lastPathSegment)) {
|
|
332
|
+
// Check for Common.Text annotation and record the annotation target path for elimination
|
|
333
|
+
const textAnnotation = lastPathSegment.annotations.Common?.Text;
|
|
334
|
+
if (isPathAnnotationExpression(textAnnotation)) {
|
|
335
|
+
// Construct the full path to the target property
|
|
336
|
+
pathsToEliminate.add(`${pathString}/${textAnnotation.path}`);
|
|
211
337
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
338
|
+
|
|
339
|
+
// Scalar property: create metadata for the property
|
|
340
|
+
const filterField = filterFields.find((field) => field.getTarget() === lastPathSegment);
|
|
341
|
+
const filterRestriction = filterExpressionRestrictions.find(
|
|
342
|
+
(expression) => expression.Property?.$target === lastPathSegment
|
|
343
|
+
);
|
|
344
|
+
const filterable = isPathFilterable(this.getDataModelObjectPath(propertyPath));
|
|
345
|
+
const filterableExpression = isConstant(filterable) ? filterable.value : true;
|
|
346
|
+
const filterRestrictionExpression = filterRestriction?.AllowedExpressions as
|
|
347
|
+
| EasyFilterPropertyMetadata["filterRestriction"]
|
|
348
|
+
| undefined;
|
|
349
|
+
const codeList = getCodeList(lastPathSegment, propertyPath);
|
|
350
|
+
const metadata: EasyFilterPropertyMetadata = {
|
|
351
|
+
name: propertyPath,
|
|
352
|
+
label: getPathLabel(currentPath),
|
|
353
|
+
dataType: lastPathSegment.type,
|
|
354
|
+
required: filterField?.required,
|
|
355
|
+
defaultValue: filterField ? this.getDefaultValueForFilterField(filterField, startupParameters) : undefined,
|
|
356
|
+
filterable: filterField ? filterableExpression : undefined,
|
|
357
|
+
hiddenFilter: !filterField,
|
|
358
|
+
filterRestriction: filterField ? filterRestrictionExpression : undefined,
|
|
359
|
+
codeList,
|
|
360
|
+
type: this.getTokenType(
|
|
361
|
+
lastPathSegment,
|
|
362
|
+
filterRestriction?.AllowedExpressions?.toString() || "MultiRangeOrSearchExpression"
|
|
363
|
+
) as Exclude<TokenType, "ValueHelp">,
|
|
364
|
+
unit: this.getUnitForProperty(lastPathSegment, pathString)
|
|
223
365
|
};
|
|
224
|
-
|
|
366
|
+
result.push(metadata);
|
|
367
|
+
} else if (this.isComplexProperty(lastPathSegment)) {
|
|
368
|
+
// Complex property: add all properties and navigation properties of the complex type
|
|
369
|
+
lastPathSegment.targetType.properties.forEach((child) => {
|
|
370
|
+
pathsToExplore.push([...currentPath, child]);
|
|
371
|
+
});
|
|
225
372
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
filterFieldName: "$editState",
|
|
241
|
-
label: this.getTranslatedText("FILTERBAR_EDITING_STATUS"),
|
|
242
|
-
dataType: "Edm.String",
|
|
243
|
-
required: false,
|
|
244
|
-
filterable: true,
|
|
245
|
-
codeList: editingStatusCodeList,
|
|
246
|
-
type: "MenuWithCheckBox"
|
|
373
|
+
// only traverse navigation properties if we are not at the maximum depth
|
|
374
|
+
if (navigationDepth < maxDepth) {
|
|
375
|
+
lastPathSegment.targetType.navigationProperties.forEach((child) => {
|
|
376
|
+
pathsToExplore.push([...currentPath, child]);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
} else if (isNavigationProperty(lastPathSegment)) {
|
|
380
|
+
// add 1:n navigation properties only if there are filter fields for at least one of the target properties
|
|
381
|
+
if (lastPathSegment.isCollection && !filterFields.some((field) => field.annotationPath?.startsWith(propertyPath))) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
lastPathSegment.targetType.entityProperties.forEach((child) => {
|
|
386
|
+
pathsToExplore.push([...currentPath, child]);
|
|
247
387
|
});
|
|
388
|
+
|
|
389
|
+
// only traverse navigation properties if we are not at the maximum depth
|
|
390
|
+
if (navigationDepth < maxDepth) {
|
|
391
|
+
lastPathSegment.targetType.navigationProperties.forEach((child) => {
|
|
392
|
+
pathsToExplore.push([...currentPath, child]);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
248
395
|
}
|
|
249
|
-
return result;
|
|
250
396
|
}
|
|
251
|
-
|
|
397
|
+
|
|
398
|
+
// [Editing Status]
|
|
399
|
+
if (ModelHelper.isMetaPathDraftSupported(definitionForPage.getMetaPath() as unknown as MetaPath<unknown>)) {
|
|
400
|
+
result.push(this.getEditStateFilterMetadata(metaModel));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Remove properties marked for elimination (unless they are filter fields)
|
|
404
|
+
return result.filter((metadata) => {
|
|
405
|
+
return (
|
|
406
|
+
!metadata.hiddenFilter || // Keep if explicit filter field
|
|
407
|
+
!pathsToEliminate.has(metadata.name) // Keep if path not marked for elimination
|
|
408
|
+
);
|
|
409
|
+
});
|
|
252
410
|
}
|
|
253
411
|
|
|
254
|
-
async getCodeListForProperty(
|
|
412
|
+
async getCodeListForProperty(propertyPath: string): Promise<CodeList> {
|
|
255
413
|
const defaultValueList = await this.getValueList(propertyPath);
|
|
256
414
|
|
|
257
415
|
if (!defaultValueList) {
|
|
@@ -266,8 +424,7 @@ export default class EasyFilterBar extends BuildingBlock implements IViewStateCo
|
|
|
266
424
|
const data = await listBinding.requestContexts();
|
|
267
425
|
|
|
268
426
|
const filterGroupValues = data.map(mapValueListToCodeList(defaultValueList));
|
|
269
|
-
this.
|
|
270
|
-
const codeListProperty = this.filterBarMetadata.find((field) => field.name === key);
|
|
427
|
+
const codeListProperty = this.filterBarMetadata.find((field) => field.name === propertyPath);
|
|
271
428
|
if (codeListProperty) {
|
|
272
429
|
codeListProperty.codeList = filterGroupValues;
|
|
273
430
|
}
|
|
@@ -279,17 +436,56 @@ export default class EasyFilterBar extends BuildingBlock implements IViewStateCo
|
|
|
279
436
|
values: TokenSelectedValuesDefinition[]
|
|
280
437
|
): Promise<ValueHelpSelectedValuesDefinition[]> {
|
|
281
438
|
const field = this.filterBarMetadata.find(({ name }) => name === fieldName);
|
|
282
|
-
|
|
283
|
-
const valueList = await this.getValueList(field.name);
|
|
439
|
+
let result: ValueHelpSelectedValuesDefinition[];
|
|
284
440
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
441
|
+
if (!field) {
|
|
442
|
+
// return original values converted to the expected format if no field is defined
|
|
443
|
+
return unresolvedResult(values);
|
|
444
|
+
}
|
|
445
|
+
const valueList = await this.getValueList(field.name);
|
|
446
|
+
|
|
447
|
+
if (valueList && ValueListHelper.isValueListSearchable(field.name, valueList)) {
|
|
448
|
+
const resolvedTokenValues = await Promise.all(values.map(async (value) => resolveTokenValue(valueList, value)));
|
|
449
|
+
result = resolvedTokenValues.flat();
|
|
450
|
+
} else {
|
|
451
|
+
result = unresolvedResult(values);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Apply maxLength filtering if defined
|
|
455
|
+
if (field.maxLength !== undefined) {
|
|
456
|
+
const filteredTokens = result
|
|
457
|
+
.map((token) => {
|
|
458
|
+
if (token.operator === FilterOperator.BT || token.operator === FilterOperator.NB) {
|
|
459
|
+
// Handle between operators - selectedValues is ValueHelpBetweenSelectedValues
|
|
460
|
+
const [a, b] = token.selectedValues;
|
|
461
|
+
|
|
462
|
+
// Check if both values exceed maxLength
|
|
463
|
+
if (String(a.value).length <= field.maxLength! && String(b.value).length <= field.maxLength!) {
|
|
464
|
+
return token; // Keep the token if both values are within limit
|
|
465
|
+
} else {
|
|
466
|
+
return null; // Remove the token if either value exceeds limit
|
|
467
|
+
}
|
|
468
|
+
} else {
|
|
469
|
+
// Handle other operators - selectedValues is CodeListType[]
|
|
470
|
+
const filtered: CodeListType[] = token.selectedValues.filter(
|
|
471
|
+
(selectedValue) => String(selectedValue.value).length <= field.maxLength!
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
// Only return the token if there are remaining values after filtering
|
|
475
|
+
if (filtered.length > 0) {
|
|
476
|
+
return { ...token, selectedValues: filtered };
|
|
477
|
+
} else {
|
|
478
|
+
return null; // Remove the token if no values remain
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
})
|
|
482
|
+
.filter((token): token is ValueHelpSelectedValuesDefinition => token !== null);
|
|
483
|
+
|
|
484
|
+
return filteredTokens;
|
|
289
485
|
}
|
|
290
486
|
|
|
291
|
-
//
|
|
292
|
-
return
|
|
487
|
+
// if no maxLength is defined, return unfiltered result
|
|
488
|
+
return result;
|
|
293
489
|
}
|
|
294
490
|
|
|
295
491
|
async getValueList(fieldName: string): Promise<ValueListInfo | undefined> {
|