Skip to content

Commit 5af2c7b

Browse files
authored
Merge pull request #14 from oasisprotocol/mz/appsDetailsMock
Add more components to apps details
2 parents d4c06ce + de236b0 commit 5af2c7b

File tree

9 files changed

+440
-82
lines changed

9 files changed

+440
-82
lines changed

src/components/AppCard/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ export const AppCard: FC<AppCardProps> = ({ app, network, type }) => {
4949
<>{app.metadata?.['net.oasis.rofl.version']}</>
5050
</Badge>
5151
)}
52-
<span className="text-xs text-muted-foreground">{app.id}</span>
52+
<span className="text-xs text-muted-foreground break-all">
53+
{app.id}
54+
</span>
5355
</div>
5456
)}
5557
</CardContent>

src/components/MachineCard/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const MachineCard: FC<ExploreAppCardProps> = ({ machine }) => {
3535
{/* TODO */}
3636
ROFL App name
3737
</span>
38-
<span className="text-xs text-muted-foreground">
38+
<span className="text-xs text-muted-foreground break-all">
3939
{machine.scheduler}
4040
</span>
4141
</div>

src/components/RainbowKitConnectButton/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type FC } from 'react';
1+
import { useEffect, useState, type FC } from 'react';
22
import { ConnectButton } from '@rainbow-me/rainbowkit';
33
import { ChevronDown, Wallet } from 'lucide-react';
44
import { Button } from '@oasisprotocol/ui-library/src/components/ui/button';
@@ -10,7 +10,7 @@ import {
1010
DropdownMenuTrigger,
1111
} from '@oasisprotocol/ui-library/src/components/ui/dropdown-menu';
1212
import { AccountAvatar } from '../AccountAvatar';
13-
import { useDisconnect } from 'wagmi';
13+
import { useAccount, useDisconnect } from 'wagmi';
1414
import { useIsMobile } from '@oasisprotocol/ui-library/src/hooks/use-mobile';
1515
import { useNavigate } from 'react-router-dom';
1616

