Skip to content
This repository has been archived by the owner on May 2, 2022. It is now read-only.

Add search box for installed apps page #316

Merged
merged 3 commits into from
Sep 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,20 @@
"decompress": "4.2.0",
"download": "7.1.0",
"electron-is-dev": "1.1.0",
"electron-packager": "14.0.5",
"electron-packager": "14.0.6",
"electron-settings": "3.2.0",
"electron-updater": "4.1.2",
"electron-window-state": "5.0.3",
"follow-redirects": "1.8.1",
"follow-redirects": "1.9.0",
"fs-extra": "8.1.0",
"icon-gen": "2.0.0",
"is-url": "1.2.4",
"jimp": "0.6.8",
"jimp": "0.8.2",
"read-chunk": "3.2.0",
"sudo-prompt": "9.0.0",
"tmp": "0.1.0",
"windows-shortcuts": "0.1.6",
"yargs-parser": "13.1.1"
"yargs-parser": "14.0.0"
},
"devDependencies": {
"@material-ui/core": "3.9.3",
Expand All @@ -62,7 +62,7 @@
"classnames": "2.2.6",
"concurrently": "4.1.2",
"cross-env": "5.2.1",
"electron": "6.0.7",
"electron": "6.0.9",
"electron-builder": "21.2.0",
"eslint": "6.1.0",
"eslint-config-airbnb": "18.0.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/pages/home/search-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class EnhancedAppBar extends React.Component {
</IconButton>
<IconButton
color="default"
aria-label="Clear"
aria-label="Search"
onClick={onResetThenGetHits}
>
<KeyboardReturnIcon />
Expand Down
11 changes: 9 additions & 2 deletions src/components/pages/installed/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import connectComponent from '../../../helpers/connect-component';
import AppCard from '../../shared/app-card';
import EmptyState from '../../shared/empty-state';

import SearchBox from './search-box';

import { fetchLatestTemplateVersionAsync } from '../../../state/general/actions';
import { updateAllApps } from '../../../state/app-management/actions';
import { getOutdatedAppsAsList } from '../../../state/app-management/utils';
import { getOutdatedAppsAsList, filterApps } from '../../../state/app-management/utils';

const styles = (theme) => ({
root: {
Expand Down Expand Up @@ -84,6 +86,11 @@ const Installed = (props) => {
</Button>
</Toolbar>
</AppBar>
<Grid container spacing={16}>
<Grid item xs={12}>
<SearchBox />
</Grid>
</Grid>
<div className={classes.scrollContainer}>
<Grid spacing={16} container className={classes.grid}>
<Grid item xs={12}>
Expand Down Expand Up @@ -138,7 +145,7 @@ Installed.propTypes = {
};

const mapStateToProps = (state) => ({
apps: state.appManagement.apps,
apps: filterApps(state.appManagement.apps, state.installed.query),
fetchingLatestTemplateVersion: state.general.fetchingLatestTemplateVersion,
outdatedAppCount: getOutdatedAppsAsList(state).length,
});
Expand Down
142 changes: 142 additions & 0 deletions src/components/pages/installed/search-box.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React from 'react';
import PropTypes from 'prop-types';

import CloseIcon from '@material-ui/icons/Close';
import IconButton from '@material-ui/core/IconButton';
import Paper from '@material-ui/core/Paper';
import SearchIcon from '@material-ui/icons/Search';
import Typography from '@material-ui/core/Typography';

import connectComponent from '../../../helpers/connect-component';

import {
updateQuery,
} from '../../../state/installed/actions';

const styles = (theme) => ({
toolbarSearchContainer: {
flex: 1,
zIndex: 10,
position: 'relative',
borderRadius: 0,
},
toolbarSectionSearch: {
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
height: 48,
margin: '0 auto',
},
searchBarText: {
lineHeight: 1.5,
padding: '0 4px',
flex: 1,
userSelect: 'none',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
transform: 'translateY(-1px)',
fontWeight: 'normal',
fontSize: 18,
},
input: {
font: 'inherit',
border: 0,
display: 'block',
verticalAlign: 'middle',
whiteSpace: 'normal',
background: 'none',
margin: 0,
color: theme.palette.text.primary,
width: '100%',
'&:focus': {
outline: 0,
},
'&::placeholder': {
color: theme.palette.text.secondary,
},
},
searchIcon: {
paddingLeft: 24,
paddingRight: 6,
fill: theme.palette.text.primary,
[theme.breakpoints.down('xs')]: {
paddingLeft: 12,
},
},
searchButton: {
[theme.breakpoints.up('md')]: {
display: 'none',
},
},
});

class EnhancedAppBar extends React.Component {
render() {
const {
classes,
onUpdateQuery,
query,
} = this.props;

const clearSearchAction = query.length > 0 && (
<IconButton
color="default"
aria-label="Clear"
onClick={() => onUpdateQuery('')}
>
<CloseIcon />
</IconButton>
);

return (
<Paper elevation={2} className={classes.toolbarSearchContainer}>
<div className={classes.toolbarSectionSearch}>
<SearchIcon
className={classes.searchIcon}
/>
<Typography
className={classes.searchBarText}
color="inherit"
variant="h6"
>
<input
className={classes.input}
onChange={(e) => onUpdateQuery(e.target.value)}
onInput={(e) => onUpdateQuery(e.target.value)}
placeholder="Search installed apps..."
ref={(inputBox) => { this.inputBox = inputBox; }}
value={query}
/>
</Typography>
{clearSearchAction}
</div>
</Paper>
);
}
}

EnhancedAppBar.defaultProps = {
query: '',
};

EnhancedAppBar.propTypes = {
classes: PropTypes.object.isRequired,
onUpdateQuery: PropTypes.func.isRequired,
query: PropTypes.string,
};

const mapStateToProps = (state) => ({
query: state.installed.query,
});

const actionCreators = {
updateQuery,
};

export default connectComponent(
EnhancedAppBar,
mapStateToProps,
actionCreators,
styles,
);
3 changes: 3 additions & 0 deletions src/constants/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ export const DIALOG_ABOUT_CLOSE = 'DIALOG_ABOUT_CLOSE';
export const DIALOG_CHOOSE_ENGINE_CLOSE = 'DIALOG_CHOOSE_ENGINE_CLOSE';
export const DIALOG_CHOOSE_ENGINE_FORM_UPDATE = 'DIALOG_CHOOSE_ENGINE_FORM_UPDATE';
export const DIALOG_CHOOSE_ENGINE_OPEN = 'DIALOG_CHOOSE_ENGINE_OPEN';

// Installed
export const INSTALLED_UPDATE_QUERY = 'INSTALLED_UPDATE_QUERY';
19 changes: 19 additions & 0 deletions src/state/app-management/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,22 @@ export const getAppCount = (state) => {
const { apps } = state.appManagement;
return Object.values(apps).length;
};

export const filterApps = (apps, query) => {
if (query.length < 1) return apps;

const processedQuery = query.trim().toLowerCase();

const newApps = {};
const keys = Object.keys(apps);
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i];
const app = apps[key];
if (app.name.toLowerCase().includes(processedQuery)
|| app.url.toLowerCase().includes(processedQuery)) {
newApps[key] = app;
}
}

return newApps;
};
2 changes: 2 additions & 0 deletions src/state/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import general from './general/reducers';
import home from './home/reducers';
import preferences from './preferences/reducers';
import router from './router/reducers';
import installed from './installed/reducers';

const rootReducer = combineReducers({
appManagement,
Expand All @@ -21,6 +22,7 @@ const rootReducer = combineReducers({
dialogSetInstallationPath,
general,
home,
installed,
preferences,
router,
});
Expand Down
8 changes: 8 additions & 0 deletions src/state/installed/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {
INSTALLED_UPDATE_QUERY,
} from '../../constants/actions';

export const updateQuery = (query) => ({
type: INSTALLED_UPDATE_QUERY,
query,
});
16 changes: 16 additions & 0 deletions src/state/installed/reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { combineReducers } from 'redux';

import {
INSTALLED_UPDATE_QUERY,
} from '../../constants/actions';

const query = (state = '', action) => {
switch (action.type) {
case INSTALLED_UPDATE_QUERY: return action.query;
default: return state;
}
};

export default combineReducers({
query,
});
6 changes: 3 additions & 3 deletions template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
"repository": "https://github.com/quanglam2807/webcatalog",
"author": "Quang Lam <[email protected]>",
"dependencies": {
"electron": "6.0.7",
"electron": "6.0.9",
"electron-is-dev": "1.1.0",
"electron-settings": "3.2.0",
"electron-spellchecker": "2.2.0",
"electron-window-state": "5.0.3",
"follow-redirects": "1.8.1",
"follow-redirects": "1.9.0",
"fs-extra": "8.1.0",
"jimp": "0.6.8",
"jimp": "0.8.2",
"menubar": "6.0.7",
"node-fetch": "2.6.0",
"request": "2.88.0",
Expand Down
Loading