Add working filters

This commit is contained in:
Adrian Wozniak 2020-04-07 20:32:21 +02:00
parent 272ff38d9a
commit 1508c971b3
7 changed files with 77 additions and 33 deletions

View File

@ -72,7 +72,6 @@ pub enum Msg {
ToggleAboutTooltip,
// project
ProjectTextFilterChanged(String),
ProjectAvatarFilterChanged(UserId, AvatarFilterActive),
ProjectToggleOnlyMy,
ProjectToggleRecentlyUpdated,

View File

@ -2,7 +2,7 @@ use seed::{prelude::*, *};
use jirs_data::IssueType;
use crate::model::{AddIssueModal, Model};
use crate::model::{AddIssueModal, ModalType, Model};
use crate::shared::styled_button::StyledButton;
use crate::shared::styled_field::StyledField;
use crate::shared::styled_form::StyledForm;
@ -10,10 +10,51 @@ use crate::shared::styled_icon::StyledIcon;
use crate::shared::styled_input::StyledInput;
use crate::shared::styled_modal::{StyledModal, Variant as ModalVariant};
use crate::shared::styled_select::StyledSelect;
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::styled_textarea::StyledTextarea;
use crate::shared::ToNode;
use crate::{FieldId, Msg};
pub fn update(msg: &Msg, model: &mut crate::model::Model, _orders: &mut impl Orders<Msg>) {
let modal = model.modals.iter_mut().find(|modal| match modal {
ModalType::AddIssue(..) => true,
_ => false,
});
let modal = match modal {
Some(ModalType::AddIssue(modal)) => modal,
_ => return,
};
match msg {
Msg::InputChanged(FieldId::DescriptionAddIssueModal, value) => {
modal.description = Some(value.clone());
}
Msg::InputChanged(FieldId::SummaryAddIssueModal, value) => {
modal.title = value.clone();
}
Msg::StyledSelectChanged(
FieldId::IssueTypeAddIssueModal,
StyledSelectChange::DropDownVisibility(b),
) => {
modal.type_select_opened = *b;
}
Msg::StyledSelectChanged(
FieldId::IssueTypeAddIssueModal,
StyledSelectChange::Text(text),
) => {
modal.type_select_filter = text.clone();
}
Msg::StyledSelectChanged(
FieldId::IssueTypeAddIssueModal,
StyledSelectChange::Changed(id),
) => {
modal.issue_type = (*id).into();
}
_ => (),
}
log!(modal);
}
pub fn view(_model: &Model, modal: &AddIssueModal) -> Node<Msg> {
let select_type = StyledSelect::build(FieldId::IssueTypeAddIssueModal)
.name("type")

View File

@ -106,6 +106,7 @@ pub fn update(msg: &Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>
_ => (),
}
add_issue::update(msg, model, orders);
}
pub fn view(model: &model::Model) -> Node<Msg> {

View File

@ -9,14 +9,14 @@ use crate::{IssueId, UserId, HOST_URL};
pub type ProjectId = i32;
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq, Hash)]
pub enum ModalType {
AddIssue(AddIssueModal),
EditIssue(IssueId, EditIssueModal),
DeleteIssueConfirm(IssueId),
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq, Hash)]
pub struct EditIssueModal {
pub id: i32,
pub top_select_opened: bool,
@ -25,7 +25,7 @@ pub struct EditIssueModal {
pub link_copied: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialOrd, PartialEq)]
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialOrd, PartialEq, Hash)]
pub struct AddIssueModal {
pub title: String,
#[serde(rename = "type")]

View File

@ -3,11 +3,12 @@ use seed::{prelude::*, *};
use jirs_data::*;
use crate::api::send_ws_msg;
use crate::model::{Model, Page};
use crate::model::{ModalType, Model, Page};
use crate::shared::styled_avatar::StyledAvatar;
use crate::shared::styled_button::StyledButton;
use crate::shared::styled_icon::{Icon, StyledIcon};
use crate::shared::styled_input::StyledInput;
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::{drag_ev, inner_layout, ToNode};
use crate::{FieldId, Msg};
@ -44,7 +45,23 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
Msg::ToggleAboutTooltip => {
model.project_page.about_tooltip_visible = !model.project_page.about_tooltip_visible;
}
Msg::ProjectTextFilterChanged(text) => {
Msg::StyledSelectChanged(
FieldId::IssueTypeEditModalTop,
StyledSelectChange::Text(text),
) => {
let modal = model
.modals
.iter_mut()
.filter_map(|modal| match modal {
ModalType::EditIssue(_, modal) => Some(modal),
_ => None,
})
.last();
if let Some(m) = modal {
m.top_select_filter = text;
}
}
Msg::InputChanged(FieldId::TextFilterBoard, text) => {
model.project_page.text_filter = text;
}
Msg::ProjectAvatarFilterChanged(user_id, active) => match active {
@ -182,9 +199,6 @@ fn project_board_filters(model: &Model) -> Node<Msg> {
let search_input = StyledInput::build(FieldId::TextFilterBoard)
.icon(Icon::Search)
.valid(true)
.on_change(input_ev(Ev::Change, |value| {
Msg::ProjectTextFilterChanged(value)
}))
.build()
.into_node();
@ -269,7 +283,13 @@ fn project_issue_list(model: &Model, status: jirs_data::IssueStatus) -> Node<Msg
let issues: Vec<Node<Msg>> = model
.issues
.iter()
.filter(|issue| status == issue.status)
.filter(|issue| {
status == issue.status
&& (model.project_page.text_filter.is_empty()
|| issue
.title
.contains(model.project_page.text_filter.as_str()))
})
.map(|issue| project_issue(model, issue))
.collect();
let label = status.to_label();

View File

@ -9,7 +9,6 @@ pub struct StyledInput {
id: FieldId,
icon: Option<Icon>,
valid: bool,
on_change: Option<EventHandler<Msg>>,
}
impl StyledInput {
@ -18,7 +17,6 @@ impl StyledInput {
id,
icon: None,
valid: None,
on_change: None,
}
}
}
@ -28,7 +26,6 @@ pub struct StyledInputBuilder {
id: FieldId,
icon: Option<Icon>,
valid: Option<bool>,
on_change: Option<EventHandler<Msg>>,
}
impl StyledInputBuilder {
@ -42,17 +39,11 @@ impl StyledInputBuilder {
self
}
pub fn on_change(mut self, on_change: EventHandler<Msg>) -> Self {
self.on_change = Some(on_change);
self
}
pub fn build(self) -> StyledInput {
StyledInput {
id: self.id,
icon: self.icon,
valid: self.valid.unwrap_or_default(),
on_change: self.on_change,
}
}
}
@ -64,12 +55,7 @@ impl ToNode for StyledInput {
}
pub fn render(values: StyledInput) -> Node<Msg> {
let StyledInput {
id,
icon,
valid,
on_change,
} = values;
let StyledInput { id, icon, valid } = values;
let mut wrapper_class_list = vec!["styledInput".to_string(), format!("{}", id)];
if !valid {
@ -88,10 +74,7 @@ pub fn render(values: StyledInput) -> Node<Msg> {
let mut handlers = vec![];
if let Some(handler) = on_change {
handlers.push(handler);
}
let input_handler = input_ev(Ev::KeyPress, move |value| Msg::InputChanged(id, value));
let input_handler = input_ev(Ev::KeyUp, move |value| Msg::InputChanged(id, value));
handlers.push(input_handler);
div![

View File

@ -14,7 +14,7 @@ pub mod sql;
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
#[cfg_attr(feature = "backend", sql_type = "IssueTypeType")]
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq)]
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum IssueType {
Task,
@ -71,7 +71,7 @@ impl std::fmt::Display for IssueType {
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
#[cfg_attr(feature = "backend", sql_type = "IssueStatusType")]
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq)]
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum IssueStatus {
Backlog,
@ -126,7 +126,7 @@ impl IssueStatus {
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
#[cfg_attr(feature = "backend", sql_type = "IssuePriorityType")]
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq)]
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq, Hash)]
pub enum IssuePriority {
Highest,
High,