| |
@@ -29,6 +29,12 @@
|
| |
"vmware": "VMware",
|
| |
"openstack": "OpenStack"
|
| |
}
|
| |
+ // innerText of tab button
|
| |
+ const tabInnerText = {
|
| |
+ "cloud_launchable": "Cloud Launchable",
|
| |
+ "metal_virt": "Bare Metal & Virtualized",
|
| |
+ "cloud_operator": "For Cloud Operators"
|
| |
+ }
|
| |
function getMember(obj, member) {
|
| |
return (member in obj) ? obj[member] : null;
|
| |
}
|
| |
@@ -66,9 +72,9 @@
|
| |
downloads[download] = entry;
|
| |
}
|
| |
}
|
| |
-
|
| |
var coreos_download_app = new Vue({
|
| |
el: '#coreos-download-app',
|
| |
+ created: function() { this.refreshStream() },
|
| |
data: {
|
| |
// currently selected stream
|
| |
stream: 'testing',
|
| |
@@ -86,19 +92,103 @@
|
| |
virtualized: {},
|
| |
cloud: {}
|
| |
},
|
| |
- // innerText of tab button
|
| |
- tabInnerText: {
|
| |
- cloud_launchable: "Cloud Launchable",
|
| |
- metal_virt: "Bare Metal & Virtualized",
|
| |
- cloud_operator: "For Cloud Operators"
|
| |
- }
|
| |
},
|
| |
- created: function() { this.refreshStream() },
|
| |
- watch: { stream: 'refreshStream' },
|
| |
+ watch: { stream: function() {
|
| |
+ this.refreshStream();
|
| |
+ } },
|
| |
methods: {
|
| |
getObjectUrl: function(path) {
|
| |
return getArtifactUrl(this.streamUrl, path);
|
| |
},
|
| |
+ // Adapted from https://stackoverflow.com/a/6109105
|
| |
+ timeSince: function(rfc3339_timestamp) {
|
| |
+ var current = Date.now();
|
| |
+ var timestamp = Date.parse(rfc3339_timestamp);
|
| |
+ var elapsed = current - timestamp;
|
| |
+ var msPerMinute = 60 * 1000;
|
| |
+ var msPerHour = msPerMinute * 60;
|
| |
+ var msPerDay = msPerHour * 24;
|
| |
+ var msPerMonth = msPerDay * 30;
|
| |
+ var msPerYear = msPerDay * 365;
|
| |
+ function stringize(n, s) {
|
| |
+ return n + ` ${s}` + (n == 1 ? "" : "s") + ' ago';
|
| |
+ };
|
| |
+ if (elapsed < msPerMinute) {
|
| |
+ return stringize(Math.floor(elapsed/1000), "second");
|
| |
+ } else if (elapsed < msPerHour) {
|
| |
+ return stringize(Math.floor(elapsed/msPerMinute), "minute");
|
| |
+ } else if (elapsed < msPerDay) {
|
| |
+ return stringize(Math.floor(elapsed/msPerHour), "hour");
|
| |
+ } else if (elapsed < msPerMonth) {
|
| |
+ return stringize(Math.floor(elapsed/msPerDay), "day");
|
| |
+ } else if (elapsed < msPerYear) {
|
| |
+ return stringize(Math.floor(elapsed/msPerMonth), "month");
|
| |
+ } else {
|
| |
+ return stringize(Math.floor(elapsed/msPerYear), "year");
|
| |
+ }
|
| |
+ },
|
| |
+ toggleHidden: function(e) {
|
| |
+ const id_list = ['cloud-launchable', 'metal-virt', 'cloud-operator'];
|
| |
+ switch(e.target.innerText) {
|
| |
+ case tabInnerText.cloud_launchable:
|
| |
+ show_id = 'cloud-launchable';
|
| |
+ id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
+ break;
|
| |
+ case tabInnerText.metal_virt:
|
| |
+ show_id = 'metal-virt';
|
| |
+ id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
+ break;
|
| |
+ case tabInnerText.cloud_operator:
|
| |
+ show_id = 'cloud-operator';
|
| |
+ id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
+ break;
|
| |
+ }
|
| |
+ },
|
| |
+ getNavbar: function(h) {
|
| |
+ cloud_icon = h('i', { class: "fas fa-cloud mr-2" })
|
| |
+ nav_cloud_launchable_btn = h('button', { class: "nav-link active col-12 h-100 overflow-hidden", attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ cloud_icon, tabInnerText.cloud_launchable ]);
|
| |
+ nav_cloud_launchable = h('li', { class: "nav-item col-4" }, [ nav_cloud_launchable_btn ]);
|
| |
+
|
| |
+ server_icon = h('i', { class: "fas fa-server mr-2" })
|
| |
+ nav_metal_virt_btn = h('button', { class: "nav-link col-12 h-100 overflow-hidden", attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ server_icon, tabInnerText.metal_virt ]);
|
| |
+ nav_metal_virt = h('li', { class: "nav-item col-4" }, [ nav_metal_virt_btn ]);
|
| |
+
|
| |
+ cloud_upload_icon = h('i', { class: "fas fa-cloud-upload-alt mr-2" })
|
| |
+ nav_cloud_operator_btn = h('button', { class: "nav-link col-12 h-100 overflow-hidden", attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, [ cloud_upload_icon, tabInnerText.cloud_operator ]);
|
| |
+ nav_cloud_operator = h('li', { class: "nav-item col-4" }, [ nav_cloud_operator_btn ]);
|
| |
+
|
| |
+ navbar = h('ul', { class: "nav nav-tabs" }, [ nav_cloud_launchable, nav_metal_virt, nav_cloud_operator ]);
|
| |
+ return navbar;
|
| |
+ },
|
| |
+ // Add dropdown options of streams
|
| |
+ getStreamName: function(h) {
|
| |
+ if (this.streamData === null) return;
|
| |
+ option_default = h('option', { attrs: { value: "testing", selected: "selected" }}, "testing");
|
| |
+ option_stable = h('option', { attrs: { value: "stable" }}, "stable");
|
| |
+ selectOptions = h('select', {
|
| |
+ class: "mx-1",
|
| |
+ on: {
|
| |
+ change: function(e) {
|
| |
+ coreos_download_app.stream = e.target.value;
|
| |
+ }
|
| |
+ }
|
| |
+ }, [
|
| |
+ option_default,
|
| |
+ option_stable
|
| |
+ ]);
|
| |
+ streamName = h('p', {}, [
|
| |
+ "Stream: ",
|
| |
+ selectOptions,
|
| |
+ " (",
|
| |
+ h('span', {}, [
|
| |
+ h('a', { attrs: { href: this.getObjectUrl(this.stream + '.json') } }, "JSON")
|
| |
+ ]),
|
| |
+ ")",
|
| |
+ (this.streamData.metadata) ? "—" : null,
|
| |
+ (this.streamData.metadata) ? h('span', {}, this.timeSince(this.streamData.metadata['last-modified'])) : null
|
| |
+ ]);
|
| |
+ return streamName;
|
| |
+ },
|
| |
isAws: function(platform) {
|
| |
return platform == "aws";
|
| |
},
|
| |
@@ -194,7 +284,7 @@
|
| |
this.streamUrl = baseUrl
|
| |
fetchStreamData(this.streamUrl, this.stream).then(streamData => {
|
| |
this.loading = false;
|
| |
- this.streamData = streamData;
|
| |
+ this.streamData = Object.entries(streamData).length === 0 && streamData.constructor === Object ? null : streamData;
|
| |
this.loadStreamDisplay();
|
| |
});
|
| |
},
|
| |
@@ -218,82 +308,14 @@
|
| |
return false;
|
| |
}
|
| |
return artifact.downloads[contentType].showSignatureAndSha;
|
| |
- },
|
| |
- // Adapted from https://stackoverflow.com/a/6109105
|
| |
- timeSince: function(rfc3339_timestamp) {
|
| |
- var current = Date.now();
|
| |
- var timestamp = Date.parse(rfc3339_timestamp);
|
| |
- var elapsed = current - timestamp;
|
| |
- var msPerMinute = 60 * 1000;
|
| |
- var msPerHour = msPerMinute * 60;
|
| |
- var msPerDay = msPerHour * 24;
|
| |
- var msPerMonth = msPerDay * 30;
|
| |
- var msPerYear = msPerDay * 365;
|
| |
- function stringize(n, s) {
|
| |
- return n + ` ${s}` + (n == 1 ? "" : "s") + ' ago';
|
| |
- };
|
| |
- if (elapsed < msPerMinute) {
|
| |
- return stringize(Math.floor(elapsed/1000), "second");
|
| |
- } else if (elapsed < msPerHour) {
|
| |
- return stringize(Math.floor(elapsed/msPerMinute), "minute");
|
| |
- } else if (elapsed < msPerDay) {
|
| |
- return stringize(Math.floor(elapsed/msPerHour), "hour");
|
| |
- } else if (elapsed < msPerMonth) {
|
| |
- return stringize(Math.floor(elapsed/msPerDay), "day");
|
| |
- } else if (elapsed < msPerYear) {
|
| |
- return stringize(Math.floor(elapsed/msPerMonth), "month");
|
| |
- } else {
|
| |
- return stringize(Math.floor(elapsed/msPerYear), "year");
|
| |
- }
|
| |
- },
|
| |
- toggleHidden: function(e) {
|
| |
- const id_list = ['cloud-launchable', 'metal-virt', 'cloud-operator'];
|
| |
- switch(e.target.innerText) {
|
| |
- case this.tabInnerText.cloud_launchable:
|
| |
- show_id = 'cloud-launchable';
|
| |
- id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
- break;
|
| |
- case this.tabInnerText.metal_virt:
|
| |
- show_id = 'metal-virt';
|
| |
- id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
- break;
|
| |
- case this.tabInnerText.cloud_operator:
|
| |
- show_id = 'cloud-operator';
|
| |
- id_list.map(id => document.getElementById(id).hidden = (id !== show_id));
|
| |
- break;
|
| |
- }
|
| |
- },
|
| |
- getNavbar: function(h) {
|
| |
- nav_cloud_launchable_btn = h('button', { class: "nav-link active", attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, this.tabInnerText.cloud_launchable);
|
| |
- nav_cloud_launchable = h('li', { class: "nav-item mr-3 ml-3" }, [ nav_cloud_launchable_btn ]);
|
| |
-
|
| |
- nav_metal_virt_btn = h('button', { class: "nav-link", attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, this.tabInnerText.metal_virt);
|
| |
- nav_metal_virt = h('li', { class: "nav-item mr-3" }, [ nav_metal_virt_btn ]);
|
| |
-
|
| |
- nav_cloud_operator_btn = h('button', { class: "nav-link", attrs: { "data-toggle": "tab" }, on: { click: this.toggleHidden } }, this.tabInnerText.cloud_operator);
|
| |
- nav_cloud_operator = h('li', { class: "nav-item" }, [ nav_cloud_operator_btn ]);
|
| |
-
|
| |
- navbar = h('ul', { class: "nav nav-tabs" }, [ nav_cloud_launchable, nav_metal_virt, nav_cloud_operator ]);
|
| |
- return navbar
|
| |
}
|
| |
},
|
| |
render: function(h) {
|
| |
+ var stream_select_container = h('div', { class: "pb-0 pt-3" }, [ h('div', { class: "container" }, [ this.getStreamName(h), this.getNavbar(h) ]) ]);
|
| |
if (this.loading) {
|
| |
- return h('div', {}, "Loading...");
|
| |
+ return h('div', {}, [ stream_select_container, "Loading..."] );
|
| |
}
|
| |
else if (this.streamData) {
|
| |
- streamName = h('p', {}, [
|
| |
- "Stream: ",
|
| |
- h('span', { "class":"font-weight-bold" }, this.streamData.stream),
|
| |
- " (",
|
| |
- h('span', {}, [
|
| |
- h('a', { attrs: { href: this.getObjectUrl(this.streamData.stream + '.json') } }, "JSON")
|
| |
- ]),
|
| |
- ")",
|
| |
- "—",
|
| |
- h('span', {}, this.timeSince(this.streamData.metadata['last-modified']))
|
| |
- ]);
|
| |
-
|
| |
cloudLaunchableTitle = h('h3', { class:"font-weight-light" }, "Cloud Launchable");
|
| |
cloudLaunchableSection = {};
|
| |
cloudLaunchable = {};
|
| |
@@ -314,7 +336,7 @@
|
| |
if (coreos_download_app.isAws(platform)) {
|
| |
if (displayInfo.list) {
|
| |
return h('div', {}, displayInfo.list.map(function(amiInfo) {
|
| |
- return h('div', {}, [
|
| |
+ return h('div', { class: "p-2 m-2" }, [
|
| |
amiInfo.platform ? h('div', { class: "font-weight-bold" }, amiInfo.platform) : null,
|
| |
amiInfo.region ? h('div', {}, [ "(", amiInfo.region, ")" ]) : null,
|
| |
amiInfo.release ? h('div', { class: "ml-2" }, [
|
| |
@@ -372,7 +394,7 @@
|
| |
}, "Verify signature & SHA256")
|
| |
]),
|
| |
coreos_download_app.showSignatureAndSha(imageType, platformFormat, contentType) ? h('div', { class: "bg-gray-100 p-2 my-2" }, [ h('p', {}, [
|
| |
- displayDownloads.sha256 ? h('div', {}, [
|
| |
+ displayDownloads.sha256 ? h('div', { class: "overflow-auto" }, [
|
| |
"SHA256: ",
|
| |
displayDownloads.sha256
|
| |
]) : null,
|
| |
@@ -416,7 +438,7 @@
|
| |
return h('div', {}, Object.entries(displayArtifacts).map(function(entry) {
|
| |
platformFormat = entry[0];
|
| |
displayInfo = entry[1];
|
| |
- return h('div', { class: "my-2" }, [
|
| |
+ return h('div', { class: "p-2 m-2" }, [
|
| |
displayInfo.platform ? h('div', { class: "font-weight-bold" }, displayInfo.platform) : null,
|
| |
displayInfo.extension ? h('div', {}, [ "(", displayInfo.extension, ")" ]) : null,
|
| |
displayInfo.release ? h('div', { class: "ml-2" }, [
|
| |
@@ -446,7 +468,7 @@
|
| |
virtualizedSection = h('div', {}, "No virtualized images found.");
|
| |
}
|
| |
virtualized = h('div', { class: "col-12 py-2 my-2" }, [ virtualizedSection ]);
|
| |
-
|
| |
+
|
| |
if (this.streamDisplay.cloud) {
|
| |
cloudSection = createArtifactsSection(this.streamDisplay.cloud, 'cloud');
|
| |
}
|
| |
@@ -463,17 +485,15 @@
|
| |
])
|
| |
]);
|
| |
|
| |
- let navbar = this.getNavbar(h);
|
| |
-
|
| |
- let bare_metal_container = h('div', { class: "col-12 p-0" }, [ bareMetalTitle, verifyBlurb, bareMetal ]);
|
| |
- let virtualized_container = h('div', { class: "col-12 p-0" }, [ virtualizedTitle, verifyBlurb, virtualized ]);
|
| |
+ let bare_metal_container = h('div', { class: "col-6" }, [ bareMetalTitle, verifyBlurb, bareMetal ]);
|
| |
+ let virtualized_container = h('div', { class: "col-6" }, [ virtualizedTitle, verifyBlurb, virtualized ]);
|
| |
|
| |
- let cloud_launchable_container = h('div', { class: "col-12 py-2 my-2", attrs: { id: "cloud-launchable", hidden: false} }, [ cloudLaunchableTitle, streamName, cloudLaunchable ]);
|
| |
- let metal_virt_container = h('div', { class: "col-12 py-2 my-2", attrs: { id: "metal-virt", hidden: true } }, [ bare_metal_container, virtualized_container ]);
|
| |
+ let cloud_launchable_container = h('div', { class: "col-12 py-2 my-2", attrs: { id: "cloud-launchable", hidden: false} }, [ cloudLaunchableTitle, cloudLaunchable ]);
|
| |
+ let metal_virt_container = h('div', { class: "row col-12 py-2 my-2", attrs: { id: "metal-virt", hidden: true } }, [ bare_metal_container, virtualized_container ]);
|
| |
let cloud_operators_container = h('div', { class: "col-12 py-2 my-2", attrs: { id: "cloud-operator", hidden: true } }, [ cloudTitle, verifyBlurb, cloud ]);
|
| |
|
| |
return h('div', {}, [
|
| |
- navbar,
|
| |
+ stream_select_container,
|
| |
cloud_launchable_container,
|
| |
metal_virt_container,
|
| |
cloud_operators_container
|
| |
Changes towards adding an option through a dropdown menu to select the
stable
stream and fetch the metadata accordingly, based on @abai's work in https://pagure.io/fedora-web/websites/pull-request/78.WIP - testing that fetch failures are handled properly, and will try to split my first commit (2edb366) up to make review easier.
To fully make the downloads page ready for the stable release on Jan 14th, also need to update the description and title of the page.