LCOV - code coverage report
Current view: top level - pkg/packagekit - history.tsx Coverage Total Hit
Test: cockpit Lines: 100.0 % 66 66
Test Date: 2026-07-17 12:03:54

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2019 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6           19 : import React from "react";
       7              : 
       8              : import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip/index.js";
       9              : import { BundleIcon } from "@patternfly/react-icons";
      10              : import { ListingTable } from "cockpit-components-table.jsx";
      11              : import type { History as PackageKitEntry } from "_internal/packagemanager-abstract";
      12              : import * as timeformat from "timeformat";
      13              : 
      14           19 : import cockpit from "cockpit";
      15              : 
      16           19 : const _ = cockpit.gettext;
      17              : 
      18              : type Packages = PackageKitEntry["packages"];
      19              : 
      20            9 : function formatPkgs(pkgs: Packages) {
      21            9 :     const names = Object.keys(pkgs);
      22            9 :     names.sort();
      23            9 :     return names.map(n => (
      24            9 :         <li key={n}>
      25            9 :             <Tooltip content={ n + " " + pkgs[n] }>
      26            9 :                 <span>{n}</span>
      27            9 :             </Tooltip>
      28            9 :         </li>)
      29            9 :     );
      30            9 : }
      31              : 
      32            1 : export const PackageList = ({ packages }: { packages?: Packages }) => packages ? <ul className='flow-list'>{formatPkgs(packages)}</ul> : null;
      33              : 
      34              : interface HistoryProps {
      35              :     packagekit: PackageKitEntry[];
      36              : }
      37              : 
      38           19 : export class History extends React.Component<HistoryProps> {
      39              :     /* Some PackageKit transactions come in pairs with identical package list,
      40              :      * but different versions. This is an internal technicality, merge them
      41              :      * together for presentation.
      42              :      *
      43              :      * Returns a time sorted (descending) list of objects like
      44              :      * { time: timestamp, num_packages: 2, packages: {names...}}
      45              :      */
      46            7 :     mergeHistory() {
      47            7 :         const history: { time: number; packages: Packages; num_packages: number }[] = [];
      48            7 :         let prevTime: number | undefined;
      49            7 :         let prevPackages: string[] | undefined;
      50              : 
      51            7 :         for (let i = 0; i < this.props.packagekit.length; ++i) {
      52            7 :             const packages = Object.keys(this.props.packagekit[i].packages);
      53            7 :             const time = this.props.packagekit[i].timestamp;
      54            7 :             packages.sort();
      55              : 
      56            2 :             if (prevTime && (time - prevTime) <= 600000 /* 10 mins */ &&
      57            2 :                 prevPackages && packages &&
      58            2 :                 prevPackages.toString() == packages.toString())
      59            1 :                 history.pop();
      60              : 
      61            7 :             history.push({ time, packages: this.props.packagekit[i].packages, num_packages: packages.length });
      62              : 
      63            7 :             if (history.length === 3)
      64            7 :                 break;
      65              : 
      66            7 :             prevPackages = packages;
      67            7 :             prevTime = time;
      68            7 :         }
      69              : 
      70            7 :         return history;
      71            7 :     }
      72              : 
      73            7 :     render() {
      74            7 :         const history = this.mergeHistory();
      75            7 :         if (history.length === 0)
      76            1 :             return null;
      77              : 
      78            7 :         const rows = history.map((update, index) => {
      79            7 :             const pkgcount = (
      80            7 :                 <div className="list-view-pf-additional-info-item">
      81            7 :                     <BundleIcon />
      82            7 :                     { cockpit.format(cockpit.ngettext("$0 package", "$0 packages", update.num_packages), update.num_packages) }
      83            7 :                 </div>);
      84              : 
      85            7 :             const expandedContent = <PackageList packages={update.packages} />;
      86              : 
      87            7 :             return ({
      88            7 :                 props: { key: update.time },
      89            7 :                 columns: [
      90            7 :                     { title: timeformat.dateTime(update.time), props: { className: "history-time" } },
      91            7 :                     { title: pkgcount, props: { className: "history-pkgcount" } },
      92            7 :                 ],
      93            7 :                 initiallyExpanded: index == 0,
      94            7 :                 hasPadding: true,
      95            7 :                 expandedContent
      96            7 :             });
      97            7 :         });
      98              : 
      99            7 :         return (
     100            7 :             <ListingTable aria-label={_("Updates history")}
     101            7 :                           showHeader={false}
     102            7 :                           className="updates-history"
     103            7 :                           columns={[_("Time"), _("History package count")]}
     104            7 :                           rows={rows} />
     105              :         );
     106            7 :     }
     107           19 : }
        

Generated by: LCOV version 2.0-1