Valid implementation of drag&drop issues
This commit is contained in:
parent
dc3be999be
commit
c3c8d1b66e
@ -87,6 +87,7 @@ pub enum Msg {
|
|||||||
IssueDragStarted(IssueId),
|
IssueDragStarted(IssueId),
|
||||||
IssueDragStopped(IssueId),
|
IssueDragStopped(IssueId),
|
||||||
ExchangePosition(IssueId),
|
ExchangePosition(IssueId),
|
||||||
|
IssueDragOverStatus(IssueStatus),
|
||||||
IssueDropZone(IssueStatus),
|
IssueDropZone(IssueStatus),
|
||||||
UnlockDragOver,
|
UnlockDragOver,
|
||||||
|
|
||||||
|
@ -118,7 +118,8 @@ pub struct ProjectPage {
|
|||||||
pub only_my_filter: bool,
|
pub only_my_filter: bool,
|
||||||
pub recently_updated_filter: bool,
|
pub recently_updated_filter: bool,
|
||||||
pub dragged_issue_id: Option<IssueId>,
|
pub dragged_issue_id: Option<IssueId>,
|
||||||
pub drag_locked: bool,
|
pub last_drag_exchange_id: Option<IssueId>,
|
||||||
|
pub dirty_issues: Vec<IssueId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -168,7 +169,8 @@ impl Default for Model {
|
|||||||
only_my_filter: false,
|
only_my_filter: false,
|
||||||
recently_updated_filter: false,
|
recently_updated_filter: false,
|
||||||
dragged_issue_id: None,
|
dragged_issue_id: None,
|
||||||
drag_locked: false,
|
last_drag_exchange_id: None,
|
||||||
|
dirty_issues: vec![],
|
||||||
},
|
},
|
||||||
modals: vec![],
|
modals: vec![],
|
||||||
project: None,
|
project: None,
|
||||||
|
@ -10,7 +10,7 @@ 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::styled_select::StyledSelectChange;
|
||||||
use crate::shared::{drag_ev, inner_layout, ToNode};
|
use crate::shared::{drag_ev, inner_layout, ToNode};
|
||||||
use crate::{FieldId, Msg, APP};
|
use crate::{FieldId, Msg};
|
||||||
|
|
||||||
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||||
match msg {
|
match msg {
|
||||||
@ -92,112 +92,15 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
|||||||
pp.recently_updated_filter = false;
|
pp.recently_updated_filter = false;
|
||||||
pp.only_my_filter = false;
|
pp.only_my_filter = false;
|
||||||
}
|
}
|
||||||
Msg::IssueDragStarted(issue_id) => {
|
Msg::IssueDragStarted(issue_id) => crate::ws::issue::drag_started(issue_id, model),
|
||||||
model.project_page.dragged_issue_id = Some(issue_id);
|
|
||||||
}
|
|
||||||
Msg::IssueDragStopped(_) => {
|
Msg::IssueDragStopped(_) => {
|
||||||
model.project_page.dragged_issue_id = None;
|
model.project_page.dragged_issue_id = None;
|
||||||
}
|
}
|
||||||
Msg::ExchangePosition(issue_bellow_id) => {
|
Msg::ExchangePosition(issue_bellow_id) => {
|
||||||
if model.project_page.drag_locked {
|
crate::ws::issue::exchange_position(issue_bellow_id, model)
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
log!(issue_bellow_id);
|
Msg::IssueDragOverStatus(status) => crate::ws::issue::change_status(status, model),
|
||||||
log!(model.project_page.dragged_issue_id);
|
Msg::IssueDropZone(status) => crate::ws::issue::dropped(status, model),
|
||||||
let dragged_id = match model.project_page.dragged_issue_id {
|
|
||||||
Some(id) => id,
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut below = None;
|
|
||||||
let mut dragged = None;
|
|
||||||
let mut issues = vec![];
|
|
||||||
std::mem::swap(&mut issues, &mut model.issues);
|
|
||||||
|
|
||||||
for issue in issues.into_iter() {
|
|
||||||
match issue.id {
|
|
||||||
id if id == issue_bellow_id => below = Some(issue),
|
|
||||||
id if id == dragged_id => dragged = Some(issue),
|
|
||||||
_ => model.issues.push(issue),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut below = match below {
|
|
||||||
Some(below) => below,
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
let mut dragged = match dragged {
|
|
||||||
Some(issue) => issue,
|
|
||||||
_ => {
|
|
||||||
model.issues.push(below);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if dragged.status == below.status {
|
|
||||||
std::mem::swap(&mut dragged.list_position, &mut below.list_position);
|
|
||||||
below.status = dragged.status.clone();
|
|
||||||
} else {
|
|
||||||
below.list_position = model
|
|
||||||
.issues
|
|
||||||
.iter()
|
|
||||||
.map(|i| i.list_position)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(0)
|
|
||||||
+ 1;
|
|
||||||
std::mem::swap(&mut dragged.list_position, &mut below.list_position);
|
|
||||||
below.status = dragged.status.clone();
|
|
||||||
}
|
|
||||||
model.issues.push(below);
|
|
||||||
model.issues.push(dragged);
|
|
||||||
model
|
|
||||||
.issues
|
|
||||||
.sort_by(|a, b| a.list_position.cmp(&b.list_position));
|
|
||||||
model.project_page.drag_locked = true;
|
|
||||||
// log!(model.issues);
|
|
||||||
}
|
|
||||||
Msg::UnlockDragOver => {
|
|
||||||
model.project_page.drag_locked = false;
|
|
||||||
}
|
|
||||||
Msg::IssueDropZone(status) => match model.project_page.dragged_issue_id.as_ref().cloned() {
|
|
||||||
Some(issue_id) => {
|
|
||||||
let mut position = 0;
|
|
||||||
let mut found: Option<&mut Issue> = None;
|
|
||||||
for issue in model.issues.iter_mut() {
|
|
||||||
if issue.status == status {
|
|
||||||
position += 1;
|
|
||||||
}
|
|
||||||
if issue.id == issue_id {
|
|
||||||
found = Some(issue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let issue = match found {
|
|
||||||
Some(i) => i,
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
issue.status = status.clone();
|
|
||||||
issue.list_position = position + 1;
|
|
||||||
|
|
||||||
let payload = UpdateIssuePayload {
|
|
||||||
title: Some(issue.title.clone()),
|
|
||||||
issue_type: Some(issue.issue_type.clone()),
|
|
||||||
status: Some(status),
|
|
||||||
priority: Some(issue.priority.clone()),
|
|
||||||
list_position: Some(issue.list_position),
|
|
||||||
description: Some(issue.description.clone()),
|
|
||||||
description_text: Some(issue.description_text.clone()),
|
|
||||||
estimate: Some(issue.estimate),
|
|
||||||
time_spent: Some(issue.time_spent),
|
|
||||||
time_remaining: Some(issue.time_remaining),
|
|
||||||
project_id: Some(issue.project_id),
|
|
||||||
user_ids: Some(issue.user_ids.clone()),
|
|
||||||
};
|
|
||||||
model.project_page.dragged_issue_id = None;
|
|
||||||
send_ws_msg(WsMsg::IssueUpdateRequest(issue_id, payload));
|
|
||||||
}
|
|
||||||
_ => error!("Drag stopped before drop :("),
|
|
||||||
},
|
|
||||||
Msg::DeleteIssue(issue_id) => {
|
Msg::DeleteIssue(issue_id) => {
|
||||||
send_ws_msg(jirs_data::WsMsg::IssueDeleteRequest(issue_id));
|
send_ws_msg(jirs_data::WsMsg::IssueDeleteRequest(issue_id));
|
||||||
}
|
}
|
||||||
@ -357,9 +260,11 @@ fn project_issue_list(model: &Model, status: jirs_data::IssueStatus) -> Node<Msg
|
|||||||
ev.prevent_default();
|
ev.prevent_default();
|
||||||
Msg::IssueDropZone(send_status)
|
Msg::IssueDropZone(send_status)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let send_status = status.clone();
|
||||||
let drag_over_handler = drag_ev(Ev::DragOver, move |ev| {
|
let drag_over_handler = drag_ev(Ev::DragOver, move |ev| {
|
||||||
ev.prevent_default();
|
ev.prevent_default();
|
||||||
Msg::NoOp
|
Msg::IssueDragOverStatus(send_status)
|
||||||
});
|
});
|
||||||
|
|
||||||
div![
|
div![
|
||||||
@ -420,23 +325,10 @@ fn project_issue(model: &Model, issue: &Issue) -> Node<Msg> {
|
|||||||
let drag_over_handler = drag_ev(Ev::DragOver, move |ev| {
|
let drag_over_handler = drag_ev(Ev::DragOver, move |ev| {
|
||||||
ev.prevent_default();
|
ev.prevent_default();
|
||||||
ev.stop_propagation();
|
ev.stop_propagation();
|
||||||
seed::set_timeout(
|
|
||||||
Box::new(|| {
|
|
||||||
let app = match unsafe { APP.as_mut().unwrap() }.write() {
|
|
||||||
Ok(app) => app,
|
|
||||||
_ => return,
|
|
||||||
};
|
|
||||||
app.update(Msg::UnlockDragOver);
|
|
||||||
}),
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
Msg::ExchangePosition(issue_id)
|
Msg::ExchangePosition(issue_id)
|
||||||
});
|
});
|
||||||
|
|
||||||
let class_list = vec!["issue"];
|
let class_list = vec!["issue"];
|
||||||
if Some(issue_id) == model.project_page.dragged_issue_id {
|
|
||||||
// class_list.push("hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
let href = format!("/issues/{id}", id = issue_id);
|
let href = format!("/issues/{id}", id = issue_id);
|
||||||
|
|
||||||
|
149
jirs-client/src/ws/issue.rs
Normal file
149
jirs-client/src/ws/issue.rs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
use seed::*;
|
||||||
|
|
||||||
|
use jirs_data::*;
|
||||||
|
|
||||||
|
use crate::api::send_ws_msg;
|
||||||
|
use crate::model::Model;
|
||||||
|
use crate::IssueId;
|
||||||
|
|
||||||
|
pub fn drag_started(issue_id: IssueId, model: &mut Model) {
|
||||||
|
model.project_page.dragged_issue_id = Some(issue_id);
|
||||||
|
|
||||||
|
mark_dirty(issue_id, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exchange_position(issue_bellow_id: IssueId, model: &mut Model) {
|
||||||
|
if model.project_page.dragged_issue_id == Some(issue_bellow_id)
|
||||||
|
|| model.project_page.last_drag_exchange_id == Some(issue_bellow_id)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let dragged_id = match model.project_page.dragged_issue_id {
|
||||||
|
Some(id) => id,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut below = None;
|
||||||
|
let mut dragged = None;
|
||||||
|
let mut issues = vec![];
|
||||||
|
std::mem::swap(&mut issues, &mut model.issues);
|
||||||
|
|
||||||
|
for issue in issues.into_iter() {
|
||||||
|
match issue.id {
|
||||||
|
id if id == issue_bellow_id => below = Some(issue),
|
||||||
|
id if id == dragged_id => dragged = Some(issue),
|
||||||
|
_ => model.issues.push(issue),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut below = match below {
|
||||||
|
Some(below) => below,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
let mut dragged = match dragged {
|
||||||
|
Some(issue) => issue,
|
||||||
|
_ => {
|
||||||
|
model.issues.push(below);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if dragged.status != below.status {
|
||||||
|
let mut issues = vec![];
|
||||||
|
std::mem::swap(&mut issues, &mut model.issues);
|
||||||
|
for mut c in issues.into_iter() {
|
||||||
|
if c.status == below.status && c.list_position > below.list_position {
|
||||||
|
c.list_position += 1;
|
||||||
|
mark_dirty(c.id, model);
|
||||||
|
}
|
||||||
|
model.issues.push(c);
|
||||||
|
}
|
||||||
|
dragged.list_position = below.list_position + 1;
|
||||||
|
dragged.status = below.status.clone();
|
||||||
|
}
|
||||||
|
std::mem::swap(&mut dragged.list_position, &mut below.list_position);
|
||||||
|
|
||||||
|
mark_dirty(dragged.id, model);
|
||||||
|
mark_dirty(below.id, model);
|
||||||
|
|
||||||
|
model.issues.push(below);
|
||||||
|
model.issues.push(dragged);
|
||||||
|
model
|
||||||
|
.issues
|
||||||
|
.sort_by(|a, b| a.list_position.cmp(&b.list_position));
|
||||||
|
model.project_page.last_drag_exchange_id = Some(issue_bellow_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dropped(_status: IssueStatus, model: &mut Model) {
|
||||||
|
for issue in model.issues.iter() {
|
||||||
|
if !model.project_page.dirty_issues.contains(&issue.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let payload = UpdateIssuePayload {
|
||||||
|
title: Some(issue.title.clone()),
|
||||||
|
issue_type: Some(issue.issue_type.clone()),
|
||||||
|
status: Some(issue.status.clone()),
|
||||||
|
priority: Some(issue.priority.clone()),
|
||||||
|
list_position: Some(issue.list_position),
|
||||||
|
description: Some(issue.description.clone()),
|
||||||
|
description_text: Some(issue.description_text.clone()),
|
||||||
|
estimate: Some(issue.estimate),
|
||||||
|
time_spent: Some(issue.time_spent),
|
||||||
|
time_remaining: Some(issue.time_remaining),
|
||||||
|
project_id: Some(issue.project_id),
|
||||||
|
user_ids: Some(issue.user_ids.clone()),
|
||||||
|
};
|
||||||
|
model.project_page.dragged_issue_id = None;
|
||||||
|
send_ws_msg(WsMsg::IssueUpdateRequest(issue.id, payload));
|
||||||
|
model.project_page.last_drag_exchange_id = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn change_status(status: IssueStatus, model: &mut Model) {
|
||||||
|
let issue_id = match model.project_page.dragged_issue_id.as_ref().cloned() {
|
||||||
|
Some(issue_id) => issue_id,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut old: Vec<Issue> = vec![];
|
||||||
|
let mut pos = 0;
|
||||||
|
let mut found: Option<Issue> = None;
|
||||||
|
std::mem::swap(&mut old, &mut model.issues);
|
||||||
|
old.sort_by(|a, b| a.list_position.cmp(&b.list_position));
|
||||||
|
|
||||||
|
for mut issue in old.into_iter() {
|
||||||
|
if issue.status == status {
|
||||||
|
issue.list_position = pos;
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
if issue.id != issue_id {
|
||||||
|
model.issues.push(issue);
|
||||||
|
} else {
|
||||||
|
found = Some(issue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut issue = match found {
|
||||||
|
Some(i) => i,
|
||||||
|
_ => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if issue.status == status {
|
||||||
|
model.issues.push(issue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
issue.status = status.clone();
|
||||||
|
issue.list_position = pos + 1;
|
||||||
|
model.issues.push(issue);
|
||||||
|
|
||||||
|
mark_dirty(issue_id, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mark_dirty(id: IssueId, model: &mut Model) {
|
||||||
|
if !model.project_page.dirty_issues.contains(&id) {
|
||||||
|
model.project_page.dirty_issues.push(id);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,8 @@ use jirs_data::WsMsg;
|
|||||||
|
|
||||||
use crate::{model, Msg, APP};
|
use crate::{model, Msg, APP};
|
||||||
|
|
||||||
|
pub mod issue;
|
||||||
|
|
||||||
pub fn handle(msg: WsMsg) {
|
pub fn handle(msg: WsMsg) {
|
||||||
let app = match unsafe { APP.as_mut().unwrap() }.write() {
|
let app = match unsafe { APP.as_mut().unwrap() }.write() {
|
||||||
Ok(app) => app,
|
Ok(app) => app,
|
||||||
|
@ -12,6 +12,11 @@ pub use sql::*;
|
|||||||
#[cfg(feature = "backend")]
|
#[cfg(feature = "backend")]
|
||||||
pub mod sql;
|
pub mod sql;
|
||||||
|
|
||||||
|
pub trait ToVec {
|
||||||
|
type Item;
|
||||||
|
fn ordered() -> Vec<Self::Item>;
|
||||||
|
}
|
||||||
|
|
||||||
#[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, Hash)]
|
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq, Hash)]
|
||||||
@ -22,6 +27,14 @@ pub enum IssueType {
|
|||||||
Story,
|
Story,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToVec for IssueType {
|
||||||
|
type Item = IssueType;
|
||||||
|
|
||||||
|
fn ordered() -> Vec<Self> {
|
||||||
|
vec![IssueType::Task, IssueType::Bug, IssueType::Story]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for IssueType {
|
impl Default for IssueType {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
IssueType::Task
|
IssueType::Task
|
||||||
@ -72,7 +85,6 @@ 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, Hash)]
|
#[derive(Clone, Deserialize, Serialize, Debug, PartialOrd, PartialEq, Hash)]
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum IssueStatus {
|
pub enum IssueStatus {
|
||||||
Backlog,
|
Backlog,
|
||||||
Selected,
|
Selected,
|
||||||
@ -100,6 +112,19 @@ impl FromStr for IssueStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToVec for IssueStatus {
|
||||||
|
type Item = IssueStatus;
|
||||||
|
|
||||||
|
fn ordered() -> Vec<Self> {
|
||||||
|
vec![
|
||||||
|
IssueStatus::Backlog,
|
||||||
|
IssueStatus::Selected,
|
||||||
|
IssueStatus::InProgress,
|
||||||
|
IssueStatus::Done,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IssueStatus {
|
impl IssueStatus {
|
||||||
pub fn to_label(&self) -> &str {
|
pub fn to_label(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
@ -135,16 +160,30 @@ pub enum IssuePriority {
|
|||||||
Lowest,
|
Lowest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToVec for IssuePriority {
|
||||||
|
type Item = IssuePriority;
|
||||||
|
|
||||||
|
fn ordered() -> Vec<Self> {
|
||||||
|
vec![
|
||||||
|
IssuePriority::Highest,
|
||||||
|
IssuePriority::High,
|
||||||
|
IssuePriority::Medium,
|
||||||
|
IssuePriority::Low,
|
||||||
|
IssuePriority::Lowest,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for IssuePriority {
|
impl FromStr for IssuePriority {
|
||||||
type Err = String;
|
type Err = String;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_lowercase().trim() {
|
match s.to_lowercase().trim() {
|
||||||
"5" | "highest" => Ok(IssuePriority::Highest),
|
"highest" => Ok(IssuePriority::Highest),
|
||||||
"4" | "high" => Ok(IssuePriority::High),
|
"high" => Ok(IssuePriority::High),
|
||||||
"3" | "medium" => Ok(IssuePriority::Medium),
|
"medium" => Ok(IssuePriority::Medium),
|
||||||
"2" | "low" => Ok(IssuePriority::Low),
|
"low" => Ok(IssuePriority::Low),
|
||||||
"1" | "lowest" => Ok(IssuePriority::Lowest),
|
"lowest" => Ok(IssuePriority::Lowest),
|
||||||
_ => Err(format!("Unknown priority {}", s)),
|
_ => Err(format!("Unknown priority {}", s)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,13 +233,11 @@ impl Into<IssuePriority> for u32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Debug, PartialEq)]
|
#[derive(Clone, Serialize, Debug, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct ErrorResponse {
|
pub struct ErrorResponse {
|
||||||
pub errors: Vec<String>,
|
pub errors: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct FullProject {
|
pub struct FullProject {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -215,11 +252,9 @@ pub struct FullProject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct FullIssue {
|
pub struct FullIssue {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub issue_type: IssueType,
|
pub issue_type: IssueType,
|
||||||
pub status: IssueStatus,
|
pub status: IssueStatus,
|
||||||
pub priority: IssuePriority,
|
pub priority: IssuePriority,
|
||||||
@ -262,7 +297,6 @@ impl Into<Issue> for FullIssue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Project {
|
pub struct Project {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -274,11 +308,9 @@ pub struct Project {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Issue {
|
pub struct Issue {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub issue_type: IssueType,
|
pub issue_type: IssueType,
|
||||||
pub status: IssueStatus,
|
pub status: IssueStatus,
|
||||||
pub priority: IssuePriority,
|
pub priority: IssuePriority,
|
||||||
@ -297,7 +329,6 @@ pub struct Issue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Comment {
|
pub struct Comment {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub body: String,
|
pub body: String,
|
||||||
@ -310,7 +341,6 @@ pub struct Comment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -322,7 +352,6 @@ pub struct User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Token {
|
pub struct Token {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
@ -333,10 +362,8 @@ pub struct Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UpdateIssuePayload {
|
pub struct UpdateIssuePayload {
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub issue_type: Option<IssueType>,
|
pub issue_type: Option<IssueType>,
|
||||||
pub status: Option<IssueStatus>,
|
pub status: Option<IssueStatus>,
|
||||||
pub priority: Option<IssuePriority>,
|
pub priority: Option<IssuePriority>,
|
||||||
@ -351,7 +378,6 @@ pub struct UpdateIssuePayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct CreateCommentPayload {
|
pub struct CreateCommentPayload {
|
||||||
pub user_id: Option<i32>,
|
pub user_id: Option<i32>,
|
||||||
pub issue_id: i32,
|
pub issue_id: i32,
|
||||||
@ -359,16 +385,13 @@ pub struct CreateCommentPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UpdateCommentPayload {
|
pub struct UpdateCommentPayload {
|
||||||
pub body: String,
|
pub body: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct CreateIssuePayload {
|
pub struct CreateIssuePayload {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub issue_type: IssueType,
|
pub issue_type: IssueType,
|
||||||
pub status: IssueStatus,
|
pub status: IssueStatus,
|
||||||
pub priority: IssuePriority,
|
pub priority: IssuePriority,
|
||||||
@ -383,7 +406,6 @@ pub struct CreateIssuePayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UpdateProjectPayload {
|
pub struct UpdateProjectPayload {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub url: Option<String>,
|
pub url: Option<String>,
|
||||||
|
Loading…
Reference in New Issue
Block a user