Skip to content

Commit 8a240a0

Browse files
authored
add getEditAttributes for issueTypeOperator (#26)
* add getEditAttributes for issueTypeOperator * add getEditAttributes for http issueTypeOperator
1 parent 9efd604 commit 8a240a0

File tree

7 files changed

+231
-81
lines changed

7 files changed

+231
-81
lines changed

kotlin-http-client/kotlin-http-client-api/src/main/kotlin/com/linkedplanet/kotlinhttpclient/api/http/Utils.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ suspend fun <T> recursiveRestCall(
3131
var index = startIndex
3232
val elements = mutableListOf<T>()
3333
do {
34-
val tmpElements: List<T> = call(index, pageSize).getOrHandle {
34+
val tmpElements: List<T> = call(index, pageSize).getOrElse {
3535
return@recursiveRestCall it.left()
3636
}
3737
elements.addAll(tmpElements)
@@ -41,15 +41,15 @@ suspend fun <T> recursiveRestCall(
4141
}
4242

4343
@Suppress("unused")
44-
suspend fun <T> recursiveRestCallPaginated(
44+
suspend fun <T, ErrorType> recursiveRestCallPaginated(
4545
startIndex: Int = 0,
4646
pageSize: Int = 100,
47-
call: suspend (Int, Int) -> Either<HttpDomainError, HttpPage<T>>
48-
): Either<HttpDomainError, List<T>> {
47+
call: suspend (Int, Int) -> Either<ErrorType, HttpPage<T>>
48+
): Either<ErrorType, List<T>> {
4949
var index = startIndex
5050
val elements = mutableListOf<T>()
5151
do {
52-
val tmpElements: HttpPage<T> = call(index, pageSize).getOrHandle {
52+
val tmpElements: HttpPage<T> = call(index, pageSize).getOrElse {
5353
return@recursiveRestCallPaginated it.left()
5454
}
5555
elements.addAll(tmpElements.getValues())
@@ -59,15 +59,15 @@ suspend fun <T> recursiveRestCallPaginated(
5959
}
6060

6161
@Suppress("unused")
62-
suspend fun <T> recursiveRestCallPaginatedRaw(
62+
suspend fun <T, ErrorType> recursiveRestCallPaginatedRaw(
6363
startIndex: Int = 0,
6464
pageSize: Int = 100,
65-
call: suspend (Int, Int) -> Either<HttpDomainError, HttpPage<T>>
66-
): Either<HttpDomainError, List<HttpPage<T>>> {
65+
call: suspend (Int, Int) -> Either<ErrorType, HttpPage<T>>
66+
): Either<ErrorType, List<HttpPage<T>>> {
6767
var index = startIndex
6868
val elements = mutableListOf<HttpPage<T>>()
6969
do {
70-
val tmpElements: HttpPage<T> = call(index, pageSize).getOrHandle {
70+
val tmpElements: HttpPage<T> = call(index, pageSize).getOrElse {
7171
return@recursiveRestCallPaginatedRaw it.left()
7272
}
7373
elements.add(tmpElements)

kotlin-jira-client/kotlin-jira-client-api/src/main/kotlin/com/linkedplanet/kotlinjiraclient/api/interfaces/JiraIssueTypeOperator.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,48 @@ interface JiraIssueTypeOperator {
4949

5050
/**
5151
* Returns a list of attributes for an issue type in a given project.
52+
* Attributes must be on a create screen.
5253
* @param projectId The ID of the project.
5354
* @param issueTypeId The ID of the issue type.
5455
* @return Either an error or a list of issue type attributes.
5556
*/
57+
@Deprecated(
58+
"Renamed for clarity",
59+
ReplaceWith("getCreateAttributesOfIssueType(projectId, issueTypeId)")
60+
)
5661
suspend fun getAttributesOfIssueType(
5762
projectId: Number,
5863
issueTypeId: Number
64+
): Either<JiraClientError, List<JiraIssueTypeAttribute>> = getCreateAttributesOfIssueType(projectId, issueTypeId)
65+
66+
/**
67+
* Returns a list of attributes for an issue type in a given project.
68+
* Attributes must be on a create screen.
69+
* @param projectId The ID of the project.
70+
* @param issueTypeId The ID of the issue type.
71+
* @return Either an error or a list of issue type attributes.
72+
*/
73+
suspend fun getCreateAttributesOfIssueType(
74+
projectId: Number,
75+
issueTypeId: Number
5976
): Either<JiraClientError, List<JiraIssueTypeAttribute>>
77+
78+
/**
79+
* Returns a list of attributes for a concrete issue.
80+
* @param issueId The ID of the issue.
81+
* @return Either an error or a list of issue type attributes.
82+
*/
83+
suspend fun getEditAttributes(
84+
issueId: Long,
85+
): Either<JiraClientError, List<JiraIssueTypeAttribute>>
86+
87+
/**
88+
* Returns a list of attributes for an issue type in a given project.
89+
* @param issueKey The Key of the issue.
90+
* @return Either an error or a list of issue type attributes.
91+
*/
92+
suspend fun getEditAttributes(
93+
issueKey: String,
94+
): Either<JiraClientError, List<JiraIssueTypeAttribute>>
95+
6096
}

kotlin-jira-client/kotlin-jira-client-http/src/main/kotlin/com/linkedplanet/kotlinjiraclient/http/HttpJiraClientContext.kt

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,73 @@
1919
*/
2020
package com.linkedplanet.kotlinjiraclient.http
2121

22+
import arrow.core.Either
23+
import com.google.gson.reflect.TypeToken
24+
import com.linkedplanet.kotlinhttpclient.api.http.GSON
2225
import com.linkedplanet.kotlinhttpclient.api.http.HttpClient
26+
import com.linkedplanet.kotlinhttpclient.api.http.HttpResponse
27+
import com.linkedplanet.kotlinjiraclient.api.error.JiraClientError
28+
import com.linkedplanet.kotlinjiraclient.http.util.fromHttpDomainError
2329

2430
class HttpJiraClientContext(val baseUrl: String, val httpClient: HttpClient)
31+
32+
33+
suspend inline fun <reified T> HttpClient.execute(
34+
method: String,
35+
path: String,
36+
params: Map<String, String> = emptyMap(),
37+
body: String? = null,
38+
contentType: String? = null,
39+
): Either<JiraClientError, HttpResponse<T?>> =
40+
this.executeRest<T>(
41+
method,
42+
path,
43+
params,
44+
body,
45+
contentType = contentType,
46+
returnType = object : TypeToken<T>() {}.type
47+
)
48+
.mapLeft { JiraClientError.fromHttpDomainError(it) }
49+
50+
suspend inline fun <reified T> HttpClient.get(
51+
path: String,
52+
params: Map<String, String> = emptyMap(),
53+
): Either<JiraClientError, T?> =
54+
this.executeGet<T>(
55+
path,
56+
params,
57+
returnType = object : TypeToken<T>() {}.type
58+
)
59+
.map { it.body }
60+
.mapLeft { JiraClientError.fromHttpDomainError(it) }
61+
62+
suspend fun HttpClient.delete(
63+
path: String,
64+
params: Map<String, String> = emptyMap(),
65+
): Either<JiraClientError, Unit> =
66+
this.executeRestCall(
67+
"DELETE",
68+
path,
69+
params = params,
70+
body = null,
71+
contentType = null,
72+
)
73+
.mapLeft { JiraClientError.fromHttpDomainError(it) }
74+
.map { /*Unit*/ }
75+
76+
suspend inline fun <reified T, InputType> HttpClient.post(
77+
path: String,
78+
body: InputType,
79+
params: Map<String, String> = emptyMap(),
80+
contentType: String? = null,
81+
): Either<JiraClientError, T?> =
82+
this.executeRest<T>(
83+
method = "POST",
84+
path,
85+
params,
86+
GSON.toJson(body),
87+
contentType = contentType,
88+
returnType = object : TypeToken<T>() {}.type
89+
)
90+
.map { it.body }
91+
.mapLeft { JiraClientError.fromHttpDomainError(it) }

kotlin-jira-client/kotlin-jira-client-http/src/main/kotlin/com/linkedplanet/kotlinjiraclient/http/HttpJiraIssueTypeOperator.kt

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,62 +21,59 @@ package com.linkedplanet.kotlinjiraclient.http
2121

2222
import arrow.core.Either
2323
import arrow.core.raise.either
24-
import com.google.gson.reflect.TypeToken
2524
import com.linkedplanet.kotlinhttpclient.api.http.DefaultHttpPage
2625
import com.linkedplanet.kotlinhttpclient.api.http.recursiveRestCallPaginated
2726
import com.linkedplanet.kotlinjiraclient.api.error.JiraClientError
2827
import com.linkedplanet.kotlinjiraclient.api.interfaces.JiraIssueTypeOperator
2928
import com.linkedplanet.kotlinjiraclient.api.model.JiraIssueType
3029
import com.linkedplanet.kotlinjiraclient.api.model.JiraIssueTypeAttribute
3130
import com.linkedplanet.kotlinjiraclient.http.model.*
32-
import com.linkedplanet.kotlinjiraclient.http.util.fromHttpDomainError
3331

3432
class HttpJiraIssueTypeOperator(private val context: HttpJiraClientContext) : JiraIssueTypeOperator {
3533

3634
override suspend fun getIssueTypes(projectId: Number): Either<JiraClientError, List<JiraIssueType>> = either {
3735
recursiveRestCallPaginated { index, pageSize ->
38-
context.httpClient.executeRest<DefaultHttpPage<HttpJiraIssueType>>(
39-
"GET",
36+
context.httpClient.get<DefaultHttpPage<HttpJiraIssueType>>(
4037
"/rest/api/2/issue/createmeta/$projectId/issuetypes?startAt=$index&maxResults=$pageSize",
41-
emptyMap(),
42-
null,
43-
"application/json",
44-
object : TypeToken<DefaultHttpPage<HttpJiraIssueType>>() {}.type
45-
).map { it.body!! }
46-
}
47-
.mapLeft { JiraClientError.fromHttpDomainError(it) }
48-
.bind()
38+
).map { it!! }
39+
}.bind()
4940
.toJiraIssueTypes()
5041
}
5142

5243
override suspend fun getIssueType(issueTypeId: Number): Either<JiraClientError, JiraIssueType?> = either {
53-
context.httpClient.executeGet<HttpJiraIssueType>(
44+
context.httpClient.get<HttpJiraIssueType>(
5445
"/rest/api/2/issuetype/$issueTypeId",
55-
emptyMap(),
56-
object : TypeToken<HttpJiraIssueType>() {}.type
57-
)
58-
.map { it.body }
59-
.mapLeft { JiraClientError.fromHttpDomainError(it) }
60-
.bind()
46+
).bind()
6147
?.toJiraIssueType()
6248
}
6349

64-
override suspend fun getAttributesOfIssueType(
50+
override suspend fun getCreateAttributesOfIssueType(
6551
projectId: Number,
6652
issueTypeId: Number
6753
): Either<JiraClientError, List<JiraIssueTypeAttribute>> = either {
6854
recursiveRestCallPaginated { index, pageSize ->
69-
context.httpClient.executeRest<DefaultHttpPage<HttpJiraIssueTypeAttribute>>(
70-
"GET",
55+
context.httpClient.get<DefaultHttpPage<HttpJiraIssueTypeAttribute>>(
7156
"/rest/api/2/issue/createmeta/$projectId/issuetypes/$issueTypeId?startAt=$index&maxResults=$pageSize",
72-
emptyMap(),
73-
null,
74-
"application/json",
75-
object : TypeToken<DefaultHttpPage<HttpJiraIssueTypeAttribute>>() {}.type
76-
).map { it.body!! }
77-
}
78-
.mapLeft { JiraClientError.fromHttpDomainError(it) }
79-
.bind()
57+
).map { it!! }
58+
}.bind()
8059
.toJiraIssueTypeAttributes()
8160
}
61+
62+
override suspend fun getEditAttributes(
63+
issueId: Long
64+
): Either<JiraClientError, List<JiraIssueTypeAttribute>> =
65+
getEditAttributes("$issueId")
66+
67+
override suspend fun getEditAttributes(
68+
issueKey: String
69+
): Either<JiraClientError, List<JiraIssueTypeAttribute>> = either {
70+
context.httpClient.get<HttpEditMeta>(
71+
"/rest/api/2/issue/$issueKey/editmeta",
72+
).bind()
73+
?.fields
74+
?.values
75+
?.toJiraIssueTypeAttributes()
76+
?: emptyList()
77+
}
78+
8279
}

kotlin-jira-client/kotlin-jira-client-http/src/main/kotlin/com/linkedplanet/kotlinjiraclient/http/model/HttpModel.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ data class HttpJiraIssueType(
9393
fun List<HttpJiraIssueType>.toJiraIssueTypes(): List<JiraIssueType> =
9494
map { it.toJiraIssueType() }
9595

96+
data class HttpEditMeta(
97+
val fields: Map<String, HttpJiraIssueTypeAttribute>
98+
)
99+
96100
data class HttpJiraIssueTypeAttribute(
97101
val required: Boolean,
98102
val schema: HttpJiraIssueTypeAttributeJsonSchema?,
@@ -117,12 +121,12 @@ data class HttpJiraIssueTypeAttribute(
117121
data class HttpJiraIssueTypeAttributeJsonSchema(
118122
val type: String, // "date" see com.atlassian.jira.issue.fields.rest.json.JsonType
119123
val items: String?, // unclear what this is
120-
val system: String?, // only used if its a system field, e.g. "assignee"
124+
val system: String?, // only used if it's a system field, e.g. "assignee"
121125
val custom: String?, // e.g. com.atlassian.jira.plugin.system.customfieldtypes:datepicker
122126
val customId: Long? // e.g. 10202
123127
)
124128

125-
fun List<HttpJiraIssueTypeAttribute>.toJiraIssueTypeAttributes(): List<JiraIssueTypeAttribute> =
129+
fun Collection<HttpJiraIssueTypeAttribute>.toJiraIssueTypeAttributes(): List<JiraIssueTypeAttribute> =
126130
map { it.toJiraIssueTypeAttribute() }
127131

128132
data class HttpJiraTransition(

0 commit comments

Comments
 (0)