Skip to content

Commit

Permalink
feat: add group module support (#189)
Browse files Browse the repository at this point in the history
* added group module

* fix update member, vote, proposal pages

* update admin, metadata of group

* fix all txns in the group

* fix group module

* fix all updates on group proposal

* fix group proposal

* fix changes in group module

* fix group proposals

* fix the errors

* fixed proposal page

* fix version available feature

* fixed lazy loading for pages

* fix the comments

* fixed msg type
  • Loading branch information
charymalloju authored Sep 22, 2022
1 parent df9436f commit 900df7e
Show file tree
Hide file tree
Showing 62 changed files with 9,991 additions and 467 deletions.
2 changes: 2 additions & 0 deletions src/app/store.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { configureStore } from "@reduxjs/toolkit";
import stakeReducer from "../features/staking/stakeSlice";
import proposalsReducer from "../features/gov/govSlice";
import nodeReducer from "../features/node/nodeSlice";
import feegrantReducer from "../features/feegrant/feegrantSlice";
import authzReducer from "../features/authz/authzSlice";
import bankReducer from "../features/bank/bankSlice";
Expand All @@ -27,6 +28,7 @@ export const store = configureStore({
group: groupSlice,
multisig: multiSlice,
slashing: slashingSlice,
node: nodeReducer,
auth: authReducer,
},
middleware: (getDefaultMiddleware) =>
Expand Down
16 changes: 8 additions & 8 deletions src/components/AppDrawer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import LogoutOutlinedIcon from "@mui/icons-material/LogoutOutlined";
import ContentCopyOutlined from "@mui/icons-material/ContentCopyOutlined";
import Button from "@mui/material/Button";
import PropTypes from "prop-types";
import { drawerListItems } from "./drawerListItems";
import { DrawerListItems } from "./DrawerListItems";
import { parseBalance } from "../utils/denom";
import { shortenAddress } from "../utils/util";
import { useLocation } from "react-router-dom";
Expand Down Expand Up @@ -191,13 +191,13 @@ export default function AppDrawer(props) {
</List>
<Divider />
<List>
{drawerListItems(
location.pathname,
(path) => {
onNavigate(path);
},
selectedNetwork?.showAirdrop
)}
<DrawerListItems
currentPath={location.pathname}
onNavigate={(path) => {
onNavigate(path)
}}
showAirdrop={selectedNetwork?.showAirdrop}
/>
</List>
</Drawer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,34 @@ import LayersIcon from "@mui/icons-material/Layers";
import BarChartOutlinedIcon from "@mui/icons-material/BarChartOutlined";
import DocumentScannerOutlinedIcon from "@mui/icons-material/DocumentScannerOutlined";
import GroupsOutlinedIcon from "@mui/icons-material/GroupsOutlined";
import { useDispatch, useSelector } from "react-redux";
import { getNodeInfo } from "../features/node/nodeSlice";

export function DrawerListItems({ currentPath, onNavigate, showAirdrop }) {
const dispatch = useDispatch();
const [nodeDataInfo, setNodeDataInfo] = React.useState(false);

const wallet = useSelector(state => state?.wallet);
const { chainInfo } = wallet;
const nodeInfo = useSelector(state => state?.node)

React.useEffect(() => {
dispatch(getNodeInfo({ baseURL: chainInfo?.config?.rest }))
}, [])

React.useEffect(() => {
if (nodeInfo?.nodeInfo?.status === 'idle') {
if (nodeInfo?.nodeInfo?.data?.application_version) {
let version = nodeInfo?.nodeInfo?.data?.application_version?.version;

if (version?.indexOf('46') >= 0) {
setNodeDataInfo(true);
} else setNodeDataInfo(false);
}
}
}, [nodeInfo?.status])


export function drawerListItems(currentPath, onNavigate, showAirdrop) {
return (
<>
<ListItemButton
Expand Down Expand Up @@ -74,15 +100,20 @@ export function drawerListItems(currentPath, onNavigate, showAirdrop) {
<ListItemText primary="Feegrant" secondary="coming soon" />
</ListItemButton>
<ListItemButton
disabled
disabled={nodeDataInfo ? false : true}
onClick={() => onNavigate("/group")}
sx={{ pb: 0.5, pt: 0.5 }}
selected={currentPath === "/group"}
>
<ListItemIcon>
<GroupsOutlinedIcon />
</ListItemIcon>
<ListItemText primary="Groups" secondary="coming soon" />
<ListItemText primary="Groups"
secondary={
nodeDataInfo?.status === 'pending'? 'Loading..':
!nodeDataInfo ? 'Not supported':
null
} />
</ListItemButton>

{showAirdrop ? (
Expand Down
30 changes: 30 additions & 0 deletions src/components/group/AlertMsg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Alert, Card, Typography } from '@mui/material'
import React from 'react'
import { gpStyles } from './groupCmpStyles'

interface AlertMsgProps {
text: string,
type: string
}

const AlertMsg = ({ text, type = 'error' }: AlertMsgProps) => {
return (
<Card sx={gpStyles.alert_card}>
{
type === 'info' && <Alert
variant='outlined'
severity="info">
<Typography>{text}</Typography>
</Alert>
}

{
type === 'error' && <Alert variant='outlined' severity="error">
<Typography>{text}</Typography>
</Alert>
}
</Card>
)
}

export default AlertMsg
42 changes: 42 additions & 0 deletions src/components/group/CardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Grid, Paper, Skeleton } from '@mui/material'
import Typography, { TypographyProps } from '@mui/material/Typography';
import { experimentalStyled as styled } from '@mui/material/styles';
import React from 'react'

const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
...theme.typography.body2,
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
}));

function CardSkeleton() {
const variant = [
'h5',
'h6',
'h1',
] as readonly TypographyProps['variant'][];
const variants = [{ variant }, { variant }, { variant }]

return (
<Grid container>
{variants.map((variant) => (
<Grid sx={{ p: 2 }} md={4}>
<Item>
{
variant?.variant.map(v => (
<Typography component="div"
key={v} variant={v}>
<Skeleton />
</Typography>
))
}
</Item>
</Grid>
))}
</Grid>
)
}

export default CardSkeleton
88 changes: 88 additions & 0 deletions src/components/group/DialogVote.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Avatar from '@mui/material/Avatar';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import DialogTitle from '@mui/material/DialogTitle';
import Dialog from '@mui/material/Dialog';
import { ListItemButton } from '@mui/material';

const options = [{
label: 'Yes',
value: 1,
active: '#6d70fe'
}, {
label: 'No',
value: 3,
active: '#e87d91'
}, {
label: 'No with Veto',
value: 4,
active: 'red'
}, {
label: 'Abstain',
value: 2,
active: '#6e81cb'
}]

interface voteprops {
vote: number, proposalId: string
}
export interface SimpleDialogProps {
open: boolean;
proposalId: string;
selectedValue: string;
voteRes: any;
onConfirm: (obj: voteprops) => void;
onClose: (value: string) => void;
}

export default function DailogVote(props: SimpleDialogProps) {
const { onClose, voteRes, proposalId, onConfirm, selectedValue, open } = props;
const [vote, setVote] = React.useState(0);

const handleClose = () => {
onClose(selectedValue);
};

const handleListItemClick = (value: number) => {
setVote(value);
};

return (
<Dialog
fullWidth
sx={{ background: 'transparent', p: 3 }}
onClose={handleClose} open={open}>
<DialogTitle>Vote for Proposal # {proposalId}</DialogTitle>
<List sx={{ pt: 3, p: 6 }}>
{options.map((option) => (
<ListItem sx={{
p: 2,
m: 1,
borderRadius: '5px',
':hover': { background: option?.value === vote ? option?.active : null },
background: option?.value === vote ? option?.active : '#f3f3f3'
}} button
onClick={() => handleListItemClick(option?.value)} key={option?.label}>
<ListItemText primary={option?.label} />
</ListItem>
))}
<ListItem>
<ListItemButton sx={{ justifyContent: 'right' }}>
<Button onClick={() => {
onConfirm({
vote: vote,
proposalId: proposalId
})
}} variant='outlined'>{
voteRes?.status === 'pending'? 'Loading...': 'Confirm'
}</Button>
</ListItemButton>
</ListItem>
</List>
</Dialog>
);
}

125 changes: 125 additions & 0 deletions src/components/group/FileProposalOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Button, Grid } from '@mui/material';
import { Box } from '@mui/system';
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
import FileUploadOutlinedIcon from "@mui/icons-material/FileUploadOutlined";
import React from 'react';


const MULTISIG_SEND_TEMPLATE = "https://resolute.witval.com/_static/send.csv";
const MULTISIG_DELEGATE_TEMPLATE =
"https://resolute.witval.com/_static/delegate.csv";
const MULTISIG_UNDELEGATE_TEMPLATE =
"https://resolute.witval.com/_static/undelegate.csv";
const MULTISIG_REDELEGATE_TEMPLATE =
"https://resolute.witval.com/_static/redelegate.csv";


const TYPE_SEND = "SEND";
const TYPE_DELEGATE = "DELEGATE";
const TYPE_UNDELEGATE = "UNDELEGATE";
const TYPE_REDELEGATE = "REDELEGATE";

interface FileProposalOptionsProps {
txType: string,
onFileContents: any
}

function FileProposalOptions({
txType,
onFileContents
}: FileProposalOptionsProps) {

return (
<Box>
<Button
variant="contained"
disableElevation
size="small"
endIcon={<FileDownloadOutlinedIcon />}
sx={{
textTransform: "none",
}}
onClick={() => {
switch (txType) {
case TYPE_SEND:
window.open(
MULTISIG_SEND_TEMPLATE,
"_blank",
"noopener,noreferrer"
);
break;
case TYPE_DELEGATE:
window.open(
MULTISIG_DELEGATE_TEMPLATE,
"_blank",
"noopener,noreferrer"
);
break;
case TYPE_UNDELEGATE:
window.open(
MULTISIG_UNDELEGATE_TEMPLATE,
"_blank",
"noopener,noreferrer"
);
break;
case TYPE_REDELEGATE:
window.open(
MULTISIG_REDELEGATE_TEMPLATE,
"_blank",
"noopener,noreferrer"
);
break;
default:
alert("unknown message type");
}
}}
>
Download template
</Button>
<Button
variant="contained"
disableElevation
aria-label="upload file"
size="small"
endIcon={<FileUploadOutlinedIcon />}
sx={{
mb: 2,
mt: 2,
ml: 1,
textTransform: "none",
}}
onClick={() => {
document.getElementById("multisig_file")!.click();
}}
>
<input
id="multisig_file"
accept="*.csv"
hidden
type="file"
onChange={(e: any) => {
const file = e.target.files[0];
if (!file) {
return;
}

const reader = new FileReader();
reader.onload = (e: any) => {
const contents = e.target.result;
onFileContents(contents, txType);
};
reader.onerror = (e) => {
alert(e);
};
reader.readAsText(file);
e.target.value = null;
}}
/>
Upload csv file
</Button>
</Box>

)
}

export default FileProposalOptions
Loading

0 comments on commit 900df7e

Please sign in to comment.