* Copyright (C) 2022 Red Hat, Inc.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
import React, { useState, useEffect } from 'react';
import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/index.js";
import { PowerOffIcon, RedoIcon } from "@patternfly/react-icons";
import * as timeformat from "timeformat";
import cockpit from "cockpit";
import "./shutdownStatus.scss";
const _ = cockpit.gettext;
const getScheduledShutdown = (setShutdownTime: (t: number) => void, setShutdownType: (t: string) => void) => {
const client = cockpit.dbus("org.freedesktop.login1");
return client.call("/org/freedesktop/login1", "org.freedesktop.DBus.Properties", "Get",
["org.freedesktop.login1.Manager", "ScheduledShutdown"], { type: "ss" })
.then(([result]) => {
const [type, time] = (result as cockpit.Variant).v as [string, number];
setShutdownType(type);
setShutdownTime(time);
})
.catch(err => console.warn("Failed to get ScheduledShutdown property", err.toString()));
};
const cancelShutdownAction = () => {
const client = cockpit.dbus("org.freedesktop.login1", { superuser: "try" });
return client.call("/org/freedesktop/login1", "org.freedesktop.login1.Manager", "CancelScheduledShutdown")
.then(([cancelled]) => {
if (!cancelled) {
console.warn("Unable to cancel shutdown");
}
})
.catch(err => console.warn("Failed to cancel shutdown", err.toString()));
};
export const ShutDownStatus = () => {
const [shutdownType, setShutdownType] = useState<string | null>(null);
const [shutdownTime, setShutdownTime] = useState<number | null>(0);
useEffect(() => {
getScheduledShutdown(setShutdownTime, setShutdownType);
cockpit.file("/run/systemd/shutdown/scheduled").watch(() => {
getScheduledShutdown(setShutdownTime, setShutdownType);
});
}, []);
if (shutdownType !== "poweroff" && shutdownType !== "reboot") {
if (shutdownType !== null && shutdownType !== "") {
console.log(`unsupported shutdown type ${shutdownType}`);
}
return null;
}
let displayDate = null;
if (shutdownTime) {
const date = new Date(shutdownTime / 1000);
const now = new Date();
if (date.getFullYear() === now.getFullYear()) {
displayDate = timeformat.dateTimeNoYear(date);
} else {
displayDate = timeformat.dateTime(date);
}
}
let text;
let cancelText;
let icon;
if (shutdownType === "poweroff") {
icon = <PowerOffIcon className="shutdown-status-poweroff-icon" />;
text = _("Scheduled poweroff at $0");
cancelText = _("Cancel poweroff");
} else {
icon = <RedoIcon className="reboot-status-poweroff-icon" />;
text = _("Scheduled reboot at $0");
cancelText = _("Cancel reboot");
}
return (
<li id="system-health-shutdown-status">
<Flex flexWrap={{ default: 'nowrap' }}>
<FlexItem>{icon}</FlexItem>
<Flex id="system-health-shutdown-status-text" spaceItems={{ default: 'spaceItemsNone' }} direction={{ default: 'column' }}>
{cockpit.format(text, displayDate)}
<FlexItem>
<Button variant="link" isInline
id="system-health-shutdown-status-cancel-btn"
className="pf-v6-u-font-size-sm"
onClick={cancelShutdownAction}>
{cancelText}
</Button>
</FlexItem>
</Flex>
</Flex>
</li>);
};