Skip to main content

kanban_tui/app/
dialog_input.rs

1use crate::components::sprint_picker::{SprintFilter, SprintPicker};
2use crate::handlers::board_handlers::BoardDeleteCounts;
3use kanban_core::{InputState, SelectionState};
4use kanban_view::ListComponent;
5use uuid::Uuid;
6
7#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
8pub enum CreateCardFocus {
9    #[default]
10    Title,
11    Column,
12    Sprint,
13}
14
15#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
16pub enum CreateColumnFocus {
17    #[default]
18    Name,
19    Status,
20}
21
22pub struct DialogInputState {
23    pub import_files: Vec<String>,
24    pub import_selection: SelectionState,
25    pub priority_selection: SelectionState,
26    pub default_status_selection: SelectionState,
27    pub column_list: ListComponent,
28    pub sprint_assign_selection: SelectionState,
29    pub task_list_view_selection: SelectionState,
30    pub carry_over_sprint_selection: SelectionState,
31    pub carry_over_source_sprint_id: Option<Uuid>,
32    pub create_card_sprint_picker: SprintPicker,
33    pub create_card_focus: CreateCardFocus,
34    pub create_column_focus: CreateColumnFocus,
35    pub create_card_column_input: InputState,
36    create_card_column_editable: bool,
37    create_card_sprint_visible: bool,
38    /// Picker for the assign-to-existing-card dialogs (single and
39    /// bulk). Configured with SprintFilter::All so the user can pick
40    /// from completed/ended sprints as well, which the create-card
41    /// picker intentionally hides.
42    pub assign_sprint_picker: SprintPicker,
43    /// Entity counts for the currently-open delete-board confirmation,
44    /// snapshotted when the dialog opens (see `handle_delete_board_key`) so
45    /// the modal never re-scans the model per frame.
46    pub(crate) board_delete_counts: Option<BoardDeleteCounts>,
47}
48
49impl Default for DialogInputState {
50    fn default() -> Self {
51        Self {
52            import_files: Vec::new(),
53            import_selection: SelectionState::default(),
54            priority_selection: SelectionState::default(),
55            default_status_selection: SelectionState::default(),
56            column_list: ListComponent::new(false),
57            sprint_assign_selection: SelectionState::default(),
58            task_list_view_selection: SelectionState::default(),
59            carry_over_sprint_selection: SelectionState::default(),
60            carry_over_source_sprint_id: None,
61            create_card_sprint_picker: SprintPicker::with_filter(SprintFilter::ActiveOnly),
62            create_card_focus: CreateCardFocus::default(),
63            create_column_focus: CreateColumnFocus::default(),
64            create_card_column_input: InputState::default(),
65            create_card_column_editable: false,
66            create_card_sprint_visible: true,
67            assign_sprint_picker: SprintPicker::with_filter(SprintFilter::All),
68            board_delete_counts: None,
69        }
70    }
71}
72
73impl DialogInputState {
74    pub fn create_card_focus_is_title(&self) -> bool {
75        self.create_card_focus == CreateCardFocus::Title
76    }
77
78    pub fn create_card_focus_is_column(&self) -> bool {
79        self.create_card_focus == CreateCardFocus::Column
80    }
81
82    pub fn create_card_focus_is_sprint(&self) -> bool {
83        self.create_card_focus == CreateCardFocus::Sprint
84    }
85
86    pub fn create_card_column_is_editable(&self) -> bool {
87        self.create_card_column_editable
88    }
89
90    pub fn create_card_sprint_is_visible(&self) -> bool {
91        self.create_card_sprint_visible
92    }
93
94    pub fn advance_create_card_focus(&mut self) {
95        self.create_card_focus = match self.create_card_focus {
96            CreateCardFocus::Title if self.create_card_column_editable => CreateCardFocus::Column,
97            CreateCardFocus::Title | CreateCardFocus::Column if self.create_card_sprint_visible => {
98                CreateCardFocus::Sprint
99            }
100            _ => CreateCardFocus::Title,
101        };
102    }
103
104    pub fn create_card_focus_is_last_visible(&self) -> bool {
105        match self.create_card_focus {
106            CreateCardFocus::Sprint => true,
107            CreateCardFocus::Column => !self.create_card_sprint_visible,
108            CreateCardFocus::Title => {
109                !self.create_card_column_editable && !self.create_card_sprint_visible
110            }
111        }
112    }
113
114    pub fn reset_create_card_focus(&mut self) {
115        self.create_card_focus = CreateCardFocus::Title;
116    }
117
118    pub fn create_column_focus_is_name(&self) -> bool {
119        self.create_column_focus == CreateColumnFocus::Name
120    }
121
122    pub fn toggle_create_column_focus(&mut self) {
123        self.create_column_focus = match self.create_column_focus {
124            CreateColumnFocus::Name => CreateColumnFocus::Status,
125            CreateColumnFocus::Status => CreateColumnFocus::Name,
126        };
127    }
128
129    pub fn reset_create_column_focus(&mut self) {
130        self.create_column_focus = CreateColumnFocus::Name;
131    }
132
133    pub fn prime_create_card_column_field(&mut self, name: String, editable: bool) {
134        self.create_card_column_editable = editable;
135        self.create_card_column_input.set(name);
136    }
137
138    pub fn prime_create_card_sprint_field(&mut self, visible: bool) {
139        self.create_card_sprint_visible = visible;
140    }
141}