Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: CPE loading changes from backend and not from workspace #2429

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

mmilko01
Copy link
Contributor

@mmilko01 mmilko01 commented Oct 1, 2024

#2445

  • Adds the merged manifest in applicationDependencies of the sap-ushell-config in the html
  • Sets asyncHints.requests to an empty string for SAPUI5 versions lower than 1.72
  • Introduces a workspacePath URL parameter to the LREP request to allow for correctly setting the workspace path in case of Adaptation Project

Copy link

changeset-bot bot commented Oct 1, 2024

🦋 Changeset detected

Latest commit: dd8a125

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 15 packages
Name Type
@sap-ux/adp-tooling Patch
@sap-ux/axios-extension Patch
@sap-ux-private/preview-middleware-client Patch
@sap-ux/preview-middleware Patch
@sap-ux/create Patch
@sap-ux/abap-deploy-config-inquirer Patch
@sap-ux/app-config-writer Patch
@sap-ux/backend-proxy-middleware Patch
@sap-ux/deploy-tooling Patch
@sap-ux/environment-check Patch
@sap-ux/odata-service-inquirer Patch
@sap-ux/system-access Patch
@sap-ux/odata-cli Patch
@sap-ux/generator-simple-fe Patch
@sap-ux/abap-deploy-config-writer Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

@tobiasqueck tobiasqueck left a comment

Choose a reason for hiding this comment

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

Please see my inline comments

@mmilko01 mmilko01 marked this pull request as ready for review October 8, 2024 11:45
@mmilko01 mmilko01 requested review from a team as code owners October 8, 2024 11:45
Copy link
Contributor

@nikmace nikmace left a comment

Choose a reason for hiding this comment

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

Test snapshots do not reflect the changes I think, I only see {\"manifest\":true}}, but in the case of ADP there should be the descriptor, or at least its mock.

Please also add a short description of the changes in this PR.

Comment on lines 29 to 40
const getNestedProperty = (obj, target) =>
target in obj
? obj[target]
: Object.values(obj).reduce((acc, val) => {
if (acc !== undefined) return acc;
if (typeof val === 'object') return getNestedProperty(val, target);
}, undefined);

const asyncHints = getNestedProperty(window['sap-ushell-config'], 'asyncHints');
if (asyncHints && asyncHints.requests) {
asyncHints.requests = [];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The code here looks more complicated than it should be. First, .reduce() is intended for accumulating values, but here you just need to find and modify a property, this can be simplified.

Your code will continue to check all properties even after finding asyncHints. The .reduce() call may still iterate over other properties in the object, even though the target has already been located. This happens because .reduce() doesn't know that asyncHints has already been found. It will continue checking other values until the entire object is traversed.

Here is the suggestion (since you are not exporting this function anywhere and it is not reusable):

    const setRequestsToEmptyArray = (obj) => {
        if (!obj || typeof obj !== 'object') return;
        
        for (const key in obj) {
            if (key === 'asyncHints' && obj[key]?.requests) {
                obj[key].requests = [];
                return;
            }
            setRequestsToEmptyArray(obj[key]);
        }
    };
    
    setRequestsToEmptyArray(window['sap-ushell-config']);

This is easier to read and maintain.

But the complexity here is O(N), where N is the total number of properties across all levels. The function may need to visit every property in the entire object structure if the target property ('asyncHints') is not found until the last node.

What I am trying to say is, if you know the structure and it is constant then you can just do this:

if (
    window['sap-ushell-config']?.level1?.level2?.asyncHints?.requests
) {
    window['sap-ushell-config'].level1.level2.asyncHints.requests = [];
}

And it will be constant time complexity, O(1). Or you can use iterative approaches.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed, I changed the algorithm used for setting the nested property.
Fixed in: 57805ce

@nikmace nikmace self-requested a review October 10, 2024 06:24
Copy link
Contributor

@nikmace nikmace left a comment

Choose a reason for hiding this comment

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

Code looks good
Comments addressed, test for adding descriptor added
Excellent coverage
Did not test manually

Copy link

sonarcloud bot commented Oct 10, 2024

Copy link
Contributor

@tobiasqueck tobiasqueck left a comment

Choose a reason for hiding this comment

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

review feedback applied as requested.

Comment on lines +25 to +52
// For UI5 version 1.71 and below, we need to remove the asyncHints.requests to load the changes in an Adaptation project.
// This logic needs to be executed here to have a reliable check for UI5 version and remove the asyncHints.requests before the sandbox is loaded.
// The sandbox shell modifies the `window['sap-ushell-config']`.
if (majorUi5Version === 1 && minorUi5Version < 72) {
const setNestedProperty = (obj) => {
if (!obj || typeof obj !== 'object') return;

const stack = [obj];

while (stack.length > 0) {
const current = stack.pop();

if (current.asyncHints) {
if (current.asyncHints.requests) {
current.asyncHints.requests = [];
}
return;
}

for (const key in current) {
if (typeof current[key] === 'object' && current[key] !== null) {
stack.push(current[key]);
}
}
}
};
setNestedProperty(window['sap-ushell-config']['applications']);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we please have an own function for this and put the comment about what it does and why it's needed in the respective JSDoc? Including setNestedProperty into the ushellBootstrap function disrupts the readability of the code.

Suggested change
// For UI5 version 1.71 and below, we need to remove the asyncHints.requests to load the changes in an Adaptation project.
// This logic needs to be executed here to have a reliable check for UI5 version and remove the asyncHints.requests before the sandbox is loaded.
// The sandbox shell modifies the `window['sap-ushell-config']`.
if (majorUi5Version === 1 && minorUi5Version < 72) {
const setNestedProperty = (obj) => {
if (!obj || typeof obj !== 'object') return;
const stack = [obj];
while (stack.length > 0) {
const current = stack.pop();
if (current.asyncHints) {
if (current.asyncHints.requests) {
current.asyncHints.requests = [];
}
return;
}
for (const key in current) {
if (typeof current[key] === 'object' && current[key] !== null) {
stack.push(current[key]);
}
}
}
};
setNestedProperty(window['sap-ushell-config']['applications']);
}
if (majorUi5Version === 1 && minorUi5Version < 72) {
removeAsyncHintsRequests();
}
/**
 * For UI5 version 1.71 and below, we need to remove the asyncHints.requests
 * to load the changes in an Adaptation project.
 * This logic needs to be executed here to have a reliable check for
 * UI5 version and remove the asyncHints.requests before the sandbox is loaded.
 * The sandbox shell modifies the `window['sap-ushell-config']`.
 */
function removeAsyncHintsRequests() {
                const obj = window['sap-ushell-config']['applications'];

                if (!obj || typeof obj !== 'object') return;

                const stack = [obj];

                while (stack.length > 0) {
                    const current = stack.pop();

                    if (current.asyncHints) {
                        if (current.asyncHints.requests) {
                            current.asyncHints.requests = [];
                        }
                        return;
                    }

                    for (const key in current) {
                        if (typeof current[key] === 'object' && current[key] !== null) {
                            stack.push(current[key]);
                        }
                    }
                }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants