feat(cockpit/editor): add status messages for file operations

This commit is contained in:
Jonathan Rainville 2019-03-08 15:06:54 -05:00
parent 3f488e1d88
commit ecdfd473df
4 changed files with 53 additions and 6 deletions

View File

@ -7,6 +7,10 @@ import FontAwesomeIcon from 'react-fontawesome';
import AddFileModal from '../components/AddFileModal';
import AddFolderModal from '../components/AddFolderModal';
const StatusText = ({message, icon, spin = false}) => (
<span className="ml-2"><FontAwesomeIcon className="mr-1" name={icon} spin={spin}/>{message}</span>
);
export const TextEditorToolbarTabs = {
Interact: { label: 'Interact', icon: 'bolt' },
Details: { label: 'Details', icon: 'info-circle' },
@ -18,10 +22,22 @@ export const TextEditorToolbarTabs = {
class TextEditorToolbar extends Component {
constructor(props) {
super(props);
this.state = {
successMessage: ''
};
this.addFileModal = React.createRef();
this.addFolderModal = React.createRef();
}
componentDidUpdate(prevProps) {
if (this.props.editorOperationStatus.success !== prevProps.editorOperationStatus.success) {
this.setState({successMessage: this.props.editorOperationStatus.success});
setTimeout(() => {
this.setState({successMessage: ''});
}, 3000);
}
}
isActiveTab(tab) {
return this.props.activeTab === tab;
}
@ -64,6 +80,9 @@ class TextEditorToolbar extends Component {
<FontAwesomeIcon className="mr-2" name="trash"/>
Delete
</Button>
{this.state.successMessage && <StatusText message={this.state.successMessage} icon="check"/>}
{this.props.editorOperationStatus.loading && <StatusText message="Processing..." icon="spinner" spin={true}/>}
{this.props.editorOperationStatus.error && <StatusText message={this.props.editorOperationStatus.error} icon="exclamation-triangle"/>}
</li>
<li className="breadcrumb-menu">
<Nav className="btn-group">
@ -87,7 +106,8 @@ TextEditorToolbar.propTypes = {
remove: PropTypes.func,
toggleShowHiddenFiles: PropTypes.func,
toggleAsideTab: PropTypes.func,
activeTab: PropTypes.object
activeTab: PropTypes.object,
editorOperationStatus: PropTypes.object
};
export default TextEditorToolbar;

View File

@ -8,7 +8,7 @@ import {
removeFile as removeFileAction,
saveFolder as saveFolderAction
} from '../actions';
import { getRootDirname, getTheme } from '../reducers/selectors';
import { getRootDirname, getTheme, getEditorOperationStatus } from '../reducers/selectors';
class TextEditorToolbarContainer extends Component {
save() {
@ -29,12 +29,14 @@ class TextEditorToolbarContainer extends Component {
saveFolder={this.props.saveFolder}
rootDirname={this.props.rootDirname}
remove={() => this.remove()}
editorOperationStatus={this.props.editorOperationStatus}
activeTab={this.props.activeTab} />;
}
}
TextEditorToolbarContainer.propTypes = {
currentFile: PropTypes.object,
editorOperationStatus: PropTypes.object,
theme: PropTypes.string,
isContract: PropTypes.bool,
saveFile: PropTypes.func,
@ -49,9 +51,10 @@ TextEditorToolbarContainer.propTypes = {
const mapStateToProps = (state) => {
return {
rootDirname: getRootDirname(state),
theme: getTheme(state)
theme: getTheme(state),
editorOperationStatus: getEditorOperationStatus(state)
}
}
};
export default connect(
mapStateToProps,

View File

@ -2,7 +2,8 @@ import {combineReducers} from 'redux';
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH, DEBUGGER_INFO,
SIGN_MESSAGE, VERIFY_MESSAGE, TOGGLE_BREAKPOINT, UPDATE_PREVIEW_URL,
UPDATE_DEPLOYMENT_PIPELINE, WEB3_CONNECT, WEB3_DEPLOY, WEB3_ESTIMAGE_GAS, FETCH_EDITOR_TABS} from "../actions";
UPDATE_DEPLOYMENT_PIPELINE, WEB3_CONNECT, WEB3_DEPLOY, WEB3_ESTIMAGE_GAS, FETCH_EDITOR_TABS,
SAVE_FILE, SAVE_FOLDER, REMOVE_FILE} from "../actions";
import {EMBARK_PROCESS_NAME, DARK_THEME, DEPLOYMENT_PIPELINES, DEFAULT_HOST, ELEMENTS_LIMIT} from '../constants';
const BN_FACTOR = 10000;
@ -376,6 +377,24 @@ function previewUrl(state= `${window.location.protocol}//${window.location.host}
return state;
}
const editorOperations = [SAVE_FILE, SAVE_FOLDER, REMOVE_FILE];
function editorOperationStatus(state = {error: '', success: '', loading: false}, action) {
// Success check
if (editorOperations.find(operation => operation[SUCCESS] === action.type)) {
return {error: '', success: 'Operation successful', loading: false};
}
// Error check
if (editorOperations.find(operation => operation[FAILURE] === action.type)) {
const message = action.error ? action.error.message || action.error : '';
return {error: 'Error during the process ' + message, success: '', loading: false};
}
// Loading check
if (editorOperations.find(operation => operation[REQUEST] === action.type)) {
return {error: '', success: '', loading: true};
}
return state;
}
const rootReducer = combineReducers({
entities,
loading,
@ -393,7 +412,8 @@ const rootReducer = combineReducers({
debuggerInfo,
theme,
editorTabs,
previewUrl
previewUrl,
editorOperationStatus
});
export default rootReducer;

View File

@ -246,3 +246,7 @@ export function getPreviewUrl(state) {
return state.previewUrl;
}
export function getEditorOperationStatus(state) {
return state.editorOperationStatus;
}