|
1 | 1 | package com.coder.gateway.views
|
2 | 2 |
|
3 |
| -import com.coder.gateway.CoderGatewayBundle |
| 3 | +import com.coder.gateway.models.CoderWorkspacesWizardModel |
4 | 4 | import com.coder.gateway.models.LoginModel
|
5 |
| -import com.coder.gateway.models.UriScheme |
6 |
| -import com.coder.gateway.sdk.CoderClientService |
7 |
| -import com.intellij.credentialStore.CredentialAttributes |
8 |
| -import com.intellij.credentialStore.askPassword |
9 |
| -import com.intellij.ide.IdeBundle |
| 5 | +import com.coder.gateway.views.steps.CoderAuthStepView |
| 6 | +import com.coder.gateway.views.steps.CoderWorkspacesStepView |
| 7 | +import com.coder.gateway.views.steps.CoderWorkspacesWizardStep |
10 | 8 | import com.intellij.openapi.Disposable
|
11 |
| -import com.intellij.openapi.application.ApplicationManager |
12 |
| -import com.intellij.openapi.diagnostic.Logger |
13 |
| -import com.intellij.openapi.ui.DialogPanel |
14 |
| -import com.intellij.openapi.ui.panel.ComponentPanelBuilder |
15 | 9 | import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreenUIManager
|
16 |
| -import com.intellij.ui.IconManager |
17 |
| -import com.intellij.ui.SeparatorComponent |
18 |
| -import com.intellij.ui.components.panels.VerticalLayout |
19 |
| -import com.intellij.ui.dsl.builder.BottomGap |
20 | 10 | import com.intellij.ui.dsl.builder.RightGap
|
21 |
| -import com.intellij.ui.dsl.builder.TopGap |
22 |
| -import com.intellij.ui.dsl.builder.bindIntText |
23 |
| -import com.intellij.ui.dsl.builder.bindItem |
24 |
| -import com.intellij.ui.dsl.builder.bindText |
25 | 11 | import com.intellij.ui.dsl.builder.panel
|
26 |
| -import com.intellij.ui.dsl.builder.toNullableProperty |
27 | 12 | import com.intellij.ui.dsl.gridLayout.HorizontalAlign
|
28 |
| -import com.intellij.util.ui.JBFont |
29 |
| -import com.intellij.util.ui.JBUI |
30 | 13 | import com.intellij.util.ui.components.BorderLayoutPanel
|
31 | 14 | import com.jetbrains.gateway.api.GatewayUI
|
32 | 15 | import kotlinx.coroutines.CoroutineScope
|
33 | 16 | import kotlinx.coroutines.Dispatchers
|
34 |
| -import kotlinx.coroutines.cancel |
35 | 17 | import kotlinx.coroutines.launch
|
36 | 18 | import kotlinx.coroutines.withContext
|
37 | 19 | import java.awt.Component
|
38 | 20 | import javax.swing.JButton
|
39 |
| -import javax.swing.JPanel |
40 | 21 |
|
41 | 22 | class CoderGatewayLoginView : BorderLayoutPanel(), Disposable {
|
42 |
| - private val logger = Logger.getInstance(CoderClientService::class.java) |
43 | 23 | private val cs = CoroutineScope(Dispatchers.Main)
|
44 |
| - private val model = LoginModel() |
45 |
| - private val coderClient: CoderClientService = ApplicationManager.getApplication().getService(CoderClientService::class.java) |
| 24 | + private var steps = arrayListOf<CoderWorkspacesWizardStep>() |
| 25 | + private var currentStep = 0 |
| 26 | + private val model = CoderWorkspacesWizardModel(LoginModel(), emptyList()) |
46 | 27 |
|
47 |
| - private lateinit var loginPanel: DialogPanel |
| 28 | + private lateinit var previousButton: JButton |
| 29 | + private lateinit var nextButton: JButton |
48 | 30 |
|
49 | 31 | init {
|
50 |
| - initView() |
| 32 | + setupWizard() |
51 | 33 | }
|
52 | 34 |
|
53 |
| - private fun initView() { |
| 35 | + private fun setupWizard() { |
54 | 36 | background = WelcomeScreenUIManager.getMainAssociatedComponentBackground()
|
55 |
| - addToCenter(createLoginComponent()) |
| 37 | + |
| 38 | + registerStep(CoderAuthStepView()) |
| 39 | + registerStep(CoderWorkspacesStepView()) |
| 40 | + |
56 | 41 | addToBottom(createBackComponent())
|
| 42 | + |
| 43 | + steps[0].apply { |
| 44 | + onInit(model) |
| 45 | + addToCenter(component) |
| 46 | + updateUI() |
| 47 | + nextButton.text = nextActionText |
| 48 | + previousButton.text = previousActionText |
| 49 | + } |
| 50 | + |
57 | 51 | }
|
58 | 52 |
|
59 |
| - private fun createLoginComponent(): DialogPanel { |
60 |
| - loginPanel = panel { |
61 |
| - indent { |
62 |
| - row { |
63 |
| - label(CoderGatewayBundle.message("gateway.connector.view.login.header.text")).applyToComponent { |
64 |
| - font = JBFont.h3().asBold() |
65 |
| - icon = IconManager.getInstance().getIcon("coder_logo_16.svg", CoderGatewayLoginView::class.java) |
66 |
| - } |
67 |
| - }.topGap(TopGap.SMALL).bottomGap(BottomGap.MEDIUM) |
68 |
| - row { |
69 |
| - cell(ComponentPanelBuilder.createCommentComponent(CoderGatewayBundle.message("gateway.connector.view.login.comment.text"), false, -1, true)) |
70 |
| - } |
71 |
| - row { |
72 |
| - browserLink(CoderGatewayBundle.message("gateway.connector.view.login.documentation.action"), "https://coder.com/docs/coder/latest/workspaces") |
73 |
| - }.bottomGap(BottomGap.MEDIUM) |
74 |
| - row { |
75 |
| - label(CoderGatewayBundle.message("gateway.connector.view.login.scheme.label")) |
76 |
| - comboBox(UriScheme.values().toList()).bindItem(model::uriScheme.toNullableProperty()) |
77 |
| - label(CoderGatewayBundle.message("gateway.connector.view.login.host.label")) |
78 |
| - textField().resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL).bindText(model::host) |
79 |
| - label(CoderGatewayBundle.message("gateway.connector.view.login.port.label")) |
80 |
| - intTextField(0..65536).bindIntText(model::port) |
81 |
| - button(CoderGatewayBundle.message("gateway.connector.view.login.connect.action")) { |
82 |
| - loginPanel.apply() |
83 |
| - model.password = askPassword( |
84 |
| - null, |
85 |
| - CoderGatewayBundle.message("gateway.connector.view.login.credentials.dialog.title"), |
86 |
| - CoderGatewayBundle.message("gateway.connector.view.login.password.label"), |
87 |
| - CredentialAttributes("Coder"), |
88 |
| - false |
89 |
| - ) |
90 |
| - cs.launch { |
91 |
| - val workspaces = withContext(Dispatchers.IO) { |
92 |
| - coderClient.initClientSession(model.uriScheme, model.host, model.port, model.email, model.password!!) |
93 |
| - coderClient.workspaces() |
94 |
| - } |
95 |
| - } |
96 |
| - |
97 |
| - }.applyToComponent { |
98 |
| - background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() |
99 |
| - border = JBUI.Borders.empty(3, 3, 3, 3) |
100 |
| - } |
101 |
| - cell() |
102 |
| - } |
| 53 | + private fun registerStep(step: CoderWorkspacesWizardStep) { |
| 54 | + steps.add(step) |
| 55 | + } |
| 56 | + |
| 57 | + private fun previous() { |
| 58 | + nextButton.isVisible = true |
| 59 | + if (currentStep == 0) { |
| 60 | + GatewayUI.Companion.getInstance().reset() |
| 61 | + } else { |
| 62 | + remove(steps[currentStep].component) |
| 63 | + updateUI() |
| 64 | + |
| 65 | + currentStep-- |
| 66 | + steps[currentStep].apply { |
| 67 | + onInit(model) |
| 68 | + addToCenter(component) |
| 69 | + nextButton.text = nextActionText |
| 70 | + previousButton.text = previousActionText |
| 71 | + } |
| 72 | + } |
| 73 | + } |
103 | 74 |
|
104 |
| - row(CoderGatewayBundle.message("gateway.connector.view.login.email.label")) { |
105 |
| - textField().resizableColumn().bindText(model::email) |
106 |
| - cell() |
| 75 | + private fun next() { |
| 76 | + cs.launch { |
| 77 | + if (currentStep + 1 < steps.size) { |
| 78 | + withContext(Dispatchers.Main) { doNextCallback() } |
| 79 | + remove(steps[currentStep].component) |
| 80 | + updateUI() |
| 81 | + currentStep++ |
| 82 | + steps[currentStep].apply { |
| 83 | + addToCenter(component) |
| 84 | + onInit(model) |
| 85 | + updateUI() |
| 86 | + |
| 87 | + nextButton.text = nextActionText |
| 88 | + previousButton.text = previousActionText |
107 | 89 | }
|
| 90 | + |
| 91 | + nextButton.isVisible = currentStep != steps.size - 1 |
108 | 92 | }
|
109 |
| - }.apply { |
110 |
| - background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() |
111 | 93 | }
|
| 94 | + } |
| 95 | + |
112 | 96 |
|
113 |
| - return loginPanel |
| 97 | + private suspend fun doNextCallback() { |
| 98 | + steps[currentStep].apply { |
| 99 | + component.apply() |
| 100 | + onNext(model) |
| 101 | + } |
114 | 102 | }
|
115 | 103 |
|
116 | 104 | private fun createBackComponent(): Component {
|
117 |
| - return JPanel(VerticalLayout(0)).apply { |
118 |
| - add(SeparatorComponent(0, 0, WelcomeScreenUIManager.getSeparatorColor(), null)) |
119 |
| - add(BorderLayoutPanel().apply { |
120 |
| - border = JBUI.Borders.empty(6, 24, 6, 0) |
121 |
| - addToLeft(JButton(IdeBundle.message("button.back")).apply { |
122 |
| - border = JBUI.Borders.empty(3, 3, 3, 3) |
123 |
| - background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() |
124 |
| - addActionListener { |
125 |
| - GatewayUI.Companion.getInstance().reset() |
126 |
| - } |
127 |
| - }) |
| 105 | + previousButton = JButton() |
| 106 | + nextButton = JButton() |
| 107 | + return panel { |
| 108 | + separator(background = WelcomeScreenUIManager.getSeparatorColor()) |
| 109 | + indent { |
| 110 | + row { |
| 111 | + |
| 112 | + label("").resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL) |
| 113 | + previousButton = button("") { previous() }.horizontalAlign(HorizontalAlign.RIGHT).gap(RightGap.SMALL).applyToComponent { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }.component |
| 114 | + nextButton = button("") { next() }.horizontalAlign(HorizontalAlign.RIGHT).gap(RightGap.SMALL).applyToComponent { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }.component |
| 115 | + } |
| 116 | + }.apply { |
128 | 117 | background = WelcomeScreenUIManager.getMainAssociatedComponentBackground()
|
129 |
| - }) |
| 118 | + } |
| 119 | + |
| 120 | + }.apply { |
130 | 121 | background = WelcomeScreenUIManager.getMainAssociatedComponentBackground()
|
131 | 122 | }
|
132 | 123 | }
|
133 | 124 |
|
134 | 125 | override fun dispose() {
|
135 |
| - cs.cancel() |
| 126 | + steps.clear() |
136 | 127 | }
|
137 | 128 | }
|
138 | 129 |
|
0 commit comments