Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a proposals description when selecting a proposal #22

Open
wants to merge 16 commits into
base: develop-deprecated
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion apps/enterprise/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { ThemeProvider } from 'styled-components';
import { GlobalStyle } from 'lib/ui/GlobalStyle';
import { TransactionErrorProvider } from 'chain/components/TransactionErrorProvider';
import { CreateProposalPage } from 'pages/create-proposal/CreateProposalPage';
import { ConditionalWallet } from 'components/conditional-wallet';

const queryClient = new QueryClient();

Expand Down Expand Up @@ -56,7 +57,10 @@ const AppBetaRoutes = () => {
<Route path="staking" element={<DAOStakingPage />} />
<Route path="members" element={<DAOMembersPage />} />
</Route>
<Route path="/dao/:address/proposals/create" element={<SelectProposalTypePage />} />
<Route
path="/dao/:address/proposals/create"
element={<ConditionalWallet connected={() => <SelectProposalTypePage />} />}
/>
<Route path="/dao/:address/proposals/create/:type" element={<CreateProposalPage />} />
<Route path="/dao/create" element={<CreateDAOPage />} />
<Route path="/dao/:address/proposals/:id" element={<ProposalPage />} />
Expand Down
1 change: 1 addition & 0 deletions apps/enterprise/src/chain/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const lunaDecimals = 6
13 changes: 13 additions & 0 deletions apps/enterprise/src/chain/queries/useDelegationsQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { QUERY_KEY } from 'queries';
import { useQuery } from 'react-query';
import { useLCDClient } from '@terra-money/wallet-provider';

export const useDelegationsQuery = (delegatorAddress: string) => {
const client = useLCDClient();

return useQuery([QUERY_KEY.DELEGATIONS, delegatorAddress], async () => {
// TODO: handle pagination
const [delegations] = await client.staking.delegations(delegatorAddress);
return delegations;
});
};
4 changes: 4 additions & 0 deletions apps/enterprise/src/chain/utils/validators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { terraAddressRegex } from '@terra-money/apps/utils';
import * as z from 'zod';

export const zodAddressValidator = z.string().regex(terraAddressRegex, { message: 'Invalid Terra address' });
28 changes: 17 additions & 11 deletions apps/enterprise/src/components/Navigation/SideNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,34 @@ export const SideNavigation = () => {
</InternalLink>
<VStack gap={12}>
<Tooltip title="Dashboard" placement="right" arrow={true}>
<DashboardButton />
<div>
<DashboardButton />
</div>
</Tooltip>
<Tooltip title="Manage your favourite DAOs" placement="right" arrow={true}>
<ManageDaosButton />
<div>
<ManageDaosButton />
</div>
</Tooltip>
<Favourites />
</VStack>
</VStack>
<VStack gap={24} alignItems="center">
<Tooltip title="Got feedback?" placement="right" arrow={true}>
<ExternalLink to="https://terra.sc/enterprisefeedback">
<IconButton variant="outline">
<ChatIcon />
</IconButton>
</ExternalLink>
<div>
<ExternalLink to="https://terra.sc/enterprisefeedback">
<IconButton variant="outline">
<ChatIcon />
</IconButton>
</ExternalLink>
</div>
</Tooltip>
{connectedWallet && (
<div>
<Tooltip title="Create a DAO" placement="right" arrow={true}>
<Tooltip title="Create a DAO" placement="right" arrow={true}>
<div>
<CreateDaoButton />
</Tooltip>
</div>
</div>
</Tooltip>
)}
</VStack>
</Container>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { getValueProviderSetup } from '@terra-money/apps/utils';
import { ProposalAction } from 'dao/shared/proposal';

export const { useValue: useCurrentProposalAction, provider: CurrentProposalActionProvider } =
getValueProviderSetup<ProposalAction>('ProposalAction');
62 changes: 60 additions & 2 deletions apps/enterprise/src/dao/shared/proposal.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
const sharedProposalTypes = [
import { capitalizeFirstLetter } from 'lib/shared/utils/capitalizeFirstLetter';
import { Proposal } from 'types';
import { enterprise } from 'types/contracts';

export const sharedProposalTypes = [
'text',
'metadata',
'config',
'upgrade',
'assets',
'nfts',
'execute',
'spend',
'delegate',
'undelegate',
'council',
] as const;

const daoProposalsRecord = {
export const daoProposalsRecord = {
multisig: [...sharedProposalTypes, 'members'] as const,
token: [...sharedProposalTypes, 'mint', 'burn'] as const,
nft: sharedProposalTypes,
Expand All @@ -23,6 +29,7 @@ export type ProposalType =

export const proposalTitle: Record<ProposalType, string> = {
text: 'Text proposal',
metadata: 'Update metadata proposal',
config: 'Update configuration proposal',
upgrade: 'Upgrade proposal',
assets: 'Update whitelisted assets',
Expand All @@ -33,9 +40,60 @@ export const proposalTitle: Record<ProposalType, string> = {
mint: 'Mint token proposal',
burn: 'Burn token proposal',
delegate: 'Delegate LUNA proposal',
undelegate: 'Undelegate LUNA proposal',
council: 'Update council',
};

export const proposalVotingTypes = ['regular', 'council'] as const;

export type ProposalVotingType = typeof proposalVotingTypes[number];

export const proposalActionShortName: Record<enterprise.ProposalActionType, string> = {
update_metadata: 'metadata',
update_gov_config: 'gov',
update_council: 'council',
update_asset_whitelist: 'assets',
update_nft_whitelist: 'nfts',
request_funding_from_dao: 'funding',
upgrade_dao: 'upgrade',
execute_msgs: 'execute',
modify_multisig_membership: 'members',
};

export const getProposalActionType = (action: enterprise.ProposalAction): enterprise.ProposalActionType => {
return Object.keys(action)[0] as enterprise.ProposalActionType;
};

export type ProposalActionMsg =
| enterprise.UpdateMetadataMsg
| enterprise.UpdateGovConfigMsg
| enterprise.UpdateCouncilMsg
| enterprise.UpdateAssetWhitelistMsg
| enterprise.UpdateNftWhitelistMsg
| enterprise.RequestFundingFromDaoMsg
| enterprise.UpgradeDaoMsg
| enterprise.ExecuteMsgsMsg
| enterprise.ModifyMultisigMembershipMsg;

export interface ProposalAction {
type: enterprise.ProposalActionType;
msg: ProposalActionMsg;
}

export const getProposalActionMsg = (action: enterprise.ProposalAction): ProposalActionMsg => {
return Object.values(action)[0] as ProposalActionMsg;
};

export const getProposalTypeName = (proposal: Proposal) => {
const { proposal_actions } = proposal;
const action = proposal_actions[0];
if (!action) {
return 'Text';
}
const type = getProposalActionType(action);
if (!type) {
return 'Other';
}

return capitalizeFirstLetter(proposalActionShortName[type]);
};
16 changes: 12 additions & 4 deletions apps/enterprise/src/pages/create-dao/DaoWizardFormProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface DaoSocialDataInput {

export interface DaoInfoInput {
name: string;
description: string;
description?: string;
logo?: string;
}

Expand Down Expand Up @@ -66,7 +66,7 @@ export interface DaoWizardInput {
initialDaoBalance: number | undefined;
tokenMarketing: FormState<TokenMarketing>;

council: FormState<CouncilInput>;
council?: FormState<CouncilInput>;

existingTokenAddr: string;
existingToken: CW20TokenInfoResponse | undefined;
Expand Down Expand Up @@ -134,7 +134,12 @@ export interface DaoWizardState extends DaoWizardInput {
}

const sharedInitialSteps: DaoWizardStep[] = ['type', 'info', 'daoImport'];
const sharedLastSteps: DaoWizardStep[] = ['govConfig', 'council', 'socials', 'confirm'];
const sharedLastSteps: DaoWizardStep[] = [
'govConfig',
// 'council',
'socials',
'confirm',
];

const daoTypeSpecificSteps: Record<enterprise.DaoType, DaoWizardStep[]> = {
multisig: ['members'],
Expand All @@ -160,7 +165,7 @@ const getInitialState = (timeConversionFactor: number, walletAddr: string | unde
type: defaultDaoType,
info: {
name: '',
description: '',
// description: '',
logo: undefined,
},
isValid: true,
Expand Down Expand Up @@ -295,6 +300,9 @@ const validateCurrentStep = (state: DaoWizardState): Partial<DaoWizardState> =>
},

council: () => {
// TODO: remove TEMP changes
if (!state.council) return {};

const council = validateCouncil(state.council);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const toCreateDaoMsg = (input: DaoWizardState): CreateDaoMsgType => {
return {
create_dao: {
dao_council:
council.members.length > 0
council && council.members.length > 0
? {
members: council.members.map((member) => member.address),
allowed_proposal_action_types: council.allowedProposalTypes,
Expand Down
6 changes: 4 additions & 2 deletions apps/enterprise/src/pages/create-dao/shared/CouncilStep.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { removeByIndex, updateAtIndex } from '@terra-money/apps/utils';
import { assertDefined, removeByIndex, updateAtIndex } from '@terra-money/apps/utils';
import { AddButton } from 'components/add-button';
import { DeleteIconButton } from 'components/delete-icon-button';
import { TextInput } from 'lib/ui/inputs/TextInput';
Expand All @@ -11,9 +11,11 @@ import { CouncilProposalActionType, ProposalTypesInput } from './ProposalTypesIn
export function CouncilStep() {
const {
formInput,
formState: { council, isValid },
formState: { council: optionalCouncil, isValid },
} = useDaoWizardForm();

// TODO: temporary change
const council = assertDefined(optionalCouncil);
const { members, allowedProposalTypes } = council;

const updateMembers = (members: CouncilMember[]) => formInput({ council: { ...council, members } });
Expand Down
6 changes: 3 additions & 3 deletions apps/enterprise/src/pages/create-dao/shared/InfoStep.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Stack } from '@mui/material';
import { DescriptionInput } from 'pages/create-proposal/shared/DescriptionInput';
// import { DescriptionInput } from 'pages/create-proposal/shared/DescriptionInput';
import { DaoInfoInput, useDaoWizardForm } from '../DaoWizardFormProvider';
import { WizardInput } from '../WizardInput';
import { WizardStep } from '../WizardStep';
Expand Down Expand Up @@ -27,12 +27,12 @@ export function InfoStep() {
error={info.name?.length > 0 ? info.nameError : undefined}
onChange={({ currentTarget }) => onChange({ name: currentTarget.value })}
/>
<DescriptionInput
{/* <DescriptionInput
label="Description"
value={info.description}
error={info.descriptionError}
onChange={(description) => onChange({ description })}
/>
/> */}
<WizardInput
label="Logo URL"
placeholder="Type the URL of your DAO's logo"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import styled from 'styled-components';
import { VStack } from 'lib/ui/Stack';
import { Header } from './Header';
import { CreateProposalProvider } from './CreateProposalProvider';
import { MetadataProposalForm } from './metadata/MetadataProposalForm';
import { UndelegateProposalForm } from './undelegate/UndelegateProposalForm';

type CreateProposalPageParams = {
type: ProposalType;
Expand Down Expand Up @@ -70,6 +72,7 @@ export const CreateProposalPage = () => {
<Header title={proposalTitle[type]} />
<ConditionalRender
value={assertDefined(type)}
metadata={() => <MetadataProposalForm />}
council={() => <CouncilForm />}
text={() => <TextProposalForm />}
config={() => <CreateConfigProposalPage />}
Expand All @@ -82,6 +85,7 @@ export const CreateProposalPage = () => {
spend={() => <SpendTreasuryProposalPage />}
burn={() => <BurnTokensProposalPage />}
delegate={() => <DelegateProposalPage />}
undelegate={() => <UndelegateProposalForm />}
/>
</CurrentDaoProvider>
) : null}
Expand Down
58 changes: 7 additions & 51 deletions apps/enterprise/src/pages/create-proposal/SelectProposalType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,65 +12,21 @@ import { PrimarySelect } from 'lib/ui/inputs/PrimarySelect';
import styled from '@emotion/styled';
import { without } from 'lodash';
import { DAO } from 'types';
import { enterprise } from 'types/contracts';
import { Text } from 'lib/ui/Text';
import { useMyVotingPower } from 'dao/components/MyVotingPowerProvider';
import { useAmICouncilMember } from 'dao/hooks/useAmICouncilMember';
import { daoProposalsRecord, proposalTitle, ProposalType } from 'dao/shared/proposal';
import { CouncilProposalActionType } from 'pages/create-dao/shared/ProposalTypesInput';

const sharedProposalTypes = [
'text',
'config',
'upgrade',
'assets',
'nfts',
'execute',
'spend',
'delegate',
'council',
] as const;

const daoProposalsRecord = {
multisig: [...sharedProposalTypes, 'members'] as const,
token: [...sharedProposalTypes, 'mint', 'burn'] as const,
nft: sharedProposalTypes,
} as const;

export type ProposalType =
| typeof daoProposalsRecord.multisig[number]
| typeof daoProposalsRecord.token[number]
| typeof daoProposalsRecord.nft[number];

const contractsProposalTypeRecord: Partial<Record<enterprise.ProposalActionType, ProposalType>> = {
// TODO
// update_metadata
// update_config
// request_funding_from_dao

update_council: 'council',
const title = 'Create a proposal';

const contractsProposalTypeRecord: Record<CouncilProposalActionType, ProposalType> = {
update_asset_whitelist: 'assets',
update_nft_whitelist: 'nfts',
upgrade_dao: 'upgrade',
execute_msgs: 'execute',
modify_multisig_membership: 'members',
};

export const proposalTitle: Record<ProposalType, string> = {
text: 'Text proposal',
config: 'Update configuration proposal',
upgrade: 'Upgrade proposal',
assets: 'Update whitelisted assets',
nfts: 'Update whitelisted NFTs',
execute: 'Proposal to execute message',
members: 'Update multisig members',
spend: 'Spend treasury proposal',
mint: 'Mint token proposal',
burn: 'Burn token proposal',
delegate: 'Delegate LUNA proposal',
council: 'Update council',
update_metadata: 'metadata',
};

const title = 'Create a proposal';

// TODO: turn into a reusable component
const NormalScreenContainer = styled(VStack)`
padding: 48px 48px 64px 48px;
Expand Down Expand Up @@ -101,7 +57,7 @@ const getProposalOptions = ({ type, council }: DAO, proposalVotingType: Proposal
const { allowed_proposal_action_types } = council;
if (allowed_proposal_action_types) {
return allowed_proposal_action_types.reduce((acc, type) => {
const proposalType = contractsProposalTypeRecord[type];
const proposalType = contractsProposalTypeRecord[type as CouncilProposalActionType];
if (proposalType) {
acc.push(proposalType);
}
Expand Down
Loading