import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
Alert,
// Button,
Table as PfTable,
FormControl,
inlineEditFormatterFactory,
} from 'patternfly-react';
import { cloneDeep, findIndex } from 'lodash';
import { translate as __ } from 'foremanReact/common/I18n';
import {
Table,
TableBody,
column,
headerFormatterWithProps,
cellFormatterWithProps,
} from 'foremanReact/components/common/table';
import ShortDateTime from 'foremanReact/components/common/dates/ShortDateTime';
import AlertBody from 'foremanReact/components/common/Alert/AlertBody';
import Loading from 'foremanReact/components/Loading/Loading';
import 'foremanReact/redux/API';
import { renderListEntryButtons } from './SnapshotListHelper';
import './snapshotList.scss';
class SnapshotList extends Component {
constructor(props) {
super(props);
this.state = {
columns: this.defineColumns(),
editMode: false,
rows: cloneDeep(props.snapshots),
};
}
defineColumns() {
const {
canDelete,
canRevert,
canUpdate,
host,
deleteAction,
updateAction,
rollbackAction,
} = this.props;
const inlineEditController = {
isEditing: ({ rowData }) => rowData.backup !== undefined,
onActivate: ({ rowData }) => {
const rows = cloneDeep(this.state.rows);
const index = findIndex(rows, { id: rowData.id });
rows[index].backup = cloneDeep(rows[index]);
this.setState({ rows, editMode: true });
},
onConfirm: ({ rowData }) => {
const rows = cloneDeep(this.state.rows);
const index = findIndex(rows, { id: rowData.id });
delete rows[index].backup;
this.setState({ rows, editMode: false });
updateAction(host, rowData);
},
onCancel: ({ rowData }) => {
const rows = cloneDeep(this.state.rows);
const index = findIndex(rows, { id: rowData.id });
rows[index] = cloneDeep(rows[index].backup);
delete rows[index].backup;
this.setState({ rows, editMode: false });
},
onChange: (value, { rowData, property }) => {
const rows = cloneDeep(this.state.rows);
const index = findIndex(rows, { id: rowData.id });
rows[index][property] = value;
this.setState({ rows });
},
};
this.inlineEditController = inlineEditController;
const renderButtons = renderListEntryButtons(
canDelete,
canRevert,
canUpdate,
host,
rollbackAction,
deleteAction,
inlineEditController
);
const inlineEditButtonCellFormatter = inlineEditFormatterFactory({
isEditing: additionalData => this.state.editMode,
renderValue: renderButtons(false),
renderEdit: renderButtons(true),
});
const inlineEditFormatter = inlineEditFormatterFactory({
isEditing: additionalData => {
if (
additionalData.property === 'name' &&
!this.props.capabilities.editableSnapshotName
)
return false;
return inlineEditController.isEditing(additionalData);
},
renderValue: (value, additionalData) => {
let date = '';
if (
additionalData.property === 'name' &&
additionalData.rowData.formatted_created_at
)
date = (
);
return (
{value}
{date}
);
},
renderEdit: (value, additionalData) => {
let type = 'input';
if (additionalData.property === 'description') type = 'textarea';
return (
inlineEditController.onChange(e.target.value, additionalData)
}
componentClass={type}
/>
);
},
});
const editCellFormatters = [cellFormatterWithProps];
if (canUpdate) editCellFormatters.unshift(inlineEditFormatter);
const columns = [
column(
'name',
__('Snapshot'),
[headerFormatterWithProps],
editCellFormatters
),
column(
'description',
__('Description'),
[headerFormatterWithProps],
editCellFormatters
),
];
if (canDelete || canUpdate || canRevert)
columns.push(
column(
'',
__('Action'),
[headerFormatterWithProps],
[inlineEditButtonCellFormatter],
{ className: 'action-buttons' }
)
);
return columns;
}
componentDidMount() {
this.props.loadSnapshots(this.props.host.id);
}
// FIXME: Remove soon, as this is deprecated!
componentWillReceiveProps(newProps) {
if (newProps.snapshots !== this.props.snapshots) {
this.setState({ rows: newProps.snapshots });
}
if (newProps.needsReload) {
newProps.loadSnapshots(newProps.host.id);
}
}
getBodyMessage() {
if (this.props.isLoading || this.props.isWorking)
return ;
if (this.props.hasError)
return (
{/* IMHO the line-break should be done by AlertBody :-( */}
{this.props.error.message}
);
return undefined;
}
render() {
const { columns } = this.state;
const bodyMessage = this.getBodyMessage();
return (
{/*
*/}
cellProps.children,
},
}}
>
({
role: 'row',
isEditing: () => this.inlineEditController.isEditing({ rowData }),
onCancel: () =>
this.inlineEditController.onCancel({ rowData, rowIndex }),
onConfirm: () =>
this.inlineEditController.onConfirm({ rowData, rowIndex }),
last: rowIndex === this.state.rows.length - 1,
})}
/>
);
}
}
SnapshotList.propTypes = {
/*
children: PropTypes.node,
className: PropTypes.string,
*/
host: PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
}).isRequired,
loadSnapshots: PropTypes.func.isRequired,
deleteAction: PropTypes.func.isRequired,
updateAction: PropTypes.func.isRequired,
rollbackAction: PropTypes.func.isRequired,
isLoading: PropTypes.bool,
isWorking: PropTypes.bool,
hasError: PropTypes.bool,
error: PropTypes.shape({ message: PropTypes.string }),
snapshots: PropTypes.array,
// permissions:
canDelete: PropTypes.bool,
canRevert: PropTypes.bool,
canUpdate: PropTypes.bool,
// capabilities
capabilities: PropTypes.shape({
editableSnapshotName: PropTypes.bool,
}),
};
SnapshotList.defaultProps = {
/*
className: '',
children: null,
*/
isLoading: true,
isWorking: false,
hasError: false,
error: undefined,
snapshots: [],
canDelete: false,
canRevert: false,
canUpdate: false,
capabilities: {
editableSnapshotName: true,
},
};
export default SnapshotList;