Line data Source code
1 : /*
2 : * Copyright (C) 2015 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 : import '../lib/patternfly/patternfly-6-cockpit.scss';
7 : import 'polyfills'; // once per application
8 : import 'cockpit-dark-theme'; // once per page
9 :
10 113 : import cockpit from "cockpit";
11 113 : import React from "react";
12 113 : import { createRoot } from 'react-dom/client';
13 : import { ExclamationCircleIcon } from "@patternfly/react-icons";
14 :
15 : import { EmptyStatePanel } from "cockpit-components-empty-state.jsx";
16 : import { PlotState } from "plot.js";
17 :
18 : import client from "./client";
19 : import { update_plot_state } from "./plot.jsx";
20 : import { StoragePage } from "./pages.jsx";
21 :
22 : import "./storage.scss";
23 :
24 113 : const _ = cockpit.gettext;
25 :
26 113 : class Application extends React.Component {
27 113 : constructor() {
28 113 : super();
29 113 : this.state = { inited: false, slow_init: false, path: cockpit.location.path };
30 113 : this.plot_state = new PlotState();
31 113 : this.on_client_changed = () => { if (!client.busy) this.setState({}); };
32 85 : this.on_navigate = () => { this.setState({ path: cockpit.location.path }) };
33 113 : }
34 :
35 113 : componentDidMount() {
36 113 : client.addEventListener("changed", this.on_client_changed);
37 113 : cockpit.addEventListener("locationchanged", this.on_navigate);
38 112 : client.init(() => { this.setState({ inited: true }) });
39 31 : window.setTimeout(() => { if (!this.state.inited) this.setState({ slow_init: true }); }, 1000);
40 113 : }
41 :
42 0 : componentWillUnmount() {
43 0 : client.removeEventListener("changed", this.on_client_changed);
44 0 : cockpit.removeEventListener("locationchanged", this.on_navigate);
45 0 : }
46 :
47 113 : render() {
48 113 : const { inited, slow_init, path } = this.state;
49 :
50 113 : if (!inited) {
51 113 : if (slow_init)
52 44 : return <EmptyStatePanel loading title={ _("Loading...") } />;
53 : else
54 113 : return null;
55 113 : }
56 :
57 113 : if (client.features == false || client.younger_than("2.6"))
58 24 : return <EmptyStatePanel icon={ExclamationCircleIcon} title={ _("Storage can not be managed on this system.") } />;
59 :
60 : // We maintain the plot state here so that the plots stay
61 : // alive no matter what page is shown.
62 113 : update_plot_state(this.plot_state, client);
63 :
64 113 : return <StoragePage location={path} plot_state={this.plot_state} />;
65 113 : }
66 113 : }
67 :
68 113 : function init() {
69 113 : const root = createRoot(document.getElementById('storage'));
70 113 : root.render(<Application />);
71 113 : document.body.removeAttribute("hidden");
72 :
73 0 : window.addEventListener('beforeunload', event => {
74 0 : if (client.busy) {
75 : // Firefox requires this when the page is in an iframe
76 0 : event.preventDefault();
77 :
78 : // see "an almost cross-browser solution" at
79 : // https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
80 0 : event.returnValue = '';
81 0 : return '';
82 0 : }
83 0 : });
84 113 : }
85 :
86 113 : document.addEventListener("DOMContentLoaded", init);
|