Skip to content

Commit

Permalink
Apply contract/message card to DeployController and ConfirmTransaction (
Browse files Browse the repository at this point in the history
#1220)

* Sunset legacy Accordion

* Apply contract/message card component to policies

* Update snapshots

---------

Co-authored-by: Tarrence van As <[email protected]>
  • Loading branch information
JunichiSugiura and tarrencev authored Jan 7, 2025
1 parent 42d1d30 commit e52e690
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 249 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
159 changes: 68 additions & 91 deletions packages/keychain/src/components/ErrorAlert.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import {
WedgeIcon,
CopyIcon,
CheckIcon,
ErrorAlertIcon,
ErrorAlertIconProps,
Button,
} from "@cartridge/ui-next";
import {
Text,
Accordion,
AccordionItem,
AccordionButton,
AccordionPanel,
Spacer,
HStack,
Box,
VStack,
Divider,
} from "@chakra-ui/react";
import { motion } from "framer-motion";
import React, { ReactElement, useCallback, useEffect, useState } from "react";
AccordionTrigger,
AccordionContent,
cn,
} from "@cartridge/ui-next";
import { Text, HStack, VStack, Divider } from "@chakra-ui/react";
import React, {
ReactElement,
useCallback,
useEffect,
useMemo,
useState,
} from "react";
import { ErrorCode } from "@cartridge/account-wasm/controller";
import { ControllerError } from "@/utils/connection";
import { parseExecutionError, parseValidationError } from "@/utils/errors";
Expand Down Expand Up @@ -52,88 +50,67 @@ export function ErrorAlert({
}, 3000);
}, [copied]);

const collapsible = !isExpanded || allowToggle;
const styles = useMemo(() => {
switch (variant) {
case "info":
return { bg: "bg-info", text: "text-info-foreground" };
case "warning":
return { bg: "bg-warning", text: "text-warning-foreground" };
case "error":
return { bg: "bg-error", text: "text-error-foreground" };
default:
return { bg: "bg-secondary", text: "text-secondary-foreground" };
}
}, [variant]);

