-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UI: resplit one component per file, clean a bit of JS style (thanks #127
- Loading branch information
Showing
15 changed files
with
448 additions
and
354 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
jsclient/src/features/editpanel/Feed/FilterSettings/Line.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import { createSelector } from "reselect"; | ||
import { connect, useDispatch } from "react-redux"; | ||
// material ui components | ||
import Select from "@material-ui/core/Select"; | ||
import MenuItem from "@material-ui/core/MenuItem"; | ||
import TextField from "@material-ui/core/TextField"; | ||
import IconButton from "@material-ui/core/IconButton"; | ||
import FormControl from "@material-ui/core/FormControl"; | ||
// material icons | ||
import MinusIcon from "@material-ui/icons/Remove"; | ||
import ArrowUpIcon from "@material-ui/icons/ArrowUpward"; | ||
import ArrowDownIcon from "@material-ui/icons/ArrowDownward"; | ||
// jarr | ||
import style from "./style"; | ||
import { moveUpFilter, moveDownFilter, editFilter, removeFilter | ||
} from "../../editSlice"; | ||
// constants | ||
const FiltersAction = { "mark as read": "mark as read", | ||
"mark as unread": "mark as unread (default)", | ||
"mark as favorite": "mark as liked", | ||
"mark as unliked": "mark as unliked (default)", | ||
"skipped": "skip", | ||
"unskipped": "unskip (default)", | ||
"allow clustering": "allow clustering (default)", | ||
"disallow clustering": "forbid clustering"}; | ||
const FiltersType = { "regex": "title match (regex)", | ||
"simple match": "title contains", | ||
"exact match": "title is", | ||
"tag match": "one of the tag is", | ||
"tag contains": "one of the tags contains" }; | ||
const FiltersTrigger = {"match": "If", "no match": "If not", }; | ||
|
||
const getFilter = (state, props) => state.edit.loadedObj.filters[props.index]; | ||
const makeGetFilter = () => createSelector([ getFilter ], (filter) => filter); | ||
|
||
const makeMapStateToProps = () => { | ||
const madeGetFilter = makeGetFilter(); | ||
const mapStateToProps = (state, props) => { | ||
return { filter: madeGetFilter(state, props) }; | ||
} | ||
return mapStateToProps | ||
} | ||
|
||
function FilterSettingLine({ index, position, filter }) { | ||
let moveUpBtn; | ||
let moveDownBtn; | ||
const dispatch = useDispatch(); | ||
const classes = style(); | ||
if (position !== "first") { | ||
moveUpBtn = ( | ||
<IconButton onClick={() => dispatch(moveUpFilter(index))} | ||
className={classes.editPanelFilterArrow} color="primary"> | ||
<ArrowUpIcon /> | ||
</IconButton>); | ||
} | ||
if (position !== "last") { | ||
moveDownBtn = ( | ||
<IconButton onClick={() => dispatch(moveDownFilter(index))} | ||
className={classes.editPanelFilterArrow} color="primary"> | ||
<ArrowDownIcon /> | ||
</IconButton> | ||
); | ||
} | ||
const onChange = (key) => (e) => dispatch(editFilter({ index, key, value: e.target.value })); | ||
return ( | ||
<div className={classes.editPanelFilter}> | ||
<div className={classes.editPanelFilterArrows}> | ||
{moveUpBtn}{moveDownBtn} | ||
</div> | ||
<FormControl key="trigger" className={classes.editPanelFilterItem}> | ||
<Select value={filter["action on"]} onChange={onChange("action on")}> | ||
{Object.entries(FiltersTrigger).map(([trigger, label]) => ( | ||
<MenuItem key={trigger} value={trigger}>{label}</MenuItem> | ||
))} | ||
</Select> | ||
</FormControl> | ||
<FormControl key="type" className={classes.editPanelFilterItem}> | ||
<Select value={filter.type} onChange={onChange("type")}> | ||
{Object.entries(FiltersType).map(([type, label]) => ( | ||
<MenuItem key={type} value={type}>{label}</MenuItem> | ||
))} | ||
</Select> | ||
</FormControl> | ||
<FormControl key="pattern" className={classes.editPanelFilterItem}> | ||
<TextField value={filter.pattern} required onChange={onChange("pattern")} /> | ||
</FormControl> | ||
<FormControl key="action" className={classes.editPanelFilterItem}> | ||
<Select value={filter.action} onChange={onChange("action")} > | ||
{Object.entries(FiltersAction).map(([action, label]) => ( | ||
<MenuItem key={action} value={action}>{label}</MenuItem> | ||
))} | ||
</Select> | ||
</FormControl> | ||
<IconButton color="primary" onClick={() => dispatch(removeFilter(index))} | ||
className={classes.editPanelFilterDelBtn}> | ||
<MinusIcon /> | ||
</IconButton> | ||
</div> | ||
); | ||
} | ||
|
||
FilterSettingLine.propTypes = { | ||
index: PropTypes.number.isRequired, | ||
position: PropTypes.string.isRequired, | ||
}; | ||
|
||
export default connect(makeMapStateToProps)(FilterSettingLine); |
86 changes: 86 additions & 0 deletions
86
jsclient/src/features/editpanel/Feed/FilterSettings/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import React, { useState } from "react"; | ||
import { connect } from "react-redux"; | ||
import PropTypes from "prop-types"; | ||
// material ui components | ||
import Fab from "@material-ui/core/Fab"; | ||
import Alert from "@material-ui/lab/Alert"; | ||
import Typography from "@material-ui/core/Typography"; | ||
import IconButton from "@material-ui/core/IconButton"; | ||
import ExpansionPanel from "@material-ui/core/ExpansionPanel"; | ||
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; | ||
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; | ||
// material icons | ||
import HelpIcon from "@material-ui/icons/Help"; | ||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; | ||
import PlusIcon from "@material-ui/icons/Add"; | ||
// jarr | ||
import editPanelStyle from "../../editPanelStyle"; | ||
import style from "./style"; | ||
import FilterSettingLine from "./Line"; | ||
import { addFilter } from "../../editSlice"; | ||
|
||
export function mapStateToProps(state) { | ||
return { filters: (state.edit.loadedObj.filters | ||
? state.edit.loadedObj.filters | ||
: []).map((filter) => filter.id), | ||
}; | ||
}; | ||
|
||
const mapDispatchToProps = (dispatch) => ({ | ||
add() { | ||
dispatch(addFilter()); | ||
}, | ||
}); | ||
|
||
function FilterSettings({ filters, add }) { | ||
const filterClasses = style(); | ||
const classes = editPanelStyle(); | ||
const [showHelp, setShowHelp] = useState(false); | ||
let help; | ||
if(showHelp) { | ||
help = ( | ||
<Alert> | ||
<p>Filters are processed in the order you place them on every new articles that will be fetched for that feed.</p> | ||
<p>Through filters you can modify the read, liked status, allow or forbid clustering new articles. You can also skip entierly the creation of an article match a filter.</p> | ||
<p>Filters are processed one after another and you can revert the filter you applied just before. For example you might want to skip every article which title contains "Python" and 'unskip' every article containing "Monthy". This way you would see every article mentionning "Monthy Python" but none about python solely.</p> | ||
</Alert> | ||
); | ||
} | ||
return ( | ||
<ExpansionPanel className={classes.editPanelCluster} > | ||
<ExpansionPanelSummary | ||
expandIcon={<ExpandMoreIcon />} | ||
aria-controls="panel1a-content" | ||
id="panel1a-header" | ||
> | ||
<Typography className={classes.heading}>Filters Settings</Typography> | ||
</ExpansionPanelSummary> | ||
<ExpansionPanelDetails className={classes.editPanelClusterSettings}> | ||
<IconButton onClick={() => setShowHelp(!showHelp)} | ||
className={classes.showHelpButton}> | ||
<HelpIcon /> | ||
</IconButton> | ||
{help} | ||
{filters.map((filter, i) => | ||
<FilterSettingLine | ||
key={filter} | ||
index={i} | ||
position={i === 0 ? "first": (i === filters.length -1 ? "last": "none")} | ||
/> | ||
)} | ||
<div className={filterClasses.editPanelFilterAddBtn}> | ||
<Fab onClick={add} color="primary"> | ||
<PlusIcon /> | ||
</Fab> | ||
</div> | ||
</ExpansionPanelDetails> | ||
</ExpansionPanel> | ||
); | ||
} | ||
|
||
FilterSettings.propTypes = { | ||
filters: PropTypes.array.isRequired, | ||
add: PropTypes.func.isRequired, | ||
}; | ||
|
||
export default connect(mapStateToProps, mapDispatchToProps)(FilterSettings); |
61 changes: 61 additions & 0 deletions
61
jsclient/src/features/editpanel/Feed/FilterSettings/style.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { makeStyles, Theme, createStyles } from "@material-ui/core/styles"; | ||
|
||
export default makeStyles((theme: Theme) => | ||
createStyles({ | ||
editPanelFilter: { | ||
display: "table", | ||
alignItems: "baseline", | ||
flexDirection: "row", | ||
marginBottom: 25, | ||
marginLeft: 16, | ||
marginRight: 16 | ||
}, | ||
editPanelFilterItem: { | ||
display: "table-cell", | ||
"& .MuiInput-root": { | ||
height: 32, | ||
justifyContent: "center" | ||
}, | ||
"& .MuiTextField-root": { | ||
height: 32, | ||
justifyContent: "center", | ||
"& input": { | ||
padding: 0 | ||
} | ||
} | ||
}, | ||
editPanelFilterArrows: { | ||
display: "flex", | ||
flexDirection: "column", | ||
justifyContent: "center", | ||
left: 5, | ||
position: "absolute" | ||
}, | ||
editPanelFilterArrow: { | ||
position: "relative", | ||
padding: 0, | ||
"& svg": { | ||
height: 18, | ||
width: 18, | ||
} | ||
}, | ||
editPanelFilterAddBtn: { | ||
textAlign: "center", | ||
width: "100%", | ||
"& button": { | ||
minHeight: "unset", | ||
height: 35, | ||
width: 35, | ||
} | ||
}, | ||
editPanelFilterDelBtn: { | ||
position: "absolute", | ||
right: 0, | ||
padding: 8, | ||
"& svg": { | ||
height: 18, | ||
width: 18 | ||
} | ||
}, | ||
}), | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import { connect } from "react-redux"; | ||
// material components | ||
import Select from "@material-ui/core/Select"; | ||
import MenuItem from "@material-ui/core/MenuItem"; | ||
import FormControl from "@material-ui/core/FormControl"; | ||
import FormHelperText from "@material-ui/core/FormHelperText"; | ||
// jarr | ||
import editPanelStyle from "../editPanelStyle"; | ||
import { editLoadedObj } from "../editSlice"; | ||
|
||
function mapStateToProps(state) { | ||
return { link: state.edit.loadedObj.link, | ||
links: state.edit.loadedObj.links, | ||
}; | ||
} | ||
|
||
const mapDispatchToProp = (dispatch) => ({ | ||
edit(value) { | ||
dispatch(editLoadedObj({ key: "link", value })); | ||
} | ||
}); | ||
|
||
function ProposedLinks({ link, links, edit }) { | ||
const classes = editPanelStyle(); | ||
if (!links) { | ||
return null; | ||
} | ||
return ( | ||
<FormControl> | ||
<FormHelperText>Other possible feed link have been found :</FormHelperText> | ||
<Select variant="outlined" value={link} | ||
onChange={(e) => edit(e.target.value)} | ||
className={classes.editPanelInput} | ||
> | ||
{links.map((proposedLink) => ( | ||
<MenuItem key={`l${links.indexOf(proposedLink)}`} | ||
value={proposedLink}>{proposedLink}</MenuItem> | ||
))} | ||
</Select> | ||
</FormControl> | ||
); | ||
} | ||
|
||
ProposedLinks.propTypes = { | ||
link: PropTypes.string, | ||
links: PropTypes.array, | ||
edit: PropTypes.func.isRequired, | ||
}; | ||
|
||
export default connect(mapStateToProps, mapDispatchToProp)(ProposedLinks) |
Oops, something went wrong.