Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/shaggy-toys-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@sap-ux-private/preview-middleware-client': patch
'@sap-ux/adp-tooling': patch
'@sap-ux/preview-middleware': patch
---

Store fragment parent control info in fragment body
9 changes: 8 additions & 1 deletion packages/adp-tooling/src/preview/change-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,21 @@ export function addXmlFragment(
if (templateConfig) {
const fragmentTemplatePath = join(__dirname, '../../templates/rta', templateConfig.path);
const text = fs.read(fragmentTemplatePath);
const template = render(text, templateConfig.getData(change));
const changeTemplate = {
...templateConfig.getData(change),
viewName: additionalChangeInfo?.viewName,
targetAggregation: additionalChangeInfo?.targetAggregation,
controlType: additionalChangeInfo?.controlType
};
const template = render(text, changeTemplate);
fs.write(fullPath, template);
} else {
// use default fragment template
const templateName = 'fragment.xml'; /* TemplateFileName.Fragment */
const fragmentTemplatePath = join(__dirname, '../../templates/rta', templateName);
const text = fs.read(fragmentTemplatePath);
const template = render(text, {
viewName: additionalChangeInfo?.viewName,
targetAggregation: additionalChangeInfo?.targetAggregation,
controlType: additionalChangeInfo?.controlType
});
Expand Down
1 change: 1 addition & 0 deletions packages/adp-tooling/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ export interface CommonAdditionalChangeInfoProperties {
templateName?: string;
targetAggregation?: string;
controlType?: string;
viewName?: string;
}

export interface ManifestChangeProperties {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<!-- Use stable and unique id's!-->
<core:FragmentDefinition xmlns="sap.m" xmlns:table="sap.ui.table" xmlns:smartfield="sap.ui.comp.smartfield" xmlns:core="sap.ui.core">
<core:FragmentDefinition xmlns="sap.m" xmlns:table="sap.ui.table" xmlns:smartfield="sap.ui.comp.smartfield" xmlns:core="sap.ui.core"><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<table:AnalyticalColumn
grouped="false"
autoResizable="true"
Expand Down
7 changes: 5 additions & 2 deletions packages/adp-tooling/templates/rta/common/custom-action.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
<!-- add your xml here -->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<!-- add your xml here -->
<Button text="New Button" id="<%- ids.toolbarActionButton %>"></Button>
</core:FragmentDefinition>
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<!-- Use stable and unique id's!-->
<core:FragmentDefinition xmlns="sap.m" xmlns:table="sap.ui.table" xmlns:smartfield="sap.ui.comp.smartfield" xmlns:core="sap.ui.core">
<core:FragmentDefinition xmlns="sap.m" xmlns:table="sap.ui.table" xmlns:smartfield="sap.ui.comp.smartfield" xmlns:core="sap.ui.core"><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<table:Column
autoResizable="true"
width="150px"
Expand Down
9 changes: 6 additions & 3 deletions packages/adp-tooling/templates/rta/common/header-field.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
xmlns:uxap="sap.uxap"
xmlns:core='sap.ui.core'
xmlns='sap.m'
>
<VBox id="<%- ids.vBoxContainer %>">
<Label id="<%- ids.label %>" text="New Field"></Label>
><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<VBox id="<%- ids.vBoxContainer %>">
<Label id="<%- ids.label %>" text="New Field"></Label>
</VBox>
</core:FragmentDefinition>
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
xmlns:uxap="sap.uxap"
xmlns:core='sap.ui.core'
xmlns='sap.m'
>
><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<uxap:ObjectPageSection
id="<%- ids.objectPageSection %>"
title="New Custom Section"
>
<uxap:ObjectPageSubSection id="<%- ids.objectPageSubSection %>">
<HBox id="<%- ids.hBox %>">
<!-- add your xml here -->
<!-- add your xml here -->
</HBox>
</uxap:ObjectPageSubSection>
</uxap:ObjectPageSection>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
<actiontoolbar:ActionToolbarAction xmlns:actiontoolbar="sap.ui.mdc.actiontoolbar" id="<%- ids.customToolbarAction%>" >
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<actiontoolbar:ActionToolbarAction xmlns:actiontoolbar="sap.ui.mdc.actiontoolbar" id="<%- ids.customToolbarAction%>" >
<Button xmlns:m="sap.m" id="<%- ids.customActionButton %>" visible="true" text="New Action" />
</actiontoolbar:ActionToolbarAction>
</core:FragmentDefinition>
6 changes: 3 additions & 3 deletions packages/adp-tooling/templates/rta/fragment.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'><% if (targetAggregation && controlType) { %>
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<!-- add your xml here -->

<!-- add your xml here -->
</core:FragmentDefinition>
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
<!-- add your xml here -->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<!-- add your xml here -->
<Text id="<%- ids.text %>" text="Sample data" />
</core:FragmentDefinition>
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
<!-- add your xml here -->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<!-- add your xml here -->
<Column id="<%- ids.column %>"
width="12em"
hAlign="Left"
Expand Down
7 changes: 5 additions & 2 deletions packages/adp-tooling/templates/rta/v4/custom-section.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
xmlns:core='sap.ui.core'
xmlns='sap.m'
>
<HBox id="<%- ids.hBox %>">
<!-- add your xml here -->
<HBox id="<%- ids.hBox %>"><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<!-- add your xml here -->
</HBox>
</core:FragmentDefinition>
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:table="sap.ui.mdc.table">
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:table="sap.ui.mdc.table"><% if (targetAggregation && controlType && viewName) { %>
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> --> <% } %>
<table:Column
id="<%- ids.column %>"
width="10%"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ describe('change-handler', () => {
mockFs.read.mockReturnValue(realTemplateContent);

addXmlFragment(projectPath, change, mockFs as unknown as Editor, mockLogger as unknown as Logger, {
viewName: 'name',
targetAggregation: 'content',
controlType: 'sampleType'
});
Expand All @@ -178,10 +179,10 @@ describe('change-handler', () => {
expect(mockFs.write.mock.calls[0][1]).toMatchInlineSnapshot(`
"<!-- Use stable and unique IDs!-->
<core:FragmentDefinition xmlns:core='sap.ui.core' xmlns='sap.m'>
<!-- viewName: name -->
<!-- controlType: sampleType -->
<!-- targetAggregation: content -->
<!-- add your xml here -->

<!-- add your xml here -->
</core:FragmentDefinition>
"
`);
Expand All @@ -196,6 +197,7 @@ describe('change-handler', () => {
mockFs.read.mockReturnValue(realTemplateContent);

addXmlFragment(projectPath, change, mockFs as unknown as Editor, mockLogger as unknown as Logger, {
viewName: 'name',
targetAggregation: 'content',
controlType: 'sampleType'
});
Expand Down Expand Up @@ -497,6 +499,44 @@ id="<%- ids.customActionButton %>"`);

expect(mockLogger.info).toHaveBeenCalledWith(`XML Fragment "${fragmentName}.fragment.xml" was created`);
});

it('should create fragment with both additional info properties and templateName', () => {
mockFs.exists.mockReturnValue(false);
mockFs.read.mockReturnValue(`
<!-- viewName: <%= viewName %> -->
<!-- controlType: <%= controlType %> -->
<!-- targetAggregation: <%= targetAggregation %> -->
id="<%- ids.customToolbarAction %>"
id="<%- ids.customActionButton %>"`);
addXmlFragment(projectPath, change, mockFs as unknown as Editor, mockLogger as unknown as Logger, {
viewName: 'name',
targetAggregation: 'content',
controlType: 'sampleType',
templateName: `TABLE_ACTION`
});

expect(mockFs.read).toHaveBeenCalled();
expect(
(mockFs.read.mock.calls[0][0] as string)
.replace(/\\/g, '/')
.endsWith('templates/rta/common/v4-table-action.xml')
).toBe(true);

expect(mockFs.write).toHaveBeenCalled();
expect(mockFs.write.mock.calls[0][0].replace(/\\/g, '/')).toMatchInlineSnapshot(
`"project/path/changes/Share.fragment.xml"`
);
expect(mockFs.write.mock.calls[0][1]).toMatchInlineSnapshot(`
"
<!-- viewName: name -->
<!-- controlType: sampleType -->
<!-- targetAggregation: content -->
id=\\"toolbarAction-30303030\\"
id=\\"btn-30303030\\""
`);

expect(mockLogger.info).toHaveBeenCalledWith(`XML Fragment "${fragmentName}.fragment.xml" was created`);
});
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import FlexChange from 'sap/ui/fl/Change';
import { getControlById } from '../../utils/core';
import { getControlById, findViewByControl } from '../../utils/core';
import {
ANALYTICAL_TABLE_TYPE,
GRID_TABLE_TYPE,
Expand All @@ -12,6 +12,7 @@ export type AddXMLAdditionalInfo = {
templateName?: string;
targetAggregation?: string;
controlType?: string;
viewName?: string;
};

export type AddXMLChangeContent = {
Expand All @@ -21,15 +22,22 @@ export type AddXMLChangeContent = {
export function getAddXMLAdditionalInfo(change: FlexChange<AddXMLChangeContent>): AddXMLAdditionalInfo | undefined {
const selectorId = change.getSelector()?.id ?? '';
const targetAggregation = change.getContent()?.targetAggregation ?? '';
const controlType = getControlById(selectorId)?.getMetadata().getName() ?? '';
const targetControl = getControlById(selectorId);
const controlType = targetControl?.getMetadata().getName() ?? '';
const templateName = getFragmentTemplateName(selectorId, targetAggregation);
const viewName = targetControl ? (findViewByControl(targetControl)?.getViewName() ?? '') : '';

const result: AddXMLAdditionalInfo = {};
if (templateName) {
return { templateName };
result.templateName = templateName;
}
if (controlType && targetAggregation) {
return { targetAggregation, controlType };
if (controlType && targetAggregation && viewName) {
result.targetAggregation = targetAggregation;
result.controlType = controlType;
result.viewName = viewName;
}
return undefined;

return Object.keys(result).length > 0 ? result : undefined;
}

export function getFragmentTemplateName(selectorId: string, targetAggregation: string): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@ export function setAdditionalChangeInfo(change: FlexChange<AddXMLChangeContent>
additionalChangeInfo = getAddXMLAdditionalInfo(change);
}

if (additionalChangeInfo && !additionalChangeInfoMap.get(key)) {
// in certain scenarios we explicitly set additional info e.g template when creating the change
// and that value should not be overwritten
additionalChangeInfoMap.set(key, additionalChangeInfo);
if (additionalChangeInfo) {
const existingInfo = additionalChangeInfoMap.get(key);
if (existingInfo) {
// Merge new info with existing info, keeping existing values and only adding new ones
const mergedInfo = {
...additionalChangeInfo,
...existingInfo
};
additionalChangeInfoMap.set(key, mergedInfo);
} else {
// No existing info, set the new info
additionalChangeInfoMap.set(key, additionalChangeInfo);
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions packages/preview-middleware-client/src/utils/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Component from 'sap/ui/core/Component';
import type { ID } from 'sap/ui/core/library';
import type ManagedObject from 'sap/ui/base/ManagedObject';
import Element from 'sap/ui/core/Element';
import View from 'sap/ui/core/mvc/View';

/**
* Gets Component by id.
Expand Down Expand Up @@ -71,6 +72,38 @@ export function hasParent(component: ManagedObject, parentIdToFind: string): boo
return hasParent(parent, parentIdToFind);
}

/**
* Utility function to safely call getParent on UI5 elements
* @param element UI5 element
* @returns parent element or null
*/
function getElementParent(element: Element | ManagedObject): ManagedObject | null {
if (typeof element.getParent === 'function') {
return element.getParent();
}
return null;
}

/**
* Finds the view that contains the given control.
*
* @param control - Control instance
* @returns View instance if found, undefined otherwise
*/
export function findViewByControl(control: Element | ManagedObject): View | undefined {
if (!control) {
return undefined;
}
if (isA<View>('sap.ui.core.mvc.View', control)) {
return control;
}
const parent = getElementParent(control);
if (!parent) {
return undefined;
}
return findViewByControl(parent);
}

export function findNestedElements(
ownerElement: Element,
candidates: Element[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ManagedObject from 'sap/ui/base/ManagedObject';
// add required functionality for testing here
export class ManagedObjectMock {
isA = jest.fn();
getParent = jest.fn();
}

export default ManagedObjectMock as unknown as ManagedObject & typeof ManagedObject;
Loading