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 AddFileModal from '../components/AddFileModal';
|
||||||
import AddFolderModal from '../components/AddFolderModal';
|
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 = {
|
export const TextEditorToolbarTabs = {
|
||||||
Interact: { label: 'Interact', icon: 'bolt' },
|
Interact: { label: 'Interact', icon: 'bolt' },
|
||||||
Details: { label: 'Details', icon: 'info-circle' },
|
Details: { label: 'Details', icon: 'info-circle' },
|
||||||
|
@ -18,10 +22,22 @@ export const TextEditorToolbarTabs = {
|
||||||
class TextEditorToolbar extends Component {
|
class TextEditorToolbar extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
successMessage: ''
|
||||||
|
};
|
||||||
this.addFileModal = React.createRef();
|
this.addFileModal = React.createRef();
|
||||||
this.addFolderModal = 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) {
|
isActiveTab(tab) {
|
||||||
return this.props.activeTab === tab;
|
return this.props.activeTab === tab;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +80,9 @@ class TextEditorToolbar extends Component {
|
||||||
<FontAwesomeIcon className="mr-2" name="trash"/>
|
<FontAwesomeIcon className="mr-2" name="trash"/>
|
||||||
Delete
|
Delete
|
||||||
</Button>
|
</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>
|
||||||
<li className="breadcrumb-menu">
|
<li className="breadcrumb-menu">
|
||||||
<Nav className="btn-group">
|
<Nav className="btn-group">
|
||||||
|
@ -87,7 +106,8 @@ TextEditorToolbar.propTypes = {
|
||||||
remove: PropTypes.func,
|
remove: PropTypes.func,
|
||||||
toggleShowHiddenFiles: PropTypes.func,
|
toggleShowHiddenFiles: PropTypes.func,
|
||||||
toggleAsideTab: PropTypes.func,
|
toggleAsideTab: PropTypes.func,
|
||||||
activeTab: PropTypes.object
|
activeTab: PropTypes.object,
|
||||||
|
editorOperationStatus: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TextEditorToolbar;
|
export default TextEditorToolbar;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
removeFile as removeFileAction,
|
removeFile as removeFileAction,
|
||||||
saveFolder as saveFolderAction
|
saveFolder as saveFolderAction
|
||||||
} from '../actions';
|
} from '../actions';
|
||||||
import { getRootDirname, getTheme } from '../reducers/selectors';
|
import { getRootDirname, getTheme, getEditorOperationStatus } from '../reducers/selectors';
|
||||||
|
|
||||||
class TextEditorToolbarContainer extends Component {
|
class TextEditorToolbarContainer extends Component {
|
||||||
save() {
|
save() {
|
||||||
|
@ -29,12 +29,14 @@ class TextEditorToolbarContainer extends Component {
|
||||||
saveFolder={this.props.saveFolder}
|
saveFolder={this.props.saveFolder}
|
||||||
rootDirname={this.props.rootDirname}
|
rootDirname={this.props.rootDirname}
|
||||||
remove={() => this.remove()}
|
remove={() => this.remove()}
|
||||||
|
editorOperationStatus={this.props.editorOperationStatus}
|
||||||
activeTab={this.props.activeTab} />;
|
activeTab={this.props.activeTab} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEditorToolbarContainer.propTypes = {
|
TextEditorToolbarContainer.propTypes = {
|
||||||
currentFile: PropTypes.object,
|
currentFile: PropTypes.object,
|
||||||
|
editorOperationStatus: PropTypes.object,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
isContract: PropTypes.bool,
|
isContract: PropTypes.bool,
|
||||||
saveFile: PropTypes.func,
|
saveFile: PropTypes.func,
|
||||||
|
@ -49,9 +51,10 @@ TextEditorToolbarContainer.propTypes = {
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
rootDirname: getRootDirname(state),
|
rootDirname: getRootDirname(state),
|
||||||
theme: getTheme(state)
|
theme: getTheme(state),
|
||||||
|
editorOperationStatus: getEditorOperationStatus(state)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
|
|
|
@ -2,7 +2,8 @@ import {combineReducers} from 'redux';
|
||||||
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
|
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
|
||||||
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH, DEBUGGER_INFO,
|
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH, DEBUGGER_INFO,
|
||||||
SIGN_MESSAGE, VERIFY_MESSAGE, TOGGLE_BREAKPOINT, UPDATE_PREVIEW_URL,
|
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';
|
import {EMBARK_PROCESS_NAME, DARK_THEME, DEPLOYMENT_PIPELINES, DEFAULT_HOST, ELEMENTS_LIMIT} from '../constants';
|
||||||
|
|
||||||
const BN_FACTOR = 10000;
|
const BN_FACTOR = 10000;
|
||||||
|
@ -376,6 +377,24 @@ function previewUrl(state= `${window.location.protocol}//${window.location.host}
|
||||||
return state;
|
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({
|
const rootReducer = combineReducers({
|
||||||
entities,
|
entities,
|
||||||
loading,
|
loading,
|
||||||
|
@ -393,7 +412,8 @@ const rootReducer = combineReducers({
|
||||||
debuggerInfo,
|
debuggerInfo,
|
||||||
theme,
|
theme,
|
||||||
editorTabs,
|
editorTabs,
|
||||||
previewUrl
|
previewUrl,
|
||||||
|
editorOperationStatus
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
|
|
@ -246,3 +246,7 @@ export function getPreviewUrl(state) {
|
||||||
return state.previewUrl;
|
return state.previewUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getEditorOperationStatus(state) {
|
||||||
|
return state.editorOperationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue