Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add project dashboard page #915 - Dashboard with chart WIP
- Loading branch information
Showing
34 changed files
with
1,257 additions
and
111 deletions.
There are no files selected for viewing
100 changes: 100 additions & 0 deletions
100
backend/app/src/main/kotlin/io/tolgee/api/v2/controllers/ProjectStatsController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright (c) 2020. Tolgee | ||
*/ | ||
|
||
package io.tolgee.api.v2.controllers | ||
|
||
import io.swagger.v3.oas.annotations.Operation | ||
import io.swagger.v3.oas.annotations.tags.Tag | ||
import io.tolgee.api.v2.hateoas.project.stats.LanguageStatsModel | ||
import io.tolgee.api.v2.hateoas.project.stats.ProjectStatsModel | ||
import io.tolgee.constants.Message | ||
import io.tolgee.exceptions.NotFoundException | ||
import io.tolgee.model.views.projectStats.ProjectLanguageStatsResultView | ||
import io.tolgee.security.api_key_auth.AccessWithApiKey | ||
import io.tolgee.security.project_auth.AccessWithAnyProjectPermission | ||
import io.tolgee.security.project_auth.ProjectHolder | ||
import io.tolgee.service.ProjectService | ||
import io.tolgee.service.ProjectStatsService | ||
import org.springframework.hateoas.MediaTypes | ||
import org.springframework.web.bind.annotation.CrossOrigin | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
import java.time.LocalDate | ||
|
||
@Suppress("MVCPathVariableInspection") | ||
@RestController | ||
@CrossOrigin(origins = ["*"]) | ||
@RequestMapping(value = ["/v2/projects/{projectId}/stats", "/v2/projects/stats"]) | ||
@Tag(name = "Projects") | ||
class ProjectStatsController( | ||
private val projectStatsService: ProjectStatsService, | ||
private val projectHolder: ProjectHolder, | ||
private val projectService: ProjectService | ||
) { | ||
@Operation(summary = "Returns project stats") | ||
@GetMapping("", produces = [MediaTypes.HAL_JSON_VALUE]) | ||
@AccessWithAnyProjectPermission | ||
@AccessWithApiKey | ||
fun getProjectStats(@PathVariable projectId: Long): ProjectStatsModel { | ||
val projectStats = projectStatsService.getProjectStats(projectId) | ||
val languageStats = projectStatsService.getLanguageStats(projectId) | ||
|
||
val baseLanguage = projectService.getOrCreateBaseLanguage(projectHolder.project.id) | ||
val baseStats = languageStats.find { it.languageId == baseLanguage?.id } | ||
?: throw NotFoundException(Message.BASE_LANGUAGE_NOT_FOUND) | ||
|
||
val nonBaseLanguages = languageStats.filter { it.languageId != baseStats.languageId } | ||
val baseWordsCount = baseStats.translatedWords + baseStats.reviewedWords | ||
|
||
val allNonBaseTotalBaseWords = baseWordsCount * nonBaseLanguages.size | ||
val allNonBaseTotalTranslatedWords = nonBaseLanguages.sumOf { it.translatedWords } | ||
val allNonBaseTotalReviewedWords = nonBaseLanguages.sumOf { it.reviewedWords } | ||
|
||
val translatedPercent = (allNonBaseTotalTranslatedWords.toDouble() / allNonBaseTotalBaseWords) * 100 | ||
val reviewedPercent = (allNonBaseTotalReviewedWords.toDouble() / allNonBaseTotalBaseWords) * 100 | ||
|
||
return ProjectStatsModel( | ||
projectId = projectStats.id, | ||
languageCount = languageStats.size, | ||
keyCount = projectStats.keyCount, | ||
baseWordsCount = baseWordsCount, | ||
translatedPercentage = translatedPercent, | ||
reviewedPercentage = reviewedPercent, | ||
membersCount = projectStats.memberCount, | ||
tagCount = projectStats.tagCount, | ||
languageStats = getSortedLanguageStatModels(languageStats, baseStats) | ||
) | ||
} | ||
|
||
@Operation(summary = "Returns project daily amount of events") | ||
@GetMapping("/daily-activity", produces = [MediaTypes.HAL_JSON_VALUE]) | ||
@AccessWithAnyProjectPermission | ||
@AccessWithApiKey | ||
fun getProjectDailyActivity(@PathVariable projectId: Long): Map<LocalDate, Long> { | ||
return projectStatsService.getProjectDailyActivity(projectId) | ||
} | ||
|
||
private fun getSortedLanguageStatModels( | ||
languageStats: List<ProjectLanguageStatsResultView>, | ||
baseStats: ProjectLanguageStatsResultView | ||
) = languageStats.sortedBy { it.languageName }.sortedBy { it.languageId != baseStats.languageId }.map { | ||
LanguageStatsModel( | ||
languageId = it.languageId, | ||
languageTag = it.languageTag, | ||
languageName = it.languageName, | ||
languageOriginalName = it.languageOriginalName, | ||
languageFlagEmoji = it.languageFlagEmoji, | ||
translatedKeyCount = it.translatedKeys, | ||
translatedWordCount = it.translatedWords, | ||
translatedPercentage = it.translatedWords.toDouble() / | ||
(baseStats.translatedWords + baseStats.reviewedWords) * 100, | ||
reviewedKeyCount = it.reviewedKeys, | ||
reviewedWordCount = it.reviewedWords, | ||
reviewedPercentage = it.reviewedWords.toDouble() / | ||
(baseStats.translatedWords + baseStats.reviewedWords) * 100, | ||
) | ||
} | ||
} |
35 changes: 0 additions & 35 deletions
35
backend/app/src/main/kotlin/io/tolgee/api/v2/controllers/V2ProjectStatsController.kt
This file was deleted.
Oops, something went wrong.
25 changes: 25 additions & 0 deletions
25
backend/app/src/main/kotlin/io/tolgee/api/v2/hateoas/organization/SimpleOrganizationModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package io.tolgee.api.v2.hateoas.organization | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema | ||
import io.tolgee.dtos.Avatar | ||
import io.tolgee.model.Permission | ||
import org.springframework.hateoas.RepresentationModel | ||
import org.springframework.hateoas.server.core.Relation | ||
|
||
@Relation(collectionRelation = "organizations", itemRelation = "organization") | ||
open class SimpleOrganizationModel( | ||
val id: Long, | ||
|
||
@Schema(example = "Beautiful organization") | ||
val name: String, | ||
|
||
@Schema(example = "btforg") | ||
val slug: String, | ||
|
||
@Schema(example = "This is a beautiful organization full of beautiful and clever people") | ||
val description: String?, | ||
val basePermissions: Permission.ProjectPermissionType, | ||
|
||
@Schema(example = "Links to avatar images") | ||
var avatar: Avatar? | ||
) : RepresentationModel<SimpleOrganizationModel>() |
27 changes: 27 additions & 0 deletions
27
...src/main/kotlin/io/tolgee/api/v2/hateoas/organization/SimpleOrganizationModelAssembler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.tolgee.api.v2.hateoas.organization | ||
|
||
import io.tolgee.api.v2.controllers.OrganizationController | ||
import io.tolgee.model.Organization | ||
import io.tolgee.service.AvatarService | ||
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport | ||
import org.springframework.hateoas.server.mvc.linkTo | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class SimpleOrganizationModelAssembler( | ||
private val avatarService: AvatarService | ||
) : RepresentationModelAssemblerSupport<Organization, SimpleOrganizationModel>( | ||
OrganizationController::class.java, SimpleOrganizationModel::class.java | ||
) { | ||
override fun toModel(entity: Organization): SimpleOrganizationModel { | ||
val link = linkTo<OrganizationController> { get(entity.slug ?: "") }.withSelfRel() | ||
return SimpleOrganizationModel( | ||
entity.id, | ||
entity.name!!, | ||
entity.slug!!, | ||
entity.description, | ||
entity.basePermissions, | ||
avatarService.getAvatarLinks(entity.avatarHash) | ||
).add(link) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 0 additions & 17 deletions
17
backend/app/src/main/kotlin/io/tolgee/api/v2/hateoas/project/ProjectStatsModel.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
backend/app/src/main/kotlin/io/tolgee/api/v2/hateoas/project/stats/LanguageStatsModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.tolgee.api.v2.hateoas.project.stats | ||
|
||
open class LanguageStatsModel( | ||
val languageId: Long?, | ||
val languageTag: String?, | ||
val languageName: String?, | ||
val languageOriginalName: String?, | ||
val languageFlagEmoji: String?, | ||
val translatedKeyCount: Long, | ||
val translatedWordCount: Long, | ||
val translatedPercentage: Double, | ||
val reviewedKeyCount: Long, | ||
val reviewedWordCount: Long, | ||
val reviewedPercentage: Double, | ||
) |
14 changes: 14 additions & 0 deletions
14
backend/app/src/main/kotlin/io/tolgee/api/v2/hateoas/project/stats/ProjectStatsModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.tolgee.api.v2.hateoas.project.stats | ||
|
||
@Suppress("unused") | ||
open class ProjectStatsModel( | ||
val projectId: Long, | ||
val languageCount: Int, | ||
val keyCount: Long, | ||
val baseWordsCount: Long, | ||
val translatedPercentage: Double, | ||
val reviewedPercentage: Double, | ||
val membersCount: Long, | ||
val tagCount: Long, | ||
val languageStats: List<LanguageStatsModel> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.