AppManager: improve installation status page

* Status is refreshed in the background
* Render release item infos instead of internal names

Change-Id: I63a6082656e4e6772a4b5c734c5dd5c23141f70b
diff --git a/core/installer/app_configs/app_base.cue b/core/installer/app_configs/app_base.cue
index d6332e3..32fc354 100644
--- a/core/installer/app_configs/app_base.cue
+++ b/core/installer/app_configs/app_base.cue
@@ -138,6 +138,7 @@
 #Helm: {
 	name: string
 	dependsOn: [...#ResourceReference] | *[]
+	info: string | *""
 	...
 }
 
@@ -164,12 +165,16 @@
 	_chart: _
 	_values: _
 	_dependencies: [...#ResourceReference] | *[]
+	_info: string | *""
 
 	apiVersion: "helm.toolkit.fluxcd.io/v2beta1"
 	kind: "HelmRelease"
 	metadata: {
 		name: _name
    		namespace: release.namespace
+        annotations: {
+          "dodo.cloud/installer-info": _info
+        }
 	}
 	spec: {
 		interval: "1m0s"
@@ -186,6 +191,7 @@
             _chart: localCharts[r.chart.name]
 			_values: r.values
 			_dependencies: r.dependsOn
+			_info: r.info
 		}
 	}
 }
