diff --git a/goosebit/ui/bff/common/columns.py b/goosebit/ui/bff/common/columns.py index 16bf97a8..c7be5ba5 100644 --- a/goosebit/ui/bff/common/columns.py +++ b/goosebit/ui/bff/common/columns.py @@ -134,6 +134,11 @@ class RolloutColumns: searchable=True, orderable=True, ) + compatibility = DTColumnDescription( + title="Compatibility", + data="software.compatibility", + name="software__compatibility", + ) paused = DTColumnDescription( title="Paused", name="paused", diff --git a/goosebit/ui/bff/rollouts/routes.py b/goosebit/ui/bff/rollouts/routes.py index 53f9960d..77b810dd 100644 --- a/goosebit/ui/bff/rollouts/routes.py +++ b/goosebit/ui/bff/rollouts/routes.py @@ -86,6 +86,7 @@ async def devices_get_columns() -> DTColumns: RolloutColumns.feed, RolloutColumns.sw_file, RolloutColumns.sw_version, + RolloutColumns.compatibility, RolloutColumns.paused, RolloutColumns.success_count, RolloutColumns.failure_count, diff --git a/goosebit/ui/static/js/rollouts.js b/goosebit/ui/static/js/rollouts.js index e4ea5f1f..9b1c0331 100644 --- a/goosebit/ui/static/js/rollouts.js +++ b/goosebit/ui/static/js/rollouts.js @@ -1,6 +1,19 @@ let dataTable; const renderFunctions = { + "software.compatibility": (data, type) => { + const result = data.reduce((acc, { model, revision }) => { + if (!acc[model]) { + acc[model] = []; + } + acc[model].push(revision); + return acc; + }, {}); + + return Object.entries(result) + .map(([model, revision]) => `${model} - ${revision.join(", ")}`) + .join("\n"); + }, paused: (data, type) => { if (type === "display") { const color = data ? "danger" : "muted"; diff --git a/goosebit/ui/static/js/util.js b/goosebit/ui/static/js/util.js index e8f8446a..1ef9affe 100644 --- a/goosebit/ui/static/js/util.js +++ b/goosebit/ui/static/js/util.js @@ -46,7 +46,11 @@ async function updateSoftwareSelection(devices = null) { const optionElem = document.createElement("option"); optionElem.value = item.id; optionElem.textContent = `${item.version}`; - const models = [...new Set(item.compatibility.map((item) => item.model))]; + const models = [ + ...new Set( + item.compatibility.map((item) => (item.revision ? `${item.model} - ${item.revision}` : item.model)), + ), + ]; optionElem.textContent = `${item.version} (${models})`; selectElem.appendChild(optionElem); }