return (
<Accordion
w="full"
allowToggle={!isExpanded || allowToggle}
defaultIndex={isExpanded ? [0] : undefined}
variant={variant}
color="solid.bg"
fontSize="sm"
type="single"
collapsible={collapsible}
defaultValue={isExpanded ? "item-1" : undefined}
>
<AccordionItem position="relative" border="none">
{({ isExpanded: itemExpanded }) => (
<>
<AccordionButton
disabled={!description || (isExpanded && !allowToggle)}
>
<HStack alignItems="flex-start">
{variant && (
<ErrorAlertIcon
variant={variant as ErrorAlertIconProps["variant"]}
size="xs"
/>
)}
<Text
as="b"
fontSize="2xs"
color="inherit"
textTransform="uppercase"
align="left"
>
{title}
</Text>
</HStack>

<Spacer />
<AccordionItem
value="item-1"
className={cn(
"flex flex-col rounded p-3 gap-3",
styles.bg,
styles.text,
)}
>
<AccordionTrigger hideIcon={!collapsible} className="items-start gap-1">
{variant && variant !== "default" && (
<div className="w-5">
<ErrorAlertIcon
variant={variant as ErrorAlertIconProps["variant"]}
/>
</div>
)}
<div className={cn("text-2xs font-bold uppercase", styles.text)}>
{title}
</div>
</AccordionTrigger>

{description && !isExpanded && (
<HStack>
<Box
as={motion.div}
animate={{
rotate: itemExpanded ? 180 : 0,
}}
>
<WedgeIcon size="sm" variant="down" />
</Box>
</HStack>
<AccordionContent>
{copyText && (
<Button
size="icon"
variant="icon"
className="absolute right-5 w-5 h-5 bg-[rgba(0,0,0,0.1)]"
onClick={() => {
setCopied(true);
navigator.clipboard.writeText(copyText);
}}
>
{copied ? (
<CheckIcon size="xs" className="text-[black]" />
) : (
<CopyIcon size="xs" className="text-[black]" />
)}
</AccordionButton>

{description && (
<AccordionPanel w="full" position="relative">
{copyText && (
<Button
size="icon"
variant="icon"
className="absolute right-3 w-5 h-5 bg-[rgba(0,0,0,0.1)]"
onClick={() => {
setCopied(true);
navigator.clipboard.writeText(copyText);
}}
>
{copied ? (
<CheckIcon size="xs" className="text-[black]" />
) : (
<CopyIcon size="xs" className="text-[black]" />
)}
</Button>
)}
<Box
h="full"
maxH={200}
p={3}
pt={0}
overflowY="auto"
pr={copyText ? 10 : undefined}
>
{description}
</Box>
</AccordionPanel>
)}
</>
)}
</Button>
)}
{description && <div className="text-xs mr-7">{description}</div>}
</AccordionContent>
</AccordionItem>
</Accordion>
);
Expand Down
159 changes: 23 additions & 136 deletions packages/keychain/src/components/Policies.tsx
Original file line number Diff line number Diff line change
@@ -1,148 +1,35 @@
import {
HStack,
VStack,
Text,
AccordionButton,
AccordionItem,
Accordion,
Spacer,
AccordionPanel,
Box,
} from "@chakra-ui/react";
import { FnIcon, WedgeIcon, CopyAddress } from "@cartridge/ui-next";
import { SessionPolicies } from "@cartridge/presets";
import { ContractCard } from "./session/ContractCard";
import { useConnection } from "@/hooks/connection";
import { MessageCard } from "./session/MessageCard";

export function Policies({
title,
policies,
}: {
title?: string;
policies: SessionPolicies;
}) {
const connection = useConnection();
const parsedContracts = connection.policies?.contracts ?? {};

return (
<Box position="relative">
{title && (
<VStack
align="flex-start"
bg="solid.primary"
p={3}
position="sticky"
top={0}
borderTopRadius="base"
>
<Text
color="text.secondaryAccent"
fontSize="xs"
fontWeight="bold"
casing="uppercase"
>
{title}
</Text>
</VStack>
<div className="flex flex-col gap-4">
{Object.entries(policies.contracts ?? {}).map(([address, p]) => {
const c = parsedContracts[address];
return (
<ContractCard
key={address}
address={address}
title={c?.meta?.name || "Contract"}
icon={c?.meta?.icon}
methods={p.methods}
/>
);
})}

{policies.messages && policies.messages.length > 0 && (
<MessageCard messages={policies.messages} />
)}

<Accordion w="full" allowMultiple overflowY="auto">
{Object.entries(policies.contracts ?? {}).map(([contractAddress, p]) =>
p.methods.map((m) => (
<AccordionItem
key={`${contractAddress}${m.entrypoint}`}
// borderTopRadius={i === 0 && !title ? "base" : "none"}
// // The container already set border radius (for top & bottom), but we
// // set the bottom radius for the last item here because for certain
// // browsers' scrolling behaviour (eg Firefox) just to make it look nicer.
// borderBottomRadius={i === policies?.length - 1 ? "base" : "none"}
>
{({ isExpanded }) => (
<>
<AccordionButton
_disabled={{
cursor: "auto",
opacity: 1,
}}
>
<HStack>
<FnIcon size="sm" />
<Text>{m.entrypoint}</Text>
</HStack>

<Spacer />

<WedgeIcon
variant={isExpanded ? "down" : "right"}
className="text-muted-foreground"
/>
</AccordionButton>

<AccordionPanel>
<VStack align="flex-start" w="full" p={3}>
<CopyAddress address={contractAddress} />
{m.description && (
<Text w="full" color="inherit">
{m.description}
</Text>
)}
</VStack>
</AccordionPanel>
</>
)}
</AccordionItem>
)),
)}
{policies.messages?.map((p) => (
<AccordionItem
key={`${p.domain.name}${p.primaryType}`}
// borderTopRadius={i === 0 && !title ? "base" : "none"}
// // The container already set border radius (for top & bottom), but we
// // set the bottom radius for the last item here because for certain
// // browsers' scrolling behaviour (eg Firefox) just to make it look nicer.
// borderBottomRadius={i === policies?.length - 1 ? "base" : "none"}
>
{({ isExpanded }) => (
<>
<AccordionButton
_disabled={{
cursor: "auto",
opacity: 1,
}}
>
<HStack>
<Text>Sign Message</Text>
</HStack>

<Spacer />

<WedgeIcon
variant={isExpanded ? "down" : "right"}
className="text-muted-foreground"
/>
</AccordionButton>

<AccordionPanel>
<VStack align="flex-start" w="full" p={3}>
<Text w="full" color="inherit">
Domain: {p.domain.name}
</Text>
<Text w="full" color="inherit">
Primary Type: {p.primaryType}
</Text>
<Text w="full" color="inherit">
Types:
</Text>
{Object.keys(p.types).map((key) =>
key === "StarknetDomain" ||
key === "StarkNetDomain" ? null : (
<Text key={key} w="full" color="inherit">
{key}: {JSON.stringify(p.types[key])}
</Text>
),
)}
</VStack>
</AccordionPanel>
</>
)}
</AccordionItem>
))}
</Accordion>
</Box>
</div>
);
}
10 changes: 6 additions & 4 deletions packages/keychain/src/components/session/ContractCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ export function ContractCard({
<Accordion type="multiple" defaultValue={["methods"]}>
<AccordionItem value="methods" className="flex flex-col gap-4">
<AccordionTrigger className="text-xs text-muted-foreground">
Approve{" "}
<span className="text-accent-foreground font-bold">
{methods.length} {methods.length > 1 ? "methods" : "method"}
</span>
<div>
Approve{" "}
<span className="text-accent-foreground font-bold">
{methods.length} {methods.length > 1 ? "methods" : "method"}
</span>
</div>
</AccordionTrigger>
<AccordionContent className="bg-background border border-background rounded-md gap-px">
{methods.map((method) => (
Expand Down
Loading

0 comments on commit e52e690

Please sign in to comment.