## 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>
155 lines
4.7 KiB
TypeScript
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;
|
|
};
|