+
+ );
+}
+
+function UpdatesList(props) {
+ var updates = [];
+
+ // PackageKit doesn"t expose source package names, so group packages with the same version and changelog
+ // create a reverse version+changes → [id] map on iteration
+ var sameUpdate = {};
+ var packageNames = {};
+ Object.keys(props.updates).forEach(id => {
+ let u = props.updates[id];
+ // did we already see the same version and description? then merge
+ let hash = u.version + u.description;
+ let seenId = sameUpdate[hash];
+ if (seenId) {
+ packageNames[seenId].push(u.name);
+ } else {
+ // this is a new update
+ sameUpdate[hash] = id;
+ packageNames[id] = [u.name];
+ updates.push(id);
+ }
+ });
+
+ // sort security first
+ updates.sort((a, b) => {
+ if (props.updates[a].security && !props.updates[b].security)
+ return -1;
+ if (!props.updates[a].security && props.updates[b].security)
+ return 1;
+ return a.localeCompare(b);
+ });
+
+ return (
+
+
+
+ {_("Cockpit itself will be updated.")}
+
+ {_("When you get disconnected, the updates will continue in the background. You can reconnect and resume watching the update progress.")}
+
+
+ : null
+ }
+
+
+ );
+
+ case "loadError":
+ case "updateError":
+ return this.state.errorMessages.map(m =>
{m}
);
+
+ case "applying":
+ return
+
+ case "uptodate":
+ return (
+