ESLint error and warning fixes
This commit is contained in:
parent
b73f42eb38
commit
0089d35bef
3 changed files with 252 additions and 198 deletions
|
|
@ -16,7 +16,6 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
* along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
"use strict";
|
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
|
|
@ -44,10 +43,10 @@ import {
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { ExclamationCircleIcon } from "@patternfly/react-icons";
|
import { ExclamationCircleIcon } from "@patternfly/react-icons";
|
||||||
import { global_danger_color_200 } from "@patternfly/react-tokens";
|
import { global_danger_color_200 } from "@patternfly/react-tokens";
|
||||||
|
import cockpit from 'cockpit';
|
||||||
|
|
||||||
const json = require('comment-json');
|
const json = require('comment-json');
|
||||||
const ini = require('ini');
|
const ini = require('ini');
|
||||||
const cockpit = require('cockpit');
|
|
||||||
const _ = cockpit.gettext;
|
const _ = cockpit.gettext;
|
||||||
|
|
||||||
class GeneralConfig extends React.Component {
|
class GeneralConfig extends React.Component {
|
||||||
|
|
@ -124,15 +123,15 @@ class GeneralConfig extends React.Component {
|
||||||
setConfig(data) {
|
setConfig(data) {
|
||||||
delete data.configuration;
|
delete data.configuration;
|
||||||
delete data.args;
|
delete data.args;
|
||||||
var flattenObject = function(ob) {
|
const flattenObject = function(ob) {
|
||||||
var toReturn = {};
|
const toReturn = {};
|
||||||
|
|
||||||
for (var i in ob) {
|
for (const i in ob) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(ob, i)) continue;
|
if (!Object.prototype.hasOwnProperty.call(ob, i)) continue;
|
||||||
|
|
||||||
if ((typeof ob[i]) == 'object') {
|
if ((typeof ob[i]) == 'object') {
|
||||||
var flatObject = flattenObject(ob[i]);
|
const flatObject = flattenObject(ob[i]);
|
||||||
for (var x in flatObject) {
|
for (const x in flatObject) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(flatObject, x)) continue;
|
if (!Object.prototype.hasOwnProperty.call(flatObject, x)) continue;
|
||||||
|
|
||||||
toReturn[i + '_' + x] = flatObject[x];
|
toReturn[i + '_' + x] = flatObject[x];
|
||||||
|
|
@ -203,13 +202,15 @@ class GeneralConfig extends React.Component {
|
||||||
<TextInput
|
<TextInput
|
||||||
id="shell"
|
id="shell"
|
||||||
value={this.state.shell}
|
value={this.state.shell}
|
||||||
onChange={shell => this.setState({ shell })} />
|
onChange={shell => this.setState({ shell })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Notice")}>
|
<FormGroup label={_("Notice")}>
|
||||||
<TextInput
|
<TextInput
|
||||||
id="notice"
|
id="notice"
|
||||||
value={this.state.notice}
|
value={this.state.notice}
|
||||||
onChange={notice => this.setState({ notice })} />
|
onChange={notice => this.setState({ notice })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Latency")}>
|
<FormGroup label={_("Latency")}>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
@ -217,7 +218,8 @@ class GeneralConfig extends React.Component {
|
||||||
type="number"
|
type="number"
|
||||||
step="1"
|
step="1"
|
||||||
value={this.state.latency}
|
value={this.state.latency}
|
||||||
onChange={latency => this.setState({ latency })} />
|
onChange={latency => this.setState({ latency })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Payload Size, bytes")}>
|
<FormGroup label={_("Payload Size, bytes")}>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
@ -225,24 +227,28 @@ class GeneralConfig extends React.Component {
|
||||||
type="number"
|
type="number"
|
||||||
step="1"
|
step="1"
|
||||||
value={this.state.payload}
|
value={this.state.payload}
|
||||||
onChange={payload => this.setState({ payload })} />
|
onChange={payload => this.setState({ payload })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Logging")}>
|
<FormGroup label={_("Logging")}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="log_input"
|
id="log_input"
|
||||||
isChecked={this.state.log_input}
|
isChecked={this.state.log_input}
|
||||||
onChange={log_input => this.setState({ log_input })}
|
onChange={log_input => this.setState({ log_input })}
|
||||||
label={_("User's Input")} />
|
label={_("User's Input")}
|
||||||
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="log_output"
|
id="log_output"
|
||||||
isChecked={this.state.log_output}
|
isChecked={this.state.log_output}
|
||||||
onChange={log_output => this.setState({ log_output })}
|
onChange={log_output => this.setState({ log_output })}
|
||||||
label={_("User's Output")} />
|
label={_("User's Output")}
|
||||||
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="log_window"
|
id="log_window"
|
||||||
isChecked={this.state.log_window}
|
isChecked={this.state.log_window}
|
||||||
onChange={log_window => this.setState({ log_window })}
|
onChange={log_window => this.setState({ log_window })}
|
||||||
label={_("Window Resize")} />
|
label={_("Window Resize")}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Limit Rate, bytes/sec")}>
|
<FormGroup label={_("Limit Rate, bytes/sec")}>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
@ -250,7 +256,8 @@ class GeneralConfig extends React.Component {
|
||||||
type="number"
|
type="number"
|
||||||
step="1"
|
step="1"
|
||||||
value={this.state.limit_rate}
|
value={this.state.limit_rate}
|
||||||
onChange={limit_rate => this.setState({ limit_rate })} />
|
onChange={limit_rate => this.setState({ limit_rate })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Burst, bytes")}>
|
<FormGroup label={_("Burst, bytes")}>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
@ -258,13 +265,15 @@ class GeneralConfig extends React.Component {
|
||||||
type="number"
|
type="number"
|
||||||
step="1"
|
step="1"
|
||||||
value={this.state.limit_burst}
|
value={this.state.limit_burst}
|
||||||
onChange={limit_burst => this.setState({ limit_burst })} />
|
onChange={limit_burst => this.setState({ limit_burst })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Logging Limit Action")}>
|
<FormGroup label={_("Logging Limit Action")}>
|
||||||
<FormSelect
|
<FormSelect
|
||||||
id="limit_action"
|
id="limit_action"
|
||||||
value={this.state.limit_action}
|
value={this.state.limit_action}
|
||||||
onChange={limit_action => this.setState({ limit_action })}>
|
onChange={limit_action => this.setState({ limit_action })}
|
||||||
|
>
|
||||||
{[
|
{[
|
||||||
{ value: "", label: "" },
|
{ value: "", label: "" },
|
||||||
{ value: "pass", label: _("Pass") },
|
{ value: "pass", label: _("Pass") },
|
||||||
|
|
@ -274,7 +283,8 @@ class GeneralConfig extends React.Component {
|
||||||
<FormSelectOption
|
<FormSelectOption
|
||||||
key={index}
|
key={index}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
label={option.label} />
|
label={option.label}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormSelect>
|
</FormSelect>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
@ -282,21 +292,24 @@ class GeneralConfig extends React.Component {
|
||||||
<TextInput
|
<TextInput
|
||||||
id="file_path"
|
id="file_path"
|
||||||
value={this.state.file_path}
|
value={this.state.file_path}
|
||||||
onChange={file_path => this.setState({ file_path })} />
|
onChange={file_path => this.setState({ file_path })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Syslog Facility")}>
|
<FormGroup label={_("Syslog Facility")}>
|
||||||
<TextInput
|
<TextInput
|
||||||
id="syslog_facility"
|
id="syslog_facility"
|
||||||
value={this.state.syslog_facility}
|
value={this.state.syslog_facility}
|
||||||
onChange={syslog_facility =>
|
onChange={syslog_facility =>
|
||||||
this.setState({ syslog_facility })} />
|
this.setState({ syslog_facility })}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Syslog Priority")}>
|
<FormGroup label={_("Syslog Priority")}>
|
||||||
<FormSelect
|
<FormSelect
|
||||||
id="syslog_priority"
|
id="syslog_priority"
|
||||||
value={this.state.syslog_priority}
|
value={this.state.syslog_priority}
|
||||||
onChange={syslog_priority =>
|
onChange={syslog_priority =>
|
||||||
this.setState({ syslog_priority })}>
|
this.setState({ syslog_priority })}
|
||||||
|
>
|
||||||
{[
|
{[
|
||||||
{ value: "", label: "" },
|
{ value: "", label: "" },
|
||||||
{ value: "info", label: _("Info") },
|
{ value: "info", label: _("Info") },
|
||||||
|
|
@ -304,7 +317,8 @@ class GeneralConfig extends React.Component {
|
||||||
<FormSelectOption
|
<FormSelectOption
|
||||||
key={index}
|
key={index}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
label={option.label} />
|
label={option.label}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormSelect>
|
</FormSelect>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
@ -313,7 +327,8 @@ class GeneralConfig extends React.Component {
|
||||||
id="journal_priority"
|
id="journal_priority"
|
||||||
value={this.state.journal_priority}
|
value={this.state.journal_priority}
|
||||||
onChange={journal_priority =>
|
onChange={journal_priority =>
|
||||||
this.setState({ journal_priority })}>
|
this.setState({ journal_priority })}
|
||||||
|
>
|
||||||
{[
|
{[
|
||||||
{ value: "", label: "" },
|
{ value: "", label: "" },
|
||||||
{ value: "info", label: _("Info") },
|
{ value: "info", label: _("Info") },
|
||||||
|
|
@ -321,7 +336,8 @@ class GeneralConfig extends React.Component {
|
||||||
<FormSelectOption
|
<FormSelectOption
|
||||||
key={index}
|
key={index}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
label={option.label} />
|
label={option.label}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormSelect>
|
</FormSelect>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
@ -331,14 +347,16 @@ class GeneralConfig extends React.Component {
|
||||||
isChecked={this.state.journal_augment}
|
isChecked={this.state.journal_augment}
|
||||||
onChange={journal_augment =>
|
onChange={journal_augment =>
|
||||||
this.setState({ journal_augment })}
|
this.setState({ journal_augment })}
|
||||||
label={_("Augment")} />
|
label={_("Augment")}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={_("Writer")}>
|
<FormGroup label={_("Writer")}>
|
||||||
<FormSelect
|
<FormSelect
|
||||||
id="writer"
|
id="writer"
|
||||||
value={this.state.writer}
|
value={this.state.writer}
|
||||||
onChange={writer =>
|
onChange={writer =>
|
||||||
this.setState({ writer })}>
|
this.setState({ writer })}
|
||||||
|
>
|
||||||
{[
|
{[
|
||||||
{ value: "", label: "" },
|
{ value: "", label: "" },
|
||||||
{ value: "journal", label: _("Journal") },
|
{ value: "journal", label: _("Journal") },
|
||||||
|
|
@ -348,7 +366,8 @@ class GeneralConfig extends React.Component {
|
||||||
<FormSelectOption
|
<FormSelectOption
|
||||||
key={index}
|
key={index}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
label={option.label} />
|
label={option.label}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormSelect>
|
</FormSelect>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
@ -356,7 +375,8 @@ class GeneralConfig extends React.Component {
|
||||||
<Button
|
<Button
|
||||||
id="btn-save-tlog-conf"
|
id="btn-save-tlog-conf"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
onClick={this.handleSubmit}>
|
onClick={this.handleSubmit}
|
||||||
|
>
|
||||||
{_("Save")}
|
{_("Save")}
|
||||||
</Button>
|
</Button>
|
||||||
{this.state.submitting === true && <Spinner size="lg" />}
|
{this.state.submitting === true && <Spinner size="lg" />}
|
||||||
|
|
@ -368,7 +388,8 @@ class GeneralConfig extends React.Component {
|
||||||
<EmptyState variant={EmptyStateVariant.small}>
|
<EmptyState variant={EmptyStateVariant.small}>
|
||||||
<EmptyStateIcon
|
<EmptyStateIcon
|
||||||
icon={ExclamationCircleIcon}
|
icon={ExclamationCircleIcon}
|
||||||
color={global_danger_color_200.value} />
|
color={global_danger_color_200.value}
|
||||||
|
/>
|
||||||
<Title headingLevel="h4" size="lg">
|
<Title headingLevel="h4" size="lg">
|
||||||
{_("There is no configuration file of tlog present in your system.")}
|
{_("There is no configuration file of tlog present in your system.")}
|
||||||
</Title>
|
</Title>
|
||||||
|
|
@ -413,15 +434,15 @@ class SssdConfig extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
restartSSSD() {
|
restartSSSD() {
|
||||||
let sssd_cmd = ["systemctl", "restart", "sssd"];
|
const sssd_cmd = ["systemctl", "restart", "sssd"];
|
||||||
cockpit.spawn(sssd_cmd, { superuser: "require" });
|
cockpit.spawn(sssd_cmd, { superuser: "require" });
|
||||||
this.setState({ submitting: false });
|
this.setState({ submitting: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
confSave(obj) {
|
confSave(obj) {
|
||||||
let chmod_cmd = ["chmod", "600", "/etc/sssd/conf.d/sssd-session-recording.conf"];
|
const chmod_cmd = ["chmod", "600", "/etc/sssd/conf.d/sssd-session-recording.conf"];
|
||||||
/* Update nsswitch, this will fail on RHEL8/F34 and lower as 'with-files-domain' feature is not added there */
|
/* Update nsswitch, this will fail on RHEL8/F34 and lower as 'with-files-domain' feature is not added there */
|
||||||
let authselect_cmd = ["authselect", "select", "sssd", "with-files-domain", "--force"];
|
const authselect_cmd = ["authselect", "select", "sssd", "with-files-domain", "--force"];
|
||||||
this.setState({ submitting: true });
|
this.setState({ submitting: true });
|
||||||
this.file.replace(obj).done(() => {
|
this.file.replace(obj).done(() => {
|
||||||
cockpit.spawn(chmod_cmd, { superuser: "require" })
|
cockpit.spawn(chmod_cmd, { superuser: "require" })
|
||||||
|
|
@ -491,7 +512,8 @@ class SssdConfig extends React.Component {
|
||||||
<FormSelect
|
<FormSelect
|
||||||
id="scope"
|
id="scope"
|
||||||
value={this.state.scope}
|
value={this.state.scope}
|
||||||
onChange={scope => this.setState({ scope })}>
|
onChange={scope => this.setState({ scope })}
|
||||||
|
>
|
||||||
{[
|
{[
|
||||||
{ value: "none", label: _("None") },
|
{ value: "none", label: _("None") },
|
||||||
{ value: "some", label: _("Some") },
|
{ value: "some", label: _("Some") },
|
||||||
|
|
@ -500,7 +522,8 @@ class SssdConfig extends React.Component {
|
||||||
<FormSelectOption
|
<FormSelectOption
|
||||||
key={index}
|
key={index}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
label={option.label} />
|
label={option.label}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</FormSelect>
|
</FormSelect>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
@ -542,7 +565,8 @@ class SssdConfig extends React.Component {
|
||||||
<Button
|
<Button
|
||||||
id="btn-save-sssd-conf"
|
id="btn-save-sssd-conf"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
onClick={this.handleSubmit}>
|
onClick={this.handleSubmit}
|
||||||
|
>
|
||||||
{_("Save")}
|
{_("Save")}
|
||||||
</Button>
|
</Button>
|
||||||
{this.state.submitting === true && <Spinner size="lg" />}
|
{this.state.submitting === true && <Spinner size="lg" />}
|
||||||
|
|
@ -577,7 +601,8 @@ groupProps={{ sticky: 'top' }}
|
||||||
{_("Settings")}
|
{_("Settings")}
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
}>
|
}
|
||||||
|
>
|
||||||
<PageSection>
|
<PageSection>
|
||||||
<Flex className="config-container">
|
<Flex className="config-container">
|
||||||
<GeneralConfig />
|
<GeneralConfig />
|
||||||
|
|
|
||||||
222
src/player.jsx
222
src/player.jsx
|
|
@ -16,7 +16,6 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
* along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
"use strict";
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './player.css';
|
import './player.css';
|
||||||
import { Terminal as Term } from 'xterm';
|
import { Terminal as Term } from 'xterm';
|
||||||
|
|
@ -55,9 +54,9 @@ import {
|
||||||
MigrationIcon,
|
MigrationIcon,
|
||||||
} from '@patternfly/react-icons';
|
} from '@patternfly/react-icons';
|
||||||
|
|
||||||
|
import cockpit from 'cockpit';
|
||||||
import { journal } from 'journal';
|
import { journal } from 'journal';
|
||||||
|
|
||||||
const cockpit = require("cockpit");
|
|
||||||
const _ = cockpit.gettext;
|
const _ = cockpit.gettext;
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
|
|
||||||
|
|
@ -77,8 +76,8 @@ const padInt = function (n, w) {
|
||||||
*/
|
*/
|
||||||
const formatDateTime = function (ms) {
|
const formatDateTime = function (ms) {
|
||||||
/* Convert local timezone offset */
|
/* Convert local timezone offset */
|
||||||
let t = new Date(ms);
|
const t = new Date(ms);
|
||||||
let z = t.getTimezoneOffset() * 60 * 1000;
|
const z = t.getTimezoneOffset() * 60 * 1000;
|
||||||
let tLocal = t - z;
|
let tLocal = t - z;
|
||||||
tLocal = new Date(tLocal);
|
tLocal = new Date(tLocal);
|
||||||
let iso = tLocal.toISOString();
|
let iso = tLocal.toISOString();
|
||||||
|
|
@ -243,11 +242,10 @@ const PacketBuffer = class {
|
||||||
* Get an object field, verifying its presence and type.
|
* Get an object field, verifying its presence and type.
|
||||||
*/
|
*/
|
||||||
getValidField(object, field, type) {
|
getValidField(object, field, type) {
|
||||||
let value;
|
|
||||||
if (!(field in object)) {
|
if (!(field in object)) {
|
||||||
this.reportError("\"" + field + "\" field is missing");
|
this.reportError("\"" + field + "\" field is missing");
|
||||||
}
|
}
|
||||||
value = object[field];
|
const value = object[field];
|
||||||
if (typeof (value) != typeof (type)) {
|
if (typeof (value) != typeof (type)) {
|
||||||
this.reportError("invalid \"" + field + "\" field type: " + typeof (value));
|
this.reportError("invalid \"" + field + "\" field type: " + typeof (value));
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +292,7 @@ const PacketBuffer = class {
|
||||||
/* Try to find an existing, matching tuple */
|
/* Try to find an existing, matching tuple */
|
||||||
for (i = 0; i < this.idxDfdList.length; i++) {
|
for (i = 0; i < this.idxDfdList.length; i++) {
|
||||||
idxDfd = this.idxDfdList[i];
|
idxDfd = this.idxDfdList[i];
|
||||||
if (idxDfd[0] == idx) {
|
if (idxDfd[0] === idx) {
|
||||||
return idxDfd[1].promise();
|
return idxDfd[1].promise();
|
||||||
} else if (idxDfd[0] > idx) {
|
} else if (idxDfd[0] > idx) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -394,7 +392,7 @@ const PacketBuffer = class {
|
||||||
matches = this.timingRE.exec(timing);
|
matches = this.timingRE.exec(timing);
|
||||||
if (matches === null) {
|
if (matches === null) {
|
||||||
this.reportError(_("invalid timing string"));
|
this.reportError(_("invalid timing string"));
|
||||||
} else if (matches[0] == "") {
|
} else if (matches[0] === "") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,14 +401,14 @@ const PacketBuffer = class {
|
||||||
/* Delay */
|
/* Delay */
|
||||||
case "+":
|
case "+":
|
||||||
x = parseInt(matches[1], 10);
|
x = parseInt(matches[1], 10);
|
||||||
if (x == 0) {
|
if (x === 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (io.length > 0) {
|
if (io.length > 0) {
|
||||||
this.addPacket({
|
this.addPacket({
|
||||||
pos: this.pos,
|
pos: this.pos,
|
||||||
is_io: true,
|
is_io: true,
|
||||||
is_output: is_output,
|
is_output,
|
||||||
io: io.join()
|
io: io.join()
|
||||||
});
|
});
|
||||||
io = [];
|
io = [];
|
||||||
|
|
@ -420,15 +418,15 @@ const PacketBuffer = class {
|
||||||
/* Text or binary input */
|
/* Text or binary input */
|
||||||
case "<":
|
case "<":
|
||||||
case "[":
|
case "[":
|
||||||
x = parseInt(matches[(t == "<") ? 2 : 3], 10);
|
x = parseInt(matches[(t === "<") ? 2 : 3], 10);
|
||||||
if (x == 0) {
|
if (x === 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (io.length > 0 && is_output) {
|
if (io.length > 0 && is_output) {
|
||||||
this.addPacket({
|
this.addPacket({
|
||||||
pos: this.pos,
|
pos: this.pos,
|
||||||
is_io: true,
|
is_io: true,
|
||||||
is_output: is_output,
|
is_output,
|
||||||
io: io.join()
|
io: io.join()
|
||||||
});
|
});
|
||||||
io = [];
|
io = [];
|
||||||
|
|
@ -436,7 +434,7 @@ const PacketBuffer = class {
|
||||||
is_output = false;
|
is_output = false;
|
||||||
/* Add (replacement) input characters */
|
/* Add (replacement) input characters */
|
||||||
s = in_txt.slice(in_txt_pos, in_txt_pos += x);
|
s = in_txt.slice(in_txt_pos, in_txt_pos += x);
|
||||||
if (s.length != x) {
|
if (s.length !== x) {
|
||||||
this.reportError(_("timing entry out of input bounds"));
|
this.reportError(_("timing entry out of input bounds"));
|
||||||
}
|
}
|
||||||
io.push(s);
|
io.push(s);
|
||||||
|
|
@ -444,15 +442,15 @@ const PacketBuffer = class {
|
||||||
/* Text or binary output */
|
/* Text or binary output */
|
||||||
case ">":
|
case ">":
|
||||||
case "]":
|
case "]":
|
||||||
x = parseInt(matches[(t == ">") ? 5 : 6], 10);
|
x = parseInt(matches[(t === ">") ? 5 : 6], 10);
|
||||||
if (x == 0) {
|
if (x === 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (io.length > 0 && !is_output) {
|
if (io.length > 0 && !is_output) {
|
||||||
this.addPacket({
|
this.addPacket({
|
||||||
pos: this.pos,
|
pos: this.pos,
|
||||||
is_io: true,
|
is_io: true,
|
||||||
is_output: is_output,
|
is_output,
|
||||||
io: io.join()
|
io: io.join()
|
||||||
});
|
});
|
||||||
io = [];
|
io = [];
|
||||||
|
|
@ -460,7 +458,7 @@ const PacketBuffer = class {
|
||||||
is_output = true;
|
is_output = true;
|
||||||
/* Add (replacement) output characters */
|
/* Add (replacement) output characters */
|
||||||
s = out_txt.slice(out_txt_pos, out_txt_pos += x);
|
s = out_txt.slice(out_txt_pos, out_txt_pos += x);
|
||||||
if (s.length != x) {
|
if (s.length !== x) {
|
||||||
this.reportError(_("timing entry out of output bounds"));
|
this.reportError(_("timing entry out of output bounds"));
|
||||||
}
|
}
|
||||||
io.push(s);
|
io.push(s);
|
||||||
|
|
@ -469,14 +467,14 @@ const PacketBuffer = class {
|
||||||
case "=":
|
case "=":
|
||||||
x = parseInt(matches[8], 10);
|
x = parseInt(matches[8], 10);
|
||||||
y = parseInt(matches[9], 10);
|
y = parseInt(matches[9], 10);
|
||||||
if (x == this.width && y == this.height) {
|
if (x === this.width && y === this.height) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (io.length > 0) {
|
if (io.length > 0) {
|
||||||
this.addPacket({
|
this.addPacket({
|
||||||
pos: this.pos,
|
pos: this.pos,
|
||||||
is_io: true,
|
is_io: true,
|
||||||
is_output: is_output,
|
is_output,
|
||||||
io: io.join()
|
io: io.join()
|
||||||
});
|
});
|
||||||
io = [];
|
io = [];
|
||||||
|
|
@ -490,6 +488,9 @@ const PacketBuffer = class {
|
||||||
this.width = x;
|
this.width = x;
|
||||||
this.height = y;
|
this.height = y;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// continue
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -504,7 +505,7 @@ const PacketBuffer = class {
|
||||||
this.addPacket({
|
this.addPacket({
|
||||||
pos: this.pos,
|
pos: this.pos,
|
||||||
is_io: true,
|
is_io: true,
|
||||||
is_output: is_output,
|
is_output,
|
||||||
io: io.join()
|
io: io.join()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -514,17 +515,12 @@ const PacketBuffer = class {
|
||||||
* Parse packets out of a tlog message and add them to the buffer.
|
* Parse packets out of a tlog message and add them to the buffer.
|
||||||
*/
|
*/
|
||||||
parseMessage(message) {
|
parseMessage(message) {
|
||||||
let matches;
|
|
||||||
let ver;
|
|
||||||
let id;
|
|
||||||
let pos;
|
|
||||||
|
|
||||||
const number = Number();
|
const number = Number();
|
||||||
const string = String();
|
const string = String();
|
||||||
|
|
||||||
/* Check version */
|
/* Check version */
|
||||||
ver = this.getValidField(message, "ver", string);
|
const ver = this.getValidField(message, "ver", string);
|
||||||
matches = ver.match("^(\\d+)\\.(\\d+)$");
|
const matches = ver.match("^(\\d+)\\.(\\d+)$");
|
||||||
if (matches === null || matches[1] > 2) {
|
if (matches === null || matches[1] > 2) {
|
||||||
this.reportError("\"ver\" field has invalid value: " + ver);
|
this.reportError("\"ver\" field has invalid value: " + ver);
|
||||||
}
|
}
|
||||||
|
|
@ -532,13 +528,13 @@ const PacketBuffer = class {
|
||||||
/* TODO Perhaps check host, rec, user, term, and session fields */
|
/* TODO Perhaps check host, rec, user, term, and session fields */
|
||||||
|
|
||||||
/* Extract message ID */
|
/* Extract message ID */
|
||||||
id = this.getValidField(message, "id", number);
|
const id = this.getValidField(message, "id", number);
|
||||||
if (id <= this.id) {
|
if (id <= this.id) {
|
||||||
this.reportError("out of order \"id\" field value: " + id);
|
this.reportError("out of order \"id\" field value: " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract message time position */
|
/* Extract message time position */
|
||||||
pos = this.getValidField(message, "pos", number);
|
const pos = this.getValidField(message, "pos", number);
|
||||||
if (pos < this.message_pos) {
|
if (pos < this.message_pos) {
|
||||||
this.reportError("out of order \"pos\" field value: " + pos);
|
this.reportError("out of order \"pos\" field value: " + pos);
|
||||||
}
|
}
|
||||||
|
|
@ -612,8 +608,7 @@ const PacketBuffer = class {
|
||||||
this.journalctl = journal.journalctl(
|
this.journalctl = journal.journalctl(
|
||||||
this.matchList,
|
this.matchList,
|
||||||
{
|
{
|
||||||
cursor: this.cursor,
|
cursor: this.cursor, follow: true, merge: true, count: "all"
|
||||||
follow: true, merge: true, count: "all"
|
|
||||||
});
|
});
|
||||||
this.journalctl.fail(this.handleError);
|
this.journalctl.fail(this.handleError);
|
||||||
this.journalctl.stream(this.handleStream);
|
this.journalctl.stream(this.handleStream);
|
||||||
|
|
@ -634,14 +629,14 @@ class Search extends React.Component {
|
||||||
this.handleStream = this.handleStream.bind(this);
|
this.handleStream = this.handleStream.bind(this);
|
||||||
this.handleError = this.handleError.bind(this);
|
this.handleError = this.handleError.bind(this);
|
||||||
this.handleSearchSubmit = this.handleSearchSubmit.bind(this);
|
this.handleSearchSubmit = this.handleSearchSubmit.bind(this);
|
||||||
this.clearSearchResults = this.clearSearchResults.bind(this);
|
this.handleClearSearchResults = this.handleClearSearchResults.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
search: cockpit.location.options.search_rec || cockpit.location.options.search || "",
|
search: cockpit.location.options.search_rec || cockpit.location.options.search || "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInputChange(name, value) {
|
handleInputChange(name, value) {
|
||||||
event.preventDefault();
|
|
||||||
const state = {};
|
const state = {};
|
||||||
state[name] = value;
|
state[name] = value;
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
|
|
@ -669,14 +664,14 @@ class Search extends React.Component {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
this.setState({ items: items });
|
this.setState({ items });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleError(data) {
|
handleError(data) {
|
||||||
this.props.errorService.addMessage(data);
|
this.props.errorService.addMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearSearchResults() {
|
handleClearSearchResults() {
|
||||||
delete cockpit.location.options.search;
|
delete cockpit.location.options.search;
|
||||||
cockpit.location.go(cockpit.location.path[0], cockpit.location.options);
|
cockpit.location.go(cockpit.location.path[0], cockpit.location.options);
|
||||||
this.setState({ search: "" });
|
this.setState({ search: "" });
|
||||||
|
|
@ -697,15 +692,18 @@ class Search extends React.Component {
|
||||||
id="search_rec"
|
id="search_rec"
|
||||||
type="search"
|
type="search"
|
||||||
value={this.state.search}
|
value={this.state.search}
|
||||||
onChange={value => this.handleInputChange("search", value)} />
|
onChange={value => this.handleInputChange("search", value)}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="control"
|
variant="control"
|
||||||
onClick={this.handleSearchSubmit}>
|
onClick={this.handleSearchSubmit}
|
||||||
|
>
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="control"
|
variant="control"
|
||||||
onClick={this.clearSearchResults}>
|
onClick={this.handleClearSearchResults}
|
||||||
|
>
|
||||||
<MinusIcon />
|
<MinusIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
@ -734,21 +732,21 @@ export class Player extends React.Component {
|
||||||
this.handlePacket = this.handlePacket.bind(this);
|
this.handlePacket = this.handlePacket.bind(this);
|
||||||
this.handleError = this.handleError.bind(this);
|
this.handleError = this.handleError.bind(this);
|
||||||
this.handleTitleChange = this.handleTitleChange.bind(this);
|
this.handleTitleChange = this.handleTitleChange.bind(this);
|
||||||
this.rewindToStart = this.rewindToStart.bind(this);
|
this.handleRewindToStart = this.handleRewindToStart.bind(this);
|
||||||
this.playPauseToggle = this.playPauseToggle.bind(this);
|
this.handlePlayPauseToggle = this.handlePlayPauseToggle.bind(this);
|
||||||
this.play = this.play.bind(this);
|
this.play = this.play.bind(this);
|
||||||
this.pause = this.pause.bind(this);
|
this.pause = this.pause.bind(this);
|
||||||
this.speedUp = this.speedUp.bind(this);
|
this.handleSpeedUp = this.handleSpeedUp.bind(this);
|
||||||
this.speedDown = this.speedDown.bind(this);
|
this.handleSpeedDown = this.handleSpeedDown.bind(this);
|
||||||
this.speedReset = this.speedReset.bind(this);
|
this.handleSpeedReset = this.handleSpeedReset.bind(this);
|
||||||
this.fastForwardToEnd = this.fastForwardToEnd.bind(this);
|
this.handleFastForwardToEnd = this.handleFastForwardToEnd.bind(this);
|
||||||
this.skipFrame = this.skipFrame.bind(this);
|
this.handleSkipFrame = this.handleSkipFrame.bind(this);
|
||||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||||
this.sync = this.sync.bind(this);
|
this.sync = this.sync.bind(this);
|
||||||
this.zoomIn = this.zoomIn.bind(this);
|
this.handleZoomIn = this.handleZoomIn.bind(this);
|
||||||
this.zoomOut = this.zoomOut.bind(this);
|
this.handleZoomOut = this.handleZoomOut.bind(this);
|
||||||
this.fitTo = this.fitTo.bind(this);
|
this.handleFitTo = this.handleFitTo.bind(this);
|
||||||
this.dragPan = this.dragPan.bind(this);
|
this.handleDragPan = this.handleDragPan.bind(this);
|
||||||
this.dragPanEnable = this.dragPanEnable.bind(this);
|
this.dragPanEnable = this.dragPanEnable.bind(this);
|
||||||
this.dragPanDisable = this.dragPanDisable.bind(this);
|
this.dragPanDisable = this.dragPanDisable.bind(this);
|
||||||
this.zoom = this.zoom.bind(this);
|
this.zoom = this.zoom.bind(this);
|
||||||
|
|
@ -756,6 +754,8 @@ export class Player extends React.Component {
|
||||||
this.sendInput = this.sendInput.bind(this);
|
this.sendInput = this.sendInput.bind(this);
|
||||||
this.clearInputPlayer = this.clearInputPlayer.bind(this);
|
this.clearInputPlayer = this.clearInputPlayer.bind(this);
|
||||||
this.handleInfoClick = this.handleInfoClick.bind(this);
|
this.handleInfoClick = this.handleInfoClick.bind(this);
|
||||||
|
this.wrapperRef = React.createRef();
|
||||||
|
this.termRef = React.createRef();
|
||||||
this.handleProgressClick = this.handleProgressClick.bind(this);
|
this.handleProgressClick = this.handleProgressClick.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
|
@ -793,6 +793,10 @@ export class Player extends React.Component {
|
||||||
|
|
||||||
this.containerHeight = 400;
|
this.containerHeight = 400;
|
||||||
|
|
||||||
|
this.setScrollwrapRef = element => {
|
||||||
|
this.scrollwrapRef = element;
|
||||||
|
};
|
||||||
|
|
||||||
/* Auto-loading buffer of recording's packets */
|
/* Auto-loading buffer of recording's packets */
|
||||||
this.error_service = new ErrorService();
|
this.error_service = new ErrorService();
|
||||||
this.reportError = this.error_service.addMessage;
|
this.reportError = this.error_service.addMessage;
|
||||||
|
|
@ -891,7 +895,7 @@ export class Player extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_transform(width, height) {
|
_transform(width, height) {
|
||||||
var relation = Math.min(
|
const relation = Math.min(
|
||||||
this.state.containerWidth / this.state.term.element.offsetWidth,
|
this.state.containerWidth / this.state.term.element.offsetWidth,
|
||||||
this.containerHeight / this.state.term.element.offsetHeight
|
this.containerHeight / this.state.term.element.offsetHeight
|
||||||
);
|
);
|
||||||
|
|
@ -1008,7 +1012,7 @@ export class Player extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playPauseToggle() {
|
handlePlayPauseToggle() {
|
||||||
this.setState({ paused: !this.state.paused });
|
this.setState({ paused: !this.state.paused });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1020,21 +1024,21 @@ export class Player extends React.Component {
|
||||||
this.setState({ paused: true });
|
this.setState({ paused: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
speedUp() {
|
handleSpeedUp() {
|
||||||
const speedExp = this.state.speedExp;
|
const speedExp = this.state.speedExp;
|
||||||
if (speedExp < 4) {
|
if (speedExp < 4) {
|
||||||
this.setState({ speedExp: speedExp + 1 });
|
this.setState({ speedExp: speedExp + 1 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
speedDown() {
|
handleSpeedDown() {
|
||||||
const speedExp = this.state.speedExp;
|
const speedExp = this.state.speedExp;
|
||||||
if (speedExp > -4) {
|
if (speedExp > -4) {
|
||||||
this.setState({ speedExp: speedExp - 1 });
|
this.setState({ speedExp: speedExp - 1 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
speedReset() {
|
handleSpeedReset() {
|
||||||
this.setState({ speedExp: 0 });
|
this.setState({ speedExp: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1042,7 +1046,7 @@ export class Player extends React.Component {
|
||||||
this.setState({ input: "" });
|
this.setState({ input: "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
rewindToStart() {
|
handleRewindToStart() {
|
||||||
this.clearInputPlayer();
|
this.clearInputPlayer();
|
||||||
this.reset();
|
this.reset();
|
||||||
this.sync();
|
this.sync();
|
||||||
|
|
@ -1051,7 +1055,7 @@ export class Player extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fastForwardToEnd() {
|
handleFastForwardToEnd() {
|
||||||
this.fastForwardTo = Infinity;
|
this.fastForwardTo = Infinity;
|
||||||
this.sync();
|
this.sync();
|
||||||
}
|
}
|
||||||
|
|
@ -1064,23 +1068,23 @@ export class Player extends React.Component {
|
||||||
this.sync();
|
this.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
skipFrame() {
|
handleSkipFrame() {
|
||||||
this.skip = true;
|
this.skip = true;
|
||||||
this.sync();
|
this.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown(event) {
|
handleKeyDown(event) {
|
||||||
const keyCodesFuncs = {
|
const keyCodesFuncs = {
|
||||||
P: this.playPauseToggle,
|
P: this.handlePlayPauseToggle,
|
||||||
"}": this.speedUp,
|
"}": this.handleSpeedUp,
|
||||||
"{": this.speedDown,
|
"{": this.handleSpeedDown,
|
||||||
Backspace: this.speedReset,
|
Backspace: this.handleSpeedReset,
|
||||||
".": this.skipFrame,
|
".": this.handleSkipFrame,
|
||||||
G: this.fastForwardToEnd,
|
G: this.handleFastForwardToEnd,
|
||||||
R: this.rewindToStart,
|
R: this.handleRewindToStart,
|
||||||
"+": this.zoomIn,
|
"+": this.handleZoomIn,
|
||||||
"=": this.zoomIn,
|
"=": this.handleZoomIn,
|
||||||
"-": this.zoomOut,
|
"-": this.handleZoomOut,
|
||||||
Z: this.fitIn,
|
Z: this.fitIn,
|
||||||
};
|
};
|
||||||
if (event.target.nodeName.toLowerCase() !== 'input') {
|
if (event.target.nodeName.toLowerCase() !== 'input') {
|
||||||
|
|
@ -1092,7 +1096,7 @@ export class Player extends React.Component {
|
||||||
|
|
||||||
zoom(scale) {
|
zoom(scale) {
|
||||||
if (scale.toFixed(6) === this.state.scale_initial.toFixed(6)) {
|
if (scale.toFixed(6) === this.state.scale_initial.toFixed(6)) {
|
||||||
this.fitTo();
|
this.handleFitTo();
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
term_top_style: "0",
|
term_top_style: "0",
|
||||||
|
|
@ -1100,27 +1104,27 @@ export class Player extends React.Component {
|
||||||
term_translate: "0, 0",
|
term_translate: "0, 0",
|
||||||
scale_lock: true,
|
scale_lock: true,
|
||||||
term_scroll: "auto",
|
term_scroll: "auto",
|
||||||
scale: scale,
|
scale,
|
||||||
term_zoom_max: false,
|
term_zoom_max: false,
|
||||||
term_zoom_min: false,
|
term_zoom_min: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dragPan() {
|
handleDragPan() {
|
||||||
(this.state.drag_pan ? this.dragPanDisable() : this.dragPanEnable());
|
(this.state.drag_pan ? this.dragPanDisable() : this.dragPanEnable());
|
||||||
}
|
}
|
||||||
|
|
||||||
dragPanEnable() {
|
dragPanEnable() {
|
||||||
this.setState({ drag_pan: true });
|
this.setState({ drag_pan: true });
|
||||||
|
|
||||||
const scrollwrap = this.refs.scrollwrap;
|
const scrollwrap = this.scrollwrapRef;
|
||||||
|
|
||||||
let clicked = false;
|
let clicked = false;
|
||||||
let clickX;
|
let clickX;
|
||||||
let clickY;
|
let clickY;
|
||||||
|
|
||||||
$(this.refs.scrollwrap).on({
|
$(this.scrollwrapRef).on({
|
||||||
mousemove: function(e) {
|
mousemove: function(e) {
|
||||||
clicked && updateScrollPos(e);
|
clicked && updateScrollPos(e);
|
||||||
},
|
},
|
||||||
|
|
@ -1144,13 +1148,13 @@ export class Player extends React.Component {
|
||||||
|
|
||||||
dragPanDisable() {
|
dragPanDisable() {
|
||||||
this.setState({ drag_pan: false });
|
this.setState({ drag_pan: false });
|
||||||
const scrollwrap = this.refs.scrollwrap;
|
const scrollwrap = this.scrollwrapRef;
|
||||||
$(scrollwrap).off("mousemove");
|
$(scrollwrap).off("mousemove");
|
||||||
$(scrollwrap).off("mousedown");
|
$(scrollwrap).off("mousedown");
|
||||||
$(scrollwrap).off("mouseup");
|
$(scrollwrap).off("mouseup");
|
||||||
}
|
}
|
||||||
|
|
||||||
zoomIn() {
|
handleZoomIn() {
|
||||||
let scale = this.state.scale;
|
let scale = this.state.scale;
|
||||||
if (scale < 2.1) {
|
if (scale < 2.1) {
|
||||||
scale = scale + 0.1;
|
scale = scale + 0.1;
|
||||||
|
|
@ -1160,7 +1164,7 @@ export class Player extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zoomOut() {
|
handleZoomOut() {
|
||||||
let scale = this.state.scale;
|
let scale = this.state.scale;
|
||||||
if (scale >= 0.2) {
|
if (scale >= 0.2) {
|
||||||
scale = scale - 0.1;
|
scale = scale - 0.1;
|
||||||
|
|
@ -1170,7 +1174,7 @@ export class Player extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fitTo() {
|
handleFitTo() {
|
||||||
this.setState({
|
this.setState({
|
||||||
term_top_style: "50%",
|
term_top_style: "50%",
|
||||||
term_left_style: "50%",
|
term_left_style: "50%",
|
||||||
|
|
@ -1182,15 +1186,17 @@ export class Player extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.state.term.on('title', this.handleTitleChange);
|
this.state.term.onData((data) => {
|
||||||
|
this.handleTitleChange();
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener("keydown", this.handleKeyDown, false);
|
window.addEventListener("keydown", this.handleKeyDown, false);
|
||||||
|
|
||||||
if (this.refs.wrapper.offsetWidth) {
|
if (this.wrapperRef.offsetWidth) {
|
||||||
this.setState({ containerWidth: this.refs.wrapper.offsetWidth });
|
this.setState({ containerWidth: this.wrapperRef.offsetWidth });
|
||||||
}
|
}
|
||||||
/* Open the terminal */
|
/* Open the terminal */
|
||||||
this.state.term.open(this.refs.term);
|
this.state.term.open(this.termRef.current);
|
||||||
window.setInterval(this.sync, 100);
|
window.setInterval(this.sync, 100);
|
||||||
/* Reset playback */
|
/* Reset playback */
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|
@ -1199,15 +1205,15 @@ export class Player extends React.Component {
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
/* If we changed pause state or speed exponent */
|
/* If we changed pause state or speed exponent */
|
||||||
if (this.state.paused != prevState.paused ||
|
if (this.state.paused !== prevState.paused ||
|
||||||
this.state.speedExp != prevState.speedExp) {
|
this.state.speedExp !== prevState.speedExp) {
|
||||||
this.speed = Math.pow(2, this.state.speedExp);
|
this.speed = Math.pow(2, this.state.speedExp);
|
||||||
this.sync();
|
this.sync();
|
||||||
}
|
}
|
||||||
if (this.state.input != prevState.input) {
|
if (this.state.input !== prevState.input) {
|
||||||
scrollToBottom("input-textarea");
|
scrollToBottom("input-textarea");
|
||||||
}
|
}
|
||||||
if (prevProps.logsTs != this.props.logsTs) {
|
if (prevProps.logsTs !== this.props.logsTs) {
|
||||||
this.fastForwardToTS(this.props.logsTs);
|
this.fastForwardToTS(this.props.logsTs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1266,7 +1272,8 @@ export class Player extends React.Component {
|
||||||
valueText={timeStr}
|
valueText={timeStr}
|
||||||
label={timeStr}
|
label={timeStr}
|
||||||
value={this.state.curTS}
|
value={this.state.curTS}
|
||||||
onClick={this.handleProgressClick} />
|
onClick={this.handleProgressClick}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const playbackControls = (
|
const playbackControls = (
|
||||||
|
|
@ -1277,7 +1284,7 @@ export class Player extends React.Component {
|
||||||
id="player-play-pause"
|
id="player-play-pause"
|
||||||
title="Play/Pause - Hotkey: p"
|
title="Play/Pause - Hotkey: p"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.playPauseToggle}
|
onClick={this.handlePlayPauseToggle}
|
||||||
>
|
>
|
||||||
{this.state.paused ? <PlayIcon /> : <PauseIcon />}
|
{this.state.paused ? <PlayIcon /> : <PauseIcon />}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1288,7 +1295,7 @@ export class Player extends React.Component {
|
||||||
id="player-skip-frame"
|
id="player-skip-frame"
|
||||||
title="Skip Frame - Hotkey: ."
|
title="Skip Frame - Hotkey: ."
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.skipFrame}
|
onClick={this.handleSkipFrame}
|
||||||
>
|
>
|
||||||
<ArrowRightIcon />
|
<ArrowRightIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1299,7 +1306,7 @@ export class Player extends React.Component {
|
||||||
id="player-restart"
|
id="player-restart"
|
||||||
title="Restart Playback - Hotkey: Shift-R"
|
title="Restart Playback - Hotkey: Shift-R"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.rewindToStart}
|
onClick={this.handleRewindToStart}
|
||||||
>
|
>
|
||||||
<UndoIcon />
|
<UndoIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1310,7 +1317,7 @@ export class Player extends React.Component {
|
||||||
id="player-fast-forward"
|
id="player-fast-forward"
|
||||||
title="Fast-forward to end - Hotkey: Shift-G"
|
title="Fast-forward to end - Hotkey: Shift-G"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.fastForwardToEnd}
|
onClick={this.handleFastForwardToEnd}
|
||||||
>
|
>
|
||||||
<RedoIcon />
|
<RedoIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1321,7 +1328,7 @@ export class Player extends React.Component {
|
||||||
id="player-speed-down"
|
id="player-speed-down"
|
||||||
title="Speed /2 - Hotkey: {"
|
title="Speed /2 - Hotkey: {"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.speedDown}
|
onClick={this.handleSpeedDown}
|
||||||
>
|
>
|
||||||
/2
|
/2
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1332,7 +1339,7 @@ export class Player extends React.Component {
|
||||||
id="player-speed-up"
|
id="player-speed-up"
|
||||||
title="Speed x2 - Hotkey: }"
|
title="Speed x2 - Hotkey: }"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.speedUp}
|
onClick={this.handleSpeedUp}
|
||||||
>
|
>
|
||||||
x2
|
x2
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1340,7 +1347,7 @@ export class Player extends React.Component {
|
||||||
{speedStr !== "" &&
|
{speedStr !== "" &&
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<ChipGroup categoryName="speed">
|
<ChipGroup categoryName="speed">
|
||||||
<Chip onClick={this.speedReset}>
|
<Chip onClick={this.handleSpeedReset}>
|
||||||
<span id="player-speed">{speedStr}</span>
|
<span id="player-speed">{speedStr}</span>
|
||||||
</Chip>
|
</Chip>
|
||||||
</ChipGroup>
|
</ChipGroup>
|
||||||
|
|
@ -1355,7 +1362,7 @@ export class Player extends React.Component {
|
||||||
variant="plain"
|
variant="plain"
|
||||||
id="player-drag-pan"
|
id="player-drag-pan"
|
||||||
title="Drag'n'Pan"
|
title="Drag'n'Pan"
|
||||||
onClick={this.dragPan}
|
onClick={this.handleDragPan}
|
||||||
>
|
>
|
||||||
{this.state.drag_pan ? <ThumbtackIcon /> : <MigrationIcon />}
|
{this.state.drag_pan ? <ThumbtackIcon /> : <MigrationIcon />}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1366,7 +1373,7 @@ export class Player extends React.Component {
|
||||||
id="player-zoom-in"
|
id="player-zoom-in"
|
||||||
title="Zoom In - Hotkey: ="
|
title="Zoom In - Hotkey: ="
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.zoomIn}
|
onClick={this.handleZoomIn}
|
||||||
disabled={this.state.term_zoom_max}
|
disabled={this.state.term_zoom_max}
|
||||||
>
|
>
|
||||||
<SearchPlusIcon />
|
<SearchPlusIcon />
|
||||||
|
|
@ -1378,7 +1385,7 @@ export class Player extends React.Component {
|
||||||
id="player-fit-to"
|
id="player-fit-to"
|
||||||
title="Fit To - Hotkey: Z"
|
title="Fit To - Hotkey: Z"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.fitTo}
|
onClick={this.handleFitTo}
|
||||||
>
|
>
|
||||||
<ExpandIcon />
|
<ExpandIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1389,7 +1396,7 @@ export class Player extends React.Component {
|
||||||
id="player-zoom-out"
|
id="player-zoom-out"
|
||||||
title="Zoom Out - Hotkey: -"
|
title="Zoom Out - Hotkey: -"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.zoomOut}
|
onClick={this.handleZoomOut}
|
||||||
disabled={this.state.term_zoom_min}
|
disabled={this.state.term_zoom_min}
|
||||||
>
|
>
|
||||||
<SearchMinusIcon />
|
<SearchMinusIcon />
|
||||||
|
|
@ -1410,7 +1417,8 @@ export class Player extends React.Component {
|
||||||
play={this.play}
|
play={this.play}
|
||||||
pause={this.pause}
|
pause={this.pause}
|
||||||
paused={this.state.paused}
|
paused={this.state.paused}
|
||||||
errorService={this.error_service} />
|
errorService={this.error_service}
|
||||||
|
/>
|
||||||
<ErrorList list={this.error_service.errors} />
|
<ErrorList list={this.error_service.errors} />
|
||||||
</ToolbarContent>
|
</ToolbarContent>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
@ -1436,7 +1444,8 @@ export class Player extends React.Component {
|
||||||
dataListCells={[
|
dataListCells={[
|
||||||
<DataListCell key="name">{item.name}</DataListCell>,
|
<DataListCell key="name">{item.name}</DataListCell>,
|
||||||
<DataListCell key="value">{item.value}</DataListCell>
|
<DataListCell key="value">{item.value}</DataListCell>
|
||||||
]} />
|
]}
|
||||||
|
/>
|
||||||
</DataListItemRow>
|
</DataListItemRow>
|
||||||
</DataListItem>
|
</DataListItem>
|
||||||
)
|
)
|
||||||
|
|
@ -1449,7 +1458,8 @@ export class Player extends React.Component {
|
||||||
id="btn-recording-info"
|
id="btn-recording-info"
|
||||||
toggleText={_("Recording Info")}
|
toggleText={_("Recording Info")}
|
||||||
onToggle={this.handleInfoClick}
|
onToggle={this.handleInfoClick}
|
||||||
isExpanded={this.state.infoEnabled === true}>
|
isExpanded={this.state.infoEnabled === true}
|
||||||
|
>
|
||||||
{recordingInfo}
|
{recordingInfo}
|
||||||
</ExpandableSection>
|
</ExpandableSection>
|
||||||
);
|
);
|
||||||
|
|
@ -1457,7 +1467,7 @@ export class Player extends React.Component {
|
||||||
// ensure react never reuses this div by keying it with the terminal widget
|
// ensure react never reuses this div by keying it with the terminal widget
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div ref="wrapper" className="panel panel-default">
|
<div ref={this.wrapperRef} className="panel panel-default">
|
||||||
<div className="panel-heading">
|
<div className="panel-heading">
|
||||||
<span>{this.state.title}</span>
|
<span>{this.state.title}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1465,12 +1475,14 @@ export class Player extends React.Component {
|
||||||
<div
|
<div
|
||||||
className={(this.state.drag_pan ? "dragnpan" : "")}
|
className={(this.state.drag_pan ? "dragnpan" : "")}
|
||||||
style={scrollwrap}
|
style={scrollwrap}
|
||||||
ref="scrollwrap">
|
ref={this.setScrollwrapRef}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
ref="term"
|
ref={this.termRef}
|
||||||
className="console-ct"
|
className="console-ct"
|
||||||
key={this.state.term}
|
key={this.state.term}
|
||||||
style={style} />
|
style={style}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{progress}
|
{progress}
|
||||||
|
|
@ -1484,6 +1496,6 @@ export class Player extends React.Component {
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.buf.stop();
|
this.buf.stop();
|
||||||
window.removeEventListener("keydown", this.handleKeyDown, false);
|
window.removeEventListener("keydown", this.handleKeyDown, false);
|
||||||
this.state.term.destroy();
|
this.state.term.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
* along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
"use strict";
|
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
Breadcrumb, BreadcrumbItem,
|
Breadcrumb, BreadcrumbItem,
|
||||||
|
|
@ -58,12 +56,12 @@ import {
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
SearchIcon
|
SearchIcon
|
||||||
} from "@patternfly/react-icons";
|
} from "@patternfly/react-icons";
|
||||||
|
import cockpit from 'cockpit';
|
||||||
import { global_danger_color_200 } from "@patternfly/react-tokens";
|
import { global_danger_color_200 } from "@patternfly/react-tokens";
|
||||||
import { debounce } from 'throttle-debounce';
|
import { debounce } from 'throttle-debounce';
|
||||||
import { journal } from 'journal';
|
import { journal } from 'journal';
|
||||||
|
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
const cockpit = require("cockpit");
|
|
||||||
const _ = cockpit.gettext;
|
const _ = cockpit.gettext;
|
||||||
const Player = require("./player.jsx");
|
const Player = require("./player.jsx");
|
||||||
const Config = require("./config.jsx");
|
const Config = require("./config.jsx");
|
||||||
|
|
@ -88,8 +86,8 @@ const padInt = function (n, w) {
|
||||||
*/
|
*/
|
||||||
const formatDateTime = function (ms) {
|
const formatDateTime = function (ms) {
|
||||||
/* Convert local timezone offset */
|
/* Convert local timezone offset */
|
||||||
let t = new Date(ms);
|
const t = new Date(ms);
|
||||||
let z = t.getTimezoneOffset() * 60 * 1000;
|
const z = t.getTimezoneOffset() * 60 * 1000;
|
||||||
let tLocal = t - z;
|
let tLocal = t - z;
|
||||||
tLocal = new Date(tLocal);
|
tLocal = new Date(tLocal);
|
||||||
let iso = tLocal.toISOString();
|
let iso = tLocal.toISOString();
|
||||||
|
|
@ -148,9 +146,9 @@ function LogElement(props) {
|
||||||
const timeClick = function(_e) {
|
const timeClick = function(_e) {
|
||||||
const ts = entry_timestamp - start;
|
const ts = entry_timestamp - start;
|
||||||
if (ts > 0) {
|
if (ts > 0) {
|
||||||
props.jumpToTs(ts);
|
props.onJumpToTs(ts);
|
||||||
} else {
|
} else {
|
||||||
props.jumpToTs(0);
|
props.onJumpToTs(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const messageClick = () => {
|
const messageClick = () => {
|
||||||
|
|
@ -159,7 +157,8 @@ function LogElement(props) {
|
||||||
win.focus();
|
win.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cells = <DataListItemCells
|
const cells = (
|
||||||
|
<DataListItemCells
|
||||||
dataListCells={[
|
dataListCells={[
|
||||||
<DataListCell key="row">
|
<DataListCell key="row">
|
||||||
<ExclamationTriangleIcon />
|
<ExclamationTriangleIcon />
|
||||||
|
|
@ -170,7 +169,9 @@ function LogElement(props) {
|
||||||
<CardBody>{entry.MESSAGE}</CardBody>
|
<CardBody>{entry.MESSAGE}</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</DataListCell>
|
</DataListCell>
|
||||||
]} />;
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataListItem>
|
<DataListItem>
|
||||||
|
|
@ -187,7 +188,8 @@ function LogsView(props) {
|
||||||
entry={entry}
|
entry={entry}
|
||||||
start={start}
|
start={start}
|
||||||
end={end}
|
end={end}
|
||||||
jumpToTs={props.jumpToTs} />
|
onJumpToTs={props.onJumpToTs}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<DataList>{rows}</DataList>
|
<DataList>{rows}</DataList>
|
||||||
|
|
@ -201,7 +203,7 @@ class Logs extends React.Component {
|
||||||
this.journalctlIngest = this.journalctlIngest.bind(this);
|
this.journalctlIngest = this.journalctlIngest.bind(this);
|
||||||
this.journalctlPrepend = this.journalctlPrepend.bind(this);
|
this.journalctlPrepend = this.journalctlPrepend.bind(this);
|
||||||
this.getLogs = this.getLogs.bind(this);
|
this.getLogs = this.getLogs.bind(this);
|
||||||
this.loadLater = this.loadLater.bind(this);
|
this.handleLoadLater = this.handleLoadLater.bind(this);
|
||||||
this.loadForTs = this.loadForTs.bind(this);
|
this.loadForTs = this.loadForTs.bind(this);
|
||||||
this.journalCtl = null;
|
this.journalCtl = null;
|
||||||
this.entries = [];
|
this.entries = [];
|
||||||
|
|
@ -224,7 +226,7 @@ class Logs extends React.Component {
|
||||||
if (entryList.length > 0) {
|
if (entryList.length > 0) {
|
||||||
this.entries.push(...entryList);
|
this.entries.push(...entryList);
|
||||||
const after = this.entries[this.entries.length - 1].__CURSOR;
|
const after = this.entries[this.entries.length - 1].__CURSOR;
|
||||||
this.setState({ entries: this.entries, after: after });
|
this.setState({ entries: this.entries, after });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,7 +276,7 @@ class Logs extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadLater() {
|
handleLoadLater() {
|
||||||
this.start = this.end;
|
this.start = this.end;
|
||||||
this.end = this.end + 3600;
|
this.end = this.end + 3600;
|
||||||
this.getLogs();
|
this.getLogs();
|
||||||
|
|
@ -335,12 +337,14 @@ class Logs extends React.Component {
|
||||||
entries={this.state.entries}
|
entries={this.state.entries}
|
||||||
start={this.props.recording.start}
|
start={this.props.recording.start}
|
||||||
end={this.props.recording.end}
|
end={this.props.recording.end}
|
||||||
jumpToTs={this.props.jumpToTs} />
|
onJumpToTs={this.props.onJumpToTs}
|
||||||
|
/>
|
||||||
<Bullseye>
|
<Bullseye>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
icon={<PlusIcon />}
|
icon={<PlusIcon />}
|
||||||
onClick={this.loadLater}>
|
onClick={this.handleLoadLater}
|
||||||
|
>
|
||||||
{_("Load later entries")}
|
{_("Load later entries")}
|
||||||
</Button>
|
</Button>
|
||||||
</Bullseye>
|
</Bullseye>
|
||||||
|
|
@ -359,11 +363,12 @@ class Logs extends React.Component {
|
||||||
class Recording extends React.Component {
|
class Recording extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.goBackToList = this.goBackToList.bind(this);
|
this.handleGoBackToList = this.handleGoBackToList.bind(this);
|
||||||
this.handleTsChange = this.handleTsChange.bind(this);
|
this.handleTsChange = this.handleTsChange.bind(this);
|
||||||
this.handleLogTsChange = this.handleLogTsChange.bind(this);
|
this.handleLogTsChange = this.handleLogTsChange.bind(this);
|
||||||
this.handleLogsClick = this.handleLogsClick.bind(this);
|
this.handleLogsClick = this.handleLogsClick.bind(this);
|
||||||
this.handleLogsReset = this.handleLogsReset.bind(this);
|
this.handleLogsReset = this.handleLogsReset.bind(this);
|
||||||
|
this.playerRef = React.createRef();
|
||||||
this.state = {
|
this.state = {
|
||||||
curTs: null,
|
curTs: null,
|
||||||
logsTs: null,
|
logsTs: null,
|
||||||
|
|
@ -389,7 +394,7 @@ class Recording extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
goBackToList() {
|
handleGoBackToList() {
|
||||||
if (cockpit.location.path[0]) {
|
if (cockpit.location.path[0]) {
|
||||||
if ("search_rec" in cockpit.location.options) {
|
if ("search_rec" in cockpit.location.options) {
|
||||||
delete cockpit.location.options.search_rec;
|
delete cockpit.location.options.search_rec;
|
||||||
|
|
@ -420,33 +425,37 @@ groupProps={{ sticky: 'top' }}
|
||||||
isBreadcrumbGrouped
|
isBreadcrumbGrouped
|
||||||
breadcrumb={
|
breadcrumb={
|
||||||
<Breadcrumb className='machines-listing-breadcrumb'>
|
<Breadcrumb className='machines-listing-breadcrumb'>
|
||||||
<BreadcrumbItem to='#' onClick={this.goBackToList}>
|
<BreadcrumbItem to='#' onClick={this.handleGoBackToList}>
|
||||||
{_("Session Recording")}
|
{_("Session Recording")}
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
<BreadcrumbItem isActive>
|
<BreadcrumbItem isActive>
|
||||||
{_("Current recording")}
|
{_("Current recording")}
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
}>
|
}
|
||||||
|
>
|
||||||
<PageSection>
|
<PageSection>
|
||||||
<Player.Player
|
<Player.Player
|
||||||
ref="player"
|
ref={this.playerRef}
|
||||||
matchList={this.props.recording.matchList}
|
matchList={this.props.recording.matchList}
|
||||||
logsTs={this.logsTs}
|
logsTs={this.logsTs}
|
||||||
search={this.props.search}
|
search={this.props.search}
|
||||||
onTsChange={this.handleTsChange}
|
onTsChange={this.handleTsChange}
|
||||||
recording={r}
|
recording={r}
|
||||||
logsEnabled={this.state.logsEnabled}
|
logsEnabled={this.state.logsEnabled}
|
||||||
onRewindStart={this.handleLogsReset} />
|
onRewindStart={this.handleLogsReset}
|
||||||
|
/>
|
||||||
<ExpandableSection
|
<ExpandableSection
|
||||||
id="btn-logs-view"
|
id="btn-logs-view"
|
||||||
toggleText={_("Logs View")}
|
toggleText={_("Logs View")}
|
||||||
onToggle={this.handleLogsClick}
|
onToggle={this.handleLogsClick}
|
||||||
isExpanded={this.state.logsEnabled === true}>
|
isExpanded={this.state.logsEnabled === true}
|
||||||
|
>
|
||||||
<Logs
|
<Logs
|
||||||
recording={this.props.recording}
|
recording={this.props.recording}
|
||||||
curTs={this.state.curTs}
|
curTs={this.state.curTs}
|
||||||
jumpToTs={this.handleLogTsChange} />
|
onJumpToTs={this.handleLogTsChange}
|
||||||
|
/>
|
||||||
</ExpandableSection>
|
</ExpandableSection>
|
||||||
</PageSection>
|
</PageSection>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
@ -463,9 +472,8 @@ groupProps={{ sticky: 'top' }}
|
||||||
class RecordingList extends React.Component {
|
class RecordingList extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.handleOnSort = this.handleOnSort.bind(this);
|
||||||
this.onSort = this.onSort.bind(this);
|
this.handleRowClick = this.handleRowClick.bind(this);
|
||||||
this.rowClickHandler = this.rowClickHandler.bind(this);
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sortBy: {
|
sortBy: {
|
||||||
index: 1,
|
index: 1,
|
||||||
|
|
@ -474,7 +482,7 @@ class RecordingList extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onSort(_event, index, direction) {
|
handleOnSort(_event, index, direction) {
|
||||||
this.setState({
|
this.setState({
|
||||||
sortBy: {
|
sortBy: {
|
||||||
index,
|
index,
|
||||||
|
|
@ -483,7 +491,7 @@ class RecordingList extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
rowClickHandler(_event, row) {
|
handleRowClick(_event, row) {
|
||||||
cockpit.location.go([row.id], cockpit.location.options);
|
cockpit.location.go([row.id], cockpit.location.options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -492,7 +500,7 @@ class RecordingList extends React.Component {
|
||||||
const { index, direction } = sortBy;
|
const { index, direction } = sortBy;
|
||||||
|
|
||||||
// generate columns
|
// generate columns
|
||||||
let titles = ["User", "Start", "End", "Duration"];
|
const titles = ["User", "Start", "End", "Duration"];
|
||||||
if (this.props.diff_hosts === true)
|
if (this.props.diff_hosts === true)
|
||||||
titles.push("Hostname");
|
titles.push("Hostname");
|
||||||
const columnTitles = titles.map(title => ({
|
const columnTitles = titles.map(title => ({
|
||||||
|
|
@ -502,7 +510,7 @@ class RecordingList extends React.Component {
|
||||||
|
|
||||||
// sort rows
|
// sort rows
|
||||||
let rows = this.props.list.map(rec => {
|
let rows = this.props.list.map(rec => {
|
||||||
let cells = [
|
const cells = [
|
||||||
rec.user,
|
rec.user,
|
||||||
formatDateTime(rec.start),
|
formatDateTime(rec.start),
|
||||||
formatDateTime(rec.end),
|
formatDateTime(rec.end),
|
||||||
|
|
@ -512,7 +520,7 @@ class RecordingList extends React.Component {
|
||||||
cells.push(rec.hostname);
|
cells.push(rec.hostname);
|
||||||
return {
|
return {
|
||||||
id: rec.id,
|
id: rec.id,
|
||||||
cells: cells
|
cells,
|
||||||
};
|
};
|
||||||
}).sort((a, b) => a.cells[index].localeCompare(b.cells[index]));
|
}).sort((a, b) => a.cells[index].localeCompare(b.cells[index]));
|
||||||
rows = direction === SortByDirection.asc ? rows : rows.reverse();
|
rows = direction === SortByDirection.asc ? rows : rows.reverse();
|
||||||
|
|
@ -524,9 +532,10 @@ class RecordingList extends React.Component {
|
||||||
cells={columnTitles}
|
cells={columnTitles}
|
||||||
rows={rows}
|
rows={rows}
|
||||||
sortBy={sortBy}
|
sortBy={sortBy}
|
||||||
onSort={this.onSort}>
|
onSort={this.handleOnSort}
|
||||||
|
>
|
||||||
<TableHeader />
|
<TableHeader />
|
||||||
<TableBody onRowClick={this.rowClickHandler} />
|
<TableBody onRowClick={this.handleRowClick} />
|
||||||
</Table>
|
</Table>
|
||||||
{!rows.length &&
|
{!rows.length &&
|
||||||
<EmptyState variant={EmptyStateVariant.small}>
|
<EmptyState variant={EmptyStateVariant.small}>
|
||||||
|
|
@ -554,7 +563,7 @@ export default class View extends React.Component {
|
||||||
this.onLocationChanged = this.onLocationChanged.bind(this);
|
this.onLocationChanged = this.onLocationChanged.bind(this);
|
||||||
this.journalctlIngest = this.journalctlIngest.bind(this);
|
this.journalctlIngest = this.journalctlIngest.bind(this);
|
||||||
this.handleInputChange = this.handleInputChange.bind(this);
|
this.handleInputChange = this.handleInputChange.bind(this);
|
||||||
this.openConfig = this.openConfig.bind(this);
|
this.handleOpenConfig = this.handleOpenConfig.bind(this);
|
||||||
/* Journalctl instance */
|
/* Journalctl instance */
|
||||||
this.journalctl = null;
|
this.journalctl = null;
|
||||||
/* Recording ID journalctl instance is invoked with */
|
/* Recording ID journalctl instance is invoked with */
|
||||||
|
|
@ -645,7 +654,7 @@ export default class View extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
r = {
|
r = {
|
||||||
id: id,
|
id,
|
||||||
matchList: ["TLOG_REC=" + id],
|
matchList: ["TLOG_REC=" + id],
|
||||||
user: e.TLOG_USER,
|
user: e.TLOG_USER,
|
||||||
boot_id: e._BOOT_ID,
|
boot_id: e._BOOT_ID,
|
||||||
|
|
@ -675,7 +684,7 @@ export default class View extends React.Component {
|
||||||
r.duration = r.end - r.start;
|
r.duration = r.end - r.start;
|
||||||
/* Find the recording in the list */
|
/* Find the recording in the list */
|
||||||
for (j = recordingList.length - 1;
|
for (j = recordingList.length - 1;
|
||||||
j >= 0 && recordingList[j] != r;
|
j >= 0 && recordingList[j] !== r;
|
||||||
j--);
|
j--);
|
||||||
/* If found */
|
/* If found */
|
||||||
if (j >= 0) {
|
if (j >= 0) {
|
||||||
|
|
@ -691,7 +700,7 @@ export default class View extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ recordingList: recordingList });
|
this.setState({ recordingList });
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -784,7 +793,7 @@ export default class View extends React.Component {
|
||||||
cockpit.location.go([], $.extend(cockpit.location.options, state));
|
cockpit.location.go([], $.extend(cockpit.location.options, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
openConfig() {
|
handleOpenConfig() {
|
||||||
cockpit.location.go("/config");
|
cockpit.location.go("/config");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -841,7 +850,8 @@ export default class View extends React.Component {
|
||||||
<EmptyState variant={EmptyStateVariant.small}>
|
<EmptyState variant={EmptyStateVariant.small}>
|
||||||
<EmptyStateIcon
|
<EmptyStateIcon
|
||||||
icon={ExclamationCircleIcon}
|
icon={ExclamationCircleIcon}
|
||||||
color={global_danger_color_200.value} />
|
color={global_danger_color_200.value}
|
||||||
|
/>
|
||||||
<Title headingLevel="h2" size="lg">
|
<Title headingLevel="h2" size="lg">
|
||||||
{_("Error")}
|
{_("Error")}
|
||||||
</Title>
|
</Title>
|
||||||
|
|
@ -862,7 +872,8 @@ export default class View extends React.Component {
|
||||||
placeholder={_("Filter since")}
|
placeholder={_("Filter since")}
|
||||||
value={this.state.date_since}
|
value={this.state.date_since}
|
||||||
type="search"
|
type="search"
|
||||||
onChange={value => this.handleInputChange("date_since", value)} />
|
onChange={value => this.handleInputChange("date_since", value)}
|
||||||
|
/>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
<ToolbarGroup>
|
<ToolbarGroup>
|
||||||
|
|
@ -873,7 +884,8 @@ export default class View extends React.Component {
|
||||||
placeholder={_("Filter until")}
|
placeholder={_("Filter until")}
|
||||||
value={this.state.date_until}
|
value={this.state.date_until}
|
||||||
type="search"
|
type="search"
|
||||||
onChange={value => this.handleInputChange("date_until", value)} />
|
onChange={value => this.handleInputChange("date_until", value)}
|
||||||
|
/>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
<ToolbarGroup>
|
<ToolbarGroup>
|
||||||
|
|
@ -884,7 +896,8 @@ export default class View extends React.Component {
|
||||||
placeholder={_("Filter by content")}
|
placeholder={_("Filter by content")}
|
||||||
value={this.state.search}
|
value={this.state.search}
|
||||||
type="search"
|
type="search"
|
||||||
onChange={value => this.handleInputChange("search", value)} />
|
onChange={value => this.handleInputChange("search", value)}
|
||||||
|
/>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
<ToolbarGroup>
|
<ToolbarGroup>
|
||||||
|
|
@ -895,7 +908,8 @@ export default class View extends React.Component {
|
||||||
placeholder={_("Filter by username")}
|
placeholder={_("Filter by username")}
|
||||||
value={this.state.username}
|
value={this.state.username}
|
||||||
type="search"
|
type="search"
|
||||||
onChange={value => this.handleInputChange("username", value)} />
|
onChange={value => this.handleInputChange("username", value)}
|
||||||
|
/>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
{this.state.diff_hosts === true &&
|
{this.state.diff_hosts === true &&
|
||||||
|
|
@ -907,11 +921,12 @@ export default class View extends React.Component {
|
||||||
placeholder={_("Filter by hostname")}
|
placeholder={_("Filter by hostname")}
|
||||||
value={this.state.hostname}
|
value={this.state.hostname}
|
||||||
type="search"
|
type="search"
|
||||||
onChange={value => this.handleInputChange("hostname", value)} />
|
onChange={value => this.handleInputChange("hostname", value)}
|
||||||
|
/>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
</ToolbarGroup>}
|
</ToolbarGroup>}
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<Button id="btn-config" onClick={this.openConfig}>
|
<Button id="btn-config" onClick={this.handleOpenConfig}>
|
||||||
<CogIcon />
|
<CogIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
|
|
@ -928,7 +943,8 @@ export default class View extends React.Component {
|
||||||
username={this.state.username}
|
username={this.state.username}
|
||||||
hostname={this.state.hostname}
|
hostname={this.state.hostname}
|
||||||
list={this.state.recordingList}
|
list={this.state.recordingList}
|
||||||
diff_hosts={this.state.diff_hosts} />
|
diff_hosts={this.state.diff_hosts}
|
||||||
|
/>
|
||||||
</PageSection>
|
</PageSection>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
|
|
@ -936,7 +952,8 @@ export default class View extends React.Component {
|
||||||
return (
|
return (
|
||||||
<Recording
|
<Recording
|
||||||
recording={this.recordingMap[this.state.recordingID]}
|
recording={this.recordingMap[this.state.recordingID]}
|
||||||
search={this.state.search} />
|
search={this.state.search}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue