mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-03 06:47:29 +03:00
commit
9a798c20c0
7 changed files with 59 additions and 13 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
|
## [4.2.1] - 2024-10-09
|
||||||
|
### Added
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* [#1325](https://github.com/shlinkio/shlink-web-client/issues/1325) Get dependency on `uuid` package back, as `crypto.randomUUID()` can only be used in [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).
|
||||||
|
* [shlink-web-component#461](https://github.com/shlinkio/shlink-web-component/issues/461) Ensure `shortUrlsList.confirmDeletion` setting is `true` in any case, except when explicitly set to `false`.
|
||||||
|
* [shlink-web-component#237](https://github.com/shlinkio/shlink-web-component/issues/237) Set darker color for previous period in charts, when light theme is enabled.
|
||||||
|
* [shlink-web-component#246](https://github.com/shlinkio/shlink-web-component/issues/246) Fix selected date range not reflected in visits comparison date range selector, when selecting it in the line chart via drag'n'drop.
|
||||||
|
|
||||||
|
|
||||||
## [4.2.0] - 2024-10-07
|
## [4.2.0] - 2024-10-07
|
||||||
### Added
|
### Added
|
||||||
* [shlink-web-component#411](https://github.com/shlinkio/shlink-web-component/issues/411) Add support for `ip-address` redirect conditions when Shlink server is >=4.2
|
* [shlink-web-component#411](https://github.com/shlinkio/shlink-web-component/issues/411) Add support for `ip-address` redirect conditions when Shlink server is >=4.2
|
||||||
|
|
33
package-lock.json
generated
33
package-lock.json
generated
|
@ -18,7 +18,7 @@
|
||||||
"@shlinkio/data-manipulation": "^1.0.3",
|
"@shlinkio/data-manipulation": "^1.0.3",
|
||||||
"@shlinkio/shlink-frontend-kit": "^0.5.2",
|
"@shlinkio/shlink-frontend-kit": "^0.5.2",
|
||||||
"@shlinkio/shlink-js-sdk": "^1.2.0",
|
"@shlinkio/shlink-js-sdk": "^1.2.0",
|
||||||
"@shlinkio/shlink-web-component": "^0.8.0",
|
"@shlinkio/shlink-web-component": "^0.8.1",
|
||||||
"bootstrap": "5.2.3",
|
"bootstrap": "5.2.3",
|
||||||
"bottlejs": "^2.0.1",
|
"bottlejs": "^2.0.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
"react-router-dom": "^6.26.2",
|
"react-router-dom": "^6.26.2",
|
||||||
"reactstrap": "^9.2.3",
|
"reactstrap": "^9.2.3",
|
||||||
"redux-localstorage-simple": "^2.5.1",
|
"redux-localstorage-simple": "^2.5.1",
|
||||||
|
"uuid": "^10.0.0",
|
||||||
"workbox-core": "^7.1.0",
|
"workbox-core": "^7.1.0",
|
||||||
"workbox-expiration": "^7.1.0",
|
"workbox-expiration": "^7.1.0",
|
||||||
"workbox-precaching": "^7.1.0",
|
"workbox-precaching": "^7.1.0",
|
||||||
|
@ -3087,9 +3088,9 @@
|
||||||
"integrity": "sha512-kYok17WEFcXRknRcbMjO4oTXtmY5XzmmQ4092q+awH0jqQfLDPfY6V2TJGUFhxYseGC4Imz4HX4tbqhcc2xntw=="
|
"integrity": "sha512-kYok17WEFcXRknRcbMjO4oTXtmY5XzmmQ4092q+awH0jqQfLDPfY6V2TJGUFhxYseGC4Imz4HX4tbqhcc2xntw=="
|
||||||
},
|
},
|
||||||
"node_modules/@shlinkio/shlink-web-component": {
|
"node_modules/@shlinkio/shlink-web-component": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-web-component/-/shlink-web-component-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-web-component/-/shlink-web-component-0.8.1.tgz",
|
||||||
"integrity": "sha512-XcIoJRmOpJEwQp9I4QAMCwFHcFv3vd5CwB85kOMIMP4AFcko5jzzvdVjtCvPUtjWDSUrRaWgpv6/yz2YZuY5pQ==",
|
"integrity": "sha512-9OxMk9lZTdyyH3+KqaS/DpMlDg376/6jaxk/1QjRbWVzqD31vCqCKD5HU9RSpY0ei2dt80xr+q8w34QxivKIwA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/drag-and-drop": "^0.0.38",
|
"@formkit/drag-and-drop": "^0.0.38",
|
||||||
|
@ -11044,6 +11045,19 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/validate-npm-package-license": {
|
"node_modules/validate-npm-package-license": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||||
|
@ -13912,9 +13926,9 @@
|
||||||
"integrity": "sha512-kYok17WEFcXRknRcbMjO4oTXtmY5XzmmQ4092q+awH0jqQfLDPfY6V2TJGUFhxYseGC4Imz4HX4tbqhcc2xntw=="
|
"integrity": "sha512-kYok17WEFcXRknRcbMjO4oTXtmY5XzmmQ4092q+awH0jqQfLDPfY6V2TJGUFhxYseGC4Imz4HX4tbqhcc2xntw=="
|
||||||
},
|
},
|
||||||
"@shlinkio/shlink-web-component": {
|
"@shlinkio/shlink-web-component": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-web-component/-/shlink-web-component-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@shlinkio/shlink-web-component/-/shlink-web-component-0.8.1.tgz",
|
||||||
"integrity": "sha512-XcIoJRmOpJEwQp9I4QAMCwFHcFv3vd5CwB85kOMIMP4AFcko5jzzvdVjtCvPUtjWDSUrRaWgpv6/yz2YZuY5pQ==",
|
"integrity": "sha512-9OxMk9lZTdyyH3+KqaS/DpMlDg376/6jaxk/1QjRbWVzqD31vCqCKD5HU9RSpY0ei2dt80xr+q8w34QxivKIwA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@formkit/drag-and-drop": "^0.0.38",
|
"@formkit/drag-and-drop": "^0.0.38",
|
||||||
"@json2csv/plainjs": "^7.0.6",
|
"@json2csv/plainjs": "^7.0.6",
|
||||||
|
@ -19410,6 +19424,11 @@
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="
|
||||||
|
},
|
||||||
"validate-npm-package-license": {
|
"validate-npm-package-license": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
"@shlinkio/data-manipulation": "^1.0.3",
|
"@shlinkio/data-manipulation": "^1.0.3",
|
||||||
"@shlinkio/shlink-frontend-kit": "^0.5.2",
|
"@shlinkio/shlink-frontend-kit": "^0.5.2",
|
||||||
"@shlinkio/shlink-js-sdk": "^1.2.0",
|
"@shlinkio/shlink-js-sdk": "^1.2.0",
|
||||||
"@shlinkio/shlink-web-component": "^0.8.0",
|
"@shlinkio/shlink-web-component": "^0.8.1",
|
||||||
"bootstrap": "5.2.3",
|
"bootstrap": "5.2.3",
|
||||||
"bottlejs": "^2.0.1",
|
"bottlejs": "^2.0.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
@ -49,6 +49,7 @@
|
||||||
"react-router-dom": "^6.26.2",
|
"react-router-dom": "^6.26.2",
|
||||||
"reactstrap": "^9.2.3",
|
"reactstrap": "^9.2.3",
|
||||||
"redux-localstorage-simple": "^2.5.1",
|
"redux-localstorage-simple": "^2.5.1",
|
||||||
|
"uuid": "^10.0.0",
|
||||||
"workbox-core": "^7.1.0",
|
"workbox-core": "^7.1.0",
|
||||||
"workbox-expiration": "^7.1.0",
|
"workbox-expiration": "^7.1.0",
|
||||||
"workbox-precaching": "^7.1.0",
|
"workbox-precaching": "^7.1.0",
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { NoMenuLayout } from '../common/NoMenuLayout';
|
||||||
import type { FCWithDeps } from '../container/utils';
|
import type { FCWithDeps } from '../container/utils';
|
||||||
import { componentFactory, useDependencies } from '../container/utils';
|
import { componentFactory, useDependencies } from '../container/utils';
|
||||||
import { useGoBack } from '../utils/helpers/hooks';
|
import { useGoBack } from '../utils/helpers/hooks';
|
||||||
|
import { randomUUID } from '../utils/utils';
|
||||||
import type { ServerData, ServersMap, ServerWithId } from './data';
|
import type { ServerData, ServersMap, ServerWithId } from './data';
|
||||||
import { DuplicatedServersModal } from './helpers/DuplicatedServersModal';
|
import { DuplicatedServersModal } from './helpers/DuplicatedServersModal';
|
||||||
import type { ImportServersBtnProps } from './helpers/ImportServersBtn';
|
import type { ImportServersBtnProps } from './helpers/ImportServersBtn';
|
||||||
|
@ -44,7 +45,7 @@ const CreateServer: FCWithDeps<CreateServerProps, CreateServerDeps> = ({ servers
|
||||||
const [isConfirmModalOpen, toggleConfirmModal] = useToggle();
|
const [isConfirmModalOpen, toggleConfirmModal] = useToggle();
|
||||||
const [serverData, setServerData] = useState<ServerData>();
|
const [serverData, setServerData] = useState<ServerData>();
|
||||||
const saveNewServer = useCallback((theServerData: ServerData) => {
|
const saveNewServer = useCallback((theServerData: ServerData) => {
|
||||||
const id = crypto.randomUUID();
|
const id = randomUUID();
|
||||||
|
|
||||||
createServers([{ ...theServerData, id }]);
|
createServers([{ ...theServerData, id }]);
|
||||||
navigate(`/server/${id}`);
|
navigate(`/server/${id}`);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import { randomUUID } from '../../utils/utils';
|
||||||
import type { ServerData, ServersMap, ServerWithId } from '../data';
|
import type { ServerData, ServersMap, ServerWithId } from '../data';
|
||||||
|
|
||||||
interface EditServer {
|
interface EditServer {
|
||||||
|
@ -19,7 +20,7 @@ const serverWithId = (server: ServerWithId | ServerData): ServerWithId => {
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...server, id: crypto.randomUUID() };
|
return { ...server, id: randomUUID() };
|
||||||
};
|
};
|
||||||
|
|
||||||
const serversListToMap = (servers: ServerWithId[]): ServersMap => servers.reduce<ServersMap>(
|
const serversListToMap = (servers: ServerWithId[]): ServersMap => servers.reduce<ServersMap>(
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import type { SyntheticEvent } from 'react';
|
import type { SyntheticEvent } from 'react';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
export const handleEventPreventingDefault = <T>(handler: () => T) => (e: SyntheticEvent) => {
|
export const handleEventPreventingDefault = <T>(handler: () => T) => (e: SyntheticEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handler();
|
handler();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const randomUUID = () => v4();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
selectedServerReducerCreator,
|
selectedServerReducerCreator,
|
||||||
selectServer as selectServerCreator,
|
selectServer as selectServerCreator,
|
||||||
} from '../../../src/servers/reducers/selectedServer';
|
} from '../../../src/servers/reducers/selectedServer';
|
||||||
|
import { randomUUID } from '../../../src/utils/utils';
|
||||||
|
|
||||||
describe('selectedServerReducer', () => {
|
describe('selectedServerReducer', () => {
|
||||||
const dispatch = vi.fn();
|
const dispatch = vi.fn();
|
||||||
|
@ -40,7 +41,7 @@ describe('selectedServerReducer', () => {
|
||||||
['latest', MAX_FALLBACK_VERSION, 'latest'],
|
['latest', MAX_FALLBACK_VERSION, 'latest'],
|
||||||
['%invalid_semver%', MIN_FALLBACK_VERSION, '%invalid_semver%'],
|
['%invalid_semver%', MIN_FALLBACK_VERSION, '%invalid_semver%'],
|
||||||
])('dispatches proper actions', async (serverVersion, expectedVersion, expectedPrintableVersion) => {
|
])('dispatches proper actions', async (serverVersion, expectedVersion, expectedPrintableVersion) => {
|
||||||
const id = crypto.randomUUID();
|
const id = randomUUID();
|
||||||
const getState = createGetStateMock(id);
|
const getState = createGetStateMock(id);
|
||||||
const expectedSelectedServer = {
|
const expectedSelectedServer = {
|
||||||
id,
|
id,
|
||||||
|
@ -59,7 +60,7 @@ describe('selectedServerReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches error when health endpoint fails', async () => {
|
it('dispatches error when health endpoint fails', async () => {
|
||||||
const id = crypto.randomUUID();
|
const id = randomUUID();
|
||||||
const getState = createGetStateMock(id);
|
const getState = createGetStateMock(id);
|
||||||
const expectedSelectedServer = fromPartial<NonReachableServer>({ id, serverNotReachable: true });
|
const expectedSelectedServer = fromPartial<NonReachableServer>({ id, serverNotReachable: true });
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ describe('selectedServerReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches error when server is not found', async () => {
|
it('dispatches error when server is not found', async () => {
|
||||||
const id = crypto.randomUUID();
|
const id = randomUUID();
|
||||||
const getState = vi.fn(() => fromPartial<ShlinkState>({ servers: {} }));
|
const getState = vi.fn(() => fromPartial<ShlinkState>({ servers: {} }));
|
||||||
const expectedSelectedServer: NotFoundServer = { serverNotFound: true };
|
const expectedSelectedServer: NotFoundServer = { serverNotFound: true };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue