Skip to content

Commit

Permalink
ui: Add column selector and filter including session details to the s…
Browse files Browse the repository at this point in the history
…ession overview page

Previously, the sessions page was missing the column selector and filter
components that the stmts and txns page have. This change adds both
components in addition to new columns in the sessions overview page and
edits to the sessions details page.

Release note (ui change): added column selector, filters, new columns to
the sessions page and sessions details.
  • Loading branch information
Gerardo Torres committed Feb 7, 2022
1 parent 7bd7ec0 commit a7a0ecf
Show file tree
Hide file tree
Showing 15 changed files with 750 additions and 246 deletions.
13 changes: 8 additions & 5 deletions pkg/ui/workspaces/cluster-ui/src/icon/circleFilled.tsx
Expand Up @@ -14,8 +14,11 @@ interface IconProps {
className: string;
}

export const CircleFilled = ({ className, ...props }: IconProps) => (
<svg viewBox="0 0 12 12" className={className} {...props}>
<circle cx="6" cy="6" r="6" fillRule="evenodd" />
</svg>
);
export function CircleFilled(props: IconProps) {
const { className } = props;
return (
<svg className={className} {...props}>
<circle cx="5" cy="5" r="5" />
</svg>
);
}
13 changes: 10 additions & 3 deletions pkg/ui/workspaces/cluster-ui/src/queryFilter/filter.tsx
Expand Up @@ -69,6 +69,7 @@ export interface Filters {
const timeUnit = [
{ label: "seconds", value: "seconds" },
{ label: "milliseconds", value: "milliseconds" },
{ label: "minutes", value: "minutes" },
];

export const defaultFilters: Filters = {
Expand Down Expand Up @@ -239,9 +240,15 @@ export const calculateActiveFilters = (filters: Filters): number => {

export const getTimeValueInSeconds = (filters: Filters): number | "empty" => {
if (filters.timeNumber === "0") return "empty";
return filters.timeUnit === "seconds"
? Number(filters.timeNumber)
: Number(filters.timeNumber) / 1000;
switch (filters.timeUnit) {
case "seconds":
return Number(filters.timeNumber);
case "minutes":
return Number(filters.timeNumber) * 60;
default:
// Milliseconds
return Number(filters.timeNumber) / 1000;
}
};

export class Filter extends React.Component<QueryFilter, FilterState> {
Expand Down
Expand Up @@ -50,3 +50,21 @@
box-shadow: 0 1px 0 #dbe1ea;
}
}

.session-details-link a {
color: $colors--link;
}

.session-status-icon {
&__active {
height: 10px;
width: 20px;
fill: $colors--primary-green-3;
}

&__idle {
height: 10px;
width: 20px;
fill: $colors--functional-orange-3;
}
}
88 changes: 64 additions & 24 deletions pkg/ui/workspaces/cluster-ui/src/sessions/sessionDetails.tsx
Expand Up @@ -50,6 +50,7 @@ import statementsPageStyles from "src/statementsPage/statementsPage.module.scss"
import styles from "./sessionDetails.module.scss";
import classNames from "classnames/bind";
import { commonStyles } from "src/common";
import { CircleFilled } from "../icon";

const cx = classNames.bind(styles);
const statementsPageCx = classNames.bind(statementsPageStyles);
Expand Down Expand Up @@ -279,12 +280,7 @@ export class SessionDetails extends React.Component<SessionDetailsProps> {
<Col className="gutter-row" span={4} />
<Col className="gutter-row" span={10}>
<SummaryCardItem
label={"Priority"}
value={txn.priority}
className={cx("details-item")}
/>
<SummaryCardItem
label={"Read Only?"}
label={"Read Only"}
value={yesOrNo(txn.read_only)}
className={cx("details-item")}
/>
Expand All @@ -293,6 +289,11 @@ export class SessionDetails extends React.Component<SessionDetailsProps> {
value={yesOrNo(txn.is_historical)}
className={cx("details-item")}
/>
<SummaryCardItem
label={"Priority"}
value={txn.priority}
className={cx("details-item")}
/>
<MemoryUsageItem
alloc_bytes={txn.alloc_bytes}
max_alloc_bytes={txn.max_alloc_bytes}
Expand Down Expand Up @@ -320,19 +321,28 @@ export class SessionDetails extends React.Component<SessionDetailsProps> {
value={TimestampToMoment(stmt.start).format(DATE_FORMAT)}
className={cx("details-item")}
/>
<Link
to={StatementLinkTarget({
statementFingerprintID: stmt.id,
statementNoConstants: stmt.sql_no_constants,
implicitTxn: session.active_txn?.implicit,
app: "",
})}
onClick={() =>
this.props.onStatementClick && this.props.onStatementClick()
<SummaryCardItem
label={
<div className={cx("session-details-link")}>
<Link
to={StatementLinkTarget({
statementFingerprintID: stmt.id,
statementNoConstants: stmt.sql_no_constants,
implicitTxn: session.active_txn?.implicit,
app: "",
})}
onClick={() =>
this.props.onStatementClick &&
this.props.onStatementClick()
}
>
View Statement Details
</Link>
</div>
}
>
View Statement Details
</Link>
value={""}
className={cx("details-item")}
/>
</Col>
<Col className="gutter-row" span={4} />
<Col className="gutter-row" span={10}>
Expand Down Expand Up @@ -363,29 +373,59 @@ export class SessionDetails extends React.Component<SessionDetailsProps> {
label={"Gateway Node"}
value={
this.props.uiConfig.showGatewayNodeLink ? (
<NodeLink
nodeId={session.node_id.toString()}
nodeNames={this.props.nodeNames}
/>
<div className={cx("session-details-link")}>
<NodeLink
nodeId={session.node_id.toString()}
nodeNames={this.props.nodeNames}
/>
</div>
) : (
session.node_id.toString()
)
}
className={cx("details-item")}
/>
)}
<SummaryCardItem
label={"Application name"}
value={session.application_name}
className={cx("details-item")}
/>
<SummaryCardItem
label={"Status"}
value={
<div>
<CircleFilled
className={cx(
session.active_queries.length > 0
? "session-status-icon__active"
: "session-status-icon__idle",
)}
/>
<span>
{session.active_queries.length > 0 ? "Active" : "Idle"}
</span>
</div>
}
className={cx("details-item")}
/>
</Col>
<Col className="gutter-row" span={4} />
<Col className="gutter-row" span={10}>
<SummaryCardItem
label={"Client Address"}
label={"Client IP Address"}
value={session.client_address}
className={cx("details-item")}
/>
<MemoryUsageItem
alloc_bytes={session.alloc_bytes}
max_alloc_bytes={session.max_alloc_bytes}
/>
<SummaryCardItem
label={"User name"}
value={session.username}
className={cx("details-item")}
/>
</Col>
</Row>
</SummaryCard>
Expand All @@ -394,7 +434,7 @@ export class SessionDetails extends React.Component<SessionDetailsProps> {
</Text>
<SummaryCard className={cx("details-section")}>{txnInfo}</SummaryCard>
<Text textType={TextTypes.Heading5} className={cx("details-header")}>
Statement
Most Recent Statement
</Text>
{curStmtInfo}
</React.Fragment>
Expand Down
Expand Up @@ -15,3 +15,12 @@
all: initial;
font-family: $font-family--base;
}

.sessions-filter {
font-size: 14px;
margin-bottom: 10px;
}

.session-column-selector {
margin-bottom: 10px;
}
24 changes: 24 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/sessions/sessionsPage.fixture.ts
Expand Up @@ -15,6 +15,7 @@ import Long from "long";
import { cockroach } from "@cockroachlabs/crdb-protobuf-client";
const Phase = cockroach.server.serverpb.ActiveQuery.Phase;
import { util } from "protobufjs";
import { defaultFilters, Filters } from "../queryFilter";
import {
CancelQueryRequestMessage,
CancelSessionRequestMessage,
Expand Down Expand Up @@ -142,7 +143,25 @@ const sessionsList: SessionInfo[] = [
activeSession,
];

export const nodeRegions: { [nodeId: string]: string } = {
"1": "gcp-us-east1",
"2": "gcp-us-east1",
"3": "gcp-us-west1",
"4": "gcp-europe-west1",
};

export const filters: Filters = {
app: "",
timeNumber: "0",
timeUnit: "seconds",
regions: "",
nodes: "",
};

export const sessionsPagePropsFixture: SessionsPageProps = {
filters: defaultFilters,
isTenant: false,
nodeRegions: nodeRegions,
history,
location: {
pathname: "/sessions",
Expand All @@ -162,13 +181,17 @@ export const sessionsPagePropsFixture: SessionsPageProps = {
ascending: false,
columnTitle: "statementAge",
},
columns: null,
refreshSessions: () => {},
cancelSession: (req: CancelSessionRequestMessage) => {},
cancelQuery: (req: CancelQueryRequestMessage) => {},
onSortingChange: () => {},
};

export const sessionsPagePropsEmptyFixture: SessionsPageProps = {
filters: defaultFilters,
isTenant: false,
nodeRegions: nodeRegions,
history,
location: {
pathname: "/sessions",
Expand All @@ -188,6 +211,7 @@ export const sessionsPagePropsEmptyFixture: SessionsPageProps = {
ascending: false,
columnTitle: "statementAge",
},
columns: null,
refreshSessions: () => {},
cancelSession: (req: CancelSessionRequestMessage) => {},
cancelQuery: (req: CancelQueryRequestMessage) => {},
Expand Down

0 comments on commit a7a0ecf

Please sign in to comment.