-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Draft UI for deployment traces feature (#5594)
Signed-off-by: kypham <[email protected]>
- Loading branch information
1 parent
330c622
commit 42df575
Showing
18 changed files
with
1,119 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { dummyDeployment } from "./dummy-deployment"; | ||
import { createRandTimes, randomUUID } from "./utils"; | ||
import { ListDeploymentTracesResponse } from "~~/api_client/service_pb"; | ||
|
||
const [createdAt, completedAt] = createRandTimes(3); | ||
|
||
export const dummyDeploymentTrace: ListDeploymentTracesResponse.DeploymentTraceRes.AsObject = { | ||
trace: { | ||
id: randomUUID(), | ||
title: "title", | ||
author: "user", | ||
commitTimestamp: createdAt.unix(), | ||
commitMessage: "commit-message", | ||
commitHash: "commit-hash", | ||
commitUrl: "commit-url", | ||
createdAt: createdAt.unix(), | ||
updatedAt: completedAt.unix(), | ||
completedAt: completedAt.unix(), | ||
}, | ||
deploymentsList: [dummyDeployment], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { | ||
ListDeploymentTracesRequest, | ||
ListDeploymentTracesResponse, | ||
} from "~~/api_client/service_pb"; | ||
import { apiClient, apiRequest } from "./client"; | ||
|
||
export const getDeploymentTraces = ({ | ||
options, | ||
pageSize, | ||
cursor, | ||
pageMinUpdatedAt, | ||
}: ListDeploymentTracesRequest.AsObject): Promise< | ||
ListDeploymentTracesResponse.AsObject | ||
> => { | ||
const req = new ListDeploymentTracesRequest(); | ||
if (options) { | ||
const opts = new ListDeploymentTracesRequest.Options(); | ||
opts.setCommitHash(options.commitHash); | ||
req.setOptions(opts); | ||
req.setPageSize(pageSize); | ||
req.setCursor(cursor); | ||
req.setPageMinUpdatedAt(pageMinUpdatedAt); | ||
} | ||
return apiRequest(req, apiClient.listDeploymentTraces); | ||
}; |
43 changes: 43 additions & 0 deletions
43
web/src/components/deployment-trace-page/deployment-trace-filter/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { render, screen, fireEvent } from "@testing-library/react"; | ||
import DeploymentTraceFilter from "./index"; | ||
import { MemoryRouter } from "~~/test-utils"; | ||
|
||
jest.useFakeTimers(); | ||
|
||
describe("DeploymentTraceFilter", () => { | ||
const mockOnChange = jest.fn(); | ||
const mockOnClear = jest.fn(); | ||
const filterValues = { commitHash: "12345" }; | ||
|
||
beforeEach(() => { | ||
render( | ||
<MemoryRouter> | ||
<DeploymentTraceFilter | ||
filterValues={filterValues} | ||
onChange={mockOnChange} | ||
onClear={mockOnClear} | ||
/> | ||
</MemoryRouter> | ||
); | ||
}); | ||
|
||
it("should render filter inputs", () => { | ||
expect( | ||
screen.getByRole("textbox", { name: /commit hash/i }) | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it("should call onChange when filter value changes", () => { | ||
const input = screen.getByRole("textbox", { name: /commit hash/i }); | ||
fireEvent.change(input, { target: { value: "67890" } }); | ||
|
||
jest.runAllTimers(); | ||
expect(mockOnChange).toHaveBeenCalledWith({ commitHash: "67890" }); | ||
}); | ||
|
||
it("should call onClear when clear button is clicked", () => { | ||
const clearButton = screen.getByRole("button", { name: /clear/i }); | ||
fireEvent.click(clearButton); | ||
expect(mockOnClear).toHaveBeenCalled(); | ||
}); | ||
}); |
65 changes: 65 additions & 0 deletions
65
web/src/components/deployment-trace-page/deployment-trace-filter/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { makeStyles, TextField } from "@material-ui/core"; | ||
import { FC, useMemo, useState } from "react"; | ||
import { FilterView } from "~/components/filter-view"; | ||
import debounce from "~/utils/debounce"; | ||
|
||
type Props = { | ||
filterValues: { commitHash?: string }; | ||
onClear: () => void; | ||
onChange: (options: { commitHash?: string }) => void; | ||
}; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
formItem: { | ||
width: "100%", | ||
marginTop: theme.spacing(4), | ||
}, | ||
})); | ||
|
||
const DEBOUNCE_INPUT_WAIT = 1000; | ||
|
||
const DeploymentTraceFilter: FC<Props> = ({ | ||
filterValues, | ||
onClear, | ||
onChange, | ||
}) => { | ||
const classes = useStyles(); | ||
const [commitHash, setCommitHash] = useState<string | null>( | ||
filterValues.commitHash ?? "" | ||
); | ||
|
||
const debounceChangeCommitHash = useMemo( | ||
() => debounce(onChange, DEBOUNCE_INPUT_WAIT), | ||
[onChange] | ||
); | ||
|
||
const onChangeCommitHash = (commitHash: string): void => { | ||
debounceChangeCommitHash({ commitHash: commitHash }); | ||
}; | ||
|
||
return ( | ||
<FilterView | ||
onClear={() => { | ||
onClear(); | ||
setCommitHash(""); | ||
}} | ||
> | ||
<div className={classes.formItem}> | ||
<TextField | ||
id="commit-hash" | ||
label="Commit hash" | ||
variant="outlined" | ||
fullWidth | ||
value={commitHash || ""} | ||
onChange={(e) => { | ||
const text = e.target.value; | ||
setCommitHash(text); | ||
onChangeCommitHash(text); | ||
}} | ||
/> | ||
</div> | ||
</FilterView> | ||
); | ||
}; | ||
|
||
export default DeploymentTraceFilter; |
33 changes: 33 additions & 0 deletions
33
web/src/components/deployment-trace-page/deployment-trace-item/deployment-item.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import DeploymentItem from "./deployment-item"; | ||
import { dummyDeployment } from "~/__fixtures__/dummy-deployment"; | ||
import { render } from "~~/test-utils"; | ||
|
||
describe("DeploymentItem", () => { | ||
it("should render deployment item with correct data", () => { | ||
const { getByText } = render( | ||
<DeploymentItem deployment={dummyDeployment} />, | ||
{} | ||
); | ||
const expectedValues = { | ||
status: "SUCCESS", | ||
applicationName: "DemoApp", | ||
kind: "KUBERNETES", | ||
description: | ||
"Quick sync by deploying the new version and configuring all traffic to it because no pipeline was configured", | ||
}; | ||
|
||
Object.values(expectedValues).forEach((value) => { | ||
expect(getByText(value)).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
it("should display 'No description.' when summary is empty", () => { | ||
const deploymentWithoutSummary = { ...dummyDeployment, summary: "" }; | ||
const { getByText } = render( | ||
<DeploymentItem deployment={deploymentWithoutSummary} />, | ||
{} | ||
); | ||
|
||
expect(getByText("No description.")).toBeInTheDocument(); | ||
}); | ||
}); |
106 changes: 106 additions & 0 deletions
106
web/src/components/deployment-trace-page/deployment-trace-item/deployment-item.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { Box, Chip, makeStyles, Typography } from "@material-ui/core"; | ||
import dayjs from "dayjs"; | ||
import { FC } from "react"; | ||
import { DeploymentStatusIcon } from "~/components/deployment-status-icon"; | ||
import { APPLICATION_KIND_TEXT } from "~/constants/application-kind"; | ||
import { DEPLOYMENT_STATE_TEXT } from "~/constants/deployment-status-text"; | ||
import { ellipsis } from "~/styles/text"; | ||
import { Deployment } from "~~/model/deployment_pb"; | ||
|
||
type Props = { | ||
deployment: Deployment.AsObject; | ||
}; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
root: { | ||
flex: 1, | ||
padding: theme.spacing(2), | ||
display: "flex", | ||
alignItems: "center", | ||
// backgroundColor: theme.palette.background.paper, | ||
}, | ||
info: { | ||
marginLeft: theme.spacing(1), | ||
}, | ||
statusText: { | ||
marginLeft: theme.spacing(1), | ||
lineHeight: "1.5rem", | ||
// Fix width to prevent misalignment of application name. | ||
width: "100px", | ||
}, | ||
description: { | ||
...ellipsis, | ||
color: theme.palette.text.hint, | ||
}, | ||
labelChip: { | ||
marginLeft: theme.spacing(1), | ||
marginBottom: theme.spacing(0.25), | ||
}, | ||
})); | ||
|
||
enum PipedVersion { | ||
V0 = "v0", | ||
V1 = "v1", | ||
} | ||
|
||
const NO_DESCRIPTION = "No description."; | ||
|
||
const DeploymentItem: FC<Props> = ({ deployment }) => { | ||
const classes = useStyles(); | ||
|
||
const pipedVersion = | ||
!deployment.platformProvider || | ||
deployment?.deployTargetsByPluginMap?.length > 0 | ||
? PipedVersion.V1 | ||
: PipedVersion.V0; | ||
|
||
return ( | ||
<Box className={classes.root}> | ||
<Box display="flex" alignItems="center"> | ||
<DeploymentStatusIcon status={deployment.status} /> | ||
<Typography | ||
variant="subtitle2" | ||
className={classes.statusText} | ||
component="span" | ||
> | ||
{DEPLOYMENT_STATE_TEXT[deployment.status]} | ||
</Typography> | ||
</Box> | ||
<Box | ||
display="flex" | ||
flexDirection="column" | ||
flex={1} | ||
pl={2} | ||
overflow="hidden" | ||
> | ||
<Box display="flex" alignItems="baseline"> | ||
<Typography variant="h6" component="span"> | ||
{deployment.applicationName} | ||
</Typography> | ||
<Typography | ||
variant="body2" | ||
color="textSecondary" | ||
className={classes.info} | ||
> | ||
{pipedVersion === PipedVersion.V0 && | ||
APPLICATION_KIND_TEXT[deployment.kind]} | ||
{pipedVersion === PipedVersion.V1 && "APPLICATION"} | ||
{deployment?.labelsMap.map(([key, value], i) => ( | ||
<Chip | ||
label={key + ": " + value} | ||
className={classes.labelChip} | ||
key={i} | ||
/> | ||
))} | ||
</Typography> | ||
</Box> | ||
<Typography variant="body1" className={classes.description}> | ||
{deployment.summary || NO_DESCRIPTION} | ||
</Typography> | ||
</Box> | ||
<div>{dayjs(deployment.createdAt * 1000).fromNow()}</div> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default DeploymentItem; |
50 changes: 50 additions & 0 deletions
50
web/src/components/deployment-trace-page/deployment-trace-item/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { fireEvent, render, screen } from "@testing-library/react"; | ||
import DeploymentTraceItem from "./index"; | ||
import { dummyDeploymentTrace } from "~/__fixtures__/dummy-deployment-trace"; | ||
import { MemoryRouter } from "~~/test-utils"; | ||
|
||
describe("DeploymentTraceItem", () => { | ||
it("should render trace information", () => { | ||
render( | ||
<MemoryRouter> | ||
<DeploymentTraceItem | ||
trace={dummyDeploymentTrace.trace} | ||
deploymentList={dummyDeploymentTrace.deploymentsList} | ||
/> | ||
</MemoryRouter> | ||
); | ||
|
||
const expectedValues = { | ||
title: "title", | ||
author: "user", | ||
commitMessage: "commit-message", | ||
commitHash: "commit-hash", | ||
commitUrl: "/commit-url", | ||
}; | ||
|
||
expect(screen.getByText(expectedValues.title)).toBeInTheDocument(); | ||
expect( | ||
screen.getByText(expectedValues.author + " authored") | ||
).toBeInTheDocument(); | ||
expect(screen.getByText(expectedValues.commitMessage)).toBeInTheDocument(); | ||
expect(screen.getByText(expectedValues.commitHash)).toBeInTheDocument(); | ||
expect(screen.getByRole("link")).toHaveAttribute( | ||
"href", | ||
expectedValues.commitUrl | ||
); | ||
}); | ||
|
||
it("should render deployment items", () => { | ||
render( | ||
<MemoryRouter> | ||
<DeploymentTraceItem | ||
trace={dummyDeploymentTrace.trace} | ||
deploymentList={dummyDeploymentTrace.deploymentsList} | ||
/> | ||
</MemoryRouter> | ||
); | ||
const buttonExpand = screen.getByRole("button", { name: /expand/i }); | ||
fireEvent.click(buttonExpand); | ||
expect(screen.getByText("DemoApp")).toBeInTheDocument(); | ||
}); | ||
}); |
Oops, something went wrong.