Skip to content

Commit 93d56ee

Browse files
JanCizmarhuglxstepan662
authored
feat: Slack integration (tolgee#2247)
Co-authored-by: Ivan Manzhosov <[email protected]> Co-authored-by: Ivan <[email protected]> Co-authored-by: Štěpán Granát <[email protected]>
1 parent f48dc56 commit 93d56ee

File tree

178 files changed

+8492
-571
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

178 files changed

+8492
-571
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,5 @@ backend/app/src/main/resources/application-js-e2e.properties
6868

6969
/webapp/src/branch.json
7070

71+
ngrok.yml
72+
ngrok.local.yml

backend/api/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ dependencies {
6767
api libs.postHog
6868
implementation libs.kotlinReflect
6969
implementation libs.jacksonModuleKotlin
70+
71+
/**
72+
* SLACK SDK
73+
*/
74+
api libs.slackApiClient
7075
}
7176

7277
sourceSets {

backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/ProjectActivityController.kt

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
package io.tolgee.api.v2.controllers
66

77
import io.swagger.v3.oas.annotations.Operation
8+
import io.swagger.v3.oas.annotations.Parameter
9+
import io.swagger.v3.oas.annotations.media.ExampleObject
810
import io.swagger.v3.oas.annotations.tags.Tag
911
import io.tolgee.activity.ActivityService
12+
import io.tolgee.exceptions.NotFoundException
13+
import io.tolgee.hateoas.activity.ModifiedEntityModel
14+
import io.tolgee.hateoas.activity.ModifiedEntityModelAssembler
1015
import io.tolgee.hateoas.activity.ProjectActivityModel
1116
import io.tolgee.hateoas.activity.ProjectActivityModelAssembler
1217
import io.tolgee.model.enums.Scope
18+
import io.tolgee.model.views.activity.ModifiedEntityView
1319
import io.tolgee.model.views.activity.ProjectActivityView
1420
import io.tolgee.security.ProjectHolder
1521
import io.tolgee.security.authentication.AllowApiAccess
@@ -21,7 +27,9 @@ import org.springframework.hateoas.MediaTypes
2127
import org.springframework.hateoas.PagedModel
2228
import org.springframework.web.bind.annotation.CrossOrigin
2329
import org.springframework.web.bind.annotation.GetMapping
30+
import org.springframework.web.bind.annotation.PathVariable
2431
import org.springframework.web.bind.annotation.RequestMapping
32+
import org.springframework.web.bind.annotation.RequestParam
2533
import org.springframework.web.bind.annotation.RestController
2634

2735
@Suppress("MVCPathVariableInspection", "SpringJavaInjectionPointsAutowiringInspection")
@@ -32,8 +40,10 @@ import org.springframework.web.bind.annotation.RestController
3240
class ProjectActivityController(
3341
private val activityService: ActivityService,
3442
private val projectHolder: ProjectHolder,
35-
private val pagedResourcesAssembler: PagedResourcesAssembler<ProjectActivityView>,
43+
private val activityPagedResourcesAssembler: PagedResourcesAssembler<ProjectActivityView>,
44+
private val modificationResourcesAssembler: PagedResourcesAssembler<ModifiedEntityView>,
3645
private val projectActivityModelAssembler: ProjectActivityModelAssembler,
46+
private val modifiedEntityModelAssembler: ModifiedEntityModelAssembler,
3747
) {
3848
@Operation(summary = "Get project activity")
3949
@GetMapping("", produces = [MediaTypes.HAL_JSON_VALUE])
@@ -42,7 +52,43 @@ class ProjectActivityController(
4252
fun getActivity(
4353
@ParameterObject pageable: Pageable,
4454
): PagedModel<ProjectActivityModel> {
45-
val views = activityService.getProjectActivity(projectId = projectHolder.project.id, pageable)
46-
return pagedResourcesAssembler.toModel(views, projectActivityModelAssembler)
55+
val views = activityService.findProjectActivity(projectId = projectHolder.project.id, pageable)
56+
return activityPagedResourcesAssembler.toModel(views, projectActivityModelAssembler)
57+
}
58+
59+
@Operation(summary = "Get one revision data")
60+
@GetMapping("/revisions/{revisionId}", produces = [MediaTypes.HAL_JSON_VALUE])
61+
@RequiresProjectPermissions([Scope.ACTIVITY_VIEW])
62+
@AllowApiAccess
63+
fun getSingleRevision(
64+
@PathVariable revisionId: Long,
65+
): ProjectActivityModel {
66+
val views =
67+
activityService.findProjectActivity(projectId = projectHolder.project.id, revisionId)
68+
?: throw NotFoundException()
69+
return projectActivityModelAssembler.toModel(views)
70+
}
71+
72+
@Operation(summary = "Get modified entities in revision")
73+
@GetMapping("/revisions/{revisionId}/modified-entities")
74+
@RequiresProjectPermissions([Scope.ACTIVITY_VIEW])
75+
fun getModifiedEntitiesByRevision(
76+
@ParameterObject pageable: Pageable,
77+
@PathVariable revisionId: Long,
78+
@Parameter(
79+
description = "Filters results by specific entity class",
80+
examples = [ExampleObject(value = "Key"), ExampleObject(value = "Translation")],
81+
)
82+
@RequestParam(required = false)
83+
filterEntityClass: List<String>?,
84+
): PagedModel<ModifiedEntityModel> {
85+
val page =
86+
activityService.getRevisionModifications(
87+
projectId = projectHolder.project.id,
88+
revisionId,
89+
pageable,
90+
filterEntityClass,
91+
)
92+
return modificationResourcesAssembler.toModel(page, modifiedEntityModelAssembler)
4793
}
4894
}

backend/api/src/main/kotlin/io/tolgee/configuration/PublicConfigurationDTO.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import io.tolgee.dtos.response.PublicBillingConfigurationDTO
88

99
@Suppress("MemberVisibilityCanBePrivate", "unused")
1010
class PublicConfigurationDTO(
11-
@Schema(hidden = true)
12-
properties: TolgeeProperties,
11+
@Schema(hidden = true) properties: TolgeeProperties,
1312
val machineTranslationServices: MtServicesDTO,
1413
val billing: PublicBillingConfigurationDTO,
1514
val version: String,
@@ -34,7 +33,14 @@ class PublicConfigurationDTO(
3433
val postHogApiKey: String? = properties.postHog.apiKey
3534
val postHogHost: String? = properties.postHog.host
3635
val contentDeliveryConfigured: Boolean = properties.contentDelivery.publicUrlPrefix != null
37-
val userSourceField: Boolean = properties.userSourceField
36+
val slack: SlackDTO =
37+
SlackDTO(
38+
enabled = (
39+
properties.slack.signingSecret != null &&
40+
(properties.slack.clientId != null || properties.slack.token != null)
41+
),
42+
connected = properties.slack.token != null,
43+
)
3844

3945
class AuthMethodsDTO(
4046
val github: OAuthPublicConfigDTO,
@@ -64,6 +70,11 @@ class PublicConfigurationDTO(
6470
val defaultEnabledForProject: Boolean,
6571
)
6672

73+
data class SlackDTO(
74+
val enabled: Boolean,
75+
val connected: Boolean,
76+
)
77+
6778
init {
6879
if (authentication) {
6980
authMethods =
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.tolgee.hateoas
2+
3+
class SlackUserInfoModel(
4+
val teamName: String,
5+
val slackName: String?,
6+
val slackId: String,
7+
val slackRealName: String?,
8+
val slackAvatar: String,
9+
)

backend/api/src/main/kotlin/io/tolgee/hateoas/activity/ModifiedEntityModel.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ package io.tolgee.hateoas.activity
33
import io.tolgee.activity.data.ExistenceEntityDescription
44
import io.tolgee.activity.data.PropertyModification
55
import io.tolgee.api.IModifiedEntityModel
6+
import org.springframework.hateoas.RepresentationModel
7+
import org.springframework.hateoas.server.core.Relation
68

9+
@Relation(collectionRelation = "modifiedEntities", itemRelation = "modifiedEntity")
710
data class ModifiedEntityModel(
11+
override val entityClass: String,
812
override val entityId: Long,
913
override val description: Map<String, Any?>? = null,
1014
override var modifications: Map<String, PropertyModification>? = null,
1115
override var relations: Map<String, ExistenceEntityDescription>? = null,
1216
override val exists: Boolean? = null,
13-
) : IModifiedEntityModel
17+
) : IModifiedEntityModel, RepresentationModel<ModifiedEntityModel>()
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.tolgee.hateoas.activity
2+
3+
import io.tolgee.model.views.activity.ModifiedEntityView
4+
import org.springframework.hateoas.server.RepresentationModelAssembler
5+
import org.springframework.stereotype.Component
6+
7+
@Component
8+
class ModifiedEntityModelAssembler : RepresentationModelAssembler<ModifiedEntityView, ModifiedEntityModel> {
9+
override fun toModel(view: ModifiedEntityView): ModifiedEntityModel {
10+
return ModifiedEntityModel(
11+
entityClass = view.entityClass,
12+
entityId = view.entityId,
13+
description = view.description,
14+
modifications = view.modifications,
15+
relations = view.describingRelations,
16+
exists = view.exists,
17+
)
18+
}
19+
}

backend/api/src/main/kotlin/io/tolgee/hateoas/activity/ProjectActivityModelAssembler.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component
1010
@Component
1111
class ProjectActivityModelAssembler(
1212
private val avatarService: AvatarService,
13+
private val modifiedEntityModelAssembler: ModifiedEntityModelAssembler,
1314
) : RepresentationModelAssemblerSupport<ProjectActivityView, ProjectActivityModel>(
1415
ApiKeyController::class.java,
1516
ProjectActivityModel::class.java,
@@ -43,13 +44,7 @@ class ProjectActivityModelAssembler(
4344
?.map { entry ->
4445
entry.key to
4546
entry.value.map {
46-
ModifiedEntityModel(
47-
entityId = it.entityId,
48-
description = it.description,
49-
modifications = it.modifications,
50-
relations = it.describingRelations,
51-
exists = it.exists,
52-
)
47+
modifiedEntityModelAssembler.toModel(it)
5348
}
5449
}?.toMap()
5550
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.tolgee.hateoas.organization.slack
2+
3+
data class ConnectToSlackUrlModel(
4+
val url: String,
5+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.tolgee.hateoas.organization.slack
2+
3+
import org.springframework.hateoas.RepresentationModel
4+
import org.springframework.hateoas.server.core.Relation
5+
6+
@Relation(collectionRelation = "workspaces", itemRelation = "workspace")
7+
open class WorkspaceModel(
8+
val id: Long,
9+
val slackTeamName: String,
10+
val slackTeamId: String,
11+
) : RepresentationModel<WorkspaceModel>()

0 commit comments

Comments
 (0)