/*
* This file is part of Cockpit.
*
* Copyright (C) 2017 Red Hat, Inc.
*
* Cockpit is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* Cockpit is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Cockpit; If not, see .
*/
"use strict";
import React from "react";
import ReactDOM from "react-dom";
let $ = require("jquery");
let cockpit = require("cockpit");
let _ = cockpit.gettext;
let moment = require("moment");
let Journal = require("journal");
let Listing = require("cockpit-components-listing.jsx");
let Player = require("./player.jsx");
require("bootstrap-datetime-picker/js/bootstrap-datetimepicker.js");
require("bootstrap-datetime-picker/css/bootstrap-datetimepicker.css");
/*
* Convert a number to integer number string and pad with zeroes to
* specified width.
*/
let padInt = function (n, w) {
let i = Math.floor(n);
let a = Math.abs(i);
let s = a.toString();
for (w -= s.length; w > 0; w--) {
s = '0' + s;
}
return ((i < 0) ? '-' : '') + s;
};
/*
* Format date and time for a number of milliseconds since Epoch.
*/
let formatDateTime = function (ms) {
let d = new Date(ms);
return (
padInt(d.getFullYear(), 4) + '-' +
padInt(d.getMonth() + 1, 2) + '-' +
padInt(d.getDate(), 2) + ' ' +
padInt(d.getHours(), 2) + ':' +
padInt(d.getMinutes(), 2) + ':' +
padInt(d.getSeconds(), 2)
);
};
/*
* Format a time interval from a number of milliseconds.
*/
let formatDuration = function (ms) {
let v = Math.floor(ms / 1000);
let s = Math.floor(v % 60);
v = Math.floor(v / 60);
let m = Math.floor(v % 60);
v = Math.floor(v / 60);
let h = Math.floor(v % 24);
let d = Math.floor(v / 24);
let str = '';
if (d > 0) {
str += d + ' ' + _("days") + ' ';
}
if (h > 0 || str.length > 0) {
str += padInt(h, 2) + ':';
}
str += padInt(m, 2) + ':' + padInt(s, 2);
return (ms < 0 ? '-' : '') + str;
};
let parseDate = function(date) {
let regex = new RegExp(/^\s*(\d\d\d\d-\d\d-\d\d)(\s+(\d\d:\d\d(:\d\d)?))?\s*$/);
let captures = regex.exec(date);
if (captures != null) {
let date = captures[1];
if (captures[3]) {
date = date + " " + captures[3];
}
if (moment(date, ["YYYY-M-D H:m:s", "YYYY-M-D H:m", "YYYY-M-D"], true).isValid()) {
return date;
}
}
if (date === "" || date === null) {
return true;
}
return false;
};
/*
* A component representing a date & time picker based on bootstrap-datetime-picker.
* Requires jQuery, bootstrap-datetime-picker, moment.js
* Properties:
* - onChange: function to call on date change event of datepicker.
* - value: variable to pass which will be used as initial value.
*/
class Datetimepicker extends React.Component {
constructor(props) {
super(props);
this.handleDateChange = this.handleDateChange.bind(this);
this.clearField = this.clearField.bind(this);
this.state = {
invalid: false,
date: this.props.value,
};
}
componentDidMount() {
$(this.refs.datepicker).datetimepicker({
format: 'yyyy-mm-dd hh:ii:00',
autoclose: true,
todayBtn: true,
})
.on('changeDate', this.handleDateChange);
// remove datepicker from input, so it only works by button press
$(this.refs.datepicker_input).datetimepicker('remove');
}
componentWillUnmount() {
$(this.refs.datepicker).datetimepicker('remove');
}
handleDateChange() {
const date = $(this.refs.datepicker_input).val()
.trim();
this.setState({invalid: false, date: date});
if (!parseDate(date)) {
this.setState({invalid: true});
} else {
this.props.onChange(date);
}
}
clearField() {
const date = "";
this.props.onChange(date);
this.setState({date: date, invalid: false});
$(this.refs.datepicker_input).val("");
}
render() {
return (
);
}
}
}
/*
* A component representing a single recording view.
* Properties:
* - recording: either null for no recording data available yet, or a
* recording object, as created by the View below.
*/
class Recording extends React.Component {
constructor(props) {
super(props);
this.goBackToList = this.goBackToList.bind(this);
}
goBackToList() {
if (cockpit.location.path[0]) {
cockpit.location.go([], cockpit.location.options);
} else {
cockpit.location.go('/');
}
}
render() {
let r = this.props.recording;
if (r == null) {
return Loading...;
} else {
let player =
();
return (