PromucFlow_constructor/app/client/src/sagas/helper.ts
subratadeypappu a480d4ff2e
feat: Store originalActionId as part of Action DTO for copied action (#25011)
## Description
To measure the impact of query modules in Appsmith. We need to track the
time a user takes to edit a copied query. Today, we do not have a
mechanism to understand if a query in question is a copied query. To fix
this, the data model of the Query action needs to change to include the
`originalQueryId` if a query is, in fact, a copied query.

- [ ] When a query is first copied, there will be no `originalActionId`
in the action object. In this scenario, the client will populate the
`originalActionId` field and call the POST API to create the copied
query.

- [ ] If the query is already a copied query, the client will duplicate
the value of the `originalActionId` when calling the POST API to create
the copied query.

|POST|`/api/v1/actions`|
----------|------|

### [Related discussion on

Notion](https://www.notion.so/appsmith/Backend-dependency-for-modules-instrumentation-889462d461844745be0a2599c8555ca5)

#### PR fixes following issue(s)
Fixes #24734 

#### Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video
>
>
#### Type of change
> Please delete options that are not relevant.
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- Chore (housekeeping or task changes that don't impact user perception)
- This change requires a documentation update
>
>
>
## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [x] Manual
- [x] JUnit
- [ ] Jest
- [ ] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed

> Pull Request Template
>
> Use this template to quickly create a well written pull request.
Delete all quotes before creating the pull request.
>
## Description
> Add a TL;DR when description is extra long (helps content team)
>
> Please include a summary of the changes and which issue has been
fixed. Please also include relevant motivation
> and context. List any dependencies that are required for this change
>
> Links to Notion, Figma or any other documents that might be relevant
to the PR
>
>
#### PR fixes following issue(s)
Fixes # (issue number)
> if no issue exists, please create an issue and ask the maintainers
about this first
>
>
#### Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video
>
>
#### Type of change
> Please delete options that are not relevant.
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- Chore (housekeeping or task changes that don't impact user perception)
- This change requires a documentation update
>
>
>
## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [ ] Manual
- [ ] Jest
- [ ] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed

---------

Co-authored-by: Abhinav Jha <abhinav@appsmith.com>
2023-07-04 13:42:09 +06:00

155 lines
4.7 KiB
TypeScript

import { createMessage } from "@appsmith/constants/messages";
import type { LayoutOnLoadActionErrors } from "constants/AppsmithActionConstants/ActionConstants";
import type {
FormEvalOutput,
ConditionalOutput,
} from "reducers/evaluationReducers/formEvaluationReducer";
import AppsmithConsole from "utils/AppsmithConsole";
import LOG_TYPE from "entities/AppsmithConsole/logtype";
import type { Log } from "entities/AppsmithConsole";
import {
ENTITY_TYPE,
LOG_CATEGORY,
PLATFORM_ERROR,
Severity,
} from "entities/AppsmithConsole";
import { toast } from "design-system";
import {
ReduxActionTypes,
type ReduxActionType,
} from "@appsmith/constants/ReduxActionConstants";
import type { Action } from "entities/Action";
import get from "lodash/get";
import set from "lodash/set";
import log from "loglevel";
// function to extract all objects that have dynamic values
export const extractFetchDynamicValueFormConfigs = (
evalOutput: FormEvalOutput,
) => {
let output: Record<string, ConditionalOutput> = {};
Object.entries(evalOutput).forEach(([key, value]) => {
if ("fetchDynamicValues" in value && !!value.fetchDynamicValues) {
output = { ...output, [key]: value };
}
});
return output;
};
// Function to extract all the objects that have to fetch dynamic values
export const extractQueueOfValuesToBeFetched = (evalOutput: FormEvalOutput) => {
let output: Record<string, ConditionalOutput> = {};
Object.entries(evalOutput).forEach(([key, value]) => {
if (
"fetchDynamicValues" in value &&
!!value.fetchDynamicValues &&
"allowedToFetch" in value.fetchDynamicValues &&
value.fetchDynamicValues.allowedToFetch
) {
output = { ...output, [key]: value };
}
});
return output;
};
/**
* Function checks if in API response, cyclic dependency issues are there or not
*
* @param layoutErrors - array of cyclical dependency issues
* @returns boolean
*/
const checkIfNoCyclicDependencyErrors = (
layoutErrors?: Array<LayoutOnLoadActionErrors>,
): boolean => {
return !layoutErrors || (!!layoutErrors && layoutErrors.length === 0);
};
/**
* // Function logs all cyclic dependency errors in debugger
*
* @param layoutErrors - array of cyclical dependency issues
*/
const logCyclicDependecyErrors = (
layoutErrors?: Array<LayoutOnLoadActionErrors>,
) => {
if (!!layoutErrors) {
for (let index = 0; index < layoutErrors.length; index++) {
toast.show(
createMessage(() => {
return layoutErrors[index]?.errorType;
}),
{
kind: "error",
},
);
}
AppsmithConsole.addLogs(
layoutErrors.reduce((acc: Log[], error: LayoutOnLoadActionErrors) => {
acc.push({
severity: Severity.ERROR,
category: LOG_CATEGORY.PLATFORM_GENERATED,
timestamp: Date.now().toString(),
id: error?.code?.toString(),
logType: LOG_TYPE.CYCLIC_DEPENDENCY_ERROR,
text: !!error.message ? error.message : error.errorType,
messages: [
{
message: {
name: "CyclicalDependencyError",
message: !!error.message ? error.message : error.errorType,
},
type: PLATFORM_ERROR.PLUGIN_EXECUTION,
},
],
source: {
type: ENTITY_TYPE.ACTION,
name: error?.code?.toString(),
id: error?.code?.toString(),
},
isExpanded: false,
});
return acc;
}, []),
);
}
};
/**
* // Function checks and logs cyclic depedency errors
*
* @param layoutErrors - array of cyclical dependency issues
*/
export const checkAndLogErrorsIfCyclicDependency = (
layoutErrors?: Array<LayoutOnLoadActionErrors>,
) => {
if (!checkIfNoCyclicDependencyErrors(layoutErrors)) {
logCyclicDependecyErrors(layoutErrors);
}
};
export const RequestPayloadAnalyticsPath = "eventData.analyticsData";
/**
* [Mutation] Utility to enhance request payload with event data, based on the Redux action type
* @param payload : Payload to be enhanced
* @param type : Redux action type
* @returns : Mutated payload with the `eventData` object
*/
export const enhanceRequestPayloadWithEventData = (
payload: unknown,
type: ReduxActionType,
) => {
try {
switch (type) {
case ReduxActionTypes.COPY_ACTION_INIT:
const actionObject = payload as Action;
const path = `${RequestPayloadAnalyticsPath}.originalActionId`;
const originalActionId = get(actionObject, path, actionObject.id);
if (originalActionId !== undefined)
return set(actionObject, path, originalActionId);
}
} catch (e) {
log.error("Failed to enhance payload with event data");
}
return payload;
};