Commit bf8e223f authored by Konstantin Tskhovrebov's avatar Konstantin Tskhovrebov 🤖

Merge branch 'feature/project_members_presentation' into 'feature/project_members_presentation'

Resolved conflicts for merging branch feature/project_members_presentation into develop.

See merge request terrakok/gitlab-client!208
parents 8526671b 0770b787
......@@ -16,8 +16,8 @@ android {
minSdkVersion(19)
targetSdkVersion(28)
versionName = "1.5.1"
versionCode = 16
versionName = "1.5.4"
versionCode = 19
buildToolsVersion = "28.0.3"
......@@ -94,7 +94,7 @@ dependencies {
//Support
implementation("androidx.appcompat:appcompat:1.0.2")
implementation("com.google.android.material:material:1.1.0-alpha06")
implementation("com.google.android.material:material:1.1.0-alpha07")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
//Kotlin
......@@ -135,13 +135,13 @@ dependencies {
//Lottie
implementation("com.airbnb.android:lottie:2.5.1")
//Date
implementation("com.jakewharton.threetenabp:threetenabp:1.0.5")
implementation("com.jakewharton.threetenabp:threetenabp:1.2.1")
//FlexBox Layout
implementation("com.google.android:flexbox:1.0.0")
//Firebase
implementation("com.google.firebase:firebase-core:16.0.9")
//Crashlytics
implementation("com.crashlytics.sdk.android:crashlytics:2.10.0")
implementation("com.crashlytics.sdk.android:crashlytics:2.10.1")
//JUnit
testImplementation("junit:junit:4.12")
......
......@@ -12,10 +12,7 @@ import ru.terrakok.gitlabclient.ui.auth.AuthFlowFragment
import ru.terrakok.gitlabclient.ui.auth.AuthFragment
import ru.terrakok.gitlabclient.ui.drawer.DrawerFlowFragment
import ru.terrakok.gitlabclient.ui.file.ProjectFileFragment
import ru.terrakok.gitlabclient.ui.issue.IssueFlowFragment
import ru.terrakok.gitlabclient.ui.issue.IssueInfoFragment
import ru.terrakok.gitlabclient.ui.issue.IssueNotesFragment
import ru.terrakok.gitlabclient.ui.issue.MainIssueFragment
import ru.terrakok.gitlabclient.ui.issue.*
import ru.terrakok.gitlabclient.ui.libraries.LibrariesFragment
import ru.terrakok.gitlabclient.ui.main.MainFragment
import ru.terrakok.gitlabclient.ui.mergerequest.*
......@@ -210,6 +207,10 @@ object Screens {
override fun getFragment() = MainMergeRequestFragment()
}
object MergeRequestDetails : SupportAppScreen() {
override fun getFragment() = MergeRequestDetailsFragment()
}
object MergeRequestInfo : SupportAppScreen() {
override fun getFragment() = MergeRequestInfoFragment()
}
......@@ -234,6 +235,10 @@ object Screens {
override fun getFragment() = IssueInfoFragment()
}
object IssueDetails : SupportAppScreen() {
override fun getFragment() = IssueDetailsFragment()
}
object IssueNotes : SupportAppScreen() {
override fun getFragment() = IssueNotesFragment()
}
......
......@@ -10,16 +10,12 @@ import ru.terrakok.gitlabclient.BuildConfig
import ru.terrakok.gitlabclient.di.*
import ru.terrakok.gitlabclient.di.provider.GsonProvider
import ru.terrakok.gitlabclient.entity.app.develop.AppInfo
import ru.terrakok.gitlabclient.model.data.storage.RawAppData
import ru.terrakok.gitlabclient.model.interactor.app.AppInfoInteractor
import ru.terrakok.gitlabclient.model.repository.app.AppInfoRepository
import ru.terrakok.gitlabclient.model.repository.session.SessionRepository
import ru.terrakok.gitlabclient.model.repository.tools.Base64Tools
import ru.terrakok.gitlabclient.model.system.AppSchedulers
import ru.terrakok.gitlabclient.model.system.ResourceManager
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import ru.terrakok.gitlabclient.model.system.message.SystemMessageNotifier
import ru.terrakok.gitlabclient.presentation.AppLauncher
import toothpick.config.Module
/**
......@@ -37,7 +33,6 @@ class AppModule(context: Context) : Module() {
bind(ResourceManager::class.java).singletonInScope()
bind(Base64Tools::class.java).toInstance(Base64Tools())
bind(AssetManager::class.java).toInstance(context.assets)
bind(RawAppData::class.java)
bind(SystemMessageNotifier::class.java).toInstance(SystemMessageNotifier())
bind(Gson::class.java).toProvider(GsonProvider::class.java).providesSingletonInScope()
......@@ -60,9 +55,5 @@ class AppModule(context: Context) : Module() {
BuildConfig.FEEDBACK_URL
)
)
bind(AppInfoRepository::class.java)
bind(AppInfoInteractor::class.java)
bind(AppLauncher::class.java).singletonInScope()
}
}
\ No newline at end of file
......@@ -13,24 +13,6 @@ import ru.terrakok.gitlabclient.entity.app.session.OAuthParams
import ru.terrakok.gitlabclient.entity.app.session.UserAccount
import ru.terrakok.gitlabclient.model.data.cache.ProjectCache
import ru.terrakok.gitlabclient.model.data.server.GitlabApi
import ru.terrakok.gitlabclient.model.data.server.MarkDownUrlResolver
import ru.terrakok.gitlabclient.model.interactor.event.EventInteractor
import ru.terrakok.gitlabclient.model.interactor.issue.IssueInteractor
import ru.terrakok.gitlabclient.model.interactor.members.MembersInteractor
import ru.terrakok.gitlabclient.model.interactor.mergerequest.MergeRequestInteractor
import ru.terrakok.gitlabclient.model.interactor.milestone.MilestoneInteractor
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
import ru.terrakok.gitlabclient.model.interactor.todo.TodoInteractor
import ru.terrakok.gitlabclient.model.interactor.user.UserInteractor
import ru.terrakok.gitlabclient.model.repository.event.EventRepository
import ru.terrakok.gitlabclient.model.repository.issue.IssueRepository
import ru.terrakok.gitlabclient.model.repository.members.MembersRepository
import ru.terrakok.gitlabclient.model.repository.mergerequest.MergeRequestRepository
import ru.terrakok.gitlabclient.model.repository.milestone.MilestoneRepository
import ru.terrakok.gitlabclient.model.repository.profile.ProfileRepository
import ru.terrakok.gitlabclient.model.repository.project.ProjectRepository
import ru.terrakok.gitlabclient.model.repository.todo.TodoRepository
import ru.terrakok.gitlabclient.model.repository.user.UserRepository
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import toothpick.config.Module
......@@ -58,7 +40,6 @@ class ServerModule(userAccount: UserAccount?) : Module() {
bind(ProjectCache::class.java).singletonInScope()
bind(GitlabApi::class.java).toProvider(ApiProvider::class.java).providesSingletonInScope()
bind(MarkDownConverter::class.java).toProvider(MarkDownConverterProvider::class.java).providesSingletonInScope()
bind(MarkDownUrlResolver::class.java)
//Auth
bind(OAuthParams::class.java).toInstance(
......@@ -71,40 +52,5 @@ class ServerModule(userAccount: UserAccount?) : Module() {
//Error handler with logout logic
bind(ErrorHandler::class.java).singletonInScope()
//Profile
bind(ProfileRepository::class.java)
//Project
bind(ProjectRepository::class.java)
bind(ProjectInteractor::class.java)
//Issue
bind(IssueRepository::class.java)
bind(IssueInteractor::class.java)
//Event
bind(EventRepository::class.java)
bind(EventInteractor::class.java)
//Merge request
bind(MergeRequestRepository::class.java)
bind(MergeRequestInteractor::class.java)
//Milestone
bind(MilestoneRepository::class.java)
bind(MilestoneInteractor::class.java)
//User info
bind(UserRepository::class.java)
bind(UserInteractor::class.java)
//Todos
bind(TodoRepository::class.java)
bind(TodoInteractor::class.java)
//Members
bind(MembersInteractor::class.java)
bind(MembersRepository::class.java)
}
}
\ No newline at end of file
......@@ -3,13 +3,13 @@ package ru.terrakok.gitlabclient.di.provider
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.Color
import ru.terrakok.gitlabclient.entity.todo.Todo
import ru.terrakok.gitlabclient.model.data.server.deserializer.ColorDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.LocalDateTimeDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.LocalDateDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.TodoDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.ZonedDateTimeDeserializer
import javax.inject.Inject
import javax.inject.Provider
......@@ -20,9 +20,9 @@ class GsonProvider @Inject constructor() : Provider<Gson> {
override fun get(): Gson =
GsonBuilder()
.registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeDeserializer())
.registerTypeAdapter(Todo::class.java, TodoDeserializer())
.registerTypeAdapter(Color::class.java, ColorDeserializer())
.registerTypeAdapter(LocalDate::class.java, LocalDateDeserializer())
.registerTypeAdapter(ZonedDateTime::class.java, ZonedDateTimeDeserializer())
.create()
}
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
data class Author(
@SerializedName("id") val id: Long,
@SerializedName("state") val state: String?,
@SerializedName("web_url") val webUrl: String?,
@SerializedName("name") val name: String,
@SerializedName("avatar_url") val avatarUrl: String?,
@SerializedName("username") val username: String
)
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 20.10.18.
......@@ -12,11 +12,11 @@ data class Commit(
@SerializedName("title") val title: String,
@SerializedName("author_name") val authorName: String,
@SerializedName("author_email") val authorEmail: String?,
@SerializedName("authored_date") val authoredDate: LocalDateTime,
@SerializedName("authored_date") val authoredDate: ZonedDateTime,
@SerializedName("commiter_name") val commiterName: String?,
@SerializedName("commiter_email") val commiterEmail: String?,
@SerializedName("commited_date") val commitedDate: LocalDateTime?,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("commited_date") val commitedDate: ZonedDateTime?,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("message") val message: String,
@SerializedName("parent_ids") val parentIds: List<String>
)
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.event.EventTargetType
data class Note(
@SerializedName("id") val id: Long,
@SerializedName("body") val body: String,
@SerializedName("author") val author: Author,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
@SerializedName("author") val author: ShortUser,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("updated_at") val updatedAt: ZonedDateTime?,
@SerializedName("system") val isSystem: Boolean,
@SerializedName("noteable_id") val noteableId: Long,
@SerializedName("noteable_type") val noteableType: EventTargetType?,
......
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
data class Owner(
@SerializedName("id") val id: Long,
@SerializedName("name") val name: String,
@SerializedName("username") val username: String,
@SerializedName("created_at") val createdAt: LocalDateTime?
@SerializedName("created_at") val createdAt: ZonedDateTime?
)
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
data class Project(
@SerializedName("id") val id: Long,
......@@ -24,8 +24,8 @@ data class Project(
@SerializedName("wiki_enabled") val wikiEnabled: Boolean,
@SerializedName("snippets_enabled") val snippetsEnabled: Boolean,
@SerializedName("container_registry_enabled") val containerRegistryEnabled: Boolean,
@SerializedName("created_at") val createdAt: LocalDateTime?,
@SerializedName("last_activity_at") val lastActivityAt: LocalDateTime?,
@SerializedName("created_at") val createdAt: ZonedDateTime?,
@SerializedName("last_activity_at") val lastActivityAt: ZonedDateTime?,
@SerializedName("creator_id") val creatorId: Long,
@SerializedName("namespace") val namespace: Namespace?,
@SerializedName("permissions") val permissions: Permissions?,
......
......@@ -2,7 +2,7 @@ package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
data class Assignee(
data class ShortUser(
@SerializedName("id") val id: Long,
@SerializedName("state") val state: String?,
@SerializedName("name") val name: String,
......
package ru.terrakok.gitlabclient.entity.target
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
......
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
data class User(
@SerializedName("id") val id: Long,
......@@ -11,7 +11,7 @@ data class User(
@SerializedName("state") val state: String?,
@SerializedName("avatar_url") val avatarUrl: String?,
@SerializedName("web_url") val webUrl: String?,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("is_admin") val isAdmin: Boolean,
@SerializedName("bio") val bio: String?,
@SerializedName("location") val location: String?,
......@@ -20,11 +20,11 @@ data class User(
@SerializedName("twitter") val twitter: String?,
@SerializedName("website_url") val websiteUrl: String?,
@SerializedName("organization") val organization: String?,
@SerializedName("last_sign_in_at") val lastSignInAt: LocalDateTime,
@SerializedName("confirmed_at") val confirmedAt: LocalDateTime,
@SerializedName("last_sign_in_at") val lastSignInAt: ZonedDateTime,
@SerializedName("confirmed_at") val confirmedAt: ZonedDateTime,
@SerializedName("color_scheme_id") val colorSchemeId: Long,
@SerializedName("projects_limit") val projectsLimit: Long,
@SerializedName("current_sign_in_at") val currentSignInAt: LocalDateTime,
@SerializedName("current_sign_in_at") val currentSignInAt: ZonedDateTime,
@SerializedName("identities") val identities: List<Identity>?,
@SerializedName("can_create_group") val canCreateGroup: Boolean,
@SerializedName("can_create_project") val canCreateProject: Boolean,
......
package ru.terrakok.gitlabclient.entity.app.target
import org.threeten.bp.LocalDateTime
import ru.terrakok.gitlabclient.entity.Author
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.ShortUser
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 24.12.17.
*/
sealed class TargetHeader {
data class Public(
val author: Author,
val author: ShortUser,
val icon: TargetHeaderIcon,
val title: TargetHeaderTitle,
val body: CharSequence,
val date: LocalDateTime,
val date: ZonedDateTime,
val target: AppTarget,
val targetId: Long,
val internal: TargetInternal?,
......
package ru.terrakok.gitlabclient.entity.event
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import ru.terrakok.gitlabclient.entity.Author
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.Note
import ru.terrakok.gitlabclient.entity.PushData
import ru.terrakok.gitlabclient.entity.ShortUser
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 22.07.17.
......@@ -18,8 +17,8 @@ data class Event(
@SerializedName("target_type") val targetType: EventTargetType?,
@SerializedName("author_id") val authorId: Long,
@SerializedName("target_title") val targetTitle: String?,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("author") val author: Author,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("author") val author: ShortUser,
@SerializedName("author_username") val authorUsername: String,
@SerializedName("push_data") val pushData: PushData?,
@SerializedName("note") val note: Note?
......
package ru.terrakok.gitlabclient.entity.issue
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import ru.terrakok.gitlabclient.entity.Assignee
import ru.terrakok.gitlabclient.entity.Author
import org.threeten.bp.LocalDate
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.ShortUser
import ru.terrakok.gitlabclient.entity.TimeStats
import ru.terrakok.gitlabclient.entity.milestone.Milestone
data class Issue(
......@@ -11,16 +12,17 @@ data class Issue(
@SerializedName("iid") val iid: Long,
@SerializedName("state") val state: IssueState,
@SerializedName("description") val description: String,
@SerializedName("author") val author: Author,
@SerializedName("author") val author: ShortUser,
@SerializedName("milestone") val milestone: Milestone?,
@SerializedName("project_id") val projectId: Long,
@SerializedName("assignees") val assignees: List<Assignee>,
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
// Assignees can be null in MergeRequest, so assume it can be null too.
@SerializedName("assignees") val assignees: List<ShortUser>?,
@SerializedName("updated_at") val updatedAt: ZonedDateTime?,
@SerializedName("title") val title: String?,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("labels") val labels: List<String>,
@SerializedName("user_notes_count") val userNotesCount: Int,
@SerializedName("due_date") val dueDate: String?,
@SerializedName("due_date") val dueDate: LocalDate?,
@SerializedName("web_url") val webUrl: String?,
@SerializedName("confidential") val confidential: Boolean,
@SerializedName("upvotes") val upvotes: Int,
......@@ -28,8 +30,12 @@ data class Issue(
// The closed_by attribute was introduced in GitLab 10.6.
// This value will only be present for issues which were closed after GitLab 10.6 and
// when the user account that closed the issue still exists.
@SerializedName("closed_by") val closedBy: Author?,
@SerializedName("closed_at") val closedAt: LocalDateTime?,
@SerializedName("closed_by") val closedBy: ShortUser?,
@SerializedName("closed_at") val closedAt: ZonedDateTime?,
// The merge_requests_count attribute was introduced in GitLab 11.9.
@SerializedName("merge_requests_count") val relatedMergeRequestCount: Int
@SerializedName("merge_requests_count") val relatedMergeRequestCount: Int,
@SerializedName("time_stats") val timeStats: TimeStats,
@SerializedName("weight") val weight: Int?,
@SerializedName("discussion_locked") val discussionLocked: Boolean,
@SerializedName("assignee") val assignee: ShortUser?
)
\ No newline at end of file
package ru.terrakok.gitlabclient.entity.mergerequest
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import ru.terrakok.gitlabclient.entity.Author
import ru.terrakok.gitlabclient.entity.User
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.ShortUser
import ru.terrakok.gitlabclient.entity.TimeStats
import ru.terrakok.gitlabclient.entity.milestone.Milestone
data class MergeRequest(
@SerializedName("id") val id: Long,
@SerializedName("iid") val iid: Long,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("updated_at") val updatedAt: ZonedDateTime?,
@SerializedName("target_branch") val targetBranch: String,
@SerializedName("source_branch") val sourceBranch: String,
@SerializedName("project_id") val projectId: Long,
......@@ -18,29 +18,32 @@ data class MergeRequest(
@SerializedName("state") val state: MergeRequestState,
@SerializedName("upvotes") val upvotes: Int,
@SerializedName("downvotes") val downvotes: Int,
@SerializedName("author") val author: Author,
@SerializedName("assignee") val assignee: User?,
@SerializedName("author") val author: ShortUser,
@SerializedName("assignee") val assignee: ShortUser?,
@SerializedName("source_project_id") val sourceProjectId: Int,
@SerializedName("target_project_id") val targetProjectId: Int,
@SerializedName("description") val description: String,
@SerializedName("work_in_progress") val workInProgress: Boolean,
@SerializedName("milestone") val milestone: Milestone?,
@SerializedName("merge_when_pipeline_succeeds") val mergeWhenPipelineSucceeds: Boolean,
@SerializedName("merge_status") val mergeStatus: String?,
@SerializedName("merge_status") val mergeStatus: MergeRequestMergeStatus,
@SerializedName("sha") val sha: String,
@SerializedName("merge_commit_sha") val mergeCommitSha: String?,
@SerializedName("user_notes_count") val userNotesCount: Int,
@SerializedName("should_remove_source_branch") val shouldRemoveSourceBranch: Boolean,
@SerializedName("force_remove_source_branch") val forceRemoveSourceBranch: Boolean,
@SerializedName("web_url") val webUrl: String?,
@SerializedName("time_stats") val timeStats: MergeRequestTimeStats?,
@SerializedName("labels") val labels: List<String>,
// The closed_by attribute was introduced in GitLab 10.6.
// This value will only be present for merge requests which were closed/merged after GitLab 10.6
// and when the user account that closed/merged the issue still exists.
@SerializedName("closed_by") val closedBy: Author?,
@SerializedName("closed_at") val closedAt: LocalDateTime?,
@SerializedName("merged_by") val mergedBy: Author?,
@SerializedName("merged_at") val mergedAt: LocalDateTime?,
@SerializedName("changes") val changes: List<MergeRequestChange>?
@SerializedName("closed_by") val closedBy: ShortUser?,
@SerializedName("closed_at") val closedAt: ZonedDateTime?,
@SerializedName("merged_by") val mergedBy: ShortUser?,
@SerializedName("merged_at") val mergedAt: ZonedDateTime?,
@SerializedName("changes") val changes: List<MergeRequestChange>?,
// It sometimes can be null.
@SerializedName("assignees") val assignees: List<ShortUser>?,
@SerializedName("time_stats") val timeStats: TimeStats,
@SerializedName("discussion_locked") val discussionLocked: Boolean
)
package ru.terrakok.gitlabclient.entity.mergerequest
import com.google.gson.annotations.SerializedName
data class MergeRequestTimeStats(
@SerializedName("time_estimate") val timeEstimate: Int,
@SerializedName("total_time_spent") val totalTimeSpent: Int,
@SerializedName("human_time_estimate") val humanTimeEstimate: String?,
@SerializedName("human_total_time_spent") val humanTotalTimeSpent: String?
)
\ No newline at end of file
......@@ -2,7 +2,7 @@ package ru.terrakok.gitlabclient.entity.milestone
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
data class Milestone(
@SerializedName("id") val id: Long,
......@@ -12,8 +12,8 @@ data class Milestone(
@SerializedName("state") val state: MilestoneState,
@SerializedName("due_date") val dueDate: LocalDate?,
@SerializedName("start_date") val startDate: LocalDate?,
@SerializedName("created_at") val createdAt: LocalDateTime?,
@SerializedName("created_at") val createdAt: ZonedDateTime?,
@SerializedName("title") val title: String?,
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
@SerializedName("updated_at") val updatedAt: ZonedDateTime?,
@SerializedName("web_url") val webUrl: String?