Skip to content

Commit

Permalink
more robust validation on the update proposal edit button, fix reload…
Browse files Browse the repository at this point in the history
… sometimes not displaying prop content, add update-slug function to create a unique slug for update candidates with the same title
  • Loading branch information
ripe0x committed Nov 18, 2023
1 parent 2987143 commit a7977e4
Showing 1 changed file with 48 additions and 16 deletions.
64 changes: 48 additions & 16 deletions packages/nouns-webapp/src/pages/EditProposal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ const EditProposalPage: React.FC<EditProposalProps> = props => {
proposal?.description && removeTitleFromDescription(proposal?.description, titleValue);
const isProposedBySigners = proposal?.signers && proposal?.signers?.length > 0 ? true : false;

const candidateUpdateSlug = (slug: string) => {
// add random string to slug to make it unique
const randomString = Math.random().toString(36).substring(7);
return `${slug}-update-${randomString}`;
}

const handleAddProposalAction = useCallback(
(transactions: ProposalTransaction | ProposalTransaction[]) => {
const transactionsArray = Array.isArray(transactions) ? transactions : [transactions];
Expand Down Expand Up @@ -158,19 +164,24 @@ const EditProposalPage: React.FC<EditProposalProps> = props => {
const handleTitleInput = useCallback(
(title: string) => {
setTitleValue(title);
setSlug(
title
.toLowerCase()
.replace(/ /g, '-')
.replace(/[^\w-]+/g, ''),
);
if (isProposedBySigners && title === proposal?.title) {
// if title is edited, then reset to original, make sure the unique update slug gets passed
setSlug(candidateUpdateSlug(title));
} else {
setSlug(
title
.toLowerCase()
.replace(/ /g, '-')
.replace(/[^\w-]+/g, ''),
);
}
if (title === proposal?.title) {
setIsTitleEdited(false);
} else {
setIsTitleEdited(true);
}
},
[setTitleValue, setSlug, proposal?.title],
[setTitleValue, setSlug, proposal?.title, isProposedBySigners],
);

const handleBodyInput = useCallback(
Expand Down Expand Up @@ -358,6 +369,8 @@ const EditProposalPage: React.FC<EditProposalProps> = props => {
}
};



// set initial values on page load
useEffect(() => {
if (
Expand All @@ -377,31 +390,38 @@ const EditProposalPage: React.FC<EditProposalProps> = props => {
signature: txn.functionSig ?? '',
};
});
const slugValue = proposal.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
setTitleValue(proposal.title);
setSlug(
proposal.title
.toLowerCase()
.replace(/ /g, '-')
.replace(/[^\w-]+/g, ''),
);
if (isProposedBySigners) {
// new candidate will need to be created, which needs a unique slug, so add a random string to the slug here
setSlug(candidateUpdateSlug(slugValue));
} else {
setSlug(slugValue);
}
setBodyValue(removeTitleFromDescription(proposal.description, proposal.title));
setProposalTransactions(transactions);
setOriginalTitleValue(proposal.title);
setOriginalBodyValue(removeTitleFromDescription(proposal.description, proposal.title));
setOriginalProposalTransactions(proposal.details);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [proposal]);

const handleCreateNewCandidate = async () => {
if (!proposalTransactions?.length ||
!titleValue ||
!bodyValue ||
!slug ||
!props.match.params.id
) return;
await createProposalCandidate(
proposalTransactions.map(({ address }) => address), // Targets
proposalTransactions.map(({ value }) => value ?? '0'), // Values
proposalTransactions.map(({ signature }) => signature), // Signatures
proposalTransactions.map(({ calldata }) => calldata), // Calldatas
`# ${titleValue}\n\n${bodyValue}`, // Description
slug, // Slug
props.match.params.id, // proposalIdToUpdate - use 0 for new proposals
props.match.params.id, // use 0 for new proposals
{ value: availableVotes! > 0 ? 0 : createCandidateCost },
);
};
Expand Down Expand Up @@ -449,6 +469,18 @@ const EditProposalPage: React.FC<EditProposalProps> = props => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [createProposalCandidateState, setModal]);

const isFormInvalid = () => {
if (
!(isProposalEdited || isTransactionsEdited() || isDescriptionEdited()) ||
!proposalTransactions.length ||
titleValue === '' ||
bodyValue === '' ||
slug === ''
) {
return true;
}
return false;
}
if (!isProposer()) {
return null;
}
Expand Down Expand Up @@ -535,7 +567,7 @@ const EditProposalPage: React.FC<EditProposalProps> = props => {
hasActiveOrPendingProposal={false} // not relevant for edit
hasEnoughVote={isProposer() ? true : hasEnoughVote}
isFormInvalid={
isProposalEdited || isTransactionsEdited() || isDescriptionEdited() ? false : true
isFormInvalid()
}
handleCreateProposal={
isProposedBySigners ? handleCreateNewCandidate : handleUpdateProposal
Expand Down

0 comments on commit a7977e4

Please sign in to comment.