mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-10 18:27:25 +03:00
Converted ShortUrlsRow component into a functional component
This commit is contained in:
parent
972eafab34
commit
f55d3a66aa
5 changed files with 49 additions and 51 deletions
|
@ -13,40 +13,36 @@ import Tag from '../../tags/helpers/Tag';
|
|||
import ShortUrlVisitsCount from './ShortUrlVisitsCount';
|
||||
import './ShortUrlsRow.scss';
|
||||
|
||||
const propTypes = {
|
||||
refreshList: PropTypes.func,
|
||||
shortUrlsListParams: shortUrlsListParamsType,
|
||||
selectedServer: serverType,
|
||||
shortUrl: shortUrlType,
|
||||
};
|
||||
|
||||
const ShortUrlsRow = (
|
||||
ShortUrlsRowMenu,
|
||||
colorGenerator,
|
||||
stateFlagTimeout
|
||||
) => class ShortUrlsRow extends React.Component {
|
||||
static propTypes = {
|
||||
refreshList: PropTypes.func,
|
||||
shortUrlsListParams: shortUrlsListParamsType,
|
||||
selectedServer: serverType,
|
||||
shortUrl: shortUrlType,
|
||||
};
|
||||
useStateFlagTimeout
|
||||
) => {
|
||||
const ShortUrlsRowComp = ({ shortUrl, selectedServer, refreshList, shortUrlsListParams }) => {
|
||||
const [ copiedToClipboard, setCopiedToClipboard ] = useStateFlagTimeout(false);
|
||||
const renderTags = (tags) => {
|
||||
if (isEmpty(tags)) {
|
||||
return <i className="indivisible"><small>No tags</small></i>;
|
||||
}
|
||||
|
||||
state = { copiedToClipboard: false };
|
||||
const selectedTags = shortUrlsListParams.tags || [];
|
||||
|
||||
renderTags(tags) {
|
||||
if (isEmpty(tags)) {
|
||||
return <i className="indivisible"><small>No tags</small></i>;
|
||||
}
|
||||
|
||||
const { refreshList, shortUrlsListParams } = this.props;
|
||||
const selectedTags = shortUrlsListParams.tags || [];
|
||||
|
||||
return tags.map((tag) => (
|
||||
<Tag
|
||||
colorGenerator={colorGenerator}
|
||||
key={tag}
|
||||
text={tag}
|
||||
onClick={() => refreshList({ tags: [ ...selectedTags, tag ] })}
|
||||
/>
|
||||
));
|
||||
}
|
||||
|
||||
render() {
|
||||
const { shortUrl, selectedServer } = this.props;
|
||||
return tags.map((tag) => (
|
||||
<Tag
|
||||
colorGenerator={colorGenerator}
|
||||
key={tag}
|
||||
text={tag}
|
||||
onClick={() => refreshList({ tags: [ ...selectedTags, tag ] })}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
return (
|
||||
<tr className="short-urls-row">
|
||||
|
@ -56,16 +52,10 @@ const ShortUrlsRow = (
|
|||
<td className="short-urls-row__cell" data-th="Short URL: ">
|
||||
<span className="indivisible short-urls-row__cell--relative">
|
||||
<ExternalLink href={shortUrl.shortUrl} />
|
||||
<CopyToClipboard
|
||||
text={shortUrl.shortUrl}
|
||||
onCopy={() => stateFlagTimeout(this.setState.bind(this), 'copiedToClipboard')}
|
||||
>
|
||||
<CopyToClipboard text={shortUrl.shortUrl} onCopy={setCopiedToClipboard}>
|
||||
<FontAwesomeIcon icon={copyIcon} className="ml-2 short-urls-row__copy-btn" />
|
||||
</CopyToClipboard>
|
||||
<span
|
||||
className="badge badge-warning short-urls-row__copy-hint"
|
||||
hidden={!this.state.copiedToClipboard}
|
||||
>
|
||||
<span className="badge badge-warning short-urls-row__copy-hint" hidden={!copiedToClipboard}>
|
||||
Copied short URL!
|
||||
</span>
|
||||
</span>
|
||||
|
@ -73,7 +63,7 @@ const ShortUrlsRow = (
|
|||
<td className="short-urls-row__cell short-urls-row__cell--break" data-th="Long URL: ">
|
||||
<ExternalLink href={shortUrl.longUrl} />
|
||||
</td>
|
||||
<td className="short-urls-row__cell" data-th="Tags: ">{this.renderTags(shortUrl.tags)}</td>
|
||||
<td className="short-urls-row__cell" data-th="Tags: ">{renderTags(shortUrl.tags)}</td>
|
||||
<td className="short-urls-row__cell text-md-right" data-th="Visits: ">
|
||||
<ShortUrlVisitsCount
|
||||
visitsCount={shortUrl.visitsCount}
|
||||
|
@ -86,7 +76,11 @@ const ShortUrlsRow = (
|
|||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ShortUrlsRowComp.propTypes = propTypes;
|
||||
|
||||
return ShortUrlsRowComp;
|
||||
};
|
||||
|
||||
export default ShortUrlsRow;
|
||||
|
|
|
@ -33,7 +33,7 @@ const provideServices = (bottle, connect) => {
|
|||
[ 'listShortUrls', 'resetShortUrlParams' ]
|
||||
));
|
||||
|
||||
bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'ShortUrlsRowMenu', 'ColorGenerator', 'stateFlagTimeout');
|
||||
bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'ShortUrlsRowMenu', 'ColorGenerator', 'useStateFlagTimeout');
|
||||
|
||||
bottle.serviceFactory(
|
||||
'ShortUrlsRowMenu',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { stateFlagTimeout } from '../utils';
|
||||
import { stateFlagTimeout, useStateFlagTimeout } from '../utils';
|
||||
import Storage from './Storage';
|
||||
import ColorGenerator from './ColorGenerator';
|
||||
import buildShlinkApiClient from './ShlinkApiClientBuilder';
|
||||
|
@ -14,6 +14,7 @@ const provideServices = (bottle) => {
|
|||
|
||||
bottle.constant('setTimeout', global.setTimeout);
|
||||
bottle.serviceFactory('stateFlagTimeout', stateFlagTimeout, 'setTimeout');
|
||||
bottle.serviceFactory('useStateFlagTimeout', useStateFlagTimeout, 'setTimeout');
|
||||
};
|
||||
|
||||
export default provideServices;
|
||||
|
|
|
@ -19,6 +19,16 @@ export const stateFlagTimeout = (setTimeout) => (
|
|||
setTimeout(() => setState({ [flagName]: !initialValue }), delay);
|
||||
};
|
||||
|
||||
export const useStateFlagTimeout = (setTimeout) => (initialValue = true, delay = DEFAULT_TIMEOUT_DELAY) => {
|
||||
const [ flag, setFlag ] = useState(initialValue);
|
||||
const callback = () => {
|
||||
setFlag(!initialValue);
|
||||
setTimeout(() => setFlag(initialValue), delay);
|
||||
};
|
||||
|
||||
return [ flag, callback ];
|
||||
};
|
||||
|
||||
export const determineOrderDir = (clickedField, currentOrderField, currentOrderDir) => {
|
||||
if (currentOrderField !== clickedField) {
|
||||
return 'ASC';
|
||||
|
|
|
@ -12,7 +12,8 @@ describe('<ShortUrlsRow />', () => {
|
|||
let wrapper;
|
||||
const mockFunction = () => '';
|
||||
const ShortUrlsRowMenu = mockFunction;
|
||||
const stateFlagTimeout = jest.fn();
|
||||
const stateFlagTimeout = jest.fn(() => true);
|
||||
const useStateFlagTimeout = jest.fn(() => [ false, stateFlagTimeout ]);
|
||||
const colorGenerator = {
|
||||
getColorForKey: mockFunction,
|
||||
setColorForKey: mockFunction,
|
||||
|
@ -30,7 +31,7 @@ describe('<ShortUrlsRow />', () => {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
const ShortUrlsRow = createShortUrlsRow(ShortUrlsRowMenu, colorGenerator, stateFlagTimeout);
|
||||
const ShortUrlsRow = createShortUrlsRow(ShortUrlsRowMenu, colorGenerator, useStateFlagTimeout);
|
||||
|
||||
wrapper = shallow(
|
||||
<ShortUrlsRow shortUrlsListParams={{}} refreshList={mockFunction} selecrtedServer={server} shortUrl={shortUrl} />
|
||||
|
@ -96,12 +97,4 @@ describe('<ShortUrlsRow />', () => {
|
|||
menu.simulate('copy');
|
||||
expect(stateFlagTimeout).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('shows copy hint when state prop is true', () => {
|
||||
const isHidden = () => wrapper.find('td').at(1).find('.short-urls-row__copy-hint').prop('hidden');
|
||||
|
||||
expect(isHidden()).toEqual(true);
|
||||
wrapper.setState({ copiedToClipboard: true });
|
||||
expect(isHidden()).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue