diff --git a/web/src/modals/epics_delete/view.rs b/web/src/modals/epics_delete/view.rs index 9e11ebd9..cba33db6 100644 --- a/web/src/modals/epics_delete/view.rs +++ b/web/src/modals/epics_delete/view.rs @@ -34,7 +34,7 @@ pub fn view(model: &model::Model, modal: &Model) -> Node { } fn warning(model: &model::Model, modal: &Model) -> Node { - let issues: Vec> = modal + let issues = modal .related_issues .iter() .flat_map(|id| model.issues_by_id.get(id)) @@ -48,12 +48,11 @@ fn warning(model: &model::Model, modal: &Model) -> Node { issue.title.as_str() ] ]] - }) - .collect(); + }); let close = StyledButton { text: Some("Close"), - on_click: Some(mouse_ev("click", move |ev| { + on_click: Some(mouse_ev(Ev::Click, move |ev| { ev.stop_propagation(); ev.prevent_default(); Msg::ModalDropped diff --git a/web/src/modals/epics_edit/model.rs b/web/src/modals/epics_edit/model.rs index 23823dbe..169f17e7 100644 --- a/web/src/modals/epics_edit/model.rs +++ b/web/src/modals/epics_edit/model.rs @@ -27,14 +27,14 @@ impl Model { }; let related_issues = model - .issues() + .issue_ids .iter() - .filter_map(|issue| { - if issue.epic_id == Some(epic_id) { - Some(issue.id) - } else { - None - } + .filter_map(|id| { + model + .issues_by_id + .get(id) + .filter(|issue| issue.epic_id == Some(epic_id)) + .map(|issue| issue.id) }) .collect(); Self { diff --git a/web/src/pages/epics_page/model.rs b/web/src/pages/epics_page/model.rs index d2174bd6..44f57ee6 100644 --- a/web/src/pages/epics_page/model.rs +++ b/web/src/pages/epics_page/model.rs @@ -16,15 +16,19 @@ impl EpicsPage { } pub fn build_issues_per_epic(model: &Model) -> HashMap> { - model.issues().iter().fold( - HashMap::with_capacity(model.issues().len()), - |mut h, issue| { - if let Some(epic_id) = issue.epic_id.as_ref() { - h.entry(*epic_id).or_default().push(issue.id); - } - h - }, - ) + model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)) + .fold( + HashMap::with_capacity(model.issue_ids.len()), + |mut h, issue| { + if let Some(epic_id) = issue.epic_id.as_ref() { + h.entry(*epic_id).or_default().push(issue.id); + } + h + }, + ) } pub fn issues(&self, epic_id: EpicId) -> Option<&Vec> { diff --git a/web/src/pages/issues_and_filters/model.rs b/web/src/pages/issues_and_filters/model.rs index dd8127a1..47cb86e9 100644 --- a/web/src/pages/issues_and_filters/model.rs +++ b/web/src/pages/issues_and_filters/model.rs @@ -20,8 +20,14 @@ pub struct IssuesAndFiltersPage { impl IssuesAndFiltersPage { pub fn new(model: &model::Model) -> Self { let jql = Jql::default(); - let visible_issues = Self::visible_issues(model.issues(), &jql); - let active_id = model.issues().first().as_ref().map(|issue| issue.id); + let visible_issues = Self::visible_issues( + model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)), + &jql, + ); + let active_id = model.issue_ids.first().copied(); Self { visible_issues, @@ -34,9 +40,11 @@ impl IssuesAndFiltersPage { } } - pub fn visible_issues(issues: &[Issue], jql: &Jql) -> Vec { + pub fn visible_issues<'l, IssueStream>(issues: IssueStream, jql: &Jql) -> Vec + where + IssueStream: std::iter::Iterator, + { issues - .iter() .filter(|issue| jql.is_visible(issue)) .map(|issue| issue.id) .collect() diff --git a/web/src/pages/issues_and_filters/update.rs b/web/src/pages/issues_and_filters/update.rs index ffde4116..7b4fa9cf 100644 --- a/web/src/pages/issues_and_filters/update.rs +++ b/web/src/pages/issues_and_filters/update.rs @@ -37,15 +37,24 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order .jql .remove_from(idx); let issues = super::IssuesAndFiltersPage::visible_issues( - model.issues(), + model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)), &crate::match_page!(model, IssuesAndFilters).jql, ); crate::match_page_mut!(model, IssuesAndFilters).visible_issues = issues; } Msg::ResourceChanged(ResourceKind::Issue, OperationKind::ListLoaded, _) => { let jql = &match_page!(model, IssuesAndFilters).jql; - let issues = super::IssuesAndFiltersPage::visible_issues(model.issues(), jql); - let first_id = model.issues().first().as_ref().map(|issue| issue.id); + let issues = super::IssuesAndFiltersPage::visible_issues( + model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)), + jql, + ); + let first_id = model.issue_ids.first().copied(); let page = crate::match_page_mut!(model, IssuesAndFilters); if page.active_id.is_none() { page.active_id = first_id; @@ -56,7 +65,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order crate::match_page_mut!(model, IssuesAndFilters).active_id = Some(id); } Msg::SetActiveIssue(None) => { - let first_id = model.issues().first().as_ref().map(|issue| issue.id); + let first_id = model.issue_ids.first().copied(); crate::match_page_mut!(model, IssuesAndFilters).active_id = first_id; } Msg::StyledSelectChanged( @@ -114,7 +123,10 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order page.current_jql_part.reset(); page.current_jql_part.opened = true; let issues = super::IssuesAndFiltersPage::visible_issues( - model.issues(), + model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)), &crate::match_page!(model, IssuesAndFilters).jql, ); crate::match_page_mut!(model, IssuesAndFilters).visible_issues = issues; diff --git a/web/src/pages/project_page/update.rs b/web/src/pages/project_page/update.rs index aaeabe8b..1407ef46 100644 --- a/web/src/pages/project_page/update.rs +++ b/web/src/pages/project_page/update.rs @@ -120,7 +120,10 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order crate::match_page!(model, Project), model.epics(), model.issue_statuses(), - model.issues(), + model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)), model.user(), ); crate::match_page_mut!(model, Project).visible_issues = visible_issues; diff --git a/web/src/pages/project_settings_page/view.rs b/web/src/pages/project_settings_page/view.rs index b206c5da..65ae7355 100644 --- a/web/src/pages/project_settings_page/view.rs +++ b/web/src/pages/project_settings_page/view.rs @@ -1,11 +1,9 @@ use std::collections::HashMap; -use seed::*; -use seed::prelude::*; - use jirs_data::{IssueStatus, ProjectCategory, TimeTracking}; +use seed::prelude::*; +use seed::*; -use crate::{FieldId, Msg, ProjectFieldId}; use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_checkbox::{ChildBuilder, StyledCheckbox, StyledCheckboxState}; use crate::components::styled_editor::render_styled_editor; @@ -19,6 +17,7 @@ use crate::components::styled_textarea::StyledTextarea; use crate::model::{self, Model, PageContent}; use crate::pages::project_settings_page::{events, ProjectSettingsPage}; use crate::shared::inner_layout; +use crate::{FieldId, Msg, ProjectFieldId}; static TIME_TRACKING_FIBONACCI: &str = include_str!("./time_tracking_fibonacci.txt"); static TIME_TRACKING_HOURLY: &str = include_str!("./time_tracking_hourly.txt"); @@ -206,10 +205,18 @@ fn category_select_option<'l>(pc: ProjectCategory) -> StyledSelectOption<'l> { fn columns_section(model: &Model, page: &ProjectSettingsPage) -> Node { let width = 100f64 / (model.issue_statuses.len() + 1) as f64; let column_style = format!("width: calc({width}% - 10px)", width = width); - let per_column_issue_count = model.issues().iter().fold(HashMap::new(), |mut h, issue| { - *h.entry(issue.issue_status_id).or_insert(0) += 1; - h - }); + let per_column_issue_count = model + .issue_ids + .iter() + .filter_map(|id| model.issues_by_id.get(id)) + .iter() + .fold( + HashMap::with_capacity(model.issue_statuses_by_id.len()), + |mut h, issue| { + *h.entry(issue.issue_status_id).or_insert(0) += 1; + h + }, + ); let columns: Vec> = model .issue_statuses .iter() diff --git a/web/src/pages/reports_page/view.rs b/web/src/pages/reports_page/view.rs index d054f34a..6314963f 100644 --- a/web/src/pages/reports_page/view.rs +++ b/web/src/pages/reports_page/view.rs @@ -240,8 +240,9 @@ fn issue_list(page: &ReportsPage, project_name: &str, this_month_updated: &[&Iss fn this_month_updated<'a>(model: &'a Model, page: &ReportsPage) -> Vec<&'a Issue> { model - .issues() + .issue_ids .iter() + .filter_map(|id| model.issues_by_id.get(id)) .filter(|issue| { issue.updated_at.date() >= page.first_day && issue.updated_at.date() <= page.last_day }) diff --git a/web/src/ws/issue.rs b/web/src/ws/issue.rs index 660d2cd2..d8e04245 100644 --- a/web/src/ws/issue.rs +++ b/web/src/ws/issue.rs @@ -30,8 +30,9 @@ pub fn change_position(below_id: EpicId, model: &mut Model) { } let (issue_status_id, epic_id) = model - .issues() + .issue_ids .iter() + .filter_map(|id| model.issues_by_id.get(id)) .find_map(|issue| { if issue.id == dragged_id { Some((issue.issue_status_id, issue.epic_id))