diff --git a/app/components/App.js b/app/components/App.js index 9b4c9d37..3470d478 100755 --- a/app/components/App.js +++ b/app/components/App.js @@ -7,7 +7,12 @@ import CssBaseline from '@material-ui/core/CssBaseline'; import Layout from 'components/layout/Layout'; import { withErrorBoundary } from 'commons/hocs'; import { setEnv } from 'models/npm/actions'; -import { initActions, updateStatus } from 'models/common/actions'; +import { + initActions, + updateStatus, + updateCommandLog, + clearCommandLog, +} from 'models/common/actions'; import { setUIException, setSnackbar } from 'models/ui/actions'; import { iMessage } from 'commons/utils'; import theme from 'styles/theme'; @@ -51,11 +56,13 @@ const App = () => { const { cmd, isTerminated } = data; const [command, ...args] = cmd; + if (isTerminated) { + return dispatch(clearCommandLog()); + } + dispatch( - setSnackbar({ - open: isTerminated === false, - type: 'info', - message: `npm ${cmd.join(' ')}`, + updateCommandLog({ + command: `npm ${cmd.join(' ')}`, }) ); }); diff --git a/app/components/packages/details/PackageDependencies.js b/app/components/packages/details/PackageDependencies.js index b0378ecf..2a44f310 100644 --- a/app/components/packages/details/PackageDependencies.js +++ b/app/components/packages/details/PackageDependencies.js @@ -10,36 +10,47 @@ import ListItemText from '@material-ui/core/ListItemText'; import styles from './styles'; -const PackageDependencies = ({ classes, dependencies }) => ( - -
- {`Dependencies (${dependencies.length})`} -
- - - {dependencies.map((item) => ( - - - {item.name} - - } - secondary={ - - {item.version} - - } - /> - - ))} - -
-); +const PackageDependencies = ({ classes, dependencies }) => { + const dependenciesNames = Object.keys(dependencies); + const enhancedDependencies = dependenciesNames.map((dependency) => ({ + name: dependency, + version: dependencies[dependency], + })); + + return ( + +
+ {`Dependencies (${enhancedDependencies.length})`} +
+ + + {enhancedDependencies.map((dependency) => ( + + + {dependency.name} + + } + secondary={ + + {dependency.version} + + } + /> + + ))} + +
+ ); +}; PackageDependencies.propTypes = { classes: objectOf(string).isRequired, - dependencies: arrayOf(objectOf(string)).isRequired, + dependencies: objectOf(string).isRequired, }; export default withStyles(styles)(PackageDependencies); diff --git a/app/components/packages/details/PackageDetails.js b/app/components/packages/details/PackageDetails.js index 54cb32a4..e29b376b 100644 --- a/app/components/packages/details/PackageDetails.js +++ b/app/components/packages/details/PackageDetails.js @@ -338,18 +338,6 @@ const PackageDetails = ({ classes, showInstallationOptions }) => { ); - useEffect(() => { - if (active && active.dependencies) { - const dependenciesNames = Object.keys(active.dependencies); - const dependenciesToArray = dependenciesNames.map((dep) => ({ - name: dep, - version: active.dependencies[dep], - })); - - setDependencies(dependenciesToArray); - } - }, [active]); - return (
{ > {({ TransitionProps }) => ( - + )} diff --git a/app/components/packages/details/styles.js b/app/components/packages/details/styles.js index 179b86fd..37fa4954 100644 --- a/app/components/packages/details/styles.js +++ b/app/components/packages/details/styles.js @@ -11,7 +11,7 @@ const styles = (theme) => ({ }, header: { ...defaultFont, - backgroundColor: lighten(grayColor, 0.75), + backgroundColor: lighten(grayColor, 0.85), fontSize: 20, fontWeight: 400, padding: theme.spacing(1), diff --git a/app/components/packages/filters/Filters.js b/app/components/packages/filters/Filters.js index 0434ecc7..f2a4c9ba 100755 --- a/app/components/packages/filters/Filters.js +++ b/app/components/packages/filters/Filters.js @@ -55,8 +55,8 @@ const Filters = ({ classes, mode, close, listFilters }) => { setFilters(remove(idx, 1, filters)); break; case filterType === 'name': - const newFilters = filters.map((filterDetails) => { - if (filterDetails.filterType === 'name') { + const newFilters = filters.map(({ filterType, filterValue }) => { + if (filterType === 'name') { return { filterType, filterValue }; } @@ -98,139 +98,123 @@ const Filters = ({ classes, mode, close, listFilters }) => { return (
-
-
-
- - - {iMessage('label', 'packageName')} - - - - {iMessage('label', 'packageNameInput')} - -
- - { - const { value } = e.currentTarget; - - if (value && value.length) { - addFilter({ - filterType: 'name', - filterValue: value, - }); - } - }} - /> -
-
-
-
-
- - - - Group - - - {iMessage('label', 'groupType')} - -1} - onChange={() => - addFilter({ - filterType: 'group', - filterValue: 'dependencies', - }) - } - value="dependencies" - /> - } - label="Dependencies" - /> - -1} - onChange={() => - addFilter({ - filterType: 'group', - filterValue: 'devDependencies', - }) - } - value="devDependencies" - /> - } - label="Dev dependencies" - /> - -1} - onChange={() => - addFilter({ - filterType: 'group', - filterValue: 'optionalDependencies', - }) - } - value="optionalDependencies" - /> - } - label="Optional dependencies" + + + + {iMessage('label', 'packageNameInput')} + +
+ + { + const { value } = e.currentTarget; + + if (value && value.length) { + addFilter({ + filterType: 'name', + filterValue: value, + }); + } + }} /> - - - - - - {iMessage('label', 'status')} - - - {iMessage('label', 'byOutdated')} - -1} - onChange={() => - addFilter({ - filterType: 'version', - filterValue: 'isOutdated', - }) - } - value="isOutdated" - /> - } - label="Outdated" - /> - - - -
- - -
+
+
+
+ + + {iMessage('label', 'groupType')} + -1} + onChange={() => + addFilter({ + filterType: 'group', + filterValue: 'dependencies', + }) + } + value="dependencies" + /> + } + label="Dependencies" + /> + -1} + onChange={() => + addFilter({ + filterType: 'group', + filterValue: 'devDependencies', + }) + } + value="devDependencies" + /> + } + label="Dev dependencies" + /> + -1} + onChange={() => + addFilter({ + filterType: 'group', + filterValue: 'optionalDependencies', + }) + } + value="optionalDependencies" + /> + } + label="Optional dependencies" + /> + + + + + + {iMessage('label', 'byOutdated')} + -1} + onChange={() => + addFilter({ + filterType: 'version', + filterValue: 'isOutdated', + }) + } + value="isOutdated" + /> + } + label="Outdated" + /> + + + +
+ +
); diff --git a/app/components/packages/filters/styles.js b/app/components/packages/filters/styles.js index 404a3c46..8e26dd81 100644 --- a/app/components/packages/filters/styles.js +++ b/app/components/packages/filters/styles.js @@ -3,12 +3,10 @@ import { defaultFont } from 'styles/variables'; const styles = (theme) => ({ root: { - minWidth: 400, - padding: theme.spacing(1), - '& > h2': { - color: theme.palette.primary.dark, - fontSize: 18, - }, + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + padding: theme.spacing(2), }, actions: { display: 'flex', @@ -17,13 +15,6 @@ const styles = (theme) => ({ marginRight: theme.spacing(1), }, }, - flexContainer: { display: 'flex' }, - filterItems: { - display: 'flex', - flexDirection: 'column', - justifyContent: 'space-between', - padding: theme.spacing(1), - }, bottomDivider: { margin: theme.spacing(1), }, @@ -57,8 +48,8 @@ const styles = (theme) => ({ ...defaultFont, padding: theme.spacing(1), }, - toolbar: { - height: 10, + controlLabel: { + fontSize: 12, }, }); diff --git a/app/components/sidebar/Container.js b/app/components/sidebar/Container.js index cf9a15fd..3e51b645 100755 --- a/app/components/sidebar/Container.js +++ b/app/components/sidebar/Container.js @@ -1,11 +1,11 @@ +import { ipcRenderer } from 'electron'; import React from 'react'; import cn from 'classnames'; import { objectOf, string } from 'prop-types'; import { useState, useEffect, useCallback } from 'react'; import { useDispatch, useMappedState } from 'redux-react-hook'; -import { ipcRenderer } from 'electron'; import { withStyles } from '@material-ui/core/styles'; -import Drawer from '@material-ui/core/Drawer'; +import { Drawer, Typography } from '@material-ui/core'; import { setActivePage } from 'models/ui/actions'; import { installPackageJson } from 'models/packages/actions'; @@ -13,11 +13,12 @@ import { setMode } from 'models/common/actions'; import { runDedupe, runCache } from 'models/npm/actions'; import { iMessage, shrinkDirectory, showDialog } from 'commons/utils'; import Sidebar from './Sidebar'; +import Log from './Log'; import styles from './styles'; const mapState = ({ - common: { mode, directory }, + common: { mode, directory, commandLog }, packages: { project: projectInfo, packagesData, @@ -42,6 +43,7 @@ const mapState = ({ packagesOutdated, notifications, npmEnv, + commandLog, }); const AppSidebar = ({ classes, className }) => { @@ -59,6 +61,7 @@ const AppSidebar = ({ classes, className }) => { notifications, fromSearch, npmEnv, + commandLog, } = useMappedState(mapState); const packagesItems = [ @@ -194,16 +197,12 @@ const AppSidebar = ({ classes, className }) => { }, []); return ( -
- +
{ dedupe={dedupe} cache={cache} /> - -
+ +
+ ); }; diff --git a/app/components/sidebar/Log.js b/app/components/sidebar/Log.js new file mode 100644 index 00000000..81903e0c --- /dev/null +++ b/app/components/sidebar/Log.js @@ -0,0 +1,49 @@ +import React, { useState, useEffect } from 'react'; +import { string, objectOf, func, bool, object, arrayOf } from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { CircularProgress, Typography } from '@material-ui/core'; + +import styles from './styles'; + +const Log = ({ classes, log }) => { + const [commandLog, setCommandLog] = useState(null); + + useEffect(() => { + if (!log.length) { + return setCommandLog(null); + } + + const [command] = log; + const { runningCommand } = command; + const newCommand = runningCommand.substr(0, runningCommand.indexOf('--')); + + setCommandLog({ + runningCommand: newCommand, + timestamp: command.timestamp, + }); + }, [log]); + + if (!commandLog) { + return null; + } + + return ( +
+ + {`running: ${commandLog.runningCommand}`} + +
+ ); +}; + +Log.propTypes = { + classes: objectOf(string).isRequired, + log: arrayOf(object), +}; + +export default withStyles(styles)(Log); diff --git a/app/components/sidebar/Sidebar.js b/app/components/sidebar/Sidebar.js index 07acbfba..e1a1cc42 100755 --- a/app/components/sidebar/Sidebar.js +++ b/app/components/sidebar/Sidebar.js @@ -1,11 +1,15 @@ import React from 'react'; import { string, objectOf, func, bool, object, arrayOf } from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; import Tabs from './tabs/Tabs'; import { PackagesTab, ActionsTab, HistoryTab } from './tabs'; import Logo from '../common/logo/Logo'; +import styles from './styles'; + const Sidebar = ({ + classes, loading, fromSearch, mode, @@ -22,7 +26,7 @@ const Sidebar = ({ return ( <> - + ({ drawer: { width: drawerWidth, - borderRight: 0, + borderRight: '0 !important', [theme.breakpoints.up('sm')]: { flexShrink: 0, }, }, + flex: { + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + height: '100%', + }, + tabs: { + flexGrow: 2, + }, + log: { + display: 'flex', + justifyContent: 'space-between', + padding: theme.spacing(1), + }, + command: { + fontSize: 12, + color: lighten(grayColor, 0.1), + wordWrap: 'break-word', + }, }); export default styles; diff --git a/app/components/sidebar/tabs/Tabs.js b/app/components/sidebar/tabs/Tabs.js index 09d92a7f..dc66444e 100644 --- a/app/components/sidebar/tabs/Tabs.js +++ b/app/components/sidebar/tabs/Tabs.js @@ -1,5 +1,6 @@ import React, { useState } from 'react'; import { withStyles } from '@material-ui/core/styles'; +import cn from 'classnames'; import { bool, node, objectOf, string } from 'prop-types'; import Typography from '@material-ui/core/Typography'; import AppBar from '@material-ui/core/AppBar'; @@ -22,11 +23,15 @@ TabContainer.propTypes = { loading: bool, }; -const SidebarTabs = ({ classes, children }) => { +const SidebarTabs = ({ classes, className, children }) => { const [value, setValue] = useState(0); return ( -
+
setValue(tabValue)}> { SidebarTabs.propTypes = { children: node.isRequired, classes: objectOf(string).isRequired, + className: string, }; export default withStyles(styles)(SidebarTabs); diff --git a/app/components/sidebar/tabs/packages/Packages.js b/app/components/sidebar/tabs/packages/Packages.js index bca4527a..1ee02d2c 100755 --- a/app/components/sidebar/tabs/packages/Packages.js +++ b/app/components/sidebar/tabs/packages/Packages.js @@ -16,7 +16,13 @@ import { iMessage } from 'commons/utils'; import styles from './styles'; const Loader = ({ classes }) => ( -
Loading..
+ + Loading.. + ); Loader.propTypes = { diff --git a/app/components/sidebar/tabs/packages/styles.js b/app/components/sidebar/tabs/packages/styles.js index d913966c..f1f86a9a 100755 --- a/app/components/sidebar/tabs/packages/styles.js +++ b/app/components/sidebar/tabs/packages/styles.js @@ -43,9 +43,8 @@ const styles = (theme) => ({ }, loading: { ...defaultFont, - paddingTop: theme.spacing(1), fontSize: 14, - color: darken(grayColor, 0.5), + paddingTop: theme.spacing(1), }, listItem: { margin: 0, diff --git a/app/components/topbar/Settings.js b/app/components/topbar/Settings.js index f2167a57..1f897765 100644 --- a/app/components/topbar/Settings.js +++ b/app/components/topbar/Settings.js @@ -28,7 +28,7 @@ const Settings = ({ classes, ...restProps }) => { Rows per page} /> - Rows per page + Set rows