Skip to content

Commit

Permalink
feat: create action transfer as community (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
b-avb authored Sep 25, 2024
1 parent dd01982 commit 1e8c865
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 51 deletions.
32 changes: 24 additions & 8 deletions src/components/molecules/action_request_list.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use dioxus::prelude::*;
use dioxus_std::{i18n::use_i18, translate};
use crate::{
components::atoms::ActionRequest,
hooks::use_initiative::{
ActionItem, AddMembersAction, ConvictionVote, KusamaTreasuryAction, VoteType,
VotingOpenGovAction,
ActionItem, AddMembersAction, CommunityTransferAction, ConvictionVote,
KusamaTreasuryAction, VoteType, VotingOpenGovAction,
},
};
use dioxus::prelude::*;
use dioxus_std::{i18n::use_i18, translate};
#[derive(PartialEq, Props, Clone)]
pub struct ActionRequestListProps {
actions: Vec<ActionItem>,
Expand All @@ -15,7 +15,7 @@ pub fn ActionRequestList(props: ActionRequestListProps) -> Element {
let i18 = use_i18();
let render_add_members = |action: &AddMembersAction| {
rsx!(
ActionRequest { name: "Add Members", details: action.members.len().to_string() }
ActionRequest { name: translate!(i18, "initiative.steps.actions.add_members.title"), details: action.members.len().to_string() }
ul { class: "requests",
for member in action.members.iter() {
li {
Expand All @@ -27,7 +27,7 @@ pub fn ActionRequestList(props: ActionRequestListProps) -> Element {
};
let render_kusama_treasury = |action: &KusamaTreasuryAction| {
rsx!(
ActionRequest { name: "Kusama Treasury Request" }
ActionRequest { name: translate!(i18, "initiative.steps.actions.kusama_treasury.title") }
ul { class: "requests",
for (index , period) in action.periods.iter().enumerate() {
li {
Expand All @@ -42,7 +42,7 @@ pub fn ActionRequestList(props: ActionRequestListProps) -> Element {
};
let render_voting_open_gov = |action: &VotingOpenGovAction| {
rsx!(
ActionRequest { name: "Voting Open Gov", details: action.proposals.len().to_string() }
ActionRequest { name: translate!(i18, "initiative.steps.actions.voting_open_gov.title"), details: action.proposals.len().to_string() }
ul { class: "requests",
for proposal in action.proposals.iter() {
li {
Expand Down Expand Up @@ -70,13 +70,29 @@ pub fn ActionRequestList(props: ActionRequestListProps) -> Element {
}
)
};
let render_community_transfer = |action: &CommunityTransferAction| {
rsx!(
ActionRequest { name: translate!(i18, "initiative.steps.actions.community_transfer.title") }
ul { class: "requests",
for transfer in action.transfers.iter() {
li {
ActionRequest {
name: format!("{}", transfer.account),
details: format!("{} KSM", transfer.value as f64 / 1_000_000_000_000.0)
}
}
}
}
)
};
rsx!(
for request in props.actions.iter() {
div { class: "requests",
match request {
ActionItem::AddMembers(action) => render_add_members(& action),
ActionItem::KusamaTreasury(action) => render_kusama_treasury(& action),
ActionItem::VotingOpenGov(action) => render_voting_open_gov(& action) }
ActionItem::VotingOpenGov(action) => render_voting_open_gov(& action) ,
ActionItem::CommunityTransfer(action) => render_community_transfer(& action) }
}
}
)
Expand Down
2 changes: 2 additions & 0 deletions src/components/molecules/actions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub mod members;
pub mod treasury;
pub mod voting;
pub mod transfer;
pub use transfer::TransferAction;
pub use members::MembersAction;
pub use treasury::TreasuryAction;
pub use voting::VotingAction;
113 changes: 113 additions & 0 deletions src/components/molecules/actions/transfer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use crate::{
components::atoms::{
dropdown::ElementSize, icon_button::Variant, AddPlus, Icon, IconButton,
Input, MinusCircle,
},
hooks::use_initiative::{use_initiative, ActionItem, CommunityTransferAction, TransferItem},
};
use dioxus::prelude::*;
use dioxus_std::{i18n::use_i18, translate};
#[derive(PartialEq, Props, Clone)]
pub struct VotingProps {
index: usize,
meta: CommunityTransferAction,
}
const KUSAMA_PRECISION_DECIMALS: u64 = 1_000_000_000_000;
pub fn TransferAction(props: VotingProps) -> Element {
let i18 = use_i18();
let mut initiative = use_initiative();
rsx!(
ul { class: "form__inputs form__inputs--combo",
{
props.meta.transfers.iter().enumerate().map(|(index_meta, transfer)| {
rsx!(
li {
div {
style: "
width: 100%;
display: flex;
gap: 4px;
",
Input {
message: transfer.account.clone(),
size: ElementSize::Small,
placeholder: translate!(i18, "initiative.steps.actions.community_transfer.dest.placeholder"),
error: None,
on_input: move |event: Event<FormData>| {
if let ActionItem::CommunityTransfer(ref mut meta) = initiative.get_action(props.index) {
meta.transfers[index_meta].account = event.value() ;
initiative.update_action(props.index, ActionItem::CommunityTransfer(meta.clone()));
}
},
on_keypress: move |_| {},
on_click: move |_| {},
}
Input {
message: (transfer.value / KUSAMA_PRECISION_DECIMALS).to_string(),
size: ElementSize::Small,
placeholder: translate!(i18, "initiative.steps.actions.community_transfer.amount.placeholder"),
error: None,
right_text: {
rsx!(
span { class: "input--right__text",
"KSM"
}
)
},
on_input: move |event: Event<FormData>| {
if let ActionItem::CommunityTransfer(ref mut meta) = initiative.get_action(props.index) {
// Scale amount
let amount = event.value().parse::<f64>().unwrap_or(0.0);
let scaled_amount = amount * KUSAMA_PRECISION_DECIMALS as f64;
meta.transfers[index_meta].value = scaled_amount as u64 ;
initiative.update_action(props.index, ActionItem::CommunityTransfer(meta.clone()));
}
},
on_keypress: move |_| {},
on_click: move |_| {},
}
}
IconButton {
variant: Variant::Round,
size: ElementSize::Small,
class: "button--avatar",
body: rsx!(
Icon {
icon: MinusCircle,
height: 24,
width: 24,
fill: "var(--state-primary-active)"
}
),
on_click: move |_| {
if let ActionItem::CommunityTransfer(ref mut meta) = initiative.get_action(props.index) {
meta.transfers.remove(index_meta);
initiative.update_action(props.index, ActionItem::CommunityTransfer(meta.clone()));
}
}
}
}
)
})
},
IconButton {
variant: Variant::Round,
size: ElementSize::Small,
class: "button--avatar",
body: rsx!(
Icon { icon : AddPlus, height : 24, width : 24, fill :
"var(--state-primary-active)" }
),
on_click: move |_| {
if let ActionItem::CommunityTransfer(ref mut meta) = initiative
.get_action(props.index)
{
meta.add_transfer(TransferItem::default());
initiative
.update_action(props.index, ActionItem::CommunityTransfer(meta.clone()));
}
}
}
}
)
}
10 changes: 9 additions & 1 deletion src/components/molecules/initiative/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
dropdown::ElementSize, icon_button::Variant, AddPlus, Dropdown, Icon,
IconButton, SubstractLine,
},
molecules::{MembersAction, TreasuryAction, VotingAction},
molecules::{MembersAction, TransferAction, TreasuryAction, VotingAction},
},
hooks::use_initiative::{
use_initiative, ActionItem, AddMembersAction, MediumOptions, MemberItem,
Expand Down Expand Up @@ -87,6 +87,14 @@ pub fn InitiativeActions() -> Element {
}
)
}
ActionItem::CommunityTransfer(meta) => {
rsx!(
TransferAction {
index: index,
meta: meta.clone()
}
)
}
}
}
)
Expand Down
74 changes: 51 additions & 23 deletions src/hooks/use_initiative.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::components::atoms::dropdown::DropdownItem;
use dioxus::prelude::*;
use serde::{Deserialize, Serialize};
use crate::components::atoms::dropdown::DropdownItem;
#[derive(Clone, Default, Deserialize, Serialize, Debug)]
pub struct InfoForm {
pub name: String,
Expand Down Expand Up @@ -154,43 +154,70 @@ impl VotingOpenGovAction {
}
}
}
#[derive(PartialEq, Clone, Default, Deserialize, Serialize, Debug)]
pub struct TransferItem {
pub account: String,
pub value: u64
}
pub type Transfers = Vec<TransferItem>;
#[derive(PartialEq, Clone, Debug, Deserialize, Serialize, Default)]
pub struct CommunityTransferAction {
pub transfers: Transfers,
}
impl CommunityTransferAction {
pub fn add_transfer(&mut self, transfer: TransferItem) {
self.transfers.push(transfer);
}
pub fn update_transfer(&mut self, index: usize, transfer: TransferItem) {
if index < self.transfers.len() {
self.transfers[index] = transfer;
} else {
println!("Index out of bounds.");
}
}
pub fn remove_transfer(&mut self, index: usize) {
if index < self.transfers.len() {
self.transfers.remove(index);
} else {
println!("Index out of bounds.");
}
}
}
#[derive(PartialEq, Clone, Deserialize, Serialize, Debug)]
#[serde(tag = "action_type")]
pub enum ActionItem {
AddMembers(AddMembersAction),
KusamaTreasury(KusamaTreasuryAction),
VotingOpenGov(VotingOpenGovAction),
CommunityTransfer(CommunityTransferAction),
}
impl ActionItem {
pub fn option(&self) -> DropdownItem {
match self {
ActionItem::AddMembers(_) => {
DropdownItem {
key: "AddMembers".to_string(),
value: "Add Members".to_string(),
}
}
ActionItem::KusamaTreasury(_) => {
DropdownItem {
key: "KusamaTreasury".to_string(),
value: "Kusama - Request treasury spend".to_string(),
}
}
ActionItem::VotingOpenGov(_) => {
DropdownItem {
key: "VotingOpenGov".to_string(),
value: "Kusama - Vote in OpenGov".to_string(),
}
}
ActionItem::AddMembers(_) => DropdownItem {
key: "AddMembers".to_string(),
value: "Add Members".to_string(),
},
ActionItem::KusamaTreasury(_) => DropdownItem {
key: "KusamaTreasury".to_string(),
value: "Kusama - Request treasury spend".to_string(),
},
ActionItem::VotingOpenGov(_) => DropdownItem {
key: "VotingOpenGov".to_string(),
value: "Kusama - Vote in OpenGov".to_string(),
},
ActionItem::CommunityTransfer(_) => DropdownItem {
key: "CommunityTransfer".to_string(),
value: "Community Transfer".to_string(),
},
}
}
fn to_option(option: String) -> ActionItem {
match &*option {
"AddMembers" => ActionItem::AddMembers(AddMembersAction::default()),
"KusamaTreasury" => {
ActionItem::KusamaTreasury(KusamaTreasuryAction::default())
}
"KusamaTreasury" => ActionItem::KusamaTreasury(KusamaTreasuryAction::default()),
"VotingOpenGov" => ActionItem::VotingOpenGov(VotingOpenGovAction::default()),
"CommunityTransfer" => ActionItem::CommunityTransfer(CommunityTransferAction::default()),
_ => todo!(),
}
}
Expand All @@ -199,6 +226,7 @@ impl ActionItem {
ActionItem::AddMembers(AddMembersAction::default()).option(),
ActionItem::KusamaTreasury(KusamaTreasuryAction::default()).option(),
ActionItem::VotingOpenGov(VotingOpenGovAction::default()).option(),
ActionItem::CommunityTransfer(CommunityTransferAction::default()).option(),
]
}
}
Expand Down Expand Up @@ -262,7 +290,7 @@ pub fn use_initiative() -> UseInitiativeState {
let actions = consume_context::<Signal<ActionsForm>>();
let settings = consume_context::<Signal<SettingsForm>>();
let confirmation = consume_context::<Signal<ConfirmationForm>>();
let mut is_loading = use_signal(|| false);
let is_loading = use_signal(|| false);
use_hook(|| UseInitiativeState {
inner: UseInitiativeInner {
info,
Expand Down
15 changes: 15 additions & 0 deletions src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,30 @@
},
"actions": {
"label": "Actions",
"add_members": {
"title": "Add Members"
},
"kusama_treasury": {
"title": "Kusama Treasury Request",
"disclaimer": {
"period_1": "The delivery of resources from the treasury will be made instantly once the proposal is approved.",
"period_n": "\nImportant: The resources for the other periods will be delivered on the dates established for each one."
},
"error": "Must be greater than 0",
"placeholder": "Delivery date"
},
"community_transfer": {
"title": "Community Transfer",
"dest": {
"placeholder": "Recipient"
},
"amount": {
"error": "Must be greater than 0",
"placeholder": "Amount"
}
},
"voting_open_gov": {
"title": "Voting Open Gov",
"poll_index": "Poll Index",
"standard": {
"title": "Standard",
Expand Down
Loading

0 comments on commit 1e8c865

Please sign in to comment.