Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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 @@ -259,6 +259,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,14 +22,24 @@ 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);
if (templateName) {
return { templateName };
}
if (controlType && targetAggregation) {
return { targetAggregation, controlType };
}
const viewName = targetControl ? (findViewByControl(targetControl)?.getViewName() ?? '') : '';

// Return additional info if we have either templateName or all required properties
if (templateName || (controlType && targetAggregation && viewName)) {
const result: AddXMLAdditionalInfo = {};
if (templateName) {
result.templateName = templateName;
}
if (controlType && targetAggregation && viewName) {
result.targetAggregation = targetAggregation;
result.controlType = controlType;
result.viewName = viewName;
}
return result;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to scale well. Next time we need to add something else we'll need to add another set of conditions which are repeated in two places. Maybe we can just check if there are any keys set before we return?

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in: 5053c37

return undefined;
}

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 | 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('sap.ui.core.mvc.View', control)) {
return control as View;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (isA('sap.ui.core.mvc.View', control)) {
return control as View;
}
if (isA<View>('sap.ui.core.mvc.View', control)) {
return control;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in: 5053c37

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
Loading