Add working filters
This commit is contained in:
parent
272ff38d9a
commit
1508c971b3
@ -72,7 +72,6 @@ pub enum Msg {
|
||||
ToggleAboutTooltip,
|
||||
|
||||
// project
|
||||
ProjectTextFilterChanged(String),
|
||||
ProjectAvatarFilterChanged(UserId, AvatarFilterActive),
|
||||
ProjectToggleOnlyMy,
|
||||
ProjectToggleRecentlyUpdated,
|
||||
|
@ -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")
|
||||
|
@ -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> {
|
||||
|
@ -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")]
|
||||
|
@ -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();
|
||||
|
@ -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![
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user