Skip to content

Commit

Permalink
Restyle LAF (#12)
Browse files Browse the repository at this point in the history
* Logos change

* Coding HTML

* Top bar

* Top bar is fine

* Restyling it

* progressing

* age line

* cosmetics

* Installed list is fine

* Save

* revision list display

* Split up files

* Rev list works

* Details

* Working on details

* Action buttons

* cosmetics

* Describe flyout

* Uninstall confirm flyout

* Working on flyouts

* Fixed the actions working

* Polishing it

* Cosmetics
  • Loading branch information
undera authored Sep 26, 2022
1 parent ea6e4d5 commit 7fd5fcc
Show file tree
Hide file tree
Showing 18 changed files with 1,239 additions and 723 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,13 @@ helm plugin uninstall dashboard

## Support Channels

We have two main channels for supporting the Helm Dashboard users: [Slack community](#TODO) for general conversations
We have two main channels for supporting the Helm Dashboard users: [Slack community](https://komodorkommunity.slack.com/x-p3820586794880-3937175868755-4092688791734/archives/C042U85BD45/p1663573506220839) for general conversations
and [GitHub issues](https://github.com/komodorio/helm-dashboard/issues) for real bugs.

## Roadmap

### First Public Version

- Helm Plugin Packaging
- CLI launcher
- Web Server with REST API
- Listing the installed applications
Expand All @@ -64,7 +63,12 @@ and [GitHub issues](https://github.com/komodorio/helm-dashboard/issues) for real
- Switch clusters
- Show manifest/describe upon clicking on resource

- Helm Plugin Packaging
- Styled properly

### Further Ideas
- solve umbrella-chart case
- use `--dry-run` instead of `template`
- Have cleaner idea on the web API structure
- Recognise & show ArgoCD-originating charts/objects, those `helm ls` does not show
- Recognise the revisions that are rollbacks by their description and mark in timeline
Expand Down
28 changes: 0 additions & 28 deletions pkg/dashboard/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/Masterminds/semver/v3"
"github.com/hexops/gotextdiff"
"github.com/hexops/gotextdiff/myers"
"github.com/hexops/gotextdiff/span"
Expand Down Expand Up @@ -174,41 +173,14 @@ func (d *DataLayer) ChartHistory(namespace string, chartName string) (res []*his
return nil, err
}

var aprev *semver.Version
var cprev *semver.Version
for _, elm := range res {
chartRepoName, curVer, err := chartAndVersion(elm.Chart)
if err != nil {
return nil, err
}
elm.ChartName = chartRepoName
elm.ChartVer = curVer
elm.Action = ""
elm.Updated.Time = elm.Updated.Time.Round(time.Second)

cver, err1 := semver.NewVersion(elm.ChartVer)
aver, err2 := semver.NewVersion(elm.AppVersion)
if err1 == nil && err2 == nil {
if aprev != nil && cprev != nil {
switch {
case aprev.LessThan(aver):
elm.Action = "app_upgrade"
case aprev.GreaterThan(aver):
elm.Action = "app_downgrade"
case cprev.LessThan(cver):
elm.Action = "chart_upgrade"
case cprev.GreaterThan(cver):
elm.Action = "chart_downgrade"
default:
elm.Action = "reconfigure"
}
}
} else {
log.Debugf("Semver parsing errors: %s=%s, %s=%s", elm.ChartVer, err1, elm.AppVersion, err2)
}

aprev = aver
cprev = cver
}

return res, nil
Expand Down
2 changes: 2 additions & 0 deletions pkg/dashboard/helmHandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func (h *HelmHandler) GetCharts(c *gin.Context) {
c.IndentedJSON(http.StatusOK, res)
}

// TODO: helm show chart komodorio/k8s-watcher to get the icon URL

func (h *HelmHandler) Uninstall(c *gin.Context) {
qp, err := getQueryProps(c, false)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion pkg/dashboard/helmTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type historyElement struct {
Description string `json:"description"`
ChartName string `json:"chart_name"`
ChartVer string `json:"chart_ver"`
Action string `json:"action"`
}

type repoChartElement struct {
Expand Down
4 changes: 4 additions & 0 deletions pkg/dashboard/static/action.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
189 changes: 189 additions & 0 deletions pkg/dashboard/static/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
$("#btnUpgradeCheck").click(function () {
const self = $(this)
self.find(".bi-repeat").hide()
self.find(".spinner-border").show()
const repoName = self.data("repo")
$("#btnUpgrade span").text("Checking...")
$.post("/api/helm/repo/update?name=" + repoName).fail(function (xhr) {
reportError("Failed to update chart repo", xhr)
}).done(function () {
self.find(".spinner-border").hide()
self.find(".bi-repeat").show()

checkUpgradeable(self.data("chart"))
$("#btnUpgradeCheck").prop("disabled", true)
})
})


function checkUpgradeable(name) {
$.getJSON("/api/helm/repo/search?name=" + name).fail(function (xhr) {
reportError("Failed to find chart in repo", xhr)
}).done(function (data) {
if (!data) {
return
}

$('#upgradeModalLabel select').empty()
for (let i = 0; i < data.length; i++) {
$('#upgradeModalLabel select').append("<option value='" + data[i].version + "'>" + data[i].version + "</option>")
}

const elm = data[0]
$("#btnUpgradeCheck").data("repo", elm.name.split('/').shift())
$("#btnUpgradeCheck").data("chart", elm.name.split('/').pop())

const verCur = $("#specRev").data("last-chart-ver");
const canUpgrade = isNewerVersion(verCur, elm.version);
$("#btnUpgradeCheck").prop("disabled", false)
if (canUpgrade) {
$("#btnUpgrade span").text("Upgrade to " + elm.version)
} else {
$("#btnUpgrade span").text("No upgrades")
}

$("#btnUpgrade").off("click").click(function () {
popUpUpgrade($(this), verCur, elm)
})
})
}

function popUpUpgrade(self, verCur, elm) {
const name = getHashParam("chart");
let url = "/api/helm/charts/install?namespace=" + getHashParam("namespace") + "&name=" + name + "&chart=" + elm.name;
$('#upgradeModalLabel select').data("url", url)

$("#upgradeModalLabel .name").text(name)
$("#upgradeModalLabel .ver-old").text(verCur)

$('#upgradeModalLabel select').val(elm.version).trigger("change")

const myModal = new bootstrap.Offcanvas(document.getElementById('upgradeModal'), {});
myModal.show()

const btnConfirm = $("#upgradeModal .btn-confirm");
btnConfirm.prop("disabled", true).off('click').click(function () {
console.log("working")
btnConfirm.prop("disabled", true).prepend('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
$.ajax({
url: url + "&version=" + $('#upgradeModalLabel select').val(),
type: 'POST',
}).fail(function (xhr) {
reportError("Failed to upgrade the chart", xhr)
}).done(function (data) {
setHashParam("revision", data.version)
window.location.reload()
})
})
}

$('#upgradeModalLabel select').change(function () {
const self = $(this)

$("#upgradeModalBody").empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
$("#upgradeModal .btn-confirm").prop("disabled", true)
$.get(self.data("url") + "&version=" + self.val()).fail(function (xhr) {
reportError("Failed to get upgrade info", xhr)
}).done(function (data) {
$("#upgradeModalBody").empty();
$("#upgradeModal .btn-confirm").prop("disabled", false)

const targetElement = document.getElementById('upgradeModalBody');
const configuration = {
inputFormat: 'diff', outputFormat: 'side-by-side',
drawFileList: false, showFiles: false, highlight: true,
};
const diff2htmlUi = new Diff2HtmlUI(targetElement, data, configuration);
diff2htmlUi.draw()
$("#upgradeModalBody").prepend("<p>Following changes will happen to cluster:</p>")
if (!data) {
$("#upgradeModalBody").html("No changes will happen to cluster")
}
})
})

const btnConfirm = $("#confirmModal .btn-confirm");
$("#btnUninstall").click(function () {
const chart = getHashParam('chart');
const namespace = getHashParam('namespace');
const revision = $("#specRev").data("last-rev")
$("#confirmModalLabel").html("Uninstall <b class='text-danger'>" + chart + "</b> from namespace <b class='text-danger'>" + namespace + "</b>")
$("#confirmModalBody").empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
btnConfirm.prop("disabled", true).off('click').click(function () {
btnConfirm.prop("disabled", true).append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
const url = "/api/helm/charts?namespace=" + namespace + "&name=" + chart;
$.ajax({
url: url,
type: 'DELETE',
}).fail(function (xhr) {
reportError("Failed to delete the chart", xhr)
}).done(function () {
window.location.href = "/"
})
})

const myModal = new bootstrap.Offcanvas(document.getElementById('confirmModal'));
myModal.show()

let qstr = "name=" + chart + "&namespace=" + namespace + "&revision=" + revision
let url = "/api/helm/charts/resources"
url += "?" + qstr
$.getJSON(url).fail(function (xhr) {
reportError("Failed to get list of resources", xhr)
}).done(function (data) {
$("#confirmModalBody").empty().append("<p>Following resources will be deleted from the cluster:</p>");
btnConfirm.prop("disabled", false)
for (let i = 0; i < data.length; i++) {
const res = data[i]
$("#confirmModalBody").append("<p class='row'><i class='col-sm-3 text-end'>" + res.kind + "</i><b class='col-sm-9'>" + res.metadata.name + "</b></p>")
}
})
})

$("#btnRollback").click(function () {
const chart = getHashParam('chart');
const namespace = getHashParam('namespace');
const revisionNew = $("#btnRollback").data("rev")
const revisionCur = $("#specRev").data("last-rev")
$("#confirmModalLabel").html("Rollback <b class='text-danger'>" + chart + "</b> from revision " + revisionCur + " to " + revisionNew)
$("#confirmModalBody").empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
btnConfirm.prop("disabled", true).off('click').click(function () {
btnConfirm.prop("disabled", true).append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
const url = "/api/helm/charts/rollback?namespace=" + namespace + "&name=" + chart + "&revision=" + revisionNew;
$.ajax({
url: url,
type: 'POST',
}).fail(function (xhr) {
reportError("Failed to rollback the chart", xhr)
}).done(function () {
window.location.reload()
})
})

const myModal = new bootstrap.Offcanvas(document.getElementById('confirmModal'), {});
myModal.show()

let qstr = "name=" + chart + "&namespace=" + namespace + "&revision=" + revisionNew + "&revisionDiff=" + revisionCur
let url = "/api/helm/charts/manifests"
url += "?" + qstr
$.get(url).fail(function (xhr) {
reportError("Failed to get list of resources", xhr)
}).done(function (data) {
$("#confirmModalBody").empty();
$("#confirmModal .btn-confirm").prop("disabled", false)

const targetElement = document.getElementById('confirmModalBody');
const configuration = {
inputFormat: 'diff', outputFormat: 'side-by-side',
drawFileList: false, showFiles: false, highlight: true,
};
const diff2htmlUi = new Diff2HtmlUI(targetElement, data, configuration);
diff2htmlUi.draw()
if (data) {
$("#confirmModalBody").prepend("<p>Following changes will happen to cluster:</p>")
} else {
$("#confirmModalBody").html("<p>No changes will happen to cluster</p>")
}
})
})

Loading

0 comments on commit 7fd5fcc

Please sign in to comment.