Skip to content

Commit

Permalink
Merge pull request #548 from alleslabs/feat/module-interact-v2
Browse files Browse the repository at this point in the history
feat: interaction query param
  • Loading branch information
songwongtp committed Sep 27, 2023
2 parents 4d0eafe + c32b220 commit f6165d2
Show file tree
Hide file tree
Showing 36 changed files with 283 additions and 134 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Improvements

- [#548](https://github.com/alleslabs/celatone-frontend/pull/548) Handle interaction page query param and refactor page
- [#546](https://github.com/alleslabs/celatone-frontend/pull/546) Handle 404 on the current selected chain
- [#540](https://github.com/alleslabs/celatone-frontend/pull/540) Add open proposal configuration
- [#532](https://github.com/alleslabs/celatone-frontend/pull/532) Implement new Amplitude structure
Expand Down
2 changes: 1 addition & 1 deletion src/lib/layout/navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const Navbar = observer(({ isExpand, setIsExpand }: NavbarProps) => {
},
{
name: "View / Execute",
slug: "/interaction",
slug: "/interact",
icon: "execute" as IconKeys,
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Button, Flex } from "@chakra-ui/react";

import { ModuleContainer } from "../common";
import { ExecuteArea, ViewArea } from "../form";
import { CustomIcon } from "lib/components/icon";
import { EmptyState } from "lib/components/state";
import type { IndexedModule } from "lib/services/moduleService";
import type { ExposedFunction, HexAddr, Option } from "lib/types";

import { ModuleContainer } from "./common";
import { ExecuteArea, ViewArea } from "./form";
import { SelectedFunctionCard } from "./SelectedFunctionCard";

interface FunctionSelectBodyProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ import { Accordion, Flex } from "@chakra-ui/react";
import type { Dispatch, SetStateAction } from "react";
import { useMemo, useState } from "react";

import {
NoImageEmptyState,
ModuleContainer,
InteractionTabs,
InteractionTypeSwitch,
} from "../common";
import { FunctionAccordion } from "../common/FunctionAccordion";
import InputWithIcon from "lib/components/InputWithIcon";
import { EmptyState } from "lib/components/state";
import type { IndexedModule } from "lib/services/moduleService";
import type { ExposedFunction, Option } from "lib/types";
import { checkAvailability } from "lib/utils";

import {
NoImageEmptyState,
ModuleContainer,
InteractionTabs,
InteractionTypeSwitch,
FunctionAccordion,
} from "./common";

const EmptyStateRender = ({ desc }: { desc: string }) => (
<ModuleContainer h="full">
<EmptyState
Expand All @@ -40,7 +41,7 @@ const RenderFunctions = ({
}: {
states: FunctionStates;
selectedFn: Option<ExposedFunction>;
setSelectedFn: Dispatch<SetStateAction<Option<ExposedFunction>>>;
setSelectedFn: (fn: ExposedFunction) => void;
}) => {
if (!states.filteredFunctions)
return (
Expand Down Expand Up @@ -75,16 +76,19 @@ const RenderFunctions = ({

interface FunctionSelectPanelProps {
module: Option<IndexedModule>;
tab: InteractionTabs;
setTab: Dispatch<SetStateAction<InteractionTabs>>;
selectedFn: Option<ExposedFunction>;
setSelectedFn: Dispatch<SetStateAction<Option<ExposedFunction>>>;
setSelectedFn: (fn: ExposedFunction) => void;
}

export const FunctionSelectPanel = ({
module,
tab,
setTab,
selectedFn,
setSelectedFn,
}: FunctionSelectPanelProps) => {
const [tab, setTab] = useState(InteractionTabs.VIEW_MODULE);
const [keyword, setKeyword] = useState("");

const functionStates = useMemo<FunctionStates>(() => {
Expand All @@ -104,9 +108,8 @@ export const FunctionSelectPanel = ({
};
}, [keyword, tab, module?.executeFunctions, module?.viewFunctions]);

// TODO: find a better way to handle height
return (
<Flex direction="column" maxH="calc(100vh - 364px)" overflow="scroll">
<div>
<InputWithIcon
iconPosition="start"
value={keyword}
Expand All @@ -119,11 +122,14 @@ export const FunctionSelectPanel = ({
my={3}
counts={[module?.viewFunctions.length, module?.executeFunctions.length]}
/>
<RenderFunctions
states={functionStates}
selectedFn={selectedFn}
setSelectedFn={setSelectedFn}
/>
</Flex>
{/* TODO: find a better way to handle height */}
<Flex direction="column" maxH="calc(100vh - 400px)" overflow="scroll">
<RenderFunctions
states={functionStates}
selectedFn={selectedFn}
setSelectedFn={setSelectedFn}
/>
</Flex>
</div>
);
};
61 changes: 61 additions & 0 deletions src/lib/pages/interact/component/common/FunctionAccordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Flex,
Text,
} from "@chakra-ui/react";

import { CountBadge, FunctionCard } from "lib/components/module";
import type { ExposedFunction, Option } from "lib/types";

import { NoImageEmptyState } from "./EmptyState";

interface FunctionAccordionProps {
filteredFns: ExposedFunction[];
isEmpty: boolean;
triggerText: string;
selectedFn: Option<ExposedFunction>;
setSelectedFn: (fn: ExposedFunction) => void;
}

export const FunctionAccordion = ({
filteredFns,
isEmpty,
triggerText,
selectedFn,
setSelectedFn,
}: FunctionAccordionProps) => (
<AccordionItem bg="background.main" py={1}>
<h6>
<AccordionButton>
<Flex align="center" justify="space-between" gap={2}>
<Text variant="body2" color="text.dark">
{triggerText}
</Text>
<CountBadge count={filteredFns.length} variant="common" />
</Flex>
<AccordionIcon color="gray.600" ml="auto" />
</AccordionButton>
</h6>
<AccordionPanel py={3} px={0}>
<Flex flexDirection="column" gap={1}>
{filteredFns.length ? (
filteredFns.map((fn) => (
<FunctionCard
key={fn.name}
variant={selectedFn?.name === fn.name ? "selected" : "common"}
exposedFn={fn}
onFunctionSelect={setSelectedFn}
/>
))
) : (
<NoImageEmptyState
desc={isEmpty ? "No function" : "No matching function found"}
/>
)}
</Flex>
</AccordionPanel>
</AccordionItem>
);
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./EmptyState";
export * from "./FunctionAccordion";
export * from "./InteractionTypeSwitch";
export * from "./ModuleContainer";
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import {
DrawerBody,
Flex,
} from "@chakra-ui/react";
import { useState } from "react";
import { useEffect, useState } from "react";

import { ModuleEmptyState } from "../common";
import { useConvertHexAddress } from "lib/app-provider";
import { CustomIcon } from "lib/components/icon";
import type { IndexedModule } from "lib/services/moduleService";
import type { HexAddr, HumanAddr } from "lib/types";
import {
useAccountModules,
type IndexedModule,
} from "lib/services/moduleService";
import type { HexAddr, HumanAddr, MoveAccountAddr, Option } from "lib/types";

import { ModuleSelectMainBody } from "./body";
import { ModuleSelector } from "./selector";
Expand All @@ -23,23 +27,62 @@ import type {
ModuleSelectFunction,
} from "./types";

interface ModuleSelectDrawerTriggerProps {
interface ModuleSelectDrawerProps {
isOpen: boolean;
onClose: () => void;
hexAddress: Option<HexAddr>;
handleModuleSelect: ModuleSelectFunction;
}

export const ModuleSelectDrawer = ({
isOpen,
onClose,
hexAddress,
handleModuleSelect,
}: ModuleSelectDrawerTriggerProps) => {
const [modules, setModules] = useState<IndexedModule[]>();
}: ModuleSelectDrawerProps) => {
const convertHexAddr = useConvertHexAddress();

const [mode, setMode] = useState<DisplayMode>("input");
const [selectedAddress, setSelectedAddress] = useState<SelectedAddress>({
address: "" as HumanAddr,
hex: "" as HexAddr,
});
const [modules, setModules] = useState<IndexedModule[]>();

const { refetch } = useAccountModules({
address: selectedAddress.hex as MoveAccountAddr,
moduleName: undefined,
functionName: undefined,
options: {
refetchOnWindowFocus: false,
enabled: false,
retry: false,
onSuccess: (data) => {
if (Array.isArray(data)) setModules(data);
},
},
});

useEffect(() => {
if (hexAddress) {
setMode("display");
setSelectedAddress({
address: convertHexAddr(hexAddress),
hex: hexAddress,
});
} else {
setMode("input");
setSelectedAddress({
address: "" as HumanAddr,
hex: "" as HexAddr,
});
setModules(undefined);
}
}, [convertHexAddr, hexAddress]);

useEffect(() => {
if (isOpen && selectedAddress.hex) refetch();
}, [isOpen, refetch, selectedAddress.hex]);

return (
<Drawer isOpen={isOpen} onClose={onClose} placement="bottom">
Expand All @@ -58,9 +101,9 @@ export const ModuleSelectDrawer = ({
mode={mode}
selectedAddress={selectedAddress}
setSelectedAddress={setSelectedAddress}
setModules={setModules}
setMode={setMode}
handleModuleSelect={handleModuleSelect}
setModules={setModules}
closeModal={onClose}
/>
{modules ? (
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pages/interact/component/drawer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./ModuleSelectDrawer";
export * from "./ModuleSelectDrawerTrigger";
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
useExampleAddresses,
} from "lib/app-provider";
import { TextInput } from "lib/components/forms";
import { useValidateModuleInput } from "lib/pages/interaction/hooks/useValidateModuleInput";
import { useValidateModuleInput } from "lib/pages/interact/hooks/useValidateModuleInput";
import type { IndexedModule } from "lib/services/moduleService";
import { useAccountModules } from "lib/services/moduleService";
import type { MoveAccountAddr, HexAddr, HumanAddr, Option } from "lib/types";
Expand All @@ -36,7 +36,7 @@ export const ModuleSelectorInput = ({
setMode,
closeModal,
}: ModuleSelectorInputProps) => {
const [keyword, setKeyword] = useState(selectedAddress.address as string);
const [keyword, setKeyword] = useState(selectedAddress.hex as string);
const [error, setError] = useState("");
const [addr, moduleName, functionName] = useMemo(
() => splitModule(keyword),
Expand All @@ -54,7 +54,6 @@ export const ModuleSelectorInput = ({
options: {
refetchOnWindowFocus: false,
enabled: false,
refetchOnMount: true,
retry: false,
onSuccess: (data) => {
setError("");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { DisplayMode } from "../types";

import { ModuleSelectorDisplay } from "./SelectorDisplay";
import type { ModuleSelectorInputProps } from "./SelectorInput";
import { ModuleSelectorInput } from "./SelectorInput";
import { ModuleSelectorDisplay } from "./ModuleSelectorDisplay";
import type { ModuleSelectorInputProps } from "./ModuleSelectorInput";
import { ModuleSelectorInput } from "./ModuleSelectorInput";

interface ModuleSelectorProps extends ModuleSelectorInputProps {
mode: DisplayMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,26 @@ export const ExecuteArea = ({

return (
<Flex direction="column">
<ConnectWalletAlert
subtitle="You need to connect your wallet to perform this action"
mb={8}
/>
{fn.is_entry ? (
<ConnectWalletAlert
subtitle="You need to connect your wallet to perform this action"
mb={8}
/>
) : (
<Alert variant="warning" mb={8} alignItems="center" gap={4}>
<CustomIcon
name="alert-circle-solid"
boxSize={4}
color="warning.main"
/>
<AlertDescription wordBreak="break-word">
Title This function cannot be executed through this page. Only
execute functions with “is_entry: true” and visibility is “public”
or “friend” are able to interacted through Celatone’s module
interactions.
</AlertDescription>
</Alert>
)}
<AbiForm
fn={executeFn}
initialData={data}
Expand All @@ -138,8 +154,8 @@ export const ExecuteArea = ({
</AlertDescription>
</Alert>
)}
<Flex alignItems="center" justify="space-between" mt={6}>
<Button>TODO: CodeSnippet</Button>
<Flex alignItems="center" justify="end" mt={6}>
{/* <Button>TODO: CodeSnippet</Button> */}
<Flex direction="row" align="center" gap={2}>
<Flex fontSize="14px" color="text.dark" alignItems="center">
Transaction Fee:{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ export const ViewArea = ({
propsOnChange={setAbiData}
propsOnErrors={setAbiErrors}
/>
<Flex justify="space-between" mt={4}>
<Button>TODO: CodeSnippet</Button>
<Flex justify="end" mt={4}>
{/* <Button>TODO: CodeSnippet</Button> */}
<Button
variant="primary"
fontSize="14px"
Expand Down
5 changes: 5 additions & 0 deletions src/lib/pages/interact/component/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./common";
export * from "./drawer";
export * from "./form";
export * from "./FunctionSelectBody";
export * from "./FunctionSelectPanel";
Loading

1 comment on commit f6165d2

@vercel
Copy link

@vercel vercel bot commented on f6165d2 Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.