1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::{ActionButton, Button, Modal, ModalMessage};
use css_in_rust_next::Style;
use yew::{html, Callback, Component, Context, Html, Properties};
use yew_feather::{plus::Plus, trash_2::Trash2};

#[derive(PartialEq, Properties)]
pub struct EditBoolProperties {
  pub title: String,
  pub field_name: String,
  pub event: Callback<EditBoolMessage>,
  pub value: Option<bool>,
  pub required: bool,
}

pub enum EditBoolMessage {
  Submit(Option<bool>),
  Cancel,
}

pub enum InternalMessage {
  Toggle,
  Modal(ModalMessage),
  AddValue,
  RemoveValue,
}

pub struct EditBool {
  style: Style,
  value: Option<bool>,
}

impl Component for EditBool {
  type Message = InternalMessage;
  type Properties = EditBoolProperties;

  fn create(ctx: &Context<Self>) -> Self {
    let style = Style::create(
      "Component",
      concat!(
        include_str!("edit_style.css"),
        include_str!("edit_bool.css")
      ),
    )
    .unwrap();

    let value = ctx.props().value;
    EditBool { style, value }
  }

  fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
    match msg {
      InternalMessage::Toggle => {
        if let Some(value) = &mut self.value {
          *value = !*value;
        } else {
          self.value = Some(true);
        }
        true
      }
      InternalMessage::Modal(message) => {
        let event = match message {
          ModalMessage::Submit | ModalMessage::Update => Some(EditBoolMessage::Submit(self.value)),
          ModalMessage::Cancel => Some(EditBoolMessage::Cancel),
          ModalMessage::Delete => None,
        };

        if let Some(event) = event {
          ctx.props().event.emit(event)
        }
        false
      }
      InternalMessage::AddValue => {
        self.value = Some(true);
        true
      }
      InternalMessage::RemoveValue => {
        self.value = None;
        true
      }
    }
  }

  fn view(&self, ctx: &Context<Self>) -> Html {
    let input_bool_callback = ctx.link().callback(|_| InternalMessage::Toggle);

    let action_buttons = vec![ActionButton::Submit(true)];

    let inner_modal: Html = if ctx.props().required {
      html! (<input type="checkbox" checked={self.value.unwrap_or_default()} onchange={input_bool_callback} />)
    } else if let Some(value) = self.value {
      html!(
        <>
        <div>
          <input type="checkbox" checked={value} onchange={input_bool_callback} />
        </div>
        <Button
          label="Remove value"
          icon={html!(<Trash2 />)}
          onclick={ctx.link().callback(|_|InternalMessage::RemoveValue)}
          />
        </>
      )
    } else {
      html!(
        <Button
          label="Add value"
          icon={html!(<Plus />)}
          onclick={ctx.link().callback(|_|InternalMessage::AddValue)}
          />
      )
    };

    html!(
      <Modal
        event={ctx.link().callback(InternalMessage::Modal)}
        height="50vh" width="19vw"
        modal_title={ctx.props().title.clone()}
        actions={action_buttons}>
        <div class={self.style.clone()}>
          <div class="editInput">
            {inner_modal}
          </div>
        </div>
      </Modal>
    )
  }
}