mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 17:57:26 +03:00
Registered remaining short URLs components in DI container
This commit is contained in:
parent
bec755b121
commit
bab1e57ab1
9 changed files with 56 additions and 69 deletions
|
@ -6,11 +6,10 @@ import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as PropTypes from 'prop-types';
|
import * as PropTypes from 'prop-types';
|
||||||
import ShortUrlsVisits from '../visits/ShortUrlVisits';
|
import ShortUrlsVisits from '../visits/ShortUrlVisits';
|
||||||
import CreateShortUrl from '../short-urls/CreateShortUrl';
|
|
||||||
import './MenuLayout.scss';
|
import './MenuLayout.scss';
|
||||||
import { serverType } from '../servers/prop-types';
|
import { serverType } from '../servers/prop-types';
|
||||||
|
|
||||||
const MenuLayout = (TagsList, ShortUrls, AsideMenu) => class MenuLayout extends React.Component {
|
const MenuLayout = (TagsList, ShortUrls, AsideMenu, CreateShortUrl) => class MenuLayout extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
match: PropTypes.object,
|
match: PropTypes.object,
|
||||||
selectServer: PropTypes.func,
|
selectServer: PropTypes.func,
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { createServer, createServers, deleteServer, listServers } from '../serve
|
||||||
import CreateServer from '../servers/CreateServer';
|
import CreateServer from '../servers/CreateServer';
|
||||||
import ServersDropdown from '../servers/ServersDropdown';
|
import ServersDropdown from '../servers/ServersDropdown';
|
||||||
import TagsList from '../tags/TagsList';
|
import TagsList from '../tags/TagsList';
|
||||||
import { filterTags, forceListTags } from '../tags/reducers/tagsList';
|
import { filterTags, forceListTags, listTags } from '../tags/reducers/tagsList';
|
||||||
import ShortUrls from '../short-urls/ShortUrls';
|
import ShortUrls from '../short-urls/ShortUrls';
|
||||||
import SearchBar from '../short-urls/SearchBar';
|
import SearchBar from '../short-urls/SearchBar';
|
||||||
import { listShortUrls } from '../short-urls/reducers/shortUrlsList';
|
import { listShortUrls } from '../short-urls/reducers/shortUrlsList';
|
||||||
|
@ -34,6 +34,13 @@ import ImportServersBtn from '../servers/helpers/ImportServersBtn';
|
||||||
import { ServersImporter } from '../servers/services/ServersImporter';
|
import { ServersImporter } from '../servers/services/ServersImporter';
|
||||||
import { ServersExporter } from '../servers/services/ServersExporter';
|
import { ServersExporter } from '../servers/services/ServersExporter';
|
||||||
import { ServersService } from '../servers/services/ServersService';
|
import { ServersService } from '../servers/services/ServersService';
|
||||||
|
import CreateShortUrl from '../short-urls/CreateShortUrl';
|
||||||
|
import { createShortUrl, resetCreateShortUrl } from '../short-urls/reducers/shortUrlCreation';
|
||||||
|
import TagsSelector from '../tags/helpers/TagsSelector';
|
||||||
|
import DeleteShortUrlModal from '../short-urls/helpers/DeleteShortUrlModal';
|
||||||
|
import { deleteShortUrl, resetDeleteShortUrl, shortUrlDeleted } from '../short-urls/reducers/shortUrlDeletion';
|
||||||
|
import EditTagsModal from '../short-urls/helpers/EditTagsModal';
|
||||||
|
import { editShortUrlTags, resetShortUrlsTags, shortUrlTagsEdited } from '../short-urls/reducers/shortUrlTags';
|
||||||
|
|
||||||
const bottle = new Bottle();
|
const bottle = new Bottle();
|
||||||
|
|
||||||
|
@ -46,7 +53,7 @@ bottle.decorator('MainHeader', withRouter);
|
||||||
bottle.serviceFactory('Home', () => Home);
|
bottle.serviceFactory('Home', () => Home);
|
||||||
bottle.decorator('Home', connect(pick([ 'servers' ]), { resetSelectedServer }));
|
bottle.decorator('Home', connect(pick([ 'servers' ]), { resetSelectedServer }));
|
||||||
|
|
||||||
bottle.serviceFactory('MenuLayout', MenuLayout, 'TagsList', 'ShortUrls', 'AsideMenu');
|
bottle.serviceFactory('MenuLayout', MenuLayout, 'TagsList', 'ShortUrls', 'AsideMenu', 'CreateShortUrl');
|
||||||
bottle.decorator(
|
bottle.decorator(
|
||||||
'MenuLayout',
|
'MenuLayout',
|
||||||
compose(
|
compose(
|
||||||
|
@ -88,7 +95,7 @@ bottle.service('ColorGenerator', ColorGenerator, 'Storage');
|
||||||
|
|
||||||
bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'Tag', 'ShortUrlsRowMenu');
|
bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'Tag', 'ShortUrlsRowMenu');
|
||||||
|
|
||||||
bottle.serviceFactory('ShortUrlsRowMenu', () => ShortUrlsRowMenu);
|
bottle.serviceFactory('ShortUrlsRowMenu', ShortUrlsRowMenu, 'DeleteShortUrlModal', 'EditTagsModal');
|
||||||
|
|
||||||
bottle.constant('axios', axios);
|
bottle.constant('axios', axios);
|
||||||
bottle.service('ShlinkApiClient', ShlinkApiClient, 'axios');
|
bottle.service('ShlinkApiClient', ShlinkApiClient, 'axios');
|
||||||
|
@ -108,4 +115,24 @@ bottle.service('ServersImporter', ServersImporter, 'csvjson');
|
||||||
bottle.service('ServersService', ServersService, 'Storage');
|
bottle.service('ServersService', ServersService, 'Storage');
|
||||||
bottle.service('ServersExporter', ServersExporter, 'ServersService', 'window', 'csvjson');
|
bottle.service('ServersExporter', ServersExporter, 'ServersService', 'window', 'csvjson');
|
||||||
|
|
||||||
|
bottle.serviceFactory('CreateShortUrl', CreateShortUrl, 'TagsSelector');
|
||||||
|
bottle.decorator('CreateShortUrl', connect(pick([ 'shortUrlCreationResult' ]), {
|
||||||
|
createShortUrl,
|
||||||
|
resetCreateShortUrl,
|
||||||
|
}));
|
||||||
|
|
||||||
|
bottle.serviceFactory('TagsSelector', TagsSelector, 'ColorGenerator');
|
||||||
|
bottle.decorator('TagsSelector', connect(pick([ 'tagsList' ]), { listTags }));
|
||||||
|
|
||||||
|
bottle.serviceFactory('DeleteShortUrlModal', () => DeleteShortUrlModal);
|
||||||
|
bottle.decorator('DeleteShortUrlModal', connect(
|
||||||
|
pick([ 'shortUrlDeletion' ]),
|
||||||
|
{ deleteShortUrl, resetDeleteShortUrl, shortUrlDeleted }
|
||||||
|
));
|
||||||
|
bottle.serviceFactory('EditTagsModal', EditTagsModal, 'TagsSelector');
|
||||||
|
bottle.decorator('EditTagsModal', connect(
|
||||||
|
pick([ 'shortUrlTags' ]),
|
||||||
|
{ editShortUrlTags, resetShortUrlsTags, shortUrlTagsEdited }
|
||||||
|
));
|
||||||
|
|
||||||
export default bottle.container;
|
export default bottle.container;
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
import downIcon from '@fortawesome/fontawesome-free-solid/faAngleDoubleDown';
|
import downIcon from '@fortawesome/fontawesome-free-solid/faAngleDoubleDown';
|
||||||
import upIcon from '@fortawesome/fontawesome-free-solid/faAngleDoubleUp';
|
import upIcon from '@fortawesome/fontawesome-free-solid/faAngleDoubleUp';
|
||||||
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
||||||
import { assoc, dissoc, isNil, pick, pipe, replace, trim } from 'ramda';
|
import { assoc, dissoc, isNil, pipe, replace, trim } from 'ramda';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Collapse } from 'reactstrap';
|
import { Collapse } from 'reactstrap';
|
||||||
import * as PropTypes from 'prop-types';
|
import * as PropTypes from 'prop-types';
|
||||||
import DateInput from '../utils/DateInput';
|
import DateInput from '../utils/DateInput';
|
||||||
import TagsSelector from '../tags/helpers/TagsSelector';
|
|
||||||
import CreateShortUrlResult from './helpers/CreateShortUrlResult';
|
import CreateShortUrlResult from './helpers/CreateShortUrlResult';
|
||||||
import { createShortUrl, createShortUrlResultType, resetCreateShortUrl } from './reducers/shortUrlCreation';
|
import { createShortUrlResultType } from './reducers/shortUrlCreation';
|
||||||
|
|
||||||
const normalizeTag = pipe(trim, replace(/ /g, '-'));
|
const normalizeTag = pipe(trim, replace(/ /g, '-'));
|
||||||
const formatDate = (date) => isNil(date) ? date : date.format();
|
const formatDate = (date) => isNil(date) ? date : date.format();
|
||||||
|
|
||||||
export class CreateShortUrlComponent extends React.Component {
|
const CreateShortUrl = (TagsSelector) => class CreateShortUrl extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
createShortUrl: PropTypes.func,
|
createShortUrl: PropTypes.func,
|
||||||
shortUrlCreationResult: createShortUrlResultType,
|
shortUrlCreationResult: createShortUrlResultType,
|
||||||
|
@ -122,11 +120,6 @@ export class CreateShortUrlComponent extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const CreateShortUrl = connect(pick([ 'shortUrlCreationResult' ]), {
|
|
||||||
createShortUrl,
|
|
||||||
resetCreateShortUrl,
|
|
||||||
})(CreateShortUrlComponent);
|
|
||||||
|
|
||||||
export default CreateShortUrl;
|
export default CreateShortUrl;
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
import React, { Component } from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { pick, identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import { shortUrlType } from '../reducers/shortUrlsList';
|
import { shortUrlType } from '../reducers/shortUrlsList';
|
||||||
import {
|
import { shortUrlDeletionType } from '../reducers/shortUrlDeletion';
|
||||||
deleteShortUrl,
|
|
||||||
resetDeleteShortUrl,
|
|
||||||
shortUrlDeleted,
|
|
||||||
shortUrlDeletionType,
|
|
||||||
} from '../reducers/shortUrlDeletion';
|
|
||||||
import './QrCodeModal.scss';
|
|
||||||
|
|
||||||
export class DeleteShortUrlModalComponent extends Component {
|
export default class DeleteShortUrlModal extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
shortUrl: shortUrlType,
|
shortUrl: shortUrlType,
|
||||||
toggle: PropTypes.func,
|
toggle: PropTypes.func,
|
||||||
|
@ -94,10 +87,3 @@ export class DeleteShortUrlModalComponent extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DeleteShortUrlModal = connect(
|
|
||||||
pick([ 'shortUrlDeletion' ]),
|
|
||||||
{ deleteShortUrl, resetDeleteShortUrl, shortUrlDeleted }
|
|
||||||
)(DeleteShortUrlModalComponent);
|
|
||||||
|
|
||||||
export default DeleteShortUrlModal;
|
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { pick } from 'ramda';
|
import { shortUrlTagsType } from '../reducers/shortUrlTags';
|
||||||
import TagsSelector from '../../tags/helpers/TagsSelector';
|
|
||||||
import {
|
|
||||||
editShortUrlTags,
|
|
||||||
resetShortUrlsTags,
|
|
||||||
shortUrlTagsType,
|
|
||||||
shortUrlTagsEdited,
|
|
||||||
} from '../reducers/shortUrlTags';
|
|
||||||
import ExternalLink from '../../utils/ExternalLink';
|
import ExternalLink from '../../utils/ExternalLink';
|
||||||
import { shortUrlType } from '../reducers/shortUrlsList';
|
import { shortUrlType } from '../reducers/shortUrlsList';
|
||||||
|
|
||||||
export class EditTagsModalComponent extends React.Component {
|
const EditTagsModal = (TagsSelector) => class EditTagsModal extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
toggle: PropTypes.func.isRequired,
|
toggle: PropTypes.func.isRequired,
|
||||||
|
@ -88,11 +80,6 @@ export class EditTagsModalComponent extends React.Component {
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const EditTagsModal = connect(
|
|
||||||
pick([ 'shortUrlTags' ]),
|
|
||||||
{ editShortUrlTags, resetShortUrlsTags, shortUrlTagsEdited }
|
|
||||||
)(EditTagsModalComponent);
|
|
||||||
|
|
||||||
export default EditTagsModal;
|
export default EditTagsModal;
|
||||||
|
|
|
@ -15,11 +15,9 @@ import { serverType } from '../../servers/prop-types';
|
||||||
import { shortUrlType } from '../reducers/shortUrlsList';
|
import { shortUrlType } from '../reducers/shortUrlsList';
|
||||||
import PreviewModal from './PreviewModal';
|
import PreviewModal from './PreviewModal';
|
||||||
import QrCodeModal from './QrCodeModal';
|
import QrCodeModal from './QrCodeModal';
|
||||||
import EditTagsModal from './EditTagsModal';
|
|
||||||
import DeleteShortUrlModal from './DeleteShortUrlModal';
|
|
||||||
import './ShortUrlsRowMenu.scss';
|
import './ShortUrlsRowMenu.scss';
|
||||||
|
|
||||||
export default class ShortUrlsRowMenu extends React.Component {
|
const ShortUrlsRowMenu = (DeleteShortUrlModal, EditTagsModal) => class ShortUrlsRowMenu extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
completeShortUrl: PropTypes.string,
|
completeShortUrl: PropTypes.string,
|
||||||
onCopyToClipboard: PropTypes.func,
|
onCopyToClipboard: PropTypes.func,
|
||||||
|
@ -105,4 +103,6 @@ export default class ShortUrlsRowMenu extends React.Component {
|
||||||
</ButtonDropdown>
|
</ButtonDropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default ShortUrlsRowMenu;
|
||||||
|
|
|
@ -1,26 +1,21 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import TagsInput from 'react-tagsinput';
|
import TagsInput from 'react-tagsinput';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Autosuggest from 'react-autosuggest';
|
import Autosuggest from 'react-autosuggest';
|
||||||
import { pick, identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import { listTags } from '../reducers/tagsList';
|
|
||||||
import colorGenerator, { colorGeneratorType } from '../../utils/ColorGenerator';
|
|
||||||
import './TagsSelector.scss';
|
|
||||||
import TagBullet from './TagBullet';
|
import TagBullet from './TagBullet';
|
||||||
|
import './TagsSelector.scss';
|
||||||
|
|
||||||
export class TagsSelectorComponent extends React.Component {
|
const TagsSelector = (colorGenerator) => class TagsSelector extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
|
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
colorGenerator: colorGeneratorType,
|
|
||||||
tagsList: PropTypes.shape({
|
tagsList: PropTypes.shape({
|
||||||
tags: PropTypes.arrayOf(PropTypes.string),
|
tags: PropTypes.arrayOf(PropTypes.string),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
colorGenerator,
|
|
||||||
placeholder: 'Add tags to the URL',
|
placeholder: 'Add tags to the URL',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +26,7 @@ export class TagsSelectorComponent extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { tags, onChange, placeholder, colorGenerator, tagsList } = this.props;
|
const { tags, onChange, placeholder, tagsList } = this.props;
|
||||||
const renderTag = ({ tag, key, disabled, onRemove, classNameRemove, getTagDisplayValue, ...other }) => (
|
const renderTag = ({ tag, key, disabled, onRemove, classNameRemove, getTagDisplayValue, ...other }) => (
|
||||||
<span key={key} style={{ backgroundColor: colorGenerator.getColorForKey(tag) }} {...other}>
|
<span key={key} style={{ backgroundColor: colorGenerator.getColorForKey(tag) }} {...other}>
|
||||||
{getTagDisplayValue(tag)}
|
{getTagDisplayValue(tag)}
|
||||||
|
@ -86,8 +81,6 @@ export class TagsSelectorComponent extends React.Component {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const TagsSelector = connect(pick([ 'tagsList' ]), { listTags })(TagsSelectorComponent);
|
|
||||||
|
|
||||||
export default TagsSelector;
|
export default TagsSelector;
|
||||||
|
|
|
@ -3,18 +3,20 @@ import { shallow } from 'enzyme';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import { CreateShortUrlComponent as CreateShortUrl } from '../../src/short-urls/CreateShortUrl';
|
import createShortUrlsCreator from '../../src/short-urls/CreateShortUrl';
|
||||||
import TagsSelector from '../../src/tags/helpers/TagsSelector';
|
|
||||||
import DateInput from '../../src/utils/DateInput';
|
import DateInput from '../../src/utils/DateInput';
|
||||||
|
|
||||||
describe('<CreateShortUrl />', () => {
|
describe('<CreateShortUrl />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
const TagsSelector = () => '';
|
||||||
const shortUrlCreationResult = {
|
const shortUrlCreationResult = {
|
||||||
loading: false,
|
loading: false,
|
||||||
};
|
};
|
||||||
const createShortUrl = sinon.spy();
|
const createShortUrl = sinon.spy();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
const CreateShortUrl = createShortUrlsCreator(TagsSelector);
|
||||||
|
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<CreateShortUrl shortUrlCreationResult={shortUrlCreationResult} createShortUrl={createShortUrl} />
|
<CreateShortUrl shortUrlCreationResult={shortUrlCreationResult} createShortUrl={createShortUrl} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { DeleteShortUrlModalComponent as DeleteShortUrlModal } from '../../../src/short-urls/helpers/DeleteShortUrlModal';
|
import DeleteShortUrlModal from '../../../src/short-urls/helpers/DeleteShortUrlModal';
|
||||||
|
|
||||||
describe('<DeleteShortUrlModal />', () => {
|
describe('<DeleteShortUrlModal />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
Loading…
Reference in a new issue