feat: update response tab UI (#37640)

## Description
Query response tab UI update.

Fixes #35290

## Automation

/ok-to-test tags="@tag.All"


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new `QueryResponseTab` component for managing query
responses in the plugin action editor.
	- Added new icons for better visual representation in the application.
- Enhanced the `NoResponse` component for improved layout and messaging.
- Added a new constant for clearer user instructions on obtaining
responses.

- **Improvements**
- Updated button labels and component structures for clarity and
usability.
- Refined validation logic and error handling across various components.
- Enhanced styling and layout behavior in the `Table` and
`ActionExecutionInProgressView` components.
- Streamlined the `EntityBottomTabs` component's styling for
consistency.
- Adjusted the height of the response container during action execution.

- **Bug Fixes**
- Adjusted test cases to ensure accurate validation of response handling
and UI elements.

- **Chores**
- Deprecated older methods and constants to streamline code and enhance
maintainability.
	- Removed unused components to simplify the codebase.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Alex 2024-11-28 14:31:50 +03:00 committed by GitHub
parent 5484c40d11
commit 91f9c9b1ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 1136 additions and 890 deletions

View File

@ -45,9 +45,9 @@ describe(
EditorNavigation.SelectEntityByName(queryName, EntityType.Query);
BottomPane.response.switchToResponseTab();
BottomPane.response.openResponseTypeMenu();
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("TABLE"),
BottomPane.response.locators.responseTypeMenuItem("TABLE"),
);
});
});

View File

