@sap-ux/fiori-mcp-server 0.0.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.
Files changed (181) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +99 -0
  3. package/dist/constant.d.ts +5 -0
  4. package/dist/constant.js +8 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +7 -0
  7. package/dist/page-editor-api/api.d.ts +48 -0
  8. package/dist/page-editor-api/api.js +93 -0
  9. package/dist/page-editor-api/index.d.ts +5 -0
  10. package/dist/page-editor-api/index.js +24 -0
  11. package/dist/page-editor-api/json-helper.d.ts +11 -0
  12. package/dist/page-editor-api/json-helper.js +64 -0
  13. package/dist/page-editor-api/parser/annotations.d.ts +9 -0
  14. package/dist/page-editor-api/parser/annotations.js +13 -0
  15. package/dist/page-editor-api/parser/index.d.ts +3 -0
  16. package/dist/page-editor-api/parser/index.js +19 -0
  17. package/dist/page-editor-api/parser/model/AggregationValidator.d.ts +64 -0
  18. package/dist/page-editor-api/parser/model/AggregationValidator.js +209 -0
  19. package/dist/page-editor-api/parser/model/ArrayAggregation.d.ts +49 -0
  20. package/dist/page-editor-api/parser/model/ArrayAggregation.js +122 -0
  21. package/dist/page-editor-api/parser/model/ObjectAggregation.d.ts +374 -0
  22. package/dist/page-editor-api/parser/model/ObjectAggregation.js +802 -0
  23. package/dist/page-editor-api/parser/model/PageEditModel.d.ts +223 -0
  24. package/dist/page-editor-api/parser/model/PageEditModel.js +954 -0
  25. package/dist/page-editor-api/parser/model/PageEditProperty.d.ts +38 -0
  26. package/dist/page-editor-api/parser/model/PageEditProperty.js +49 -0
  27. package/dist/page-editor-api/parser/model/RootAggregation.d.ts +24 -0
  28. package/dist/page-editor-api/parser/model/RootAggregation.js +54 -0
  29. package/dist/page-editor-api/parser/model/actions/ActionAggregation.d.ts +34 -0
  30. package/dist/page-editor-api/parser/model/actions/ActionAggregation.js +92 -0
  31. package/dist/page-editor-api/parser/model/actions/ActionsAggregation.d.ts +96 -0
  32. package/dist/page-editor-api/parser/model/actions/ActionsAggregation.js +252 -0
  33. package/dist/page-editor-api/parser/model/actions/index.d.ts +3 -0
  34. package/dist/page-editor-api/parser/model/actions/index.js +19 -0
  35. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectAggregation.d.ts +17 -0
  36. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectAggregation.js +26 -0
  37. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectsAggregation.d.ts +46 -0
  38. package/dist/page-editor-api/parser/model/additionalObjects/AdditionalObjectsAggregation.js +66 -0
  39. package/dist/page-editor-api/parser/model/additionalObjects/index.d.ts +3 -0
  40. package/dist/page-editor-api/parser/model/additionalObjects/index.js +19 -0
  41. package/dist/page-editor-api/parser/model/chart/ChartAggregation.d.ts +41 -0
  42. package/dist/page-editor-api/parser/model/chart/ChartAggregation.js +94 -0
  43. package/dist/page-editor-api/parser/model/chart/index.d.ts +2 -0
  44. package/dist/page-editor-api/parser/model/chart/index.js +18 -0
  45. package/dist/page-editor-api/parser/model/fields/ConnectedFieldsAggregation.d.ts +9 -0
  46. package/dist/page-editor-api/parser/model/fields/ConnectedFieldsAggregation.js +13 -0
  47. package/dist/page-editor-api/parser/model/fields/FieldAggregation.d.ts +25 -0
  48. package/dist/page-editor-api/parser/model/fields/FieldAggregation.js +42 -0
  49. package/dist/page-editor-api/parser/model/fields/FieldsAggregation.d.ts +22 -0
  50. package/dist/page-editor-api/parser/model/fields/FieldsAggregation.js +34 -0
  51. package/dist/page-editor-api/parser/model/fields/index.d.ts +4 -0
  52. package/dist/page-editor-api/parser/model/fields/index.js +20 -0
  53. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldAggregation.d.ts +39 -0
  54. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldAggregation.js +94 -0
  55. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldsAggregation.d.ts +36 -0
  56. package/dist/page-editor-api/parser/model/filter-fields/FilterFieldsAggregation.js +59 -0
  57. package/dist/page-editor-api/parser/model/filter-fields/index.d.ts +3 -0
  58. package/dist/page-editor-api/parser/model/filter-fields/index.js +19 -0
  59. package/dist/page-editor-api/parser/model/index.d.ts +19 -0
  60. package/dist/page-editor-api/parser/model/index.js +35 -0
  61. package/dist/page-editor-api/parser/model/macros/MacrosRoot.d.ts +48 -0
  62. package/dist/page-editor-api/parser/model/macros/MacrosRoot.js +114 -0
  63. package/dist/page-editor-api/parser/model/macros/index.d.ts +2 -0
  64. package/dist/page-editor-api/parser/model/macros/index.js +18 -0
  65. package/dist/page-editor-api/parser/model/sections/HeaderSectionsAggregation.d.ts +31 -0
  66. package/dist/page-editor-api/parser/model/sections/HeaderSectionsAggregation.js +82 -0
  67. package/dist/page-editor-api/parser/model/sections/SectionAggregation.d.ts +78 -0
  68. package/dist/page-editor-api/parser/model/sections/SectionAggregation.js +131 -0
  69. package/dist/page-editor-api/parser/model/sections/SectionsAggregation.d.ts +135 -0
  70. package/dist/page-editor-api/parser/model/sections/SectionsAggregation.js +402 -0
  71. package/dist/page-editor-api/parser/model/sections/SectionsObjectAggregation.d.ts +50 -0
  72. package/dist/page-editor-api/parser/model/sections/SectionsObjectAggregation.js +119 -0
  73. package/dist/page-editor-api/parser/model/sections/SubSectionsAggregation.d.ts +39 -0
  74. package/dist/page-editor-api/parser/model/sections/SubSectionsAggregation.js +70 -0
  75. package/dist/page-editor-api/parser/model/sections/index.d.ts +6 -0
  76. package/dist/page-editor-api/parser/model/sections/index.js +22 -0
  77. package/dist/page-editor-api/parser/model/table/ColumnAggregation.d.ts +89 -0
  78. package/dist/page-editor-api/parser/model/table/ColumnAggregation.js +175 -0
  79. package/dist/page-editor-api/parser/model/table/ColumnsAggregation.d.ts +113 -0
  80. package/dist/page-editor-api/parser/model/table/ColumnsAggregation.js +293 -0
  81. package/dist/page-editor-api/parser/model/table/TableAggregation.d.ts +13 -0
  82. package/dist/page-editor-api/parser/model/table/TableAggregation.js +21 -0
  83. package/dist/page-editor-api/parser/model/table/ToolbarAggregation.d.ts +15 -0
  84. package/dist/page-editor-api/parser/model/table/ToolbarAggregation.js +22 -0
  85. package/dist/page-editor-api/parser/model/table/index.d.ts +5 -0
  86. package/dist/page-editor-api/parser/model/table/index.js +21 -0
  87. package/dist/page-editor-api/parser/model/table/utils.d.ts +12 -0
  88. package/dist/page-editor-api/parser/model/table/utils.js +44 -0
  89. package/dist/page-editor-api/parser/model/types/annotations.d.ts +63 -0
  90. package/dist/page-editor-api/parser/model/types/annotations.js +29 -0
  91. package/dist/page-editor-api/parser/model/types/common.d.ts +13 -0
  92. package/dist/page-editor-api/parser/model/types/common.js +3 -0
  93. package/dist/page-editor-api/parser/model/types/index.d.ts +220 -0
  94. package/dist/page-editor-api/parser/model/types/index.js +149 -0
  95. package/dist/page-editor-api/parser/model/utils/annotations.d.ts +38 -0
  96. package/dist/page-editor-api/parser/model/utils/annotations.js +120 -0
  97. package/dist/page-editor-api/parser/model/utils/i18n.d.ts +33 -0
  98. package/dist/page-editor-api/parser/model/utils/i18n.js +69 -0
  99. package/dist/page-editor-api/parser/model/utils/index.d.ts +6 -0
  100. package/dist/page-editor-api/parser/model/utils/index.js +22 -0
  101. package/dist/page-editor-api/parser/model/utils/object.d.ts +25 -0
  102. package/dist/page-editor-api/parser/model/utils/object.js +68 -0
  103. package/dist/page-editor-api/parser/model/utils/sort.d.ts +31 -0
  104. package/dist/page-editor-api/parser/model/utils/sort.js +18 -0
  105. package/dist/page-editor-api/parser/model/utils/utils.d.ts +94 -0
  106. package/dist/page-editor-api/parser/model/utils/utils.js +267 -0
  107. package/dist/page-editor-api/parser/model/views/ViewAggregation.d.ts +62 -0
  108. package/dist/page-editor-api/parser/model/views/ViewAggregation.js +112 -0
  109. package/dist/page-editor-api/parser/model/views/ViewsAggregation.d.ts +54 -0
  110. package/dist/page-editor-api/parser/model/views/ViewsAggregation.js +141 -0
  111. package/dist/page-editor-api/parser/model/views/index.d.ts +3 -0
  112. package/dist/page-editor-api/parser/model/views/index.js +19 -0
  113. package/dist/page-editor-api/parser/model/visual-filters/VisualFilterAggregation.d.ts +11 -0
  114. package/dist/page-editor-api/parser/model/visual-filters/VisualFilterAggregation.js +15 -0
  115. package/dist/page-editor-api/parser/model/visual-filters/VisualFiltersAggregation.d.ts +11 -0
  116. package/dist/page-editor-api/parser/model/visual-filters/VisualFiltersAggregation.js +15 -0
  117. package/dist/page-editor-api/parser/model/visual-filters/index.d.ts +3 -0
  118. package/dist/page-editor-api/parser/model/visual-filters/index.js +19 -0
  119. package/dist/page-editor-api/parser/tree.d.ts +135 -0
  120. package/dist/page-editor-api/parser/tree.js +464 -0
  121. package/dist/page-editor-api/project.d.ts +40 -0
  122. package/dist/page-editor-api/project.js +124 -0
  123. package/dist/page-editor-api/sapuxFtfsFileIO.d.ts +84 -0
  124. package/dist/page-editor-api/sapuxFtfsFileIO.js +195 -0
  125. package/dist/server.d.ts +35 -0
  126. package/dist/server.js +120 -0
  127. package/dist/tools/execute-functionality.d.ts +19 -0
  128. package/dist/tools/execute-functionality.js +175 -0
  129. package/dist/tools/functionalities/controller-extension/index.d.ts +4 -0
  130. package/dist/tools/functionalities/controller-extension/index.js +136 -0
  131. package/dist/tools/functionalities/functionalities.d.ts +4 -0
  132. package/dist/tools/functionalities/functionalities.js +19 -0
  133. package/dist/tools/functionalities/generate-fiori-ui-app/command.d.ts +9 -0
  134. package/dist/tools/functionalities/generate-fiori-ui-app/command.js +158 -0
  135. package/dist/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.d.ts +4 -0
  136. package/dist/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.js +240 -0
  137. package/dist/tools/functionalities/generate-fiori-ui-app/index.d.ts +2 -0
  138. package/dist/tools/functionalities/generate-fiori-ui-app/index.js +7 -0
  139. package/dist/tools/functionalities/index.d.ts +2 -0
  140. package/dist/tools/functionalities/index.js +18 -0
  141. package/dist/tools/functionalities/page/add-page.d.ts +5 -0
  142. package/dist/tools/functionalities/page/add-page.js +89 -0
  143. package/dist/tools/functionalities/page/application.d.ts +212 -0
  144. package/dist/tools/functionalities/page/application.js +616 -0
  145. package/dist/tools/functionalities/page/delete-page.d.ts +4 -0
  146. package/dist/tools/functionalities/page/delete-page.js +71 -0
  147. package/dist/tools/functionalities/page/index.d.ts +3 -0
  148. package/dist/tools/functionalities/page/index.js +10 -0
  149. package/dist/tools/functionalities/page/service.d.ts +82 -0
  150. package/dist/tools/functionalities/page/service.js +114 -0
  151. package/dist/tools/functionalities/page/serviceStore.d.ts +17 -0
  152. package/dist/tools/functionalities/page/serviceStore.js +34 -0
  153. package/dist/tools/functionalities/page/types.d.ts +42 -0
  154. package/dist/tools/functionalities/page/types.js +11 -0
  155. package/dist/tools/functionalities/page/utils.d.ts +12 -0
  156. package/dist/tools/functionalities/page/utils.js +63 -0
  157. package/dist/tools/get-functionality-details.d.ts +24 -0
  158. package/dist/tools/get-functionality-details.js +142 -0
  159. package/dist/tools/index.d.ts +7 -0
  160. package/dist/tools/index.js +55 -0
  161. package/dist/tools/input-schema/execute-functionality.json +28 -0
  162. package/dist/tools/input-schema/get-functionality-details.json +24 -0
  163. package/dist/tools/input-schema/index.d.ts +5 -0
  164. package/dist/tools/input-schema/index.js +15 -0
  165. package/dist/tools/input-schema/list-fiori-apps.json +12 -0
  166. package/dist/tools/input-schema/list-functionality.json +10 -0
  167. package/dist/tools/list-fiori-apps.d.ts +10 -0
  168. package/dist/tools/list-fiori-apps.js +33 -0
  169. package/dist/tools/list-functionalities.d.ts +10 -0
  170. package/dist/tools/list-functionalities.js +145 -0
  171. package/dist/tools/output-schema/execute-functionality.json +39 -0
  172. package/dist/tools/output-schema/get-functionality-details.json +142 -0
  173. package/dist/tools/output-schema/index.d.ts +5 -0
  174. package/dist/tools/output-schema/index.js +15 -0
  175. package/dist/tools/output-schema/list-fiori-apps.json +41 -0
  176. package/dist/tools/output-schema/list-functionality.json +37 -0
  177. package/dist/tools/utils.d.ts +16 -0
  178. package/dist/tools/utils.js +74 -0
  179. package/dist/types.d.ts +170 -0
  180. package/dist/types.js +3 -0
  181. package/package.json +63 -0
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SectionAggregation = void 0;
7
+ const ObjectAggregation_1 = require("../ObjectAggregation");
8
+ const i18next_1 = __importDefault(require("i18next"));
9
+ const types_1 = require("../types");
10
+ /**
11
+ * Represents an aggregation for section objects.
12
+ */
13
+ class SectionAggregation extends ObjectAggregation_1.ObjectAggregation {
14
+ actions = [types_1.AggregationActions.Delete];
15
+ title;
16
+ id;
17
+ position;
18
+ data;
19
+ useDescriptionAsId;
20
+ isViewNode = true;
21
+ sortableCollection = 'sections';
22
+ /**
23
+ * Creates an instance of `SectionAggregation`.
24
+ *
25
+ * @param data Optional aggregation data object used to initialize properties.
26
+ * @param schema Optional JSON schema fragment associated with this aggregation.
27
+ */
28
+ constructor(data, schema) {
29
+ super(data, schema);
30
+ this.sortableItem = types_1.SortingOptions.Enabled;
31
+ }
32
+ /**
33
+ * Setter for title.
34
+ *
35
+ * @param title Title.
36
+ */
37
+ setTitle(title) {
38
+ this.title = title;
39
+ }
40
+ /**
41
+ * Setter for id.
42
+ *
43
+ * @param id Title.
44
+ */
45
+ setId(id) {
46
+ this.id = id;
47
+ }
48
+ /**
49
+ * Method returns display name of aggregation without applying i18n translation.
50
+ * Overwritten for section handling.
51
+ *
52
+ * @returns Display name of aggregation.
53
+ */
54
+ getRawDisplayName() {
55
+ return this.title || this.getSectionId() || super.getRawDisplayName();
56
+ }
57
+ /**
58
+ * Public method to read/determine section id.
59
+ *
60
+ * @param fallback Resolve id with V4 fallback solution by reading label/description.
61
+ * @returns Section id.
62
+ */
63
+ getSectionId(fallback = true) {
64
+ if (this.schema) {
65
+ if (this.schema.title?.startsWith(types_1.FacetTitlePrefix)) {
66
+ const parts = this.schema.title.split(types_1.FacetTitlePrefix);
67
+ if (parts.length > 1) {
68
+ return parts[parts.length - 1];
69
+ }
70
+ return parts[0];
71
+ }
72
+ else if (fallback && this.useDescriptionAsId && this.schema.description) {
73
+ // V4 specific part - if facet ID does not exist then id is label
74
+ return this.schema.description;
75
+ }
76
+ }
77
+ if (this.data && 'id' in this.data) {
78
+ return this.data['id'];
79
+ }
80
+ return undefined;
81
+ }
82
+ /**
83
+ * Public method to mark section as replaced with other section.
84
+ *
85
+ * @param replacedWith Section replaced with.
86
+ */
87
+ markAsReplaced(replacedWith) {
88
+ this.inactive = true;
89
+ this.additionalText = i18next_1.default.t('PAGE_EDITOR_OUTLINE_NODE_DESC_SECTION_REPLACED_WITH', {
90
+ section: replacedWith
91
+ });
92
+ }
93
+ /**
94
+ * Public method to mark section as custom section.
95
+ *
96
+ * @param data Configuration of section(segment of page config).
97
+ * @param i18nKey I18n custom key.
98
+ * @param goCodeAction Go to code action.
99
+ */
100
+ markAsCustomSection(data, i18nKey, goCodeAction) {
101
+ this.custom = true;
102
+ this.actions = [types_1.AggregationActions.Delete, goCodeAction || types_1.AggregationActions.OpenSource];
103
+ this.sortableItem = types_1.SortingOptions.Enabled;
104
+ this.additionalText = i18next_1.default.t('PAGE_EDITOR_OUTLINE_NODE_DESC_CUSTOM_SECTION');
105
+ this.data = data;
106
+ this.i18nKey = i18nKey;
107
+ }
108
+ /**
109
+ * Method parses object path key and returns field name / technical id.
110
+ *
111
+ * @returns Section id.
112
+ */
113
+ getTechnicalName() {
114
+ return this.getSectionId();
115
+ }
116
+ /**
117
+ * Protected method which returns name with additional formatting by removing 'SAP_ANNOTATION_NAMESPACE' from full name/id.
118
+ *
119
+ * @returns Name of aggregation.
120
+ */
121
+ getFormattedName() {
122
+ let name = this.name;
123
+ const replaceQuery = `${types_1.SAP_ANNOTATION_NAMESPACE}.`;
124
+ if (name?.includes(replaceQuery)) {
125
+ name = name.replace(replaceQuery, '');
126
+ }
127
+ return name;
128
+ }
129
+ }
130
+ exports.SectionAggregation = SectionAggregation;
131
+ //# sourceMappingURL=SectionAggregation.js.map
@@ -0,0 +1,135 @@
1
+ import type { PageEditAggregationData } from '../ObjectAggregation';
2
+ import { ObjectAggregation } from '../ObjectAggregation';
3
+ import type { PageData, CreationFormOptions, ModelParserParams, PageAnnotations, PropertyPath } from '../types';
4
+ import { AggregationCreationForm } from '../types';
5
+ import type { JSONSchema4 } from 'json-schema';
6
+ import type { PageConfig, PageType } from '@sap/ux-specification/dist/types/src';
7
+ type CustomSectionSchemaParserParams = ModelParserParams<ObjectAggregation> | undefined;
8
+ /**
9
+ * Represents an aggregation for sections objects.
10
+ */
11
+ export declare class SectionsAggregation extends ObjectAggregation {
12
+ private customSections;
13
+ private sections;
14
+ private sortingApproach;
15
+ allowedAnnotationCreationForms?: AggregationCreationForm[];
16
+ sortableCollection: string | undefined;
17
+ /**
18
+ * Creates an instance of `SectionsAggregation`.
19
+ *
20
+ * @param data Optional aggregation data object used to initialize properties.
21
+ * @param schema Optional JSON schema fragment associated with this aggregation.
22
+ */
23
+ constructor(data?: PageEditAggregationData, schema?: JSONSchema4);
24
+ /**
25
+ * Overwritten method for data update of object page sections
26
+ * Method receives current values for sections - loops custom sections array and appends existing/standard aggregations with custom section aggregations.
27
+ *
28
+ * @param data Data which should be used for value population.
29
+ * @param page Page config data.
30
+ * @param pageType Page type.
31
+ * @param path Aggregation path.
32
+ * @param annotations Page annotations.
33
+ * @param parser Model parser parameters.
34
+ */
35
+ updatePropertiesValues(data: PageData, page: PageConfig, pageType: PageType, path: PropertyPath, annotations?: PageAnnotations, parser?: CustomSectionSchemaParserParams): void;
36
+ /**
37
+ * Overwritten method which caled when properties and aggregation data was applied and updated.
38
+ * Code checks if need to disable deletion of last annotation node.
39
+ */
40
+ protected onPropertiesUpdated(): void;
41
+ /**
42
+ * Method traverses custom section with recursion.
43
+ * Reason why we need recursion is because in V4 - custom section can refference to each other.
44
+ *
45
+ * @param relatedFacet Facet id - method will traverso all section refferenced to passed id.
46
+ * @param callback Traverse callback method.
47
+ */
48
+ private traverseCustomSections;
49
+ /**
50
+ * Factory method which creates aggregation object for passed custom section.
51
+ *
52
+ * @param page Page config data.
53
+ * @param pageType Page type.
54
+ * @param path Aggregation path.
55
+ * @param parser Model parser parameters.
56
+ * @param sectionData Custom section data.
57
+ */
58
+ private customSectionFactory;
59
+ /**
60
+ * Method corrects children section data.
61
+ * Currently json schema for sections does not return labels for sections, but 'relatedFacet' schema data have it
62
+ * - we can map them and read label for 'relatedFacet'.
63
+ */
64
+ correctSectionData(): void;
65
+ /**
66
+ * Is section id matches related facet id.
67
+ *
68
+ * @param sectionId Section id.
69
+ * @param relatedFacet Related facet id.
70
+ * @returns True if section id matches passed related facet id.
71
+ */
72
+ isSectionMatchesRelatedFacet(sectionId?: string, relatedFacet?: string): boolean;
73
+ /**
74
+ * Determines the appropriate index at which a custom section should be inserted
75
+ * in the existing sections list based on its relative position and related facet.
76
+ * The function supports positioning the section before, after, or replacing an existing one.
77
+ * If no related facet is found, the section is added at the end.
78
+ *
79
+ * @param customSectionData Custom section data object.
80
+ * @returns The index in the sections array where the new custom section should be inserted.
81
+ */
82
+ private findSectionInsertPosition;
83
+ /**
84
+ * Finds the first section that matches the given related facet and returns its index and aggregation.
85
+ *
86
+ * @param relatedFacet The related facet identifier used to match against section IDs.
87
+ * @returns An object containing the matching section's index and aggregation.
88
+ */
89
+ private findReferenceSection;
90
+ /**
91
+ * Method receives custom section data and determines position of custom section in flat array.
92
+ * Also generates unique id if custom section has same values.
93
+ *
94
+ * @param customSectionData Section id.
95
+ * @returns Custom section id.
96
+ */
97
+ private storeSection;
98
+ /**
99
+ * Method returns available section id for candidate section id.
100
+ *
101
+ * @param sectionId Candidate section id.
102
+ * @returns Available section id.
103
+ */
104
+ getFreeSectionId(sectionId: string): string;
105
+ /**
106
+ * Checks whether the given position string matches any of the provided section positions.
107
+ *
108
+ * @param position A section position string (case-insensitive). Defaults to an empty string.
109
+ * @param matchingPositions One or more section positions to check against.
110
+ * @returns True if the position string includes any of the matching section positions; otherwise, false.
111
+ */
112
+ private checkRelatedPosition;
113
+ /**
114
+ * Method returns sorting/reorder approach - it can be different for V2 or V4.
115
+ *
116
+ * @returns Sorting approach.
117
+ */
118
+ private getSortingApproach;
119
+ /**
120
+ * Checks whether the section schema belongs to a Fiori Elements V4 application.
121
+ *
122
+ * @returns {boolean} True if the schema is for a V4 application.
123
+ */
124
+ private isV4;
125
+ /**
126
+ * Method provides creation options based on its related annotation node.
127
+ * Overwritten, specificly for sections - we should check dialogsContext to determine if creation enabled for AnalyticalChart form.
128
+ *
129
+ * @param annotations Page annotations.
130
+ * @returns Array of creation forms.
131
+ */
132
+ protected getNativeNodeCreationForms(annotations: PageAnnotations | undefined): CreationFormOptions[];
133
+ }
134
+ export {};
135
+ //# sourceMappingURL=SectionsAggregation.d.ts.map
@@ -0,0 +1,402 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SectionsAggregation = void 0;
7
+ const i18next_1 = __importDefault(require("i18next"));
8
+ const ObjectAggregation_1 = require("../ObjectAggregation");
9
+ const SectionAggregation_1 = require("./SectionAggregation");
10
+ const types_1 = require("../types");
11
+ const src_1 = require("@sap/ux-specification/dist/types/src");
12
+ const utils_1 = require("../utils");
13
+ const sort_1 = require("../utils/sort");
14
+ const macros_1 = require("../macros");
15
+ // Some interface of custom sections data - that interface should be on spec, but I can not use as it is V2/V4 specific
16
+ const CUSTOM_PROPERTY_NAME = 'custom';
17
+ /**
18
+ * Represents an aggregation for sections objects.
19
+ */
20
+ class SectionsAggregation extends ObjectAggregation_1.ObjectAggregation {
21
+ // Array of end result ordered sections
22
+ customSections = [];
23
+ sections = [];
24
+ sortingApproach = sort_1.SortingApproach.Normal;
25
+ allowedAnnotationCreationForms = undefined;
26
+ sortableCollection = 'sections';
27
+ /**
28
+ * Creates an instance of `SectionsAggregation`.
29
+ *
30
+ * @param data Optional aggregation data object used to initialize properties.
31
+ * @param schema Optional JSON schema fragment associated with this aggregation.
32
+ */
33
+ constructor(data, schema) {
34
+ super(data, schema);
35
+ // Child objects as section aggregation
36
+ this.childClass = SectionAggregation_1.SectionAggregation;
37
+ if (schema?.properties?.custom) {
38
+ // Custom creation form
39
+ this.schemaCreationForms = [
40
+ {
41
+ name: types_1.AggregationCreationForm.CustomSection,
42
+ kind: types_1.SCHEMA_CREATION_FORM,
43
+ title: 'PAGE_EDITOR_OUTLINE_ADD_CUSTOM_SECTIONS_TITLE',
44
+ disabled: false
45
+ }
46
+ ];
47
+ }
48
+ // Sortable
49
+ this.sortableList = true;
50
+ // i18n key
51
+ this.i18nKey = 'SECTIONS';
52
+ }
53
+ /**
54
+ * Overwritten method for data update of object page sections
55
+ * Method receives current values for sections - loops custom sections array and appends existing/standard aggregations with custom section aggregations.
56
+ *
57
+ * @param data Data which should be used for value population.
58
+ * @param page Page config data.
59
+ * @param pageType Page type.
60
+ * @param path Aggregation path.
61
+ * @param annotations Page annotations.
62
+ * @param parser Model parser parameters.
63
+ */
64
+ updatePropertiesValues(data, page, pageType, path, annotations, parser) {
65
+ super.updatePropertiesValues(data, page, pageType, path, annotations, parser);
66
+ // Hold custom section aggregation
67
+ this.formSchema = this.aggregations[CUSTOM_PROPERTY_NAME];
68
+ this.sortingApproach = this.getSortingApproach();
69
+ delete this.aggregations[CUSTOM_PROPERTY_NAME];
70
+ // Some code which can be removed when schema will return information about section label
71
+ // Correct section title using labels - section schema does not return that information, but that information is in related facets
72
+ this.correctSectionData();
73
+ // Handle custom columns
74
+ if (this.formSchema) {
75
+ this.customSections = data && CUSTOM_PROPERTY_NAME in data ? data[CUSTOM_PROPERTY_NAME] : [];
76
+ if (this.customSections.length) {
77
+ // Array with backend sections
78
+ this.sections = Object.keys(this.aggregations);
79
+ // Loop sections and create all related/associated custom sections
80
+ const sections = [...this.sections];
81
+ for (const i in sections) {
82
+ const targetSection = this.aggregations[sections[i]];
83
+ this.traverseCustomSections(targetSection.getSectionId() || sections[i], this.customSectionFactory.bind(this, page, pageType, path, parser));
84
+ }
85
+ // Detect orphan section - maybe we could mark with warning info them
86
+ const orphanSections = this.customSections.filter((customSectionData) => {
87
+ for (const key in this.aggregations) {
88
+ const aggregation = this.aggregations[key];
89
+ if (aggregation['data'] === customSectionData) {
90
+ return false;
91
+ }
92
+ }
93
+ return true;
94
+ });
95
+ for (const orphanSection of orphanSections) {
96
+ this.customSectionFactory(page, pageType, path, parser, orphanSection);
97
+ }
98
+ // Use correct ordering
99
+ const aggregations = this.aggregations;
100
+ this.aggregations = {};
101
+ let order = 0;
102
+ for (const section of this.sections) {
103
+ this.aggregations[section] = aggregations[section];
104
+ this.aggregations[section].order = order;
105
+ order++;
106
+ }
107
+ }
108
+ }
109
+ }
110
+ /**
111
+ * Overwritten method which caled when properties and aggregation data was applied and updated.
112
+ * Code checks if need to disable deletion of last annotation node.
113
+ */
114
+ onPropertiesUpdated() {
115
+ if (this.customSections.length && !this.isV4()) {
116
+ // Ensure that last native column is not deletable for v2
117
+ (0, utils_1.ensureLastNodeIsUndeletable)(this, 'SECTION_UNDELETABLE_LAST_NATIVE_NODE');
118
+ }
119
+ }
120
+ /**
121
+ * Method traverses custom section with recursion.
122
+ * Reason why we need recursion is because in V4 - custom section can refference to each other.
123
+ *
124
+ * @param relatedFacet Facet id - method will traverso all section refferenced to passed id.
125
+ * @param callback Traverse callback method.
126
+ */
127
+ traverseCustomSections(relatedFacet, callback) {
128
+ const relatedSections = this.customSections.filter((customSection) => {
129
+ return this.isSectionMatchesRelatedFacet(customSection.relatedFacet, relatedFacet);
130
+ });
131
+ const useRecursion = this.sortingApproach === sort_1.SortingApproach.WithIds;
132
+ for (const relatedSection of relatedSections) {
133
+ callback(relatedSection);
134
+ if (useRecursion && 'id' in relatedSection) {
135
+ // V4 logic - go with recursion, because facets can refference to other custom section.
136
+ this.traverseCustomSections(relatedSection['id'], callback);
137
+ }
138
+ }
139
+ }
140
+ /**
141
+ * Factory method which creates aggregation object for passed custom section.
142
+ *
143
+ * @param page Page config data.
144
+ * @param pageType Page type.
145
+ * @param path Aggregation path.
146
+ * @param parser Model parser parameters.
147
+ * @param sectionData Custom section data.
148
+ */
149
+ customSectionFactory(page, pageType, path, parser, sectionData) {
150
+ if (!this.formSchema) {
151
+ return;
152
+ }
153
+ const index = this.customSections.indexOf(sectionData);
154
+ // Create instance for Custom section aggregation by copying form schema
155
+ const customSection = this.formSchema.getCopy(SectionAggregation_1.SectionAggregation);
156
+ customSection.markAsCustomSection(sectionData, this.i18nKey);
157
+ if (parser) {
158
+ const fragmentData = sectionData;
159
+ const { fragmentName } = fragmentData;
160
+ // Get custom sections fragment from definitions schema
161
+ const customSectionFragmentDefinition = parser?.definitions[`CustomExtensionFragment<${fragmentName}>`];
162
+ // Check if custom section has controls aggregation
163
+ if (customSectionFragmentDefinition && customSection.aggregations.controls) {
164
+ const macrosAggregation = new macros_1.MacrosRootAggregation(undefined, customSectionFragmentDefinition);
165
+ customSection.addAggregation('controls', macrosAggregation, customSection.path, undefined, true);
166
+ // parseSchema with schema to fragment file from definitions
167
+ parser.parse(customSection.aggregations.controls, customSectionFragmentDefinition, undefined, undefined, path, {
168
+ filePath: customSectionFragmentDefinition.metadata?.filePath
169
+ });
170
+ }
171
+ }
172
+ customSection.updatePropertiesValues(sectionData, page, pageType, path, parser?.annotations);
173
+ customSection.setTitle(sectionData.title);
174
+ customSection.position = sectionData.relativePosition;
175
+ const customSectionId = this.storeSection(sectionData);
176
+ // Store in aggregation
177
+ this.addAggregation(customSectionId, customSection, this.path.concat([CUSTOM_PROPERTY_NAME, index]));
178
+ // Sync anchor property
179
+ for (const name of ObjectAggregation_1.CUSTOM_EXTENSION_ANCHOR_PROPERTIES) {
180
+ const property = customSection.properties[name];
181
+ if (property) {
182
+ property.schema = (0, utils_1.updateAnchorSchema)(customSection, property.schema);
183
+ }
184
+ }
185
+ // validate extension by checking related facets
186
+ const relatedFacets = this.formSchema.properties.relatedFacet?.schema.oneOf
187
+ ? this.formSchema.properties.relatedFacet?.schema.oneOf
188
+ : [];
189
+ const facetMatches = this.isV4() && !sectionData.relatedFacet
190
+ ? true
191
+ : relatedFacets.some((facet) => facet.const === sectionData.relatedFacet);
192
+ (0, utils_1.validateExtension)(customSection, facetMatches, i18next_1.default.t('PAGE_EDITOR_CUSTOM_SECTION_NO_FACET'));
193
+ }
194
+ /**
195
+ * Method corrects children section data.
196
+ * Currently json schema for sections does not return labels for sections, but 'relatedFacet' schema data have it
197
+ * - we can map them and read label for 'relatedFacet'.
198
+ */
199
+ correctSectionData() {
200
+ const relatedFacets = this.formSchema?.properties.relatedFacet?.schema.oneOf
201
+ ? this.formSchema.properties.relatedFacet.schema.oneOf
202
+ : [];
203
+ for (const key in this.aggregations) {
204
+ const section = this.aggregations[key];
205
+ if (section.custom) {
206
+ continue;
207
+ }
208
+ if (this.isV4()) {
209
+ section.useDescriptionAsId = true;
210
+ }
211
+ if (section.description) {
212
+ section.setTitle(section.description);
213
+ }
214
+ const sectionId = section.getSectionId() || key;
215
+ const facet = relatedFacets.find((facet) => this.isSectionMatchesRelatedFacet(sectionId, facet.const));
216
+ if (facet?.description) {
217
+ section.setTitle(facet.description);
218
+ section.setId(facet.const);
219
+ }
220
+ }
221
+ }
222
+ /**
223
+ * Is section id matches related facet id.
224
+ *
225
+ * @param sectionId Section id.
226
+ * @param relatedFacet Related facet id.
227
+ * @returns True if section id matches passed related facet id.
228
+ */
229
+ isSectionMatchesRelatedFacet(sectionId = '', relatedFacet = '') {
230
+ // At some point maybe we would not need it, but currently schema does not return same ids as custom section's facets
231
+ return sectionId.replace(/@/g, '') === relatedFacet.replace(/@/g, '');
232
+ }
233
+ /**
234
+ * Determines the appropriate index at which a custom section should be inserted
235
+ * in the existing sections list based on its relative position and related facet.
236
+ * The function supports positioning the section before, after, or replacing an existing one.
237
+ * If no related facet is found, the section is added at the end.
238
+ *
239
+ * @param customSectionData Custom section data object.
240
+ * @returns The index in the sections array where the new custom section should be inserted.
241
+ */
242
+ findSectionInsertPosition(customSectionData) {
243
+ const { relativePosition, relatedFacet } = customSectionData;
244
+ const isAfterOrReplace = this.checkRelatedPosition(relativePosition, src_1.v2.SectionPosition.AfterFacet, src_1.v2.SectionPosition.ReplaceFacet);
245
+ // Find first matching reference section
246
+ const foundSection = this.findReferenceSection(relatedFacet);
247
+ // Check if any reference section exists
248
+ if (!foundSection) {
249
+ return this.sections.length;
250
+ }
251
+ const isReplace = this.checkRelatedPosition(relativePosition, src_1.v2.SectionPosition.ReplaceFacet);
252
+ const isBefore = this.checkRelatedPosition(relativePosition, src_1.v2.SectionPosition.BeforeFacet);
253
+ const checkPositions = isReplace
254
+ ? [src_1.v2.SectionPosition.ReplaceFacet]
255
+ : [src_1.v2.SectionPosition.AfterFacet, src_1.v2.SectionPosition.ReplaceFacet];
256
+ let insertIndex = foundSection.index;
257
+ // Continue searching for insert position
258
+ if (isAfterOrReplace && this.sortingApproach === sort_1.SortingApproach.Normal) {
259
+ for (let j = insertIndex + 1; j < this.sections.length; j++) {
260
+ const tempAgg = this.aggregations[this.sections[j]];
261
+ if (tempAgg?.custom &&
262
+ tempAgg.position &&
263
+ this.checkRelatedPosition(tempAgg.position, ...checkPositions)) {
264
+ insertIndex++;
265
+ }
266
+ else {
267
+ break;
268
+ }
269
+ }
270
+ }
271
+ return insertIndex + (isBefore ? 0 : 1);
272
+ }
273
+ /**
274
+ * Finds the first section that matches the given related facet and returns its index and aggregation.
275
+ *
276
+ * @param relatedFacet The related facet identifier used to match against section IDs.
277
+ * @returns An object containing the matching section's index and aggregation.
278
+ */
279
+ findReferenceSection(relatedFacet) {
280
+ for (let i = 0; i < this.sections.length; i++) {
281
+ const key = this.sections[i];
282
+ const aggregation = this.aggregations[key];
283
+ const sectionId = aggregation?.getSectionId?.() ?? key;
284
+ if (sectionId && this.isSectionMatchesRelatedFacet(sectionId, relatedFacet)) {
285
+ return {
286
+ index: i,
287
+ aggregation
288
+ };
289
+ }
290
+ }
291
+ }
292
+ /**
293
+ * Method receives custom section data and determines position of custom section in flat array.
294
+ * Also generates unique id if custom section has same values.
295
+ *
296
+ * @param customSectionData Section id.
297
+ * @returns Custom section id.
298
+ */
299
+ storeSection(customSectionData) {
300
+ // Determine the insertion index based on relative position and related facet
301
+ const position = this.findSectionInsertPosition(customSectionData);
302
+ // Generate a unique section ID from provided ID or title
303
+ const customSectionId = this.getFreeSectionId('id' in customSectionData && typeof customSectionData.id === 'string'
304
+ ? customSectionData.id
305
+ : customSectionData.title);
306
+ // Insert the custom section into the list
307
+ this.sections.splice(position, 0, customSectionId);
308
+ // Mark the referenced section as replaced (if applicable)
309
+ const referenceSection = this.findReferenceSection(customSectionData.relatedFacet);
310
+ if (referenceSection?.aggregation &&
311
+ this.checkRelatedPosition(customSectionData.relativePosition, src_1.v2.SectionPosition.ReplaceFacet)) {
312
+ referenceSection.aggregation.markAsReplaced(customSectionData.title);
313
+ }
314
+ return customSectionId;
315
+ }
316
+ /**
317
+ * Method returns available section id for candidate section id.
318
+ *
319
+ * @param sectionId Candidate section id.
320
+ * @returns Available section id.
321
+ */
322
+ getFreeSectionId(sectionId) {
323
+ // Find available id
324
+ let counter = 1;
325
+ // If section id is undefined - use 'missingId' key.
326
+ const originalSectionId = sectionId ?? 'missingId';
327
+ sectionId = originalSectionId;
328
+ const keys = Object.keys(this.aggregations).filter((key) => {
329
+ return this.sections.indexOf(key) === -1;
330
+ });
331
+ const sectionIds = [...this.sections, ...keys];
332
+ while (sectionIds.includes(sectionId)) {
333
+ sectionId = originalSectionId + counter;
334
+ counter++;
335
+ }
336
+ return sectionId;
337
+ }
338
+ /**
339
+ * Checks whether the given position string matches any of the provided section positions.
340
+ *
341
+ * @param position A section position string (case-insensitive). Defaults to an empty string.
342
+ * @param matchingPositions One or more section positions to check against.
343
+ * @returns True if the position string includes any of the matching section positions; otherwise, false.
344
+ */
345
+ checkRelatedPosition(position = '', ...matchingPositions) {
346
+ const positionQuery = new Map([
347
+ [src_1.v2.SectionPosition.AfterFacet, 'after'],
348
+ [src_1.v2.SectionPosition.BeforeFacet, 'before'],
349
+ [src_1.v2.SectionPosition.ReplaceFacet, 'replace']
350
+ ]);
351
+ position = position.toLowerCase();
352
+ for (const checkPosition of matchingPositions) {
353
+ const query = positionQuery.get(checkPosition);
354
+ if (query && position.includes(query)) {
355
+ return true;
356
+ }
357
+ }
358
+ return false;
359
+ }
360
+ /**
361
+ * Method returns sorting/reorder approach - it can be different for V2 or V4.
362
+ *
363
+ * @returns Sorting approach.
364
+ */
365
+ getSortingApproach() {
366
+ if (this.isV4()) {
367
+ return sort_1.SortingApproach.WithIds;
368
+ }
369
+ return sort_1.SortingApproach.Normal;
370
+ }
371
+ /**
372
+ * Checks whether the section schema belongs to a Fiori Elements V4 application.
373
+ *
374
+ * @returns {boolean} True if the schema is for a V4 application.
375
+ */
376
+ isV4() {
377
+ return !!this.formSchema?.properties.id;
378
+ }
379
+ /**
380
+ * Method provides creation options based on its related annotation node.
381
+ * Overwritten, specificly for sections - we should check dialogsContext to determine if creation enabled for AnalyticalChart form.
382
+ *
383
+ * @param annotations Page annotations.
384
+ * @returns Array of creation forms.
385
+ */
386
+ getNativeNodeCreationForms(annotations) {
387
+ if (!annotations) {
388
+ return [];
389
+ }
390
+ const forms = super.getNativeNodeCreationForms(annotations);
391
+ const chartForm = forms.find((form) => form.name === types_1.AggregationCreationForm.AnalyticalChart);
392
+ if (chartForm && !chartForm.disabled) {
393
+ chartForm.disabled = !annotations.dialogsContext?.analyticalChartSupport?.creationEnabled;
394
+ if (annotations.dialogsContext?.analyticalChartSupport?.creationTooltip) {
395
+ chartForm.disabledTitle = annotations.dialogsContext.analyticalChartSupport.creationTooltip;
396
+ }
397
+ }
398
+ return forms;
399
+ }
400
+ }
401
+ exports.SectionsAggregation = SectionsAggregation;
402
+ //# sourceMappingURL=SectionsAggregation.js.map