-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from kotalco/ipfs
Ipfs
- Loading branch information
Showing
30 changed files
with
2,435 additions
and
15 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
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
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
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
81 changes: 81 additions & 0 deletions
81
...kspaceId]/(main)/deployments/ipfs/cluster-peers/[nodeName]/components/danger-zone-tab.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,81 @@ | ||
"use client"; | ||
|
||
import { useState } from "react"; | ||
import { useParams, useRouter } from "next/navigation"; | ||
import qs from "query-string"; | ||
|
||
import { AlertModal } from "@/components/modals/alert-modal"; | ||
import { DeleteNodeForm } from "@/components/delete-node-form"; | ||
import { useToast } from "@/components/ui/use-toast"; | ||
import { TabsFooter } from "@/components/ui/tabs"; | ||
import { Button } from "@/components/ui/button"; | ||
import { IPFSClusterPeer } from "@/types"; | ||
import { client } from "@/lib/client-instance"; | ||
|
||
interface DangerZoneTabProps { | ||
node: IPFSClusterPeer; | ||
} | ||
|
||
export const DangerZoneTab: React.FC<DangerZoneTabProps> = ({ node }) => { | ||
const params = useParams(); | ||
const router = useRouter(); | ||
const { toast } = useToast(); | ||
|
||
const [open, setOpen] = useState(false); | ||
|
||
async function onDeleteIPFSClusterPeer() { | ||
const url = qs.stringifyUrl({ | ||
url: `/ipfs/clusterpeers/${node.name}`, | ||
query: { workspace_id: params.workspaceId }, | ||
}); | ||
await client.delete(url); | ||
router.push( | ||
`/${params.workspaceId}/deployments/ipfs?deployment=cluster-peers` | ||
); | ||
router.refresh(); | ||
toast({ | ||
title: "Cluster peer has been deleted", | ||
description: `${node.name} peer has been deleted successfully.`, | ||
}); | ||
setOpen(false); | ||
} | ||
|
||
return ( | ||
<> | ||
<div> | ||
<p className="text-muted-foreground"> | ||
By deleting this peer, all connected apps will lose access to the | ||
Blockchain Network. | ||
</p> | ||
<p className="text-muted-foreground"> | ||
Peer attached volume that persists Blockchain data will not be | ||
removed, you need to delete it yourself. | ||
</p> | ||
<p className="text-muted-foreground"> | ||
Are you sure you want to delete this peer? | ||
</p> | ||
<TabsFooter> | ||
<Button | ||
variant="destructive" | ||
className="btn btn-alert" | ||
onClick={() => setOpen(true)} | ||
> | ||
Delete Peer | ||
</Button> | ||
</TabsFooter> | ||
</div> | ||
|
||
<AlertModal | ||
isOpen={open} | ||
onClose={() => setOpen(false)} | ||
title="Delete Cluster Peer" | ||
description={`This action cann't be undone. This will permnantly delete (${node.name}) Cluster Peer.`} | ||
> | ||
<DeleteNodeForm | ||
nodeName={node.name} | ||
onDelete={onDeleteIPFSClusterPeer} | ||
/> | ||
</AlertModal> | ||
</> | ||
); | ||
}; |
195 changes: 195 additions & 0 deletions
195
...)/[workspaceId]/(main)/deployments/ipfs/cluster-peers/[nodeName]/components/peers-tab.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,195 @@ | ||
"use client"; | ||
|
||
import * as z from "zod"; | ||
import { isAxiosError } from "axios"; | ||
import { useForm } from "react-hook-form"; | ||
import { zodResolver } from "@hookform/resolvers/zod"; | ||
|
||
import { client } from "@/lib/client-instance"; | ||
import { IPFSClusterPeer, IPFSPeer } from "@/types"; | ||
import { Roles } from "@/enums"; | ||
import { | ||
Form, | ||
FormDescription, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage, | ||
} from "@/components/ui/form"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Alert, AlertDescription } from "@/components/ui/alert"; | ||
import { TabsFooter } from "@/components/ui/tabs"; | ||
import { SelectWithInput } from "@/components/ui/select-with-input"; | ||
import { MultiSelect } from "@/components/ui/multi-select"; | ||
import { Label } from "@/components/ui/label"; | ||
|
||
interface PeersTabProps { | ||
node: IPFSClusterPeer; | ||
role: Roles; | ||
peers: IPFSPeer[]; | ||
clusterPeers: IPFSClusterPeer[]; | ||
} | ||
|
||
const schema = z.object({ | ||
peerEndpoint: z | ||
.string({ required_error: "Peer endpoint is required" }) | ||
.min(1, "Peer endpoint is required") | ||
.trim(), | ||
bootstrapPeers: z.string().array().optional(), | ||
}); | ||
|
||
type Schema = z.infer<typeof schema>; | ||
|
||
export const PeersTab: React.FC<PeersTabProps> = ({ | ||
node, | ||
role, | ||
peers, | ||
clusterPeers, | ||
}) => { | ||
const { peerEndpoint, bootstrapPeers, trustedPeers } = node; | ||
const peerEndpoints = peers.map(({ name }) => ({ | ||
label: name, | ||
value: `/dns4/${name}/tcp/5001`, | ||
})); | ||
|
||
const ipfsClusterPeers = clusterPeers.map(({ name, id }) => ({ | ||
label: name, | ||
value: `/dns4/${name}/tcp/9096/p2p/${id}`, | ||
})); | ||
|
||
const form = useForm<Schema>({ | ||
resolver: zodResolver(schema), | ||
defaultValues: { peerEndpoint, bootstrapPeers }, | ||
}); | ||
|
||
const { | ||
formState: { | ||
isSubmitted, | ||
isSubmitting, | ||
isValid, | ||
isDirty, | ||
isSubmitSuccessful, | ||
errors, | ||
}, | ||
reset, | ||
setError, | ||
} = form; | ||
|
||
const onSubmit = async (values: Schema) => { | ||
try { | ||
const { data } = await client.put<IPFSClusterPeer>( | ||
`/ipfs/clusterpeers/${node.name}`, | ||
values | ||
); | ||
const { peerEndpoint, bootstrapPeers } = data; | ||
reset({ peerEndpoint, bootstrapPeers }); | ||
} catch (error) { | ||
if (isAxiosError(error)) { | ||
const { response } = error; | ||
|
||
setError("root", { | ||
type: response?.status.toString(), | ||
message: "Something went wrong.", | ||
}); | ||
} | ||
} | ||
}; | ||
|
||
return ( | ||
<Form {...form}> | ||
<form | ||
onSubmit={form.handleSubmit(onSubmit)} | ||
className="relative space-y-4" | ||
> | ||
<FormField | ||
control={form.control} | ||
name="peerEndpoint" | ||
render={({ field }) => ( | ||
<FormItem className="max-w-xs"> | ||
<FormLabel>IPFS Peer</FormLabel> | ||
<SelectWithInput | ||
placeholder="Select a Peer" | ||
disabled={isSubmitting || role === Roles.Reader} | ||
onChange={field.onChange} | ||
defaultValue={field.value} | ||
value={field.value} | ||
options={peerEndpoints} | ||
otherLabel="Use External Peer" | ||
/> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
|
||
<FormField | ||
shouldUnregister={true} | ||
control={form.control} | ||
name="bootstrapPeers" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel>Bootstrap Cluster Peers</FormLabel> | ||
<div> | ||
<div className="max-w-xs"> | ||
<MultiSelect | ||
defaultValue={field.value} | ||
disabled={isSubmitting || role === Roles.Reader} | ||
value={field.value} | ||
placeholder="Select bootstrap peers" | ||
options={ipfsClusterPeers} | ||
onChange={field.onChange} | ||
emptyText="Enter your own peers" | ||
allowCustomValues | ||
/> | ||
</div> | ||
<FormDescription> | ||
Select cluster peers or enter your own peers | ||
</FormDescription> | ||
</div> | ||
|
||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
|
||
{!!trustedPeers && ( | ||
<div className="max-w-xs mt-4"> | ||
<Label>Trusted Cluster Peers</Label> | ||
<ul className="ml-5 text-sm"> | ||
{trustedPeers.map((peer) => ( | ||
<li key={peer} className="text-foreground/50 list-disc"> | ||
{peer} | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
)} | ||
|
||
{isSubmitSuccessful && ( | ||
<Alert variant="success" className="text-center"> | ||
<AlertDescription> | ||
Peers settings have been updated successfully. | ||
</AlertDescription> | ||
</Alert> | ||
)} | ||
|
||
{errors.root && ( | ||
<Alert variant="destructive" className="text-center"> | ||
<AlertDescription>{errors.root.message}</AlertDescription> | ||
</Alert> | ||
)} | ||
|
||
{role !== Roles.Reader && ( | ||
<TabsFooter> | ||
<Button | ||
disabled={(isSubmitted && !isValid) || isSubmitting || !isDirty} | ||
data-testid="submit" | ||
type="submit" | ||
> | ||
Save | ||
</Button> | ||
</TabsFooter> | ||
)} | ||
</form> | ||
</Form> | ||
); | ||
}; |
74 changes: 74 additions & 0 deletions
74
...workspaceId]/(main)/deployments/ipfs/cluster-peers/[nodeName]/components/protocol-tab.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,74 @@ | ||
import { EditImageVersionForm } from "@/components/edit-image-version-form"; | ||
import { ConsensusAlgorithm, Roles } from "@/enums"; | ||
import { getEnumKey } from "@/lib/utils"; | ||
import { IPFSClusterPeer, Version } from "@/types"; | ||
|
||
interface ProtocolTabProps { | ||
node: IPFSClusterPeer; | ||
role: Roles; | ||
versions: Version[]; | ||
} | ||
|
||
export const ProtocolTab: React.FC<ProtocolTabProps> = ({ | ||
node, | ||
role, | ||
versions, | ||
}) => { | ||
const { image, name, consensus, id, privatekeySecretName } = node; | ||
return ( | ||
<> | ||
<ul className="space-y-3"> | ||
<li className="flex flex-col"> | ||
<span className="text-sm font-medium text-foreground">Protocol</span> | ||
<span className="text-sm text-foreground/50">IPFS</span> | ||
</li> | ||
|
||
<li className="flex flex-col"> | ||
<span className="text-sm font-medium text-foreground">Chain</span> | ||
<span className="text-sm text-foreground/50">public-swarm</span> | ||
</li> | ||
|
||
<li className="flex flex-col"> | ||
<span className="text-sm font-medium text-foreground">Client</span> | ||
<a | ||
href="https://github.com/ipfs/ipfs-cluster" | ||
target="_blank" | ||
rel="noreferrer" | ||
className="text-primary hover:underline" | ||
> | ||
ipfs-cluster-service | ||
</a> | ||
</li> | ||
|
||
<li className="flex flex-col"> | ||
<span className="text-sm font-medium text-foreground">Consensus</span> | ||
<span className="text-sm text-foreground/50"> | ||
{getEnumKey(ConsensusAlgorithm, consensus)} | ||
</span> | ||
</li> | ||
|
||
{id && ( | ||
<li className="flex flex-col"> | ||
<span className="text-sm font-medium text-foreground">ID</span> | ||
<span className="text-sm text-foreground/50">{id}</span> | ||
</li> | ||
)} | ||
|
||
{privatekeySecretName && ( | ||
<li className="flex flex-col"> | ||
<span className="text-sm font-medium text-foreground">From</span> | ||
<span className="text-sm text-foreground/50"> | ||
{privatekeySecretName} | ||
</span> | ||
</li> | ||
)} | ||
</ul> | ||
<EditImageVersionForm | ||
role={role} | ||
versions={versions} | ||
image={image} | ||
updateUrl={`/ipfs/clusterpeers/${name}`} | ||
/> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.