Delete issue status full logic
This commit is contained in:
parent
b2cbb251d1
commit
4d07639e90
3
jirs-client/js/css/deleteIssueStatus.css
Normal file
3
jirs-client/js/css/deleteIssueStatus.css
Normal file
@ -0,0 +1,3 @@
|
||||
.deleteIssueStatus {
|
||||
min-width: 800px;
|
||||
}
|
@ -55,3 +55,21 @@
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#projectSettings > .formContainer .styledForm > .formElement > .styledField > .columnsSection > .columns > .columnPreview > .columnName > .removeColumn {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
#projectSettings > .formContainer .styledForm > .formElement > .styledField > .columnsSection > .columns > .columnPreview:hover > .columnName > .removeColumn,
|
||||
#projectSettings > .formContainer .styledForm > .formElement > .styledField > .columnsSection > .columns > .columnPreview:focus > .columnName > .removeColumn,
|
||||
#projectSettings > .formContainer .styledForm > .formElement > .styledField > .columnsSection > .columns > .columnPreview:active > .columnName > .removeColumn {
|
||||
|
||||
}
|
||||
|
||||
#projectSettings > .formContainer .styledForm > .formElement > .styledField > .columnsSection > .columns > .columnPreview > .columnName > .issueCount {
|
||||
text-transform: none;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@
|
||||
--font-black: "CircularStdBlack";
|
||||
}
|
||||
|
||||
:root {
|
||||
:root { /* user without avatar */
|
||||
--avatar-color-1: rgb(218, 118, 87);
|
||||
--avatar-color-2: rgb(106, 218, 87);
|
||||
--avatar-color-3: rgb(87, 132, 218);
|
||||
|
@ -240,6 +240,9 @@ pub enum Msg {
|
||||
AddIssue,
|
||||
DeleteIssue(IssueId),
|
||||
|
||||
// issue statuses
|
||||
DeleteIssueStatus(IssueStatusId),
|
||||
|
||||
// comments
|
||||
SaveComment,
|
||||
DeleteComment(CommentId),
|
||||
|
43
jirs-client/src/modal/delete_issue_status.rs
Normal file
43
jirs-client/src/modal/delete_issue_status.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use seed::prelude::*;
|
||||
|
||||
use jirs_data::{IssueStatusId, WsMsg};
|
||||
|
||||
use crate::api::send_ws_msg;
|
||||
use crate::model::{DeleteIssueStatusModal, ModalType, Model};
|
||||
use crate::shared::styled_confirm_modal::StyledConfirmModal;
|
||||
use crate::shared::ToNode;
|
||||
use crate::{model, Msg};
|
||||
|
||||
pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
let _modal: &mut Box<DeleteIssueStatusModal> =
|
||||
match model.modals.iter_mut().find_map(|modal| match modal {
|
||||
ModalType::DeleteIssueStatusModal(modal) => Some(modal),
|
||||
_ => None,
|
||||
}) {
|
||||
Some(m) => m,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
match msg {
|
||||
Msg::DeleteIssueStatus(issue_status_id) => {
|
||||
send_ws_msg(WsMsg::IssueStatusDelete(*issue_status_id));
|
||||
}
|
||||
Msg::WsMsg(WsMsg::IssueStatusDelete(_)) => {
|
||||
orders.skip().perform_cmd(Msg::ModalDropped);
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn view(_model: &model::Model, issue_status_id: IssueStatusId) -> Node<Msg> {
|
||||
StyledConfirmModal::build()
|
||||
.title("Delete column")
|
||||
.cancel_text("No")
|
||||
.confirm_text("Yes")
|
||||
.on_confirm(mouse_ev(Ev::Click, move |_| {
|
||||
Msg::DeleteIssueStatus(issue_status_id)
|
||||
}))
|
||||
.message("Are you sure you want to delete column?")
|
||||
.build()
|
||||
.into_node()
|
||||
}
|
@ -292,10 +292,10 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
|
||||
pub fn view(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
|
||||
div![
|
||||
attrs![At::Class => "issueDetails"],
|
||||
class!["issueDetails"],
|
||||
top_modal_row(model, modal),
|
||||
div![
|
||||
attrs![At::Class => "content"],
|
||||
class!["content"],
|
||||
left_modal_column(model, modal),
|
||||
right_modal_column(model, modal),
|
||||
],
|
||||
|
@ -11,6 +11,7 @@ use crate::{model, FieldChange, FieldId, Msg};
|
||||
|
||||
mod add_issue;
|
||||
mod confirm_delete_issue;
|
||||
mod delete_issue_status;
|
||||
mod issue_details;
|
||||
pub mod time_tracking;
|
||||
|
||||
@ -57,6 +58,7 @@ pub fn update(msg: &Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>
|
||||
}
|
||||
add_issue::update(msg, model, orders);
|
||||
issue_details::update(msg, model, orders);
|
||||
delete_issue_status::update(msg, model, orders);
|
||||
}
|
||||
|
||||
pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
@ -90,6 +92,9 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
.into_node()
|
||||
}
|
||||
ModalType::TimeTracking(issue_id) => time_tracking::view(model, *issue_id),
|
||||
ModalType::DeleteIssueStatusModal(delete_issue_modal) => {
|
||||
delete_issue_status::view(model, delete_issue_modal.delete_id)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
section![id!["modals"], modals]
|
||||
|
@ -21,6 +21,7 @@ pub enum ModalType {
|
||||
DeleteIssueConfirm(IssueId),
|
||||
DeleteCommentConfirm(CommentId),
|
||||
TimeTracking(IssueId),
|
||||
DeleteIssueStatusModal(Box<DeleteIssueStatusModal>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
@ -30,9 +31,24 @@ pub struct CommentForm {
|
||||
pub creating: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub struct DeleteIssueStatusModal {
|
||||
pub delete_id: IssueStatusId,
|
||||
pub receiver_id: Option<IssueStatusId>,
|
||||
}
|
||||
|
||||
impl DeleteIssueStatusModal {
|
||||
pub fn new(delete_id: IssueStatusId) -> Self {
|
||||
Self {
|
||||
delete_id,
|
||||
receiver_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub struct EditIssueModal {
|
||||
pub id: i32,
|
||||
pub id: IssueId,
|
||||
pub link_copied: bool,
|
||||
pub payload: UpdateIssuePayload,
|
||||
pub top_type_state: StyledSelectState,
|
||||
|
@ -1,11 +1,14 @@
|
||||
use seed::{prelude::*, *};
|
||||
use wasm_bindgen::__rt::std::collections::HashMap;
|
||||
|
||||
use jirs_data::{
|
||||
IssueStatus, IssueStatusId, ProjectCategory, TimeTracking, ToVec, UpdateProjectPayload, WsMsg,
|
||||
};
|
||||
|
||||
use crate::api::send_ws_msg;
|
||||
use crate::model::{Model, Page, PageContent, ProjectSettingsPage};
|
||||
use crate::model::{
|
||||
DeleteIssueStatusModal, ModalType, Model, Page, PageContent, ProjectSettingsPage,
|
||||
};
|
||||
use crate::shared::styled_button::StyledButton;
|
||||
use crate::shared::styled_checkbox::StyledCheckbox;
|
||||
use crate::shared::styled_editor::StyledEditor;
|
||||
@ -31,12 +34,14 @@ pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>)
|
||||
Msg::WsMsg(WsMsg::AuthorizeLoaded(..)) => {
|
||||
send_ws_msg(WsMsg::ProjectRequest);
|
||||
send_ws_msg(WsMsg::IssueStatusesRequest);
|
||||
send_ws_msg(WsMsg::ProjectIssuesRequest);
|
||||
}
|
||||
Msg::ChangePage(Page::ProjectSettings) => {
|
||||
build_page_content(model);
|
||||
if model.user.is_some() {
|
||||
send_ws_msg(WsMsg::ProjectRequest);
|
||||
send_ws_msg(WsMsg::IssueStatusesRequest);
|
||||
send_ws_msg(WsMsg::ProjectIssuesRequest);
|
||||
}
|
||||
}
|
||||
Msg::WsMsg(WsMsg::ProjectLoaded(..)) => {
|
||||
@ -245,6 +250,12 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
|
||||
let width = 100f64 / (model.issue_statuses.len() + 1) as f64;
|
||||
let column_style = format!("width: calc({width}% - 10px)", width = width);
|
||||
let mut per_column_issue_count = HashMap::new();
|
||||
for issue in model.issues.iter() {
|
||||
*per_column_issue_count
|
||||
.entry(issue.issue_status_id)
|
||||
.or_insert(0) += 1;
|
||||
}
|
||||
let columns: Vec<Node<Msg>> = model
|
||||
.issue_statuses
|
||||
.iter()
|
||||
@ -284,21 +295,40 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
.into_node();
|
||||
|
||||
div![
|
||||
class!["columnPreview"],
|
||||
div![class!["columnName"], input]
|
||||
class!["columnPreview"],
|
||||
div![class!["columnName"], input]
|
||||
]
|
||||
} else {
|
||||
let edit = mouse_ev(Ev::Click, move |_| {
|
||||
let on_edit = mouse_ev(Ev::Click, move |_| {
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(ProjectPageChange::EditIssueStatusName(Some(id))))
|
||||
});
|
||||
let issue_count_in_column = per_column_issue_count.get(&id).cloned().unwrap_or_default();
|
||||
let delete_row = if issue_count_in_column == 0 {
|
||||
let on_delete = mouse_ev(Ev::Click, move |ev| {
|
||||
ev.prevent_default();
|
||||
ev.stop_propagation();
|
||||
Msg::ModalOpened(Box::new(ModalType::DeleteIssueStatusModal(Box::new(DeleteIssueStatusModal::new(id)))))
|
||||
});
|
||||
let delete = StyledButton::build()
|
||||
.primary()
|
||||
.add_class("removeColumn")
|
||||
.icon(Icon::Trash)
|
||||
.on_click(on_delete)
|
||||
.build()
|
||||
.into_node();
|
||||
div![class!["removeColumn"], delete]
|
||||
} else {
|
||||
div![class!["issueCount"], format!("Issues in column: {}", issue_count_in_column)]
|
||||
};
|
||||
|
||||
div![
|
||||
class!["columnPreview"],
|
||||
attrs![At::Style => column_style.as_str(), At::Draggable => "true", At::DropZone => "true"],
|
||||
div![class!["columnName"], span![is.name], edit],
|
||||
drag_started,
|
||||
drag_stopped,
|
||||
drag_over_handler,
|
||||
drag_out,
|
||||
class!["columnPreview"],
|
||||
attrs![At::Style => column_style.as_str(), At::Draggable => "true", At::DropZone => "true"],
|
||||
div![class!["columnName"], span![is.name], on_edit, delete_row],
|
||||
drag_started,
|
||||
drag_stopped,
|
||||
drag_over_handler,
|
||||
drag_out,
|
||||
]
|
||||
}
|
||||
})
|
||||
@ -352,7 +382,12 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
|
||||
let project_section = vec![div![class!["formContainer"], form]];
|
||||
|
||||
inner_layout(model, "projectSettings", project_section, empty![])
|
||||
inner_layout(
|
||||
model,
|
||||
"projectSettings",
|
||||
project_section,
|
||||
crate::modal::view(model),
|
||||
)
|
||||
}
|
||||
|
||||
fn exchange_position(bellow_id: IssueStatusId, model: &mut Model) {
|
||||
|
@ -29,11 +29,11 @@ impl Variant {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StyledModal {
|
||||
pub variant: Variant,
|
||||
pub width: usize,
|
||||
pub with_icon: bool,
|
||||
pub children: Vec<Node<Msg>>,
|
||||
pub class_list: Vec<String>,
|
||||
variant: Variant,
|
||||
width: usize,
|
||||
with_icon: bool,
|
||||
children: Vec<Node<Msg>>,
|
||||
class_list: Vec<String>,
|
||||
}
|
||||
|
||||
impl ToNode for StyledModal {
|
||||
@ -63,6 +63,10 @@ impl StyledModalBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
// pub fn center(mut self) -> Self {
|
||||
// self.variant(Variant::Center)
|
||||
// }
|
||||
|
||||
pub fn width(mut self, width: usize) -> Self {
|
||||
self.width = Some(width);
|
||||
self
|
||||
|
Loading…
Reference in New Issue
Block a user