mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Loaded version of selected server and created component to filter content based on that version
This commit is contained in:
parent
67a23bfe33
commit
4120d09220
11 changed files with 71 additions and 21 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -4951,6 +4951,11 @@
|
|||
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
|
||||
"dev": true
|
||||
},
|
||||
"compare-versions": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.1.tgz",
|
||||
"integrity": "sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg=="
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
"bottlejs": "^1.7.1",
|
||||
"chart.js": "^2.7.2",
|
||||
"classnames": "^2.2.6",
|
||||
"compare-versions": "^3.5.1",
|
||||
"csvjson": "^5.1.0",
|
||||
"leaflet": "^1.4.0",
|
||||
"moment": "^2.22.2",
|
||||
|
|
|
@ -10,14 +10,19 @@ const initialState = null;
|
|||
|
||||
export const resetSelectedServer = createAction(RESET_SELECTED_SERVER);
|
||||
|
||||
export const selectServer = ({ findServerById }) => (serverId) => (dispatch) => {
|
||||
export const selectServer = ({ findServerById }, buildShlinkApiClient) => (serverId) => async (dispatch) => {
|
||||
dispatch(resetShortUrlParams());
|
||||
|
||||
const selectedServer = findServerById(serverId);
|
||||
const { health } = await buildShlinkApiClient(selectedServer);
|
||||
const { version } = await health();
|
||||
|
||||
dispatch({
|
||||
type: SELECT_SERVER,
|
||||
selectedServer,
|
||||
selectedServer: {
|
||||
...selectedServer,
|
||||
version,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ const provideServices = (bottle, connect, withRouter) => {
|
|||
bottle.service('ServersExporter', ServersExporter, 'ServersService', 'window', 'csvjson');
|
||||
|
||||
// Actions
|
||||
bottle.serviceFactory('selectServer', selectServer, 'ServersService');
|
||||
bottle.serviceFactory('selectServer', selectServer, 'ServersService', 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('createServer', createServer, 'ServersService', 'listServers');
|
||||
bottle.serviceFactory('createServers', createServers, 'ServersService', 'listServers');
|
||||
bottle.serviceFactory('deleteServer', deleteServer, 'ServersService', 'listServers');
|
||||
|
|
|
@ -6,6 +6,8 @@ import { Collapse } from 'reactstrap';
|
|||
import * as PropTypes from 'prop-types';
|
||||
import DateInput from '../utils/DateInput';
|
||||
import Checkbox from '../utils/Checkbox';
|
||||
import ForVersion from '../utils/ForVersion';
|
||||
import { serverType } from '../servers/prop-types';
|
||||
import { createShortUrlResultType } from './reducers/shortUrlCreation';
|
||||
import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
|
||||
|
||||
|
@ -17,6 +19,7 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShort
|
|||
createShortUrl: PropTypes.func,
|
||||
shortUrlCreationResult: createShortUrlResultType,
|
||||
resetCreateShortUrl: PropTypes.func,
|
||||
selectedServer: serverType,
|
||||
};
|
||||
|
||||
state = {
|
||||
|
@ -108,16 +111,21 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShort
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-4 text-right">
|
||||
<Checkbox
|
||||
className="mr-2"
|
||||
checked={this.state.findIfExists}
|
||||
onChange={(findIfExists) => this.setState({ findIfExists })}
|
||||
>
|
||||
Use existing URL if found
|
||||
</Checkbox>
|
||||
<UseExistingIfFoundInfoIcon />
|
||||
</div>
|
||||
<ForVersion
|
||||
minVersion="1.16.0"
|
||||
currentServerVersion={this.props.selectedServer ? this.props.selectedServer.version : ''}
|
||||
>
|
||||
<div className="mb-4 text-right">
|
||||
<Checkbox
|
||||
className="mr-2"
|
||||
checked={this.state.findIfExists}
|
||||
onChange={(findIfExists) => this.setState({ findIfExists })}
|
||||
>
|
||||
Use existing URL if found
|
||||
</Checkbox>
|
||||
<UseExistingIfFoundInfoIcon />
|
||||
</div>
|
||||
</ForVersion>
|
||||
</Collapse>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -23,8 +23,8 @@ const renderInfoModal = (isOpen, toggle) => (
|
|||
if none is found.
|
||||
</li>
|
||||
<li>
|
||||
When long URL and custom slug are provided: Same as in previous case, but it will try to match the short URL
|
||||
using both the long URL and the slug.
|
||||
When long URL and custom slug and/or domain are provided: Same as in previous case, but it will try to match
|
||||
the short URL using both the long URL and the slug, the long URL and the domain, or the three of them.
|
||||
<br />
|
||||
If the slug is being used by another long URL, an error will be returned.
|
||||
</li>
|
||||
|
|
|
@ -39,7 +39,7 @@ const provideServices = (bottle, connect) => {
|
|||
bottle.serviceFactory('CreateShortUrl', CreateShortUrl, 'TagsSelector', 'CreateShortUrlResult');
|
||||
bottle.decorator(
|
||||
'CreateShortUrl',
|
||||
connect([ 'shortUrlCreationResult' ], [ 'createShortUrl', 'resetCreateShortUrl' ])
|
||||
connect([ 'shortUrlCreationResult', 'selectedServer' ], [ 'createShortUrl', 'resetCreateShortUrl' ])
|
||||
);
|
||||
|
||||
bottle.serviceFactory('DeleteShortUrlModal', () => DeleteShortUrlModal);
|
||||
|
|
19
src/utils/ForVersion.js
Normal file
19
src/utils/ForVersion.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compare } from 'compare-versions';
|
||||
import { isEmpty } from 'ramda';
|
||||
|
||||
const propTypes = {
|
||||
minVersion: PropTypes.string.isRequired,
|
||||
currentServerVersion: PropTypes.string.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
const ForVersion = ({ minVersion, currentServerVersion, children }) =>
|
||||
isEmpty(currentServerVersion) || compare(minVersion, currentServerVersion, '>')
|
||||
? null
|
||||
: <React.Fragment>{children}</React.Fragment>;
|
||||
|
||||
ForVersion.propTypes = propTypes;
|
||||
|
||||
export default ForVersion;
|
|
@ -50,6 +50,8 @@ export default class ShlinkApiClient {
|
|||
this._performRequest('/tags', 'PUT', {}, { oldName, newName })
|
||||
.then(() => ({ oldName, newName }));
|
||||
|
||||
health = () => this._performRequest('/health', 'GET').then((resp) => resp.data);
|
||||
|
||||
_performRequest = async (url, method = 'GET', query = {}, body = {}) =>
|
||||
await this.axios({
|
||||
method,
|
||||
|
|
|
@ -13,8 +13,10 @@ const getSelectedServerFromState = async (getState) => {
|
|||
return selectedServer;
|
||||
};
|
||||
|
||||
const buildShlinkApiClient = (axios) => async (getState) => {
|
||||
const { url, apiKey } = await getSelectedServerFromState(getState);
|
||||
const buildShlinkApiClient = (axios) => async (getStateOrSelectedServer) => {
|
||||
const { url, apiKey } = typeof getStateOrSelectedServer === 'function'
|
||||
? await getSelectedServerFromState(getStateOrSelectedServer)
|
||||
: getStateOrSelectedServer;
|
||||
const clientKey = `${url}_${apiKey}`;
|
||||
|
||||
if (!apiClients[clientKey]) {
|
||||
|
|
|
@ -29,22 +29,30 @@ describe('selectedServerReducer', () => {
|
|||
const selectedServer = {
|
||||
id: serverId,
|
||||
};
|
||||
const version = '1.19.0';
|
||||
const ServersServiceMock = {
|
||||
findServerById: jest.fn(() => selectedServer),
|
||||
};
|
||||
const apiClientMock = {
|
||||
health: jest.fn().mockResolvedValue({ version }),
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
ServersServiceMock.findServerById.mockClear();
|
||||
});
|
||||
|
||||
it('dispatches proper actions', () => {
|
||||
it('dispatches proper actions', async () => {
|
||||
const dispatch = jest.fn();
|
||||
const expectedSelectedServer = {
|
||||
...selectedServer,
|
||||
version,
|
||||
};
|
||||
|
||||
selectServer(ServersServiceMock)(serverId)(dispatch);
|
||||
await selectServer(ServersServiceMock, async () => apiClientMock)(serverId)(dispatch);
|
||||
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: RESET_SHORT_URL_PARAMS });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: SELECT_SERVER, selectedServer });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
|
||||
});
|
||||
|
||||
it('invokes dependencies', () => {
|
||||
|
|
Loading…
Reference in a new issue