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

Add indicator for pending proposal #1998

Merged
merged 21 commits into from
Jun 18, 2024
Merged

Conversation

DarksightKellar
Copy link
Contributor

This PR temporarily caches recently created proposal data (transaction hash and metadata). The application can then read this cache and indicate to the user that there are pending proposals waiting to be shown on the UI when ready.

The cached proposal is removed when proposals are loaded and any of them has a transaction hash that matches its transaction hash.

Pending toast:
Screenshot 2024-06-13 at 18 01 24

Toast dismissed when proposal shows up:
Screenshot 2024-06-13 at 18 01 43

Note: the toast is a temporary workaround while waiting on @decentdao/design to finalise the actual look for pending proposal(s) UI.

closes #1983

Copy link

netlify bot commented Jun 13, 2024

Deploy Preview for decent-interface-dev ready!

Name Link
🔨 Latest commit f81788d
🔍 Latest deploy log https://app.netlify.com/sites/decent-interface-dev/deploys/66710585e4951100088131fa
😎 Deploy Preview https://deploy-preview-1998.app.dev.decentdao.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@DarksightKellar DarksightKellar requested review from a team June 13, 2024 17:39
@nicolaus-sherrill
Copy link

@DarksightKellar are you thinking that this would be a new card added to the top of the list that communicates "this is temporary until your actual proposal is visible"?

@DarksightKellar
Copy link
Contributor Author

@DarksightKellar are you thinking that this would be a new card added to the top of the list that communicates "this is temporary until your actual proposal is visible"?

@nicolaus-sherrill Yep, I had 2 options in mind:

  • a single new card that communicates that one or more proposals are pending

  • a new list that shows basic data for each pending proposal. These won't be clickable, of course

This PR's set up for both, so that won't be an issue, just need to decide which is better UX

Copy link
Contributor

@Da-Colon Da-Colon left a comment

Choose a reason for hiding this comment

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

a few minor comments

