diff --git a/src/container/index.js b/src/container/index.js index 88593418..8bd9537e 100644 --- a/src/container/index.js +++ b/src/container/index.js @@ -20,7 +20,6 @@ import SearchBar from '../short-urls/SearchBar'; import { listShortUrls } from '../short-urls/reducers/shortUrlsList'; import ShortUrlsList from '../short-urls/ShortUrlsList'; import { resetShortUrlParams } from '../short-urls/reducers/shortUrlsListParams'; -import Tag from '../tags/helpers/Tag'; import { ColorGenerator } from '../utils/ColorGenerator'; import { Storage } from '../utils/Storage'; import ShortUrlsRow from '../short-urls/helpers/ShortUrlsRow'; @@ -41,6 +40,11 @@ import { deleteShortUrl, resetDeleteShortUrl, shortUrlDeleted } from '../short-u import EditTagsModal from '../short-urls/helpers/EditTagsModal'; import { editShortUrlTags, resetShortUrlsTags, shortUrlTagsEdited } from '../short-urls/reducers/shortUrlTags'; import buildShlinkApiClient from '../api/ShlinkApiClientBuilder'; +import TagCard from '../tags/TagCard'; +import DeleteTagConfirmModal from '../tags/helpers/DeleteTagConfirmModal'; +import { deleteTag, tagDeleted } from '../tags/reducers/tagDelete'; +import EditTagModal from '../tags/helpers/EditTagModal'; +import { editTag, tagEdited } from '../tags/reducers/tagEdit'; const bottle = new Bottle(); const { container } = bottle; @@ -78,7 +82,7 @@ bottle.serviceFactory('App', App, 'MainHeader', 'Home', 'MenuLayout', 'CreateSer bottle.serviceFactory('ServersDropdown', ServersDropdown, 'ServersExporter'); bottle.decorator('ServersDropdown', connectDecorator([ 'servers', 'selectedServer' ], { listServers, selectServer })); -bottle.serviceFactory('TagsList', () => TagsList); +bottle.serviceFactory('TagsList', TagsList, 'TagCard'); bottle.decorator('TagsList', connectDecorator([ 'tagsList' ], { forceListTags, filterTags })); bottle.serviceFactory('ShortUrls', ShortUrls, 'SearchBar', 'ShortUrlsList'); @@ -86,7 +90,7 @@ bottle.decorator('ShortUrls', connect( (state) => assoc('shortUrlsList', state.shortUrlsList.shortUrls, state.shortUrlsList) )); -bottle.serviceFactory('SearchBar', SearchBar, 'Tag'); +bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator'); bottle.decorator('SearchBar', connectDecorator([ 'shortUrlsListParams' ], { listShortUrls })); bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow'); @@ -95,13 +99,11 @@ bottle.decorator('ShortUrlsList', connectDecorator( { listShortUrls, resetShortUrlParams } )); -bottle.serviceFactory('Tag', Tag, 'ColorGenerator'); - bottle.constant('localStorage', global.localStorage); bottle.service('Storage', Storage, 'localStorage'); bottle.service('ColorGenerator', ColorGenerator, 'Storage'); -bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'Tag', 'ShortUrlsRowMenu'); +bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'ShortUrlsRowMenu', 'ColorGenerator'); bottle.serviceFactory('ShortUrlsRowMenu', ShortUrlsRowMenu, 'DeleteShortUrlModal', 'EditTagsModal'); @@ -151,4 +153,12 @@ bottle.serviceFactory('shortUrlTagsEdited', () => shortUrlTagsEdited); bottle.serviceFactory('buildShlinkApiClient', buildShlinkApiClient, 'axios'); +bottle.serviceFactory('TagCard', TagCard, 'DeleteTagConfirmModal', 'EditTagModal', 'ColorGenerator'); + +bottle.serviceFactory('DeleteTagConfirmModal', () => DeleteTagConfirmModal); +bottle.decorator('DeleteTagConfirmModal', connectDecorator([ 'tagDelete' ], { deleteTag, tagDeleted })); + +bottle.serviceFactory('EditTagModal', EditTagModal, 'ColorGenerator'); +bottle.decorator('EditTagModal', connectDecorator([ 'tagEdit' ], { editTag, tagEdited })); + export default container; diff --git a/src/short-urls/SearchBar.js b/src/short-urls/SearchBar.js index 640682b3..6e343c70 100644 --- a/src/short-urls/SearchBar.js +++ b/src/short-urls/SearchBar.js @@ -4,6 +4,7 @@ import React from 'react'; import { isEmpty } from 'ramda'; import PropTypes from 'prop-types'; import SearchField from '../utils/SearchField'; +import Tag from '../tags/helpers/Tag'; import { shortUrlsListParamsType } from './reducers/shortUrlsListParams'; import './SearchBar.scss'; @@ -12,7 +13,7 @@ const propTypes = { shortUrlsListParams: shortUrlsListParamsType, }; -const SearchBar = (Tag) => { +const SearchBar = (colorGenerator) => { const SearchBar = ({ listShortUrls, shortUrlsListParams }) => { const selectedTags = shortUrlsListParams.tags || []; @@ -29,6 +30,7 @@ const SearchBar = (Tag) => {   {selectedTags.map((tag) => ( class ShortUrlsRow extends React.Component { +const ShortUrlsRow = (ShortUrlsRowMenu, colorGenerator) => class ShortUrlsRow extends React.Component { static propTypes = { refreshList: PropTypes.func, shortUrlsListParams: shortUrlsListParamsType, @@ -29,6 +30,7 @@ const ShortUrlsRow = (Tag, ShortUrlsRowMenu) => class ShortUrlsRow extends React return tags.map((tag) => ( refreshList({ tags: [ ...selectedTags, tag ] })} diff --git a/src/tags/TagCard.js b/src/tags/TagCard.js index 538a86ac..9e2033cd 100644 --- a/src/tags/TagCard.js +++ b/src/tags/TagCard.js @@ -7,10 +7,8 @@ import React from 'react'; import { Link } from 'react-router-dom'; import TagBullet from './helpers/TagBullet'; import './TagCard.scss'; -import DeleteTagConfirmModal from './helpers/DeleteTagConfirmModal'; -import EditTagModal from './helpers/EditTagModal'; -export default class TagCard extends React.Component { +const TagCard = (DeleteTagConfirmModal, EditTagModal, colorGenerator) => class TagCard extends React.Component { static propTypes = { tag: PropTypes.string, currentServerId: PropTypes.string, @@ -35,7 +33,7 @@ export default class TagCard extends React.Component {
- + {tag}
@@ -45,4 +43,6 @@ export default class TagCard extends React.Component { ); } -} +}; + +export default TagCard; diff --git a/src/tags/TagsList.js b/src/tags/TagsList.js index edf1f1c2..1982f6fc 100644 --- a/src/tags/TagsList.js +++ b/src/tags/TagsList.js @@ -3,12 +3,11 @@ import { splitEvery } from 'ramda'; import PropTypes from 'prop-types'; import MuttedMessage from '../utils/MuttedMessage'; import SearchField from '../utils/SearchField'; -import TagCard from './TagCard'; const { ceil } = Math; const TAGS_GROUPS_AMOUNT = 4; -export default class TagsList extends React.Component { +const TagsList = (TagCard) => class TagsList extends React.Component { static propTypes = { filterTags: PropTypes.func, forceListTags: PropTypes.func, @@ -80,4 +79,6 @@ export default class TagsList extends React.Component { ); } -} +}; + +export default TagsList; diff --git a/src/tags/helpers/DeleteTagConfirmModal.js b/src/tags/helpers/DeleteTagConfirmModal.js index e201c799..a7e62718 100644 --- a/src/tags/helpers/DeleteTagConfirmModal.js +++ b/src/tags/helpers/DeleteTagConfirmModal.js @@ -1,11 +1,9 @@ import React from 'react'; -import { connect } from 'react-redux'; import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; import PropTypes from 'prop-types'; -import { pick } from 'ramda'; -import { deleteTag, tagDeleted, tagDeleteType } from '../reducers/tagDelete'; +import { tagDeleteType } from '../reducers/tagDelete'; -export class DeleteTagConfirmModalComponent extends React.Component { +export default class DeleteTagConfirmModal extends React.Component { static propTypes = { tag: PropTypes.string.isRequired, toggle: PropTypes.func.isRequired, @@ -67,10 +65,3 @@ export class DeleteTagConfirmModalComponent extends React.Component { ); } } - -const DeleteTagConfirmModal = connect( - pick([ 'tagDelete' ]), - { deleteTag, tagDeleted } -)(DeleteTagConfirmModalComponent); - -export default DeleteTagConfirmModal; diff --git a/src/tags/helpers/EditTagModal.js b/src/tags/helpers/EditTagModal.js index 91e58bd9..f017fc49 100644 --- a/src/tags/helpers/EditTagModal.js +++ b/src/tags/helpers/EditTagModal.js @@ -1,31 +1,23 @@ import React from 'react'; -import { connect } from 'react-redux'; import { Modal, ModalBody, ModalFooter, ModalHeader, Popover } from 'reactstrap'; -import { pick } from 'ramda'; import { ChromePicker } from 'react-color'; import colorIcon from '@fortawesome/fontawesome-free-solid/faPalette'; import FontAwesomeIcon from '@fortawesome/react-fontawesome'; import PropTypes from 'prop-types'; -import colorGenerator, { colorGeneratorType } from '../../utils/ColorGenerator'; -import { editTag, tagEdited } from '../reducers/tagEdit'; import './EditTagModal.scss'; -export class EditTagModalComponent extends React.Component { +const EditTagModal = ({ getColorForKey }) => class EditTagModal extends React.Component { static propTypes = { tag: PropTypes.string, editTag: PropTypes.func, toggle: PropTypes.func, tagEdited: PropTypes.func, - colorGenerator: colorGeneratorType, isOpen: PropTypes.bool, tagEdit: PropTypes.shape({ error: PropTypes.bool, editing: PropTypes.bool, }), }; - static defaultProps = { - colorGenerator, - }; saveTag = (e) => { e.preventDefault(); @@ -53,12 +45,12 @@ export class EditTagModalComponent extends React.Component { constructor(props) { super(props); - const { colorGenerator, tag } = props; + const { tag } = props; this.state = { showColorPicker: false, tag, - color: colorGenerator.getColorForKey(tag), + color: getColorForKey(tag), }; } @@ -131,8 +123,6 @@ export class EditTagModalComponent extends React.Component { ); } -} - -const EditTagModal = connect(pick([ 'tagEdit' ]), { editTag, tagEdited })(EditTagModalComponent); +}; export default EditTagModal; diff --git a/src/tags/helpers/Tag.js b/src/tags/helpers/Tag.js index dad93103..2356e818 100644 --- a/src/tags/helpers/Tag.js +++ b/src/tags/helpers/Tag.js @@ -1,36 +1,35 @@ import React from 'react'; import PropTypes from 'prop-types'; import './Tag.scss'; +import { colorGeneratorType } from '../../utils/ColorGenerator'; const propTypes = { text: PropTypes.string, children: PropTypes.node, clearable: PropTypes.bool, + colorGenerator: colorGeneratorType, onClick: PropTypes.func, onClose: PropTypes.func, }; -const Tag = (colorGenerator) => { - const Tag = ({ - text, - children, - clearable, - onClick = () => {}, - onClose = () => {}, - }) => ( - - {children || text} - {clearable && ×} - - ); +const Tag = ({ + text, + children, + clearable, + colorGenerator, + onClick = () => {}, + onClose = () => {}, +}) => ( + + {children || text} + {clearable && ×} + +); - Tag.propTypes = propTypes; - - return Tag; -}; +Tag.propTypes = propTypes; export default Tag; diff --git a/src/tags/helpers/TagBullet.js b/src/tags/helpers/TagBullet.js index 1427613a..6afcd79d 100644 --- a/src/tags/helpers/TagBullet.js +++ b/src/tags/helpers/TagBullet.js @@ -1,24 +1,20 @@ import React from 'react'; import * as PropTypes from 'prop-types'; -import colorGenerator, { colorGeneratorType } from '../../utils/ColorGenerator'; +import { colorGeneratorType } from '../../utils/ColorGenerator'; import './TagBullet.scss'; const propTypes = { tag: PropTypes.string.isRequired, colorGenerator: colorGeneratorType, }; -const defaultProps = { - colorGenerator, -}; -export default function TagBullet({ tag, colorGenerator }) { - return ( -
- ); -} +const TagBullet = ({ tag, colorGenerator }) => ( +
+); TagBullet.propTypes = propTypes; -TagBullet.defaultProps = defaultProps; + +export default TagBullet; diff --git a/src/tags/helpers/TagsSelector.js b/src/tags/helpers/TagsSelector.js index fdbfeffd..161a9237 100644 --- a/src/tags/helpers/TagsSelector.js +++ b/src/tags/helpers/TagsSelector.js @@ -54,7 +54,7 @@ const TagsSelector = (colorGenerator) => class TagsSelector extends React.Compon getSuggestionValue={(suggestion) => suggestion} renderSuggestion={(suggestion) => ( - + {suggestion} )} diff --git a/test/short-urls/SearchBar.test.js b/test/short-urls/SearchBar.test.js index ae811817..d3a3869e 100644 --- a/test/short-urls/SearchBar.test.js +++ b/test/short-urls/SearchBar.test.js @@ -3,12 +3,12 @@ import { shallow } from 'enzyme'; import sinon from 'sinon'; import searchBarCreator from '../../src/short-urls/SearchBar'; import SearchField from '../../src/utils/SearchField'; +import Tag from '../../src/tags/helpers/Tag'; describe('', () => { let wrapper; const listShortUrlsMock = sinon.spy(); - const Tag = () => ''; - const SearchBar = searchBarCreator(Tag); + const SearchBar = searchBarCreator({}); afterEach(() => { listShortUrlsMock.resetHistory(); diff --git a/test/tags/TagCard.test.js b/test/tags/TagCard.test.js index a905b07e..b8049ba1 100644 --- a/test/tags/TagCard.test.js +++ b/test/tags/TagCard.test.js @@ -1,13 +1,15 @@ import React from 'react'; import { shallow } from 'enzyme'; import { Link } from 'react-router-dom'; -import TagCard from '../../src/tags/TagCard'; +import createTagCard from '../../src/tags/TagCard'; import TagBullet from '../../src/tags/helpers/TagBullet'; describe('', () => { let wrapper; beforeEach(() => { + const TagCard = createTagCard(() => '', () => '', {}); + wrapper = shallow(); }); afterEach(() => wrapper.unmount()); diff --git a/test/tags/TagsList.test.js b/test/tags/TagsList.test.js index ade440d9..0098eee9 100644 --- a/test/tags/TagsList.test.js +++ b/test/tags/TagsList.test.js @@ -2,16 +2,17 @@ import React from 'react'; import { shallow } from 'enzyme'; import { identity, range } from 'ramda'; import * as sinon from 'sinon'; -import TagsList from '../../src/tags/TagsList'; +import createTagsList from '../../src/tags/TagsList'; import MuttedMessage from '../../src/utils/MuttedMessage'; -import TagCard from '../../src/tags/TagCard'; import SearchField from '../../src/utils/SearchField'; describe('', () => { let wrapper; const filterTags = sinon.spy(); + const TagCard = () => ''; const createWrapper = (tagsList) => { const params = { serverId: '1' }; + const TagsList = createTagsList(TagCard); wrapper = shallow(