feat: show template versions (#3003)

This commit is contained in:
Abhineet Jain
2022-07-15 15:25:47 -07:00
committed by GitHub
parent 9a5fa3f050
commit ccdf82dd7e
10 changed files with 171 additions and 4 deletions

View File

@ -136,6 +136,15 @@ export const getTemplateVersionResources = async (
return response.data
}
export const getTemplateVersions = async (
templateId: string,
): Promise<TypesGen.TemplateVersion[]> => {
const response = await axios.get<TypesGen.TemplateVersion[]>(
`/api/v2/templates/${templateId}/versions`,
)
return response.data
}
export const getWorkspace = async (
workspaceId: string,
params?: TypesGen.WorkspaceOptions,

View File

@ -0,0 +1,27 @@
import { ComponentMeta, Story } from "@storybook/react"
import { MockTemplateVersion } from "../../testHelpers/entities"
import { VersionsTable, VersionsTableProps } from "./VersionsTable"
export default {
title: "components/VersionsTable",
component: VersionsTable,
} as ComponentMeta<typeof VersionsTable>
const Template: Story<VersionsTableProps> = (args) => <VersionsTable {...args} />
export const Example = Template.bind({})
Example.args = {
versions: [
MockTemplateVersion,
{
...MockTemplateVersion,
name: "test-template-version-2",
created_at: "2022-05-18T18:39:01.382927298Z",
},
],
}
export const Empty = Template.bind({})
Empty.args = {
versions: [],
}

View File

@ -0,0 +1,74 @@
import Box from "@material-ui/core/Box"
import { Theme } from "@material-ui/core/styles"
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import useTheme from "@material-ui/styles/useTheme"
import { FC } from "react"
import * as TypesGen from "../../api/typesGenerated"
import { EmptyState } from "../EmptyState/EmptyState"
import { TableLoader } from "../TableLoader/TableLoader"
export const Language = {
emptyMessage: "No versions found",
nameLabel: "Version name",
createdAtLabel: "Created at",
createdByLabel: "Created by",
}
export interface VersionsTableProps {
versions?: TypesGen.TemplateVersion[]
}
export const VersionsTable: FC<VersionsTableProps> = ({ versions }) => {
const isLoading = !versions
const theme: Theme = useTheme()
return (
<Table data-testid="versions-table">
<TableHead>
<TableRow>
<TableCell width="30%">{Language.nameLabel}</TableCell>
<TableCell width="30%">{Language.createdAtLabel}</TableCell>
<TableCell width="40%">{Language.createdByLabel}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{isLoading && <TableLoader />}
{versions &&
versions
.slice()
.reverse()
.map((version) => {
return (
<TableRow key={version.id} data-testid={`version-${version.id}`}>
<TableCell>{version.name}</TableCell>
<TableCell>
<span style={{ color: theme.palette.text.secondary }}>
{new Date(version.created_at).toLocaleString()}
</span>
</TableCell>
<TableCell>
<span style={{ color: theme.palette.text.secondary }}>
{version.created_by_name}
</span>
</TableCell>
</TableRow>
)
})}
{versions && versions.length === 0 && (
<TableRow>
<TableCell colSpan={999}>
<Box p={4}>
<EmptyState message={Language.emptyMessage} />
</Box>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
)
}

View File

@ -1,6 +1,7 @@
import { screen } from "@testing-library/react"
import {
MockTemplate,
MockTemplateVersion,
MockWorkspaceResource,
renderWithAuth,
} from "../../testHelpers/renderHelpers"
@ -15,5 +16,6 @@ describe("TemplatePage", () => {
await screen.findByText(MockTemplate.name)
screen.getByTestId("markdown")
screen.getByText(MockWorkspaceResource.name)
screen.getByTestId(`version-${MockTemplateVersion.id}`)
})
})

View File

@ -27,7 +27,8 @@ export const TemplatePage: FC = () => {
organizationId,
},
})
const { template, activeTemplateVersion, templateResources } = templateState.context
const { template, activeTemplateVersion, templateResources, templateVersions } =
templateState.context
const isLoading = !template || !activeTemplateVersion || !templateResources
if (isLoading) {
@ -43,6 +44,7 @@ export const TemplatePage: FC = () => {
template={template}
activeTemplateVersion={activeTemplateVersion}
templateResources={templateResources}
templateVersions={templateVersions}
/>
</>
)

View File

@ -14,6 +14,7 @@ Example.args = {
template: Mocks.MockTemplate,
activeTemplateVersion: Mocks.MockTemplateVersion,
templateResources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2],
templateVersions: [Mocks.MockTemplateVersion],
}
export const SmallViewport = Template.bind({})
@ -33,6 +34,7 @@ You can add instructions here
\`\`\``,
},
templateResources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2],
templateVersions: [Mocks.MockTemplateVersion],
}
SmallViewport.parameters = {
chromatic: { viewports: [600] },

View File

@ -16,6 +16,7 @@ import {
import { Stack } from "../../components/Stack/Stack"
import { TemplateResourcesTable } from "../../components/TemplateResourcesTable/TemplateResourcesTable"
import { TemplateStats } from "../../components/TemplateStats/TemplateStats"
import { VersionsTable } from "../../components/VersionsTable/VersionsTable"
import { WorkspaceSection } from "../../components/WorkspaceSection/WorkspaceSection"
const Language = {
@ -23,18 +24,21 @@ const Language = {
noDescription: "",
readmeTitle: "README",
resourcesTitle: "Resources",
versionsTitle: "Version history",
}
export interface TemplatePageViewProps {
template: Template
activeTemplateVersion: TemplateVersion
templateResources: WorkspaceResource[]
templateVersions?: TemplateVersion[]
}
export const TemplatePageView: FC<TemplatePageViewProps> = ({
template,
activeTemplateVersion,
templateResources,
templateVersions,
}) => {
const styles = useStyles()
const readme = frontMatter(activeTemplateVersion.readme)
@ -88,6 +92,12 @@ export const TemplatePageView: FC<TemplatePageViewProps> = ({
</ReactMarkdown>
</div>
</WorkspaceSection>
<WorkspaceSection
title={Language.versionsTitle}
contentsProps={{ className: styles.versionsTableContents }}
>
<VersionsTable versions={templateVersions} />
</WorkspaceSection>
</Stack>
</Margins>
)
@ -111,5 +121,8 @@ export const useStyles = makeStyles((theme) => {
resourcesTableContents: {
margin: 0,
},
versionsTableContents: {
margin: 0,
},
}
})

View File

@ -101,8 +101,9 @@ export const MockRunningProvisionerJob: TypesGen.ProvisionerJob = {
export const MockTemplateVersion: TypesGen.TemplateVersion = {
id: "test-template-version",
created_at: "",
updated_at: "",
created_at: "2022-05-17T17:39:01.382927298Z",
updated_at: "2022-05-17T17:39:01.382927298Z",
template_id: "test-template",
job: MockProvisionerJob,
name: "test-version",
readme: `---

View File

@ -25,6 +25,9 @@ export const handlers = [
rest.get("/api/v2/templates/:templateId", async (req, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockTemplate))
}),
rest.get("/api/v2/templates/:templateId/versions", async (req, res, ctx) => {
return res(ctx.status(200), ctx.json([M.MockTemplateVersion]))
}),
rest.get("/api/v2/templateversions/:templateVersionId", async (req, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockTemplateVersion))
}),

View File

@ -1,5 +1,10 @@
import { assign, createMachine } from "xstate"
import { getTemplateByName, getTemplateVersion, getTemplateVersionResources } from "../../api/api"
import {
getTemplateByName,
getTemplateVersion,
getTemplateVersionResources,
getTemplateVersions,
} from "../../api/api"
import { Template, TemplateVersion, WorkspaceResource } from "../../api/typesGenerated"
interface TemplateContext {
@ -8,6 +13,7 @@ interface TemplateContext {
template?: Template
activeTemplateVersion?: TemplateVersion
templateResources?: WorkspaceResource[]
templateVersions?: TemplateVersion[]
}
export const templateMachine = createMachine(
@ -24,6 +30,9 @@ export const templateMachine = createMachine(
getTemplateResources: {
data: WorkspaceResource[]
}
getTemplateVersions: {
data: TemplateVersion[]
}
},
},
tsTypes: {} as import("./templateXService.typegen").Typegen0,
@ -72,6 +81,21 @@ export const templateMachine = createMachine(
success: { type: "final" },
},
},
templateVersions: {
initial: "gettingTemplateVersions",
states: {
gettingTemplateVersions: {
invoke: {
src: "getTemplateVersions",
onDone: {
actions: ["assignTemplateVersions"],
target: "success",
},
},
},
success: { type: "final" },
},
},
},
},
loaded: {},
@ -94,6 +118,13 @@ export const templateMachine = createMachine(
return getTemplateVersionResources(ctx.template.active_version_id)
},
getTemplateVersions: (ctx) => {
if (!ctx.template) {
throw new Error("Template not loaded")
}
return getTemplateVersions(ctx.template.id)
},
},
actions: {
assignTemplate: assign({
@ -105,6 +136,9 @@ export const templateMachine = createMachine(
assignTemplateResources: assign({
templateResources: (_, event) => event.data,
}),
assignTemplateVersions: assign({
templateVersions: (_, event) => event.data,
}),
},
},
)