import React from "react";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { ContentRef, actions, AppState, selectors } from "@nteract/core";
import { CellType, ExecutionCount } from "@nteract/commutable";
export interface ComponentProps {
id: string;
contentRef: ContentRef;
children: React.ReactNode;
}
export interface StateProps {
type?: CellType;
executionCount?: ExecutionCount;
}
export interface DispatchProps {
executeCell: () => void;
deleteCell: () => void;
clearOutputs: () => void;
toggleParameterCell: () => void;
toggleCellInputVisibility: () => void;
toggleCellOutputVisibility: () => void;
toggleOutputExpansion: () => void;
changeToMarkdownCell: () => void;
changeToCodeCell: () => void;
changeCellType: (to: CellType) => void;
selectCell: () => void;
focusEditor: () => void;
focusAboveCell: () => void;
focusBelowCell: () => void;
unfocusEditor: () => void;
markCellAsDeleting: () => void;
insertCodeCellBelow: () => void;
insertCodeCellAbove: () => void;
}
export const CellToolbarContext = React.createContext({});
export type CellToolbarProps = DispatchProps & StateProps;
class CellToolbar extends React.Component<
ComponentProps & StateProps & DispatchProps
> {
render() {
return (
{this.props.children}
);
}
}
const makeMapStateToProps = (
state: AppState,
ownProps: ComponentProps
): ((state: AppState) => StateProps) => {
const mapStateToProps = (state: AppState): StateProps => {
const { id, contentRef } = ownProps;
const model = selectors.model(state, { contentRef });
let type: CellType = "code";
let executionCount: ExecutionCount = null;
if (model && model.type === "notebook") {
const cell = selectors.notebook.cellById(model, { id });
if (cell) {
type = cell.get("cell_type", "code");
executionCount = cell.get("execution_count", null);
}
}
return { type, executionCount };
};
return mapStateToProps;
};
const mapDispatchToProps = (
dispatch: Dispatch,
ownProps: ComponentProps
): DispatchProps => {
const { id, contentRef } = ownProps;
return {
executeCell: () => dispatch(actions.executeCell({ id, contentRef })),
deleteCell: () => dispatch(actions.deleteCell({ id, contentRef })),
clearOutputs: () => dispatch(actions.clearOutputs({ id, contentRef })),
toggleParameterCell: () =>
dispatch(actions.toggleParameterCell({ id, contentRef })),
toggleCellInputVisibility: () =>
dispatch(actions.toggleCellInputVisibility({ id, contentRef })),
toggleCellOutputVisibility: () =>
dispatch(actions.toggleCellOutputVisibility({ id, contentRef })),
toggleOutputExpansion: () =>
dispatch(actions.toggleOutputExpansion({ id, contentRef })),
changeToMarkdownCell: () =>
dispatch(actions.changeCellType({ id, contentRef, to: "markdown" })),
changeToCodeCell: () =>
dispatch(actions.changeCellType({ id, contentRef, to: "code" })),
changeCellType: (to: CellType) =>
dispatch(actions.changeCellType({ id, contentRef, to })),
selectCell: () => dispatch(actions.focusCell({ id, contentRef })),
focusEditor: () => dispatch(actions.focusCellEditor({ id, contentRef })),
focusAboveCell: () => {
dispatch(actions.focusPreviousCell({ id, contentRef }));
dispatch(actions.focusPreviousCellEditor({ id, contentRef }));
},
focusBelowCell: () => {
dispatch(
actions.focusNextCell({ id, createCellIfUndefined: true, contentRef })
);
dispatch(actions.focusNextCellEditor({ id, contentRef }));
},
unfocusEditor: () =>
dispatch(actions.focusCellEditor({ id: undefined, contentRef })),
markCellAsDeleting: () =>
dispatch(actions.markCellAsDeleting({ id, contentRef })),
insertCodeCellBelow: () =>
dispatch(actions.createCellBelow({ cellType: "code", contentRef })),
insertCodeCellAbove: () =>
dispatch(actions.createCellAbove({ cellType: "code", contentRef })),
};
};
export default connect(
makeMapStateToProps,
mapDispatchToProps
)(CellToolbar);