Wizard: fix FUS collector for wizard

This commit is contained in:
Ilya Kirillov
2020-04-08 16:21:49 +03:00
parent e395844567
commit 7ad7d28d97
7 changed files with 49 additions and 40 deletions
@@ -104,8 +104,8 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
}.isSuccess }.isSuccess
if (success) { if (success) {
val projectCreationStats = ProjectCreationStats( val projectCreationStats = ProjectCreationStats(
wizard.projectTemplate!!.title, wizard.projectTemplate!!.id,
wizard.buildSystemType!!.text wizard.buildSystemType!!.id
) )
WizardStatsService.logDataOnProjectGenerated( WizardStatsService.logDataOnProjectGenerated(
projectCreationStats, projectCreationStats,
@@ -1,8 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep
import com.intellij.ui.components.JBLabel import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBTextField
import com.intellij.ui.layout.panel
import com.intellij.util.ui.JBUI import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats
@@ -24,14 +22,13 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.KotlinNewProjectWizardUIB
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.* import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent
import javax.swing.JComponent import javax.swing.JComponent
class ModuleSettingsComponent( class ModuleSettingsComponent(
private val context: Context, private val context: Context,
uiEditorUsagesStats: UiEditorUsageStats private val uiEditorUsagesStats: UiEditorUsageStats
) : DynamicComponent(context) { ) : DynamicComponent(context) {
private val settingsList = TitledComponentsList(emptyList(), context).asSubComponent() private val settingsList = TitledComponentsList(emptyList(), context).asSubComponent()
private val moduleDependenciesComponent = ModuleDependenciesComponent(context) private val moduleDependenciesComponent = ModuleDependenciesComponent(context)
@@ -64,7 +61,7 @@ class ModuleSettingsComponent(
private fun createTemplatesListComponentForModule(module: Module) = private fun createTemplatesListComponentForModule(module: Module) =
read { availableTemplatesFor(module) }.takeIf { it.isNotEmpty() }?.let { templates -> read { availableTemplatesFor(module) }.takeIf { it.isNotEmpty() }?.let { templates ->
ModuleTemplateComponent(context, module, templates) { ModuleTemplateComponent(context, module, templates, uiEditorUsagesStats) {
updateModule(module) updateModule(module)
component.updateUI() component.updateUI()
} }
@@ -114,6 +111,7 @@ private class ModuleTemplateComponent(
context: Context, context: Context,
private val module: Module, private val module: Module,
templates: List<Template>, templates: List<Template>,
uiEditorUsagesStats: UiEditorUsageStats,
onTemplateChanged: () -> Unit onTemplateChanged: () -> Unit
) : TitledComponent(context) { ) : TitledComponent(context) {
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
@@ -127,6 +125,7 @@ private class ModuleTemplateComponent(
labelText = null, labelText = null,
) { value -> ) { value ->
module.template = value.takeIf { it != NoneTemplate } module.template = value.takeIf { it != NoneTemplate }
uiEditorUsagesStats.moduleTemplateChanged++
changeTemplateDescription(module.template) changeTemplateDescription(module.template)
onTemplateChanged() onTemplateChanged()
}.asSubComponent() }.asSubComponent()
@@ -63,7 +63,7 @@ class TargetsModel(
} }
fun add(module: Module) { fun add(module: Module) {
uiEditorUsagesStats?.modulesCreated?.inc() uiEditorUsagesStats?.let { it.modulesCreated++ }
addToTheTree(module, modifyValue = true, parent = tree.selectedNode ?: root) addToTheTree(module, modifyValue = true, parent = tree.selectedNode ?: root)
context.writeSettings { context.writeSettings {
module.apply { initDefaultValuesForSettings() } module.apply { initDefaultValuesForSettings() }
@@ -80,7 +80,7 @@ class TargetsModel(
fun removeSelected() { fun removeSelected() {
val selectedNode = tree.selectedNode?.takeIf { it.userObject is Module } ?: return val selectedNode = tree.selectedNode?.takeIf { it.userObject is Module } ?: return
uiEditorUsagesStats?.modulesRemoved?.inc() uiEditorUsagesStats?.let { it.modulesRemoved++ }
when (val parent = selectedNode.parent.safeAs<DefaultMutableTreeNode>()?.userObject) { when (val parent = selectedNode.parent.safeAs<DefaultMutableTreeNode>()?.userObject) {
ModulesEditorTree.PROJECT_USER_OBJECT -> { ModulesEditorTree.PROJECT_USER_OBJECT -> {
val index = selectedNode.parent.getIndex(selectedNode) val index = selectedNode.parent.getIndex(selectedNode)
@@ -35,10 +35,6 @@ object ExperimentalFeatures {
val platformVersion = PlatformVersion.getCurrent() ?: return true val platformVersion = PlatformVersion.getCurrent() ?: return true
return platformVersion.platform != PlatformVersion.Platform.ANDROID_STUDIO return platformVersion.platform != PlatformVersion.Platform.ANDROID_STUDIO
} }
override fun onFeatureStatusChanged(enabled: Boolean) {
WizardStatsService.logWizardStatusChanged(isEnabled = enabled)
}
} }
val allFeatures: List<ExperimentalFeature> = listOf( val allFeatures: List<ExperimentalFeature> = listOf(
@@ -14,38 +14,35 @@ interface WizardStats {
} }
data class ProjectCreationStats( data class ProjectCreationStats(
val projectTemplateName: String, val projectTemplateId: String,
val buildSystemType: String val buildSystemType: String
) : WizardStats { ) : WizardStats {
override fun toMap(): Map<String, String> = mapOf( override fun toMap(): Map<String, String> = mapOf(
::projectTemplateName.name to projectTemplateName, "project_template" to projectTemplateId,
::buildSystemType.name to buildSystemType "build_system" to buildSystemType
) )
} }
data class UiEditorUsageStats( data class UiEditorUsageStats(
var modulesCreated: Int = 0, var modulesCreated: Int = 0,
var modulesRemoved: Int = 0, var modulesRemoved: Int = 0,
var moduleTemplatesRemoved: Int = 0, var moduleTemplateChanged: Int = 0
var moduleTemplatesSet: Int = 0
) : WizardStats { ) : WizardStats {
override fun toMap(): Map<String, String> = mapOf( override fun toMap(): Map<String, String> = mapOf(
::modulesCreated.name to modulesCreated.toString(), "modules_created" to modulesCreated.toString(),
::modulesRemoved.name to modulesRemoved.toString(), "modules_removed" to modulesRemoved.toString(),
::moduleTemplatesRemoved.name to moduleTemplatesRemoved.toString(), "module_template_changed" to moduleTemplateChanged.toString()
::moduleTemplatesSet.name to moduleTemplatesSet.toString()
) )
} }
private enum class WizardStatsEvent(@NonNls val text: String) { private enum class WizardStatsEvent(@NonNls val text: String) {
PROJECT_OPEN_BY_HYPERLINK("Wizard opened by hyperlink"), PROJECT_OPEN_BY_HYPERLINK("wizard_opened_by_hyperlink"),
PROJECT_CREATED("Project Created"), PROJECT_CREATED("project_created")
WIZARD_STATE_CHANGE("New Wizard enabled or disable")
} }
object WizardStatsService { object WizardStatsService {
fun logWizardOpenByHyperlink(templateId: String?) { fun logWizardOpenByHyperlink(templateId: String?) {
val data = mapOf("templateId" to (templateId ?: "None")) val data = mapOf("template_id" to (templateId ?: "none"))
log(WizardStatsEvent.PROJECT_OPEN_BY_HYPERLINK, data) log(WizardStatsEvent.PROJECT_OPEN_BY_HYPERLINK, data)
} }
@@ -54,11 +51,6 @@ object WizardStatsService {
log(WizardStatsEvent.PROJECT_CREATED, data) log(WizardStatsEvent.PROJECT_CREATED, data)
} }
fun logWizardStatusChanged(isEnabled: Boolean) {
val data = mapOf("enabled" to isEnabled.toString())
log(WizardStatsEvent.WIZARD_STATE_CHANGE, data)
}
private fun log(event: WizardStatsEvent, data: Map<String, String>) { private fun log(event: WizardStatsEvent, data: Map<String, String>) {
KotlinFUSLogger.log(FUSEventGroups.NewWizard, event.text, data) KotlinFUSLogger.log(FUSEventGroups.NewWizard, event.text, data)
} }
@@ -122,14 +122,28 @@ data class BuildFileData(
@NonNls val buildFileName: String @NonNls val buildFileName: String
) )
enum class BuildSystemType(@Nls override val text: String, val fullText: String = text) : DisplayableSettingItem { enum class BuildSystemType(
GradleKotlinDsl(KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.kotlin")), @Nls override val text: String,
GradleGroovyDsl(KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.groovy")), @NonNls val id: String, // used for FUS, should never be changed
Jps( val fullText: String = text
KotlinNewProjectWizardBundle.message("buildsystem.type.intellij"), ) : DisplayableSettingItem {
KotlinNewProjectWizardBundle.message("buildsystem.type.intellij.full") GradleKotlinDsl(
text = KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.kotlin"),
id = "gradleKotlin"
), ),
Maven(KotlinNewProjectWizardBundle.message("buildsystem.type.maven")) GradleGroovyDsl(
text = KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.groovy"),
id = "gradleGroovy"
),
Jps(
text = KotlinNewProjectWizardBundle.message("buildsystem.type.intellij"),
id = "jps",
fullText = KotlinNewProjectWizardBundle.message("buildsystem.type.intellij.full")
),
Maven(
text = KotlinNewProjectWizardBundle.message("buildsystem.type.maven"),
id = "maven"
)
; ;
@@ -19,8 +19,7 @@ sealed class ProjectTemplate : DisplayableSettingItem {
abstract val description: String abstract val description: String
abstract val suggestedProjectName: String abstract val suggestedProjectName: String
abstract val projectKind: ProjectKind abstract val projectKind: ProjectKind
open val id: String abstract val id: String
get() = this::class.simpleName.toString().removeSuffix("Template").removeSuffix("Project")
private val setsDefaultValues: List<SettingWithValue<*, *>> private val setsDefaultValues: List<SettingWithValue<*, *>>
get() = listOf(KotlinPlugin::projectKind.reference withValue projectKind) get() = listOf(KotlinPlugin::projectKind.reference withValue projectKind)
@@ -137,6 +136,7 @@ private fun ModuleType.createDefaultTarget(
object BackendApplicationProjectTemplate : ProjectTemplate() { object BackendApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.empty.singleplatform.title") override val title = KotlinNewProjectWizardBundle.message("project.template.empty.singleplatform.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.empty.singleplatform.description") override val description = KotlinNewProjectWizardBundle.message("project.template.empty.singleplatform.description")
override val id = "backendApplication"
@NonNls @NonNls
override val suggestedProjectName = "myKotlinJvmProject" override val suggestedProjectName = "myKotlinJvmProject"
@@ -153,6 +153,7 @@ object BackendApplicationProjectTemplate : ProjectTemplate() {
object MultiplatformApplicationProjectTemplate : ProjectTemplate() { object MultiplatformApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.empty.mpp.title") override val title = KotlinNewProjectWizardBundle.message("project.template.empty.mpp.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.empty.mpp.description") override val description = KotlinNewProjectWizardBundle.message("project.template.empty.mpp.description")
override val id = "multiplatformApplication"
@NonNls @NonNls
override val suggestedProjectName = "myKotlinMultiplatformProject" override val suggestedProjectName = "myKotlinMultiplatformProject"
@@ -169,6 +170,7 @@ object MultiplatformApplicationProjectTemplate : ProjectTemplate() {
object ConsoleApplicationProjectTemplate : ProjectTemplate() { object ConsoleApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.empty.jvm.console.title") override val title = KotlinNewProjectWizardBundle.message("project.template.empty.jvm.console.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.empty.jvm.console.description") override val description = KotlinNewProjectWizardBundle.message("project.template.empty.jvm.console.description")
override val id = "consoleApplication"
@NonNls @NonNls
override val suggestedProjectName = "myConsoleApplication" override val suggestedProjectName = "myConsoleApplication"
@@ -190,6 +192,7 @@ object ConsoleApplicationProjectTemplate : ProjectTemplate() {
object MultiplatformLibraryProjectTemplate : ProjectTemplate() { object MultiplatformLibraryProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.mpp.lib.title") override val title = KotlinNewProjectWizardBundle.message("project.template.mpp.lib.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.mpp.lib.description") override val description = KotlinNewProjectWizardBundle.message("project.template.mpp.lib.description")
override val id = "multiplatformLibrary"
@NonNls @NonNls
override val suggestedProjectName = "myMultiplatformLibrary" override val suggestedProjectName = "myMultiplatformLibrary"
@@ -216,6 +219,7 @@ object MultiplatformLibraryProjectTemplate : ProjectTemplate() {
object FullStackWebApplicationProjectTemplate : ProjectTemplate() { object FullStackWebApplicationProjectTemplate : ProjectTemplate() {
override val title: String = KotlinNewProjectWizardBundle.message("project.template.full.stack.title") override val title: String = KotlinNewProjectWizardBundle.message("project.template.full.stack.title")
override val description: String = KotlinNewProjectWizardBundle.message("project.template.full.stack.description") override val description: String = KotlinNewProjectWizardBundle.message("project.template.full.stack.description")
override val id = "fullStackWebApplication"
@NonNls @NonNls
override val suggestedProjectName: String = "myFullStackApplication" override val suggestedProjectName: String = "myFullStackApplication"
@@ -242,6 +246,7 @@ object FullStackWebApplicationProjectTemplate : ProjectTemplate() {
object NativeApplicationProjectTemplate : ProjectTemplate() { object NativeApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.native.console.title") override val title = KotlinNewProjectWizardBundle.message("project.template.native.console.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.native.console.description") override val description = KotlinNewProjectWizardBundle.message("project.template.native.console.description")
override val id = "nativeApplication"
@NonNls @NonNls
override val suggestedProjectName = "myNativeConsoleApp" override val suggestedProjectName = "myNativeConsoleApp"
@@ -268,6 +273,7 @@ object NativeApplicationProjectTemplate : ProjectTemplate() {
object FrontendApplicationProjectTemplate : ProjectTemplate() { object FrontendApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.frontend.title") override val title = KotlinNewProjectWizardBundle.message("project.template.frontend.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.frontend.description") override val description = KotlinNewProjectWizardBundle.message("project.template.frontend.description")
override val id = "frontendApplication"
@NonNls @NonNls
override val suggestedProjectName = "myKotlinJsApplication" override val suggestedProjectName = "myKotlinJsApplication"
@@ -292,6 +298,7 @@ object FrontendApplicationProjectTemplate : ProjectTemplate() {
object MultiplatformMobileApplicationProjectTemplate : ProjectTemplate() { object MultiplatformMobileApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.title") override val title = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.description") override val description = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.description")
override val id = "multiplatformMobileApplication"
@NonNls @NonNls
override val suggestedProjectName = "myIOSApplication" override val suggestedProjectName = "myIOSApplication"
@@ -343,6 +350,7 @@ object MultiplatformMobileApplicationProjectTemplate : ProjectTemplate() {
object MultiplatformMobileLibraryProjectTemplate : ProjectTemplate() { object MultiplatformMobileLibraryProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.lib.title") override val title = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.lib.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.lib.description") override val description = KotlinNewProjectWizardBundle.message("project.template.mpp.mobile.lib.description")
override val id = "multiplatformMobileLibrary"
@NonNls @NonNls
override val suggestedProjectName = "myMppMobileLibrary" override val suggestedProjectName = "myMppMobileLibrary"