@@ -34,6 +34,14 @@ export const RainbowKitConnectButton: FC<Props> = ({ onMobileClose }) => {
3434
const isMobile = useIsMobile();
3535
const { disconnect } = useDisconnect();
3636
const navigate = useNavigate();
37+
const { chainId } = useAccount();
38+
const [selectedChainId, setSelectedChainId] = useState(chainId);
39+
useEffect(() => {
40+
if (chainId && chainId !== selectedChainId) {
41+
setSelectedChainId(chainId);
42+
navigate('/dashboard');
43+
}
44+
}, [chainId, navigate, selectedChainId]);
3745

3846
const handleDisconnect = () => {
3947
disconnect();

src/pages/Dashboard/AppDetails/AppMetadata.tsx

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,32 @@ import { Link } from 'react-router-dom';
33
import { Button } from '@oasisprotocol/ui-library/src/components/ui/button';
44
import { DetailsSectionRow } from '../../../components/DetailsSectionRow';
55
import { SquarePen } from 'lucide-react';
6+
import {
7+
useGetRuntimeRoflAppsIdTransactions,
8+
type RoflApp,
9+
} from '../../../nexus/api';
10+
import { useNetwork } from '../../../hooks/useNetwork';
11+
import { isUrlSafe } from '../../../utils/url';
12+
import { trimLongString } from '../../../utils/trimLongString';
13+
14+
type AppMetadataProps = {
15+
app: RoflApp;
16+
};
17+
18+
export const AppMetadata: FC<AppMetadataProps> = ({ app }) => {
19+
const network = useNetwork();
20+
const { data } = useGetRuntimeRoflAppsIdTransactions(
21+
network,
22+
'sapphire',
23+
app.id,
24+
{
25+
limit: 1,
26+
method: 'rofl.Update',
27+
}
28+
);
29+
const transaction = data?.data.transactions[0];
30+
const repositoryUrl = app.metadata?.['net.oasis.rofl.repository'] as string;
631

7-
export const AppMetadata: FC = () => {
832
return (
933
<div className="space-y-4">
1034
<DetailsSectionRow label="Machine(s)">
@@ -17,12 +41,12 @@ export const AppMetadata: FC = () => {
1741
</DetailsSectionRow>
1842
<DetailsSectionRow label="Explorer Link" className="pb-6 border-b">
1943
<a
20-
href="https://explorer.oasis.io/mainnet/sapphire/rofl/app/rofl1qpdzzm4h73gtes04xjn4whan84s3k33l5gx787l2"
44+
href={`https://explorer.oasis.io/${network}/sapphire/rofl/app/${app.id}`}
2145
target="_blank"
2246
rel="noopener noreferrer"
2347
className="text-primary"
2448
>
25-
rofl1qpdzzm4h73gtes04xjn4whan84s3k33l5gx787l2
49+
{app.id}
2650
</a>
2751
</DetailsSectionRow>
2852
<Button
@@ -34,47 +58,47 @@ export const AppMetadata: FC = () => {
3458
Edit
3559
</Button>
3660
<DetailsSectionRow label="Author">
37-
<a
38-
href="https://explorer.oasis.io/mainnet/sapphire/address/0x1441b57bD02E92473c89733D00881e859Eff6508"
39-
target="_blank"
40-
rel="noopener noreferrer"
41-
className="text-primary"
42-
>
43-
0x1441b57bD02E92473c89733D00881e859Eff6508
44-
</a>
61+
<>{app.metadata?.['net.oasis.rofl.author']}</>
4562
</DetailsSectionRow>
4663
<DetailsSectionRow label="Description">
47-
Ac vel nullam elit facilisis justo dictum non metus a. Dictum quisque
48-
condimentum duis sit amet ac. Pharetra amet sed ornare id nunc vivamus
49-
habitant enim in. Sed lorem scelerisque sed purus eleifend diam.
50-
</DetailsSectionRow>
51-
<DetailsSectionRow label="Homepage">
52-
<a
53-
href="https://www.wt3.ai"
54-
target="_blank"
55-
rel="noopener noreferrer"
56-
className="text-primary"
57-
>
58-
www.wt3.ai
59-
</a>
64+
<>{app.metadata?.['net.oasis.rofl.description']}</>
6065
</DetailsSectionRow>
6166
<DetailsSectionRow label="Repository">
62-
<a
63-
href="https://github.com/oasisprotocol"
64-
target="_blank"
65-
rel="noopener noreferrer"
66-
className="text-primary"
67-
>
68-
https://github.com/oasisprotocol
69-
</a>
67+
{isUrlSafe(repositoryUrl) ? (
68+
<a
69+
href={repositoryUrl}
70+
target="_blank"
71+
rel="noopener noreferrer"
72+
className="text-primary"
73+
>
74+
{repositoryUrl}
75+
</a>
76+
) : undefined}
7077
</DetailsSectionRow>
7178
<DetailsSectionRow label="License" className=" pb-6 border-b">
72-
Apache-2.0
79+
<>{app.metadata?.['net.oasis.rofl.license']}</>
7380
</DetailsSectionRow>
7481
<div className="text-xl font-bold">Policy</div>
75-
<DetailsSectionRow label="Who can run this app">Anyone</DetailsSectionRow>
82+
<DetailsSectionRow label="Who can run this app">-</DetailsSectionRow>
7683
<DetailsSectionRow label="Latest Update" className=" pb-6 border-b">
77-
May 14, 2025
84+
{transaction && (
85+
<>
86+
{new Intl.DateTimeFormat('en-US', {
87+
year: 'numeric',
88+
month: 'long',
89+
day: 'numeric',
90+
}).format(new Date(transaction?.timestamp))}
91+
<br />
92+
<a
93+
href={`https://explorer.oasis.io/mainnet/sapphire/tx/${transaction.hash}`}
94+
target="_blank"
95+
rel="noopener noreferrer"
96+
className="text-primary"
97+
>
98+
{trimLongString(transaction.eth_hash || transaction.hash)}
99+
</a>
100+
</>
101+
)}
78102
</DetailsSectionRow>
79103
</div>
80104
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { type FC } from 'react';
2+
import {
3+
Table,
4+
TableHeader,
5+
TableBody,
6+
TableRow,
7+
TableHead,
8+
TableCell,
9+
} from '@oasisprotocol/ui-library/src/components/ui/table';
10+
import { LockKeyhole } from 'lucide-react';
11+
import type { RoflAppSecrets } from '../../../nexus/api';
12+
import { RemoveSecret } from './RemoveSecret';
13+
import { SecretDialog } from './SecretDialog';
14+
15+
type AppSecretsProps = {
16+
secrets: RoflAppSecrets;
17+
};
18+
19+
export const AppSecrets: FC<AppSecretsProps> = ({ secrets }) => {
20+
const hasSecrets = Object.keys(secrets).length > 0;
21+
return (
22+
<div className="space-y-4">
23+
{hasSecrets && (
24+
<Table>
25+
<TableHeader>
26+
<TableRow>
27+
<TableHead></TableHead>
28+
<TableHead>Name</TableHead>
29+
<TableHead></TableHead>
30+
<TableHead></TableHead>
31+
</TableRow>
32+
</TableHeader>
33+
<TableBody>
34+
{Object.keys(secrets).map((key) => (
35+
<TableRow key={key}>
36+
<TableCell>
37+
<LockKeyhole size={16} className="font-white" />
38+
</TableCell>
39+
<TableCell>
40+
{key}: [{(secrets[key] as string).length} bytes]
41+
</TableCell>
42+
<TableCell className="w-10">
43+
<SecretDialog mode="edit" secret={key} />
44+
</TableCell>
45+
<TableCell className="w-10">
46+
<RemoveSecret secret={key} />
47+
</TableCell>
48+
</TableRow>
49+
))}
50+
</TableBody>
51+
</Table>
52+
)}
53+
<SecretDialog mode="add" />
54+
</div>
55+
);
56+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { FC } from 'react';
2+
import { Button } from '@oasisprotocol/ui-library/src/components/ui/button';
3+
import {
4+
Dialog,
5+
DialogClose,
6+
DialogContent,
7+
DialogDescription,
8+
DialogFooter,
9+
DialogHeader,
10+
DialogTitle,
11+
DialogTrigger,
12+
} from '@oasisprotocol/ui-library/src/components/ui/dialog';
13+
import { Trash2 } from 'lucide-react';
14+
15+
type RemoveSecretProps = {
16+
secret: string;
17+
};
18+
19+
export const RemoveSecret: FC<RemoveSecretProps> = ({ secret }) => {
20+
return (
21+
<Dialog>
22+
<DialogTrigger asChild>
23+
<Button
24+
variant="ghost"
25+
className="text-destructive hover:text-destructive"
26+
>
27+
<Trash2 />
28+
</Button>
29+
</DialogTrigger>
30+
<DialogContent className="sm:max-w-[425px]">
31+
<DialogHeader>
32+
<DialogTitle>Please confirm your action</DialogTitle>
33+
<DialogDescription>
34+
Secret key <strong>{secret}</strong> will be removed from ROFL app.
35+
</DialogDescription>
36+
</DialogHeader>
37+
<DialogFooter>
38+
<DialogClose asChild>
39+
<Button variant="outline">Cancel</Button>
40+
</DialogClose>
41+
<DialogClose asChild>
42+
<Button
43+
variant="destructive"
44+
onClick={() => console.log('trigger stop action')}
45+
>
46+
Confirm
47+
</Button>
48+
</DialogClose>
49+
</DialogFooter>
50+
</DialogContent>
51+
</Dialog>
52+
);
53+
};

0 commit comments

Comments
 (0)