From 0c1f9e6c8dc998f41fe71f31f12259f7b72bd963 Mon Sep 17 00:00:00 2001 From: Qstick Date: Sat, 10 Nov 2018 23:08:31 -0500 Subject: [PATCH] New: Optional Search Button on Artist Index views --- .../Artist/Index/ArtistIndexItemConnector.js | 50 +++++++++++- .../Index/Banners/ArtistIndexBanner.css | 1 + .../Artist/Index/Banners/ArtistIndexBanner.js | 19 ++++- .../ArtistIndexBannerOptionsModalContent.js | 26 ++++++- .../Index/Overview/ArtistIndexOverview.js | 16 ++++ .../ArtistIndexOverviewOptionsModalContent.js | 28 ++++++- .../Index/Posters/ArtistIndexPoster.css | 1 + .../Artist/Index/Posters/ArtistIndexPoster.js | 19 ++++- .../ArtistIndexPosterOptionsModalContent.js | 26 ++++++- .../Artist/Index/Table/ArtistIndexHeader.css | 2 +- .../Artist/Index/Table/ArtistIndexHeader.js | 3 + .../src/Artist/Index/Table/ArtistIndexRow.css | 2 +- .../src/Artist/Index/Table/ArtistIndexRow.js | 21 ++++- .../Index/Table/ArtistIndexTableOptions.js | 76 +++++++++++++++++++ .../Table/ArtistIndexTableOptionsConnector.js | 14 ++++ .../Table/TableOptions/TableOptionsModal.js | 10 +++ .../Reducers/createSetTableOptionReducer.js | 3 +- .../src/Store/Actions/artistIndexActions.js | 17 +++-- 18 files changed, 310 insertions(+), 24 deletions(-) create mode 100644 frontend/src/Artist/Index/Table/ArtistIndexTableOptions.js create mode 100644 frontend/src/Artist/Index/Table/ArtistIndexTableOptionsConnector.js diff --git a/frontend/src/Artist/Index/ArtistIndexItemConnector.js b/frontend/src/Artist/Index/ArtistIndexItemConnector.js index a7e093733..eb1f2d0b9 100644 --- a/frontend/src/Artist/Index/ArtistIndexItemConnector.js +++ b/frontend/src/Artist/Index/ArtistIndexItemConnector.js @@ -13,14 +13,42 @@ import createMetadataProfileSelector from 'Store/Selectors/createMetadataProfile import { executeCommand } from 'Store/Actions/commandActions'; import * as commandNames from 'Commands/commandNames'; +function selectShowSearchAction() { + return createSelector( + (state) => state.artistIndex, + (artistIndex) => { + const view = artistIndex.view; + + switch (view) { + case 'posters': + return artistIndex.posterOptions.showSearchAction; + case 'banners': + return artistIndex.bannerOptions.showSearchAction; + case 'overview': + return artistIndex.overviewOptions.showSearchAction; + default: + return artistIndex.tableOptions.showSearchAction; + } + } + ); +} + function createMapStateToProps() { return createSelector( createArtistSelector(), createQualityProfileSelector(), createLanguageProfileSelector(), createMetadataProfileSelector(), + selectShowSearchAction(), createCommandsSelector(), - (artist, qualityProfile, languageProfile, metadataProfile, commands) => { + ( + artist, + qualityProfile, + languageProfile, + metadataProfile, + showSearchAction, + commands + ) => { const isRefreshingArtist = commands.some((command) => { return ( command.name === commandNames.REFRESH_ARTIST && @@ -29,6 +57,14 @@ function createMapStateToProps() { ); }); + const isSearchingArtist = commands.some((command) => { + return ( + command.name === commandNames.ARTIST_SEARCH && + command.body.artistId === artist.id && + isCommandExecuting(command) + ); + }); + const latestAlbum = _.maxBy(artist.albums, (album) => album.releaseDate); return { @@ -37,7 +73,9 @@ function createMapStateToProps() { languageProfile, metadataProfile, latestAlbum, - isRefreshingArtist + showSearchAction, + isRefreshingArtist, + isSearchingArtist }; } ); @@ -59,6 +97,13 @@ class ArtistIndexItemConnector extends Component { }); } + onSearchPress = () => { + this.props.executeCommand({ + name: commandNames.ARTIST_SEARCH, + artistId: this.props.id + }); + } + // // Render @@ -72,6 +117,7 @@ class ArtistIndexItemConnector extends Component { ); } diff --git a/frontend/src/Artist/Index/Banners/ArtistIndexBanner.css b/frontend/src/Artist/Index/Banners/ArtistIndexBanner.css index f4ee5c289..b721a3612 100644 --- a/frontend/src/Artist/Index/Banners/ArtistIndexBanner.css +++ b/frontend/src/Artist/Index/Banners/ArtistIndexBanner.css @@ -61,6 +61,7 @@ $hoverScale: 1.05; position: absolute; bottom: 10px; left: 10px; + z-index: 3; border-radius: 4px; background-color: #216044; color: $white; diff --git a/frontend/src/Artist/Index/Banners/ArtistIndexBanner.js b/frontend/src/Artist/Index/Banners/ArtistIndexBanner.js index dbe5f1a1d..42883da51 100644 --- a/frontend/src/Artist/Index/Banners/ArtistIndexBanner.js +++ b/frontend/src/Artist/Index/Banners/ArtistIndexBanner.js @@ -69,12 +69,15 @@ class ArtistIndexBanner extends Component { showTitle, showMonitored, showQualityProfile, + showSearchAction, qualityProfile, showRelativeDates, shortDateFormat, timeFormat, isRefreshingArtist, + isSearchingArtist, onRefreshArtistPress, + onSearchPress, ...otherProps } = this.props; @@ -111,6 +114,17 @@ class ArtistIndexBanner extends Component { onPress={onRefreshArtistPress} /> + { + showSearchAction && + + } + + + + Show Search + + + @@ -185,6 +204,7 @@ ArtistIndexBannerOptionsModalContent.propTypes = { showTitle: PropTypes.bool.isRequired, showQualityProfile: PropTypes.bool.isRequired, detailedProgressBar: PropTypes.bool.isRequired, + showSearchAction: PropTypes.bool.isRequired, onChangeBannerOption: PropTypes.func.isRequired, showMonitored: PropTypes.bool.isRequired, onModalClose: PropTypes.func.isRequired diff --git a/frontend/src/Artist/Index/Overview/ArtistIndexOverview.js b/frontend/src/Artist/Index/Overview/ArtistIndexOverview.js index 0dd5fb1d2..ca77bafa3 100644 --- a/frontend/src/Artist/Index/Overview/ArtistIndexOverview.js +++ b/frontend/src/Artist/Index/Overview/ArtistIndexOverview.js @@ -84,6 +84,7 @@ class ArtistIndexOverview extends Component { posterHeight, qualityProfile, overviewOptions, + showSearchAction, showRelativeDates, shortDateFormat, longDateFormat, @@ -91,7 +92,9 @@ class ArtistIndexOverview extends Component { rowHeight, isSmallScreen, isRefreshingArtist, + isSearchingArtist, onRefreshArtistPress, + onSearchPress, ...otherProps } = this.props; @@ -175,6 +178,17 @@ class ArtistIndexOverview extends Component { onPress={onRefreshArtistPress} /> + { + showSearchAction && + + } + + + + Show Search + + + @@ -252,6 +271,7 @@ class ArtistIndexOverviewOptionsModalContent extends Component { ArtistIndexOverviewOptionsModalContent.propTypes = { size: PropTypes.string.isRequired, + detailedProgressBar: PropTypes.bool.isRequired, showMonitored: PropTypes.bool.isRequired, showQualityProfile: PropTypes.bool.isRequired, showLastAlbum: PropTypes.bool.isRequired, @@ -259,7 +279,7 @@ ArtistIndexOverviewOptionsModalContent.propTypes = { showAlbumCount: PropTypes.bool.isRequired, showPath: PropTypes.bool.isRequired, showSizeOnDisk: PropTypes.bool.isRequired, - detailedProgressBar: PropTypes.bool.isRequired, + showSearchAction: PropTypes.bool.isRequired, onChangeOverviewOption: PropTypes.func.isRequired, onModalClose: PropTypes.func.isRequired }; diff --git a/frontend/src/Artist/Index/Posters/ArtistIndexPoster.css b/frontend/src/Artist/Index/Posters/ArtistIndexPoster.css index b97796747..9f58a8f21 100644 --- a/frontend/src/Artist/Index/Posters/ArtistIndexPoster.css +++ b/frontend/src/Artist/Index/Posters/ArtistIndexPoster.css @@ -61,6 +61,7 @@ $hoverScale: 1.05; position: absolute; bottom: 10px; left: 10px; + z-index: 3; border-radius: 4px; background-color: #216044; color: $white; diff --git a/frontend/src/Artist/Index/Posters/ArtistIndexPoster.js b/frontend/src/Artist/Index/Posters/ArtistIndexPoster.js index 9437b878b..0d89e51b5 100644 --- a/frontend/src/Artist/Index/Posters/ArtistIndexPoster.js +++ b/frontend/src/Artist/Index/Posters/ArtistIndexPoster.js @@ -70,11 +70,14 @@ class ArtistIndexPoster extends Component { showMonitored, showQualityProfile, qualityProfile, + showSearchAction, showRelativeDates, shortDateFormat, timeFormat, isRefreshingArtist, + isSearchingArtist, onRefreshArtistPress, + onSearchPress, ...otherProps } = this.props; @@ -111,6 +114,17 @@ class ArtistIndexPoster extends Component { onPress={onRefreshArtistPress} /> + { + showSearchAction && + + } + + + + Show Search + + + @@ -186,6 +205,7 @@ ArtistIndexPosterOptionsModalContent.propTypes = { showMonitored: PropTypes.bool.isRequired, showQualityProfile: PropTypes.bool.isRequired, detailedProgressBar: PropTypes.bool.isRequired, + showSearchAction: PropTypes.bool.isRequired, onChangePosterOption: PropTypes.func.isRequired, onModalClose: PropTypes.func.isRequired }; diff --git a/frontend/src/Artist/Index/Table/ArtistIndexHeader.css b/frontend/src/Artist/Index/Table/ArtistIndexHeader.css index bffcb5fd8..ec7a1dbfd 100644 --- a/frontend/src/Artist/Index/Table/ArtistIndexHeader.css +++ b/frontend/src/Artist/Index/Table/ArtistIndexHeader.css @@ -80,5 +80,5 @@ .actions { composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css'; - flex: 0 0 70px; + flex: 0 1 90px; } diff --git a/frontend/src/Artist/Index/Table/ArtistIndexHeader.js b/frontend/src/Artist/Index/Table/ArtistIndexHeader.js index 8c1bd8682..f46bbde5f 100644 --- a/frontend/src/Artist/Index/Table/ArtistIndexHeader.js +++ b/frontend/src/Artist/Index/Table/ArtistIndexHeader.js @@ -5,6 +5,7 @@ import IconButton from 'Components/Link/IconButton'; import VirtualTableHeader from 'Components/Table/VirtualTableHeader'; import VirtualTableHeaderCell from 'Components/Table/VirtualTableHeaderCell'; import TableOptionsModal from 'Components/Table/TableOptions/TableOptionsModal'; +import ArtistIndexTableOptionsConnector from './ArtistIndexTableOptionsConnector'; import styles from './ArtistIndexHeader.css'; class ArtistIndexHeader extends Component { @@ -36,6 +37,7 @@ class ArtistIndexHeader extends Component { render() { const { + showSearchAction, columns, onTableOptionChange, ...otherProps @@ -90,6 +92,7 @@ class ArtistIndexHeader extends Component { diff --git a/frontend/src/Artist/Index/Table/ArtistIndexRow.css b/frontend/src/Artist/Index/Table/ArtistIndexRow.css index 0e051087c..5de727246 100644 --- a/frontend/src/Artist/Index/Table/ArtistIndexRow.css +++ b/frontend/src/Artist/Index/Table/ArtistIndexRow.css @@ -82,7 +82,7 @@ .actions { composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css'; - flex: 0 0 70px; + flex: 0 1 90px; } .checkInput { diff --git a/frontend/src/Artist/Index/Table/ArtistIndexRow.js b/frontend/src/Artist/Index/Table/ArtistIndexRow.js index d5b554459..787ababb9 100644 --- a/frontend/src/Artist/Index/Table/ArtistIndexRow.js +++ b/frontend/src/Artist/Index/Table/ArtistIndexRow.js @@ -80,9 +80,12 @@ class ArtistIndexRow extends Component { ratings, path, tags, + showSearchAction, columns, isRefreshingArtist, - onRefreshArtistPress + isSearchingArtist, + onRefreshArtistPress, + onSearchPress } = this.props; const { @@ -360,6 +363,17 @@ class ArtistIndexRow extends Component { onPress={onRefreshArtistPress} /> + { + showSearchAction && + + } + { + this.setState({ + [name]: value + }, () => { + this.props.onTableOptionChange({ + tableOptions: { + ...this.state, + [name]: value + } + }); + }); + } + + // + // Render + + render() { + const { + showSearchAction + } = this.state; + + return ( + + Show Search + + + + ); + } +} + +ArtistIndexTableOptions.propTypes = { + showSearchAction: PropTypes.bool.isRequired, + onTableOptionChange: PropTypes.func.isRequired +}; + +export default ArtistIndexTableOptions; diff --git a/frontend/src/Artist/Index/Table/ArtistIndexTableOptionsConnector.js b/frontend/src/Artist/Index/Table/ArtistIndexTableOptionsConnector.js new file mode 100644 index 000000000..0a1607cf2 --- /dev/null +++ b/frontend/src/Artist/Index/Table/ArtistIndexTableOptionsConnector.js @@ -0,0 +1,14 @@ +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import ArtistIndexTableOptions from './ArtistIndexTableOptions'; + +function createMapStateToProps() { + return createSelector( + (state) => state.artistIndex.tableOptions, + (tableOptions) => { + return tableOptions; + } + ); +} + +export default connect(createMapStateToProps)(ArtistIndexTableOptions); diff --git a/frontend/src/Components/Table/TableOptions/TableOptionsModal.js b/frontend/src/Components/Table/TableOptions/TableOptionsModal.js index ee970d7cc..fd3810bf7 100644 --- a/frontend/src/Components/Table/TableOptions/TableOptionsModal.js +++ b/frontend/src/Components/Table/TableOptions/TableOptionsModal.js @@ -109,6 +109,8 @@ class TableOptionsModal extends Component { isOpen, columns, canModifyColumns, + optionsComponent: OptionsComponent, + onTableOptionChange, onModalClose } = this.props; @@ -152,6 +154,13 @@ class TableOptionsModal extends Component { } + { + !!OptionsComponent && + + } + { canModifyColumns && @@ -231,6 +240,7 @@ TableOptionsModal.propTypes = { columns: PropTypes.arrayOf(PropTypes.object).isRequired, pageSize: PropTypes.number, canModifyColumns: PropTypes.bool.isRequired, + optionsComponent: PropTypes.func.isRequired, onTableOptionChange: PropTypes.func.isRequired, onModalClose: PropTypes.func.isRequired }; diff --git a/frontend/src/Store/Actions/Creators/Reducers/createSetTableOptionReducer.js b/frontend/src/Store/Actions/Creators/Reducers/createSetTableOptionReducer.js index f353be97c..70b57446d 100644 --- a/frontend/src/Store/Actions/Creators/Reducers/createSetTableOptionReducer.js +++ b/frontend/src/Store/Actions/Creators/Reducers/createSetTableOptionReducer.js @@ -4,7 +4,8 @@ import updateSectionState from 'Utilities/State/updateSectionState'; const whitelistedProperties = [ 'pageSize', - 'columns' + 'columns', + 'tableOptions' ]; function createSetTableOptionReducer(section) { diff --git a/frontend/src/Store/Actions/artistIndexActions.js b/frontend/src/Store/Actions/artistIndexActions.js index fd75b6413..bf719f6c1 100644 --- a/frontend/src/Store/Actions/artistIndexActions.js +++ b/frontend/src/Store/Actions/artistIndexActions.js @@ -1,4 +1,3 @@ -import moment from 'moment'; import { createAction } from 'redux-actions'; import sortByName from 'Utilities/Array/sortByName'; import { filterBuilderTypes, filterBuilderValueTypes, sortDirections } from 'Helpers/Props'; @@ -28,7 +27,8 @@ export const defaultState = { size: 'large', showTitle: true, showMonitored: true, - showQualityProfile: true + showQualityProfile: true, + showSearchAction: false }, bannerOptions: { @@ -36,7 +36,8 @@ export const defaultState = { size: 'large', showTitle: false, showMonitored: true, - showQualityProfile: true + showQualityProfile: true, + showSearchAction: false }, overviewOptions: { @@ -48,7 +49,12 @@ export const defaultState = { showAdded: false, showAlbumCount: true, showPath: false, - showSizeOnDisk: false + showSizeOnDisk: false, + showSearchAction: false + }, + + tableOptions: { + showSearchAction: false }, columns: [ @@ -337,7 +343,8 @@ export const persistState = [ 'artistIndex.columns', 'artistIndex.posterOptions', 'artistIndex.bannerOptions', - 'artistIndex.overviewOptions' + 'artistIndex.overviewOptions', + 'artistIndex.tableOptions' ]; //