diff --git a/core/installer/app_configs/app_global_env.cue b/core/installer/app_configs/app_global_env.cue
index 1ae2f4d..ca7e099 100644
--- a/core/installer/app_configs/app_global_env.cue
+++ b/core/installer/app_configs/app_global_env.cue
@@ -97,6 +97,7 @@
 			ingress: {
 				chart: charts.ingress
 				_service: service
+                info: "Generating TLS certificate for https://\(_domain)"
 				values: {
 					domain: _domain
 					ingressClassName: network.ingressClass
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 9ee9671..612f9a7 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -201,6 +201,7 @@
 type Resource struct {
 	Name      string `json:"name"`
 	Namespace string `json:"namespace"`
+	Info      string `json:"info"`
 }
 
 type ReleaseResources struct {
@@ -366,9 +367,13 @@
 }
 
 type helmRelease struct {
-	Metadata Resource `json:"metadata"`
-	Kind     string   `json:"kind"`
-	Status   struct {
+	Metadata struct {
+		Name        string            `json:"name"`
+		Namespace   string            `json:"namespace"`
+		Annotations map[string]string `json:"annotations"`
+	} `json:"metadata"`
+	Kind   string `json:"kind"`
+	Status struct {
 		Conditions []struct {
 			Type   string `json:"type"`
 			Status string `json:"status"`
@@ -384,7 +389,18 @@
 			panic(err) // TODO(gio): handle
 		}
 		if h.Kind == "HelmRelease" {
-			ret = append(ret, h.Metadata)
+			res := Resource{
+				Name:      h.Metadata.Name,
+				Namespace: h.Metadata.Namespace,
+				Info:      fmt.Sprintf("%s/%s", h.Metadata.Namespace, h.Metadata.Name),
+			}
+			if h.Metadata.Annotations != nil {
+				info, ok := h.Metadata.Annotations["dodo.cloud/installer-info"]
+				if ok && len(info) != 0 {
+					res.Info = info
+				}
+			}
+			ret = append(ret, res)
 		}
 	}
 	return ret
diff --git a/core/installer/tasks/release.go b/core/installer/tasks/release.go
index 53e5e74..229d76e 100644
--- a/core/installer/tasks/release.go
+++ b/core/installer/tasks/release.go
@@ -1,7 +1,6 @@
 package tasks
 
 import (
-	"fmt"
 	"time"
 
 	"github.com/giolekva/pcloud/core/installer"
@@ -16,7 +15,7 @@
 }
 
 func newMonitorHelm(mon installer.HelmReleaseMonitor, h installer.Resource) Task {
-	t := newLeafTask(fmt.Sprintf("%s/%s", h.Namespace, h.Name), func() error {
+	t := newLeafTask(h.Info, func() error {
 		for {
 			if ok, err := mon.IsReleased(h.Namespace, h.Name); err == nil && ok {
 				break
diff --git a/core/installer/values-tmpl/dodo-app.cue b/core/installer/values-tmpl/dodo-app.cue
index db8989d..a03566b 100644
--- a/core/installer/values-tmpl/dodo-app.cue
+++ b/core/installer/values-tmpl/dodo-app.cue
@@ -65,6 +65,7 @@
 helm: {
 	softserve: {
 		chart: charts.softserve
+		info: "Installing Git server"
 		values: {
 			serviceType: "ClusterIP"
 			addressPool: ""
@@ -84,6 +85,7 @@
 	}
 	"dodo-app": {
 		chart: charts.dodoApp
+		info: "Installing supervisor"
 		values: {
 			image: {
 				repository: images.dodoApp.fullName
diff --git a/core/installer/values-tmpl/gerrit.cue b/core/installer/values-tmpl/gerrit.cue
index 529d0f3..d89e0c6 100644
--- a/core/installer/values-tmpl/gerrit.cue
+++ b/core/installer/values-tmpl/gerrit.cue
@@ -118,6 +118,7 @@
 helm: {
 	"oauth2-client": {
 		chart: charts.oauth2Client
+		info: "Creating OAuth2 client"
 		values: {
 			name: "gerrit-oauth2-client"
 			secretName: _oauth2ClientCredentials
@@ -129,6 +130,7 @@
 	}
 	"config-renderer": {
 		chart: charts.resourceRenderer
+		info: "Generating Gerrit configuration"
 		values: {
 			name: "config-renderer"
 			secretName: _oauth2ClientCredentials
@@ -205,6 +207,7 @@
 	}
 	gerrit: {
 		chart: charts.gerrit
+		info: "Installing Gerrit server"
 		values: {
 			images: {
 				busybox: {
@@ -306,10 +309,12 @@
 	}
 	"git-volume": {
 		chart: charts.volume
+		info: "Creating disk for Git repositories"
 		values: volumes.git
 	}
 	"log-volume": {
 		chart: charts.volume
+		info: "Creating disk for logging"
 		values: volumes.logs
 	}
 }
diff --git a/core/installer/values-tmpl/jenkins.cue b/core/installer/values-tmpl/jenkins.cue
index 5326c7a..9fce898 100644
--- a/core/installer/values-tmpl/jenkins.cue
+++ b/core/installer/values-tmpl/jenkins.cue
@@ -71,6 +71,7 @@
 helm: {
 	"oauth2-client": {
 		chart: charts.oauth2Client
+		info: "Creating OAuth2 client"
 		values: {
 			name: "oauth2-client"
 			secretName: _oauth2ClientCredentials
@@ -83,6 +84,7 @@
 	}
     jenkins: {
         chart: charts.jenkins
+		info: "Installing Jenkins server"
         values: {
 			fullnameOverride: "jenkins"
 			controller: {
@@ -136,6 +138,7 @@
     }
 	"jenkins-data": {
 		chart: charts.volume
+		info: "Creating disk"
 		values: volumes.jenkins
 	}
 }
diff --git a/core/installer/values-tmpl/matrix.cue b/core/installer/values-tmpl/matrix.cue
index 37103b7..ba2627d 100644
--- a/core/installer/values-tmpl/matrix.cue
+++ b/core/installer/values-tmpl/matrix.cue
@@ -52,6 +52,7 @@
 helm: {
 	"oauth2-client": {
 		chart: charts.oauth2Client
+		info: "Creating OAuth2 client"
 		values: {
 			name: "oauth2-client"
 			secretName: _oauth2ClientSecretName
@@ -68,6 +69,7 @@
 			namespace: release.namespace
 		}]
 		chart: charts.matrix
+		info: "Installing Synapse server"
 		values: {
 			domain: global.domain
 			subdomain: input.subdomain
@@ -97,6 +99,7 @@
 	}
 	postgres: {
 		chart: charts.postgres
+		info: "Installing PostgreSQL"
 		values: {
 			fullnameOverride: "postgres"
 			image: {
diff --git a/core/installer/values-tmpl/pihole.cue b/core/installer/values-tmpl/pihole.cue
index c5f740d..7802599 100644
--- a/core/installer/values-tmpl/pihole.cue
+++ b/core/installer/values-tmpl/pihole.cue
@@ -48,6 +48,7 @@
 helm: {
 	pihole: {
 		chart: charts.pihole
+		info: "Installing Pi-hole server"
 		values: {
 			fullnameOverride: "pihole"
 			persistentVolumeClaim: { // TODO(gio): create volume separately as a dependency
diff --git a/core/installer/values-tmpl/rpuppy.cue b/core/installer/values-tmpl/rpuppy.cue
index 0e40fe9..c452a7e 100644
--- a/core/installer/values-tmpl/rpuppy.cue
+++ b/core/installer/values-tmpl/rpuppy.cue
@@ -47,6 +47,7 @@
 helm: {
 	rpuppy: {
 		chart: charts.rpuppy
+		info: "Installing rPuppy server"
 		values: {
 			image: {
 				repository: images.rpuppy.fullName
diff --git a/core/installer/values-tmpl/soft-serve.cue b/core/installer/values-tmpl/soft-serve.cue
index e2e351b..5c96771 100644
--- a/core/installer/values-tmpl/soft-serve.cue
+++ b/core/installer/values-tmpl/soft-serve.cue
@@ -56,6 +56,7 @@
 helm: {
 	softserve: {
 		chart: charts.softserve
+		info: "Installing SoftServe server"
 		values: {
 			serviceType: "ClusterIP"
 			adminKey: input.adminKey
diff --git a/core/installer/values-tmpl/url-shortener.cue b/core/installer/values-tmpl/url-shortener.cue
index 06ac7e1..a7293d5 100644
--- a/core/installer/values-tmpl/url-shortener.cue
+++ b/core/installer/values-tmpl/url-shortener.cue
@@ -48,6 +48,7 @@
 helm: {
     "url-shortener": {
         chart: charts.urlShortener
+		info: "Installing server"
         values: {
             storage: {
                 size: "1Gi"
diff --git a/core/installer/values-tmpl/vaultwarden.cue b/core/installer/values-tmpl/vaultwarden.cue
index 7d11904..ca471df 100644
--- a/core/installer/values-tmpl/vaultwarden.cue
+++ b/core/installer/values-tmpl/vaultwarden.cue
@@ -33,6 +33,7 @@
 helm: {
 	vaultwarden: {
 		chart: charts.vaultwarden
+		info: "Installing Vaultwarden server"
 		values: {
 			ingressClassName: input.network.ingressClass
 			certificateIssuer: input.network.certificateIssuer
diff --git a/core/installer/values-tmpl/zot.cue b/core/installer/values-tmpl/zot.cue
index f83c671..0c63c76 100644
--- a/core/installer/values-tmpl/zot.cue
+++ b/core/installer/values-tmpl/zot.cue
@@ -67,6 +67,7 @@
 helm: {
 	zot: {
 		chart: charts.zot
+		info: "Installing Zot server"
 		values: {
 			image: {
 				repository: images.zot.fullName
@@ -106,6 +107,7 @@
 	}
 	volume: {
 		chart: charts.volume
+		info: "Creating disk"
 		values: volumes.zot
 	}
 }
diff --git a/core/installer/welcome/appmanager-tmpl/app.html b/core/installer/welcome/appmanager-tmpl/app.html
index b97a187..5ce3534 100644
--- a/core/installer/welcome/appmanager-tmpl/app.html
+++ b/core/installer/welcome/appmanager-tmpl/app.html
@@ -1,7 +1,7 @@
 {{ define "task" }}
 {{ range . }}
 <li aria-busy="{{ eq .Status 1 }}">
-	{{ if eq .Status 3 }}<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none"><circle cx="12" cy="12" r="8" fill="green" fill-opacity="0.25"/><path stroke="green" stroke-width="1.2" d="m8.5 11l2.894 2.894a.15.15 0 0 0 .212 0L19.5 6"/><path stroke="green" stroke-linecap="round" d="M19.358 10.547a7.5 7.5 0 1 1-3.608-5.042"/></g></svg>{{ end }}{{ .Title }}{{ if .Err }} - {{ .Err.Error }} {{ end }}
+	{{ if eq .Status 3 }}<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="black" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59z"/></svg>{{ end }}{{ .Title }}{{ if .Err }} - {{ .Err.Error }} {{ end }}
 	{{ if .Subtasks }}
 	<ul>
    		{{ template "task" .Subtasks }}
@@ -104,7 +104,6 @@
     <ul class="progress">
       {{ template "task" .Task.Subtasks }}
     </ul>
-    <script>setTimeout(() => location.reload(), 3000);</script>
     {{ end }}
   {{ end }}
 
@@ -228,14 +227,40 @@
      {{ end }}
  }
 
- document.getElementById("config-form").addEventListener("submit", (event) => {
-     event.preventDefault();
-     if (event.submitter.id === "submit") {
-         install();
-     } if (event.submitter.id === "uninstall") {
-         uninstall();
-     }
- });
+ const configForm = document.getElementById("config-form");
+ if (configForm) {
+	 configForm.addEventListener("submit", (event) => {
+		 event.preventDefault();
+		 if (event.submitter.id === "submit") {
+			 install();
+		 } if (event.submitter.id === "uninstall") {
+			 uninstall();
+		 }
+	 });
+ }
+
+ {{ if .Task }}
+ async function refresh() {
+	 try {
+		 const resp = await fetch(window.location.href);
+		 if (resp.ok) {
+			 var tmp = document.createElement("html");
+			 tmp.innerHTML = await resp.text();
+			 const progress = tmp.getElementsByClassName("progress")[0];
+			 if (progress) {
+				 document.getElementsByClassName("progress")[0].innerHTML = progress.innerHTML;
+			 } else {
+				 location.reload();
+			 }
+		 }
+	 } catch (error) {
+		 console.log(error);
+	 } finally {
+		 setTimeout(refresh, 3000);
+	 }
+ }
+ setTimeout(refresh, 3000);
+ {{ end }}
 </script>
 
 {{end}}
diff --git a/core/installer/welcome/appmanager-tmpl/base.html b/core/installer/welcome/appmanager-tmpl/base.html
index f1a26b2..759ce87 100644
--- a/core/installer/welcome/appmanager-tmpl/base.html
+++ b/core/installer/welcome/appmanager-tmpl/base.html
@@ -3,7 +3,7 @@
 	<head>
 		<meta charset="utf-8" />
         <link rel="stylesheet" href="/static/pico.2.0.6.min.css">
-        <link rel="stylesheet" type="text/css" href="/static/appmanager.css?v=0.0.1">
+        <link rel="stylesheet" type="text/css" href="/static/appmanager.css?v=0.0.2">
 		<meta name="viewport" content="width=device-width, initial-scale=1" />
 	</head>
 	<body>
diff --git a/core/installer/welcome/appmanager-tmpl/index.html b/core/installer/welcome/appmanager-tmpl/index.html
index 8916a9e..356dc28 100644
--- a/core/installer/welcome/appmanager-tmpl/index.html
+++ b/core/installer/welcome/appmanager-tmpl/index.html
@@ -1,6 +1,6 @@
 {{ define "header" }}
   <form class="search-bar">
-      <input type="search" placeholder="Search" />
+      <input name="search" type="search" placeholder="Search" />
   </form>
 {{ end }}
 
diff --git a/core/installer/welcome/static/appmanager.css b/core/installer/welcome/static/appmanager.css
index d5015f5..2f3564f 100644
--- a/core/installer/welcome/static/appmanager.css
+++ b/core/installer/welcome/static/appmanager.css
@@ -220,3 +220,15 @@
   margin: 0;
   padding: 0;
 }
+
+.progress {
+  padding-left: 0;
+}
+
+.progress ul {
+  padding-left: 15px;
+}
+
+.progress li {
+  list-style-type: none;
+}
diff --git a/core/installer/welcome/static/main.css b/core/installer/welcome/static/main.css
index 76485a1..7c9f8f5 100644
--- a/core/installer/welcome/static/main.css
+++ b/core/installer/welcome/static/main.css
@@ -114,10 +114,6 @@
 	color: #3a3a3a;
 }
 
-/* .progress { */
-/* 	padding-top: 10px; */
-/* } */
-
 .progress {
 	padding-left: 0;
 }