fix: UI inconsistency in log tab (#21037)

> This includes fixes to Ui inconsistencies in the
Error|Respionse|header|lLog tab for the entity.

> Please delete options that are not relevant.

- Bug fix (non-breaking change which fixes an issue)

- Manual
- Not including cypress as we are going to change the UI in the upcoming
phases of error handling

> Add Testsmith test cases links that relate to this PR

> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag

- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test

(cherry picked from commit 2f435d90e7)
This commit is contained in:
ChandanBalajiBP 2023-03-03 18:14:41 +05:30 committed by Goutham Pratapa
parent 26f33be81a
commit f7f21e6a5b
10 changed files with 137 additions and 112 deletions

View File

@ -34,11 +34,11 @@ describe("Chart Widget Skeleton Loading Functionality", function() {
//Step3 & 4
cy.get(`${datasource.datasourceCard}`)
.filter(":contains('Users')")
.last()
.within(() => {
cy.get(`${datasource.createQuery}`).click({ force: true });
});
.filter(":contains('Users')")
.last()
.within(() => {
cy.get(`${datasource.createQuery}`).click({ force: true });
});
//Step5.1: Click the editing field
cy.get(".t--action-name-edit-field").click({ force: true });

View File

@ -3,20 +3,20 @@ import homePage from "../../../../locators/HomePage";
import * as _ from "../../../../support/Objects/ObjectsCore";
describe("Delete workspace test spec", function() {
let newWorkspaceName
let newWorkspaceName;
it("1. Should delete the workspace", function() {
cy.visit("/applications");
cy.generateUUID().then((uid) => {
newWorkspaceName = uid;
_.homePage.CreateNewWorkspace(newWorkspaceName);
cy.wait(500);
cy.contains("Delete Workspace").click();
cy.contains("Are you sure").click();
cy.wait("@deleteWorkspaceApiCall").then((httpResponse) => {
expect(httpResponse.status).to.equal(200);
});
cy.get(newWorkspaceName).should("not.exist");
cy.wait(500);
cy.contains("Delete Workspace").click();
cy.contains("Are you sure").click();
cy.wait("@deleteWorkspaceApiCall").then((httpResponse) => {
expect(httpResponse.status).to.equal(200);
});
cy.get(newWorkspaceName).should("not.exist");
});
});
@ -26,24 +26,21 @@ describe("Delete workspace test spec", function() {
cy.generateUUID().then((uid) => {
newWorkspaceName = uid;
_.homePage.CreateNewWorkspace(newWorkspaceName);
cy.wait(500);
cy.contains("Delete Workspace");
_.homePage.InviteUserToWorkspace(
newWorkspaceName,
Cypress.env("TESTUSERNAME1"),
"App Viewer",
);
cy.LogOut();
cy.LogintoApp(
Cypress.env("TESTUSERNAME1"),
Cypress.env("TESTPASSWORD1"),
);
cy.visit("/applications");
cy.openWorkspaceOptionsPopup(newWorkspaceName);
cy.get(homePage.workspaceNamePopoverContent)
.contains("Delete Workspace")
.should("not.exist");
cy.LogOut();
cy.wait(500);
cy.contains("Delete Workspace");
_.homePage.InviteUserToWorkspace(
newWorkspaceName,
Cypress.env("TESTUSERNAME1"),
"App Viewer",
);
cy.LogOut();
cy.LogintoApp(Cypress.env("TESTUSERNAME1"), Cypress.env("TESTPASSWORD1"));
cy.visit("/applications");
cy.openWorkspaceOptionsPopup(newWorkspaceName);
cy.get(homePage.workspaceNamePopoverContent)
.contains("Delete Workspace")
.should("not.exist");
cy.LogOut();
});
});
});

View File

@ -50,7 +50,7 @@
"cypress-log-to-output": "^1.1.2",
"dayjs": "^1.10.6",
"deep-diff": "^1.0.2",
"design-system-old": "npm:@appsmithorg/design-system-old@1.0.50",
"design-system-old": "npm:@appsmithorg/design-system-old@1.0.52",
"downloadjs": "^1.4.7",
"draft-js": "^0.11.7",
"exceljs": "^4.3.0",

View File

@ -81,6 +81,9 @@ const ResponseContainer = styled.div`
.react-tabs__tab-panel {
overflow: hidden;
}
.CodeMirror-code {
font-size: 12px;
}
`;
const ResponseMetaInfo = styled.div`
display: flex;
@ -165,12 +168,17 @@ const FailedMessage = styled.div`
.api-debugcta {
margin-top: 0px;
height: 26px;
}
`;
const StyledCallout = styled(Callout)`
.${Classes.TEXT} {
line-height: normal;
font-size: 12px;
}
.${Classes.ICON} {
width: 16px;
}
`;

View File

@ -152,7 +152,7 @@ const searchAction: Record<
if (intercomAppID && window.Intercom) {
window.Intercom(
"showNewMessage",
createMessage(DEBUGGER_INTERCOM_TEXT, error.message),
createMessage(DEBUGGER_INTERCOM_TEXT, error.message.message),
);
}
},
@ -195,8 +195,8 @@ const MenuItem = styled.a`
align-items: center;
justify-content: space-between;
text-decoration: none;
padding: 0px ${(props) => props.theme.spaces[6]}px;
height: 40px;
padding: 8px ${(props) => props.theme.spaces[7]}px;
height: 36px;
.${Classes.TEXT} {
color: ${(props) => props.theme.colors.menuItem.hoverText};
@ -234,7 +234,7 @@ export default function ContextualMenu(props: ContextualMenuProps) {
<Popover2
className="t--debugger-contextual-error-menu"
content={
<MenuWrapper width={"264px"}>
<MenuWrapper width={"200px"}>
{options.map((e) => {
const menuProps = searchAction[e];
const onSelect = () => {
@ -258,9 +258,9 @@ export default function ContextualMenu(props: ContextualMenuProps) {
<Icon
fillColor="#858282"
name={menuProps.icon}
size={IconSize.SMALL}
size={IconSize.XL}
/>
<Text type={TextType.P1} weight={FontWeight.NORMAL}>
<Text type={TextType.P3} weight={FontWeight.NORMAL}>
{menuProps.text}
</Text>
</IconContainer>

View File

@ -32,6 +32,7 @@ import ContextualMenu from "../ContextualMenu";
import LogEntityLink from "./components/LogEntityLink";
import LogTimeStamp from "./components/LogTimeStamp";
import { getLogIcon } from "../helpers";
import moment from "moment";
const InnerWrapper = styled.div`
display: flex;
@ -42,7 +43,7 @@ const InnerWrapper = styled.div`
const Wrapper = styled.div<{ collapsed: boolean }>`
display: flex;
flex-direction: column;
padding: 6px 12px 6px 12px;
padding: 8px 16px 8px 16px;
cursor: default;
&.${Severity.INFO} {
@ -143,11 +144,11 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
`;
const StyledSearchIcon = styled(AppIcon)`
height: 14px;
width: 14px;
height: 16px;
width: 16px;
svg {
height: 14px;
width: 14px;
height: 16px;
width: 16px;
}
`;
@ -167,6 +168,19 @@ const showToggleIcon = (e: Log) => {
return !!e.state;
};
//format the requestedAt timestamp to a readable format.
const getUpdateTimestamp = (state?: Record<string, any>) => {
if (state) {
//clone state to avoid mutating the original state.
const copyState = JSON.parse(JSON.stringify(state));
copyState.requestedAt = moment(copyState.requestedAt).format(
"YYYY-MM-DD HH:mm:ss",
);
return copyState;
}
return state;
};
// returns required parameters for log item
export const getLogItemProps = (e: Log) => {
return {
@ -181,7 +195,7 @@ export const getLogItemProps = (e: Log) => {
timeTaken: e.timeTaken ? `${e.timeTaken}ms` : "",
severity: e.severity,
text: e.text,
state: e.state,
state: getUpdateTimestamp(e.state),
id: e.source ? e.source.id : undefined,
messages: e.messages,
collapsable: showToggleIcon(e),
@ -232,7 +246,7 @@ function ErrorLogItem(props: LogItemProps) {
: ""
}
name={props.icon}
size={IconSize.SMALL}
size={IconSize.XL}
/>
{props.logType &&
@ -253,7 +267,7 @@ function ErrorLogItem(props: LogItemProps) {
fillColor={get(theme, "colors.debugger.collapseIcon")}
name={"expand-more"}
onClick={() => setIsOpen(!isOpen)}
size={IconSize.MEDIUM}
size={IconSize.XL}
/>
)}
<div className={`debugger-error-type`}>

View File

@ -12,7 +12,7 @@ const StyledCollapse = styled(Collapse)<StyledCollapseProps>`
props.isOpen && props.category === LOG_CATEGORY.USER_GENERATED
? " -20px"
: " 4px"};
padding-left: 83px;
padding-left: 87px;
`;
type StyledCollapseProps = PropsWithChildren<{

View File

@ -45,24 +45,24 @@ export default function LogEntityLink(props: LogItemProps) {
// If the source is a widget.
if (props.source.type === ENTITY_TYPE.WIDGET && props.source.pluginType) {
return (
<WidgetIcon height={12} type={props.source.pluginType} width={12} />
<WidgetIcon height={16} type={props.source.pluginType} width={16} />
);
}
// If the source is a JS action.
else if (props.source.type === ENTITY_TYPE.JSACTION) {
return JsFileIconV2(12, 12);
return JsFileIconV2(16, 16);
} else if (props.source.type === ENTITY_TYPE.ACTION) {
// If the source is an API action.
if (
props.source.pluginType === PluginType.API &&
props.source.httpMethod
) {
return ApiMethodIcon(props.source.httpMethod, "9px", "17px", 28);
return ApiMethodIcon(props.source.httpMethod, "16px", "32px", 50);
}
// If the source is a Datasource action.
else if (props.iconId && pluginGroups[props.iconId]) {
return (
<EntityIcon height={"12px"} width={"12px"}>
<EntityIcon height={"16px"} width={"16px"}>
<img
alt="entityIcon"
src={pluginGroups[props.iconId].iconLocation}

View File

@ -38,7 +38,6 @@ const InnerWrapper = styled.div`
`;
const Wrapper = styled.div<{ collapsed: boolean }>`
display: flex;
flex-direction: column;
padding: 8px 16px 8px 16px;
@ -49,10 +48,8 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
}
&.${Severity.ERROR} {
background-color: ${(props) =>
props.theme.colors.debugger.error.backgroundColor};
border-bottom: 1px solid
${(props) => props.theme.colors.debugger.error.borderBottom};
background-color: #fff8f8;
border-bottom: 1px solid #ffebeb;
}
&.${Severity.WARNING} {
@ -62,10 +59,6 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
${(props) => props.theme.colors.debugger.warning.borderBottom};
}
.bp3-popover-target {
display: inline;
}
.${Classes.ICON} {
display: inline-block;
}
@ -75,12 +68,13 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
props.collapsed
? `transform: rotate(-90deg);`
: `transform: rotate(0deg); `};
}
padding-right: 4px;
}
.debugger-time {
${getTypographyByKey("h6")}
line-height: 16px;
margin-left: 8px;
margin-right: 18px;
letter-spacing: -0.24px;
margin-left: 4px;
margin-right: 4px;
&.${Severity.INFO} {
color: ${(props) => props.theme.colors.debugger.info.time};
}
@ -93,9 +87,9 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
color: ${(props) => props.theme.colors.debugger.warning.time};
}
}
.debugger-occurences{
height: 18px;
width: 18px;
.debugger-occurences {
height: 16px;
width: 16px;
border-radius: 36px;
display: inline-flex;
align-items: center;
@ -123,13 +117,16 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
.debugger-label {
color: ${(props) => props.theme.colors.debugger.label};
${getTypographyByKey("p1")}
line-height: 14px;
font-size: 12px;
padding-right: 4px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
-webkit-user-select: all; /* Chrome 49+ */
-moz-user-select: all; /* Firefox 43+ */
-ms-user-select: all; /* No support yet */
user-select: all; /* Likely future */
-webkit-user-select: all; /* Chrome 49+ */
-moz-user-select: all; /* Firefox 43+ */
-ms-user-select: all; /* No support yet */
user-select: all; /* Likely future */
}
.debugger-entity {
color: ${(props) => props.theme.colors.debugger.entity};
@ -156,7 +153,7 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
.debugger-entity-link {
margin-left: auto;
${getTypographyByKey("btnMedium")}
${getTypographyByKey("btnMedium")};
color: ${(props) => props.theme.colors.debugger.entityLink};
text-transform: uppercase;
cursor: pointer;
@ -164,12 +161,20 @@ const Wrapper = styled.div<{ collapsed: boolean }>`
`;
const StyledSearchIcon = styled(AppIcon)`
&& {
margin-left: 10px;
padding-top: 3px;
height: 14px;
width: 14px;
svg {
height: 14px;
width: 14px;
}
`;
const ContextWrapper = styled.div`
height: 14px;
display: flex;
align-items: center;
`;
const JsonWrapper = styled.div`
padding-top: ${(props) => props.theme.spaces[1]}px;
svg {
@ -185,17 +190,18 @@ type StyledCollapseProps = PropsWithChildren<{
}>;
const StyledCollapse = styled(Collapse)<StyledCollapseProps>`
margin-top:${(props) =>
props.isOpen && props.category === LOG_CATEGORY.USER_GENERATED
? " -20px"
: " 4px"} ;
margin-left: 120px;
margin-top: ${(props) =>
props.isOpen && props.category === LOG_CATEGORY.USER_GENERATED
? " -20px"
: " 4px"};
margin-left: 92px;
.debugger-message {
${getTypographyByKey("p2")}
line-height: 14px;
letter-spacing: -0.24px;
font-size: 12px;
color: ${(props) => props.theme.colors.debugger.message};
text-decoration-line: underline;
cursor: pointer;
}
.${Classes.ICON} {
@ -204,7 +210,7 @@ margin-top:${(props) =>
`;
const MessageWrapper = styled.div`
padding-top: ${(props) => props.theme.spaces[1]}px;
line-height: 14px;
`;
const showToggleIcon = (e: Log) => {
@ -264,15 +270,15 @@ function LogItem(props: LogItemProps) {
displayObjectSize: false,
displayDataTypes: false,
style: {
fontSize: "13px",
fontFamily:
"-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue",
fontSize: "11px",
fontWeight: "400",
letterSpacing: "-0.195px",
lineHeight: "13px",
},
collapsed: 1,
};
// The error to sent to the contextual menu
const errorToSearch =
props.messages && props.messages.length
? props.messages[0]
: { message: { name: "", message: props.text } };
const messages = props.messages || [];
const { collapsable } = props;
@ -286,15 +292,6 @@ function LogItem(props: LogItemProps) {
}}
>
<InnerWrapper>
<Icon
className={`${Classes.ICON} debugger-toggle`}
clickable={collapsable}
fillColor={get(theme, "colors.debugger.jsonIcon")}
invisible={!collapsable}
name={"expand-more"}
onClick={() => setIsOpen(!isOpen)}
size={IconSize.XXXXL}
/>
<Icon
clickable={collapsable}
fillColor={
@ -308,6 +305,16 @@ function LogItem(props: LogItemProps) {
<span className={`debugger-time ${props.severity}`}>
{props.timestamp}
</span>
<Icon
className={`${Classes.ICON} debugger-toggle`}
clickable={collapsable}
fillColor={get(theme, "colors.debugger.jsonIcon")}
invisible={!collapsable}
name={"expand-more"}
onClick={() => setIsOpen(!isOpen)}
size={IconSize.XL}
/>
{!(
props.collapsable &&
isOpen &&
@ -335,8 +342,11 @@ function LogItem(props: LogItemProps) {
)}
{props.category === LOG_CATEGORY.PLATFORM_GENERATED &&
props.severity === Severity.ERROR && (
<div onClick={(e) => e.stopPropagation()}>
<ContextualMenu entity={props.source} error={errorToSearch}>
<ContextWrapper onClick={(e) => e.stopPropagation()}>
<ContextualMenu
entity={props.source}
error={{ message: { name: "", message: "" } }}
>
<TooltipComponent
content={
<Text style={{ color: "#ffffff" }} type={TextType.P3}>
@ -353,7 +363,7 @@ function LogItem(props: LogItemProps) {
/>
</TooltipComponent>
</ContextualMenu>
</div>
</ContextWrapper>
)}
</div>
)}
@ -379,13 +389,9 @@ function LogItem(props: LogItemProps) {
key={e.message.message}
onClick={(e) => e.stopPropagation()}
>
<ContextualMenu entity={props.source} error={e}>
<span className="debugger-message t--debugger-message">
{isString(e.message)
? e.message
: JSON.stringify(e.message)}
</span>
</ContextualMenu>
<span className="debugger-message t--debugger-message">
{isString(e.message) ? e.message : e.message.message}
</span>
</MessageWrapper>
);
})}

View File

@ -6587,10 +6587,10 @@ depd@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
"design-system-old@npm:@appsmithorg/design-system-old@1.0.50":
version "1.0.50"
resolved "https://registry.yarnpkg.com/@appsmithorg/design-system-old/-/design-system-old-1.0.50.tgz#5d41257c71bf0ba8620858bec9a79b70090c9857"
integrity sha512-0SgeKURwh7XvMmeYv3Yz3ldCgjuBW6yD1hnXc/9Pndm1Rtcth34jjvsqtUfZmh1Dvs7xhbtOtCAxfHEPKZ4wQg==
"design-system-old@npm:@appsmithorg/design-system-old@1.0.52":
version "1.0.52"
resolved "https://registry.yarnpkg.com/@appsmithorg/design-system-old/-/design-system-old-1.0.52.tgz#031b179a9b3689a081e29c3994b7296935fa3edb"
integrity sha512-iB20Dhq+BGS1vac18UtgC+mSLCAOGLH3FpVGMyfVuw+S2ZugqECnLSLmpPYGDN4Bx9ohWqYTR1CQoJgTK1kw1w==
dependencies:
emoji-mart "3.0.1"