Add working filters
This commit is contained in:
parent
272ff38d9a
commit
1508c971b3
@ -72,7 +72,6 @@ pub enum Msg {
|
|||||||
ToggleAboutTooltip,
|
ToggleAboutTooltip,
|
||||||
|
|
||||||
// project
|
// project
|
||||||
ProjectTextFilterChanged(String),
|
|
||||||
ProjectAvatarFilterChanged(UserId, AvatarFilterActive),
|
ProjectAvatarFilterChanged(UserId, AvatarFilterActive),
|
||||||
ProjectToggleOnlyMy,
|
ProjectToggleOnlyMy,
|
||||||
ProjectToggleRecentlyUpdated,
|
ProjectToggleRecentlyUpdated,
|
||||||
|
@ -2,7 +2,7 @@ use seed::{prelude::*, *};
|
|||||||
|
|
||||||
use jirs_data::IssueType;
|
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_button::StyledButton;
|
||||||
use crate::shared::styled_field::StyledField;
|
use crate::shared::styled_field::StyledField;
|
||||||
use crate::shared::styled_form::StyledForm;
|
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_input::StyledInput;
|
||||||
use crate::shared::styled_modal::{StyledModal, Variant as ModalVariant};
|
use crate::shared::styled_modal::{StyledModal, Variant as ModalVariant};
|
||||||
use crate::shared::styled_select::StyledSelect;
|
use crate::shared::styled_select::StyledSelect;
|
||||||
|
use crate::shared::styled_select::StyledSelectChange;
|
||||||
use crate::shared::styled_textarea::StyledTextarea;
|
use crate::shared::styled_textarea::StyledTextarea;
|
||||||
use crate::shared::ToNode;
|
use crate::shared::ToNode;
|
||||||
use crate::{FieldId, Msg};
|
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> {
|
pub fn view(_model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
||||||
let select_type = StyledSelect::build(FieldId::IssueTypeAddIssueModal)
|
let select_type = StyledSelect::build(FieldId::IssueTypeAddIssueModal)
|
||||||
.name("type")
|
.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> {
|
pub fn view(model: &model::Model) -> Node<Msg> {
|
||||||
|
@ -9,14 +9,14 @@ use crate::{IssueId, UserId, HOST_URL};
|
|||||||
|
|
||||||
pub type ProjectId = i32;
|
pub type ProjectId = i32;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq, Hash)]
|
||||||
pub enum ModalType {
|
pub enum ModalType {
|
||||||
AddIssue(AddIssueModal),
|
AddIssue(AddIssueModal),
|
||||||
EditIssue(IssueId, EditIssueModal),
|
EditIssue(IssueId, EditIssueModal),
|
||||||
DeleteIssueConfirm(IssueId),
|
DeleteIssueConfirm(IssueId),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, PartialEq, Hash)]
|
||||||
pub struct EditIssueModal {
|
pub struct EditIssueModal {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub top_select_opened: bool,
|
pub top_select_opened: bool,
|
||||||
@ -25,7 +25,7 @@ pub struct EditIssueModal {
|
|||||||
pub link_copied: bool,
|
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 struct AddIssueModal {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -3,11 +3,12 @@ use seed::{prelude::*, *};
|
|||||||
use jirs_data::*;
|
use jirs_data::*;
|
||||||
|
|
||||||
use crate::api::send_ws_msg;
|
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_avatar::StyledAvatar;
|
||||||
use crate::shared::styled_button::StyledButton;
|
use crate::shared::styled_button::StyledButton;
|
||||||
use crate::shared::styled_icon::{Icon, StyledIcon};
|
use crate::shared::styled_icon::{Icon, StyledIcon};
|
||||||
use crate::shared::styled_input::StyledInput;
|
use crate::shared::styled_input::StyledInput;
|
||||||
|
use crate::shared::styled_select::StyledSelectChange;
|
||||||
use crate::shared::{drag_ev, inner_layout, ToNode};
|
use crate::shared::{drag_ev, inner_layout, ToNode};
|
||||||
use crate::{FieldId, Msg};
|
use crate::{FieldId, Msg};
|
||||||
|
|
||||||
@ -44,7 +45,23 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
|||||||
Msg::ToggleAboutTooltip => {
|
Msg::ToggleAboutTooltip => {
|
||||||
model.project_page.about_tooltip_visible = !model.project_page.about_tooltip_visible;
|
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;
|
model.project_page.text_filter = text;
|
||||||
}
|
}
|
||||||
Msg::ProjectAvatarFilterChanged(user_id, active) => match active {
|
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)
|
let search_input = StyledInput::build(FieldId::TextFilterBoard)
|
||||||
.icon(Icon::Search)
|
.icon(Icon::Search)
|
||||||
.valid(true)
|
.valid(true)
|
||||||
.on_change(input_ev(Ev::Change, |value| {
|
|
||||||
Msg::ProjectTextFilterChanged(value)
|
|
||||||
}))
|
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
|
|
||||||
@ -269,7 +283,13 @@ fn project_issue_list(model: &Model, status: jirs_data::IssueStatus) -> Node<Msg
|
|||||||
let issues: Vec<Node<Msg>> = model
|
let issues: Vec<Node<Msg>> = model
|
||||||
.issues
|
.issues
|
||||||
.iter()
|
.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))
|
.map(|issue| project_issue(model, issue))
|
||||||
.collect();
|
.collect();
|
||||||
let label = status.to_label();
|
let label = status.to_label();
|
||||||
|
@ -9,7 +9,6 @@ pub struct StyledInput {
|
|||||||
id: FieldId,
|
id: FieldId,
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
valid: bool,
|
valid: bool,
|
||||||
on_change: Option<EventHandler<Msg>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StyledInput {
|
impl StyledInput {
|
||||||
@ -18,7 +17,6 @@ impl StyledInput {
|
|||||||
id,
|
id,
|
||||||
icon: None,
|
icon: None,
|
||||||
valid: None,
|
valid: None,
|
||||||
on_change: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,7 +26,6 @@ pub struct StyledInputBuilder {
|
|||||||
id: FieldId,
|
id: FieldId,
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
valid: Option<bool>,
|
valid: Option<bool>,
|
||||||
on_change: Option<EventHandler<Msg>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StyledInputBuilder {
|
impl StyledInputBuilder {
|
||||||
@ -42,17 +39,11 @@ impl StyledInputBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_change(mut self, on_change: EventHandler<Msg>) -> Self {
|
|
||||||
self.on_change = Some(on_change);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(self) -> StyledInput {
|
pub fn build(self) -> StyledInput {
|
||||||
StyledInput {
|
StyledInput {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
icon: self.icon,
|
icon: self.icon,
|
||||||
valid: self.valid.unwrap_or_default(),
|
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> {
|
pub fn render(values: StyledInput) -> Node<Msg> {
|
||||||
let StyledInput {
|
let StyledInput { id, icon, valid } = values;
|
||||||
id,
|
|
||||||
icon,
|
|
||||||
valid,
|
|
||||||
on_change,
|
|
||||||
} = values;
|
|
||||||
|
|
||||||
let mut wrapper_class_list = vec!["styledInput".to_string(), format!("{}", id)];
|
let mut wrapper_class_list = vec!["styledInput".to_string(), format!("{}", id)];
|
||||||
if !valid {
|
if !valid {
|
||||||
@ -88,10 +74,7 @@ pub fn render(values: StyledInput) -> Node<Msg> {
|
|||||||
|
|
||||||
let mut handlers = vec![];
|
let mut handlers = vec![];
|
||||||
|
|
||||||
if let Some(handler) = on_change {
|
let input_handler = input_ev(Ev::KeyUp, move |value| Msg::InputChanged(id, value));
|
||||||
handlers.push(handler);
|
|
||||||
}
|
|
||||||
let input_handler = input_ev(Ev::KeyPress, move |value| Msg::InputChanged(id, value));
|
|
||||||
handlers.push(input_handler);
|
handlers.push(input_handler);
|
||||||
|
|
||||||
div![
|
div![
|
||||||
|
@ -14,7 +14,7 @@ pub mod sql;
|
|||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
|
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
|
||||||
#[cfg_attr(feature = "backend", sql_type = "IssueTypeType")]
|
#[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")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum IssueType {
|
pub enum IssueType {
|
||||||
Task,
|
Task,
|
||||||
@ -71,7 +71,7 @@ impl std::fmt::Display for IssueType {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
|
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
|
||||||
#[cfg_attr(feature = "backend", sql_type = "IssueStatusType")]
|
#[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")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum IssueStatus {
|
pub enum IssueStatus {
|
||||||
Backlog,
|
Backlog,
|
||||||
@ -126,7 +126,7 @@ impl IssueStatus {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
|
#[cfg_attr(feature = "backend", derive(FromSqlRow, AsExpression))]
|
||||||
#[cfg_attr(feature = "backend", sql_type = "IssuePriorityType")]
|
#[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 {
|
pub enum IssuePriority {
|
||||||
Highest,
|
Highest,
|
||||||
High,
|
High,
|
||||||
|
Loading…
Reference in New Issue
Block a user