Skip to content

Commit 83fd1a1

Browse files
committed
wip view
1 parent ee5653a commit 83fd1a1

File tree

4 files changed

+61
-25
lines changed

4 files changed

+61
-25
lines changed

coderd/apikey.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,6 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) {
152152
}
153153

154154
keys, err := api.Database.GetAPIKeysByLoginType(ctx, database.LoginTypeToken)
155-
if errors.Is(err, sql.ErrNoRows) {
156-
httpapi.Write(ctx, rw, http.StatusOK, []codersdk.APIKey{})
157-
return
158-
}
159155
if err != nil {
160156
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
161157
Message: "Internal error fetching API keys.",
@@ -164,7 +160,7 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) {
164160
return
165161
}
166162

167-
var apiKeys []codersdk.APIKey
163+
apiKeys := []codersdk.APIKey{}
168164
for _, key := range keys {
169165
apiKeys = append(apiKeys, convertAPIKey(key))
170166
}

site/src/components/SettingsLayout/SettingsLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ export const Language = {
1212
securityLabel: "Security",
1313
sshKeysLabel: "SSH keys",
1414
settingsLabel: "Settings",
15+
tokensLabel: "Tokens",
1516
}
1617

1718
const menuItems = [
1819
{ label: Language.accountLabel, path: "/settings/account" },
1920
{ label: Language.securityLabel, path: "/settings/security" },
2021
{ label: Language.sshKeysLabel, path: "/settings/ssh-keys" },
22+
{ label: Language.tokensLabel, path: "/settings/tokens" },
2123
]
2224

2325
export const SettingsLayout: FC = () => {

site/src/pages/UserSettingsPage/TokensPage/TokensPage.tsx

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Button from "@material-ui/core/Button"
2+
import Add from "@material-ui/icons/Add"
13
import React from "react"
24
import { Section } from "../../../components/Section/Section"
35
import { TokensPageView } from "./TokensPageView"
@@ -6,21 +8,51 @@ export const Language = {
68
title: "Authentication Tokens",
79
description: (
810
<p>
9-
The following public key is used to authenticate Git in workspaces. You
10-
may add it to Git services (such as GitHub) that you need to access from
11-
your workspace. <br />
12-
<br />
13-
Coder configures authentication via <code>$GIT_SSH_COMMAND</code>.
11+
Authentication tokens are used to authenticate with the Coder API.
1412
</p>
1513
),
1614
}
1715

1816
export const TokensPage: React.FC<React.PropsWithChildren<unknown>> = () => {
1917
return (
2018
<>
21-
<Section title={Language.title} description={Language.description}>
22-
<TokensPageView
23-
tokens={[]}
19+
<Section
20+
title={Language.title}
21+
description={Language.description}
22+
layout="fluid"
23+
toolbar={
24+
<Button
25+
startIcon={<Add />}
26+
>
27+
New Token
28+
</Button>
29+
}
30+
>
31+
<TokensPageView
32+
tokens={[
33+
{
34+
"id":"tBoVE3dqLl",
35+
"user_id":"f9ee61d8-1d84-4410-ab6e-c1ec1a641e0b",
36+
"last_used":"0001-01-01T00:00:00Z",
37+
"expires_at":"2023-01-15T20:10:45.637438Z",
38+
"created_at":"2022-12-16T20:10:45.637452Z",
39+
"updated_at":"2022-12-16T20:10:45.637452Z",
40+
"login_type":"token",
41+
"scope":"all",
42+
"lifetime_seconds":2592000,
43+
},
44+
{
45+
"id":"tBoVE3dqLl",
46+
"user_id":"f9ee61d8-1d84-4410-ab6e-c1ec1a641e0b",
47+
"last_used":"0001-01-01T00:00:00Z",
48+
"expires_at":"2023-01-15T20:10:45.637438Z",
49+
"created_at":"2022-12-16T20:10:45.637452Z",
50+
"updated_at":"2022-12-16T20:10:45.637452Z",
51+
"login_type":"token",
52+
"scope":"all",
53+
"lifetime_seconds":2592000,
54+
}
55+
]}
2456
/>
2557
</Section>
2658
</>

site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { Maybe } from "components/Conditionals/Maybe"
1111
import { Stack } from "components/Stack/Stack"
1212
import { TableEmpty } from "components/TableEmpty/TableEmpty"
1313
import { TableLoader } from "components/TableLoader/TableLoader"
14+
import DeleteOutlineIcon from '@material-ui/icons/DeleteOutline';
15+
import dayjs from "dayjs"
1416
import { FC } from "react"
1517

1618
export const Language = {
@@ -39,11 +41,11 @@ export const TokensPageView: FC<
3941
<Table>
4042
<TableHead>
4143
<TableRow>
42-
<TableCell width="34%">{Language.idLabel}</TableCell>
43-
<TableCell width="16%">{Language.createdAtLabel}</TableCell>
44-
<TableCell width="16%">{Language.lastUsedLabel}</TableCell>
45-
<TableCell width="16%">{Language.expiresAtLabel}</TableCell>
46-
<TableCell width="1%"></TableCell>
44+
<TableCell width="30%">{Language.idLabel}</TableCell>
45+
<TableCell width="20%">{Language.createdAtLabel}</TableCell>
46+
<TableCell width="20%">{Language.lastUsedLabel}</TableCell>
47+
<TableCell width="20%">{Language.expiresAtLabel}</TableCell>
48+
<TableCell width="10%"></TableCell>
4749
</TableRow>
4850
</TableHead>
4951
<TableBody>
@@ -52,18 +54,19 @@ export const TokensPageView: FC<
5254
</Maybe>
5355

5456
<ChooseOne>
55-
<Cond condition={Boolean(tokens?.length)}>
57+
<Cond condition={tokens?.length === 0}>
5658
<TableEmpty
5759
message={Language.emptyMessage}
5860
/>
5961
</Cond>
6062
<Cond>
6163
{tokens?.map((token) => {
62-
64+
const t = dayjs(token.last_used)
65+
const now = dayjs()
66+
const lastUsed = now.isBefore(t.add(100, "year")) ? t.fromNow() : "Never"
6367
return (
6468
<TableRow
6569
key={token.id}
66-
hover
6770
data-testid={`token-${token.id}`}
6871
tabIndex={0}
6972
>
@@ -79,24 +82,27 @@ export const TokensPageView: FC<
7982
<span
8083
style={{ color: theme.palette.text.secondary }}
8184
>
82-
{token.created_at}
85+
{dayjs(token.created_at).fromNow()}
8386
</span>
8487
</TableCell>
8588

8689

90+
<TableCell>
91+
{lastUsed}
92+
</TableCell>
93+
8794
<TableCell>
8895
<span
8996
style={{ color: theme.palette.text.secondary }}
9097
>
91-
{token.last_used}
98+
{dayjs(token.expires_at).fromNow()}
9299
</span>
93100
</TableCell>
94-
95101
<TableCell>
96102
<span
97103
style={{ color: theme.palette.text.secondary }}
98104
>
99-
{token.expires_at}
105+
<DeleteOutlineIcon />
100106
</span>
101107
</TableCell>
102108
</TableRow>

0 commit comments

Comments
 (0)