From d0be683b1e216e9211b4e49e550050ea914a5ca3 Mon Sep 17 00:00:00 2001 From: Gustav Andreasson Date: Mon, 1 Jan 2024 22:47:48 +0100 Subject: [PATCH] Attributes add to filter by click --- frontend/src/actions/processActions.js | 8 +-- .../Artists/Artists.component.js | 8 +-- .../{ => Attributes}/Artists/index.js | 0 .../Attributes/Formats/Formats.component.js | 28 ++++++++++ .../Attributes/Formats/Formats.container.js | 11 ++++ .../Attributes/Formats/Formats.scss | 4 ++ .../components/Attributes/Formats/index.js | 1 + .../Attributes/Genres/Genres.component.js | 23 ++++++++ .../Attributes/Genres/Genres.container.js | 11 ++++ .../components/Attributes/Genres/Genres.scss | 4 ++ .../src/components/Attributes/Genres/index.js | 1 + .../Attributes/Price/Price.component.js | 5 ++ .../Attributes/Price/Price.container.js | 8 +++ .../src/components/Attributes/Price/index.js | 1 + .../Attributes/Year/Year.component.js | 17 ++++++ .../Attributes/Year/Year.container.js | 11 ++++ .../src/components/Attributes/Year/Year.scss | 4 ++ .../src/components/Attributes/Year/index.js | 1 + frontend/src/components/Attributes/index.js | 5 ++ .../Collection/Record/Record.component.js | 52 ++++++------------- .../Collection/Record/Record.container.js | 6 +-- .../RecordInfo/RecordInfo.component.js | 28 +++++----- .../RecordInfo/RecordInfo.container.js | 5 +- frontend/src/reducers/artistReducer.js | 5 -- frontend/src/reducers/collectionReducer.js | 5 ++ frontend/src/reducers/processReducer.js | 24 ++++----- 26 files changed, 193 insertions(+), 83 deletions(-) rename frontend/src/components/{ => Attributes}/Artists/Artists.component.js (57%) rename frontend/src/components/{ => Attributes}/Artists/index.js (100%) create mode 100644 frontend/src/components/Attributes/Formats/Formats.component.js create mode 100644 frontend/src/components/Attributes/Formats/Formats.container.js create mode 100644 frontend/src/components/Attributes/Formats/Formats.scss create mode 100644 frontend/src/components/Attributes/Formats/index.js create mode 100644 frontend/src/components/Attributes/Genres/Genres.component.js create mode 100644 frontend/src/components/Attributes/Genres/Genres.container.js create mode 100644 frontend/src/components/Attributes/Genres/Genres.scss create mode 100644 frontend/src/components/Attributes/Genres/index.js create mode 100644 frontend/src/components/Attributes/Price/Price.component.js create mode 100644 frontend/src/components/Attributes/Price/Price.container.js create mode 100644 frontend/src/components/Attributes/Price/index.js create mode 100644 frontend/src/components/Attributes/Year/Year.component.js create mode 100644 frontend/src/components/Attributes/Year/Year.container.js create mode 100644 frontend/src/components/Attributes/Year/Year.scss create mode 100644 frontend/src/components/Attributes/Year/index.js create mode 100644 frontend/src/components/Attributes/index.js diff --git a/frontend/src/actions/processActions.js b/frontend/src/actions/processActions.js index d9db7dc..709d91b 100644 --- a/frontend/src/actions/processActions.js +++ b/frontend/src/actions/processActions.js @@ -16,8 +16,8 @@ export const updateSearch = query => ({ query, }) -export const FILTER_YEAR = "FILTER_YEAR" -export const filterYear = year => ({ - type: FILTER_YEAR, - year, +export const ADD_FILTER = "ADD_FILTER" +export const addFilter = filter => ({ + type: ADD_FILTER, + filter, }) diff --git a/frontend/src/components/Artists/Artists.component.js b/frontend/src/components/Attributes/Artists/Artists.component.js similarity index 57% rename from frontend/src/components/Artists/Artists.component.js rename to frontend/src/components/Attributes/Artists/Artists.component.js index d7d6266..9277042 100644 --- a/frontend/src/components/Artists/Artists.component.js +++ b/frontend/src/components/Attributes/Artists/Artists.component.js @@ -1,12 +1,12 @@ import React, { Fragment } from "react" import Artist from "Components/Artist" -const Artists = ({ artists }) => - artists && - artists.map((artist, index) => ( +const Artists = ({ value }) => + value && + value.map((artist, index) => ( - {index < artists.length - 1 && " " + artist.delimiter + " "} + {index < value.length - 1 && " " + artist.delimiter + " "} )) export default Artists diff --git a/frontend/src/components/Artists/index.js b/frontend/src/components/Attributes/Artists/index.js similarity index 100% rename from frontend/src/components/Artists/index.js rename to frontend/src/components/Attributes/Artists/index.js diff --git a/frontend/src/components/Attributes/Formats/Formats.component.js b/frontend/src/components/Attributes/Formats/Formats.component.js new file mode 100644 index 0000000..4ab2dc3 --- /dev/null +++ b/frontend/src/components/Attributes/Formats/Formats.component.js @@ -0,0 +1,28 @@ +import React, { Fragment } from "react" +import { useTranslation } from "react-i18next" +import "./Formats.scss" + +const Formats = ({ value, filterFormat }) => { + const { t, i18n } = useTranslation() + return value + ? value + .filter(format => format.name !== "All-Media") + .map((format, index) => ( + + {(index && ", ") || null} + { + e.stopPropagation() + filterFormat(format) + }} + key={index} + > + {(format.qty > 1 ? format.qty + "x" : "") + t("format." + format.name, format.name)} + + + )) + : null +} + +export default Formats diff --git a/frontend/src/components/Attributes/Formats/Formats.container.js b/frontend/src/components/Attributes/Formats/Formats.container.js new file mode 100644 index 0000000..f37d3fa --- /dev/null +++ b/frontend/src/components/Attributes/Formats/Formats.container.js @@ -0,0 +1,11 @@ +import { connect } from "react-redux" +import { addFilter } from "Actions" +import Formats from "./Formats.component" + +const mapDispatchToProps = dispatch => ({ + filterFormat: format => { + dispatch(addFilter({ attribute: "formats", compare: "seq", value: format.name })) + }, +}) + +export default connect(null, mapDispatchToProps)(Formats) diff --git a/frontend/src/components/Attributes/Formats/Formats.scss b/frontend/src/components/Attributes/Formats/Formats.scss new file mode 100644 index 0000000..a616e39 --- /dev/null +++ b/frontend/src/components/Attributes/Formats/Formats.scss @@ -0,0 +1,4 @@ +.format { + color: #0000aa; + cursor: pointer; +} diff --git a/frontend/src/components/Attributes/Formats/index.js b/frontend/src/components/Attributes/Formats/index.js new file mode 100644 index 0000000..ecef5e5 --- /dev/null +++ b/frontend/src/components/Attributes/Formats/index.js @@ -0,0 +1 @@ +export { default } from "./Formats.container" diff --git a/frontend/src/components/Attributes/Genres/Genres.component.js b/frontend/src/components/Attributes/Genres/Genres.component.js new file mode 100644 index 0000000..5327067 --- /dev/null +++ b/frontend/src/components/Attributes/Genres/Genres.component.js @@ -0,0 +1,23 @@ +import React, { Fragment } from "react" +import "./Genres.scss" + +const Genres = ({ value, filterGenre }) => + value + ? value.map((genre, index) => ( + + {(index && ", ") || null} + { + e.stopPropagation() + filterGenre(genre) + }} + key={index} + > + {genre} + + + )) + : null + +export default Genres diff --git a/frontend/src/components/Attributes/Genres/Genres.container.js b/frontend/src/components/Attributes/Genres/Genres.container.js new file mode 100644 index 0000000..ec5ea71 --- /dev/null +++ b/frontend/src/components/Attributes/Genres/Genres.container.js @@ -0,0 +1,11 @@ +import { connect } from "react-redux" +import { addFilter } from "Actions" +import Genres from "./Genres.component" + +const mapDispatchToProps = dispatch => ({ + filterGenre: genre => { + dispatch(addFilter({ attribute: "genres", compare: "seq", value: genre })) + }, +}) + +export default connect(null, mapDispatchToProps)(Genres) diff --git a/frontend/src/components/Attributes/Genres/Genres.scss b/frontend/src/components/Attributes/Genres/Genres.scss new file mode 100644 index 0000000..d408a80 --- /dev/null +++ b/frontend/src/components/Attributes/Genres/Genres.scss @@ -0,0 +1,4 @@ +.genre { + color: #0000aa; + cursor: pointer; +} diff --git a/frontend/src/components/Attributes/Genres/index.js b/frontend/src/components/Attributes/Genres/index.js new file mode 100644 index 0000000..ac20ca3 --- /dev/null +++ b/frontend/src/components/Attributes/Genres/index.js @@ -0,0 +1 @@ +export { default } from "./Genres.container" diff --git a/frontend/src/components/Attributes/Price/Price.component.js b/frontend/src/components/Attributes/Price/Price.component.js new file mode 100644 index 0000000..36b4c13 --- /dev/null +++ b/frontend/src/components/Attributes/Price/Price.component.js @@ -0,0 +1,5 @@ +import React from "react" + +const Price = ({ value, rate }) => <>{value && (value * rate).toFixed(2)} + +export default Price diff --git a/frontend/src/components/Attributes/Price/Price.container.js b/frontend/src/components/Attributes/Price/Price.container.js new file mode 100644 index 0000000..ad43486 --- /dev/null +++ b/frontend/src/components/Attributes/Price/Price.container.js @@ -0,0 +1,8 @@ +import { connect } from "react-redux" +import Price from "./Price.component" + +const mapStateToProps = state => ({ + rate: state.collection.rate, +}) + +export default connect(mapStateToProps)(Price) diff --git a/frontend/src/components/Attributes/Price/index.js b/frontend/src/components/Attributes/Price/index.js new file mode 100644 index 0000000..b081b71 --- /dev/null +++ b/frontend/src/components/Attributes/Price/index.js @@ -0,0 +1 @@ +export { default } from "./Price.container" diff --git a/frontend/src/components/Attributes/Year/Year.component.js b/frontend/src/components/Attributes/Year/Year.component.js new file mode 100644 index 0000000..e02d307 --- /dev/null +++ b/frontend/src/components/Attributes/Year/Year.component.js @@ -0,0 +1,17 @@ +import React from "react" +import "./Year.scss" + +const Year = ({ value, filterYear }) => + value ? ( + { + e.stopPropagation() + filterYear(value) + }} + > + {value} + + ) : null + +export default Year diff --git a/frontend/src/components/Attributes/Year/Year.container.js b/frontend/src/components/Attributes/Year/Year.container.js new file mode 100644 index 0000000..3445014 --- /dev/null +++ b/frontend/src/components/Attributes/Year/Year.container.js @@ -0,0 +1,11 @@ +import { connect } from "react-redux" +import { addFilter } from "Actions" +import Year from "./Year.component" + +const mapDispatchToProps = dispatch => ({ + filterYear: year => { + dispatch(addFilter({ attribute: "year", compare: "eq", value: year })) + }, +}) + +export default connect(null, mapDispatchToProps)(Year) diff --git a/frontend/src/components/Attributes/Year/Year.scss b/frontend/src/components/Attributes/Year/Year.scss new file mode 100644 index 0000000..aecc126 --- /dev/null +++ b/frontend/src/components/Attributes/Year/Year.scss @@ -0,0 +1,4 @@ +.year { + color: #0000aa; + cursor: pointer; +} diff --git a/frontend/src/components/Attributes/Year/index.js b/frontend/src/components/Attributes/Year/index.js new file mode 100644 index 0000000..0302298 --- /dev/null +++ b/frontend/src/components/Attributes/Year/index.js @@ -0,0 +1 @@ +export { default } from "./Year.container" diff --git a/frontend/src/components/Attributes/index.js b/frontend/src/components/Attributes/index.js new file mode 100644 index 0000000..59e49fc --- /dev/null +++ b/frontend/src/components/Attributes/index.js @@ -0,0 +1,5 @@ +export { default as Artists } from "./Artists" +export { default as Formats } from "./Formats" +export { default as Genres } from "./Genres" +export { default as Price } from "./Price" +export { default as Year } from "./Year" diff --git a/frontend/src/components/Collection/Record/Record.component.js b/frontend/src/components/Collection/Record/Record.component.js index f8f66b3..78ebc82 100644 --- a/frontend/src/components/Collection/Record/Record.component.js +++ b/frontend/src/components/Collection/Record/Record.component.js @@ -1,11 +1,16 @@ import React from "react" -import { useTranslation } from "react-i18next" import LazyLoad from "react-lazyload" -import Artists from "Components/Artists" +import { Artists, Formats, Genres, Price, Year } from "Components/Attributes" import "./Record.scss" -const Record = ({ rec, gridView, gridColumns, rate, handleClick, handleYearClick }) => { - const { t, i18n } = useTranslation() +const Record = ({ rec, gridView, gridColumns, handleClick }) => { + const attributes = { + artists: Artists, + formats: Formats, + genres: Genres, + price: Price, + year: Year, + } const artists = rec.artists .map( (artist, index) => @@ -29,37 +34,14 @@ const Record = ({ rec, gridView, gridColumns, rate, handleClick, handleYearClick {gridColumns && - gridColumns.map(column => ( -
- {column == "artist" ? ( - - ) : column == "price" ? ( - rec.price && (rec.price * rate).toFixed(2) - ) : column == "year" ? ( - rec.year ? ( - { - e.stopPropagation() - handleYearClick(rec.year) - }} - > - {rec.year} - - ) : null - ) : column == "formats" ? ( - rec.formats && - rec.formats - .filter(f => f.name !== "All-Media") - .map(f => (f.qty > 1 ? f.qty + "x" : "") + t("format." + f.name, f.name)) - .join(", ") - ) : column == "genres" ? ( - rec.genres && rec.genres.join(", ") - ) : ( - column in rec && rec[column] - )} -
- ))} + gridColumns.map(column => { + const Attribute = attributes[column] + return ( +
+ {Attribute ? : column in rec && rec[column]} +
+ ) + })} ) : (
handleClick(rec)}> diff --git a/frontend/src/components/Collection/Record/Record.container.js b/frontend/src/components/Collection/Record/Record.container.js index 25010f1..27e685e 100644 --- a/frontend/src/components/Collection/Record/Record.container.js +++ b/frontend/src/components/Collection/Record/Record.container.js @@ -1,20 +1,16 @@ import { connect } from "react-redux" -import { showRecord, filterYear } from "Actions" +import { showRecord } from "Actions" import Record from "./Record.component" const mapStateToProps = state => ({ gridView: state.ui.gridView, gridColumns: state.ui.gridColumns, - rate: state.collection.rate, }) const mapDispatchToProps = dispatch => ({ handleClick: rec => { dispatch(showRecord(rec)) }, - handleYearClick: year => { - dispatch(filterYear(year)) - }, }) export default connect(mapStateToProps, mapDispatchToProps)(Record) diff --git a/frontend/src/components/RecordInfo/RecordInfo.component.js b/frontend/src/components/RecordInfo/RecordInfo.component.js index 48e4142..70d3c45 100644 --- a/frontend/src/components/RecordInfo/RecordInfo.component.js +++ b/frontend/src/components/RecordInfo/RecordInfo.component.js @@ -1,7 +1,6 @@ import React, { useEffect } from "react" -import { useTranslation } from "react-i18next" import Popup from "Components/Popup" -import Artists from "Components/Artists" +import { Artists, Formats, Genres, Price, Year } from "Components/Attributes" import Listen from "./Listen" import "./RecordInfo.scss" @@ -11,11 +10,9 @@ const RecordInfo = ({ rate, currency, updateRecord, - handleYearClick, handleListenClick, hideRecord, }) => { - const { t, i18n } = useTranslation() useEffect(() => { if (rec) { let threeMonthsAgo = new Date() @@ -40,27 +37,30 @@ const RecordInfo = ({
- +
{rec.formats && (
- {rec.formats - .filter(f => f.name !== "All-Media") - .map(f => (f.qty > 1 ? f.qty + "x" : "") + t("format." + f.name, f.name)) - .join(", ")} +
)} {(rec.year && ( -
handleYearClick(rec.year)}> - {rec.year} +
+
)) || null} - {rec.genres &&
{rec.genres.join(", ")}
} + {rec.genres && ( +
+ +
+ )} {rec.price && rate && (
- {"(" + (rec.price * rate).toFixed(2) + " " + currency + ")"} + {"("} + + {" " + currency + ")"}
)}
@@ -71,7 +71,7 @@ const RecordInfo = ({ {track.artists && ( <> {" ("} - + {")"} )} diff --git a/frontend/src/components/RecordInfo/RecordInfo.container.js b/frontend/src/components/RecordInfo/RecordInfo.container.js index c072867..473f6ac 100644 --- a/frontend/src/components/RecordInfo/RecordInfo.container.js +++ b/frontend/src/components/RecordInfo/RecordInfo.container.js @@ -1,5 +1,5 @@ import { connect } from "react-redux" -import { updateRecord, filterYear, showListen, hideRecord } from "Actions" +import { updateRecord, showListen, hideRecord } from "Actions" import { selectActiveRecord } from "Selectors" import RecordInfo from "./RecordInfo.component" @@ -14,9 +14,6 @@ const mapDispatchToProps = dispatch => ({ updateRecord: record => { dispatch(updateRecord(record)) }, - handleYearClick: year => { - dispatch(filterYear(year)) - }, handleListenClick: listen => { dispatch(showListen(listen)) }, diff --git a/frontend/src/reducers/artistReducer.js b/frontend/src/reducers/artistReducer.js index 71caf74..2cf1821 100644 --- a/frontend/src/reducers/artistReducer.js +++ b/frontend/src/reducers/artistReducer.js @@ -10,7 +10,6 @@ import { VIEW_ARTIST_COLLECTION, TOGGLE_VIEW_ARTIST_COLLECTION, RECEIVE_RECORD, - FILTER_YEAR, } from "Actions" function artist( @@ -68,10 +67,6 @@ function artist( return Object.assign({}, state, { viewArtistCollection: !state.viewArtistCollection, }) - case FILTER_YEAR: - return Object.assign({}, state, { - activeRecord: null, - }) default: return state } diff --git a/frontend/src/reducers/collectionReducer.js b/frontend/src/reducers/collectionReducer.js index c9414b6..bc56247 100644 --- a/frontend/src/reducers/collectionReducer.js +++ b/frontend/src/reducers/collectionReducer.js @@ -13,6 +13,7 @@ import { SHOW_ARTIST, SET_CURRENCY, RECEIVE_RATE, + ADD_FILTER, } from "Actions" function collection( @@ -84,6 +85,10 @@ function collection( return Object.assign({}, state, { rate: action.rate.currency == state.currency ? action.rate.rate : state.rate, }) + case ADD_FILTER: + return Object.assign({}, state, { + activeRecord: null, + }) default: return state } diff --git a/frontend/src/reducers/processReducer.js b/frontend/src/reducers/processReducer.js index d73c46f..83ffcca 100644 --- a/frontend/src/reducers/processReducer.js +++ b/frontend/src/reducers/processReducer.js @@ -1,4 +1,4 @@ -import { SET_ORDERS, SET_FILTERS, UPDATE_SEARCH, FILTER_YEAR } from "Actions" +import { SET_ORDERS, SET_FILTERS, UPDATE_SEARCH, ADD_FILTER } from "Actions" function process(state = { orders: {}, filters: {}, searchQuery: "" }, action) { switch (action.type) { @@ -8,17 +8,17 @@ function process(state = { orders: {}, filters: {}, searchQuery: "" }, action) { return Object.assign({}, state, { filters: action.filters }) case UPDATE_SEARCH: return Object.assign({}, state, { searchQuery: action.query }) - case FILTER_YEAR: - return Object.assign({}, state, { - filters: [ - ...state.filters, - { - attribute: "year", - compare: "eq", - value: action.year, - }, - ], - }) + case ADD_FILTER: + return state.filters.some( + f => + f.attribute === action.filter.attribute && + f.compare === action.filter.compare && + f.value === action.filter.value + ) + ? state + : Object.assign({}, state, { + filters: [...state.filters, action.filter], + }) default: return state }