Skip to content

Commit

Permalink
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
Browse files Browse the repository at this point in the history
…o action-redesign/gsheets
  • Loading branch information
ankitakinger committed Sep 11, 2024
2 parents 39ed64a + 91fd967 commit 578b1ca
Show file tree
Hide file tree
Showing 25 changed files with 621 additions and 468 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/ci-test-limited-with-count.yml
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,12 @@ jobs:
npx cypress-repeat-pro run -n ${{ inputs.run_count }} --force \
--spec ${{ env.specs_to_run }} \
--config-file "cypress_ci_custom.config.ts"
cat cy-repeat-summary.txt
cat cy-repeat-summary.txt
# Check if "Total Failed: 0" is present
if ! grep -q "Total Failed: 0" cy-repeat-summary.txt; then
echo "Tests failed, failing the GitHub Action."
exit 1 # Fails the step if tests failed
fi
- name: Trim number of cypress log files
if: failure()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ describe(
});

it("6. should check that on option select is working", () => {
_.agHelper.CheckForPageSaveError();
featureFlagIntercept({ release_table_cell_label_value_enabled: true });
cy.openPropertyPane("tablewidgetv2");
cy.editColumn("step");
Expand Down
8 changes: 3 additions & 5 deletions app/client/cypress/e2e/Sanity/Datasources/GraphQL_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ describe(
});

apiPage.SelectPaneTab("Authentication");
agHelper.ClickButton("Save as datasource");
agHelper.GetNClick(locators._saveDatasource);

agHelper.AssertText(
locators._inputFieldByName("URL") + "//" + locators._inputField,
Expand All @@ -296,16 +296,14 @@ describe(
// });
dataSources.SaveDatasource();
agHelper.ValidateToastMessage("datasource created");
agHelper.AssertElementVisibility(
locators._buttonByText("Edit datasource"),
);
agHelper.AssertElementVisibility(locators._saveDatasource);
apiPage.SelectPaneTab("Body");
dataSources.UpdateGraphqlQueryAndVariable({
query: GRAPHQL_QUERY,
variable: GRAPHQL_VARIABLES,
});
apiPage.RunAPI();
agHelper.ClickButton("Edit datasource");
agHelper.GetNClick(locators._saveDatasource);
dataSources.AssertDataSourceInfo([
dataManager.dsValues[
dataManager.defaultEnviorment
Expand Down
1 change: 1 addition & 0 deletions app/client/cypress/support/Objects/CommonLocators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,5 @@ export class CommonLocators {
errorPageDescription = ".t--error-page-description";
_selectClearButton_testId = "selectbutton.btn.cancel";
_selectClearButton_dataTestId = `[data-testid="${this._selectClearButton_testId}"]`;
_saveDatasource = `[data-testid='t--store-as-datasource']`;
}
4 changes: 2 additions & 2 deletions app/client/src/ce/constants/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ export const DATASOURCE_UPDATE = (dsName: string) =>
`${dsName} datasource updated successfully`;
export const DATASOURCE_VALID = (dsName: string) =>
`${dsName} datasource is valid`;
export const EDIT_DATASOURCE = () => "Edit datasource";
export const SAVE_DATASOURCE = () => "Save as datasource";
export const EDIT_DATASOURCE = () => "Edit";
export const SAVE_DATASOURCE = () => "Save";
export const SAVE_DATASOURCE_MESSAGE = () =>
"Save the URL as a datasource to access authentication settings";
export const EDIT_DATASOURCE_MESSAGE = () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ function StoreAsDatasource(props: storeDataSourceProps) {
return (
<Button
className="t--store-as-datasource"
data-testid="t--store-as-datasource"
isDisabled={!props.enable}
kind="secondary"
onClick={saveOrEditDatasource}
size="md"
startIcon={props.shouldSave ? "cloud" : "pencil-line"}
startIcon={props.shouldSave ? "database-2-line" : "pencil-line"}
>
{props.shouldSave
? createMessage(SAVE_DATASOURCE)
Expand Down
21 changes: 20 additions & 1 deletion app/client/src/entities/DependencyMap/DependencyMapUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class DependencyMapUtils {
return { success: false, cyclicNode: node, error };
}
}

// this function links childNode to its parent as a dependency for the entire dependencyGraph
static makeParentsDependOnChildren(dependencyMap: DependencyMap) {
const dependencies = dependencyMap.rawDependencies;
for (const [node, deps] of dependencies.entries()) {
Expand All @@ -49,6 +49,25 @@ export class DependencyMapUtils {
return dependencyMap;
}

// this function links childNode to its parent as a dependency for only affectedNodes in the graph
static linkAffectedChildNodesToParent(
dependencyMap: DependencyMap,
affectedSet: Set<string>,
) {
const dependencies = dependencyMap.rawDependencies;
for (const [node, deps] of dependencies.entries()) {
if (affectedSet.has(node)) {
DependencyMapUtils.makeParentsDependOnChild(dependencyMap, node);
}
deps.forEach((dep) => {
if (affectedSet.has(dep)) {
DependencyMapUtils.makeParentsDependOnChild(dependencyMap, dep);
}
});
}
return dependencyMap;
}

static makeParentsDependOnChild = (
dependencyMap: DependencyMap,
child: string,
Expand Down
64 changes: 64 additions & 0 deletions app/client/src/entities/DependencyMap/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2708,6 +2708,70 @@ describe("Tests for DependencyMapUtils", () => {
"Api1",
]);
}
describe("linkAffectedChildNodesToParent", () => {
const createSomeDependencyMap = () => {
const dependencyMap = new DependencyMap();
dependencyMap.addNodes({
tableWidget: true,
apiData: true,
"tableWidget.tableData": true,
"apiData.data": true,
"apiData.allData": true,
"apiData.allData.paginatedData": true,
});
dependencyMap.addDependency("tableWidget", ["tableWidget.tableData"]);
return dependencyMap;
};

test("should link child node to its parentNode as a dependant", () => {
const dependencyMap = createSomeDependencyMap();
dependencyMap.addDependency("tableWidget.tableData", ["apiData.data"]);
// although "apiData.data" was attached as a dependency to "tableWidget.tableData", it's parent "apiData" also needs to be linked to "apiData.data"
expect(dependencyMap.rawDependencies.get("apiData")).toEqual(undefined);
const affectedNodes = new Set(["apiData.data"]);
DependencyMapUtils.linkAffectedChildNodesToParent(
dependencyMap,
affectedNodes,
);
// after linkAffectedChildNodesToParent execution "apiData" does get linked to "apiData.data"
expect(dependencyMap.rawDependencies.get("apiData")).toEqual(
new Set(["apiData.data"]),
);
});
test("should not link child node to its parentNode as a dependant when the child node is not affected ", () => {
const dependencyMap = createSomeDependencyMap();
dependencyMap.addDependency("tableWidget.tableData", ["apiData.data"]);
// although "apiData.data" was attached as a dependency to "tableWidget.tableData", it's parent "apiData" also needs to be linked to "apiData.data"
expect(dependencyMap.rawDependencies.get("apiData")).toEqual(undefined);
const emptyAffectedNodes = new Set([]);
DependencyMapUtils.linkAffectedChildNodesToParent(
dependencyMap,
emptyAffectedNodes,
);
expect(dependencyMap.rawDependencies.get("apiData")).toEqual(undefined);
});

test("should link child node to its grand parent node as a dependant", () => {
const dependencyMap = createSomeDependencyMap();
dependencyMap.addDependency("tableWidget.tableData", [
"apiData.allData.paginatedData",
]);
expect(dependencyMap.rawDependencies.get("apiData")).toEqual(undefined);
const affectedNodes = new Set(["apiData.allData.paginatedData"]);

DependencyMapUtils.linkAffectedChildNodesToParent(
dependencyMap,
affectedNodes,
);
// after linkAffectedChildNodesToParent execution "apiData.allData.paginatedData" get linked to "apiData.data" and its parent "apiData.data" gets linked to "apiData"
expect(dependencyMap.getDirectDependencies("apiData")).toEqual([
"apiData.allData",
]);
expect(dependencyMap.getDirectDependencies("apiData.allData")).toEqual([
"apiData.allData.paginatedData",
]);
});
});
describe("makeParentsDependOnChild", () => {
const createSomeDependencyMap = () => {
const dependencyMap = new DependencyMap();
Expand Down
10 changes: 8 additions & 2 deletions app/client/src/sagas/ActionSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,13 +795,19 @@ function* copyActionSaga(

// @ts-expect-error: type mismatch Action vs ActionCreateUpdateResponse
yield put(copyActionSuccess(payload));
} catch (e) {
} catch (e: unknown) {
const actionName = actionObject ? actionObject.name : "";
const errorMessage =
e instanceof Error
? e.message
: createMessage(ERROR_ACTION_COPY_FAIL, actionName);
yield put(
copyActionError({
...action.payload,
show: true,
error: { message: createMessage(ERROR_ACTION_COPY_FAIL, actionName) },
error: {
message: errorMessage,
},
}),
);
}
Expand Down
27 changes: 17 additions & 10 deletions app/client/src/sagas/ErrorSagas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,16 @@ export function* validateResponse(
}

if (!response.responseMeta && response.status) {
throw Error(getErrorMessage(response.status, response.resourceType));
yield put({
type: ReduxActionErrorTypes.API_ERROR,
payload: {
error: new Error(
getErrorMessage(response.status, response.resourceType),
),
logToSentry,
show,
},
});
}

if (response.responseMeta.success) {
Expand Down Expand Up @@ -218,22 +227,20 @@ export interface ErrorActionPayload {
export function* errorSaga(errorAction: ReduxAction<ErrorActionPayload>) {
const effects = [ErrorEffectTypes.LOG_TO_CONSOLE];
const { payload, type } = errorAction;
const {
error,
logToDebugger,
logToSentry,
show = true,
sourceEntity,
} = payload || {};
const { error, logToDebugger, logToSentry, show, sourceEntity } =
payload || {};
const appMode: APP_MODE = yield select(getAppMode);

// "show" means show a toast. We check if the error has been asked to not been shown
// By making the default behaviour "true" we are ensuring undefined actions still pass through this check
if (show) {
// By checking undefined, undecided actions still pass through this check
if (show === undefined) {
// We want to show toasts for certain actions only so we avoid issues or if it is outside edit mode
if (shouldShowToast(type) || appMode !== APP_MODE.EDIT) {
effects.push(ErrorEffectTypes.SHOW_ALERT);
}
// If true is passed, show the error no matter what
} else if (show) {
effects.push(ErrorEffectTypes.SHOW_ALERT);
}

if (logToDebugger) {
Expand Down
66 changes: 55 additions & 11 deletions app/client/src/workers/common/DependencyMap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from "ee/workers/Evaluation/Actions";
import { isWidgetActionOrJsObject } from "ee/entities/DataTree/utils";
import { getValidEntityType } from "workers/common/DataTreeEvaluator/utils";
import type DependencyMap from "entities/DependencyMap";

export function createDependencyMap(
dataTreeEvalRef: DataTreeEvaluator,
Expand Down Expand Up @@ -72,6 +73,30 @@ export function createDependencyMap(
inverseDependencies: dependencyMap.inverseDependencies,
};
}
const addingAffectedNodesToList = (
affectedNodes: Set<string>,
addedNodes: string[],
) => {
addedNodes.forEach((v) => affectedNodes.add(v));
};

const addNodesToDependencyMap =
(affectedNodes: Set<string>, dependencyMap: DependencyMap) =>
(addedNodes: Record<string, true>, strict?: boolean) => {
const didUpdateDep = dependencyMap.addNodes(addedNodes, strict);
if (didUpdateDep) {
addingAffectedNodesToList(affectedNodes, Object.keys(addedNodes));
}
return didUpdateDep;
};

const setDependenciesToDependencyMap =
(affectedNodes: Set<string>, dependencyMap: DependencyMap) =>
(node: string, dependencies: string[]) => {
dependencyMap.addDependency(node, dependencies);

addingAffectedNodesToList(affectedNodes, [node, ...dependencies]);
};

export const updateDependencyMap = ({
configTree,
Expand All @@ -91,7 +116,15 @@ export const updateDependencyMap = ({
const { allKeys, dependencyMap, oldConfigTree, oldUnEvalTree } =
dataTreeEvalRef;
let { errors: dataTreeEvalErrors } = dataTreeEvalRef;

const affectedNodes: Set<string> = new Set();
const addNodesToDepedencyMapFn = addNodesToDependencyMap(
affectedNodes,
dependencyMap,
);
const setDependenciesToDepedencyMapFn = setDependenciesToDependencyMap(
affectedNodes,
dependencyMap,
);
translatedDiffs.forEach((dataTreeDiff) => {
const {
event,
Expand All @@ -117,15 +150,18 @@ export const updateDependencyMap = ({
});
// If a new entity is added, add setter functions to all nodes
if (entityName === fullPropertyPath) {
const didUpdateDep = dependencyMap.addNodes(
getEntitySetterFunctions(entityConfig, entityName, entity),
const addedNodes = getEntitySetterFunctions(
entityConfig,
entityName,
entity,
);
if (didUpdateDep) didUpdateDependencyMap = true;
didUpdateDependencyMap =
addNodesToDepedencyMapFn(addedNodes) || didUpdateDependencyMap;
}

const didUpdateDep = dependencyMap.addNodes(allAddedPaths, false);

if (didUpdateDep) didUpdateDependencyMap = true;
didUpdateDependencyMap =
addNodesToDepedencyMapFn(allAddedPaths, false) ||
didUpdateDependencyMap;

if (isWidgetActionOrJsObject(entity)) {
if (!isDynamicLeaf(unEvalDataTree, fullPropertyPath, configTree)) {
Expand All @@ -141,7 +177,9 @@ export const updateDependencyMap = ({
([path, pathDependencies]) => {
const { errors: extractDependencyErrors, references } =
extractInfoFromBindings(pathDependencies, allKeys);
dependencyMap.addDependency(path, references);

setDependenciesToDepedencyMapFn(path, references);

didUpdateDependencyMap = true;
dataTreeEvalErrors = dataTreeEvalErrors.concat(
extractDependencyErrors,
Expand All @@ -158,7 +196,9 @@ export const updateDependencyMap = ({
);
const { errors: extractDependencyErrors, references } =
extractInfoFromBindings(entityPathDependencies, allKeys);
dependencyMap.addDependency(fullPropertyPath, references);

setDependenciesToDepedencyMapFn(fullPropertyPath, references);

didUpdateDependencyMap = true;
dataTreeEvalErrors = dataTreeEvalErrors.concat(
extractDependencyErrors,
Expand Down Expand Up @@ -218,7 +258,8 @@ export const updateDependencyMap = ({
);
const { errors: extractDependencyErrors, references } =
extractInfoFromBindings(entityPathDependencies, allKeys);
dependencyMap.addDependency(fullPropertyPath, references);
setDependenciesToDepedencyMapFn(fullPropertyPath, references);

didUpdateDependencyMap = true;
dataTreeEvalErrors = dataTreeEvalErrors.concat(
extractDependencyErrors,
Expand All @@ -237,7 +278,10 @@ export const updateDependencyMap = ({
const updateChangedDependenciesStart = performance.now();

if (didUpdateDependencyMap) {
DependencyMapUtils.makeParentsDependOnChildren(dependencyMap);
DependencyMapUtils.linkAffectedChildNodesToParent(
dependencyMap,
affectedNodes,
);
dataTreeEvalRef.sortedDependencies = dataTreeEvalRef.sortDependencies(
dependencyMap,
translatedDiffs,
Expand Down
Loading

0 comments on commit 578b1ca

Please sign in to comment.