Skip to content

Commit 87db368

Browse files
committed
fix: change formatting of createdAt and elevation/expiry
1 parent dc6d775 commit 87db368

9 files changed

Lines changed: 61 additions & 44 deletions

File tree

ui/src/application/Applications.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ import * as config from '../config';
3232
import {UpdateApplicationDialog} from './UpdateApplicationDialog';
3333
import {IApplication} from '../types';
3434
import {LastUsedCell} from '../common/LastUsedCell';
35-
import TimeAgo from 'react-timeago';
36-
import {TimeAgoFormatter} from '../common/TimeAgoFormatter';
35+
import {formatDate} from '../common/TimeAgoFormatter';
3736
import {useStores} from '../stores';
3837
import {observer} from 'mobx-react-lite';
3938
import {makeStyles} from 'tss-react/mui';
@@ -128,8 +127,8 @@ const Applications = observer(() => {
128127
<TableCell>Token</TableCell>
129128
<TableCell>Description</TableCell>
130129
<TableCell>Priority</TableCell>
131-
<TableCell>Created</TableCell>
132130
<TableCell>Last Used</TableCell>
131+
<TableCell>Created</TableCell>
133132
<TableCell />
134133
<TableCell />
135134
</TableRow>
@@ -261,12 +260,10 @@ const Row = ({app, fDelete, fUpload, fDeleteImage, fEdit}: IRowProps) => {
261260
</TableCell>
262261
<TableCell>{app.description}</TableCell>
263262
<TableCell>{app.defaultPriority}</TableCell>
264-
<TableCell>
265-
<TimeAgo date={app.createdAt} formatter={TimeAgoFormatter.long} />
266-
</TableCell>
267263
<TableCell>
268264
<LastUsedCell lastUsed={app.lastUsed} />
269265
</TableCell>
266+
<TableCell title={app.createdAt}>{formatDate(app.createdAt)}</TableCell>
270267
<TableCell align="right" padding="none">
271268
<IconButton onClick={fEdit} className="edit">
272269
<Edit />

ui/src/client/Clients.tsx

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import Edit from '@mui/icons-material/Edit';
1212
import Security from '@mui/icons-material/Security';
1313
import Button from '@mui/material/Button';
1414
import Tooltip from '@mui/material/Tooltip';
15-
import TimeAgo from 'react-timeago';
1615
import ConfirmDialog from '../common/ConfirmDialog';
1716
import DefaultPage from '../common/DefaultPage';
1817
import AddClientDialog from './AddClientDialog';
@@ -21,7 +20,8 @@ import ElevateClientDialog from './ElevateClientDialog';
2120
import {IClient} from '../types';
2221
import CopyableSecret from '../common/CopyableSecret';
2322
import {LastUsedCell} from '../common/LastUsedCell';
24-
import {TimeAgoFormatter} from '../common/TimeAgoFormatter';
23+
import {formatDate} from '../common/TimeAgoFormatter';
24+
import {RemainingTime} from '../common/RemainingTime';
2525
import {observer} from 'mobx-react-lite';
2626
import {useStores} from '../stores';
2727

@@ -55,10 +55,10 @@ const Clients = observer(() => {
5555
<TableRow style={{textAlign: 'center'}}>
5656
<TableCell>Name</TableCell>
5757
<TableCell style={{width: 200}}>Token</TableCell>
58-
<TableCell>Last Used</TableCell>
5958
<TableCell>Elevation ends</TableCell>
60-
<TableCell>Created</TableCell>
6159
<TableCell>Expires in</TableCell>
60+
<TableCell>Last Used</TableCell>
61+
<TableCell>Created</TableCell>
6262
<TableCell />
6363
<TableCell />
6464
<TableCell />
@@ -152,26 +152,22 @@ const Row = ({
152152
style={{display: 'flex', alignItems: 'center', width: 250}}
153153
/>
154154
</TableCell>
155-
<TableCell>
156-
<LastUsedCell lastUsed={lastUsed} />
155+
<TableCell align="right" title={elevatedUntil}>
156+
<RemainingTime
157+
until={
158+
elevatedUntil && Date.parse(elevatedUntil) > Date.now()
159+
? elevatedUntil
160+
: undefined
161+
}
162+
/>
157163
</TableCell>
158-
<TableCell>
159-
{elevatedUntil && Date.parse(elevatedUntil) > Date.now() ? (
160-
<TimeAgo date={elevatedUntil} formatter={TimeAgoFormatter.longMinutes} />
161-
) : (
162-
'-'
163-
)}
164+
<TableCell align="right" className="expires-in" title={expiresAt ?? undefined}>
165+
<RemainingTime until={expiresAt} />
164166
</TableCell>
165167
<TableCell>
166-
<TimeAgo date={createdAt} formatter={TimeAgoFormatter.long} />
167-
</TableCell>
168-
<TableCell className="expires-in">
169-
{expiresAt ? (
170-
<TimeAgo date={expiresAt} formatter={TimeAgoFormatter.longMinutes} />
171-
) : (
172-
'-'
173-
)}
168+
<LastUsedCell lastUsed={lastUsed} />
174169
</TableCell>
170+
<TableCell title={createdAt}>{formatDate(createdAt)}</TableCell>
175171
<TableCell align="right" padding="none">
176172
<Tooltip title="Elevate">
177173
<IconButton onClick={fElevate} className="elevate">

ui/src/common/RemainingTime.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, {useEffect, useState} from 'react';
2+
3+
const MINUTE_MS = 60 * 1000;
4+
const HOUR_MS = 60 * MINUTE_MS;
5+
const DAY_MS = 24 * HOUR_MS;
6+
const REFRESH_MS = 5 * MINUTE_MS;
7+
8+
const format = (until: string): string => {
9+
const diffMs = Math.max(0, Date.parse(until) - Date.now());
10+
const days = Math.floor(diffMs / DAY_MS);
11+
const hours = Math.floor((diffMs % DAY_MS) / HOUR_MS);
12+
const minutes = Math.floor((diffMs % HOUR_MS) / MINUTE_MS);
13+
const parts: string[] = [];
14+
if (days > 0) parts.push(`${days}d`);
15+
if (days > 0 || hours > 0) parts.push(`${hours}h`);
16+
parts.push(`${minutes}m`);
17+
return parts.join(' ');
18+
};
19+
20+
export const RemainingTime: React.FC<{until: string | null | undefined}> = ({until}) => {
21+
const [, setTick] = useState(0);
22+
useEffect(() => {
23+
const id = window.setInterval(() => setTick((t) => t + 1), REFRESH_MS);
24+
return () => window.clearInterval(id);
25+
}, []);
26+
if (!until) return <>-</>;
27+
return <>{format(until)}</>;
28+
};

ui/src/common/TimeAgoFormatter.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ export const TimeAgoFormatter = {
1111
narrow: makeIntlFormatter({style: 'narrow', locale: 'en'}),
1212
longMinutes: longMinutesFormatter,
1313
} as const satisfies Record<string, Formatter>;
14+
15+
export const formatDate = (date: string): string => date.slice(0, 10);

ui/src/plugin/Plugins.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import Settings from '@mui/icons-material/Settings';
1111
import {Switch, Button} from '@mui/material';
1212
import DefaultPage from '../common/DefaultPage';
1313
import CopyableSecret from '../common/CopyableSecret';
14-
import TimeAgo from 'react-timeago';
15-
import {TimeAgoFormatter} from '../common/TimeAgoFormatter';
14+
import {formatDate} from '../common/TimeAgoFormatter';
1615
import {observer} from 'mobx-react-lite';
1716
import {IPlugin} from '../types';
1817
import {useStores} from '../stores';
@@ -83,9 +82,7 @@ const Row: React.FC<IRowProps> = observer(
8382
<TableCell>
8483
<CopyableSecret value={token} style={{display: 'flex', alignItems: 'center'}} />
8584
</TableCell>
86-
<TableCell>
87-
<TimeAgo date={createdAt} formatter={TimeAgoFormatter.long} />
88-
</TableCell>
85+
<TableCell title={createdAt}>{formatDate(createdAt)}</TableCell>
8986
<TableCell align="right" padding="none">
9087
<Link to={'/plugins/' + id}>
9188
<Button>

ui/src/tests/application.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ enum Col {
1919
Token = 4,
2020
Description = 5,
2121
DefaultPriority = 6,
22-
Created = 7,
23-
LastUsed = 8,
22+
LastUsed = 7,
23+
Created = 8,
2424
EditUpdate = 9,
2525
EditDelete = 10,
2626
}

ui/src/tests/client.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ describe('Client', () => {
8181
});
8282
it('shows expires after for new clients', async () => {
8383
expect(await innerText(page, $table.cell(2, ClientCol.ExpiresIn))).toBe('-');
84-
expect(await innerText(page, $table.cell(3, ClientCol.ExpiresIn))).toBe('in 1 hour');
84+
expect(await innerText(page, $table.cell(3, ClientCol.ExpiresIn))).toBe('59m');
8585
});
8686
it('updates client', updateClient(1, {name: 'firefox', expiresAfter: 60 * 60 * 10}));
8787
it('has updated client name', waitForClient('firefox', 1));
8888
it('has updated expires after', async () => {
89-
expect(await innerText(page, $table.cell(1, ClientCol.ExpiresIn))).toBe('in 10 hours');
89+
expect(await innerText(page, $table.cell(1, ClientCol.ExpiresIn))).toBe('9h 59m');
9090
});
9191
it('shows token', async () => {
9292
await page.click($table.cell(3, ClientCol.Token, '.toggle-visibility'));

ui/src/tests/utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ export const clearField = async (element: ElementHandle | Page, selector: string
7171
export enum ClientCol {
7272
Name = 1,
7373
Token = 2,
74-
LastSeen = 3,
75-
ElevationEnds = 4,
76-
Created = 5,
77-
ExpiresIn = 6,
74+
ElevationEnds = 3,
75+
ExpiresIn = 4,
76+
LastSeen = 5,
77+
Created = 6,
7878
Elevate = 7,
7979
Edit = 8,
8080
Delete = 9,

ui/src/user/Users.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ import AddEditDialog from './AddEditUserDialog';
1616
import {IUser} from '../types';
1717
import {useStores} from '../stores';
1818
import {observer} from 'mobx-react-lite';
19-
import TimeAgo from 'react-timeago';
20-
import {TimeAgoFormatter} from '../common/TimeAgoFormatter';
19+
import {formatDate} from '../common/TimeAgoFormatter';
2120

2221
interface IRowProps {
2322
name: string;
@@ -31,9 +30,7 @@ const UserRow: React.FC<IRowProps> = ({name, admin, createdAt, fDelete, fEdit})
3130
<TableRow>
3231
<TableCell>{name}</TableCell>
3332
<TableCell>{admin ? 'Yes' : 'No'}</TableCell>
34-
<TableCell>
35-
<TimeAgo date={createdAt} formatter={TimeAgoFormatter.long} />
36-
</TableCell>
33+
<TableCell title={createdAt}>{formatDate(createdAt)}</TableCell>
3734
<TableCell align="right" padding="none">
3835
<IconButton onClick={fEdit} className="edit" size="large">
3936
<Edit />

0 commit comments

Comments
 (0)