@DarksightKellar DarksightKellar requested review from Da-Colon and a team June 14, 2024 14:02
.filter(proposal => filters.includes(proposal.state!))
return (proposals || [])
.filter(proposal => {
removeTemporaryProposal(proposal.transactionHash!);
Copy link
Member

@adamgall adamgall Jun 14, 2024

Choose a reason for hiding this comment

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

Hmm, at first glance it feels weird to have this state-changing code within a filter....

I wouldn't expect a filter to have side effects like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeahhh I was trying to avoid having run yet another loop over the proposals just to remove potentially 1 (if ever) pending proposal. Besides filter is just a fancy way of doing map plus manually adding to a pre-declared array based on the predicate. I'm totally fine with it in this case.

Copy link
Member

Choose a reason for hiding this comment

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

I just don't think this code belongs here. We're way to far up at the presentation layer to be fucking around with cleaning up our localstorage state.

Could this go into the the reducer actions for when saving actual proposals into state?

const temporaryProposals = (getValue(CacheKeys.TEMP_PROPOSALS, chain.id) ||
[]) as TempProposalData[];
const updatedProposals = [...temporaryProposals, tempProposal];
setValue(CacheKeys.TEMP_PROPOSALS, updatedProposals, CacheExpiry.ONE_DAY);
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, but actually, how was the decision made to store these "temporary pending" proposals in local storage?

I understand that these will persist through a refresh, but do we really need that?

imo seems a bit overkill to utilize localstorage for this functionality.

Copy link
Member

@adamgall adamgall Jun 14, 2024

Choose a reason for hiding this comment

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

@DarksightKellar this is probably my most important and biggest-picture question about this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm I suppose this could all be implemented with "simpler" app state. But I've tested (and tasted) the ability to refresh and still seeing that persistent pending toast. I like it and don't wanna go back.

Besides, won't the logic largely be the same? The only real difference feels like it'd be where the temp data is coming from (+ the tiny extra ms needed to read/write to storage).

Copy link
Contributor

@Da-Colon Da-Colon Jun 16, 2024

Choose a reason for hiding this comment

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

We could go crazy and make it slightly more 'complex' and use netlify/functions and the store? though probably not worth the lift to show all viewers of pending proposals.

Copy link
Member

Choose a reason for hiding this comment

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

It wouldn't make sense to show anyone other than the creator of the proposal, anything about that proposal before their RPC node picked up the block and added it to the official in-memory list.

Copy link
Member

Choose a reason for hiding this comment

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

I do still think localstorage is a bit excessive for this implementation, but that's on me for not being clearer on upfront on what I was expecting.

I'll need to go look at the code again that manages adding/removing from this "pending transaction" datastore in localstorage...

transactionHash: multiSigTransaction.transactionHash,
transactionHash:
multiSigTransaction.transactionHash ||
(transaction as SafeMultisigTransactionWithTransfersResponse).safeTxHash,
Copy link
Member

Choose a reason for hiding this comment

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

Is this needed? The code builds for me without this change.

Logically, I suppose the reason why it would needed is if transactionHash is the empty string (Typescript says it's type is simply string).

empty string is falsey, so safeTxHash will be used in the || conditional.

Smells to me like maybe this is an opportunity to tighten up some typing.

Do you follow where my head's at? and if so do you agree? If so, Please add a TODO comment here for someone searching the codebase later for things to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is needed, yep. The typing in that case is misleading, and multiSigTransaction.transactionHash turns out to always be an empty string (or was it undefined?). I chose not to replace the line with transactionHash: (transaction as SafeMultisigTransactionWithTransfersResponse).safeTxHash in case there's some legacy reasoning behind the choice in the first place.

I'll add the todo for the team to revisit this.

@tomstuart123
Copy link

@DarksightKellar
Copy link
Contributor Author

@DarksightKellar - I maybe missing something but I couldn't replicate this and get the toaster to show up.

I tried 4 proposals here - https://deploy-preview-1998.app.dev.decentdao.org/proposals?dao=sep:0x40C6E5eFCE3b1f101bFB59e876F14aa5455D3E19

Video here - https://decentdao.slack.com/archives/C06QZTUTKRC/p1718379588738149?thread_ts=1718379569.781799&cid=C06QZTUTKRC

@tomstuart123 Yikes, one of the newer cleanup commits broke the cache. I've reverted -- should be working now

@DarksightKellar DarksightKellar requested a review from adamgall June 14, 2024 19:59
Copy link
Contributor

@mudrila mudrila left a comment

Choose a reason for hiding this comment

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

Besides some @adamgall comments - looks good! Straight to prod! :shipit: 🚀

Comment on lines +230 to 232
} else {
transactionHash = createdEvent.transactionHash;
}
Copy link
Member

Choose a reason for hiding this comment

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

And then I guess I do have an outstanding question at the moment... what is going on here with finding a new use for this transactionHash property with a brand new createdEvent object?

Copy link
Member

@adamgall adamgall left a comment

Choose a reason for hiding this comment

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

Looks good, just a few comments and questions

@tomstuart123
Copy link

Awesome, this works so smoothly for 'Create Proposal'. Thanks @DarksightKellar

Last question, pre approval --> which other types of proposals should this work with? I tried it with SendAssets and it worked but not when I tried a change Safename proposal

@adamgall
Copy link
Member

adamgall commented Jun 17, 2024

Awesome, this works so smoothly for 'Create Proposal'. Thanks @DarksightKellar

Last question, pre approval --> which other types of proposals should this work with? I tried it with SendAssets and it worked but not when I tried a change Safename proposal

Awesome, this works so smoothly for 'Create Proposal'. Thanks @DarksightKellar

Last question, pre approval --> which other types of proposals should this work with? I tried it with SendAssets and it worked but not when I tried a change Safename proposal

This is a great question and makes me question whether useSubmitProposal is the appropriate place to trigger adding a temp proposal record...

where else in the codebase can it go to capture all proposal creation, or does that place not exist (yet)?

edit: @tomstuart123 i'm not asking you of course, just thinking out loud

@adamgall adamgall force-pushed the 1983-indicate-pending-proposal branch 2 times, most recently from b608532 to 7a0c587 Compare June 17, 2024 22:41
adamgall
adamgall previously approved these changes Jun 17, 2024
@adamgall adamgall self-requested a review June 17, 2024 22:54
@adamgall adamgall dismissed their stale review June 17, 2024 22:54

Need to do more testing

- Reduce as many whitespace changes as possible
- add some dev comments to the code in places that look funky
- add Pending Proposals to global state
- Don't use localstorage for pending data, just in-app memory
- Make code to remove "pending proposals" run automatically
@adamgall adamgall force-pushed the 1983-indicate-pending-proposal branch from c9f86f1 to 197a3d8 Compare June 17, 2024 22:56
@adamgall
Copy link
Member

ok @decentdao/engineering and @decentdao/product, this is ready for a full code re-review and UX re-test

@adamgall adamgall force-pushed the 1983-indicate-pending-proposal branch from 08c020a to f81788d Compare June 18, 2024 03:56
@tomstuart123
Copy link

Nice, this works for all of the below:

  • Create child safe
  • Create proposal
  • send assets
  • change name
  • change snapshot space

Approved. Great work

@adamgall adamgall merged commit 97b586f into develop Jun 18, 2024
10 checks passed
@adamgall adamgall deleted the 1983-indicate-pending-proposal branch June 18, 2024 16:54
Copy link

sentry-io bot commented Jun 24, 2024

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ Error: Proposal state is EXECUTED, but no event found //home View Issue

Did you find this useful? React with a 👍 or 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Indicate pending created proposal in proposal list
6 participants