mirror of https://github.com/embarklabs/embark.git
feat(cockpit/editor): add status messages for file operations
This commit is contained in:
parent
3f488e1d88
commit
ecdfd473df
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -246,3 +246,7 @@ export function getPreviewUrl(state) {
|
|||
return state.previewUrl;
|
||||
}
|
||||
|
||||
export function getEditorOperationStatus(state) {
|
||||
return state.editorOperationStatus;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue