gitbay/Dashboard/DashboardModels.swift

v1.14.1
gitbay-ios/gitbay/Dashboard/DashboardModels.swift history · blame · raw

81 lines · 3168 bytes

 1import Foundation
 2
 3/// The `dashboard` command: the same account aggregate as the web
 4/// dashboard, in one read. Newer arrays default empty so an updated app
 5/// can still talk to a server from before the dashboard parity contract.
 6nonisolated struct DashboardData: Decodable, Sendable, Hashable {
 7    let reviewQueue: [DashboardItem]
 8    let assignedIssues: [DashboardItem]
 9    let openMRs: [DashboardItem]
10    let openIssues: [DashboardItem]
11    /// Pinned repos share `repo list`'s row shape.
12    let pinned: [RepoSummary]
13    let recentActivity: [FeedEvent]
14    /// Retained by the CLI for compatibility; builds are not a web
15    /// dashboard section.
16    let builds: [DashboardBuild]
17    /// The unread notification count, so a client showing a badge does
18    /// not need a second read to fill it.
19    let unread: Int
20    /// Pinned saved queries with their first rows (gitbay v1.39.0).
21    let queries: [DashboardQuery]
22
23    enum CodingKeys: String, CodingKey {
24        case pinned, builds, unread, queries
25        case reviewQueue = "review_queue"
26        case openMRs = "open_mrs"
27        case assignedIssues = "assigned_issues"
28        case openIssues = "open_issues"
29        case recentActivity = "recent_activity"
30    }
31
32    init(from decoder: any Decoder) throws {
33        let values = try decoder.container(keyedBy: CodingKeys.self)
34        reviewQueue = try values.decodeIfPresent([DashboardItem].self, forKey: .reviewQueue) ?? []
35        assignedIssues = try values.decodeIfPresent([DashboardItem].self, forKey: .assignedIssues) ?? []
36        openMRs = try values.decodeIfPresent([DashboardItem].self, forKey: .openMRs) ?? []
37        openIssues = try values.decodeIfPresent([DashboardItem].self, forKey: .openIssues) ?? []
38        pinned = try values.decodeIfPresent([RepoSummary].self, forKey: .pinned) ?? []
39        recentActivity = try values.decodeIfPresent([FeedEvent].self, forKey: .recentActivity) ?? []
40        builds = try values.decodeIfPresent([DashboardBuild].self, forKey: .builds) ?? []
41        unread = try values.decodeIfPresent(Int.self, forKey: .unread) ?? 0
42        queries = try values.decodeIfPresent([DashboardQuery].self, forKey: .queries) ?? []
43    }
44}
45
46/// One open issue or MR row, repo resolved server-side.
47nonisolated struct DashboardItem: Decodable, Sendable, Hashable, Identifiable {
48    let repo: String
49    let number: Int64
50    let title: String
51    let author: String
52    let state: String
53    let updatedAt: Date
54
55    enum CodingKeys: String, CodingKey {
56        case repo, number, title, author, state
57        case updatedAt = "updated_at"
58    }
59
60    var id: String { "\(repo)#\(number)" }
61}
62
63/// One build row with its repo attached.
64nonisolated struct DashboardBuild: Decodable, Sendable, Hashable, Identifiable {
65    let repo: String
66    let number: Int64
67    let job: String
68    let status: String
69    let sha: String
70    let ref: String
71    let createdAt: Date
72    let finishedAt: Date?
73
74    enum CodingKeys: String, CodingKey {
75        case repo, number, job, status, sha, ref
76        case createdAt = "created_at"
77        case finishedAt = "finished_at"
78    }
79
80    var id: String { "\(repo)#\(number)" }
81}