LCOV - code coverage report
Current view: top level - pkg/packagekit - history.tsx Coverage Total Hit
Test: cockpit Lines: 90.9 % 66 60
Test Date: 2026-06-17 06:28:00

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2019 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6            1 : 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            1 : import cockpit from "cockpit";
      15              : 
      16            1 : const _ = cockpit.gettext;
      17              : 
      18              : type Packages = PackageKitEntry["packages"];
      19              : 
      20            1 : function formatPkgs(pkgs: Packages) {
      21            1 :     const names = Object.keys(pkgs);
      22            1 :     names.sort();
      23            1 :     return names.map(n => (
      24            1 :         <li key={n}>
      25            1 :             <Tooltip content={ n + " " + pkgs[n] }>
      26            1 :                 <span>{n}</span>
      27            1 :             </Tooltip>
      28            1 :         </li>)
      29            1 :     );
      30            1 : }
      31              : 
      32            0 : 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            1 : 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            1 :     mergeHistory() {
      47            1 :         const history: { time: number; packages: Packages; num_packages: number }[] = [];
      48            1 :         let prevTime: number | undefined;
      49            1 :         let prevPackages: string[] | undefined;
      50              : 
      51            1 :         for (let i = 0; i < this.props.packagekit.length; ++i) {
      52            1 :             const packages = Object.keys(this.props.packagekit[i].packages);
      53            1 :             const time = this.props.packagekit[i].timestamp;
      54            1 :             packages.sort();
      55              : 
      56            0 :             if (prevTime && (time - prevTime) <= 600000 /* 10 mins */ &&
      57            0 :                 prevPackages && packages &&
      58            0 :                 prevPackages.toString() == packages.toString())
      59            0 :                 history.pop();
      60              : 
      61            1 :             history.push({ time, packages: this.props.packagekit[i].packages, num_packages: packages.length });
      62              : 
      63            1 :             if (history.length === 3)
      64            1 :                 break;
      65              : 
      66            1 :             prevPackages = packages;
      67            1 :             prevTime = time;
      68            1 :         }
      69              : 
      70            1 :         return history;
      71            1 :     }
      72              : 
      73            1 :     render() {
      74            1 :         const history = this.mergeHistory();
      75            1 :         if (history.length === 0)
      76            0 :             return null;
      77              : 
      78            1 :         const rows = history.map((update, index) => {
      79            1 :             const pkgcount = (
      80            1 :                 <div className="list-view-pf-additional-info-item">
      81            1 :                     <BundleIcon />
      82            1 :                     { cockpit.format(cockpit.ngettext("$0 package", "$0 packages", update.num_packages), update.num_packages) }
      83            1 :                 </div>);
      84              : 
      85            1 :             const expandedContent = <PackageList packages={update.packages} />;
      86              : 
      87            1 :             return ({
      88            1 :                 props: { key: update.time },
      89            1 :                 columns: [
      90            1 :                     { title: timeformat.dateTime(update.time), props: { className: "history-time" } },
      91            1 :                     { title: pkgcount, props: { className: "history-pkgcount" } },
      92            1 :                 ],
      93            1 :                 initiallyExpanded: index == 0,
      94            1 :                 hasPadding: true,
      95            1 :                 expandedContent
      96            1 :             });
      97            1 :         });
      98              : 
      99            1 :         return (
     100            1 :             <ListingTable aria-label={_("Updates history")}
     101            1 :                           showHeader={false}
     102            1 :                           className="updates-history"
     103            1 :                           columns={[_("Time"), _("History package count")]}
     104            1 :                           rows={rows} />
     105              :         );
     106            1 :     }
     107            1 : }
        

Generated by: LCOV version 2.0-1