escouade_plugin_protocol/tickets.rs
1//! The data of the Kanban's sources (docs/PLUGINS.md §4.5, `tickets/*`) as a plugin writes it: containers, states,
2//! tickets and their pages. The core reads them into its own types, which name the source by an id it interns
3//! (`Service`); here it is the string the data holds (`github`, `gitlab`…), the rest is the same JSON.
4
5use serde::{Deserialize, Serialize};
6
7/// Where an account's tickets live: a repository, a project, a board.
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
9#[serde(rename_all = "camelCase")]
10pub struct Container {
11 pub id: String,
12 pub name: String,
13 /// Where it is in its service's hierarchy, as the window groups it; none for most.
14 #[serde(default, skip_serializing_if = "Option::is_none")]
15 pub group: Option<String>,
16 /// The project's own repository (its remote's), which the import offers to link at once.
17 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
18 pub own: bool,
19}
20
21/// A state of an external ticket: for GitHub "open", "closed" or `label:<name>`.
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
23#[serde(rename_all = "camelCase", default)]
24pub struct ExternalState {
25 pub id: String,
26 pub name: String,
27}
28
29/// A filter of the import modal, shown as a chip.
30#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
31#[serde(rename_all = "camelCase")]
32pub struct IssueFilter {
33 pub id: String,
34 pub label: String,
35}
36
37/// What the import asks of a source.
38#[derive(Debug, Clone, Default, Serialize, Deserialize)]
39pub struct Query {
40 /// Typed in the search field.
41 pub text: String,
42 /// The ids of the chips turned on (`IssueFilter::id`).
43 pub filters: Vec<String>,
44 /// Only the tickets that carry this label (automatic import).
45 pub label: Option<String>,
46 /// The page after the first one: `IssuePage::next` of the one before.
47 pub page: Option<String>,
48}
49
50/// An external ticket as the import modal lists it, and as it is imported.
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
52#[serde(rename_all = "camelCase", default)]
53pub struct ExternalIssue {
54 /// The source's id.
55 pub service: String,
56 /// What its API knows it by (`ExternalRef::id`).
57 pub id: String,
58 /// As shown: #142.
59 pub key: String,
60 pub title: String,
61 /// As shown, in the interface's language.
62 pub kind: String,
63 /// What the window colours it by, the same in every language: `issue`, `bug`, `task`…
64 pub kind_code: String,
65 /// Its priority, assignee and state, those it has.
66 pub meta: Vec<String>,
67 pub url: String,
68 /// As markdown.
69 pub description: String,
70 /// Those its description or checklists list.
71 pub criteria: Vec<String>,
72 pub container: String,
73 /// Already on the project's Kanban (the core says it, not the plugin).
74 pub imported: bool,
75}
76
77/// A page of a source's tickets for the import modal, and the chips that filter them.
78#[derive(Debug, Clone, Serialize, PartialEq, Default, Deserialize)]
79#[serde(rename_all = "camelCase")]
80pub struct IssuePage {
81 pub issues: Vec<ExternalIssue>,
82 pub filters: Vec<IssueFilter>,
83 /// What asks for the next page (`Query::page`), when the service has more.
84 pub next: Option<String>,
85 /// How many tickets match in all, when the service says so.
86 pub total: Option<u64>,
87}
88
89/// Where an imported ticket comes from.
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
91#[serde(rename_all = "camelCase", default)]
92pub struct ExternalRef {
93 /// The source's id.
94 pub service: String,
95 /// What its API knows it by: the GitHub issue's number.
96 pub id: String,
97 /// As it is shown: #42.
98 pub key: String,
99 /// Its repository, project or board.
100 pub container: String,
101 pub url: String,
102 /// Why its last sync failed, until one succeeds.
103 pub error: Option<String>,
104}