@ -30,32 +30,32 @@ describe(
//Add HSET
dataSources.CreateQueryAfterDSSaved();
dataSources.EnterQuery(hSetReceipe);
dataSources.RunQueryNVerifyResponseViews(1); //verify all views are returned!
dataSources.runQueryAndVerifyResponseViews(); //verify all views are returned!
dataSources.AssertQueryTableResponse(0, "4"); //Success response for 4 keys inserted via above HSET!
//Read only one key from above HSET
dataSources.EnterQuery(hGetKeys);
dataSources.RunQueryNVerifyResponseViews(1); //verify all views are returned!
dataSources.runQueryAndVerifyResponseViews(); //verify all views are returned!
dataSources.AssertQueryTableResponse(0, "Vegetable Stir Fry");
//Read more than one key from above HSET
dataSources.EnterQuery(hMGet);
dataSources.RunQueryNVerifyResponseViews(2);
dataSources.runQueryAndVerifyResponseViews({ count: 2 }); //verify all views are returned!
dataSources.AssertQueryTableResponse(0, "easy");
dataSources.AssertQueryTableResponse(1, "Vegetable Stir Fry");
//Update key value in HSET
dataSources.EnterQuery(hUpdate);
dataSources.RunQueryNVerifyResponseViews(1); //verify all views are returned!
dataSources.runQueryAndVerifyResponseViews(); //verify all views are returned!
//validate updated key
dataSources.EnterQuery(getUpdatedKey);
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryTableResponse(0, "medium");
//Get All keys from HSET
dataSources.EnterQuery(getAll);
dataSources.RunQueryNVerifyResponseViews(8); //4 keys, 4 values
dataSources.runQueryAndVerifyResponseViews({ count: 8 }); //4 keys, 4 values
dataSources.ReadQueryTableResponse(0).then(($cellData: any) => {
expect($cellData).to.be.oneOf([
"name",
@ -70,11 +70,11 @@ describe(
//Ading one more key/value to HSET
dataSources.EnterQuery(addNewKeyValue);
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
//Verify new key/value also added to HSET
dataSources.EnterQuery(getAll);
dataSources.RunQueryNVerifyResponseViews(10); //5 keys, 5 values
dataSources.runQueryAndVerifyResponseViews({ count: 10 }); //5 keys, 5 values
dataSources.ReadQueryTableResponse(0).then(($cellData: any) => {
expect($cellData).to.be.oneOf([
"name",
@ -87,11 +87,11 @@ describe(
//Deleting the Hash key
dataSources.EnterQuery(deletehKey);
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
//Verify Deletion is success
dataSources.EnterQuery(hGetKeys);
dataSources.RunQueryNVerifyResponseViews(); //5 keys, 5 values
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryTableResponse(0, "null");
// Delete the query & datasource

View File

@ -166,7 +166,7 @@ describe(
agHelper.FocusElement(locators._codeMirrorTextArea);
//agHelper.VerifyEvaluatedValue(tableCreateQuery); //failing sometimes!
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertTableInVirtuosoList(dsName, "productlines");
agHelper.ActionContextMenuWithInPane({
@ -282,7 +282,7 @@ describe(
agHelper.FocusElement(locators._codeMirrorTextArea);
//agHelper.VerifyEvaluatedValue(tableCreateQuery);
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertTableInVirtuosoList(dsName, "Stores", false);
});

View File

@ -68,7 +68,7 @@ describe(
agHelper.FocusElement(locators._codeMirrorTextArea);
//agHelper.VerifyEvaluatedValue(tableCreateQuery);
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertTableInVirtuosoList(dsName, "Stores");
agHelper.ActionContextMenuWithInPane({
@ -79,7 +79,7 @@ describe(
it("2. Validate Select record from Postgress datasource & verify query response", () => {
dataSources.CreateQueryForDS(dsName, "SELECT * FROM Stores LIMIT 10");
dataSources.RunQueryNVerifyResponseViews(10);
dataSources.runQueryAndVerifyResponseViews({ count: 10 });
dataSources.AssertQueryTableResponse(5, "2112");
dataSources.AssertQueryTableResponse(6, "Mike's Liquors");
// Commenting this deletion of query to make the generate crud work on the new page instead of the current page
@ -375,7 +375,7 @@ describe(
agHelper.FocusElement(locators._codeMirrorTextArea);
//agHelper.VerifyEvaluatedValue(tableCreateQuery);
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertTableInVirtuosoList(dsName, "Stores", false);
agHelper.ActionContextMenuWithInPane({

View File

@ -61,7 +61,7 @@ describe(
agHelper.FocusElement(locators._codeMirrorTextArea);
//agHelper.VerifyEvaluatedValue(tableCreateQuery); //failing sometimes!
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
});
it("2. Validate Select record from Postgress datasource & verify query response", () => {
@ -70,7 +70,7 @@ describe(
"public.vessels",
"Select",
);
dataSources.RunQueryNVerifyResponseViews(10);
dataSources.runQueryAndVerifyResponseViews({ count: 10 });
dataSources.AssertQueryTableResponse(0, "371681");
dataSources.AssertQueryTableResponse(6, "Passenger");
agHelper.ActionContextMenuWithInPane({
@ -617,7 +617,7 @@ describe(
dataSources.CreateQueryForDS(dsName, deleteTblQuery, "DropVessels");
agHelper.FocusElement(locators._codeMirrorTextArea);
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertTableInVirtuosoList(dsName, "public.vessels", false);
});

View File

@ -259,7 +259,7 @@ describe(
//Validating use of extention
query = `CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto"`;
dataSources.CreateQueryForDS(dsName, query, "verifyUUIDFunctions");
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryResponseHeaders(["affectedRows"]);
dataSources.ReadQueryTableResponse(0).then(($cellData) => {
expect($cellData).to.eq("0");
@ -297,7 +297,7 @@ describe(
//Validating Addition of new column taking default value form package method
query = `ALTER TABLE uuidtype ADD COLUMN newUUID uuid DEFAULT uuid_generate_v4();`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryResponseHeaders(["affectedRows"]);
dataSources.ReadQueryTableResponse(0).then(($cellData) => {
expect($cellData).to.eq("0");
@ -314,7 +314,7 @@ describe(
//Validating altering the new column default value to generate id from pgcrypto package
query = `ALTER TABLE uuidtype ALTER COLUMN newUUID SET DEFAULT gen_random_uuid();`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryResponseHeaders(["affectedRows"]);
dataSources.ReadQueryTableResponse(0).then(($cellData) => {
expect($cellData).to.eq("0");

View File

@ -16,7 +16,6 @@ import EditorNavigation, {
EntityType,
} from "../../../../support/Pages/EditorNavigation";
import PageList from "../../../../support/Pages/PageList";
import BottomPane from "../../../../support/Pages/IDE/BottomPane";
let dsName: any;
@ -333,7 +332,11 @@ describe(
"Find",
);
dataSources.ValidateNSelectDropdown("Command", "Find document(s)");
dataSources.RunQueryNVerifyResponseViews(1, false);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -352,7 +355,11 @@ describe(
directInput: false,
inputFieldName: "Query",
});
dataSources.RunQueryNVerifyResponseViews(1, false);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -430,12 +437,13 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.n)),
).to.eq(3);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -467,12 +475,13 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.nModified)),
).to.eq(0);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -514,12 +523,13 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.nModified)),
).to.eq(2);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -556,12 +566,13 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.nModified)),
).to.eq(1);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -587,12 +598,13 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.n)),
).to.eq(0);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -620,12 +632,13 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.n)),
).to.eq(1);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -657,12 +670,13 @@ describe(
2,
);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -682,12 +696,13 @@ describe(
7,
);
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -719,12 +734,13 @@ describe(
JSON.parse(JSON.stringify(resObj.response.body.data.body.values[1])),
).to.eql("51e062189c6ae665454e301d");
});
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -738,7 +754,12 @@ describe(
"Aggregate",
);
dataSources.ValidateNSelectDropdown("Command", "Aggregate");
dataSources.RunQueryNVerifyResponseViews(7, false);
dataSources.runQueryAndVerifyResponseViews({
count: 7,
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -899,7 +920,12 @@ describe(
"Find",
);
dataSources.ValidateNSelectDropdown("Command", "Find document(s)");
dataSources.RunQueryNVerifyResponseViews(4, false);
dataSources.runQueryAndVerifyResponseViews({
count: 4,
responseTypes: ["JSON", "RAW"],
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,

View File

@ -71,7 +71,7 @@ describe(
dataSources.EnterQuery(`{"find": "listingAndReviews","limit": 10}`);
agHelper.FocusElement(locators._codeMirrorTextArea);
dataSources.RunQuery();
BottomPane.response.validateRecordCount(10);
BottomPane.response.validateRecordCount({ count: 10, operator: "lte" });
cy.deleteQueryUsingContext();
});
@ -93,7 +93,7 @@ describe(
fieldValue: "listingAndReviews",
});
dataSources.RunQuery();
BottomPane.response.validateRecordCount(10);
BottomPane.response.validateRecordCount({ count: 10, operator: "lte" });
agHelper.EnterValue("{beds : {$lte: 2}}", {
propFieldName: "",
@ -101,7 +101,7 @@ describe(
inputFieldName: "Query",
});
dataSources.RunQuery();
BottomPane.response.validateRecordCount(10);
BottomPane.response.validateRecordCount({ count: 10, operator: "lte" });
agHelper.EnterValue("{number_of_reviews: -1}", {
propFieldName: "",
@ -109,7 +109,7 @@ describe(
inputFieldName: "Sort",
}); //sort descending
dataSources.RunQuery();
BottomPane.response.validateRecordCount(10);
BottomPane.response.validateRecordCount({ count: 10, operator: "lte" });
agHelper.EnterValue("{house_rules: 1, description:1}", {
propFieldName: "",
@ -131,7 +131,7 @@ describe(
"Response is not as expected for Find commmand with multiple conditions",
);
});
BottomPane.response.validateRecordCount(5);
BottomPane.response.validateRecordCount({ count: 5, operator: "lte" });
agHelper.EnterValue("2", {
propFieldName: "",
@ -145,7 +145,7 @@ describe(
"Response is not as expected for Find commmand with multiple conditions",
);
});
BottomPane.response.validateRecordCount(5);
BottomPane.response.validateRecordCount({ count: 5, operator: "lte" });
cy.deleteQueryUsingContext();
});
@ -433,7 +433,7 @@ describe(
);
dataSources.RunQuery();
BottomPane.response.validateRecordCount(3);
BottomPane.response.validateRecordCount({ count: 10, operator: "lte" });
dataSources.AssertTableInVirtuosoList(datasourceName, "NonAsciiTest");

View File

@ -77,7 +77,11 @@ describe(
"List files",
);
dataSources.RunQueryNVerifyResponseViews(100);
dataSources.runQueryAndVerifyResponseViews({
count: 100,
operator: "gte",
});
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
@ -191,8 +195,7 @@ describe(
cy.typeValueNValidate(fileName, formControls.s3ListPrefix);
dataSources.RunQuery({ toValidateResponse: false });
BottomPane.response.switchResponseType("TABLE");
BottomPane.response.switchResponseType("JSON");
BottomPane.response.selectResponseResponseTypeFromMenu("JSON");
cy.wait("@postExecute").then(({ response }) => {
expect(response.body.data.isExecutionSuccess).to.eq(true);

View File

@ -219,7 +219,7 @@ if (CURRENT_REPO == REPO.CE) {
}
INTO ${collectionName}`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryResponseHeaders([
"writesExecuted",
"writesIgnored",
@ -232,7 +232,7 @@ if (CURRENT_REPO == REPO.CE) {
FILTER place.type == "Natural"
RETURN { country: doc.country, name: place.name }`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews(5); //Verify all records are filtered
dataSources.runQueryAndVerifyResponseViews({ count: 5 }); //Verify all records are filtered
dataSources.AssertQueryTableResponse(0, "Japan");
dataSources.AssertQueryTableResponse(1, "Mount Fuji");
dataSources.AssertQueryTableResponse(6, "Brazil"); //Widget binding is verified here
@ -265,7 +265,7 @@ if (CURRENT_REPO == REPO.CE) {
}
IN ${collectionName}`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews();
dataSources.runQueryAndVerifyResponseViews();
dataSources.createQueryWithDatasourceSchemaTemplate(
dsName,
@ -276,7 +276,7 @@ if (CURRENT_REPO == REPO.CE) {
FILTER document._key == "1"
RETURN document`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews(1);
dataSources.runQueryAndVerifyResponseViews();
dataSources.AssertQueryTableResponse(3, "Australia");
//Delete record from collection
@ -287,7 +287,7 @@ if (CURRENT_REPO == REPO.CE) {
);
query = `REMOVE "1" in ${collectionName}`;
dataSources.EnterQuery(query);
dataSources.RunQueryNVerifyResponseViews(1); //Removing Australia
dataSources.runQueryAndVerifyResponseViews(); //Removing Australia
//Verify no records return for the deleted key
query = `FOR document IN ${collectionName}

View File

@ -42,7 +42,11 @@ describe(
'SELECT * FROM public."users" LIMIT 10;',
);
dataSources.RunQueryNVerifyResponseViews(); //minimum 1 rows are expected
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
}); //minimum 1 rows are expected
AppSidebar.navigate(AppSidebarButton.Data);
dataSources
.getDatasourceListItemDescription(mockDBName)
@ -57,7 +61,11 @@ describe(
expect(interception.request.body.source).to.equal("SELF");
});
dataSources.RunQueryNVerifyResponseViews(); //minimum 1 rows are expected
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
}); //minimum 1 rows are expected
AppSidebar.navigate(AppSidebarButton.Data);
dataSources
.getDatasourceListItemDescription(mockDBName)
@ -81,6 +89,12 @@ describe(
assertHelper.AssertNetworkStatus("@trigger");
dataSources.ValidateNSelectDropdown("Command", "Find document(s)");
dataSources.runQueryAndVerifyResponseViews({
count: 1,
operator: "gte",
responseTypes: ["JSON", "RAW"],
});
});
});
},

View File

@ -1133,6 +1133,7 @@ export class DataSources {
this.assertHelper.AssertNetworkStatus("@saveAction", 200);
}
/** @deprecated */
public RunQueryNVerifyResponseViews(
expectedRecordsCount = 1,
tableCheck = true,
@ -1149,7 +1150,35 @@ export class DataSources {
BottomPane.response.getResponseTypeSelector("RAW"),
);
}
BottomPane.response.validateRecordCount(expectedRecordsCount);
}
public runQueryAndVerifyResponseViews({
count = 1,
operator = "eq",
responseTypes = ["TABLE", "JSON", "RAW"],
}: {
count?: number;
operator?: Parameters<
typeof BottomPane.response.validateRecordCount
>[0]["operator"];
responseTypes?: ("TABLE" | "JSON" | "RAW")[];
} = {}) {
this.RunQuery();
BottomPane.response.openResponseTypeMenu();
responseTypes.forEach((responseType) => {
this.agHelper.AssertElementVisibility(
BottomPane.response.locators.responseTypeMenuItem(responseType),
);
});
BottomPane.response.closeResponseTypeMenu();
BottomPane.response.validateRecordCount({
count,
operator,
});
}
public CreateDataSource(

View File

@ -1,21 +1,85 @@
type ComparisonOperator = "eq" | "gt" | "gte" | "lt" | "lte";
interface ValidationParams {
count: number;
operator?: ComparisonOperator;
}
class Response {
private ResponseTab = "//button[@data-testid='t--tab-RESPONSE_TAB']";
public locators = {
responseTab: "[data-testid='t--tab-RESPONSE_TAB']",
responseDataContainer: "[data-testid='t--query-response-data-container']",
responseTypeMenuTrigger: "[data-testid='t--query-response-type-trigger']",
responseRecordCount: "[data-testid='t--query-response-record-count']",
public switchToResponseTab(): void {
cy.xpath(this.ResponseTab).click({ force: true });
}
/** @deprecated */
responseType(type: string): string {
return `//div[@data-testid='t--response-tab-segmented-control']//span[text()='${type}']`;
},
public getResponseTypeSelector(type: string): string {
return `//div[@data-testid='t--response-tab-segmented-control']//span[text()='${type}']`;
}
responseTypeMenuItem(type: string) {
return `[data-testid="t--query-response-type-menu-item"][data-value="${type}"]`;
},
};
/** @deprecated: method will be deleted when segmented control in response pane is replaced */
public getResponseTypeSelector = this.locators.responseType;
/** @deprecated: method will be deleted when segmented control in response pane is replaced */
public switchResponseType(type: string): void {
this.switchToResponseTab();
cy.xpath(this.getResponseTypeSelector(type)).click({ force: true });
cy.xpath(this.locators.responseType(type)).click({ force: true });
}
// TODO: Implement this method when response UI is ready
public validateRecordCount(count: number): void {}
public switchToResponseTab(): void {
cy.get(this.locators.responseTab).click({ force: true });
}
public openResponseTypeMenu() {
cy.get(this.locators.responseDataContainer).realHover();
cy.get(this.locators.responseTypeMenuTrigger).click({ force: true });
}
public selectResponseResponseTypeFromMenu(type: string): void {
this.switchToResponseTab();
this.openResponseTypeMenu();
cy.get(this.locators.responseTypeMenuItem(type)).realClick();
}
public closeResponseTypeMenu() {
cy.get(this.locators.responseTypeMenuTrigger).realClick();
}
public validateRecordCount({
count,
operator = "eq",
}: ValidationParams): void {
cy.get(this.locators.responseRecordCount)
.invoke("text")
.then((text) => {
const extractedCount = parseInt(text.match(/\d+/)?.[0] || "0", 10);
switch (operator) {
case "eq":
expect(extractedCount).to.equal(count);
break;
case "gt":
expect(extractedCount).to.be.greaterThan(count);
break;
case "gte":
expect(extractedCount).to.be.at.least(count);
break;
case "lt":
expect(extractedCount).to.be.lessThan(count);
break;
case "lte":
expect(extractedCount).to.be.at.most(count);
break;
default:
throw new Error(`Invalid comparison operator: ${operator}`);
}
});
}
}
export { Response };

View File

@ -1072,6 +1072,18 @@ const InputCursorMoveIcon = importSvg(
async () => import("../__assets__/icons/ads/input-cursor-move.svg"),
);
const ContentTypeTable = importSvg(
async () => import("../__assets__/icons/ads/content-type-table.svg"),
);
const ContentTypeJson = importSvg(
async () => import("../__assets__/icons/ads/content-type-json.svg"),
);
const ContentTypeRaw = importSvg(
async () => import("../__assets__/icons/ads/content-type-raw.svg"),
);
import PlayIconPNG from "../__assets__/icons/control/play-icon.png";
function PlayIconPNGWrapper() {
@ -1085,134 +1097,168 @@ function PlayIconPNGWrapper() {
}
const ICON_LOOKUP = {
"delete-control": DeleteIcon,
"move-control": MoveIcon,
"edit-control": EditIcon,
"view-control": ViewIcon,
"more-vertical-control": MoreVerticalIcon,
"more-horizontal-control": OverflowMenuIcon,
"js-toggle": JsToggleIcon,
"increase-control": IncreaseIcon,
"decrease-control": DecreaseIcon,
"draggable-control": DraggableIcon,
"drag-handle": DragHandleIcon,
"close-control": CloseIcon,
"close-circle-control": CloseCircleIcon,
"account-box-line": AccountBoxLineIcon,
"add-box-line": AddBoxLineIcon,
"add-circle-control": AddCircleIcon,
"pick-my-location-selected-control": PickMyLocationSelectedIcon,
"settings-control": SettingsIcon,
"help-control": HelpIcon,
"play-video": PlayIconPNGWrapper,
"remove-control": RemoveIcon,
"drag-control": DragIcon,
"collapse-control": CollapseIcon,
"sort-control": SortIcon,
"edit-white": EditWhiteIcon,
"launch-control": LaunchIcon,
"add-line": AddLineIcon,
"add-more": AddMoreIcon,
"add-more-fill": AddMoreFillIcon,
"alert-fill": AlertFillIcon,
"alert-line": AlertLineIcon,
"align-center": AlignCenter,
"align-left": AlignLeft,
"align-right": AlignRight,
"apps-line": AppsLineIcon,
"arrow-down-s-fill": ArrowDownSFillIcon,
"arrow-down-s-line": ArrowDownSLineIcon,
"arrow-forward": ArrowForwardIcon,
"arrow-go-back": ArrowGoBackLineIcon,
"arrow-left": ArrowLeft,
"arrow-left-line": ArrowLeftLineIcon,
"arrow-left-s-line": ArrowLeftSLineIcon,
"arrow-right-line": ArrowRightLineIcon,
"arrow-right-s-fill": ArrowRightSFillIcon,
"arrow-right-s-line": ArrowRightSLineIcon,
"arrow-right-up-line": ArrowRightUpLineIcon,
"arrow-up-line": ArrowUpLineIcon,
"arrow-up-s-line": ArrowUpSLineIcon,
"back-control": BackIcon,
"show-column": EyeIcon,
"hide-column": EyeOffIcon,
"delete-column": DeleteColumnIcon,
"bold-font": BoldFontIcon,
underline: UnderlineIcon,
"italics-font": ItalicsFontIcon,
"center-align": CenterAlignIcon,
"left-align": LeftAlignIcon,
"right-align": RightAlignIcon,
"vertical-right": VerticalAlignRight,
"vertical-left": VerticalAlignLeft,
"vertical-top": VerticalAlignTop,
"vertical-bottom": VerticalAlignBottom,
"vertical-center": VerticalAlignCenter,
"copy-control": CopyIcon,
"copy2-control": Copy2Icon,
"cut-control": CutIcon,
"group-control": GroupIcon,
bullets: BulletsIcon,
"divider-cap-right": DividerCapRightIcon,
"divider-cap-left": DividerCapLeftIcon,
"divider-cap-all": DividerCapAllIcon,
"bill-line": BillLineIcon,
"bind-data-control": TrendingFlat,
"icon-align-left": AlignLeftIcon,
"icon-align-right": AlignRightIcon,
"border-radius-sharp": BorderRadiusSharpIcon,
"border-radius-rounded": BorderRadiusRoundedIcon,
"binding-new": BindingIcon,
"bold-font": BoldFontIcon,
"book-line": BookLineIcon,
"border-radius-circle": BorderRadiusCircleIcon,
"border-radius-rounded": BorderRadiusRoundedIcon,
"border-radius-sharp": BorderRadiusSharpIcon,
"box-3-line": Box3LineIcon,
"box-shadow-none": BoxShadowNoneIcon,
"box-shadow-variant1": BoxShadowVariant1Icon,
"box-shadow-variant2": BoxShadowVariant2Icon,
"box-shadow-variant3": BoxShadowVariant3Icon,
"box-shadow-variant4": BoxShadowVariant4Icon,
"box-shadow-variant5": BoxShadowVariant5Icon,
"increase-control-v2": IncreaseV2Icon,
question: QuestionIcon,
"column-unfreeze": SubtractIcon,
"heading-one": HeadingOneIcon,
"heading-two": HeadingTwoIcon,
"heading-three": HeadingThreeIcon,
"gift-line": GiftLineIcon,
paragraph: ParagraphIcon,
"paragraph-two": ParagraphTwoIcon,
"add-box-line": AddBoxLineIcon,
"add-more": AddMoreIcon,
"add-more-fill": AddMoreFillIcon,
"alert-line": AlertLineIcon,
"alert-fill": AlertFillIcon,
"info-fill": InfoFillIcon,
"arrow-down-s-fill": ArrowDownSFillIcon,
"arrow-forward": ArrowForwardIcon,
"arrow-go-back": ArrowGoBackLineIcon,
"arrow-left": ArrowLeft,
"arrow-right-s-fill": ArrowRightSFillIcon,
"arrow-right-up-line": ArrowRightUpLineIcon,
"arrow-up-line": ArrowUpLineIcon,
"book-line": BookLineIcon,
"braces-line": BracesLineIcon,
"bug-line": BugLineIcon,
"cap-dot": CapDotIcon,
"cap-solid": CapSolidIcon,
"card-context-menu": CardContextMenu,
"center-align": CenterAlignIcon,
"chat-help": ChatIcon,
"chat-upload-line": ChatUploadLineIcon,
"check-line": CheckLineIcon,
"chevron-left": ChevronLeft,
"chevron-right": ChevronRight,
"close-circle": CloseCircleIcon,
"close-circle-control": CloseCircleIcon,
"close-circle-line": CloseCircleLineIcon,
"close-control": CloseIcon,
"close-line": CloseIcon,
"close-modal": CloseLineIcon,
"close-x": CloseLineIcon,
"cloud-off-line": CloudOfflineIcon,
"collapse-control": CollapseIcon,
"column-freeze": ColumnFreeze,
"column-unfreeze": SubtractIcon,
"comment-context-menu": CommentContextMenu,
"compasses-line": CompassesLine,
"content-type-table": ContentTypeTable,
"content-type-json": ContentTypeJson,
"content-type-raw": ContentTypeRaw,
"context-menu": ContextMenuIcon,
"contract-left-line": ContractLeft,
"contract-right-line": ContractRight,
"copy-control": CopyIcon,
"copy2-control": Copy2Icon,
"cut-control": CutIcon,
"dashboard-line": DashboardLineIcon,
"database-2-line": Database2Line,
"datasource-v3": DatasourceV3Icon,
"datasources-2": Datasources2,
"decrease-control": DecreaseIcon,
"delete-bin-line": DeleteBinLineIcon,
"delete-blank": DeleteBin7,
"delete-column": DeleteColumnIcon,
"delete-control": DeleteIcon,
"delete-row": DeleteRowIcon,
"double-arrow-right": DoubleArrowRightIcon,
"divider-cap-all": DividerCapAllIcon,
"divider-cap-left": DividerCapLeftIcon,
"divider-cap-right": DividerCapRightIcon,
"double-arrow-left": DoubleArrowLeftIcon,
"double-arrow-right": DoubleArrowRightIcon,
"down-arrow": DownArrowIcon,
"down-arrow-2": ArrowDownLineIcon,
"download-line": DownloadLineIcon,
"edit-box-line": EditBoxLineIcon,
"edit-line": EditLineIcon,
"drag-control": DragIcon,
"drag-handle": DragHandleIcon,
"draggable-control": DraggableIcon,
"edit-2-line": Edit2LineIcon,
"edit-box-line": EditBoxLineIcon,
"edit-control": EditIcon,
"edit-line": EditLineIcon,
"edit-underline": EditUnderlineIcon,
"edit-white": EditWhiteIcon,
"editor-v3": EditorV3Icon,
"enter-line": CornerDownLeftLineIcon,
"expand-less": ExpandLess,
"expand-more": ExpandMore,
"external-link-line": ExternalLinkIcon,
"eye-off": EyeOff,
"eye-on": EyeOn,
"file-add-line": FileAddLineIcon,
"file-copy-2-line": FileCopy2Line,
"file-line": FileLine,
"file-list-2-line": FileList2LineIcon,
"file-list-line": FileListLineIcon,
"file-paper-2-line": FilePaper2LineIcon,
"file-transfer": FileTransfer,
"fork-2": Fork2Icon,
"folder-download-line": FolderDownloadLineIcon,
"folder-line": FolderLineIcon,
"folder-reduce-line": FolderReduceLineIcon,
"forbid-line": ForbidLineIcon,
"fork-2": Fork2Icon,
"gift-line": GiftLineIcon,
"git-branch": GitBranchLineIcon,
"git-commit": GitCommit,
"git-pull-request": GitPullRequest,
"git-repository": GitRepository,
"github-fill": GithubFillIcon,
"global-line": GlobalLineIcon,
"google-colored": GoogleColoredIcon,
"google-fill": GoogleFillIcon,
"group-2-line": Group2LineIcon,
"group-control": GroupIcon,
"group-line": GroupLineIcon,
"h-line": HLineIcon,
"heading-one": HeadingOneIcon,
"heading-three": HeadingThreeIcon,
"heading-two": HeadingTwoIcon,
"help-control": HelpIcon,
"hide-column": EyeOffIcon,
"home-3-line": Home3LineIcon,
"icon-align-left": AlignLeftIcon,
"icon-align-right": AlignRightIcon,
"increase-control": IncreaseIcon,
"increase-control-v2": IncreaseV2Icon,
"info-fill": InfoFillIcon,
"input-cursor-move": InputCursorMoveIcon,
"invite-user": InviteUserIcon,
"italics-font": ItalicsFontIcon,
"js-file": JSFile,
"js-function": JSFunction,
"js-icon-v2": JSIconV2,
"js-square-v3": JsSquareV3Icon,
"js-toggle": JsToggleIcon,
"js-toggle-v2": JsToggleV2,
"js-toggle-v2-bold": JsToggleV2Bold,
"js-yellow": JSYellowIcon,
"key-2-line": Key2LineIcon,
"launch-control": LaunchIcon,
"layout-2-line": Layout2LineIcon,
"layout-5-line": Layout5LineIcon,
"layout-column-line": LayoutColumnLineIcon,
"layout-left-2-line": LayoutLeft2LineIcon,
"left-align": LeftAlignIcon,
"left-arrow-2": LeftArrowIcon2,
"lightbulb-flash-line": LightbulbFlashLine,
"line-dashed": LineDashedIcon,
@ -1220,45 +1266,88 @@ const ICON_LOOKUP = {
"link-2": Link2,
"link-unlink": LinkUnlinkIcon,
"links-line": LinksLineIcon,
"external-link-line": ExternalLinkIcon,
"loader-line": LoaderLineIcon,
"lock-2-line": Lock2LineIcon,
"lock-fill": LockFillIcon,
"lock-password-line": LockPasswordLineIcon,
"lock-unlock-line": LockUnlockLineIcon,
"lock-fill": LockFillIcon,
"magic-line": MagicLineIcon,
"mail-check-line": MailCheckLineIcon,
"mail-line": MailLineIcon,
"map-2-line": Map2LineIcon,
"map-pin-2-line": MapPin2LineIcon,
"map-pin-5-line": MapPin5LineIcon,
"map-pin-user-line": MapPinUserLineIcon,
"maximize-v3": MaximizeV3Icon,
"menu-fold": MenuFoldLineIcon,
"menu-unfold": MenuUnfoldLineIcon,
"message-2-line": Message2LineIcon,
"minimize-v3": MinimizeV3Icon,
"money-dollar-circle-line": MoneyDollarCircleLineIcon,
"more-2-fill": More2FillIcon,
"more-horizontal-control": OverflowMenuIcon,
"more-vertical-control": MoreVerticalIcon,
"move-control": MoveIcon,
"news-paper": NewsPaperLine,
"no-action": ForbidTwoLineIcon,
"no-response": NoResponseIcon,
"oval-check": OvalCheck,
"oval-check-fill": OvalCheckFill,
"packages-v3": PackagesV3Icon,
"page-line": PagesLineIcon,
"paragraph-two": ParagraphTwoIcon,
"pencil-fill-icon": PencilFillIcon,
"pencil-line": PencilLineIcon,
"pick-my-location-selected-control": PickMyLocationSelectedIcon,
"pin-3": Pin3,
"play-circle-line": PlayCircleLineIcon,
"play-line": PlayLineIcon,
"play-video": PlayIconPNGWrapper,
"queries-line": QueriesLineIcon,
"queries-v3": QueriesV3Icon,
"query-main": QueryMain,
"question-fill": QuestionFillIcon,
"question-line": QuestionLineIcon,
"question-mark": QuestionMarkIcon,
"reaction-2": Reaction2,
"read-pin": ReadPin,
"remove-control": RemoveIcon,
"restart-line": RestartLineIcon,
"right-align": RightAlignIcon,
"right-arrow": RightArrowIcon,
"right-arrow-2": RightArrowIcon2,
"search-eye-line": SearchEyeLineIcon,
"search-line": SearchLineIcon,
"send-button": SendButton,
"server-line": ServerLineIcon,
"settings-2-line": Settings2LineIcon,
"settings-control": SettingsIcon,
"settings-line": SettingsLineIcon,
"settings-v3": SettingsV3Icon,
"share-2": ShareIcon2,
"share-box": ShareBoxFillIcon,
"share-box-line": ShareBoxLineIcon,
"share-line": ShareLineIcon,
"show-column": EyeIcon,
"show-modal": ShowModalIcon,
"sip-line": SipLineIcon,
"skip-left-line": SkipLeftLineIcon,
"skip-right-line": SkipRightLineIcon,
"sort-asc": SortAscIcon,
"sort-control": SortIcon,
"sort-desc": SortDescIcon,
"star-fill": StarFillIcon,
"star-line": StarLineIcon,
"subtract-line": SubtractLine,
"swap-horizontal": ArrowLeftRightIcon,
"text-bold": BoldIcon,
"text-italic": ItalicIcon,
"text-underline": UnderLineIcon,
"thumb-down-line": ThumbDownLineIcon,
"thumb-up-line": ThumbUpLineIcon,
"timer-2-line": Timer2LineIcon,
"timer-flash-line": TimerFlashLineIcon,
"timer-line": TimerLineIcon,
"trash-outline": TrashOutline,
"trending-flat": TrendingFlat,
"unread-pin": UnreadPin,
@ -1274,104 +1363,27 @@ const ICON_LOOKUP = {
"user-settings-line": UserSettingsLineIcon,
"user-shared-line": UserSharedLineIcon,
"user-unfollow-line": UserUnfollowLineIcon,
"view-all": RightArrowIcon,
"view-less": LeftArrowIcon,
"warning-line": WarningLineIcon,
"warning-triangle": WarningTriangleIcon,
"money-dollar-circle-line": MoneyDollarCircleLineIcon,
"js-toggle-v2": JsToggleV2,
"js-toggle-v2-bold": JsToggleV2Bold,
"query-main": QueryMain,
"js-icon-v2": JSIconV2,
"js-file": JSFile,
"js-function": JSFunction,
"datasources-2": Datasources2,
"arrow-left-line": ArrowLeftLineIcon,
"arrow-right-line": ArrowRightLineIcon,
"close-line": CloseIcon,
"close-circle-line": CloseCircleLineIcon,
"arrow-left-s-line": ArrowLeftSLineIcon,
"arrow-right-s-line": ArrowRightSLineIcon,
"arrow-up-s-line": ArrowUpSLineIcon,
"arrow-down-s-line": ArrowDownSLineIcon,
"account-box-line": AccountBoxLineIcon,
"add-line": AddLineIcon,
"search-line": SearchLineIcon,
"loader-line": LoaderLineIcon,
"delete-bin-line": DeleteBinLineIcon,
"align-center": AlignCenter,
"align-left": AlignLeft,
"align-right": AlignRight,
"column-freeze": ColumnFreeze,
"vertical-align-bottom": VerticalBottom,
"vertical-align-middle": VerticalMiddle,
"vertical-align-top": VerticalTop,
"skip-right-line": SkipRightLineIcon,
"skip-left-line": SkipLeftLineIcon,
"contract-left-line": ContractLeft,
"contract-right-line": ContractRight,
"vertical-bottom": VerticalAlignBottom,
"vertical-center": VerticalAlignCenter,
"vertical-left": VerticalAlignLeft,
"vertical-right": VerticalAlignRight,
"vertical-top": VerticalAlignTop,
"view-all": RightArrowIcon,
"view-control": ViewIcon,
"view-less": LeftArrowIcon,
"w-line": WLineIcon,
"h-line": HLineIcon,
"file-add-line": FileAddLineIcon,
"layout-2-line": Layout2LineIcon,
"page-line": PagesLineIcon,
"pencil-line": PencilLineIcon,
"server-line": ServerLineIcon,
"layout-column-line": LayoutColumnLineIcon,
"layout-left-2-line": LayoutLeft2LineIcon,
"text-bold": BoldIcon,
"text-italic": ItalicIcon,
"text-underline": UnderLineIcon,
"sip-line": SipLineIcon,
"no-action": ForbidTwoLineIcon,
"message-2-line": Message2LineIcon,
"folder-download-line": FolderDownloadLineIcon,
"restart-line": RestartLineIcon,
"folder-reduce-line": FolderReduceLineIcon,
"timer-flash-line": TimerFlashLineIcon,
"timer-line": TimerLineIcon,
"map-2-line": Map2LineIcon,
"map-pin-user-line": MapPinUserLineIcon,
"map-pin-5-line": MapPin5LineIcon,
"chat-upload-line": ChatUploadLineIcon,
"home-3-line": Home3LineIcon,
"show-modal": ShowModalIcon,
"folder-line": FolderLineIcon,
"google-colored": GoogleColoredIcon,
"google-fill": GoogleFillIcon,
"github-fill": GithubFillIcon,
"enter-line": CornerDownLeftLineIcon,
"play-line": PlayLineIcon,
"thumb-up-line": ThumbUpLineIcon,
"thumb-down-line": ThumbDownLineIcon,
"menu-fold": MenuFoldLineIcon,
"menu-unfold": MenuUnfoldLineIcon,
"layout-5-line": Layout5LineIcon,
"js-yellow": JSYellowIcon,
"binding-new": BindingIcon,
"bill-line": BillLineIcon,
"file-paper-2-line": FilePaper2LineIcon,
"file-copy-2-line": FileCopy2Line,
"box-3-line": Box3LineIcon,
"apps-line": AppsLineIcon,
"queries-line": QueriesLineIcon,
"braces-line": BracesLineIcon,
"dashboard-line": DashboardLineIcon,
"js-square-v3": JsSquareV3Icon,
"queries-v3": QueriesV3Icon,
"warning-line": WarningLineIcon,
"warning-triangle": WarningTriangleIcon,
"widgets-v3": WidgetsV3Icon,
"datasource-v3": DatasourceV3Icon,
"editor-v3": EditorV3Icon,
"settings-v3": SettingsV3Icon,
"packages-v3": PackagesV3Icon,
"minimize-v3": MinimizeV3Icon,
"maximize-v3": MaximizeV3Icon,
"workflows-mono": WorkflowsMonochromeIcon,
"input-cursor-move": InputCursorMoveIcon,
billing: BillingIcon,
binding: Binding,
book: BookIcon,
bug: BugIcon,
bullets: BulletsIcon,
cancel: CancelIcon,
chat: Chat,
close: CloseIcon,
@ -1402,9 +1414,9 @@ const ICON_LOOKUP = {
general: GeneralIcon,
grid: GridLineIcon,
guide: GuideIcon,
history: HistoryLineIcon,
hamburger: HamburgerIcon,
help: HelpIcon,
history: HistoryLineIcon,
info: InfoIcon,
js: JsIcon,
key: KeyIcon,
@ -1418,14 +1430,17 @@ const ICON_LOOKUP = {
member: UserHeartLineIcon,
minimize: MinimizeIcon,
minus: RemoveIcon,
module: ModuleIcon,
mobile: MobileIcon,
module: ModuleIcon,
open: OpenIcon,
package: PackageIcon,
pantone: PantoneLineIcon,
paragraph: ParagraphIcon,
pin: Pin,
play: PlayIcon,
plus: CreateNewIcon,
query: QueryIcon,
question: QuestionIcon,
reaction: Reaction,
refresh: RefreshLineIcon,
rocket: RocketIcon,
@ -1433,8 +1448,9 @@ const ICON_LOOKUP = {
search: SearchIcon,
setting: SettingIcon,
share: ShareForwardIcon,
shine: ShineIcon,
shield: Shield,
shine: ShineIcon,
slash: SlashIcon,
snippet: Snippet,
success: SuccessIcon,
support: SupportIcon,
@ -1442,6 +1458,7 @@ const ICON_LOOKUP = {
tablet: TabletIcon,
tabletLandscape: TabletLandscapeIcon,
trash: Trash,
underline: UnderlineIcon,
unpin: Unpin,
upArrow: UpArrow,
upgrade: DvdLineIcon,
@ -1452,8 +1469,6 @@ const ICON_LOOKUP = {
widget: WidgetIcon,
workflows: WorkflowsIcon,
workspace: WorkspaceIcon,
package: PackageIcon,
slash: SlashIcon,
};
export const IconCollection = Object.keys(ICON_LOOKUP);

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M2.66683 12V9.53333C2.66683 9.26812 2.56147 9.01376 2.37394 8.82623C2.1864 8.63869 1.93205 8.53333 1.66683 8.53333H1.3335V7.46667H1.66683C1.79815 7.46667 1.92819 7.4408 2.04951 7.39055C2.17084 7.34029 2.28108 7.26663 2.37394 7.17377C2.46679 7.08092 2.54045 6.97068 2.59071 6.84935C2.64096 6.72802 2.66683 6.59799 2.66683 6.46667V4C2.66683 3.46957 2.87754 2.96086 3.25262 2.58579C3.62769 2.21071 4.1364 2 4.66683 2H5.3335V3.33333H4.66683C4.49002 3.33333 4.32045 3.40357 4.19543 3.5286C4.0704 3.65362 4.00016 3.82319 4.00016 4V6.73333C4.00023 7.01401 3.91173 7.28755 3.74726 7.51498C3.58278 7.74242 3.35073 7.91215 3.08416 8C3.35073 8.08785 3.58278 8.25758 3.74726 8.48502C3.91173 8.71245 4.00023 8.98599 4.00016 9.26667V12C4.00016 12.1768 4.0704 12.3464 4.19543 12.4714C4.32045 12.5964 4.49002 12.6667 4.66683 12.6667H5.3335V14H4.66683C4.1364 14 3.62769 13.7893 3.25262 13.4142C2.87754 13.0391 2.66683 12.5304 2.66683 12V12ZM13.3335 9.53333V12C13.3335 12.5304 13.1228 13.0391 12.7477 13.4142C12.3726 13.7893 11.8639 14 11.3335 14H10.6668V12.6667H11.3335C11.5103 12.6667 11.6799 12.5964 11.8049 12.4714C11.9299 12.3464 12.0002 12.1768 12.0002 12V9.26667C12.0001 8.98599 12.0886 8.71245 12.2531 8.48502C12.4175 8.25758 12.6496 8.08785 12.9162 8C12.6496 7.91215 12.4175 7.74242 12.2531 7.51498C12.0886 7.28755 12.0001 7.01401 12.0002 6.73333V4C12.0002 3.82319 11.9299 3.65362 11.8049 3.5286C11.6799 3.40357 11.5103 3.33333 11.3335 3.33333H10.6668V2H11.3335C11.8639 2 12.3726 2.21071 12.7477 2.58579C13.1228 2.96086 13.3335 3.46957 13.3335 4V6.46667C13.3335 6.73188 13.4389 6.98624 13.6264 7.17377C13.8139 7.36131 14.0683 7.46667 14.3335 7.46667H14.6668V8.53333H14.3335C14.0683 8.53333 13.8139 8.63869 13.6264 8.82623C13.4389 9.01376 13.3335 9.26812 13.3335 9.53333V9.53333Z" fill="#4C5664"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M14 5.3335V13.9955C14.0006 14.083 13.984 14.1699 13.951 14.251C13.9181 14.3321 13.8695 14.4059 13.808 14.4683C13.7466 14.5306 13.6734 14.5802 13.5928 14.6143C13.5121 14.6484 13.4255 14.6662 13.338 14.6668H2.662C2.48654 14.6668 2.31826 14.5972 2.19413 14.4732C2.07 14.3492 2.00018 14.181 2 14.0055V1.99483C2 1.63683 2.29933 1.3335 2.668 1.3335H9.998L14 5.3335ZM12.6667 6.00016H9.33333V2.66683H3.33333V13.3335H12.6667V6.00016ZM5.33333 4.66683H7.33333V6.00016H5.33333V4.66683ZM5.33333 7.3335H10.6667V8.66683H5.33333V7.3335ZM5.33333 10.0002H10.6667V11.3335H5.33333V10.0002Z" fill="#4C5664"/>
</svg>

After

Width:  |  Height:  |  Size: 701 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M2.66683 5.33333H13.3335V3.33333H2.66683V5.33333ZM9.3335 12.6667V6.66667H6.66683V12.6667H9.3335ZM10.6668 12.6667H13.3335V6.66667H10.6668V12.6667ZM5.3335 12.6667V6.66667H2.66683V12.6667H5.3335ZM2.00016 2H14.0002C14.177 2 14.3465 2.07024 14.4716 2.19526C14.5966 2.32029 14.6668 2.48986 14.6668 2.66667V13.3333C14.6668 13.5101 14.5966 13.6797 14.4716 13.8047C14.3465 13.9298 14.177 14 14.0002 14H2.00016C1.82335 14 1.65378 13.9298 1.52876 13.8047C1.40373 13.6797 1.3335 13.5101 1.3335 13.3333V2.66667C1.3335 2.48986 1.40373 2.32029 1.52876 2.19526C1.65378 2.07024 1.82335 2 2.00016 2V2Z" fill="#4C5664"/>
</svg>

After

Width:  |  Height:  |  Size: 715 B

View File

@ -70,7 +70,7 @@ interface Props {
const ViewHideButton = styled(Button)`
&.view-hide-button {
position: absolute;
top: 3px;
top: 2px;
right: 0;
padding: 9px 11px;
}

View File

@ -380,7 +380,7 @@ function BindDataButton(props: BindDataButtonProps) {
size="sm"
startIcon="binding-new"
>
Bind Data
Display on UI
</Button>
</MenuTrigger>
<MenuContent

View File

@ -1,65 +0,0 @@
import NoResponseSVG from "assets/images/no-response.svg";
import { Classes, Text, TextType } from "@appsmith/ads-old";
import {
EMPTY_RESPONSE_FIRST_HALF,
EMPTY_RESPONSE_LAST_HALF,
} from "ee/constants/messages";
import { Button } from "@appsmith/ads";
import React from "react";
import styled from "styled-components";
const StyledText = styled(Text)`
&&&& {
margin-top: 0;
}
`;
const NoResponseContainer = styled.div`
flex: 1;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.${Classes.ICON} {
margin-right: 0;
svg {
width: 150px;
height: 150px;
}
}
.${Classes.TEXT} {
margin-top: ${(props) => props.theme.spaces[9]}px;
}
`;
interface NoResponseProps {
isRunDisabled: boolean;
isRunning: boolean;
onRunClick: () => void;
}
export const NoResponse = ({
isRunDisabled,
isRunning,
onRunClick,
}: NoResponseProps) => (
<NoResponseContainer>
<img alt="no-response-yet" src={NoResponseSVG} />
<div className="flex gap-2 items-center mt-4">
<StyledText type={TextType.P1}>{EMPTY_RESPONSE_FIRST_HALF()}</StyledText>
<Button
isDisabled={isRunDisabled}
isLoading={isRunning}
onClick={onRunClick}
size="sm"
>
Run
</Button>
<StyledText type={TextType.P1}>{EMPTY_RESPONSE_LAST_HALF()}</StyledText>
</div>
</NoResponseContainer>
);

View File

@ -0,0 +1,34 @@
import React from "react";
import { Button } from "@appsmith/ads";
import NoResponseSVG from "assets/images/no-response.svg";
import { EMPTY_RESPONSE_RUN } from "ee/constants/messages";
import * as Styled from "./styles";
interface NoResponseProps {
isRunDisabled: boolean;
isRunning: boolean;
onRunClick: () => void;
}
export const NoResponse = ({
isRunDisabled,
isRunning,
onRunClick,
}: NoResponseProps) => (
<Styled.Container>
<img alt="no-response-yet" src={NoResponseSVG} />
<Styled.RunGroup>
<Styled.Text>{EMPTY_RESPONSE_RUN()}</Styled.Text>
<Button
isDisabled={isRunDisabled}
isLoading={isRunning}
onClick={onRunClick}
size="sm"
>
Run
</Button>
</Styled.RunGroup>
</Styled.Container>
);

View File

@ -0,0 +1 @@
export { NoResponse } from "./NoResponse";

View File

@ -0,0 +1,27 @@
import styled from "styled-components";
import { Text as AdsText } from "@appsmith/ads";
import { TAB_BAR_HEIGHT } from "../constants";
export const Text = styled(AdsText)`
&&&& {
margin-top: 0;
}
`;
export const Container = styled.div`
width: 100%;
height: calc(100% - ${TAB_BAR_HEIGHT}px);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 24px;
`;
export const RunGroup = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
`;

View File

@ -1,356 +0,0 @@
import React, { useCallback, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import ReactJson from "react-json-view";
import {
apiReactJsonProps,
ResponseTabErrorContainer,
ResponseTabErrorContent,
ResponseTabErrorDefaultMessage,
} from "./ApiResponse";
import { ResponseFormatTabs } from "./ResponseFormatTabs";
import { NoResponse } from "./NoResponse";
import LogAdditionalInfo from "components/editorComponents/Debugger/ErrorLogs/components/LogAdditionalInfo";
import LogHelper from "components/editorComponents/Debugger/ErrorLogs/components/LogHelper";
import LOG_TYPE from "entities/AppsmithConsole/logtype";
import { JsonWrapper } from "components/editorComponents/Debugger/ErrorLogs/components/LogCollapseData";
import {
Callout,
Flex,
SegmentedControl,
type CalloutLinkProps,
} from "@appsmith/ads";
import styled from "styled-components";
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/constants";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { setActionResponseDisplayFormat } from "actions/pluginActionActions";
import { getUpdateTimestamp } from "components/editorComponents/Debugger/ErrorLogs/ErrorLogItem";
import type { SourceEntity } from "entities/AppsmithConsole";
import type { Action } from "entities/Action";
import { getActionData } from "ee/selectors/entitiesSelector";
import { actionResponseDisplayDataFormats } from "pages/Editor/utils";
import { getErrorAsString } from "sagas/ActionExecution/errorUtils";
import { isString } from "lodash";
import ActionExecutionInProgressView from "components/editorComponents/ActionExecutionInProgressView";
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
import BindDataButton from "./BindDataButton";
import {
getPluginActionDebuggerState,
openPluginActionSettings,
setPluginActionEditorSelectedTab,
} from "../../../store";
import {
createMessage,
PREPARED_STATEMENT_WARNING,
} from "ee/constants/messages";
import { EDITOR_TABS } from "constants/QueryEditorConstants";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
const HelpSection = styled.div``;
export const ResponseDataContainer = styled.div`
padding: 0 var(--ads-v2-spaces-7);
padding-top: var(--ads-v2-spaces-4);
display: flex;
flex-direction: column;
gap: var(--ads-v2-spaces-4);
overflow-y: clip;
overflow-x: scroll;
`;
const ResponseContentWrapper = styled.div<{ isError: boolean }>`
overflow-y: clip;
display: grid;
height: ${(props) => (props.isError ? "" : "100%")};
${HelpSection} {
margin-bottom: 10px;
}
position: relative;
`;
interface Props {
actionSource: SourceEntity;
isRunDisabled?: boolean;
isRunning: boolean;
onRunClick: () => void;
currentActionConfig: Action;
runErrorMessage?: string;
actionName: string;
}
const QueryResponseTab = (props: Props) => {
const {
actionName,
actionSource,
currentActionConfig,
isRunDisabled = false,
isRunning,
onRunClick,
runErrorMessage,
} = props;
const dispatch = useDispatch();
const isActionRedesignEnabled = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);
const actionResponse = useSelector((state) =>
getActionData(state, currentActionConfig.id),
);
const { responseTabHeight } = useSelector(getPluginActionDebuggerState);
const { responseDataTypes, responseDisplayFormat } =
actionResponseDisplayDataFormats(actionResponse);
let output: Record<string, unknown>[] | string = "";
const responseBodyTabs =
responseDataTypes &&
responseDataTypes.map((dataType, index) => {
return {
index: index,
key: dataType.key,
title: dataType.title,
panelComponent: (
<ResponseFormatTabs
data={output}
responseType={dataType.key}
tableBodyHeight={responseTabHeight}
/>
),
};
});
const segmentedControlOptions =
responseBodyTabs &&
responseBodyTabs.map((item) => {
return { value: item.key, label: item.title };
});
const [selectedControl, setSelectedControl] = useState(
segmentedControlOptions[0]?.value,
);
const responseState =
actionResponse && getUpdateTimestamp(actionResponse.request);
const selectedTabIndex =
responseDataTypes &&
responseDataTypes.findIndex(
(dataType) => dataType.title === responseDisplayFormat?.title,
);
const onResponseTabSelect = (tabKey: string) => {
if (tabKey === DEBUGGER_TAB_KEYS.ERROR_TAB) {
AnalyticsUtil.logEvent("OPEN_DEBUGGER", {
source: "QUERY_PANE",
});
}
dispatch(
setActionResponseDisplayFormat({
id: currentActionConfig?.id || "",
field: "responseDisplayFormat",
value: tabKey,
}),
);
};
const responseTabOnRunClick = () => {
onRunClick();
AnalyticsUtil.logEvent("RESPONSE_TAB_RUN_ACTION_CLICK", {
source: "QUERY_PANE",
});
};
let error = runErrorMessage;
let hintMessages: Array<string> = [];
let showPreparedStatementWarning = false;
// Query is executed even once during the session, show the response data.
if (actionResponse) {
if (!actionResponse.isExecutionSuccess) {
// Pass the error to be shown in the error tab
error = actionResponse.readableError
? getErrorAsString(actionResponse.readableError)
: getErrorAsString(actionResponse.body);
} else if (isString(actionResponse.body)) {
//reset error.
error = "";
try {
// Try to parse response as JSON array to be displayed in the Response tab
output = JSON.parse(actionResponse.body);
} catch (e) {
// In case the string is not a JSON, wrap it in a response object
output = [
{
response: actionResponse.body,
},
];
}
} else {
//reset error.
error = "";
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
output = actionResponse.body as any;
}
if (actionResponse.messages && actionResponse.messages.length) {
//reset error.
error = "";
hintMessages = actionResponse.messages;
}
const { actionConfiguration } = currentActionConfig;
const hasPluginSpecifiedTemplates =
actionConfiguration?.pluginSpecifiedTemplates?.[0]?.value === true;
// oracle have different key for prepared statements
const hasPreparedStatement =
actionConfiguration?.formData?.preparedStatement?.data === true;
if (error && (hasPluginSpecifiedTemplates || hasPreparedStatement)) {
showPreparedStatementWarning = true;
}
}
const navigateToSettings = useCallback(() => {
if (isActionRedesignEnabled) {
dispatch(openPluginActionSettings(true));
} else {
dispatch(setPluginActionEditorSelectedTab(EDITOR_TABS.SETTINGS));
}
}, [dispatch, isActionRedesignEnabled]);
const preparedStatementCalloutLinks: CalloutLinkProps[] = [
{
onClick: navigateToSettings,
children: createMessage(PREPARED_STATEMENT_WARNING.LINK),
},
];
if (isRunning) {
return (
<ActionExecutionInProgressView
actionType="query"
theme={EditorTheme.LIGHT}
/>
);
}
return (
<ResponseContentWrapper isError={!!error}>
{showPreparedStatementWarning && (
<Callout
data-testid="t--prepared-statement-warning"
kind="warning"
links={preparedStatementCalloutLinks}
>
{createMessage(PREPARED_STATEMENT_WARNING.MESSAGE)}
</Callout>
)}
{error && (
<ResponseTabErrorContainer>
<ResponseTabErrorContent>
<ResponseTabErrorDefaultMessage>
Your query failed to execute
{actionResponse &&
(actionResponse.pluginErrorDetails || actionResponse.body) &&
":"}
</ResponseTabErrorDefaultMessage>
{actionResponse &&
(actionResponse.pluginErrorDetails ? (
<>
<div data-testid="t--query-error">
{actionResponse.pluginErrorDetails.downstreamErrorMessage ||
actionResponse.pluginErrorDetails.appsmithErrorMessage}
</div>
{actionResponse.pluginErrorDetails.downstreamErrorCode && (
<LogAdditionalInfo
text={
actionResponse.pluginErrorDetails.downstreamErrorCode
}
/>
)}
</>
) : (
actionResponse.body && (
<div data-testid="t--query-error">{actionResponse.body}</div>
)
))}
<LogHelper
logType={LOG_TYPE.ACTION_EXECUTION_ERROR}
name="PluginExecutionError"
pluginErrorDetails={
actionResponse && actionResponse.pluginErrorDetails
}
source={actionSource}
/>
</ResponseTabErrorContent>
{actionResponse && actionResponse.request && (
<JsonWrapper
className="t--debugger-log-state"
onClick={(e) => e.stopPropagation()}
>
<ReactJson src={responseState} {...apiReactJsonProps} />
</JsonWrapper>
)}
</ResponseTabErrorContainer>
)}
{hintMessages && hintMessages.length > 0 && (
<HelpSection>
{hintMessages.map((msg, index) => (
<Callout key={index} kind="warning">
{msg}
</Callout>
))}
</HelpSection>
)}
{currentActionConfig &&
output &&
responseBodyTabs &&
responseBodyTabs.length > 0 &&
selectedTabIndex !== -1 && (
<ResponseDataContainer>
<Flex justifyContent="space-between">
<SegmentedControl
data-testid="t--response-tab-segmented-control"
defaultValue={segmentedControlOptions[0]?.value}
isFullWidth={false}
onChange={(value) => {
setSelectedControl(value);
onResponseTabSelect(value);
}}
options={segmentedControlOptions}
value={selectedControl}
/>
<BindDataButton
actionName={actionName || currentActionConfig.name}
hasResponse={!!actionResponse}
suggestedWidgets={actionResponse?.suggestedWidgets}
/>
</Flex>
<ResponseFormatTabs
data={output}
responseType={
selectedControl || segmentedControlOptions[0]?.value
}
tableBodyHeight={responseTabHeight}
/>
</ResponseDataContainer>
)}
{!output && !error && (
<NoResponse
isRunDisabled={isRunDisabled}
isRunning={isRunning}
onRunClick={responseTabOnRunClick}
/>
)}
</ResponseContentWrapper>
);
};
export default QueryResponseTab;

View File

@ -0,0 +1,480 @@
import React, { useCallback, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import ReactJson from "react-json-view";
import {
apiReactJsonProps,
ResponseTabErrorContainer,
ResponseTabErrorContent,
ResponseTabErrorDefaultMessage,
} from "../ApiResponse";
import { ResponseFormatTabs } from "../ResponseFormatTabs";
import { NoResponse } from "../NoResponse";
import LogAdditionalInfo from "components/editorComponents/Debugger/ErrorLogs/components/LogAdditionalInfo";
import LogHelper from "components/editorComponents/Debugger/ErrorLogs/components/LogHelper";
import LOG_TYPE from "entities/AppsmithConsole/logtype";
import { JsonWrapper } from "components/editorComponents/Debugger/ErrorLogs/components/LogCollapseData";
import {
Callout,
Menu,
MenuContent,
MenuGroup,
MenuGroupName,
MenuItem,
MenuTrigger,
Text,
Tooltip,
type CalloutLinkProps,
} from "@appsmith/ads";
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/constants";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { setActionResponseDisplayFormat } from "actions/pluginActionActions";
import { getUpdateTimestamp } from "components/editorComponents/Debugger/ErrorLogs/ErrorLogItem";
import type { SourceEntity } from "entities/AppsmithConsole";
import type { Action } from "entities/Action";
import { getActionData } from "ee/selectors/entitiesSelector";
import { actionResponseDisplayDataFormats } from "pages/Editor/utils";
import { getErrorAsString } from "sagas/ActionExecution/errorUtils";
import { isString } from "lodash";
import ActionExecutionInProgressView from "components/editorComponents/ActionExecutionInProgressView";
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
import BindDataButton from "../BindDataButton";
import {
getPluginActionDebuggerState,
openPluginActionSettings,
setPluginActionEditorSelectedTab,
} from "../../../../store";
import {
createMessage,
PREPARED_STATEMENT_WARNING,
} from "ee/constants/messages";
import { EDITOR_TABS } from "constants/QueryEditorConstants";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import * as Styled from "./styles";
import { useBoolean, useEventCallback } from "usehooks-ts";
import { RESPONSE_TABLE_HEIGHT_OFFSET } from "./constants";
import { scrollbarWidth } from "utils/helpers";
interface Props {
actionSource: SourceEntity;
isRunDisabled?: boolean;
isRunning: boolean;
onRunClick: () => void;
currentActionConfig: Action;
runErrorMessage?: string;
actionName: string;
}
export const QueryResponseTab = (props: Props) => {
const {
actionName,
actionSource,
currentActionConfig,
isRunDisabled = false,
isRunning,
onRunClick,
runErrorMessage,
} = props;
const dispatch = useDispatch();
const { toggle: toggleContentTypeMenuOpen, value: isContentTypeMenuOpen } =
useBoolean(false);
const {
setFalse: setIsNotHovered,
setTrue: setIsHovered,
value: isDataContainerHovered,
} = useBoolean(false);
const isContentTypeSelectorVisible =
isDataContainerHovered || isContentTypeMenuOpen;
const isActionRedesignEnabled = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);
const actionResponse = useSelector((state) =>
getActionData(state, currentActionConfig.id),
);
const { responseTabHeight } = useSelector(getPluginActionDebuggerState);
const { responseDataTypes, responseDisplayFormat } =
actionResponseDisplayDataFormats(actionResponse);
const scrollbarOffset = scrollbarWidth();
let output: Record<string, unknown>[] | string = "";
let errorMessage = runErrorMessage;
let hintMessages: Array<string> = [];
let showPreparedStatementWarning = false;
// Query is executed even once during the session, show the response data.
if (actionResponse) {
if (!actionResponse.isExecutionSuccess) {
// Pass the error to be shown in the error tab
errorMessage = actionResponse.readableError
? getErrorAsString(actionResponse.readableError)
: getErrorAsString(actionResponse.body);
} else if (isString(actionResponse.body)) {
//reset error.
errorMessage = "";
try {
// Try to parse response as JSON array to be displayed in the Response tab
output = JSON.parse(actionResponse.body);
} catch (e) {
// In case the string is not a JSON, wrap it in a response object
output = [
{
response: actionResponse.body,
},
];
}
} else {
//reset error.
errorMessage = "";
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
output = actionResponse.body as any;
}
if (actionResponse.messages && actionResponse.messages.length) {
//reset error.
errorMessage = "";
hintMessages = actionResponse.messages;
}
const { actionConfiguration } = currentActionConfig;
const hasPluginSpecifiedTemplates =
actionConfiguration?.pluginSpecifiedTemplates?.[0]?.value === true;
// oracle have different key for prepared statements
const hasPreparedStatement =
actionConfiguration?.formData?.preparedStatement?.data === true;
if (errorMessage && (hasPluginSpecifiedTemplates || hasPreparedStatement)) {
showPreparedStatementWarning = true;
}
}
const recordCount = output?.length ?? 1;
const responseBodyTabs =
responseDataTypes &&
responseDataTypes.map((dataType, index) => {
return {
index: index,
key: dataType.key,
title: dataType.title,
panelComponent: (
<ResponseFormatTabs
data={output}
responseType={dataType.key}
tableBodyHeight={responseTabHeight}
/>
),
};
});
const contentTypeOptions =
responseBodyTabs &&
responseBodyTabs.map((item) => {
return { value: item.key, label: item.title };
});
const [firstContentTypeOption] = contentTypeOptions;
const [selectedContentType, setSelectedContentType] = useState(
firstContentTypeOption?.value,
);
const currentContentType =
selectedContentType || firstContentTypeOption?.value;
const responseState =
actionResponse && getUpdateTimestamp(actionResponse.request);
const selectedTabIndex =
responseDataTypes &&
responseDataTypes.findIndex(
(dataType) => dataType.title === responseDisplayFormat?.title,
);
const onResponseTabSelect = (tabKey: string) => {
if (tabKey === DEBUGGER_TAB_KEYS.ERROR_TAB) {
AnalyticsUtil.logEvent("OPEN_DEBUGGER", {
source: "QUERY_PANE",
});
}
dispatch(
setActionResponseDisplayFormat({
id: currentActionConfig?.id || "",
field: "responseDisplayFormat",
value: tabKey,
}),
);
};
const handleRunClick = useEventCallback(() => {
onRunClick();
AnalyticsUtil.logEvent("RESPONSE_TAB_RUN_ACTION_CLICK", {
source: "QUERY_PANE",
});
});
const navigateToSettings = useCallback(() => {
if (isActionRedesignEnabled) {
dispatch(openPluginActionSettings(true));
} else {
dispatch(setPluginActionEditorSelectedTab(EDITOR_TABS.SETTINGS));
}
}, [dispatch, isActionRedesignEnabled]);
const preparedStatementCalloutLinks: CalloutLinkProps[] = useMemo(
() => [
{
onClick: navigateToSettings,
children: createMessage(PREPARED_STATEMENT_WARNING.LINK),
},
],
[navigateToSettings],
);
const queryTooltipContent = useMemo(() => {
if (actionResponse) {
const messages = [
[
"duration",
"Time to run",
`${(Number(actionResponse.duration) / 1000).toFixed(1)}s`,
],
];
if (actionResponse.size) {
messages.push([
"size",
"Response size",
`${(Number(actionResponse.size) / 1000).toFixed(1)}kb`,
]);
}
return (
<>
{messages.map(([key, title, message]) => (
<div key={key}>{`${title}: ${message}`}</div>
))}
</>
);
}
return null;
}, [actionResponse]);
const handleContentTypeChange = useEventCallback((e?: Event) => {
if (e?.target && e.target instanceof HTMLElement) {
const { value } = e.target.dataset;
if (typeof value === "string") {
setSelectedContentType(value);
onResponseTabSelect(value);
}
}
});
const handleJsonWrapperClick = useEventCallback(
(e: React.MouseEvent<HTMLDivElement>) => e.stopPropagation(),
);
if (isRunning) {
return (
<Styled.LoadingContainer>
<ActionExecutionInProgressView
actionType="query"
theme={EditorTheme.LIGHT}
/>
</Styled.LoadingContainer>
);
}
if (!output && !errorMessage) {
return (
<NoResponse
isRunDisabled={isRunDisabled}
isRunning={isRunning}
onRunClick={handleRunClick}
/>
);
}
return (
<Styled.Root>
{errorMessage && (
<div>
<Styled.StatusBar>
<Styled.StatusBarInfo>
<Styled.StatusBarText $isBold kind="code">
{`${actionName}.run():`}
</Styled.StatusBarText>
<Styled.StatusBarText $isError kind="code">
Error
</Styled.StatusBarText>
</Styled.StatusBarInfo>
</Styled.StatusBar>
<ResponseTabErrorContainer>
<ResponseTabErrorContent>
<ResponseTabErrorDefaultMessage>
Your query failed to execute
{actionResponse &&
(actionResponse.pluginErrorDetails || actionResponse.body) &&
":"}
</ResponseTabErrorDefaultMessage>
{actionResponse &&
(actionResponse.pluginErrorDetails ? (
<>
<div data-testid="t--query-error">
{actionResponse.pluginErrorDetails
.downstreamErrorMessage ||
actionResponse.pluginErrorDetails.appsmithErrorMessage}
</div>
{actionResponse.pluginErrorDetails.downstreamErrorCode && (
<LogAdditionalInfo
text={
actionResponse.pluginErrorDetails.downstreamErrorCode
}
/>
)}
</>
) : (
actionResponse.body && (
<div data-testid="t--query-error">
{actionResponse.body}
</div>
)
))}
<LogHelper
logType={LOG_TYPE.ACTION_EXECUTION_ERROR}
name="PluginExecutionError"
pluginErrorDetails={
actionResponse && actionResponse.pluginErrorDetails
}
source={actionSource}
/>
</ResponseTabErrorContent>
{actionResponse && actionResponse.request && (
<JsonWrapper
className="t--debugger-log-state"
onClick={handleJsonWrapperClick}
>
<ReactJson src={responseState} {...apiReactJsonProps} />
</JsonWrapper>
)}
</ResponseTabErrorContainer>
</div>
)}
{showPreparedStatementWarning && (
<Callout
data-testid="t--prepared-statement-warning"
kind="warning"
links={preparedStatementCalloutLinks}
>
{createMessage(PREPARED_STATEMENT_WARNING.MESSAGE)}
</Callout>
)}
{hintMessages && hintMessages.length > 0 && (
<Styled.HelpSection>
{hintMessages.map((msg, index) => (
<Callout key={index} kind="warning">
{msg}
</Callout>
))}
</Styled.HelpSection>
)}
{currentActionConfig &&
output &&
responseBodyTabs &&
responseBodyTabs.length > 0 &&
selectedTabIndex !== -1 && (
<Styled.DataContainer
$height={responseTabHeight}
data-testid="t--query-response-data-container"
onMouseEnter={setIsHovered}
onMouseLeave={setIsNotHovered}
>
<Styled.StatusBar>
<Tooltip
content={queryTooltipContent}
isDisabled={!queryTooltipContent}
placement="bottom"
>
<Styled.StatusBarInfo>
<Styled.StatusBarText $hasTooltip $isBold kind="code">
{`${actionName}.run():`}
</Styled.StatusBarText>
<Styled.StatusBarText
$hasTooltip
data-testid="t--query-response-record-count"
kind="code"
>{`${recordCount} record${recordCount > 1 ? "s" : ""}`}</Styled.StatusBarText>
</Styled.StatusBarInfo>
</Tooltip>
<BindDataButton
actionName={actionName || currentActionConfig.name}
hasResponse={!!actionResponse}
suggestedWidgets={actionResponse?.suggestedWidgets}
/>
</Styled.StatusBar>
<Styled.Response>
<ResponseFormatTabs
data={output}
responseType={currentContentType}
tableBodyHeight={
responseTabHeight +
RESPONSE_TABLE_HEIGHT_OFFSET -
scrollbarOffset
}
/>
</Styled.Response>
<Menu onOpenChange={toggleContentTypeMenuOpen}>
<MenuTrigger>
<Styled.Fab
$isVisible={isContentTypeSelectorVisible}
aria-label={`Change response format. Current format: ${currentContentType}`}
data-testid="t--query-response-type-trigger"
endIcon={
isContentTypeMenuOpen
? "arrow-up-s-line"
: "arrow-down-s-line"
}
kind="secondary"
startIcon={`content-type-${currentContentType.toLocaleLowerCase()}`}
>
{currentContentType}
</Styled.Fab>
</MenuTrigger>
<MenuContent loop>
<MenuGroupName asChild>
<Text kind="body-s">View as</Text>
</MenuGroupName>
<MenuGroup>
{contentTypeOptions.map(({ label, value }) => (
<MenuItem
data-testid="t--query-response-type-menu-item"
data-value={value}
key={value}
onSelect={handleContentTypeChange}
startIcon={`content-type-${value.toLocaleLowerCase()}`}
>
{label}
</MenuItem>
))}
</MenuGroup>
</MenuContent>
</Menu>
</Styled.DataContainer>
)}
</Styled.Root>
);
};

View File

@ -0,0 +1,2 @@
/** Offset needed to make table height match response tab height */
export const RESPONSE_TABLE_HEIGHT_OFFSET = 14;

View File

@ -0,0 +1 @@
export { QueryResponseTab as default } from "./QueryResponseTab";

View File

@ -0,0 +1,73 @@
import styled from "styled-components";
import { Button, Text } from "@appsmith/ads";
import { TAB_BAR_HEIGHT } from "../constants";
export const HelpSection = styled.div``;
export const Root = styled.div`
display: flex;
flex-direction: column;
`;
export const DataContainer = styled.div<{ $height: number }>`
height: calc(${({ $height }) => $height}px - 1px);
display: grid;
grid-template-rows: ${TAB_BAR_HEIGHT}px 1fr;
grid-template-columns: 100%;
position: relative;
overflow: clip;
`;
export const Response = styled.div`
overflow: auto;
width: 100%;
height: 100%;
`;
export const StatusBar = styled.div`
position: sticky;
top: 0px;
display: flex;
justify-content: space-between;
height: ${TAB_BAR_HEIGHT}px;
padding: 8px;
border-bottom: 1px solid var(--ads-v2-color-border);
z-index: var(--ads-v2-z-index-1);
`;
export const StatusBarInfo = styled.div`
display: flex;
align-items: center;
gap: var(--ads-v2-spaces-2);
`;
export const Fab = styled(Button)<{ $isVisible: boolean }>`
&& {
position: absolute;
right: 20px;
bottom: calc(${TAB_BAR_HEIGHT}px + 20px);
box-shadow: 0px 1px 20px 0px rgba(76, 86, 100, 0.11);
z-index: var(--ads-v2-z-index-3);
opacity: ${({ $isVisible }) => ($isVisible ? 1 : 0)};
transition: opacity 0.25s;
}
`;
export const LoadingContainer = styled.div`
height: calc(100% - ${TAB_BAR_HEIGHT}px);
`;
interface StatusBarTextProps {
$isBold?: boolean;
$isError?: boolean;
$hasTooltip?: boolean;
}
export const StatusBarText = styled(Text)<StatusBarTextProps>`
font-size: 13px;
${({ $hasTooltip }) =>
$hasTooltip &&
`text-decoration: underline var(--ads-v2-color-border) dashed;`}
${({ $isBold }) => $isBold && `font-weight: 700;`}
${({ $isError }) => $isError && `color: var(--ads-v2-color-fg-on-error);`}
`;

View File

@ -39,12 +39,11 @@ export const TableWrapper = styled.div<{ minColumnWidth?: number }>`
width: 100%;
height: auto;
background: var(--ads-v2-color-bg);
border: 1px solid var(--ads-v2-color-border);
box-sizing: border-box;
display: flex;
justify-content: space-between;
flex-direction: column;
overflow: scroll;
overflow: auto;
.tableWrap {
height: 100%;
display: block;
@ -55,7 +54,6 @@ export const TableWrapper = styled.div<{ minColumnWidth?: number }>`
border-spacing: 0;
color: var(--ads-v2-color-fg);
position: relative;
background: var(--ads-v2-color-gray-50);
display: table;
width: 100%;
height: auto;
@ -71,13 +69,7 @@ export const TableWrapper = styled.div<{ minColumnWidth?: number }>`
}
.tr {
overflow: hidden;
border-right: 1px solid var(--ads-v2-color-border);
:nth-child(even) {
background: var(--ads-v2-color-gray-50);
}
:nth-child(odd) {
background: var(--ads-v2-color-bg);
}
border-bottom: 1px solid var(--ads-v2-color-black-75);
&.selected-row {
background: var(--ads-v2-color-bg-subtle);
&:hover {
@ -92,7 +84,6 @@ export const TableWrapper = styled.div<{ minColumnWidth?: number }>`
.td {
margin: 0;
padding: 9px 10px;
border-right: 1px solid var(--ads-v2-color-border);
position: relative;
font-size: ${TABLE_SIZES.ROW_FONT_SIZE}px;
line-height: ${TABLE_SIZES.ROW_FONT_SIZE}px;
@ -255,7 +246,7 @@ function Table(props: TableProps) {
const defaultColumn = React.useMemo(
() => ({
width: 170,
minWidth: 170,
}),
[],
);
@ -343,7 +334,7 @@ function Table(props: TableProps) {
<TableWrapper
className="t--table-response"
data-guided-tour-id="query-table-response"
minColumnWidth={defaultColumn.width}
minColumnWidth={defaultColumn.minWidth}
>
<div className="tableWrap">
<div {...getTableProps()} className="table">

View File

@ -0,0 +1,2 @@
/** Height for tab bar in px. Required for container height calculations. */
export const TAB_BAR_HEIGHT = 40;

View File

@ -2,4 +2,4 @@
* When action execution is triggered, open response
* container to height specified by this variable.
*/
export const ActionExecutionResizerHeight = (window.innerHeight * 30) / 100;
export const ActionExecutionResizerHeight = (window.innerHeight * 35) / 100;

View File

@ -1,27 +1,56 @@
<svg width="109" height="110" viewBox="0 0 109 110" fill="none" xmlns="http://www.w3.org/2000/svg">
<ellipse opacity="0.68" cx="69.3562" cy="105.3" rx="38.9051" ry="4.69994" fill="#E3E8EF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M57.7178 60.1503L66.9468 69.3975L74.0376 62.5656L63.1989 52.2455L57.7178 60.1503Z" fill="#CDD5DF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M66.7128 70.2179L62.1182 95.2086H79.7655L74.96 69.3975L66.7128 70.2179ZM68.9984 76.2747H72.9581L75.8396 91.5191H66.1844L68.9984 76.2747Z" fill="#99A4B3"/>
<circle cx="70.9635" cy="66.5783" r="6.94783" fill="#CDD5DF"/>
<circle cx="70.9639" cy="66.5783" r="3.87996" fill="#99A4B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M57.6992 96.1878C57.6992 95.0341 58.6344 94.0989 59.7881 94.0989H82.1385C83.2921 94.0989 84.2273 95.0341 84.2273 96.1878V102.4H57.6992V96.1878Z" fill="#CDD5DF"/>
<path d="M68.1553 77.1583L68.7925 76.3307L75.3381 81.3707L68.1281 85.0658L76.5285 90.4748L75.9631 91.353L66.0391 84.9632L73.3952 81.193L68.1553 77.1583Z" fill="#99A4B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M63.7458 18.1125C63.177 17.3874 62.1092 17.3352 61.4559 17.9852L22.3025 56.9341C21.6847 57.5486 21.6888 58.5471 22.3349 59.1317C23.3342 60.0356 24.8106 61.2932 26.0566 62.0387C34.8813 67.3181 51.187 70.3572 62.6728 58.05C74.1023 45.8031 72.1776 31.9489 66.9561 22.675C66.1713 21.281 64.7371 19.3764 63.7458 18.1125Z" fill="#E3E8EF"/>
<ellipse cx="42.4461" cy="44.3939" rx="21.2655" ry="22.2503" fill="#F1F5F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M52.4668 102.026C52.4668 101.439 52.9432 100.968 53.5295 100.981C56.683 101.051 66.0707 101.252 70.9412 101.252C75.8215 101.252 85.3919 101.051 88.5804 100.98C89.1665 100.967 89.6422 101.439 89.6422 102.025V105.013C89.6422 105.279 89.4475 105.502 89.1829 105.529C87.2973 105.72 79.829 106.418 70.9412 106.418C62.0695 106.418 54.7802 105.723 52.9245 105.53C52.6606 105.502 52.4668 105.28 52.4668 105.014L52.4668 102.026Z" fill="#99A4B3"/>
<path opacity="0.2" fill-rule="evenodd" clip-rule="evenodd" d="M74.9248 94.0989C74.9248 94.0989 76.0373 94.2302 76.0373 95.4718C76.0373 96.7134 76.0373 100.426 76.0373 101.236C79.2577 101.169 80.9128 101.138 80.9128 101.138C80.9128 101.138 81.9849 101.073 81.9849 102.186C81.9849 103.298 81.9849 106.106 81.9849 106.106C81.9849 106.106 84.5046 105.969 86.1673 105.836C87.318 105.744 88.5397 105.609 89.1831 105.534C89.4451 105.504 89.6413 105.282 89.6413 105.018V102.024C89.6413 101.438 89.1598 100.967 88.5743 100.98L84.2274 101.073V96.1878C84.2274 95.0341 83.2922 94.0989 82.1385 94.0989H74.9248Z" fill="#6A7585"/>
<circle cx="32.1646" cy="27.7787" r="2.61672" fill="#E3E8EF"/>
<path d="M31.8061 19.2943C29.5977 19.386 27.4162 20.2748 25.7301 21.961C24.0101 23.6809 23.1197 25.9163 23.0589 28.1698" stroke="#99A4B3" stroke-width="1.56665" stroke-linecap="round"/>
<path d="M32.161 13.1327C31.8984 13.1331 31.6358 13.1403 31.3735 13.1542C27.737 13.3467 24.1562 14.8319 21.3785 17.6096C18.6736 20.3145 17.1944 23.7808 16.9409 27.3186C16.9184 27.6319 16.9056 27.9457 16.9024 28.2596" stroke="#99A4B3" stroke-width="1.56665" stroke-linecap="round"/>
<circle cx="3.08825" cy="50.5812" r="2.34997" fill="#CDD5DF" stroke="#CDD5DF" stroke-width="1.30554"/>
<circle cx="91.8313" cy="80.3411" r="1.48661" fill="#CDD5DF" stroke="#CDD5DF" stroke-width="0.84949"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.0902 0V7.13572V0Z" fill="#CDD5DF"/>
<path d="M51.0902 0V7.13572" stroke="#CDD5DF" stroke-width="1.56665"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.5225 3.56786H54.6582H47.5225Z" fill="#CDD5DF"/>
<path d="M47.5225 3.56786H54.6582" stroke="#CDD5DF" stroke-width="1.56665"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.1343 79.3768V88.0205V79.3768Z" fill="#CDD5DF"/>
<path d="M35.1343 79.3768V88.0205" stroke="#CDD5DF" stroke-width="1.30554"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.8125 83.6986H39.4562H30.8125Z" fill="#CDD5DF"/>
<path d="M30.8125 83.6986H39.4562" stroke="#CDD5DF" stroke-width="1.30554"/>
<circle cx="84.3392" cy="47.7827" r="2.34997" fill="#CDD5DF"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="119" height="101" viewBox="0 0 119 101" fill="none">
<g clip-path="url(#clip0_4032_107537)">
<path d="M88.1445 85.0502C84.3303 86.2928 84.4366 86.6384 80.6224 87.881C76.8082 89.1236 76.7151 88.8445 72.8943 90.0871C69.0734 91.3297 69.1399 91.5357 65.319 92.785C61.4982 94.0342 61.5181 94.094 57.7039 95.3366C53.8897 96.5792 53.8565 96.4928 50.0356 97.7421C46.2148 98.9914 46.2546 99.1043 42.4338 100.354C42.4271 100.354 42.2743 100.32 42.2677 100.32C38.7791 98.3667 38.8521 98.2272 35.3635 96.2802C31.8749 94.3332 31.968 94.1538 28.4794 92.2002C24.9908 90.2466 24.8446 90.4925 21.356 88.5455C17.8674 86.5985 17.9803 86.3859 14.4851 84.4389C10.9898 82.4919 11.0098 82.4454 7.51452 80.4918C4.01927 78.5382 4.03256 78.5182 0.537312 76.5646C0.510733 76.5513 0.377833 76.5978 0.411058 76.5912C4.22526 75.3486 4.29836 75.5612 8.11257 74.3186C11.9268 73.076 11.9068 72.9963 15.721 71.747C19.5353 70.4978 19.5751 70.6174 23.396 69.3748C27.2168 68.1322 27.1703 67.986 30.9845 66.7434C34.7987 65.5008 34.7389 65.2948 38.5598 64.0522C42.3806 62.8096 42.5069 63.1883 46.3277 61.9391C46.3344 61.9391 46.3277 61.66 46.341 61.6666C49.8296 63.6202 49.8429 63.6003 53.3315 65.5539C56.8201 67.5075 56.8533 67.4544 60.3486 69.408C63.8438 71.3616 63.804 71.4281 67.2992 73.375C70.7945 75.322 70.7546 75.3951 74.2432 77.3487C77.7318 79.3023 77.765 79.2492 81.2603 81.2028C84.7555 83.1564 84.7422 83.183 88.2375 85.1366C88.2641 85.1499 88.171 85.0569 88.1445 85.0702V85.0502Z" fill="#EDEBFC"/>
<path d="M88.2639 85.2563C84.4431 86.4989 84.3899 86.3261 80.5691 87.5687C76.7482 88.8113 76.8346 89.0705 73.0138 90.3131C69.1929 91.5557 69.1663 91.4826 65.3455 92.7252C61.5246 93.9678 61.4914 93.8615 57.6706 95.1107C53.8497 96.36 53.8896 96.473 50.0621 97.7222C46.2346 98.9715 46.1615 98.7323 42.3406 99.9815C42.3207 99.9882 42.4935 100.154 42.4935 100.134C42.4935 96.3666 42.4469 96.3666 42.4469 92.5923C42.4469 88.818 42.2808 88.8246 42.2808 85.0503C42.2808 81.2759 42.1812 81.2826 42.1812 77.5082C42.1812 73.7339 42.2077 73.7406 42.2077 69.9729C42.2077 66.2052 42.4004 66.2052 42.4004 62.4308C42.4004 58.6565 42.4004 58.6565 42.4004 54.8888C42.4004 51.1211 42.3805 51.1211 42.3805 47.3468C42.3805 43.5724 42.2476 43.5724 42.2476 39.8047C42.2476 36.0371 42.3805 36.0304 42.3805 32.2627C42.3805 32.2494 42.427 32.4023 42.4403 32.3956C46.2612 31.153 46.1814 30.9204 50.0023 29.6712C53.8231 28.4219 53.8497 28.5017 57.6706 27.2591C61.4914 26.0165 61.4582 25.9101 65.279 24.6675C69.0999 23.4249 69.0733 23.3385 72.8942 22.0959C76.715 20.8533 76.8346 21.2188 80.6621 19.9695C84.4896 18.7203 84.3766 18.3947 88.2041 17.1521C88.2241 17.1454 88.337 17.2916 88.337 17.3116C88.337 21.0792 88.4766 21.0792 88.4766 24.8536C88.4766 28.6279 88.1908 28.6213 88.1908 32.3956C88.1908 36.17 88.4766 36.1633 88.4766 39.9376C88.4766 43.712 88.1975 43.7053 88.1975 47.473C88.1975 51.2407 88.1111 51.2407 88.1111 55.0151C88.1111 58.7894 88.2374 58.7894 88.2374 62.5571C88.2374 66.3248 88.3769 66.3248 88.3769 70.0991C88.3769 73.8735 88.2108 73.8735 88.2108 77.6411C88.2108 81.4088 88.1643 81.4155 88.1643 85.1832C88.1643 85.1965 88.2905 85.2563 88.2772 85.2563H88.2639Z" fill="#D5E1E6"/>
<path d="M88.1908 17.2586C84.3766 18.5012 84.3899 18.5477 80.569 19.7903C76.7482 21.0329 76.7349 20.9864 72.9141 22.229C69.0932 23.4716 69.0799 23.4317 65.2591 24.6743C61.4382 25.917 61.4515 25.9635 57.6373 27.2061C53.8231 28.4487 53.8031 28.4088 49.9823 29.6514C46.1614 30.894 46.2212 31.0734 42.4004 32.3227C42.3938 32.3227 42.3738 32.1898 42.3672 32.1832C37.1642 29.2793 37.204 29.2129 32.001 26.309C31.9745 26.2957 31.9146 26.3489 31.9412 26.3422C35.7554 25.0996 35.7355 25.0265 39.5497 23.7839C43.3639 22.5413 43.3839 22.5812 47.1981 21.3386C51.0123 20.096 50.9923 20.0229 54.8132 18.7736C58.634 17.5244 58.7138 17.7769 62.528 16.5276C66.3422 15.2784 66.3223 15.192 70.1431 13.9494C73.964 12.7068 73.9108 12.5473 77.7316 11.3047C77.7383 11.3047 77.7649 11.4575 77.7715 11.4575C82.9745 14.3614 82.9413 14.4212 88.1376 17.325C88.1642 17.3383 88.2041 17.2453 88.1775 17.2519L88.1908 17.2586Z" fill="#EAF0F3"/>
<path d="M42.3078 100.154C37.1048 97.2437 37.0649 97.3035 31.8619 94.393C31.8486 94.393 31.8353 94.3066 31.8353 94.3C31.8353 90.5323 31.8685 90.5323 31.8685 86.7646C31.8685 82.9969 32.0214 82.9969 32.0214 79.2225C32.0214 75.4482 32.0347 75.4548 32.0347 71.6805C32.0347 67.9062 32.0347 67.9128 32.0347 64.1451C32.0347 60.3774 31.7622 60.3774 31.7622 56.6031C31.7622 52.8288 31.7755 52.8354 31.7755 49.0611C31.7755 45.2867 31.8353 45.2934 31.8353 41.519C31.8353 37.7447 31.9948 37.7447 31.9948 33.977C31.9948 30.2093 31.8685 30.2027 31.8685 26.435C31.8685 26.4084 31.9549 26.3087 31.9748 26.322C37.1778 29.2325 37.1712 29.2524 42.3742 32.1629C42.3875 32.1629 42.4207 32.2427 42.4207 32.256C42.4207 36.0237 42.5403 36.0237 42.5403 39.7913C42.5403 43.559 42.3543 43.559 42.3543 47.3334C42.3543 51.1077 42.2612 51.1011 42.2612 54.8754C42.2612 58.6497 42.1815 58.6431 42.1815 62.4108C42.1815 66.1785 42.4074 66.1785 42.4074 69.9528C42.4074 73.7272 42.3343 73.7205 42.3343 77.4949C42.3343 81.2692 42.4141 81.2625 42.4141 85.0369C42.4141 88.8112 42.4606 88.8112 42.4606 92.5789C42.4606 96.3466 42.1881 96.3532 42.1881 100.121C42.1881 100.148 42.3277 100.167 42.3078 100.154Z" fill="#ABBBC1"/>
<path d="M42.3009 100.168C37.0979 97.2574 37.1112 97.2308 31.9082 94.3203" stroke="#80949C" stroke-width="0.888897" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M45.9889 27.4518C44.0154 28.1562 43.9822 28.0565 42.0086 28.7608C41.9887 28.7675 41.9953 28.7941 41.9953 28.7675C41.9953 24.3619 42.0153 24.3619 42.0153 19.9563C42.0153 15.5507 41.9688 15.544 41.9688 11.1384C41.9688 6.73281 42.0352 6.72616 42.0352 2.32056C42.0352 2.30727 41.9887 2.24746 42.002 2.24082C42.9655 1.89528 42.9788 1.94179 43.9423 1.59626C43.9622 1.58961 43.929 1.61619 43.9357 1.63613C44.1572 4.49346 44.3764 7.35079 44.5935 10.2081C44.9258 14.5008 44.9523 14.4941 45.2846 18.7868C45.6168 23.0794 45.7165 23.0661 46.0488 27.3588C46.0488 27.3721 46.0022 27.4518 45.9889 27.4518Z" fill="#D5E1E6"/>
<path d="M43.9154 1.60941C43.2819 1.83534 42.6462 2.06348 42.0082 2.29384C42.0082 2.29384 41.9883 2.29384 41.9817 2.29384C41.3526 1.94387 40.7258 1.59391 40.1011 1.24394C40.1011 1.24394 40.0812 1.17749 40.1011 1.17084C41.0514 0.831951 41.058 0.845241 42.0149 0.506348C42.0215 0.506348 42.0282 0.506348 42.0415 0.506348C42.6705 0.856315 43.2974 1.2085 43.922 1.5629C43.922 1.5629 43.9419 1.60941 43.922 1.61606L43.9154 1.60941Z" fill="#EAF0F3"/>
<path d="M41.942 28.7605C40.0017 27.6773 39.9618 27.7438 38.0215 26.6607C38.0082 26.6607 37.9883 26.6008 37.9883 26.5876C38.3205 22.368 38.367 22.368 38.6993 18.1485C39.0315 13.9289 39.0116 13.9223 39.3505 9.70271C39.6894 5.48317 39.7226 5.48317 40.0549 1.25697C40.0549 1.23039 40.0748 1.19052 40.0947 1.20381C41.045 1.73541 40.9984 1.81515 41.942 2.34674C41.9553 2.34674 41.9686 2.30687 41.9686 2.31352C41.9686 6.71913 42.0151 6.71913 42.0151 11.1247C42.0151 15.5303 41.9553 15.5303 41.9553 19.9426C41.9553 24.3549 42.0284 24.3482 42.0284 28.7605C42.0284 28.787 41.9686 28.7737 41.9487 28.7605H41.942Z" fill="#ABBBC1"/>
<path d="M82.7953 65.9796C79.9867 66.8966 77.1759 67.8114 74.3629 68.724C70.15 70.0995 70.1367 70.0596 65.9238 71.4352C61.7109 72.8107 61.7375 72.917 57.5246 74.2858C53.3117 75.6547 53.3117 75.6813 49.0988 77.0568C47.8229 77.4754 46.5006 76.4388 46.5006 75.0965C46.5006 71.3222 46.4674 71.3222 46.4674 67.5478C46.4674 63.7735 46.5537 63.7735 46.5537 59.9992C46.5537 56.2248 46.4474 56.2248 46.4474 52.4505C46.4474 48.6762 46.5404 48.6762 46.5404 44.8952C46.5404 41.1208 46.3677 41.1208 46.3677 37.3399C46.3677 36.4893 47.0388 35.7318 47.8495 35.466C52.0624 34.0905 52.0757 34.1171 56.2886 32.7415C60.5015 31.366 60.4683 31.2664 64.6878 29.8909C68.9074 28.5154 68.9207 28.5752 73.1402 27.1997C77.3598 25.8241 77.3465 25.7843 81.5594 24.4088C82.8352 23.9901 84.2506 25.0002 84.2506 26.3425C84.2506 30.1168 84.0579 30.1168 84.0579 33.8911C84.0579 37.6655 84.1841 37.6655 84.1841 41.4398C84.1841 45.2141 84.1974 45.2141 84.1974 48.9885C84.1974 52.7628 84.038 52.7628 84.038 56.5438C84.038 59.06 84.038 61.5785 84.038 64.0991C84.038 64.9497 83.626 65.7205 82.8086 65.9863L82.7953 65.9796Z" fill="#FCBA44"/>
<path d="M67.7513 60.8831C66.1831 61.3925 64.6171 61.9064 63.0534 62.4247C62.8739 62.4845 62.7012 62.3582 62.7012 62.1722C62.7012 60.3049 62.7078 60.3049 62.7078 58.4377C62.7078 58.3181 62.7743 58.2184 62.8872 58.1852C65.2395 57.421 65.2329 57.4011 67.5852 56.6303C67.7646 56.5705 67.964 56.7167 67.964 56.9027C67.964 58.1475 67.964 59.3924 67.964 60.6372C67.964 60.7568 67.871 60.8498 67.758 60.8831H67.7513Z" fill="white"/>
<path d="M67.7514 53.0885C65.3991 53.8527 65.3991 53.846 63.0468 54.6102C62.8674 54.67 62.688 54.5637 62.688 54.3776C62.688 50.9821 62.7079 50.9821 62.7079 47.5865C62.7079 44.1909 62.7079 44.1909 62.7079 40.7953C62.7079 40.6757 62.7744 40.5628 62.8873 40.5229C65.2397 39.7587 65.233 39.7388 67.5853 38.968C67.7647 38.9082 67.984 39.0743 67.984 39.2603C67.984 42.6559 67.9774 42.6559 67.9774 46.0515C67.9774 49.4471 67.9707 49.4471 67.9707 52.8426C67.9707 52.9622 67.8777 53.0486 67.7647 53.0885H67.7514Z" fill="white"/>
<path d="M47.9886 85.3033V85.2966C47.2443 85.5425 46.4868 84.991 46.4868 84.2069C46.4868 84.0939 46.4868 84.0939 46.4868 83.9876C46.4868 83.4892 46.8124 83.0506 47.2842 82.8978V82.8912C48.0284 82.6453 48.786 83.2035 48.786 83.9876C48.786 84.1005 48.7926 84.1005 48.7926 84.2069C48.7926 84.7052 48.4737 85.1505 47.9952 85.3033H47.9886Z" fill="#ABBBC1"/>
<path d="M51.5108 84.1534C50.7666 84.3993 50.0024 83.8411 50.0024 83.057C50.0024 82.944 50.0024 82.944 50.0024 82.8377C50.0024 82.3393 50.3214 81.8941 50.7998 81.7413C51.5441 81.4954 52.3149 82.0602 52.3149 82.8443C52.3149 82.9573 52.3082 82.9573 52.3082 83.0636C52.3082 83.562 51.9893 84.0006 51.5175 84.1534H51.5108Z" fill="#ABBBC1"/>
<path d="M55.0323 83.0039C54.2881 83.2497 53.5239 82.6982 53.5239 81.9141C53.5239 81.8011 53.5239 81.8011 53.5239 81.6948C53.5239 81.1964 53.8495 80.7579 54.3213 80.605C55.0656 80.3592 55.8297 80.9173 55.8297 81.7014C55.8297 81.8144 55.8364 81.8144 55.8364 81.9207C55.8364 82.4191 55.5108 82.8643 55.039 83.0171L55.0323 83.0039Z" fill="#ABBBC1"/>
<path d="M58.5543 81.8609C57.8101 82.1068 57.0459 81.5486 57.0459 80.7645C57.0459 80.6515 57.0459 80.6515 57.0459 80.5452C57.0459 80.0469 57.3582 79.6016 57.8367 79.4488C58.5809 79.2029 59.3517 79.7678 59.3517 80.5519C59.3517 80.6648 59.3517 80.6648 59.3517 80.7712C59.3517 81.2695 59.0261 81.7147 58.5543 81.8676V81.8609Z" fill="#ABBBC1"/>
<path d="M62.0829 80.7178C61.3387 80.9637 60.5679 80.4055 60.5679 79.6214C60.5679 79.5085 60.5745 79.5085 60.5745 79.4021C60.5745 78.9038 60.8935 78.4585 61.3653 78.3057C62.1095 78.0599 62.867 78.618 62.867 79.4021C62.867 79.5151 62.867 79.5151 62.867 79.6214C62.867 80.1198 62.5481 80.565 62.0763 80.7245L62.0829 80.7178Z" fill="#ABBBC1"/>
<path d="M65.5981 79.5552C64.8538 79.8011 64.083 79.2429 64.083 78.4588C64.083 78.3459 64.083 78.3459 64.083 78.2395C64.083 77.7412 64.402 77.296 64.8738 77.1431C65.618 76.8973 66.3822 77.4554 66.3822 78.2395C66.3822 78.3525 66.3822 78.3525 66.3822 78.4588C66.3822 78.9572 66.0566 79.3958 65.5848 79.5486L65.5981 79.5552Z" fill="#ABBBC1"/>
<path d="M47.9889 89.4363C47.2446 89.6821 46.4805 89.124 46.4805 88.3399C46.4805 88.2269 46.4805 88.2269 46.4805 88.1206C46.4805 87.6222 46.7994 87.177 47.2712 87.0242V87.0308C48.0155 86.7849 48.773 87.3365 48.773 88.1206C48.773 88.2335 48.773 88.2335 48.773 88.3399C48.773 88.8382 48.454 89.2768 47.9822 89.4296L47.9889 89.4363Z" fill="#ABBBC1"/>
<path d="M51.5108 88.2867C50.7666 88.5326 50.0024 87.9744 50.0024 87.1903C50.0024 87.0773 50.0024 87.0773 50.0024 86.971C50.0024 86.4726 50.3214 86.0341 50.7998 85.8812V85.8746C51.5441 85.6287 52.3082 86.1935 52.3082 86.9777C52.3082 87.0906 52.3082 87.0906 52.3082 87.1969C52.3082 87.6953 51.9826 88.1339 51.5108 88.2933V88.2867Z" fill="#ABBBC1"/>
<path d="M55.0323 87.1374V87.1441C54.2881 87.39 53.5239 86.8251 53.5239 86.041C53.5239 85.9281 53.5239 85.9281 53.5239 85.8217C53.5239 85.3234 53.8429 84.8782 54.3213 84.7253V84.732C55.0656 84.4861 55.8297 85.0376 55.8297 85.8217C55.8297 85.9347 55.8297 85.9347 55.8297 86.041C55.8297 86.5394 55.5041 86.978 55.0323 87.1308V87.1374Z" fill="#ABBBC1"/>
<path d="M58.5543 85.9876C57.8101 86.2334 57.0459 85.6752 57.0459 84.8911C57.0459 84.7782 57.0459 84.7782 57.0459 84.6719C57.0459 84.1735 57.3715 83.7349 57.8433 83.5821C58.5875 83.3362 59.3451 83.8944 59.3451 84.6785C59.3451 84.7915 59.3517 84.7915 59.3517 84.8978C59.3517 85.3962 59.0261 85.8347 58.5543 85.9876Z" fill="#ABBBC1"/>
<path d="M62.0765 84.8381C61.3322 85.084 60.5747 84.5258 60.5747 83.7484C60.5747 83.6354 60.5747 83.6354 60.5747 83.5291C60.5747 83.0307 60.9003 82.5855 61.3721 82.4327C62.1163 82.1868 62.8872 82.745 62.8872 83.5291C62.8872 83.6044 62.8872 83.6775 62.8872 83.7484C62.8872 84.2467 62.5616 84.6853 62.0831 84.8381H62.0765Z" fill="#ABBBC1"/>
<path d="M65.598 83.6954C64.8537 83.9412 64.0962 83.3831 64.0962 82.599C64.0962 82.486 64.0962 82.486 64.0962 82.3797C64.0962 81.8813 64.4152 81.4427 64.8869 81.2833C65.6312 81.0374 66.3887 81.5956 66.3887 82.3797C66.3887 82.4926 66.3887 82.4926 66.3887 82.599C66.3887 83.0973 66.0697 83.5425 65.598 83.6954Z" fill="#ABBBC1"/>
<path d="M47.9889 93.5694C47.2446 93.8153 46.4805 93.2571 46.4805 92.473C46.4805 92.36 46.4805 92.36 46.4805 92.2537C46.4805 91.7553 46.7994 91.3101 47.2779 91.1573C48.0221 90.9114 48.7796 91.4696 48.7796 92.2537C48.7796 92.3667 48.7929 92.3667 48.7929 92.473C48.7929 92.9714 48.4673 93.4099 47.9889 93.5628V93.5694Z" fill="#ABBBC1"/>
<path d="M51.5107 92.4265V92.4199C50.7664 92.6657 49.9956 92.1076 49.9956 91.3301C49.9956 91.2171 50.0023 91.2171 50.0023 91.1108C50.0023 90.6124 50.3212 90.1739 50.793 90.021C51.5372 89.7752 52.3014 90.3334 52.3014 91.1175C52.3014 91.2304 52.3014 91.2304 52.3014 91.3367C52.3014 91.8351 51.9824 92.2803 51.5107 92.4398V92.4265Z" fill="#ABBBC1"/>
<path d="M55.0323 91.2704V91.2771C54.2881 91.523 53.5239 90.9648 53.5239 90.1807C53.5239 90.0677 53.5239 90.0677 53.5239 89.9614C53.5239 89.463 53.8429 89.0178 54.3213 88.8583V88.8716C55.0656 88.6258 55.8297 89.1773 55.8297 89.9614C55.8297 90.0744 55.8297 90.0744 55.8297 90.1807C55.8297 90.679 55.5041 91.1176 55.0323 91.2704Z" fill="#ABBBC1"/>
<path d="M58.5546 90.1273C57.8104 90.3732 57.0396 89.8084 57.0396 89.0242C57.0396 88.9113 57.0396 88.9113 57.0396 88.805C57.0396 88.3066 57.3585 87.868 57.8369 87.7085C58.5812 87.4627 59.352 88.0209 59.352 88.805C59.352 88.9179 59.352 88.9179 59.352 89.0242C59.352 89.5226 59.033 89.9678 58.5612 90.1207L58.5546 90.1273Z" fill="#ABBBC1"/>
<path d="M62.0763 88.9775V88.9841C61.332 89.23 60.5679 88.6652 60.5679 87.8877C60.5679 87.7747 60.5679 87.7747 60.5679 87.6684C60.5679 87.17 60.8868 86.7248 61.3586 86.572V86.5786C62.1029 86.3328 62.8604 86.8843 62.8604 87.6684C62.8604 87.7814 62.8604 87.7814 62.8604 87.8877C62.8604 88.3861 62.5414 88.8246 62.0696 88.9775H62.0763Z" fill="#ABBBC1"/>
<path d="M65.5978 87.8281C64.8535 88.0739 64.0894 87.5224 64.0894 86.7383C64.0894 86.6253 64.0894 86.6253 64.0894 86.519C64.0894 86.0206 64.4083 85.5821 64.8868 85.4292C65.631 85.1834 66.3885 85.7349 66.3885 86.519C66.3885 86.632 66.3952 86.632 66.3952 86.7383C66.3952 87.2367 66.0762 87.6819 65.5978 87.8347V87.8281Z" fill="#ABBBC1"/>
<path d="M69.08 78.3059C68.3358 78.5518 67.5649 78.0002 67.5649 77.2161C67.5649 77.1032 67.5782 77.1032 67.5782 76.9969C67.5782 76.4985 67.8972 76.0599 68.369 75.9071V75.9004C69.1132 75.6546 69.8774 76.2128 69.8774 76.9969C69.8774 77.1098 69.8774 77.1098 69.8774 77.2161C69.8774 77.7145 69.5584 78.1597 69.08 78.3126V78.3059Z" fill="#ABBBC1"/>
<path d="M72.6082 77.1563C71.864 77.4022 71.1064 76.844 71.1064 76.0599C71.1064 75.9469 71.1064 75.9469 71.1064 75.8406C71.1064 75.3422 71.4254 74.897 71.8972 74.7442C72.6414 74.4983 73.4122 75.0565 73.4122 75.8406C73.4122 75.9536 73.4122 75.9536 73.4122 76.0599C73.4122 76.5583 73.0866 77.0035 72.6148 77.1563H72.6082Z" fill="#ABBBC1"/>
<path d="M76.1234 76.0069C75.3792 76.2528 74.615 75.6946 74.615 74.9105C74.615 74.7975 74.6084 74.7975 74.6084 74.6912C74.6084 74.1928 74.934 73.7476 75.4058 73.5948C76.15 73.3489 76.9142 73.9071 76.9142 74.6912C76.9142 74.8042 76.9142 74.8042 76.9142 74.9105C76.9142 75.4089 76.5886 75.8474 76.1102 76.0069H76.1234Z" fill="#ABBBC1"/>
<path d="M79.652 74.864C78.9077 75.1099 78.1436 74.5584 78.1436 73.7743C78.1436 73.6613 78.1502 73.6613 78.1502 73.555C78.1502 73.0566 78.4692 72.6181 78.9409 72.4652V72.4586C79.6852 72.2127 80.4494 72.7775 80.4494 73.5616C80.4494 73.6746 80.4494 73.6746 80.4494 73.7809C80.4494 74.2793 80.1238 74.7245 79.652 74.8773V74.864Z" fill="#ABBBC1"/>
<path d="M83.1739 73.7076C82.4297 73.9534 81.6655 73.3953 81.6655 72.6112C81.6655 72.4982 81.6655 72.4982 81.6655 72.3919C81.6655 71.8935 81.9845 71.4483 82.4563 71.2955C83.2005 71.0496 83.9647 71.6078 83.9647 72.3919C83.9647 72.5048 83.9647 72.5048 83.9647 72.6112C83.9647 73.1095 83.6457 73.5481 83.1739 73.7076Z" fill="#ABBBC1"/>
<path d="M69.0863 82.4457C68.3421 82.6915 67.5713 82.1267 67.5713 81.3426C67.5713 81.2296 67.5713 81.2296 67.5713 81.1233C67.5713 80.6249 67.8969 80.1797 68.3687 80.0269C69.1129 79.781 69.8771 80.3326 69.8771 81.1167C69.8771 81.2296 69.8771 81.2296 69.8771 81.3359C69.8771 81.8343 69.5581 82.2795 69.0863 82.4324V82.4457Z" fill="#ABBBC1"/>
<path d="M72.6017 81.2895C71.8574 81.5354 71.0999 80.9838 71.0999 80.1997C71.0999 80.0868 71.0933 80.0868 71.0933 79.9804C71.0933 79.4821 71.4189 79.0435 71.8907 78.8907C72.6349 78.6448 73.4057 79.203 73.4057 79.9871C73.4057 80.1001 73.4057 80.1001 73.4057 80.2064C73.4057 80.7047 73.0801 81.1433 72.6083 81.2961L72.6017 81.2895Z" fill="#ABBBC1"/>
<path d="M76.1234 80.1399V80.1465C75.3792 80.3924 74.6084 79.8342 74.6084 79.0501C74.6084 78.9371 74.6084 78.9371 74.6084 78.8308C74.6084 78.3325 74.9274 77.8872 75.3992 77.7278V77.7344C76.1434 77.4885 76.9076 78.0401 76.9076 78.8242C76.9076 78.9371 76.9076 78.9371 76.9076 79.0435C76.9076 79.5418 76.582 79.9804 76.1102 80.1332L76.1234 80.1399Z" fill="#ABBBC1"/>
<path d="M79.6523 78.9971C78.908 79.243 78.1372 78.6782 78.1372 77.8941C78.1372 77.7811 78.1372 77.7811 78.1372 77.6748C78.1372 77.1764 78.4628 76.7378 78.9346 76.585C79.6788 76.3391 80.4497 76.8907 80.4497 77.6748C80.4497 77.7877 80.443 77.7877 80.443 77.8941C80.443 78.3924 80.1307 78.8376 79.6523 78.9905V78.9971Z" fill="#ABBBC1"/>
<path d="M83.1737 77.8471C82.4295 78.093 81.6587 77.5281 81.6587 76.744C81.6587 76.6311 81.6587 76.6311 81.6587 76.5247C81.6587 76.0264 81.9843 75.5812 82.4561 75.4283C83.2003 75.1825 83.9645 75.7473 83.9645 76.5247C83.9645 76.6377 83.9645 76.6377 83.9645 76.744C83.9645 77.2424 83.6389 77.6876 83.1671 77.8404L83.1737 77.8471Z" fill="#ABBBC1"/>
<path d="M69.0797 86.5721C68.3355 86.8179 67.5713 86.2598 67.5713 85.4823C67.5713 85.3693 67.5713 85.3693 67.5713 85.263C67.5713 84.7646 67.8903 84.3194 68.3687 84.1666C69.1129 83.9207 69.8837 84.4856 69.8837 85.263C69.8837 85.376 69.8704 85.376 69.8704 85.4823C69.8704 85.9807 69.5581 86.4192 69.0797 86.5787V86.5721Z" fill="#ABBBC1"/>
<path d="M72.6083 85.4293C71.8641 85.6751 71.0933 85.1103 71.0933 84.3262C71.0933 84.2132 71.0933 84.2132 71.0933 84.1069C71.0933 83.6085 71.4122 83.17 71.8907 83.0171C72.6349 82.7713 73.3991 83.3295 73.3991 84.1136C73.3991 84.2265 73.4057 84.2265 73.4057 84.3328C73.4057 84.8312 73.0801 85.2764 72.6083 85.4293Z" fill="#ABBBC1"/>
<path d="M76.13 84.2798C75.3858 84.5257 74.6216 83.9675 74.6216 83.1834C74.6216 83.0705 74.6216 83.0705 74.6216 82.9641C74.6216 82.4658 74.9405 82.0272 75.4123 81.8677C76.1566 81.6219 76.9274 82.18 76.9274 82.9641C76.9274 83.0771 76.9207 83.0771 76.9207 83.1834C76.9207 83.6818 76.6084 84.127 76.13 84.2798Z" fill="#ABBBC1"/>
<path d="M79.652 83.1303C78.9077 83.3762 78.1436 82.818 78.1436 82.0406C78.1436 81.9276 78.1436 81.9276 78.1436 81.8213C78.1436 81.3229 78.4692 80.8843 78.9409 80.7315C79.6852 80.4856 80.4494 81.0438 80.4494 81.8279C80.4494 81.9409 80.4494 81.9409 80.4494 82.0472C80.4494 82.5456 80.1304 82.9908 79.6586 83.1436L79.652 83.1303Z" fill="#ABBBC1"/>
<path d="M83.1736 81.9809C82.4294 82.2267 81.6719 81.6619 81.6719 80.8778C81.6719 80.7648 81.6719 80.7648 81.6719 80.6585C81.6719 80.1602 81.9908 79.7216 82.4626 79.5621C83.2069 79.3162 83.971 79.8811 83.971 80.6585C83.971 80.7715 83.971 80.7715 83.971 80.8778C83.971 81.3762 83.6521 81.8214 83.1736 81.9742V81.9809Z" fill="#ABBBC1"/>
<path d="M88.2707 85.2698C84.4499 86.5125 84.4034 86.3663 80.5825 87.6089C76.7617 88.8515 76.775 88.898 72.9541 90.1406C69.1333 91.3832 69.1798 91.536 65.3589 92.7853C61.5381 94.0346 61.5048 93.9282 57.684 95.1708C53.8631 96.4134 53.8831 96.4732 50.0556 97.7225C46.2281 98.9718 46.2015 98.8787 42.3806 100.128M42.3806 100.128C42.3607 100.135 42.3806 100.155 42.3806 100.128ZM42.3806 100.128C42.3806 95.6559 42.4072 95.6559 42.4072 91.1839C42.4072 86.7118 42.2544 86.7118 42.2544 82.2397" stroke="#80949C" stroke-width="0.888897" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M82.8152 66.0327C78.6023 67.4082 78.5491 67.262 74.3362 68.6375C70.1233 70.013 70.1233 70.0263 65.9104 71.4018C61.6975 72.7773 61.7241 72.877 57.5112 74.2525C53.2983 75.628 53.285 75.6081 49.0721 76.9836C47.7963 77.4022 46.4872 76.4321 46.4872 75.0964C46.4872 71.5082 46.4673 71.5082 46.4673 67.9265" stroke="#FFF3E2" stroke-width="0.888897" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M47.8364 35.439C52.0493 34.0635 52.0826 34.1698 56.3021 32.7943C60.5217 31.4188 60.5084 31.3989 64.7213 30.0234C68.9342 28.6479 68.9342 28.6279 73.1471 27.2524C77.36 25.8769 77.34 25.8105 81.5596 24.4349C82.8354 24.0163 84.2309 24.9998 84.2309 26.342C84.2309 28.9602 84.2176 28.9602 84.2176 31.5783" stroke="#F9A619" stroke-width="0.888897" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_4032_107537">
<rect width="118" height="100" fill="white" transform="translate(0.5 0.5)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -569,6 +569,7 @@ export const ACTION_CONFIGURATION_UPDATED = () => "Configuration updated";
export const WIDGET_PROPERTIES_UPDATED = () => "Widget properties were updated";
export const EMPTY_RESPONSE_FIRST_HALF = () => "🙌 Click on";
export const EMPTY_RESPONSE_LAST_HALF = () => "to get a response";
export const EMPTY_RESPONSE_RUN = () => "Click Run to get a response";
export const EMPTY_JS_RESPONSE_LAST_HALF = () =>
"to view response of selected function";
export const INVALID_EMAIL = () => "Please enter a valid email";

View File

@ -21,13 +21,12 @@ const LoadingOverlayContainer = styled.div`
flex-direction: column;
justify-content: center;
align-items: center;
gap: var(--ads-v2-spaces-3);
gap: var(--ads-v2-spaces-5);
background-color: transparent;
position: relative;
z-index: 20;
width: 100%;
height: 100%;
margin-top: 5px;
`;
const LoadingProgressWrapper = styled.div`
@ -56,7 +55,7 @@ const ActionExecutionInProgressView = ({
<LoadingProgressWrapper>
<LoadingOverlayScreen theme={theme} />
<LoadingOverlayContainer>
<Spinner size="md" />
<Spinner size="lg" />
<InProgressText kind="body-m" renderAs="p">
{createMessage(ACTION_EXECUTION_MESSAGE, actionType)}
</InProgressText>
@ -64,7 +63,7 @@ const ActionExecutionInProgressView = ({
className={`t--cancel-action-button`}
kind="secondary"
onClick={handleCancelActionExecution}
size="md"
size="sm"
>
{createMessage(ACTION_EXECUTION_CANCEL)}
</Button>

View File

@ -24,8 +24,10 @@ const TabPanelWrapper = styled(TabPanel)`
`;
const TabsListWrapper = styled(TabsList)`
padding: calc(var(--ads-v2-spaces-1) + 2px) var(--ads-v2-spaces-7)
var(--ads-v2-spaces-1);
&& {
padding: var(--ads-v2-spaces-2);
padding-bottom: var(--ads-v2-spaces-1);
}
`;
export interface BottomTab {

View File

@ -12,7 +12,7 @@ import { EditorViewMode } from "ee/entities/IDE/constants";
import type { JSCollectionData } from "ee/reducers/entityReducers/jsActionsReducer";
import { PluginType } from "entities/Action";
import "@testing-library/jest-dom/extend-expect";
import { EMPTY_RESPONSE_LAST_HALF } from "ee/constants/messages";
import { EMPTY_RESPONSE_RUN } from "ee/constants/messages";
import { DEBUGGER_TAB_KEYS } from "./Debugger/constants";
jest.mock("ee/utils/actionExecutionUtils");
@ -116,7 +116,7 @@ describe("JSResponseView", () => {
</Provider>,
);
expect(getByText(EMPTY_RESPONSE_LAST_HALF())).toBeInTheDocument();
expect(getByText(EMPTY_RESPONSE_RUN())).toBeInTheDocument();
});
it("should render correctly when isBrowserExecutionAllowed returns false", () => {
@ -144,7 +144,7 @@ describe("JSResponseView", () => {
</Provider>,
);
// nothing should be rendered here since the implementation for component is in EE code
expect(queryByText(document.body, EMPTY_RESPONSE_LAST_HALF())).toBeNull();
expect(queryByText(document.body, EMPTY_RESPONSE_RUN())).toBeNull();
});
it("the container should have class select-text to enable the selection of text for user", () => {

View File

@ -1,5 +1,5 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import { render } from "@testing-library/react";
import configureStore from "redux-mock-store";
import { Provider } from "react-redux";
import { ThemeProvider } from "styled-components";
@ -10,36 +10,9 @@ import { EditorViewMode } from "ee/entities/IDE/constants";
import "@testing-library/jest-dom/extend-expect";
import QueryDebuggerTabs from "./QueryDebuggerTabs";
import { ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
import type { ActionResponse } from "api/ActionAPI";
const mockStore = configureStore([]);
const mockSuccessResponse: ActionResponse = {
body: ["Record 1", "Record 2"],
statusCode: "200",
dataTypes: [],
duration: "3000",
size: "200",
isExecutionSuccess: true,
headers: {
"Content-Type": ["application/json"],
"Cache-Control": ["no-cache"],
},
};
const mockFailedResponse: ActionResponse = {
body: [{ response: "Failed" }],
statusCode: "200",
dataTypes: [],
duration: "3000",
size: "200",
isExecutionSuccess: false,
headers: {
"Content-Type": ["application/json"],
"Cache-Control": ["no-cache"],
},
};
const storeState = {
...unitTestBaseMockStore,
evaluations: {
@ -113,59 +86,4 @@ describe("ApiResponseView", () => {
?.classList.contains("select-text"),
).toBe(true);
});
it("should show record count as result if the query response returns records", () => {
render(
<Provider store={store}>
<ThemeProvider theme={lightTheme}>
<Router>
<QueryDebuggerTabs
actionName="Query1"
actionResponse={mockSuccessResponse}
actionSource={{
id: "ID1",
name: "Query1",
type: ENTITY_TYPE.ACTION,
}}
isRunning={false}
onRunClick={() => {}}
/>
</Router>
</ThemeProvider>
</Provider>,
);
const expectedResultText = "Result: 2 Records";
const resultTextElement = screen.getByTestId("result-text");
expect(resultTextElement).toBeInTheDocument();
expect(resultTextElement?.textContent).toContain(expectedResultText);
});
it("should show error as result if the query response returns the error", () => {
render(
<Provider store={store}>
<ThemeProvider theme={lightTheme}>
<Router>
<QueryDebuggerTabs
actionName="Query1"
actionResponse={mockFailedResponse}
actionSource={{
id: "ID1",
name: "Query1",
type: ENTITY_TYPE.ACTION,
}}
isRunning={false}
onRunClick={() => {}}
/>
</Router>
</ThemeProvider>
</Provider>,
);
const expectedResultText = "Result: Error";
const resultTextElement = screen.getByTestId("result-text");
expect(resultTextElement).toBeInTheDocument();
expect(resultTextElement?.textContent).toContain(expectedResultText);
});
});

View File

@ -2,9 +2,7 @@ import type { BottomTab } from "components/editorComponents/EntityBottomTabs";
import EntityBottomTabs from "components/editorComponents/EntityBottomTabs";
import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import styled from "styled-components";
import { getErrorCount } from "selectors/debuggerSelectors";
import { Text, TextType } from "@appsmith/ads-old";
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/constants";
import {
DEBUGGER_ERRORS,
@ -16,7 +14,6 @@ import DebuggerLogs from "components/editorComponents/Debugger/DebuggerLogs";
import ErrorLogs from "components/editorComponents/Debugger/Errors";
import { Schema } from "PluginActionEditor/components/PluginActionResponse/components/Schema";
import type { ActionResponse } from "api/ActionAPI";
import { isString } from "lodash";
import type { SourceEntity } from "entities/AppsmithConsole";
import type { Action } from "entities/Action";
import QueryResponseTab from "PluginActionEditor/components/PluginActionResponse/components/QueryResponseTab";
@ -37,17 +34,6 @@ import { getIDEViewMode } from "selectors/ideSelectors";
import { EditorViewMode } from "ee/entities/IDE/constants";
import { IDEBottomView, ViewHideBehaviour } from "IDE";
const ResultsCount = styled.div`
position: absolute;
right: ${(props) => props.theme.spaces[17] + 1}px;
top: 9px;
color: var(--ads-v2-color-fg);
`;
const ErrorText = styled(Text)`
color: var(--ads-v2-colors-action-error-label-default-fg);
`;
interface QueryDebuggerTabsProps {
actionSource: SourceEntity;
currentActionConfig?: Action;
@ -71,9 +57,6 @@ function QueryDebuggerTabs({
runErrorMessage,
showSchema,
}: QueryDebuggerTabsProps) {
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let output: Record<string, any>[] | null = null;
const dispatch = useDispatch();
const { open, responseTabHeight, selectedTab } = useSelector(
@ -172,27 +155,6 @@ function QueryDebuggerTabs({
}
}, [currentActionConfig?.id]);
// Query is executed even once during the session, show the response data.
if (actionResponse) {
if (isString(actionResponse.body)) {
try {
// Try to parse response as JSON array to be displayed in the Response tab
output = JSON.parse(actionResponse.body);
} catch (e) {
// In case the string is not a JSON, wrap it in a response object
output = [
{
response: actionResponse.body,
},
];
}
} else {
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
output = actionResponse.body as any;
}
}
const setQueryResponsePaneHeight = useCallback(
(height: number) => {
dispatch(
@ -276,21 +238,6 @@ function QueryDebuggerTabs({
onHideClick={onToggle}
setHeight={setQueryResponsePaneHeight}
>
{output && !!output.length && (
<ResultsCount>
<Text data-testid="result-text" type={TextType.P3}>
Result:
{actionResponse?.isExecutionSuccess ? (
<Text type={TextType.H5}>{` ${output.length} Record${
output.length > 1 ? "s" : ""
}`}</Text>
) : (
<ErrorText type={TextType.H5}>{" Error"}</ErrorText>
)}
</Text>
</ResultsCount>
)}
<EntityBottomTabs
isCollapsed={!open}
onSelect={setSelectedResponseTab}